Skip to content

Commit 8b2e09f

Browse files
committed
Avoid the UB of a null reference to a slice
1 parent 3580c4c commit 8b2e09f

File tree

1 file changed

+24
-10
lines changed

1 file changed

+24
-10
lines changed

src/libcore/tests/ptr.rs

Lines changed: 24 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,26 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11+
use core::mem;
1112
use core::ptr::*;
12-
use core::slice;
1313
use core::cell::RefCell;
1414

15+
16+
/// Create a null pointer to a mutable slice. This is implemented like
17+
/// `slice::from_raw_parts_mut`, which we can't use directly because
18+
/// having a null `&mut [T]` even temporarily is UB.
19+
fn null_slice<T>() -> *mut [T] {
20+
unsafe {
21+
#[repr(C)]
22+
struct Repr<T> {
23+
pub data: *mut T,
24+
pub len: usize,
25+
}
26+
27+
mem::transmute(Repr { data: null_mut::<T>(), len: 0 })
28+
}
29+
}
30+
1531
#[test]
1632
fn test() {
1733
unsafe {
@@ -78,13 +94,11 @@ fn test_is_null() {
7894
let mz: *mut [u8] = &mut [];
7995
assert!(!mz.is_null());
8096

81-
unsafe {
82-
let ncs: *const [u8] = slice::from_raw_parts(null(), 0);
83-
assert!(ncs.is_null());
97+
let ncs: *const [u8] = null_slice();
98+
assert!(ncs.is_null());
8499

85-
let nms: *mut [u8] = slice::from_raw_parts_mut(null_mut(), 0);
86-
assert!(nms.is_null());
87-
}
100+
let nms: *mut [u8] = null_slice();
101+
assert!(nms.is_null());
88102
}
89103

90104
#[test]
@@ -123,10 +137,10 @@ fn test_as_ref() {
123137
let mz: *mut [u8] = &mut [];
124138
assert_eq!(mz.as_ref(), Some(&[][..]));
125139

126-
let ncs: *const [u8] = slice::from_raw_parts(null(), 0);
140+
let ncs: *const [u8] = null_slice();
127141
assert_eq!(ncs.as_ref(), None);
128142

129-
let nms: *mut [u8] = slice::from_raw_parts_mut(null_mut(), 0);
143+
let nms: *mut [u8] = null_slice();
130144
assert_eq!(nms.as_ref(), None);
131145
}
132146
}
@@ -155,7 +169,7 @@ fn test_as_mut() {
155169
let mz: *mut [u8] = &mut [];
156170
assert_eq!(mz.as_mut(), Some(&mut [][..]));
157171

158-
let nms: *mut [u8] = slice::from_raw_parts_mut(null_mut(), 0);
172+
let nms: *mut [u8] = null_slice();
159173
assert_eq!(nms.as_mut(), None);
160174
}
161175
}

0 commit comments

Comments
 (0)