Skip to content

Commit 0b994b2

Browse files
committed
follow-up2 to reviews from RalfJung
1 parent e06cdc7 commit 0b994b2

File tree

1 file changed

+24
-16
lines changed

1 file changed

+24
-16
lines changed

src/helpers.rs

Lines changed: 24 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -447,10 +447,12 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
447447
}
448448
}
449449

450+
/// Dispatches to appropriate implementations for reading an OsString from Memory,
451+
/// depending on the interpretation target.
450452
fn read_os_str_from_target_str<'a>(&'a self, scalar: Scalar<Tag>) -> InterpResult<'tcx, OsString> {
451453
let target_os = self.eval_context_ref().tcx.sess.target.target.target_os.as_str();
452454
match target_os {
453-
"linux" => self.read_os_str_from_c_str(scalar).map(|x| x.to_os_string()),
455+
"linux" | "macos" => self.read_os_str_from_c_str(scalar).map(|x| x.to_os_string()),
454456
"windows" => self.read_os_str_from_wide_str(scalar),
455457
_ => throw_unsup_format!("support for target OS not yet available"),
456458
}
@@ -481,11 +483,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
481483

482484
/// Helper function to read an OsString from a 0x0000-terminated sequence of u16,
483485
/// which is what the Windows APIs usually handle.
484-
fn read_os_str_from_wide_str<'a>(&'a self, scalar: Scalar<Tag>) -> InterpResult<'tcx, OsString>
485-
where
486-
'tcx: 'a,
487-
'mir: 'a,
488-
{
486+
fn read_os_str_from_wide_str<'a>(&'a self, scalar: Scalar<Tag>) -> InterpResult<'tcx, OsString> {
489487
#[cfg(target_os = "windows")]
490488
fn u16vec_to_osstring<'tcx>(u16_vec: Vec<u16>) -> InterpResult<'tcx, OsString> {
491489
Ok(std::os::windows::ffi::OsStringExt::from_wide(&u16_vec[..]))
@@ -497,11 +495,12 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
497495
Ok(s.into())
498496
}
499497

500-
let this = self.eval_context_ref();
501-
let u16_vec = this.memory.read_wide_str(scalar)?;
498+
let u16_vec = self.eval_context_ref().memory.read_wide_str(scalar)?;
502499
u16vec_to_osstring(u16_vec)
503500
}
504501

502+
/// Dispatches to appropriate implementations for writing an OsString to Memory,
503+
/// depending on the interpretation target.
505504
fn write_os_str_to_target_str(
506505
&mut self,
507506
os_str: &OsStr,
@@ -510,9 +509,9 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
510509
) -> InterpResult<'tcx, (bool, u64)> {
511510
let target_os = self.eval_context_ref().tcx.sess.target.target.target_os.as_str();
512511
match target_os {
513-
"linux" => self.write_os_str_to_c_str(os_str, mplace.ptr, size),
512+
"linux" | "macos" => self.write_os_str_to_c_str(os_str, mplace.ptr, size),
514513
"windows" => self.write_os_str_to_wide_str(os_str, mplace, size),
515-
_ => panic!("support for target OS not yet available"),
514+
_ => throw_unsup_format!("support for target OS not yet available"),
516515
}
517516
}
518517

@@ -567,15 +566,21 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
567566
size: u64,
568567
) -> InterpResult<'tcx, (bool, u64)> {
569568
#[cfg(target_os = "windows")]
570-
fn os_str_to_u16vec(os_str: &OsStr) -> Vec<u16> {
571-
std::os::windows::ffi::OsStrExt::encode_wide(os_str).collect()
569+
fn os_str_to_u16vec<'tcx>(os_str: &OsStr) -> InterpResult<'tcx, Vec<u16>> {
570+
Ok(std::os::windows::ffi::OsStrExt::encode_wide(os_str).collect())
572571
}
573572
#[cfg(not(target_os = "windows"))]
574-
fn os_str_to_u16vec(os_str: &OsStr) -> Vec<u16> {
575-
os_str.to_str().unwrap().encode_utf16().collect()
573+
fn os_str_to_u16vec<'tcx>(os_str: &OsStr) -> InterpResult<'tcx, Vec<u16>> {
574+
// On non-unix platforms the best we can do to transform Vec<u16> from/to OS strings is to do the
575+
// intermediate transformation into strings. Which invalidates non-utf8 paths that are actually
576+
// valid.
577+
os_str
578+
.to_str()
579+
.map(|s| s.encode_utf16().collect())
580+
.ok_or_else(|| err_unsup_format!("{:?} is not a valid utf-8 string", os_str).into())
576581
}
577582

578-
let u16_vec = os_str_to_u16vec(os_str);
583+
let u16_vec = os_str_to_u16vec(os_str)?;
579584
// If `size` is smaller or equal than `bytes.len()`, writing `bytes` plus the required
580585
// 0x0000 terminator to memory would cause an out-of-bounds access.
581586
let string_length = u16_vec.len() as u64;
@@ -594,15 +599,18 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
594599
Ok((true, string_length))
595600
}
596601

602+
/// Dispatches to appropriate implementations for allocating & writing OsString in Memory,
603+
/// depending on the interpretation target.
597604
fn alloc_os_str_as_target_str(
598605
&mut self,
599606
os_str: &OsStr,
600607
memkind: MemoryKind<MiriMemoryKind>,
601608
) -> MPlaceTy<'tcx, Tag> {
602609
let target_os = self.eval_context_ref().tcx.sess.target.target.target_os.as_str();
603610
match target_os {
604-
"linux" => self.alloc_os_str_as_c_str(os_str, memkind),
611+
"linux" | "macos" => self.alloc_os_str_as_c_str(os_str, memkind),
605612
"windows" => self.alloc_os_str_as_wide_str(os_str, memkind),
613+
_ => panic!("support for target OS not yet available"),
606614
}
607615
}
608616

0 commit comments

Comments
 (0)