@@ -345,10 +345,9 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
345345 }
346346 Ok ( ( ) )
347347 }
348- }
349-
350348
351- pub fn bytes_to_os_string < ' tcx > ( bytes : Vec < u8 > ) -> InterpResult < ' tcx , OsString > {
349+ fn read_os_string ( & mut self , scalar : Scalar < Tag > ) -> InterpResult < ' tcx , OsString > {
350+ let bytes = self . eval_context_mut ( ) . memory . read_c_str ( scalar) ?. to_vec ( ) ;
352351 if cfg ! ( unix) {
353352 Ok ( std:: os:: unix:: ffi:: OsStringExt :: from_vec ( bytes) )
354353 } else {
@@ -358,13 +357,30 @@ pub fn bytes_to_os_string<'tcx>(bytes: Vec<u8>) -> InterpResult<'tcx, OsString>
358357 }
359358 }
360359
361- pub fn os_string_to_bytes < ' tcx > ( os_string : OsString ) -> InterpResult < ' tcx , Vec < u8 > > {
362- if cfg ! ( unix) {
363- Ok ( std:: os:: unix:: ffi:: OsStringExt :: into_vec ( os_string) )
360+ fn write_os_string ( & mut self , os_string : OsString , ptr : Pointer < Tag > , size : u64 ) -> InterpResult < ' tcx > {
361+ let mut bytes = if cfg ! ( unix) {
362+ std:: os:: unix:: ffi:: OsStringExt :: into_vec ( os_string)
364363 } else {
365364 os_string
366365 . into_string ( )
367- . map_err ( |os_string| err_unsup_format ! ( "{:?} is not a valid utf-8 string" , os_string) . into ( ) )
368- . map ( |s| s. into_bytes ( ) )
366+ . map_err ( |os_string| err_unsup_format ! ( "{:?} is not a valid utf-8 string" , os_string) ) ?
367+ . into_bytes ( )
368+ } ;
369+ // If `size` is smaller or equal than `bytes.len()`, writing `bytes` plus the required null
370+ // terminator to memory using the `ptr` pointer would cause an overflow.
371+ if ( bytes. len ( ) as u64 ) < size {
372+ // We add a `/0` terminator
373+ bytes. push ( 0 ) ;
374+ let this = self . eval_context_mut ( ) ;
375+ let tcx = & { this. tcx . tcx } ;
376+ // This is ok because the buffer was strictly larger than `bytes`, so after adding the
377+ // null terminator, the buffer size is larger or equal to `bytes.len()`, meaning that
378+ // `bytes` actually fit inside tbe buffer.
379+ this. memory
380+ . get_mut ( ptr. alloc_id ) ?
381+ . write_bytes ( tcx, ptr, & bytes)
382+ } else {
383+ throw_unsup_format ! ( "OsString is larger than destination" )
369384 }
370385 }
386+ }
0 commit comments