about summary refs log tree commit diff
path: root/src/libstd
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2013-07-08 23:10:35 -0700
committerbors <bors@rust-lang.org>2013-07-08 23:10:35 -0700
commitac026e2e6948760380ab013e9dc82fc86ad92edc (patch)
treed7d02519258f6ad2281a365f9346efe714d9844d /src/libstd
parenta48ca3290df992fde2f74ccf5b9f4e36563af8da (diff)
parentfe4a15886c97f6095f99fcc894f050dcf6f974eb (diff)
downloadrust-ac026e2e6948760380ab013e9dc82fc86ad92edc.tar.gz
rust-ac026e2e6948760380ab013e9dc82fc86ad92edc.zip
auto merge of #7578 : alexcrichton/rust/overflow, r=thestinger
This should never cause a segfault, but rather fail somehow. Possibly a condition could be used here, but for now there's not much else to do.
Diffstat (limited to 'src/libstd')
-rw-r--r--src/libstd/vec.rs15
1 files changed, 14 insertions, 1 deletions
diff --git a/src/libstd/vec.rs b/src/libstd/vec.rs
index a69ffca026b..191c2a4a0b2 100644
--- a/src/libstd/vec.rs
+++ b/src/libstd/vec.rs
@@ -1172,7 +1172,11 @@ impl<T> OwnedVector<T> for ~[T] {
                     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;
                 }
@@ -3327,4 +3331,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);
+    }
 }