]> git.lizzy.rs Git - rust.git/commitdiff
Fail when a vec::reserve is too large
authorAlex Crichton <alex@alexcrichton.com>
Thu, 4 Jul 2013 03:59:34 +0000 (20:59 -0700)
committerAlex Crichton <alex@alexcrichton.com>
Thu, 4 Jul 2013 03:59:34 +0000 (20:59 -0700)
src/libstd/vec.rs

index fb9c47b43733b1db42bc766d7e87122638ae1853..2c42da3383f50d8cd23c7d31504495f66d13a85f 100644 (file)
@@ -1183,7 +1183,11 @@ fn reserve(&mut self, n: uint) {
                     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 @@ fn test_bytes_set_memory() {
         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);
+    }
 }