Skip to content

Commit 8b6af3e

Browse files
committed
avoid using unchecked casts or arithmetic
1 parent 9082cc4 commit 8b6af3e

File tree

14 files changed

+71
-61
lines changed

14 files changed

+71
-61
lines changed

src/bin/miri.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -259,7 +259,6 @@ fn main() {
259259
rustc_driver::install_ice_hook();
260260
let result = rustc_driver::catch_fatal_errors(move || {
261261
rustc_driver::run_compiler(&rustc_args, &mut MiriCompilerCalls { miri_config }, None, None)
262-
})
263-
.and_then(|result| result);
262+
});
264263
std::process::exit(result.is_err() as i32);
265264
}

src/eval.rs

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
//! Main evaluator loop and setting up the initial stack frame.
22
33
use std::ffi::OsStr;
4+
use std::convert::TryFrom;
45

56
use rand::rngs::StdRng;
67
use rand::SeedableRng;
@@ -101,25 +102,25 @@ pub fn create_ecx<'mir, 'tcx: 'mir>(
101102
// First argument: pointer to `main()`.
102103
let main_ptr = ecx.memory.create_fn_alloc(FnVal::Instance(main_instance));
103104
// Second argument (argc): length of `config.args`.
104-
let argc = Scalar::from_uint(config.args.len() as u128, ecx.pointer_size());
105+
let argc = Scalar::from_uint(u64::try_from(config.args.len()).unwrap(), ecx.pointer_size());
105106
// Third argument (`argv`): created from `config.args`.
106107
let argv = {
107108
// Put each argument in memory, collect pointers.
108109
let mut argvs = Vec::<Scalar<Tag>>::new();
109110
for arg in config.args.iter() {
110111
// Make space for `0` terminator.
111-
let size = arg.len() as u64 + 1;
112+
let size = u64::try_from(arg.len()).unwrap().checked_add(1).unwrap();
112113
let arg_type = tcx.mk_array(tcx.types.u8, size);
113114
let arg_place = ecx.allocate(ecx.layout_of(arg_type)?, MiriMemoryKind::Machine.into());
114115
ecx.write_os_str_to_c_str(OsStr::new(arg), arg_place.ptr, size)?;
115116
argvs.push(arg_place.ptr);
116117
}
117118
// Make an array with all these pointers, in the Miri memory.
118119
let argvs_layout =
119-
ecx.layout_of(tcx.mk_array(tcx.mk_imm_ptr(tcx.types.u8), argvs.len() as u64))?;
120+
ecx.layout_of(tcx.mk_array(tcx.mk_imm_ptr(tcx.types.u8), u64::try_from(argvs.len()).unwrap()))?;
120121
let argvs_place = ecx.allocate(argvs_layout, MiriMemoryKind::Machine.into());
121122
for (idx, arg) in argvs.into_iter().enumerate() {
122-
let place = ecx.mplace_field(argvs_place, idx as u64)?;
123+
let place = ecx.mplace_field(argvs_place, u64::try_from(idx).unwrap())?;
123124
ecx.write_scalar(arg, place.into())?;
124125
}
125126
ecx.memory.mark_immutable(argvs_place.ptr.assert_ptr().alloc_id)?;
@@ -153,13 +154,13 @@ pub fn create_ecx<'mir, 'tcx: 'mir>(
153154
cmd.push(std::char::from_u32(0).unwrap());
154155

155156
let cmd_utf16: Vec<u16> = cmd.encode_utf16().collect();
156-
let cmd_type = tcx.mk_array(tcx.types.u16, cmd_utf16.len() as u64);
157+
let cmd_type = tcx.mk_array(tcx.types.u16, u64::try_from(cmd_utf16.len()).unwrap());
157158
let cmd_place = ecx.allocate(ecx.layout_of(cmd_type)?, MiriMemoryKind::Machine.into());
158159
ecx.machine.cmd_line = Some(cmd_place.ptr);
159160
// Store the UTF-16 string. We just allocated so we know the bounds are fine.
160161
let char_size = Size::from_bytes(2);
161162
for (idx, &c) in cmd_utf16.iter().enumerate() {
162-
let place = ecx.mplace_field(cmd_place, idx as u64)?;
163+
let place = ecx.mplace_field(cmd_place, u64::try_from(idx).unwrap())?;
163164
ecx.write_scalar(Scalar::from_uint(c, char_size), place.into())?;
164165
}
165166
}

src/helpers.rs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use std::ffi::OsStr;
22
use std::{iter, mem};
3+
use std::convert::TryFrom;
34

45
use rustc::mir;
56
use rustc::ty::{
@@ -81,7 +82,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
8182
}
8283

8384
/// Generate some random bytes, and write them to `dest`.
84-
fn gen_random(&mut self, ptr: Scalar<Tag>, len: usize) -> InterpResult<'tcx> {
85+
fn gen_random(&mut self, ptr: Scalar<Tag>, len: u64) -> InterpResult<'tcx> {
8586
// Some programs pass in a null pointer and a length of 0
8687
// to their platform's random-generation function (e.g. getrandom())
8788
// on Linux. For compatibility with these programs, we don't perform
@@ -92,7 +93,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
9293
}
9394
let this = self.eval_context_mut();
9495

95-
let mut data = vec![0; len];
96+
let mut data = vec![0; usize::try_from(len).unwrap()];
9697

9798
if this.machine.communicate {
9899
// Fill the buffer using the host's rng.
@@ -499,7 +500,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
499500
let bytes = os_str_to_bytes(os_str)?;
500501
// If `size` is smaller or equal than `bytes.len()`, writing `bytes` plus the required null
501502
// terminator to memory using the `ptr` pointer would cause an out-of-bounds access.
502-
let string_length = bytes.len() as u64;
503+
let string_length = u64::try_from(bytes.len()).unwrap();
503504
if size <= string_length {
504505
return Ok((false, string_length));
505506
}
@@ -514,7 +515,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
514515
os_str: &OsStr,
515516
memkind: MemoryKind<MiriMemoryKind>,
516517
) -> Pointer<Tag> {
517-
let size = os_str.len() as u64 + 1; // Make space for `0` terminator.
518+
let size = u64::try_from(os_str.len()).unwrap().checked_add(1).unwrap(); // Make space for `0` terminator.
518519
let this = self.eval_context_mut();
519520

520521
let arg_type = this.tcx.mk_array(this.tcx.types.u8, size);

src/shims/dlsym.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
3737
GetEntropy => {
3838
let ptr = this.read_scalar(args[0])?.not_undef()?;
3939
let len = this.read_scalar(args[1])?.to_machine_usize(this)?;
40-
this.gen_random(ptr, len as usize)?;
40+
this.gen_random(ptr, len)?;
4141
this.write_null(dest)?;
4242
}
4343
}

src/shims/env.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use std::ffi::{OsString, OsStr};
22
use std::env;
3+
use std::convert::TryFrom;
34

45
use crate::stacked_borrows::Tag;
56
use crate::rustc_target::abi::LayoutOf;
@@ -58,7 +59,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
5859
Ok(match this.machine.env_vars.map.get(name) {
5960
// The offset is used to strip the "{name}=" part of the string.
6061
Some(var_ptr) => {
61-
Scalar::from(var_ptr.offset(Size::from_bytes(name.len() as u64 + 1), this)?)
62+
Scalar::from(var_ptr.offset(Size::from_bytes(u64::try_from(name.len()).unwrap().checked_add(1).unwrap()), this)?)
6263
}
6364
None => Scalar::ptr_null(&*this.tcx),
6465
})
@@ -181,10 +182,10 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
181182
// Make an array with all these pointers inside Miri.
182183
let tcx = this.tcx;
183184
let vars_layout =
184-
this.layout_of(tcx.mk_array(tcx.types.usize, vars.len() as u64))?;
185+
this.layout_of(tcx.mk_array(tcx.types.usize, u64::try_from(vars.len()).unwrap()))?;
185186
let vars_place = this.allocate(vars_layout, MiriMemoryKind::Machine.into());
186187
for (idx, var) in vars.into_iter().enumerate() {
187-
let place = this.mplace_field(vars_place, idx as u64)?;
188+
let place = this.mplace_field(vars_place, u64::try_from(idx).unwrap())?;
188189
this.write_scalar(var, place.into())?;
189190
}
190191
this.write_scalar(

src/shims/foreign_items.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
mod windows;
22
mod posix;
33

4-
use std::{convert::TryInto, iter};
4+
use std::{convert::{TryInto, TryFrom}, iter};
55

66
use rustc_hir::def_id::DefId;
77
use rustc::mir;
@@ -250,7 +250,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
250250
MiriMemoryKind::Rust.into(),
251251
);
252252
// We just allocated this, the access is definitely in-bounds.
253-
this.memory.write_bytes(ptr.into(), iter::repeat(0u8).take(size as usize)).unwrap();
253+
this.memory.write_bytes(ptr.into(), iter::repeat(0u8).take(usize::try_from(size).unwrap())).unwrap();
254254
this.write_scalar(ptr, dest)?;
255255
}
256256
"__rust_dealloc" => {
@@ -350,7 +350,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
350350
"strlen" => {
351351
let ptr = this.read_scalar(args[0])?.not_undef()?;
352352
let n = this.memory.read_c_str(ptr)?.len();
353-
this.write_scalar(Scalar::from_uint(n as u64, dest.layout.size), dest)?;
353+
this.write_scalar(Scalar::from_uint(u64::try_from(n).unwrap(), dest.layout.size), dest)?;
354354
}
355355

356356
// math functions
@@ -440,9 +440,9 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
440440

441441
// Saturating cast to i16. Even those are outside the valid exponent range to
442442
// `scalbn` below will do its over/underflow handling.
443-
let exp = if exp > i16::MAX as i32 {
443+
let exp = if exp > i32::from(i16::MAX) {
444444
i16::MAX
445-
} else if exp < i16::MIN as i32 {
445+
} else if exp < i32::from(i16::MIN) {
446446
i16::MIN
447447
} else {
448448
exp.try_into().unwrap()

src/shims/foreign_items/posix.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
mod linux;
22
mod macos;
33

4+
use std::convert::TryFrom;
5+
46
use crate::*;
57
use rustc::mir;
68
use rustc::ty::layout::{Align, LayoutOf, Size};
@@ -84,7 +86,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
8486
io::stderr().write(buf_cont)
8587
};
8688
match res {
87-
Ok(n) => n as i64,
89+
Ok(n) => i64::try_from(n).unwrap(),
8890
Err(_) => -1,
8991
}
9092
} else {

src/shims/foreign_items/posix/linux.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ fn getrandom<'tcx>(
114114
// neither of which have any effect on our current PRNG.
115115
let _flags = this.read_scalar(args[2])?.to_i32()?;
116116

117-
this.gen_random(ptr, len as usize)?;
117+
this.gen_random(ptr, len)?;
118118
this.write_scalar(Scalar::from_uint(len, dest.layout.size), dest)?;
119119
Ok(())
120120
}

src/shims/foreign_items/posix/macos.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
9797
"SecRandomCopyBytes" => {
9898
let len = this.read_scalar(args[1])?.to_machine_usize(this)?;
9999
let ptr = this.read_scalar(args[2])?.not_undef()?;
100-
this.gen_random(ptr, len as usize)?;
100+
this.gen_random(ptr, len)?;
101101
this.write_null(dest)?;
102102
}
103103

src/shims/foreign_items/windows.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -165,12 +165,12 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
165165
this.write_scalar(Scalar::from_uint(key, dest.layout.size), dest)?;
166166
}
167167
"TlsGetValue" => {
168-
let key = this.read_scalar(args[0])?.to_u32()? as u128;
168+
let key = u128::from(this.read_scalar(args[0])?.to_u32()?);
169169
let ptr = this.machine.tls.load_tls(key, tcx)?;
170170
this.write_scalar(ptr, dest)?;
171171
}
172172
"TlsSetValue" => {
173-
let key = this.read_scalar(args[0])?.to_u32()? as u128;
173+
let key = u128::from(this.read_scalar(args[0])?.to_u32()?);
174174
let new_ptr = this.read_scalar(args[1])?.not_undef()?;
175175
this.machine.tls.store_tls(key, this.test_null(new_ptr)?)?;
176176

@@ -197,7 +197,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
197197
"SystemFunction036" => {
198198
let ptr = this.read_scalar(args[0])?.not_undef()?;
199199
let len = this.read_scalar(args[1])?.to_u32()?;
200-
this.gen_random(ptr, len as usize)?;
200+
this.gen_random(ptr, len.into())?;
201201
this.write_scalar(Scalar::from_bool(true), dest)?;
202202
}
203203
// We don't support threading.

0 commit comments

Comments
 (0)