]> git.lizzy.rs Git - rust.git/commitdiff
copy_within: replace element access by pointer arithmetic to avoid UB
authorkennytm <kennytm@gmail.com>
Sun, 2 Jun 2019 15:30:18 +0000 (23:30 +0800)
committerkennytm <kennytm@gmail.com>
Sun, 2 Jun 2019 15:30:18 +0000 (23:30 +0800)
This ensures we won't accidentally read *src or *dest even when count = 0.

src/libcore/slice/mod.rs
src/libcore/tests/slice.rs

index 44ff3696b8dae09c9d981f49d362eb31e2d2bba7..231082e5a17562c65939a99d32f37a023fb5af7d 100644 (file)
@@ -2177,8 +2177,8 @@ pub fn copy_within<R: ops::RangeBounds<usize>>(&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,
             );
         }
index 9710f019f4e4df0ba630cfd6c4a0c0e6bd246345..401757295922278bca01672d0f609e3ec64fa847 100644 (file)
@@ -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() {