Skip to content

Commit fd72321

Browse files
committed
FIX: Replace uses of <[T]>::get_unchecked_mut with raw pointer accessor
This is a soundness fix w.r.t unsafe coding guidelines. In some of the instances, `get_unchecked_mut() -> &mut T as *mut T` was used in places where the element was potentially uninitialized. This was a problem in push. (Not a problem in IntoIter next/next_back, where the whole range we're iterating is initialized).
1 parent 1483c6d commit fd72321

File tree

1 file changed

+11
-6
lines changed

1 file changed

+11
-6
lines changed

src/lib.rs

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -238,10 +238,15 @@ impl<A: Array> ArrayVec<A> {
238238
pub unsafe fn push_unchecked(&mut self, element: A::Item) {
239239
let len = self.len();
240240
debug_assert!(len < A::CAPACITY);
241-
ptr::write(self.get_unchecked_mut(len), element);
241+
ptr::write(self.get_unchecked_ptr(len), element);
242242
self.set_len(len + 1);
243243
}
244244

245+
/// Get pointer to where element at `index` would be
246+
unsafe fn get_unchecked_ptr(&mut self, index: usize) -> *mut A::Item {
247+
self.xs.ptr_mut().add(index)
248+
}
249+
245250
/// Insert `element` at position `index`.
246251
///
247252
/// Shift up all elements after `index`.
@@ -299,7 +304,7 @@ impl<A: Array> ArrayVec<A> {
299304
unsafe { // infallible
300305
// The spot to put the new value
301306
{
302-
let p: *mut _ = self.get_unchecked_mut(index);
307+
let p: *mut _ = self.get_unchecked_ptr(index);
303308
// Shift everything over to make space. (Duplicating the
304309
// `index`th element into two consecutive places.)
305310
ptr::copy(p, p.offset(1), len - index);
@@ -333,7 +338,7 @@ impl<A: Array> ArrayVec<A> {
333338
unsafe {
334339
let new_len = self.len() - 1;
335340
self.set_len(new_len);
336-
Some(ptr::read(self.get_unchecked_mut(new_len)))
341+
Some(ptr::read(self.get_unchecked_ptr(new_len)))
337342
}
338343
}
339344

@@ -760,7 +765,7 @@ impl<A: Array> Iterator for IntoIter<A> {
760765
unsafe {
761766
let index = self.index.to_usize();
762767
self.index = Index::from(index + 1);
763-
Some(ptr::read(self.v.get_unchecked_mut(index)))
768+
Some(ptr::read(self.v.get_unchecked_ptr(index)))
764769
}
765770
}
766771
}
@@ -779,7 +784,7 @@ impl<A: Array> DoubleEndedIterator for IntoIter<A> {
779784
unsafe {
780785
let new_len = self.v.len() - 1;
781786
self.v.set_len(new_len);
782-
Some(ptr::read(self.v.get_unchecked_mut(new_len)))
787+
Some(ptr::read(self.v.get_unchecked_ptr(new_len)))
783788
}
784789
}
785790
}
@@ -795,7 +800,7 @@ impl<A: Array> Drop for IntoIter<A> {
795800
unsafe {
796801
self.v.set_len(0);
797802
let elements = slice::from_raw_parts_mut(
798-
self.v.get_unchecked_mut(index),
803+
self.v.get_unchecked_ptr(index),
799804
len - index);
800805
ptr::drop_in_place(elements);
801806
}

0 commit comments

Comments
 (0)