@@ -5,10 +5,13 @@ use super::{helpers, unsupported_err};
55use crate :: ffi:: { OsStr , OsString } ;
66use crate :: marker:: PhantomData ;
77use crate :: os:: uefi;
8+ use crate :: os:: uefi:: ffi:: { OsStrExt , OsStringExt } ;
89use crate :: path:: { self , PathBuf } ;
910use crate :: ptr:: NonNull ;
1011use crate :: { fmt, io} ;
1112
13+ const PATHS_SEP : u16 = b';' as u16 ;
14+
1215pub fn getcwd ( ) -> io:: Result < PathBuf > {
1316 match helpers:: open_shell ( ) {
1417 Some ( shell) => {
@@ -54,17 +57,38 @@ impl<'a> Iterator for SplitPaths<'a> {
5457#[ derive( Debug ) ]
5558pub 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 >
5863where
5964 I : Iterator < Item = T > ,
6065 T : AsRef < OsStr > ,
6166{
62- Err ( JoinPathsError )
67+ let mut joined = Vec :: new ( ) ;
68+
69+ for ( i, path) in paths. enumerate ( ) {
70+ let path = path. as_ref ( ) ;
71+ if i > 0 {
72+ joined. push ( PATHS_SEP )
73+ }
74+ let v = path. encode_wide ( ) . collect :: < Vec < u16 > > ( ) ;
75+ if v. contains ( & ( b'"' as u16 ) ) {
76+ return Err ( JoinPathsError ) ;
77+ } else if v. contains ( & PATHS_SEP ) {
78+ joined. push ( b'"' as u16 ) ;
79+ joined. extend_from_slice ( & v[ ..] ) ;
80+ joined. push ( b'"' as u16 ) ;
81+ } else {
82+ joined. extend_from_slice ( & v[ ..] ) ;
83+ }
84+ }
85+
86+ Ok ( OsString :: from_wide ( & joined[ ..] ) )
6387}
6488
6589impl fmt:: Display for JoinPathsError {
6690 fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
67- "not supported on this platform yet " . fmt ( f)
91+ "path segment contains ` \" ` " . fmt ( f)
6892 }
6993}
7094
0 commit comments