Skip to content

Commit 845f848

Browse files
committed
std: sys: uefi: os: Implement join_paths
- PATHS_SEP is defined as global const since I will implement split_paths in the future. - Tested using OVMF using QEMU. Signed-off-by: Ayush Singh <ayush@beagleboard.org>
1 parent b6fdaf2 commit 845f848

2 files changed

Lines changed: 28 additions & 5 deletions

File tree

library/std/src/env.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -518,8 +518,9 @@ pub struct JoinPathsError {
518518
///
519519
/// Returns an [`Err`] (containing an error message) if one of the input
520520
/// [`Path`]s contains an invalid character for constructing the `PATH`
521-
/// variable (a double quote on Windows or a colon on Unix), or if the system
522-
/// does not have a `PATH`-like variable (e.g. UEFI or WASI).
521+
/// variable (a double quote on Windows or a colon on Unix or both double
522+
/// quote/colon on UEFI), or if the system does not have a `PATH`-like
523+
/// variable (e.g. UEFI or WASI).
523524
///
524525
/// # Examples
525526
///

library/std/src/sys/pal/uefi/os.rs

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,13 @@ use super::{helpers, unsupported_err};
55
use crate::ffi::{OsStr, OsString};
66
use crate::marker::PhantomData;
77
use crate::os::uefi;
8+
use crate::os::uefi::ffi::{OsStrExt, OsStringExt};
89
use crate::path::{self, PathBuf};
910
use crate::ptr::NonNull;
1011
use crate::{fmt, io};
1112

13+
const PATHS_SEP: u16 = b';' as u16;
14+
1215
pub fn getcwd() -> io::Result<PathBuf> {
1316
match helpers::open_shell() {
1417
Some(shell) => {
@@ -54,17 +57,36 @@ impl<'a> Iterator for SplitPaths<'a> {
5457
#[derive(Debug)]
5558
pub struct JoinPathsError;
5659

57-
pub fn join_paths<I, T>(_paths: I) -> Result<OsString, JoinPathsError>
60+
// UEFI Shell Path variable is defined in Section 3.6.1
61+
// [UEFI Shell Specification](https://uefi.org/sites/default/files/resources/UEFI_Shell_2_2.pdf).
62+
pub fn join_paths<I, T>(paths: I) -> Result<OsString, JoinPathsError>
5863
where
5964
I: Iterator<Item = T>,
6065
T: AsRef<OsStr>,
6166
{
62-
Err(JoinPathsError)
67+
const QUOTE: u16 = b'"' as u16;
68+
69+
let mut joined = Vec::new();
70+
71+
for (i, path) in paths.enumerate() {
72+
let path = path.as_ref();
73+
if i > 0 {
74+
joined.push(PATHS_SEP)
75+
}
76+
let v = path.encode_wide().collect::<Vec<u16>>();
77+
if v.contains(&QUOTE) || v.contains(&PATHS_SEP) {
78+
return Err(JoinPathsError);
79+
}
80+
81+
joined.extend_from_slice(&v[..]);
82+
}
83+
84+
Ok(OsString::from_wide(&joined[..]))
6385
}
6486

6587
impl fmt::Display for JoinPathsError {
6688
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
67-
"not supported on this platform yet".fmt(f)
89+
"path segment contains `\"` or `;`".fmt(f)
6890
}
6991
}
7092

0 commit comments

Comments
 (0)