about summary refs log tree commit diff
path: root/src/liballoc
diff options
context:
space:
mode:
authorSimon Sapin <simon.sapin@exyr.org>2019-10-06 23:45:25 +0200
committerSimon Sapin <simon.sapin@exyr.org>2019-10-06 23:48:55 +0200
commit23d3ff1b9756c768c4412dcd1d80cff0617fd5c5 (patch)
tree3dfa942bea1445703fc9873ffccdf3282c44d023 /src/liballoc
parent421bd77f42c2fe8a2596dbcc1580ec97fb89009f (diff)
downloadrust-23d3ff1b9756c768c4412dcd1d80cff0617fd5c5.tar.gz
rust-23d3ff1b9756c768c4412dcd1d80cff0617fd5c5.zip
Fix zero-size uninitialized boxes
Requesting a zero-size allocation is not allowed,
return a dangling pointer instead.

CC https://github.com/rust-lang/rust/issues/63291#issuecomment-538692745
Diffstat (limited to 'src/liballoc')
-rw-r--r--src/liballoc/boxed.rs18
1 files changed, 14 insertions, 4 deletions
diff --git a/src/liballoc/boxed.rs b/src/liballoc/boxed.rs
index 9b5d9431ae2..2693a64e13b 100644
--- a/src/liballoc/boxed.rs
+++ b/src/liballoc/boxed.rs
@@ -141,6 +141,9 @@ impl<T> Box<T> {
     /// ```
     #[unstable(feature = "new_uninit", issue = "63291")]
     pub fn new_uninit() -> Box<mem::MaybeUninit<T>> {
+        if mem::size_of::<T>() == 0 {
+            return Box(NonNull::dangling().into())
+        }
         let layout = alloc::Layout::new::<mem::MaybeUninit<T>>();
         let ptr = unsafe {
             Global.alloc(layout)
@@ -181,10 +184,17 @@ impl<T> Box<[T]> {
     /// ```
     #[unstable(feature = "new_uninit", issue = "63291")]
     pub fn new_uninit_slice(len: usize) -> Box<[mem::MaybeUninit<T>]> {
-        let layout = alloc::Layout::array::<mem::MaybeUninit<T>>(len).unwrap();
-        let ptr = unsafe { alloc::alloc(layout) };
-        let unique = Unique::new(ptr).unwrap_or_else(|| alloc::handle_alloc_error(layout));
-        let slice = unsafe { slice::from_raw_parts_mut(unique.cast().as_ptr(), len) };
+        let ptr = if mem::size_of::<T>() == 0 || len == 0 {
+            NonNull::dangling()
+        } else {
+            let layout = alloc::Layout::array::<mem::MaybeUninit<T>>(len).unwrap();
+            unsafe {
+                Global.alloc(layout)
+                    .unwrap_or_else(|_| alloc::handle_alloc_error(layout))
+                    .cast()
+            }
+        };
+        let slice = unsafe { slice::from_raw_parts_mut(ptr.as_ptr(), len) };
         Box(Unique::from(slice))
     }
 }