@@ -305,10 +305,9 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
305305 fn eval_libc_i32 ( & mut self , name : & str ) -> InterpResult < ' tcx , i32 > {
306306 self . eval_libc ( name) ?. to_i32 ( )
307307 }
308- }
309-
310308
311- pub fn bytes_to_os_string < ' tcx > ( bytes : Vec < u8 > ) -> InterpResult < ' tcx , OsString > {
309+ fn read_os_string ( & mut self , scalar : Scalar < Tag > ) -> InterpResult < ' tcx , OsString > {
310+ let bytes = self . eval_context_mut ( ) . memory ( ) . read_c_str ( scalar) ?. to_vec ( ) ;
312311 if cfg ! ( unix) {
313312 Ok ( std:: os:: unix:: ffi:: OsStringExt :: from_vec ( bytes) )
314313 } else {
@@ -318,13 +317,32 @@ pub fn bytes_to_os_string<'tcx>(bytes: Vec<u8>) -> InterpResult<'tcx, OsString>
318317 }
319318 }
320319
321- pub fn os_string_to_bytes < ' tcx > ( os_string : OsString ) -> InterpResult < ' tcx , Vec < u8 > > {
322- if cfg ! ( unix) {
323- Ok ( std:: os:: unix:: ffi:: OsStringExt :: into_vec ( os_string) )
320+ fn write_os_string ( & mut self , os_string : OsString , ptr : Pointer < Tag > , size : u64 ) -> InterpResult < ' tcx > {
321+ let mut bytes = if cfg ! ( unix) {
322+ std:: os:: unix:: ffi:: OsStringExt :: into_vec ( os_string)
324323 } else {
325324 os_string
326325 . into_string ( )
327- . map_err ( |os_string| err_unsup_format ! ( "{:?} is not a valid utf-8 string" , os_string) . into ( ) )
328- . map ( |s| s. into_bytes ( ) )
326+ . map_err ( |os_string| err_unsup_format ! ( "{:?} is not a valid utf-8 string" , os_string) ) ?
327+ . into_bytes ( )
328+ } ;
329+ // If `size` is smaller or equal than `bytes.len()`, writing `bytes` plus the required null
330+ // terminator to memory using the `ptr` pointer would cause an overflow.
331+ if ( bytes. len ( ) as u64 ) < size {
332+ // We add a `/0` terminator
333+ bytes. push ( 0 ) ;
334+ let this = self . eval_context_mut ( ) ;
335+ let tcx = & { this. tcx . tcx } ;
336+ // This is ok because the buffer was strictly larger than `bytes`, so after adding the
337+ // null terminator, the buffer size is larger or equal to `bytes.len()`, meaning that
338+ // `bytes` actually fit inside tbe buffer.
339+ this. memory_mut ( )
340+ . get_mut ( ptr. alloc_id ) ?
341+ . write_bytes ( tcx, ptr, & bytes)
342+ } else {
343+ throw_unsup_format ! ( "OsString is larger than destination" )
329344 }
330345 }
346+ }
347+
348+
0 commit comments