Skip to content

Commit aac9bc5

Browse files
committed
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.
1 parent be6fc6a commit aac9bc5

File tree

2 files changed

+16
-2
lines changed

2 files changed

+16
-2
lines changed

src/libcore/slice/mod.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -2177,8 +2177,8 @@ impl<T> [T] {
21772177
assert!(dest <= self.len() - count, "dest is out of bounds");
21782178
unsafe {
21792179
ptr::copy(
2180-
self.get_unchecked(src_start),
2181-
self.get_unchecked_mut(dest),
2180+
self.as_ptr().add(src_start),
2181+
self.as_mut_ptr().add(dest),
21822182
count,
21832183
);
21842184
}

src/libcore/tests/slice.rs

+14
Original file line numberDiff line numberDiff line change
@@ -1512,6 +1512,13 @@ fn test_copy_within() {
15121512
let mut bytes = *b"Hello, World!";
15131513
bytes.copy_within(.., 0);
15141514
assert_eq!(&bytes, b"Hello, World!");
1515+
1516+
// Ensure that copying at the end of slice won't cause UB.
1517+
let mut bytes = *b"Hello, World!";
1518+
bytes.copy_within(13..13, 5);
1519+
assert_eq!(&bytes, b"Hello, World!");
1520+
bytes.copy_within(5..5, 13);
1521+
assert_eq!(&bytes, b"Hello, World!");
15151522
}
15161523

15171524
#[test]
@@ -1536,6 +1543,13 @@ fn test_copy_within_panics_src_inverted() {
15361543
// 2 is greater than 1, so this range is invalid.
15371544
bytes.copy_within(2..1, 0);
15381545
}
1546+
#[test]
1547+
#[should_panic(expected = "attempted to index slice up to maximum usize")]
1548+
fn test_copy_within_panics_src_out_of_bounds() {
1549+
let mut bytes = *b"Hello, World!";
1550+
// 2 is greater than 1, so this range is invalid.
1551+
bytes.copy_within(usize::max_value()..=usize::max_value(), 0);
1552+
}
15391553

15401554
#[test]
15411555
fn test_is_sorted() {

0 commit comments

Comments
 (0)