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

View File

@ -230,13 +230,16 @@ pub mod raw {
// 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;
}
}

View File

@ -3659,6 +3659,14 @@ mod tests {
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];