convert dir separators on path load/store
This commit is contained in:
parent
4ac91384ff
commit
c4e29c8646
@ -1,9 +1,14 @@
|
||||
use std::ffi::{OsStr, OsString};
|
||||
use std::path::Path;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::{iter, mem};
|
||||
use std::convert::TryFrom;
|
||||
use std::borrow::Cow;
|
||||
|
||||
#[cfg(unix)]
|
||||
use std::os::unix::ffi::{OsStrExt, OsStringExt};
|
||||
#[cfg(windows)]
|
||||
use std::os::windows::ffi::{OsStrExt, OsStringExt};
|
||||
|
||||
use rustc::mir;
|
||||
use rustc::ty::{
|
||||
self,
|
||||
@ -479,7 +484,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
|
||||
{
|
||||
#[cfg(unix)]
|
||||
fn bytes_to_os_str<'tcx, 'a>(bytes: &'a [u8]) -> InterpResult<'tcx, &'a OsStr> {
|
||||
Ok(std::os::unix::ffi::OsStrExt::from_bytes(bytes))
|
||||
Ok(OsStr::from_bytes(bytes))
|
||||
}
|
||||
#[cfg(not(unix))]
|
||||
fn bytes_to_os_str<'tcx, 'a>(bytes: &'a [u8]) -> InterpResult<'tcx, &'a OsStr> {
|
||||
@ -499,8 +504,34 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
|
||||
'tcx: 'a,
|
||||
'mir: 'a,
|
||||
{
|
||||
let os_str = self.read_os_str_from_c_str(scalar)?;
|
||||
Ok(Cow::Borrowed(Path::new(os_str)))
|
||||
let this = self.eval_context_ref();
|
||||
let os_str = this.read_os_str_from_c_str(scalar)?;
|
||||
|
||||
#[cfg(windows)]
|
||||
return Ok(if this.tcx.sess.target.target.target_os == "windows" {
|
||||
// Windows-on-Windows, all fine.
|
||||
Cow::Borrowed(Path::new(os_str))
|
||||
} else {
|
||||
// Unix target, Windows host. Need to convert target '/' to host '\'.
|
||||
let converted = os_str
|
||||
.encode_wide()
|
||||
.map(|wchar| if wchar == '/' as u16 { '\\' as u16 } else { wchar })
|
||||
.collect::<Vec<_>>();
|
||||
Cow::Owned(PathBuf::from(OsString::from_wide(&converted)))
|
||||
});
|
||||
#[cfg(unix)]
|
||||
return Ok(if this.tcx.sess.target.target.target_os == "windows" {
|
||||
// Windows target, Unix host. Need to convert target '\' to host '/'.
|
||||
let converted = os_str
|
||||
.as_bytes()
|
||||
.iter()
|
||||
.map(|&wchar| if wchar == '/' as u8 { '\\' as u8 } else { wchar })
|
||||
.collect::<Vec<_>>();
|
||||
Cow::Owned(PathBuf::from(OsString::from_vec(converted)))
|
||||
} else {
|
||||
// Unix-on-Unix, all is fine.
|
||||
Cow::Borrowed(Path::new(os_str))
|
||||
});
|
||||
}
|
||||
|
||||
/// Helper function to read an OsString from a 0x0000-terminated sequence of u16,
|
||||
@ -512,7 +543,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
|
||||
{
|
||||
#[cfg(windows)]
|
||||
pub fn u16vec_to_osstring<'tcx, 'a>(u16_vec: Vec<u16>) -> InterpResult<'tcx, OsString> {
|
||||
Ok(std::os::windows::ffi::OsStringExt::from_wide(&u16_vec[..]))
|
||||
Ok(OsString::from_wide(&u16_vec[..]))
|
||||
}
|
||||
#[cfg(not(windows))]
|
||||
pub fn u16vec_to_osstring<'tcx, 'a>(u16_vec: Vec<u16>) -> InterpResult<'tcx, OsString> {
|
||||
@ -538,7 +569,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
|
||||
) -> InterpResult<'tcx, (bool, u64)> {
|
||||
#[cfg(unix)]
|
||||
fn os_str_to_bytes<'tcx, 'a>(os_str: &'a OsStr) -> InterpResult<'tcx, &'a [u8]> {
|
||||
Ok(std::os::unix::ffi::OsStrExt::as_bytes(os_str))
|
||||
Ok(os_str.as_bytes())
|
||||
}
|
||||
#[cfg(not(unix))]
|
||||
fn os_str_to_bytes<'tcx, 'a>(os_str: &'a OsStr) -> InterpResult<'tcx, &'a [u8]> {
|
||||
@ -571,8 +602,37 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
|
||||
scalar: Scalar<Tag>,
|
||||
size: u64,
|
||||
) -> InterpResult<'tcx, (bool, u64)> {
|
||||
let os_str = path.as_os_str();
|
||||
self.write_os_str_to_c_str(os_str, scalar, size)
|
||||
let this = self.eval_context_mut();
|
||||
|
||||
#[cfg(windows)]
|
||||
let os_str = if this.tcx.sess.target.target.target_os == "windows" {
|
||||
// Windows-on-Windows, all fine.
|
||||
Cow::Borrowed(path.as_os_str())
|
||||
} else {
|
||||
// Unix target, Windows host. Need to convert host '\\' to target '/'.
|
||||
let converted = path
|
||||
.as_os_str()
|
||||
.encode_wide()
|
||||
.map(|wchar| if wchar == '\\' as u16 { '/' as u16 } else { wchar })
|
||||
.collect::<Vec<_>>();
|
||||
Cow::Owned(OsString::from_wide(&converted))
|
||||
};
|
||||
#[cfg(unix)]
|
||||
let os_str = if this.tcx.sess.target.target.target_os == "windows" {
|
||||
// Windows target, Unix host. Need to convert host '/' to target '\'.
|
||||
let converted = path
|
||||
.as_os_str()
|
||||
.as_bytes()
|
||||
.iter()
|
||||
.map(|&wchar| if wchar == '/' as u8 { '\\' as u8 } else { wchar })
|
||||
.collect::<Vec<_>>();
|
||||
Cow::Owned(OsString::from_vec(converted))
|
||||
} else {
|
||||
// Unix-on-Unix, all is fine.
|
||||
Cow::Borrowed(path.as_os_str())
|
||||
};
|
||||
|
||||
this.write_os_str_to_c_str(&os_str, scalar, size)
|
||||
}
|
||||
|
||||
/// Helper function to write an OsStr as a 0x0000-terminated u16-sequence, which is what
|
||||
@ -588,7 +648,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
|
||||
) -> InterpResult<'tcx, (bool, u64)> {
|
||||
#[cfg(windows)]
|
||||
fn os_str_to_u16vec<'tcx>(os_str: &OsStr) -> InterpResult<'tcx, Vec<u16>> {
|
||||
Ok(std::os::windows::ffi::OsStrExt::encode_wide(os_str).collect())
|
||||
Ok(os_str.encode_wide().collect())
|
||||
}
|
||||
#[cfg(not(windows))]
|
||||
fn os_str_to_u16vec<'tcx>(os_str: &OsStr) -> InterpResult<'tcx, Vec<u16>> {
|
||||
|
Loading…
x
Reference in New Issue
Block a user