@@ -60,20 +60,36 @@ fn convert_path_separator<'a>(
6060 } ;
6161}
6262
63+ #[ cfg( unix) ]
64+ pub fn os_str_to_bytes < ' a , ' tcx > ( os_str : & ' a OsStr ) -> InterpResult < ' tcx , & ' a [ u8 ] > {
65+ Ok ( os_str. as_bytes ( ) )
66+ }
67+
68+ #[ cfg( not( unix) ) ]
69+ pub fn os_str_to_bytes < ' a , ' tcx > ( os_str : & ' a OsStr ) -> InterpResult < ' tcx , & ' a [ u8 ] > {
70+ // On non-unix platforms the best we can do to transform bytes from/to OS strings is to do the
71+ // intermediate transformation into strings. Which invalidates non-utf8 paths that are actually
72+ // valid.
73+ os_str
74+ . to_str ( )
75+ . map ( |s| s. as_bytes ( ) )
76+ . ok_or_else ( || err_unsup_format ! ( "{:?} is not a valid utf-8 string" , os_str) . into ( ) )
77+ }
78+
79+ #[ cfg( unix) ]
80+ pub fn bytes_to_os_str < ' a , ' tcx > ( bytes : & ' a [ u8 ] ) -> InterpResult < ' tcx , & ' a OsStr > {
81+ Ok ( OsStr :: from_bytes ( bytes) )
82+ }
83+ #[ cfg( not( unix) ) ]
84+ pub fn bytes_to_os_str < ' a , ' tcx > ( bytes : & ' a [ u8 ] ) -> InterpResult < ' tcx , & ' a OsStr > {
85+ let s = std:: str:: from_utf8 ( bytes)
86+ . map_err ( |_| err_unsup_format ! ( "{:?} is not a valid utf-8 string" , bytes) ) ?;
87+ Ok ( OsStr :: new ( s) )
88+ }
89+
6390impl < ' mir , ' tcx : ' mir > EvalContextExt < ' mir , ' tcx > for crate :: MiriEvalContext < ' mir , ' tcx > { }
6491pub trait EvalContextExt < ' mir , ' tcx : ' mir > : crate :: MiriEvalContextExt < ' mir , ' tcx > {
6592
66- #[ cfg( unix) ]
67- fn bytes_to_os_str < ' a > ( & self , bytes : & ' a [ u8 ] ) -> InterpResult < ' tcx , & ' a OsStr > {
68- Ok ( OsStr :: from_bytes ( bytes) )
69- }
70- #[ cfg( not( unix) ) ]
71- fn bytes_to_os_str < ' a > ( & self , bytes : & ' a [ u8 ] ) -> InterpResult < ' tcx , & ' a OsStr > {
72- let s = std:: str:: from_utf8 ( bytes)
73- . map_err ( |_| err_unsup_format ! ( "{:?} is not a valid utf-8 string" , bytes) ) ?;
74- Ok ( OsStr :: new ( s) )
75- }
76-
7793 /// Helper function to read an OsString from a null-terminated sequence of bytes, which is what
7894 /// the Unix APIs usually handle.
7995 fn read_os_str_from_c_str < ' a > ( & ' a self , scalar : Scalar < Tag > ) -> InterpResult < ' tcx , & ' a OsStr >
@@ -83,7 +99,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
8399 {
84100 let this = self . eval_context_ref ( ) ;
85101 let bytes = this. memory . read_c_str ( scalar) ?;
86- self . bytes_to_os_str ( bytes)
102+ bytes_to_os_str ( bytes)
87103 }
88104
89105 /// Helper function to read an OsString from a 0x0000-terminated sequence of u16,
@@ -108,22 +124,6 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
108124 u16vec_to_osstring ( u16_vec)
109125 }
110126
111- #[ cfg( unix) ]
112- fn os_str_to_bytes < ' a > ( & self , os_str : & ' a OsStr ) -> InterpResult < ' tcx , & ' a [ u8 ] > {
113- Ok ( os_str. as_bytes ( ) )
114- }
115-
116- #[ cfg( not( unix) ) ]
117- fn os_str_to_bytes < ' a > ( & self , os_str : & ' a OsStr ) -> InterpResult < ' tcx , & ' a [ u8 ] > {
118- // On non-unix platforms the best we can do to transform bytes from/to OS strings is to do the
119- // intermediate transformation into strings. Which invalidates non-utf8 paths that are actually
120- // valid.
121- os_str
122- . to_str ( )
123- . map ( |s| s. as_bytes ( ) )
124- . ok_or_else ( || err_unsup_format ! ( "{:?} is not a valid utf-8 string" , os_str) . into ( ) )
125- }
126-
127127 /// Helper function to write an OsStr as a null-terminated sequence of bytes, which is what
128128 /// the Unix APIs usually handle. This function returns `Ok((false, length))` without trying
129129 /// to write if `size` is not large enough to fit the contents of `os_string` plus a null
@@ -136,7 +136,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
136136 size : u64 ,
137137 ) -> InterpResult < ' tcx , ( bool , u64 ) > {
138138
139- let bytes = self . os_str_to_bytes ( os_str) ?;
139+ let bytes = os_str_to_bytes ( os_str) ?;
140140 // If `size` is smaller or equal than `bytes.len()`, writing `bytes` plus the required null
141141 // terminator to memory using the `ptr` pointer would cause an out-of-bounds access.
142142 let string_length = u64:: try_from ( bytes. len ( ) ) . unwrap ( ) ;
@@ -269,3 +269,4 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
269269 this. write_os_str_to_wide_str ( & os_str, scalar, size)
270270 }
271271}
272+
0 commit comments