about summary refs log tree commit diff
diff options
context:
space:
mode:
authorJosh Stone <jistone@redhat.com>2017-09-29 13:19:20 -0700
committerJosh Stone <jistone@redhat.com>2017-09-29 13:19:20 -0700
commit8b2e09ffbbb69402f8881824f8689f785695a780 (patch)
tree978b9ce5219a4fb0edd32feedf43194b391b4100
parent3580c4c58940ad5d62a068609b9b696e8eb31309 (diff)
downloadrust-8b2e09ffbbb69402f8881824f8689f785695a780.tar.gz
rust-8b2e09ffbbb69402f8881824f8689f785695a780.zip
Avoid the UB of a null reference to a slice
-rw-r--r--src/libcore/tests/ptr.rs34
1 files changed, 24 insertions, 10 deletions
diff --git a/src/libcore/tests/ptr.rs b/src/libcore/tests/ptr.rs
index 4bd725f828f..6af74eb532b 100644
--- a/src/libcore/tests/ptr.rs
+++ b/src/libcore/tests/ptr.rs
@@ -8,10 +8,26 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+use core::mem;
 use core::ptr::*;
-use core::slice;
 use core::cell::RefCell;
 
+
+/// Create a null pointer to a mutable slice.  This is implemented like
+/// `slice::from_raw_parts_mut`, which we can't use directly because
+/// having a null `&mut [T]` even temporarily is UB.
+fn null_slice<T>() -> *mut [T] {
+    unsafe {
+        #[repr(C)]
+        struct Repr<T> {
+            pub data: *mut T,
+            pub len: usize,
+        }
+
+        mem::transmute(Repr { data: null_mut::<T>(), len: 0 })
+    }
+}
+
 #[test]
 fn test() {
     unsafe {
@@ -78,13 +94,11 @@ fn test_is_null() {
     let mz: *mut [u8] = &mut [];
     assert!(!mz.is_null());
 
-    unsafe {
-        let ncs: *const [u8] = slice::from_raw_parts(null(), 0);
-        assert!(ncs.is_null());
+    let ncs: *const [u8] = null_slice();
+    assert!(ncs.is_null());
 
-        let nms: *mut [u8] = slice::from_raw_parts_mut(null_mut(), 0);
-        assert!(nms.is_null());
-    }
+    let nms: *mut [u8] = null_slice();
+    assert!(nms.is_null());
 }
 
 #[test]
@@ -123,10 +137,10 @@ fn test_as_ref() {
         let mz: *mut [u8] = &mut [];
         assert_eq!(mz.as_ref(), Some(&[][..]));
 
-        let ncs: *const [u8] = slice::from_raw_parts(null(), 0);
+        let ncs: *const [u8] = null_slice();
         assert_eq!(ncs.as_ref(), None);
 
-        let nms: *mut [u8] = slice::from_raw_parts_mut(null_mut(), 0);
+        let nms: *mut [u8] = null_slice();
         assert_eq!(nms.as_ref(), None);
     }
 }
@@ -155,7 +169,7 @@ fn test_as_mut() {
         let mz: *mut [u8] = &mut [];
         assert_eq!(mz.as_mut(), Some(&mut [][..]));
 
-        let nms: *mut [u8] = slice::from_raw_parts_mut(null_mut(), 0);
+        let nms: *mut [u8] = null_slice();
         assert_eq!(nms.as_mut(), None);
     }
 }