diff options
| author | blake2-ppc <blake2-ppc> | 2013-09-12 05:00:25 +0200 |
|---|---|---|
| committer | blake2-ppc <blake2-ppc> | 2013-09-17 02:48:00 +0200 |
| commit | e211888407db32fcec53f4fa9eb84acdbdf59f87 (patch) | |
| tree | 74b7b8aae3027586895cb1717c9a93eb751fbcd0 /src/libstd/at_vec.rs | |
| parent | 6e538edea2557018c3c8eae41aacf6cdf6370a4d (diff) | |
| download | rust-e211888407db32fcec53f4fa9eb84acdbdf59f87.tar.gz rust-e211888407db32fcec53f4fa9eb84acdbdf59f87.zip | |
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
Diffstat (limited to 'src/libstd/at_vec.rs')
| -rw-r--r-- | src/libstd/at_vec.rs | 13 |
1 files changed, 8 insertions, 5 deletions
diff --git a/src/libstd/at_vec.rs b/src/libstd/at_vec.rs index ce8e90e1a43..42f511f722d 100644 --- a/src/libstd/at_vec.rs +++ b/src/libstd/at_vec.rs @@ -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; } } |
