Make size error distinguishable from other errors

This commit is contained in:
Christian Poveda 2019-10-22 16:57:07 -05:00
parent be415dbeda
commit fb4cb5bf4a
2 changed files with 14 additions and 5 deletions

View file

@ -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)
}
}

View file

@ -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")?;