Skip to content

Commit 462f582

Browse files
committed
Make helper functions freestanding
1 parent 5fc5490 commit 462f582

File tree

2 files changed

+31
-30
lines changed

2 files changed

+31
-30
lines changed

src/shims/os_str.rs

Lines changed: 30 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -60,20 +60,36 @@ fn convert_path_separator<'a>(
6060
};
6161
}
6262

63+
#[cfg(unix)]
64+
pub fn os_str_to_bytes<'a, 'tcx>(os_str: &'a OsStr) -> InterpResult<'tcx, &'a [u8]> {
65+
Ok(os_str.as_bytes())
66+
}
67+
68+
#[cfg(not(unix))]
69+
pub fn os_str_to_bytes<'a, 'tcx>(os_str: &'a OsStr) -> InterpResult<'tcx, &'a [u8]> {
70+
// On non-unix platforms the best we can do to transform bytes from/to OS strings is to do the
71+
// intermediate transformation into strings. Which invalidates non-utf8 paths that are actually
72+
// valid.
73+
os_str
74+
.to_str()
75+
.map(|s| s.as_bytes())
76+
.ok_or_else(|| err_unsup_format!("{:?} is not a valid utf-8 string", os_str).into())
77+
}
78+
79+
#[cfg(unix)]
80+
pub fn bytes_to_os_str<'a, 'tcx>(bytes: &'a [u8]) -> InterpResult<'tcx, &'a OsStr> {
81+
Ok(OsStr::from_bytes(bytes))
82+
}
83+
#[cfg(not(unix))]
84+
pub fn bytes_to_os_str<'a, 'tcx>(bytes: &'a [u8]) -> InterpResult<'tcx, &'a OsStr> {
85+
let s = std::str::from_utf8(bytes)
86+
.map_err(|_| err_unsup_format!("{:?} is not a valid utf-8 string", bytes))?;
87+
Ok(OsStr::new(s))
88+
}
89+
6390
impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriEvalContext<'mir, 'tcx> {}
6491
pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx> {
6592

66-
#[cfg(unix)]
67-
fn bytes_to_os_str<'a>(&self, bytes: &'a [u8]) -> InterpResult<'tcx, &'a OsStr> {
68-
Ok(OsStr::from_bytes(bytes))
69-
}
70-
#[cfg(not(unix))]
71-
fn bytes_to_os_str<'a>(&self, bytes: &'a [u8]) -> InterpResult<'tcx, &'a OsStr> {
72-
let s = std::str::from_utf8(bytes)
73-
.map_err(|_| err_unsup_format!("{:?} is not a valid utf-8 string", bytes))?;
74-
Ok(OsStr::new(s))
75-
}
76-
7793
/// Helper function to read an OsString from a null-terminated sequence of bytes, which is what
7894
/// the Unix APIs usually handle.
7995
fn read_os_str_from_c_str<'a>(&'a self, scalar: Scalar<Tag>) -> InterpResult<'tcx, &'a OsStr>
@@ -83,7 +99,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
8399
{
84100
let this = self.eval_context_ref();
85101
let bytes = this.memory.read_c_str(scalar)?;
86-
self.bytes_to_os_str(bytes)
102+
bytes_to_os_str(bytes)
87103
}
88104

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

111-
#[cfg(unix)]
112-
fn os_str_to_bytes<'a>(&self, os_str: &'a OsStr) -> InterpResult<'tcx, &'a [u8]> {
113-
Ok(os_str.as_bytes())
114-
}
115-
116-
#[cfg(not(unix))]
117-
fn os_str_to_bytes<'a>(&self, os_str: &'a OsStr) -> InterpResult<'tcx, &'a [u8]> {
118-
// On non-unix platforms the best we can do to transform bytes from/to OS strings is to do the
119-
// intermediate transformation into strings. Which invalidates non-utf8 paths that are actually
120-
// valid.
121-
os_str
122-
.to_str()
123-
.map(|s| s.as_bytes())
124-
.ok_or_else(|| err_unsup_format!("{:?} is not a valid utf-8 string", os_str).into())
125-
}
126-
127127
/// Helper function to write an OsStr as a null-terminated sequence of bytes, which is what
128128
/// the Unix APIs usually handle. This function returns `Ok((false, length))` without trying
129129
/// to write if `size` is not large enough to fit the contents of `os_string` plus a null
@@ -136,7 +136,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
136136
size: u64,
137137
) -> InterpResult<'tcx, (bool, u64)> {
138138

139-
let bytes = self.os_str_to_bytes(os_str)?;
139+
let bytes = os_str_to_bytes(os_str)?;
140140
// If `size` is smaller or equal than `bytes.len()`, writing `bytes` plus the required null
141141
// terminator to memory using the `ptr` pointer would cause an out-of-bounds access.
142142
let string_length = u64::try_from(bytes.len()).unwrap();
@@ -269,3 +269,4 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
269269
this.write_os_str_to_wide_str(&os_str, scalar, size)
270270
}
271271
}
272+

src/shims/posix/fs.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1371,7 +1371,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
13711371
let result = std::fs::read_link(pathname);
13721372
match result {
13731373
Ok(resolved) => {
1374-
let mut path_bytes = this.os_str_to_bytes(resolved.as_ref())?;
1374+
let mut path_bytes = crate::shims::os_str::os_str_to_bytes(resolved.as_ref())?;
13751375
let bufsize: usize = bufsize.try_into().unwrap();
13761376
if path_bytes.len() > bufsize {
13771377
path_bytes = &path_bytes[..bufsize]

0 commit comments

Comments
 (0)