aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJoe Wilm <joe@jwilm.com>2017-01-10 21:16:03 -0800
committerJoe Wilm <joe@jwilm.com>2017-01-10 21:17:29 -0800
commit5efa369bddf7de23cc290d5170f86bc36d3384f0 (patch)
tree639fa814b0d1e3c3e6d29f360039c7ed670390a0 /src
parent3149ed008ad0694a85ca50231e3d6833998d53cf (diff)
downloadr-alacritty-vte-5efa369bddf7de23cc290d5170f86bc36d3384f0.tar.gz
r-alacritty-vte-5efa369bddf7de23cc290d5170f86bc36d3384f0.tar.bz2
r-alacritty-vte-5efa369bddf7de23cc290d5170f86bc36d3384f0.zip
Fix bug with OSC parsing
An osc_dispatch with zero params would cause an underflow and index out of bounds of self.osc_params.
Diffstat (limited to 'src')
-rw-r--r--src/lib.rs81
1 files changed, 55 insertions, 26 deletions
diff --git a/src/lib.rs b/src/lib.rs
index 8ec62c5..eb4ef94 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -263,11 +263,22 @@ impl Parser {
Action::OscEnd => {
let param_idx = self.osc_num_params;
let idx = self.osc_idx;
- // Finish last parameter if not already maxed
- if param_idx != MAX_PARAMS {
- let prev = self.osc_params[param_idx - 1];
- let begin = prev.1;
- self.osc_params[param_idx] = (begin, idx);
+
+ match param_idx {
+ // Finish last parameter if not already maxed
+ MAX_PARAMS => (),
+
+ // First param is special - 0 to current byte index
+ 0 => {
+ self.osc_params[param_idx] = (0, idx);
+ },
+
+ // All other params depend on previous indexing
+ _ => {
+ let prev = self.osc_params[param_idx - 1];
+ let begin = prev.1;
+ self.osc_params[param_idx] = (begin, idx);
+ }
}
self.osc_num_params += 1;
@@ -393,38 +404,56 @@ mod tests {
0x07 // End OSC
];
+ #[derive(Default)]
+ struct OscDispatcher {
+ dispatched_osc: bool,
+ params: Vec<Vec<u8>>,
+ }
+
+ // All empty bodies except osc_dispatch
+ impl Perform for OscDispatcher {
+ fn print(&mut self, _: char) {}
+ fn execute(&mut self, _byte: u8) {}
+ fn hook(&mut self, _params: &[i64], _intermediates: &[u8], _ignore: bool) {}
+ fn put(&mut self, _byte: u8) {}
+ fn unhook(&mut self) {}
+ fn osc_dispatch(&mut self, params: &[&[u8]]) {
+ // Set a flag so we know these assertions all run
+ self.dispatched_osc = true;
+ self.params = params.iter().map(|p| p.to_vec()).collect();
+ }
+ fn csi_dispatch(&mut self, _params: &[i64], _intermediates: &[u8], _ignore: bool, _c: char) {}
+ fn esc_dispatch(&mut self, _params: &[i64], _intermediates: &[u8], _ignore: bool, _byte: u8) {}
+ }
+
#[test]
fn parse_osc() {
- #[derive(Default)]
- struct OscDispatcher {
- dispatched_osc: bool
- }
+ // Create dispatcher and check state
+ let mut dispatcher = OscDispatcher::default();
+ assert_eq!(dispatcher.dispatched_osc, false);
- // All empty bodies except osc_dispatch
- impl Perform for OscDispatcher {
- fn print(&mut self, _: char) {}
- fn execute(&mut self, _byte: u8) {}
- fn hook(&mut self, _params: &[i64], _intermediates: &[u8], _ignore: bool) {}
- fn put(&mut self, _byte: u8) {}
- fn unhook(&mut self) {}
- fn osc_dispatch(&mut self, params: &[&[u8]]) {
- // Set a flag so we know these assertions all run
- self.dispatched_osc = true;
- assert_eq!(params.len(), 2);
- assert_eq!(params[0], &OSC_BYTES[1..2]);
- assert_eq!(params[1], &OSC_BYTES[3..(OSC_BYTES.len() - 1)]);
- }
- fn csi_dispatch(&mut self, _params: &[i64], _intermediates: &[u8], _ignore: bool, _c: char) {}
- fn esc_dispatch(&mut self, _params: &[i64], _intermediates: &[u8], _ignore: bool, _byte: u8) {}
+ // Run parser using OSC_BYTES
+ let mut parser = Parser::new();
+ for byte in OSC_BYTES {
+ parser.advance(&mut dispatcher, *byte);
}
+ // Check that flag is set and thus osc_dispatch assertions ran.
+ assert!(dispatcher.dispatched_osc);
+ assert_eq!(dispatcher.params.len(), 2);
+ assert_eq!(dispatcher.params[0], &OSC_BYTES[1..2]);
+ assert_eq!(dispatcher.params[1], &OSC_BYTES[3..(OSC_BYTES.len() - 1)]);
+ }
+
+ #[test]
+ fn parse_empty_osc() {
// Create dispatcher and check state
let mut dispatcher = OscDispatcher::default();
assert_eq!(dispatcher.dispatched_osc, false);
// Run parser using OSC_BYTES
let mut parser = Parser::new();
- for byte in OSC_BYTES {
+ for byte in &[0x9d, 0x07] {
parser.advance(&mut dispatcher, *byte);
}