diff options
Diffstat (limited to 'src/raw_input.rs')
| -rw-r--r-- | src/raw_input.rs | 28 |
1 files changed, 17 insertions, 11 deletions
diff --git a/src/raw_input.rs b/src/raw_input.rs index 510768fc..5f750ca8 100644 --- a/src/raw_input.rs +++ b/src/raw_input.rs @@ -108,19 +108,22 @@ pub(crate) const GHOSTTY_COLOR_SCHEME_LIGHT_REPORT: &[u8] = b"\x1b[?997;2n"; const BRACKETED_PASTE_START: &[u8] = b"\x1b[200~"; const BRACKETED_PASTE_END: &[u8] = b"\x1b[201~"; -/// Returns whether `data` is exactly one complete bracketed-paste sequence. -/// +/// Returns the UTF-8 payload when `data` is exactly one complete bracketed paste. +pub(crate) fn complete_text_bracketed_paste(data: &[u8]) -> Option<&str> { + if !data.starts_with(BRACKETED_PASTE_START) { + return None; + } + let end = find_subsequence(data, BRACKETED_PASTE_END)?; + if end + BRACKETED_PASTE_END.len() != data.len() { + return None; + } + std::str::from_utf8(&data[BRACKETED_PASTE_START.len()..end]).ok() +} + /// Client transport uses this to distinguish recoverable oversized interactive /// pastes from generic oversized input, which remains a protocol violation. pub(crate) fn is_complete_text_bracketed_paste(data: &[u8]) -> bool { - if !data.starts_with(BRACKETED_PASTE_START) { - return false; - } - let Some(end) = find_subsequence(data, BRACKETED_PASTE_END) else { - return false; - }; - end + BRACKETED_PASTE_END.len() == data.len() - && std::str::from_utf8(&data[BRACKETED_PASTE_START.len()..end]).is_ok() + complete_text_bracketed_paste(data).is_some() } #[derive(Debug)] @@ -1424,7 +1427,10 @@ mod tests { #[test] fn complete_text_bracketed_paste_requires_one_exact_utf8_sequence() { - assert!(is_complete_text_bracketed_paste(b"\x1b[200~hello\x1b[201~")); + assert_eq!( + complete_text_bracketed_paste(b"\x1b[200~hello\x1b[201~"), + Some("hello") + ); assert!(!is_complete_text_bracketed_paste(b"\x1b[200~hello")); assert!(!is_complete_text_bracketed_paste( b"\x1b[200~hello\x1b[201~rest" |
