@@ -305,10 +305,9 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
305
305
fn eval_libc_i32 ( & mut self , name : & str ) -> InterpResult < ' tcx , i32 > {
306
306
self . eval_libc ( name) ?. to_i32 ( )
307
307
}
308
- }
309
-
310
308
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 ( ) ;
312
311
if cfg ! ( unix) {
313
312
Ok ( std:: os:: unix:: ffi:: OsStringExt :: from_vec ( bytes) )
314
313
} else {
@@ -318,13 +317,32 @@ pub fn bytes_to_os_string<'tcx>(bytes: Vec<u8>) -> InterpResult<'tcx, OsString>
318
317
}
319
318
}
320
319
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)
324
323
} else {
325
324
os_string
326
325
. 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" )
329
344
}
330
345
}
346
+ }
347
+
348
+
0 commit comments