From: Christian Poveda Date: Sun, 13 Oct 2019 20:26:03 +0000 (-0500) Subject: Add OsString from/to bytes helper functions X-Git-Url: https://git.lizzy.rs/?a=commitdiff_plain;h=61da8b84282d4b44f4dd1742328867cae9e5cefc;p=rust.git Add OsString from/to bytes helper functions --- diff --git a/src/helpers.rs b/src/helpers.rs index c09d5c823e1..c2e4131a76d 100644 --- a/src/helpers.rs +++ b/src/helpers.rs @@ -1,4 +1,5 @@ use std::mem; +use std::ffi::OsString; use rustc::hir::def_id::{DefId, CRATE_DEF_INDEX}; use rustc::mir; @@ -345,3 +346,25 @@ fn check_no_isolation(&mut self, name: &str) -> InterpResult<'tcx> { Ok(()) } } + + +pub fn bytes_to_os_string<'tcx>(bytes: Vec) -> InterpResult<'tcx, OsString> { + if cfg!(unix) { + Ok(std::os::unix::ffi::OsStringExt::from_vec(bytes)) + } else { + std::str::from_utf8(&bytes) + .map_err(|_| err_unsup_format!("{:?} is not a valid utf-8 string", bytes).into()) + .map(OsString::from) + } + } + +pub fn os_string_to_bytes<'tcx>(os_string: OsString) -> InterpResult<'tcx, Vec> { + if cfg!(unix) { + Ok(std::os::unix::ffi::OsStringExt::into_vec(os_string)) + } else { + os_string + .into_string() + .map_err(|os_string| err_unsup_format!("{:?} is not a valid utf-8 string", os_string).into()) + .map(|s| s.into_bytes()) + } + } diff --git a/src/shims/env.rs b/src/shims/env.rs index 6078ca26e26..1fe08aeffb7 100644 --- a/src/shims/env.rs +++ b/src/shims/env.rs @@ -1,9 +1,9 @@ use std::collections::HashMap; use std::env; -use std::path::Path; use crate::stacked_borrows::Tag; use crate::*; + use rustc::ty::layout::Size; use rustc_mir::interpret::{Memory, Pointer}; @@ -128,7 +128,7 @@ fn getcwd( match env::current_dir() { Ok(cwd) => { // It is not clear what happens with non-utf8 paths here - let mut bytes = cwd.display().to_string().into_bytes(); + let mut bytes = helpers::os_string_to_bytes(cwd.into())?; // If `size` is smaller or equal than the `bytes.len()`, writing `bytes` plus the // required null terminator to memory using the `buf` pointer would cause an // overflow. The desired behavior in this case is to return null. @@ -156,16 +156,10 @@ fn chdir(&mut self, path_op: OpTy<'tcx, Tag>) -> InterpResult<'tcx, i32> { this.check_no_isolation("chdir")?; - let path_bytes = this - .memory - .read_c_str(this.read_scalar(path_op)?.not_undef()?)?; - - let path = Path::new( - std::str::from_utf8(path_bytes) - .map_err(|_| err_unsup_format!("{:?} is not a valid utf-8 string", path_bytes))?, - ); + let bytes = this.memory.read_c_str(this.read_scalar(path_op)?.not_undef()?)?; + let path = helpers::bytes_to_os_string(bytes.to_vec()); - match env::set_current_dir(path) { + match env::set_current_dir(path?) { Ok(()) => Ok(0), Err(e) => { this.consume_io_error(e)?; diff --git a/src/shims/fs.rs b/src/shims/fs.rs index 891474bc3bd..cc776295bd4 100644 --- a/src/shims/fs.rs +++ b/src/shims/fs.rs @@ -94,11 +94,10 @@ fn open( throw_unsup_format!("unsupported flags {:#x}", flag & !mirror); } - let path_bytes = this + let bytes = this .memory .read_c_str(this.read_scalar(path_op)?.not_undef()?)?; - let path = std::str::from_utf8(path_bytes) - .map_err(|_| err_unsup_format!("{:?} is not a valid utf-8 string", path_bytes))?; + let path: std::path::PathBuf = helpers::bytes_to_os_string(bytes.to_vec())?.into(); let fd = options.open(path).map(|file| { let mut fh = &mut this.machine.file_handler; diff --git a/tests/compile-fail/chdir_invalid_path.rs b/tests/compile-fail/chdir_invalid_path.rs deleted file mode 100644 index 22b0d723aad..00000000000 --- a/tests/compile-fail/chdir_invalid_path.rs +++ /dev/null @@ -1,11 +0,0 @@ -// compile-flags: -Zmiri-disable-isolation - -extern { - pub fn chdir(dir: *const u8) -> i32; -} - -fn main() { - let path = vec![0xc3u8, 0x28, 0]; - // test that `chdir` errors with invalid utf-8 path - unsafe { chdir(path.as_ptr()) }; //~ ERROR is not a valid utf-8 string -}