From f7d38121b341c2339e443962470512ade60b3772 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Boczar?= Date: Sat, 4 Feb 2023 19:30:46 +0100 Subject: [PATCH] fix: cobs accumulator out-of-bounds index when data is 1 byte too long --- src/accumulator.rs | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/src/accumulator.rs b/src/accumulator.rs index 6a160fa..0fd0872 100644 --- a/src/accumulator.rs +++ b/src/accumulator.rs @@ -132,7 +132,7 @@ impl CobsAccumulator { let (take, release) = input.split_at(n + 1); // Does it fit? - if (self.idx + n) <= N { + if (self.idx + take.len()) <= N { // Aw yiss - add to array self.extend_unchecked(take); @@ -286,3 +286,21 @@ fn double_loop_test_ref() { assert!(Demo { a: 256854231, b: 115, c : "different test" } == demo2); } + +#[test] +fn extend_unchecked_in_bounds_test() { + // Test bug present in revision abcb407: + // extend_unchecked may be passed slice with size 1 greater than accumulator buffer causing panic + + #[derive(serde::Serialize, Deserialize, Debug, PartialEq, Eq)] + struct Demo { + data: [u8; 10], + } + + // Accumulator has 1 byte less space than encoded message + let mut acc: CobsAccumulator<11> = CobsAccumulator::new(); + let mut data = crate::to_vec_cobs::<_, 128>(&Demo { data: [0xcc; 10] }).unwrap(); + assert_eq!(data.len(), 12); // 1 byte for offset + 1 sentinel byte appended + + assert!(matches!(acc.feed::(&data[..]), FeedResult::OverFull(_))); +}