@@ -349,10 +349,9 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
349349 }
350350 Ok ( ( ) )
351351 }
352- }
353-
354352
355- pub fn bytes_to_os_string < ' tcx > ( bytes : Vec < u8 > ) -> InterpResult < ' tcx , OsString > {
353+ fn read_os_string ( & mut self , scalar : Scalar < Tag > ) -> InterpResult < ' tcx , OsString > {
354+ let bytes = self . eval_context_mut ( ) . memory ( ) . read_c_str ( scalar) ?. to_vec ( ) ;
356355 if cfg ! ( unix) {
357356 Ok ( std:: os:: unix:: ffi:: OsStringExt :: from_vec ( bytes) )
358357 } else {
@@ -362,13 +361,30 @@ pub fn bytes_to_os_string<'tcx>(bytes: Vec<u8>) -> InterpResult<'tcx, OsString>
362361 }
363362 }
364363
365- pub fn os_string_to_bytes < ' tcx > ( os_string : OsString ) -> InterpResult < ' tcx , Vec < u8 > > {
366- if cfg ! ( unix) {
367- Ok ( std:: os:: unix:: ffi:: OsStringExt :: into_vec ( os_string) )
364+ fn write_os_string ( & mut self , os_string : OsString , ptr : Pointer < Tag > , size : u64 ) -> InterpResult < ' tcx > {
365+ let mut bytes = if cfg ! ( unix) {
366+ std:: os:: unix:: ffi:: OsStringExt :: into_vec ( os_string)
368367 } else {
369368 os_string
370369 . into_string ( )
371- . map_err ( |os_string| err_unsup_format ! ( "{:?} is not a valid utf-8 string" , os_string) . into ( ) )
372- . map ( |s| s. into_bytes ( ) )
370+ . map_err ( |os_string| err_unsup_format ! ( "{:?} is not a valid utf-8 string" , os_string) ) ?
371+ . into_bytes ( )
372+ } ;
373+ // If `size` is smaller or equal than `bytes.len()`, writing `bytes` plus the required null
374+ // terminator to memory using the `ptr` pointer would cause an overflow.
375+ if ( bytes. len ( ) as u64 ) < size {
376+ // We add a `/0` terminator
377+ bytes. push ( 0 ) ;
378+ let this = self . eval_context_mut ( ) ;
379+ let tcx = & { this. tcx . tcx } ;
380+ // This is ok because the buffer was strictly larger than `bytes`, so after adding the
381+ // null terminator, the buffer size is larger or equal to `bytes.len()`, meaning that
382+ // `bytes` actually fit inside tbe buffer.
383+ this. memory_mut ( )
384+ . get_mut ( ptr. alloc_id ) ?
385+ . write_bytes ( tcx, ptr, & bytes)
386+ } else {
387+ throw_unsup_format ! ( "OsString is larger than destination" )
373388 }
374389 }
390+ }
0 commit comments