@@ -5,6 +5,7 @@ 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} ;
@@ -107,12 +108,34 @@ impl<'a> Iterator for SplitPaths<'a> {
107108#[ derive( Debug ) ]
108109pub struct JoinPathsError ;
109110
110- pub fn join_paths < I , T > ( _paths : I ) -> Result < OsString , JoinPathsError >
111+ // UEFI Shell Path variable is defined in Section 3.6.1
112+ // [UEFI Shell Specification](https://uefi.org/sites/default/files/resources/UEFI_Shell_2_2.pdf).
113+ pub fn join_paths < I , T > ( paths : I ) -> Result < OsString , JoinPathsError >
111114where
112115 I : Iterator < Item = T > ,
113116 T : AsRef < OsStr > ,
114117{
115- Err ( JoinPathsError )
118+ let mut joined = Vec :: new ( ) ;
119+ let sep = b';' as u16 ;
120+
121+ for ( i, path) in paths. enumerate ( ) {
122+ let path = path. as_ref ( ) ;
123+ if i > 0 {
124+ joined. push ( sep)
125+ }
126+ let v = path. encode_wide ( ) . collect :: < Vec < u16 > > ( ) ;
127+ if v. contains ( & ( b'"' as u16 ) ) {
128+ return Err ( JoinPathsError ) ;
129+ } else if v. contains ( & sep) {
130+ joined. push ( b'"' as u16 ) ;
131+ joined. extend_from_slice ( & v[ ..] ) ;
132+ joined. push ( b'"' as u16 ) ;
133+ } else {
134+ joined. extend_from_slice ( & v[ ..] ) ;
135+ }
136+ }
137+
138+ Ok ( OsString :: from_wide ( & joined[ ..] ) )
116139}
117140
118141impl fmt:: Display for JoinPathsError {
0 commit comments