diff options
| author | Alex Crichton <alex@alexcrichton.com> | 2013-07-03 20:59:34 -0700 |
|---|---|---|
| committer | Alex Crichton <alex@alexcrichton.com> | 2013-07-03 20:59:34 -0700 |
| commit | fe4a15886c97f6095f99fcc894f050dcf6f974eb (patch) | |
| tree | 63775d58f5225992d82ac8fedf2a9e79c9e8af0b | |
| parent | 648c5e9c92c635f3fa11bcf82623f4af2c201f0c (diff) | |
| download | rust-fe4a15886c97f6095f99fcc894f050dcf6f974eb.tar.gz rust-fe4a15886c97f6095f99fcc894f050dcf6f974eb.zip | |
Fail when a vec::reserve is too large
| -rw-r--r-- | src/libstd/vec.rs | 15 |
1 files changed, 14 insertions, 1 deletions
diff --git a/src/libstd/vec.rs b/src/libstd/vec.rs index fb9c47b4373..2c42da3383f 100644 --- a/src/libstd/vec.rs +++ b/src/libstd/vec.rs @@ -1183,7 +1183,11 @@ impl<T> OwnedVector<T> for ~[T] { rustrt::vec_reserve_shared_actual(td, ptr as **raw::VecRepr, n as libc::size_t); } else { let alloc = n * sys::nonzero_size_of::<T>(); - *ptr = realloc_raw(*ptr as *mut c_void, alloc + size_of::<raw::VecRepr>()) + let size = alloc + size_of::<raw::VecRepr>(); + if alloc / sys::nonzero_size_of::<T>() != n || size < alloc { + fail!("vector size is too large: %u", n); + } + *ptr = realloc_raw(*ptr as *mut c_void, size) as *mut raw::VecRepr; (**ptr).unboxed.alloc = alloc; } @@ -3229,4 +3233,13 @@ mod tests { values.mut_slice(2,4).set_memory(0xFF); assert_eq!(values, [0xAB, 0xAB, 0xFF, 0xFF, 0xAB]); } + + #[test] + #[should_fail] + fn test_overflow_does_not_cause_segfault() { + let mut v = ~[]; + v.reserve(-1); + v.push(1); + v.push(2); + } } |
