From 87bd8a6c73487b7904b8a2745ddee4a4846ba1c5 Mon Sep 17 00:00:00 2001 From: Dominik Maier Date: Fri, 9 May 2025 20:09:29 +0200 Subject: [PATCH] bolts: Fix UB in Truncate trait (#3207) * bolts: Fix UB in Truncate trait * fix test * rename test * fmt --- libafl_bolts/src/ownedref.rs | 32 +++++++++++++++++++++++++++++--- 1 file changed, 29 insertions(+), 3 deletions(-) diff --git a/libafl_bolts/src/ownedref.rs b/libafl_bolts/src/ownedref.rs index 445e5225f5..acf0072279 100644 --- a/libafl_bolts/src/ownedref.rs +++ b/libafl_bolts/src/ownedref.rs @@ -97,9 +97,12 @@ impl Truncate for &[T] { impl Truncate for &mut [T] { fn truncate(&mut self, len: usize) { - let mut value = core::mem::take(self); - value = unsafe { value.get_unchecked_mut(..len) }; - let _: &mut [T] = core::mem::replace(self, value); + let value = core::mem::take(self); + let len = value.len().min(len); + let truncated = value + .get_mut(..len) + .expect("Truncate with len <= len() should always work"); + let _: &mut [T] = core::mem::replace(self, truncated); } } @@ -1232,3 +1235,26 @@ where } } } + +#[cfg(test)] +mod test { + use crate::Truncate; + + #[test] + fn test_truncate() { + let mut data = [0; 1024]; + let mut slice = &mut data as &mut [_]; + + slice.truncate(1); + assert_eq!(0, slice[0]); + assert_eq!(1, slice.len()); + + slice.truncate(100); + assert_eq!(0, slice[0]); + assert_eq!(1, slice.len()); + + slice.truncate(0); + slice.truncate(100); + assert_eq!(0, slice.len()); + } +}