From aac9bc5ffac941b5880ad269076169b752a1c7e9 Mon Sep 17 00:00:00 2001 From: kennytm Date: Sun, 2 Jun 2019 23:30:18 +0800 Subject: [PATCH] copy_within: replace element access by pointer arithmetic to avoid UB This ensures we won't accidentally read *src or *dest even when count = 0. --- src/libcore/slice/mod.rs | 4 ++-- src/libcore/tests/slice.rs | 14 ++++++++++++++ 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/src/libcore/slice/mod.rs b/src/libcore/slice/mod.rs index 44ff3696b8d..231082e5a17 100644 --- a/src/libcore/slice/mod.rs +++ b/src/libcore/slice/mod.rs @@ -2177,8 +2177,8 @@ pub fn copy_within>(&mut self, src: R, dest: usize) assert!(dest <= self.len() - count, "dest is out of bounds"); unsafe { ptr::copy( - self.get_unchecked(src_start), - self.get_unchecked_mut(dest), + self.as_ptr().add(src_start), + self.as_mut_ptr().add(dest), count, ); } diff --git a/src/libcore/tests/slice.rs b/src/libcore/tests/slice.rs index 9710f019f4e..40175729592 100644 --- a/src/libcore/tests/slice.rs +++ b/src/libcore/tests/slice.rs @@ -1512,6 +1512,13 @@ fn test_copy_within() { let mut bytes = *b"Hello, World!"; bytes.copy_within(.., 0); assert_eq!(&bytes, b"Hello, World!"); + + // Ensure that copying at the end of slice won't cause UB. + let mut bytes = *b"Hello, World!"; + bytes.copy_within(13..13, 5); + assert_eq!(&bytes, b"Hello, World!"); + bytes.copy_within(5..5, 13); + assert_eq!(&bytes, b"Hello, World!"); } #[test] @@ -1536,6 +1543,13 @@ fn test_copy_within_panics_src_inverted() { // 2 is greater than 1, so this range is invalid. bytes.copy_within(2..1, 0); } +#[test] +#[should_panic(expected = "attempted to index slice up to maximum usize")] +fn test_copy_within_panics_src_out_of_bounds() { + let mut bytes = *b"Hello, World!"; + // 2 is greater than 1, so this range is invalid. + bytes.copy_within(usize::max_value()..=usize::max_value(), 0); +} #[test] fn test_is_sorted() { -- 2.44.0