Skip to content

Commit

Permalink
copy_within: replace element access by pointer arithmetic to avoid UB
Browse files Browse the repository at this point in the history
This ensures we won't accidentally read *src or *dest even when count = 0.
  • Loading branch information
kennytm committed Jun 2, 2019
1 parent be6fc6a commit aac9bc5
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 2 deletions.
4 changes: 2 additions & 2 deletions src/libcore/slice/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2177,8 +2177,8 @@ impl<T> [T] {
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,
);
}
Expand Down
14 changes: 14 additions & 0 deletions src/libcore/tests/slice.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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]
Expand All @@ -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() {
Expand Down

0 comments on commit aac9bc5

Please sign in to comment.