From 8b2e09ffbbb69402f8881824f8689f785695a780 Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Fri, 29 Sep 2017 13:19:20 -0700 Subject: [PATCH] Avoid the UB of a null reference to a slice --- src/libcore/tests/ptr.rs | 34 ++++++++++++++++++++++++---------- 1 file changed, 24 insertions(+), 10 deletions(-) diff --git a/src/libcore/tests/ptr.rs b/src/libcore/tests/ptr.rs index 4bd725f828f0..6af74eb532b9 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() -> *mut [T] { + unsafe { + #[repr(C)] + struct Repr { + pub data: *mut T, + pub len: usize, + } + + mem::transmute(Repr { data: null_mut::(), 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); } }