Skip to content

Commit 56c5e53

Browse files
committed
Handle host's usize correctly
1 parent d0b4407 commit 56c5e53

File tree

2 files changed

+38
-14
lines changed

2 files changed

+38
-14
lines changed

src/helpers.rs

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

45
use rustc::hir::def_id::{DefId, CRATE_DEF_INDEX};
56
use rustc::mir;
@@ -459,3 +460,16 @@ fn bytes_to_os_str<'tcx, 'a>(bytes: &'a[u8]) -> InterpResult<'tcx, &'a OsStr> {
459460
.map_err(|_| err_unsup_format!("{:?} is not a valid utf-8 string", bytes))?;
460461
Ok(&OsStr::new(s))
461462
}
463+
464+
pub fn try_into_host_usize(i: impl Into<u128>) -> Option<usize> {
465+
let i: u128 = i.into();
466+
if i > usize::max_value() as u128 {
467+
None
468+
} else {
469+
Some(i as usize)
470+
}
471+
}
472+
473+
pub fn try_from_host_usize<T: TryFrom<u128>>(i: usize) -> Option<T> {
474+
T::try_from(i as u128).ok()
475+
}

src/shims/fs.rs

Lines changed: 24 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -178,16 +178,21 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
178178
let mut bytes = vec![0; count as usize];
179179
let result = handle.file.read(&mut bytes);
180180

181-
if let Ok(c) = result {
182-
// Check that we read less than `i64::MAX` bytes.
183-
if (c as u64) > (i64::max_value() as u64) {
184-
throw_unsup_format!("Number of read bytes {} is larger than the maximum value", c);
181+
match result {
182+
Ok(c) => {
183+
if let Some(read_bytes) = helpers::try_from_host_usize::<i64>(c) {
184+
// If reading to `bytes` did not fail, we write those bytes to the buffer.
185+
this.memory.write_bytes(buf, bytes)?;
186+
Ok(read_bytes)
187+
} else {
188+
throw_unsup_format!("Number of read bytes {} cannot be transformed to i64", c);
189+
}
190+
},
191+
Err(e) => {
192+
this.set_last_error_from_io_error(e)?;
193+
Ok(-1)
185194
}
186-
// If reading to `bytes` did not fail, we write those bytes to the buffer.
187-
this.memory.write_bytes(buf, bytes)?
188195
}
189-
190-
this.try_unwrap_io_result(result.map(|c| c as i64))
191196
} else {
192197
this.handle_not_found()
193198
}
@@ -215,14 +220,19 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
215220
let bytes = this.memory.read_bytes(buf, Size::from_bytes(count))?;
216221
let result = handle.file.write(&bytes);
217222

218-
if let Ok(c) = result {
219-
// Check that we wrote less than `i64::MAX` bytes.
220-
if (c as u64) > (i64::max_value() as u64) {
221-
throw_unsup_format!("Number of written bytes {} is larger than the maximum value", c);
223+
match result {
224+
Ok(c) => {
225+
if let Some(written_bytes) = helpers::try_from_host_usize::<i64>(c) {
226+
Ok(written_bytes)
227+
} else {
228+
throw_unsup_format!("Number of written bytes {} cannot be transformed to i64", c);
229+
}
230+
},
231+
Err(e) => {
232+
this.set_last_error_from_io_error(e)?;
233+
Ok(-1)
222234
}
223235
}
224-
225-
this.try_unwrap_io_result(result.map(|c| c as i64))
226236
} else {
227237
this.handle_not_found()
228238
}

0 commit comments

Comments
 (0)