Skip to content

Commit c93760d

Browse files
author
bcoopers
committed
Vector can currently panic when pushing an element or reserving space
for only half of the maximum size available on the architecture. This allows vectors to keep expanding with those two methods until the amount of bytes exceeds usize.
1 parent fa3d778 commit c93760d

File tree

1 file changed

+11
-5
lines changed

1 file changed

+11
-5
lines changed

src/libcollections/vec.rs

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -306,9 +306,12 @@ impl<T> Vec<T> {
306306
pub fn reserve(&mut self, additional: usize) {
307307
if self.cap - self.len < additional {
308308
let err_msg = "Vec::reserve: `usize` overflow";
309-
let new_cap = self.len.checked_add(additional).expect(err_msg)
310-
.checked_next_power_of_two().expect(err_msg);
311-
self.grow_capacity(new_cap);
309+
310+
let new_min_cap = self.len.checked_add(additional).expect(err_msg);
311+
match new_min_cap.checked_next_power_of_two() {
312+
None => self.grow_capacity(new_min_cap),
313+
Some(x) => self.grow_capacity(x),
314+
}
312315
}
313316
}
314317

@@ -639,8 +642,11 @@ impl<T> Vec<T> {
639642
#[inline(never)]
640643
fn resize<T>(vec: &mut Vec<T>) {
641644
let old_size = vec.cap * mem::size_of::<T>();
642-
let size = max(old_size, 2 * mem::size_of::<T>()) * 2;
643-
if old_size > size { panic!("capacity overflow") }
645+
if old_size == std::usize::MAX { panic!("capacity overflow") }
646+
let mut size = max(old_size, 2 * mem::size_of::<T>()) * 2;
647+
if old_size > size {
648+
size = std::usize::MAX;
649+
}
644650
unsafe {
645651
let ptr = alloc_or_realloc(*vec.ptr, old_size, size);
646652
if ptr.is_null() { ::alloc::oom() }

0 commit comments

Comments
 (0)