diff --git a/library/std/src/env.rs b/library/std/src/env.rs index 5c068ad2471ad..7a9a243ff4ead 100644 --- a/library/std/src/env.rs +++ b/library/std/src/env.rs @@ -518,8 +518,9 @@ pub struct JoinPathsError { /// /// Returns an [`Err`] (containing an error message) if one of the input /// [`Path`]s contains an invalid character for constructing the `PATH` -/// variable (a double quote on Windows or a colon on Unix), or if the system -/// does not have a `PATH`-like variable (e.g. UEFI or WASI). +/// variable (a double quote on Windows or a colon on Unix or both double +/// quote/colon on UEFI), or if the system does not have a `PATH`-like +/// variable (e.g. UEFI or WASI). /// /// # Examples /// diff --git a/library/std/src/sys/pal/uefi/os.rs b/library/std/src/sys/pal/uefi/os.rs index 178f7f506341e..a4041c23f8507 100644 --- a/library/std/src/sys/pal/uefi/os.rs +++ b/library/std/src/sys/pal/uefi/os.rs @@ -5,10 +5,14 @@ use super::{helpers, unsupported_err}; use crate::ffi::{OsStr, OsString}; use crate::marker::PhantomData; use crate::os::uefi; +use crate::os::uefi::ffi::{OsStrExt, OsStringExt}; use crate::path::{self, PathBuf}; use crate::ptr::NonNull; use crate::{fmt, io}; +const PATHS_SEP: u16 = b';' as u16; +const QUOTE: u16 = b'"' as u16; + pub fn getcwd() -> io::Result { match helpers::open_shell() { Some(shell) => { @@ -54,17 +58,34 @@ impl<'a> Iterator for SplitPaths<'a> { #[derive(Debug)] pub struct JoinPathsError; -pub fn join_paths(_paths: I) -> Result +// UEFI Shell Path variable is defined in Section 3.6.1 +// [UEFI Shell Specification](https://uefi.org/sites/default/files/resources/UEFI_Shell_2_2.pdf). +pub fn join_paths(paths: I) -> Result where I: Iterator, T: AsRef, { - Err(JoinPathsError) + let mut joined = Vec::new(); + + for (i, path) in paths.enumerate() { + let path = path.as_ref(); + if i > 0 { + joined.push(PATHS_SEP) + } + let v = path.encode_wide().collect::>(); + if v.contains("E) || v.contains(&PATHS_SEP) { + return Err(JoinPathsError); + } + + joined.extend_from_slice(&v[..]); + } + + Ok(OsString::from_wide(&joined[..])) } impl fmt::Display for JoinPathsError { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - "not supported on this platform yet".fmt(f) + "path segment contains `\"` or `;`".fmt(f) } }