-
Notifications
You must be signed in to change notification settings - Fork 10
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix oob get_unchecked, overlapping _nonoverlapping #21
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -205,7 +205,7 @@ impl<'a, T> Drop for DmSorter<'a, T> { | |
// This code will only run on stack-unwind (panic). | ||
|
||
// Move back all elements into the slice: | ||
ptr::copy_nonoverlapping(self.dropped.as_ptr(), &mut self.slice[self.write], self.dropped.len()); | ||
ptr::copy_nonoverlapping(self.dropped.as_ptr(), self.slice.as_mut_ptr().add(self.write), self.dropped.len()); | ||
|
||
// Make sure the objects aren't destroyed when self.dropped is dropped (avoid-double-free). | ||
self.dropped.set_len(0); | ||
|
@@ -217,13 +217,14 @@ impl<'a, T> Drop for DmSorter<'a, T> { | |
unsafe fn unsafe_push<T>(vec: &mut Vec<T>, value: &T) { | ||
let old_len = vec.len(); | ||
vec.reserve(1); | ||
ptr::copy_nonoverlapping(value, vec.get_unchecked_mut(old_len), 1); | ||
ptr::copy_nonoverlapping(value, vec.as_mut_ptr().add(old_len), 1); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This |
||
vec.set_len(old_len + 1); | ||
} | ||
|
||
#[inline(always)] | ||
unsafe fn unsafe_copy<T>(slice: &mut [T], source: usize, dest: usize) { | ||
ptr::copy_nonoverlapping(slice.get_unchecked(source), slice.get_unchecked_mut(dest), 1); | ||
let ptr = slice.as_mut_ptr(); | ||
ptr::copy_nonoverlapping(ptr.add(source), ptr.add(dest), 1); | ||
Comment on lines
-226
to
+227
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This change is only required with |
||
} | ||
|
||
fn sort_move_by<T, F>(slice: &mut [T], mut compare: F) | ||
|
@@ -266,7 +267,9 @@ where | |
|| compare(s.slice.get_unchecked(read), s.slice.get_unchecked(s.write - 1)) != Ordering::Less | ||
{ | ||
// The element is order - keep it: | ||
unsafe_copy(s.slice, read, s.write); | ||
if read != s.write { | ||
unsafe_copy(s.slice, read, s.write); | ||
} | ||
Comment on lines
+270
to
+272
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Some of the calls here to |
||
read += 1; | ||
s.write += 1; | ||
num_dropped_in_row = 0; | ||
|
@@ -317,8 +320,8 @@ where | |
let old_len = s.dropped.len(); | ||
s.dropped.reserve(num_backtracked); | ||
ptr::copy_nonoverlapping( | ||
s.slice.get_unchecked(s.write), | ||
s.dropped.get_unchecked_mut(old_len), | ||
s.slice.as_ptr().add(s.write), | ||
s.dropped.as_mut_ptr().add(old_len), | ||
Comment on lines
-320
to
+324
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Both of these indexes are out-of-bounds for the slice, but inbounds for the backing allocation. |
||
num_backtracked, | ||
); | ||
s.dropped.set_len(old_len + num_backtracked); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In this case, the pointer created here is a pointer to a single element, but this call actually needs a pointer which has provenance over a range. This could be created with something like
&mut self.slice[self.write..][..self.dropped.len()] as *mut T
but just offsetting a pointer to the whole slice is simpler.