Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add OsString from/to bytes helper functions #993

Merged
merged 12 commits into from
Oct 23, 2019
Prev Previous commit
Next Next commit
Make size error distinguishable from other errors
pvdrz committed Oct 22, 2019
commit fb4cb5bf4af633ca057a84b995bab3b08333df41
17 changes: 13 additions & 4 deletions src/helpers.rs
Original file line number Diff line number Diff line change
@@ -412,16 +412,25 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
}

/// Helper function to write an OsStr as a null-terminated sequence of bytes, which is what
/// the Unix APIs usually handle.
fn write_os_str_to_c_string(&mut self, os_str: &OsStr, scalar: Scalar<Tag>, size: u64) -> InterpResult<'tcx> {
/// the Unix APIs usually handle. This function returns `Ok(false)` without trying to write if
/// `size` is not large enough to fit the contents of `os_string` plus a null terminator. It
/// returns `Ok(true)` if the writing process was successful. Otherwise it returns an
/// `InterpError`.
fn write_os_str_to_c_string(
&mut self,
os_str: &OsStr,
scalar: Scalar<Tag>,
size: u64
) -> InterpResult<'tcx, bool> {
let bytes = os_str_to_bytes(os_str)?;
// If `size` is smaller or equal than `bytes.len()`, writing `bytes` plus the required null
// terminator to memory using the `ptr` pointer would cause an overflow.
if size <= bytes.len() as u64 {
throw_unsup_format!("OsString of length {} is too large for destination buffer of size {}", bytes.len(), size)
return Ok(false);
}
// FIXME: We should use `Iterator::chain` instead when rust-lang/rust#65704 lands.
self.eval_context_mut().memory.write_bytes(scalar, [bytes, &[0]].concat())
self.eval_context_mut().memory.write_bytes(scalar, [bytes, &[0]].concat())?;
Ok(true)
}
}

2 changes: 1 addition & 1 deletion src/shims/env.rs
Original file line number Diff line number Diff line change
@@ -128,7 +128,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
// If we cannot get the current directory, we return null
match env::current_dir() {
Ok(cwd) => {
if this.write_os_str_to_c_string(&OsString::from(cwd), buf, size).is_ok() {
if this.write_os_str_to_c_string(&OsString::from(cwd), buf, size)? {
return Ok(buf);
}
let erange = this.eval_libc("ERANGE")?;