From c1df87ea09446f14eb7ea606c3ec06ba9ca3c14a Mon Sep 17 00:00:00 2001 From: Roman Krasiuk Date: Thu, 22 Feb 2024 10:34:10 +0100 Subject: [PATCH] fix: out-of-bound memory read on `Nibbles::get_byte` --- src/nibbles.rs | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/nibbles.rs b/src/nibbles.rs index 109d0fa..9499a62 100644 --- a/src/nibbles.rs +++ b/src/nibbles.rs @@ -397,9 +397,13 @@ impl Nibbles { /// assert_eq!(nibbles.get_byte(2), Some(0xCD)); /// assert_eq!(nibbles.get_byte(3), None); /// ``` + /// + /// # Panics + /// + /// If `i` equals to [usize::MAX] and next consecutive byte overflows. #[inline] pub fn get_byte(&self, i: usize) -> Option { - if i + 1 < self.len() { + if i.checked_add(1).expect("overflow") < self.len() { Some(unsafe { self.get_byte_unchecked(i) }) } else { None @@ -737,6 +741,16 @@ mod tests { assert_eq!(nibbles.len(), 0); } + /// Test panic out-of-bound memory read. + /// This test only makes sense with no debug assertions in std environment. + #[cfg(all(feature = "std", not(debug_assertions)))] + #[test] + fn get_byte_max() { + let nibbles = Nibbles::from_nibbles_unchecked([0x0A, 0x0B, 0x0C, 0x0D]); + let result = std::panic::catch_unwind(|| nibbles.get_byte(usize::MAX)); + assert!(result.is_err()); + } + #[cfg(feature = "arbitrary")] mod arbitrary { use super::*;