Skip to content

Commit

Permalink
Make helper functions freestanding
Browse files Browse the repository at this point in the history
  • Loading branch information
Aaron1011 committed Oct 4, 2020
1 parent baea138 commit e0ca8c4
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 30 deletions.
59 changes: 30 additions & 29 deletions src/shims/os_str.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,20 +60,36 @@ fn convert_path_separator<'a>(
};
}

#[cfg(unix)]
pub fn os_str_to_bytes<'a, 'tcx>(os_str: &'a OsStr) -> InterpResult<'tcx, &'a [u8]> {
Ok(os_str.as_bytes())
}

#[cfg(not(unix))]
pub fn os_str_to_bytes<'a, 'tcx>(os_str: &'a OsStr) -> InterpResult<'tcx, &'a [u8]> {
// On non-unix platforms the best we can do to transform bytes from/to OS strings is to do the
// intermediate transformation into strings. Which invalidates non-utf8 paths that are actually
// valid.
os_str
.to_str()
.map(|s| s.as_bytes())
.ok_or_else(|| err_unsup_format!("{:?} is not a valid utf-8 string", os_str).into())
}

#[cfg(unix)]
pub fn bytes_to_os_str<'a, 'tcx>(bytes: &'a [u8]) -> InterpResult<'tcx, &'a OsStr> {
Ok(OsStr::from_bytes(bytes))
}
#[cfg(not(unix))]
pub fn bytes_to_os_str<'a, 'tcx>(bytes: &'a [u8]) -> InterpResult<'tcx, &'a OsStr> {
let s = std::str::from_utf8(bytes)
.map_err(|_| err_unsup_format!("{:?} is not a valid utf-8 string", bytes))?;
Ok(OsStr::new(s))
}

impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriEvalContext<'mir, 'tcx> {}
pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx> {

#[cfg(unix)]
fn bytes_to_os_str<'a>(&self, bytes: &'a [u8]) -> InterpResult<'tcx, &'a OsStr> {
Ok(OsStr::from_bytes(bytes))
}
#[cfg(not(unix))]
fn bytes_to_os_str<'a>(&self, bytes: &'a [u8]) -> InterpResult<'tcx, &'a OsStr> {
let s = std::str::from_utf8(bytes)
.map_err(|_| err_unsup_format!("{:?} is not a valid utf-8 string", bytes))?;
Ok(OsStr::new(s))
}

/// Helper function to read an OsString from a null-terminated sequence of bytes, which is what
/// the Unix APIs usually handle.
fn read_os_str_from_c_str<'a>(&'a self, scalar: Scalar<Tag>) -> InterpResult<'tcx, &'a OsStr>
Expand All @@ -83,7 +99,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
{
let this = self.eval_context_ref();
let bytes = this.memory.read_c_str(scalar)?;
self.bytes_to_os_str(bytes)
bytes_to_os_str(bytes)
}

/// Helper function to read an OsString from a 0x0000-terminated sequence of u16,
Expand All @@ -108,22 +124,6 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
u16vec_to_osstring(u16_vec)
}

#[cfg(unix)]
fn os_str_to_bytes<'a>(&self, os_str: &'a OsStr) -> InterpResult<'tcx, &'a [u8]> {
Ok(os_str.as_bytes())
}

#[cfg(not(unix))]
fn os_str_to_bytes<'a>(&self, os_str: &'a OsStr) -> InterpResult<'tcx, &'a [u8]> {
// On non-unix platforms the best we can do to transform bytes from/to OS strings is to do the
// intermediate transformation into strings. Which invalidates non-utf8 paths that are actually
// valid.
os_str
.to_str()
.map(|s| s.as_bytes())
.ok_or_else(|| err_unsup_format!("{:?} is not a valid utf-8 string", os_str).into())
}

/// Helper function to write an OsStr as a null-terminated sequence of bytes, which is what
/// the Unix APIs usually handle. This function returns `Ok((false, length))` without trying
/// to write if `size` is not large enough to fit the contents of `os_string` plus a null
Expand All @@ -136,7 +136,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
size: u64,
) -> InterpResult<'tcx, (bool, u64)> {

let bytes = self.os_str_to_bytes(os_str)?;
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 out-of-bounds access.
let string_length = u64::try_from(bytes.len()).unwrap();
Expand Down Expand Up @@ -269,3 +269,4 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
this.write_os_str_to_wide_str(&os_str, scalar, size)
}
}

2 changes: 1 addition & 1 deletion src/shims/posix/fs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1373,7 +1373,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
let result = std::fs::read_link(pathname);
match result {
Ok(resolved) => {
let mut path_bytes = this.os_str_to_bytes(resolved.as_ref())?;
let mut path_bytes = crate::shims::os_str::os_str_to_bytes(resolved.as_ref())?;
let bufsize: usize = bufsize.try_into().unwrap();
if path_bytes.len() > bufsize {
path_bytes = &path_bytes[..bufsize]
Expand Down

0 comments on commit e0ca8c4

Please sign in to comment.