std::at_vec: Fix segfault on overflow when resizing ~[@T]

Easy to reproduce:

    let mut v = ~[@1];
    v.resize(-1);  // success a.k.a silent failure
    v.push(@2); // segfault
This commit is contained in:
blake2-ppc
2013-09-12 05:00:25 +02:00
parent 6e538edea2
commit e211888407
2 changed files with 16 additions and 5 deletions
+8 -5
View File
@@ -230,13 +230,16 @@ pub unsafe fn reserve<T>(v: &mut @[T], n: uint) {
// Implementation detail. Shouldn't be public
#[allow(missing_doc)]
pub fn reserve_raw(ty: *TyDesc, ptr: *mut *mut Box<Vec<()>>, n: uint) {
// check for `uint` overflow
unsafe {
let size_in_bytes = n * (*ty).size;
if size_in_bytes > (**ptr).data.alloc {
let total_size = size_in_bytes + sys::size_of::<Vec<()>>();
if n > (**ptr).data.alloc / (*ty).size {
let alloc = n * (*ty).size;
let total_size = alloc + sys::size_of::<Vec<()>>();
if alloc / (*ty).size != n || total_size < alloc {
fail!("vector size is too large: %u", n);
}
(*ptr) = local_realloc(*ptr as *(), total_size) as *mut Box<Vec<()>>;
(**ptr).data.alloc = size_in_bytes;
(**ptr).data.alloc = alloc;
}
}
+8
View File
@@ -3659,6 +3659,14 @@ fn test_overflow_does_not_cause_segfault() {
v.push(2);
}
#[test]
#[should_fail]
fn test_overflow_does_not_cause_segfault_managed() {
let mut v = ~[@1];
v.reserve(-1);
v.push(@2);
}
#[test]
fn test_mut_split() {
let mut values = [1u8,2,3,4,5];