Skip to content

Commit 0c1cb32

Browse files
committed
test for too long slices
1 parent 96baf1c commit 0c1cb32

File tree

3 files changed

+31
-9
lines changed

3 files changed

+31
-9
lines changed

src/librustc_mir/interpret/validity.rs

+14-2
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use std::ops::RangeInclusive;
33

44
use syntax_pos::symbol::{sym, Symbol};
55
use rustc::hir;
6-
use rustc::ty::layout::{self, TyLayout, LayoutOf, VariantIdx};
6+
use rustc::ty::layout::{self, Size, TyLayout, LayoutOf, VariantIdx};
77
use rustc::ty;
88
use rustc_data_structures::fx::FxHashSet;
99

@@ -276,8 +276,20 @@ impl<'rt, 'mir, 'tcx, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, 'tcx, M
276276
// FIXME: More checks for the vtable.
277277
}
278278
ty::Slice(..) | ty::Str => {
279-
try_validation!(meta.unwrap().to_usize(self.ecx),
279+
let len = try_validation!(meta.unwrap().to_usize(self.ecx),
280280
"non-integer slice length in wide pointer", self.path);
281+
// check max slice length
282+
let elem_size = match tail.sty {
283+
ty::Str => Size::from_bytes(1),
284+
ty::Slice(ty) => self.ecx.layout_of(ty)?.size,
285+
_ => bug!("It cannot be another type"),
286+
};
287+
if elem_size.checked_mul(len, &*self.ecx.tcx).is_none() {
288+
throw_validation_failure!(
289+
"too large slice (longer than isize::MAX bytes)",
290+
self.path
291+
);
292+
}
281293
}
282294
ty::Foreign(..) => {
283295
// Unsized, but not wide.

src/test/ui/consts/const-eval/ub-wide-ptr.rs

+2
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,8 @@ const I3: &MySliceBool = &MySlice(true, [unsafe { BoolTransmute { val: 3 }.bl }]
126126
// # raw slice
127127
const RAW_SLICE_VALID: *const [u8] = unsafe { SliceTransmute { repr: SliceRepr { ptr: &42, len: 1 } }.raw_slice}; // ok
128128
const RAW_SLICE_TOO_LONG: *const [u8] = unsafe { SliceTransmute { repr: SliceRepr { ptr: &42, len: 999 } }.raw_slice}; // ok because raw
129+
const RAW_SLICE_MUCH_TOO_LONG: *const [u8] = unsafe { SliceTransmute { repr: SliceRepr { ptr: &42, len: usize::max_value() } }.raw_slice};
130+
//~^ ERROR it is undefined behavior to use this value
129131
const RAW_SLICE_LENGTH_UNINIT: *const [u8] = unsafe { SliceTransmute { addr: 42 }.raw_slice};
130132
//~^ ERROR it is undefined behavior to use this value
131133

src/test/ui/consts/const-eval/ub-wide-ptr.stderr

+15-7
Original file line numberDiff line numberDiff line change
@@ -89,59 +89,67 @@ LL | const I3: &MySliceBool = &MySlice(true, [unsafe { BoolTransmute { val: 3 }.
8989
error[E0080]: it is undefined behavior to use this value
9090
--> $DIR/ub-wide-ptr.rs:129:1
9191
|
92+
LL | const RAW_SLICE_MUCH_TOO_LONG: *const [u8] = unsafe { SliceTransmute { repr: SliceRepr { ptr: &42, len: usize::max_value() } }.raw_slice};
93+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered too large slice (longer than isize::MAX bytes)
94+
|
95+
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
96+
97+
error[E0080]: it is undefined behavior to use this value
98+
--> $DIR/ub-wide-ptr.rs:131:1
99+
|
92100
LL | const RAW_SLICE_LENGTH_UNINIT: *const [u8] = unsafe { SliceTransmute { addr: 42 }.raw_slice};
93101
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered uninitialized data in wide pointer metadata
94102
|
95103
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
96104

97105
error[E0080]: it is undefined behavior to use this value
98-
--> $DIR/ub-wide-ptr.rs:134:1
106+
--> $DIR/ub-wide-ptr.rs:136:1
99107
|
100108
LL | const D: &dyn Trait = unsafe { DynTransmute { repr: DynRepr { ptr: &92, vtable: &3 } }.rust};
101109
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered dangling or unaligned vtable pointer in wide pointer or too small vtable
102110
|
103111
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
104112

105113
error[E0080]: it is undefined behavior to use this value
106-
--> $DIR/ub-wide-ptr.rs:137:1
114+
--> $DIR/ub-wide-ptr.rs:139:1
107115
|
108116
LL | const E: &dyn Trait = unsafe { DynTransmute { repr2: DynRepr2 { ptr: &92, vtable: &3 } }.rust};
109117
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered dangling or unaligned vtable pointer in wide pointer or too small vtable
110118
|
111119
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
112120

113121
error[E0080]: it is undefined behavior to use this value
114-
--> $DIR/ub-wide-ptr.rs:140:1
122+
--> $DIR/ub-wide-ptr.rs:142:1
115123
|
116124
LL | const F: &dyn Trait = unsafe { DynTransmute { bad: BadDynRepr { ptr: &92, vtable: 3 } }.rust};
117125
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered dangling or unaligned vtable pointer in wide pointer or too small vtable
118126
|
119127
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
120128

121129
error[E0080]: it is undefined behavior to use this value
122-
--> $DIR/ub-wide-ptr.rs:144:1
130+
--> $DIR/ub-wide-ptr.rs:146:1
123131
|
124132
LL | const G: &dyn Trait = &unsafe { BoolTransmute { val: 3 }.bl };
125133
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 3 at .<deref>.<dyn-downcast>, but expected something less or equal to 1
126134
|
127135
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
128136

129137
error[E0080]: it is undefined behavior to use this value
130-
--> $DIR/ub-wide-ptr.rs:148:1
138+
--> $DIR/ub-wide-ptr.rs:150:1
131139
|
132140
LL | const RAW_TRAIT_OBJ_VTABLE_NULL: *const dyn Trait = unsafe { DynTransmute { bad: BadDynRepr { ptr: &92, vtable: 0 } }.rust};
133141
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered dangling or unaligned vtable pointer in wide pointer or too small vtable
134142
|
135143
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
136144

137145
error[E0080]: it is undefined behavior to use this value
138-
--> $DIR/ub-wide-ptr.rs:150:1
146+
--> $DIR/ub-wide-ptr.rs:152:1
139147
|
140148
LL | const RAW_TRAIT_OBJ_VTABLE_INVALID: *const dyn Trait = unsafe { DynTransmute { repr2: DynRepr2 { ptr: &92, vtable: &3 } }.raw_rust};
141149
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered dangling or unaligned vtable pointer in wide pointer or too small vtable
142150
|
143151
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
144152

145-
error: aborting due to 18 previous errors
153+
error: aborting due to 19 previous errors
146154

147155
For more information about this error, try `rustc --explain E0080`.

0 commit comments

Comments
 (0)