Skip to content

Commit a95f754

Browse files
committed
better error when reading from stdin
1 parent f280e7e commit a95f754

File tree

2 files changed

+29
-19
lines changed

2 files changed

+29
-19
lines changed

src/shims/foreign_items/posix.rs

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -62,20 +62,31 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
6262
}
6363
"read" => {
6464
let &[fd, buf, count] = check_arg_count(args)?;
65-
let result = this.read(fd, buf, count)?;
65+
let fd = this.read_scalar(fd)?.to_i32()?;
66+
let buf = this.read_scalar(buf)?.not_undef()?;
67+
let count = this.read_scalar(count)?.to_machine_usize(this)?;
68+
let result = if fd == 0 {
69+
throw_unsup_format!("reading from stdin is not implemented")
70+
} else if fd == 1 || fd == 2 {
71+
throw_unsup_format!("cannot read from stdout/stderr")
72+
} else {
73+
this.read(fd, buf, count)?
74+
};
6675
this.write_scalar(Scalar::from_machine_isize(result, this), dest)?;
6776
}
6877
"write" => {
6978
let &[fd, buf, n] = check_arg_count(args)?;
7079
let fd = this.read_scalar(fd)?.to_i32()?;
7180
let buf = this.read_scalar(buf)?.not_undef()?;
72-
let n = this.read_scalar(n)?.to_machine_usize(this)?;
73-
trace!("Called write({:?}, {:?}, {:?})", fd, buf, n);
74-
let result = if fd == 1 || fd == 2 {
81+
let count = this.read_scalar(n)?.to_machine_usize(this)?;
82+
trace!("Called write({:?}, {:?}, {:?})", fd, buf, count);
83+
let result = if fd == 0 {
84+
throw_unsup_format!("cannot write to stdin")
85+
} else if fd == 1 || fd == 2 {
7586
// stdout/stderr
7687
use std::io::{self, Write};
7788

78-
let buf_cont = this.memory.read_bytes(buf, Size::from_bytes(n))?;
89+
let buf_cont = this.memory.read_bytes(buf, Size::from_bytes(count))?;
7990
// We need to flush to make sure this actually appears on the screen
8091
let res = if fd == 1 {
8192
// Stdout is buffered, flush to make sure it appears on the screen.
@@ -94,7 +105,6 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
94105
Err(_) => -1,
95106
}
96107
} else {
97-
let &[fd, buf, count] = check_arg_count(args)?;
98108
this.write(fd, buf, count)?
99109
};
100110
// Now, `result` is the value we return back to the program.

src/shims/fs.rs

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ use std::io::{Read, Seek, SeekFrom, Write};
55
use std::path::Path;
66
use std::time::SystemTime;
77

8+
use log::trace;
9+
810
use rustc_data_structures::fx::FxHashMap;
911
use rustc_target::abi::{Align, LayoutOf, Size};
1012

@@ -413,17 +415,16 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
413415

414416
fn read(
415417
&mut self,
416-
fd_op: OpTy<'tcx, Tag>,
417-
buf_op: OpTy<'tcx, Tag>,
418-
count_op: OpTy<'tcx, Tag>,
418+
fd: i32,
419+
buf: Scalar<Tag>,
420+
count: u64,
419421
) -> InterpResult<'tcx, i64> {
420422
let this = self.eval_context_mut();
421423

422424
this.check_no_isolation("read")?;
425+
assert!(fd >= 3);
423426

424-
let fd = this.read_scalar(fd_op)?.to_i32()?;
425-
let buf = this.read_scalar(buf_op)?.not_undef()?;
426-
let count = this.read_scalar(count_op)?.to_machine_usize(&*this.tcx)?;
427+
trace!("Reading from FD {}, size {}", fd, count);
427428

428429
// Check that the *entire* buffer is actually valid memory.
429430
this.memory.check_ptr_access(
@@ -437,6 +438,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
437438
let count = count.min(this.machine_isize_max() as u64).min(isize::MAX as u64);
438439

439440
if let Some(FileHandle { file, writable: _ }) = this.machine.file_handler.handles.get_mut(&fd) {
441+
trace!("read: FD mapped to {:?}", file);
440442
// This can never fail because `count` was capped to be smaller than
441443
// `isize::MAX`.
442444
let count = isize::try_from(count).unwrap();
@@ -461,23 +463,21 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
461463
}
462464
}
463465
} else {
466+
trace!("read: FD not found");
464467
this.handle_not_found()
465468
}
466469
}
467470

468471
fn write(
469472
&mut self,
470-
fd_op: OpTy<'tcx, Tag>,
471-
buf_op: OpTy<'tcx, Tag>,
472-
count_op: OpTy<'tcx, Tag>,
473+
fd: i32,
474+
buf: Scalar<Tag>,
475+
count: u64,
473476
) -> InterpResult<'tcx, i64> {
474477
let this = self.eval_context_mut();
475478

476479
this.check_no_isolation("write")?;
477-
478-
let fd = this.read_scalar(fd_op)?.to_i32()?;
479-
let buf = this.read_scalar(buf_op)?.not_undef()?;
480-
let count = this.read_scalar(count_op)?.to_machine_usize(&*this.tcx)?;
480+
assert!(fd >= 3);
481481

482482
// Check that the *entire* buffer is actually valid memory.
483483
this.memory.check_ptr_access(

0 commit comments

Comments
 (0)