fix escape code leak
This commit is contained in:
@@ -0,0 +1,78 @@
|
||||
use crate::vt_parser::*;
|
||||
|
||||
pub struct DummyHandler {
|
||||
pub text: String,
|
||||
pub osc_calls: Vec<Vec<u8>>,
|
||||
}
|
||||
impl Handler for DummyHandler {
|
||||
fn text(&mut self, codepoints: &[u32]) {
|
||||
for &c in codepoints {
|
||||
if let Some(ch) = char::from_u32(c) {
|
||||
self.text.push(ch);
|
||||
}
|
||||
}
|
||||
}
|
||||
fn control(&mut self, _byte: u8) {}
|
||||
fn csi(&mut self, _csi: &CsiParams) {}
|
||||
fn osc(&mut self, osc: &[u8]) {
|
||||
self.osc_calls.push(osc.to_vec());
|
||||
}
|
||||
fn save_cursor(&mut self) {}
|
||||
fn restore_cursor(&mut self) {}
|
||||
fn reset(&mut self) {}
|
||||
fn index(&mut self) {}
|
||||
fn newline(&mut self) {}
|
||||
fn reverse_index(&mut self) {}
|
||||
fn screen_alignment(&mut self) {}
|
||||
fn set_tab_stop(&mut self) {}
|
||||
fn set_keypad_mode(&mut self, _mode: bool) {}
|
||||
fn add_vt_parser_ns(&mut self, _ns: u64) {}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_osc_leak_byte_by_byte() {
|
||||
let parser = SharedParser::new();
|
||||
let mut handler = DummyHandler { text: String::new(), osc_calls: Vec::new() };
|
||||
|
||||
let data = b"\x1b]4;1;#769E00\x1b\\\x1b]4;2;#93DE88\x1b\\";
|
||||
|
||||
for &byte in data {
|
||||
let (ptr, _) = parser.create_write_buffer();
|
||||
unsafe {
|
||||
*ptr = byte;
|
||||
}
|
||||
parser.commit_write(1);
|
||||
|
||||
while parser.run_parse_pass(&mut handler) {}
|
||||
}
|
||||
|
||||
println!("TEXT: {:?}", handler.text);
|
||||
println!("OSC calls: {}", handler.osc_calls.len());
|
||||
for call in &handler.osc_calls {
|
||||
println!(" OSC: {:?}", std::str::from_utf8(call).unwrap());
|
||||
}
|
||||
|
||||
assert_eq!(handler.text, "", "Text should be empty, but leaked escape sequence bytes!");
|
||||
assert_eq!(handler.osc_calls.len(), 2, "Should have parsed exactly two OSC calls");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_csi_aborted_by_osc() {
|
||||
let parser = SharedParser::new();
|
||||
let mut handler = DummyHandler { text: String::new(), osc_calls: Vec::new() };
|
||||
|
||||
// An incomplete CSI sequence aborted by an OSC sequence
|
||||
let data = b"\x1b[38;2;255;0;0\x1b]4;1;#769E00\x1b\\";
|
||||
|
||||
let (ptr, len) = parser.create_write_buffer();
|
||||
assert!(len >= data.len());
|
||||
unsafe {
|
||||
std::ptr::copy_nonoverlapping(data.as_ptr(), ptr, data.len());
|
||||
}
|
||||
parser.commit_write(data.len());
|
||||
|
||||
while parser.run_parse_pass(&mut handler) {}
|
||||
|
||||
assert_eq!(handler.text, "", "Text should be empty, but leaked escape sequence bytes!");
|
||||
assert_eq!(handler.osc_calls.len(), 1, "Should have parsed the OSC sequence even after aborting CSI");
|
||||
}
|
||||
Reference in New Issue
Block a user