From db37c7343017fed1e5ada6d7e820c507a937a3f8 Mon Sep 17 00:00:00 2001 From: Joseph Angelo Date: Fri, 1 May 2020 19:45:48 -0700 Subject: [PATCH] Improve how the parser handles errors, advancing the buffer in any error case. Include a test of this behavior --- rust/sbp/src/lib.rs | 30 ++++++++++++++++++++++++++++++ rust/sbp/src/parser/mod.rs | 9 +++++++-- 2 files changed, 37 insertions(+), 2 deletions(-) diff --git a/rust/sbp/src/lib.rs b/rust/sbp/src/lib.rs index fd6f4db9d3..b57b57c5d1 100644 --- a/rust/sbp/src/lib.rs +++ b/rust/sbp/src/lib.rs @@ -189,6 +189,36 @@ mod tests { } } + #[test] + fn parser_crc_error() { + let packet = vec![ + // Start with a mostly valid message, with a single byte error + 0x55, 0x0c, // This byte should be 0x0b, changed to intentionally cause a CRC error + 0x02, 0xd3, 0x88, 0x14, 0x28, 0xf4, 0x7a, 0x13, 0x96, + 0x62, 0xee, 0xff, 0xbe, 0x40, 0x14, 0x00, 0xf6, 0xa3, 0x09, 0x00, 0x00, 0x00, 0x0e, + 0x00, 0xdb, 0xbf, 0xde, 0xad, 0xbe, 0xef, + // Include another valid message to properly parse + 0x55u8, 0x0b, 0x02, 0xd3, 0x88, 0x14, 0x28, 0xf4, 0x7a, 0x13, 0x96, + 0x62, 0xee, 0xff, 0xbe, 0x40, 0x14, 0x00, 0xf6, 0xa3, 0x09, 0x00, 0x00, 0x00, 0x0e, + 0x00, 0xdb, 0xbf, 0xde, 0xad, 0xbe, 0xef, + ]; + let mut reader = std::io::Cursor::new(packet); + let mut parser = crate::parser::Parser::new(); + // Iterate through the data until we hit something that is + // parsable + let sbp_result = parser.parse(&mut reader); + assert!(sbp_result.is_err()); + match sbp_result.unwrap_err() { + crate::Error::CrcError => {}, + e => { + assert!(false, "Unexpected error: {:?}", e); + } + }; + + let sbp_result = parser.parse(&mut reader); + assert!(sbp_result.is_ok()); + } + #[test] fn making_frame() { use crate::messages::SBPMessage; diff --git a/rust/sbp/src/parser/mod.rs b/rust/sbp/src/parser/mod.rs index bb8b241006..8b1a76fa5c 100644 --- a/rust/sbp/src/parser/mod.rs +++ b/rust/sbp/src/parser/mod.rs @@ -131,14 +131,19 @@ impl Parser { self.buffer = self.buffer[bytes_read..].to_vec(); break Ok(msg); } - (Err(crate::Error::ParseError), bytes_read) => { + (Err(e), bytes_read) => { if bytes_read >= self.buffer.len() { self.buffer.clear() } else { self.buffer = self.buffer[bytes_read..].to_vec(); } + + if let crate::Error::ParseError = e { + // Continue parsing + } else { + break Err(e) + } } - (Err(e), _bytes_read) => break Err(e), } if self.buffer.is_empty() {