Skip to content

Commit 8ddebb0

Browse files
committed
Change helper functions to read/write
1 parent 25ed2b6 commit 8ddebb0

File tree

3 files changed

+30
-29
lines changed

3 files changed

+30
-29
lines changed

src/helpers.rs

Lines changed: 26 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -305,10 +305,9 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
305305
fn eval_libc_i32(&mut self, name: &str) -> InterpResult<'tcx, i32> {
306306
self.eval_libc(name)?.to_i32()
307307
}
308-
}
309-
310308

311-
pub fn bytes_to_os_string<'tcx>(bytes: Vec<u8>) -> InterpResult<'tcx, OsString> {
309+
fn read_os_string(&mut self, scalar: Scalar<Tag>) -> InterpResult<'tcx, OsString> {
310+
let bytes = self.eval_context_mut().memory().read_c_str(scalar)?.to_vec();
312311
if cfg!(unix) {
313312
Ok(std::os::unix::ffi::OsStringExt::from_vec(bytes))
314313
} else {
@@ -318,13 +317,32 @@ pub fn bytes_to_os_string<'tcx>(bytes: Vec<u8>) -> InterpResult<'tcx, OsString>
318317
}
319318
}
320319

321-
pub fn os_string_to_bytes<'tcx>(os_string: OsString) -> InterpResult<'tcx, Vec<u8>> {
322-
if cfg!(unix) {
323-
Ok(std::os::unix::ffi::OsStringExt::into_vec(os_string))
320+
fn write_os_string(&mut self, os_string: OsString, ptr: Pointer<Tag>, size: u64) -> InterpResult<'tcx> {
321+
let mut bytes = if cfg!(unix) {
322+
std::os::unix::ffi::OsStringExt::into_vec(os_string)
324323
} else {
325324
os_string
326325
.into_string()
327-
.map_err(|os_string| err_unsup_format!("{:?} is not a valid utf-8 string", os_string).into())
328-
.map(|s| s.into_bytes())
326+
.map_err(|os_string| err_unsup_format!("{:?} is not a valid utf-8 string", os_string))?
327+
.into_bytes()
328+
};
329+
// If `size` is smaller or equal than `bytes.len()`, writing `bytes` plus the required null
330+
// terminator to memory using the `ptr` pointer would cause an overflow.
331+
if (bytes.len() as u64) < size {
332+
// We add a `/0` terminator
333+
bytes.push(0);
334+
let this = self.eval_context_mut();
335+
let tcx = &{ this.tcx.tcx };
336+
// This is ok because the buffer was strictly larger than `bytes`, so after adding the
337+
// null terminator, the buffer size is larger or equal to `bytes.len()`, meaning that
338+
// `bytes` actually fit inside tbe buffer.
339+
this.memory_mut()
340+
.get_mut(ptr.alloc_id)?
341+
.write_bytes(tcx, ptr, &bytes)
342+
} else {
343+
throw_unsup_format!("OsString is larger than destination")
329344
}
330345
}
346+
}
347+
348+

src/shims/env.rs

Lines changed: 3 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -131,20 +131,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
131131
// If we cannot get the current directory, we return null
132132
match env::current_dir() {
133133
Ok(cwd) => {
134-
// It is not clear what happens with non-utf8 paths here
135-
let mut bytes = helpers::os_string_to_bytes(cwd.into())?;
136-
// If `size` is smaller or equal than the `bytes.len()`, writing `bytes` plus the
137-
// required null terminator to memory using the `buf` pointer would cause an
138-
// overflow. The desired behavior in this case is to return null.
139-
if (bytes.len() as u64) < size {
140-
// We add a `/0` terminator
141-
bytes.push(0);
142-
// This is ok because the buffer was strictly larger than `bytes`, so after
143-
// adding the null terminator, the buffer size is larger or equal to
144-
// `bytes.len()`, meaning that `bytes` actually fit inside tbe buffer.
145-
this.memory_mut()
146-
.get_mut(buf.alloc_id)?
147-
.write_bytes(tcx, buf, &bytes)?;
134+
if this.write_os_string(cwd.into(), buf, size).is_ok() {
148135
return Ok(Scalar::Ptr(buf));
149136
}
150137
let erange = this.eval_libc("ERANGE")?;
@@ -162,10 +149,9 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
162149
throw_unsup_format!("`chdir` not available when isolation is enabled")
163150
}
164151

165-
let bytes = this.memory().read_c_str(this.read_scalar(path_op)?.not_undef()?)?;
166-
let path = helpers::bytes_to_os_string(bytes.to_vec());
152+
let path = this.read_os_string(this.read_scalar(path_op)?.not_undef()?)?;
167153

168-
match env::set_current_dir(path?) {
154+
match env::set_current_dir(path) {
169155
Ok(()) => Ok(0),
170156
Err(e) => {
171157
this.consume_io_error(e)?;

src/shims/fs.rs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -67,10 +67,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
6767
options.create(true);
6868
}
6969

70-
let bytes = this
71-
.memory()
72-
.read_c_str(this.read_scalar(path_op)?.not_undef()?)?;
73-
let path: std::path::PathBuf = helpers::bytes_to_os_string(bytes.to_vec())?.into();
70+
let path: std::path::PathBuf = this.read_os_string(this.read_scalar(path_op)?.not_undef()?)?.into();
7471

7572
let fd = options.open(path).map(|file| {
7673
let mut fh = &mut this.machine.file_handler;

0 commit comments

Comments
 (0)