11use std:: collections:: HashMap ;
2- use std:: ffi:: OsString ;
2+ use std:: ffi:: { OsString , OsStr } ;
33use std:: env;
44
55use crate :: stacked_borrows:: Tag ;
66use crate :: * ;
77
88use rustc:: ty:: layout:: Size ;
9- use rustc_mir:: interpret:: { Memory , Pointer } ;
9+ use rustc_mir:: interpret:: Pointer ;
1010
1111#[ derive( Default ) ]
1212pub struct EnvVars {
1313 /// Stores pointers to the environment variables. These variables must be stored as
1414 /// null-terminated C strings with the `"{name}={value}"` format.
15- map : HashMap < Vec < u8 > , Pointer < Tag > > ,
15+ map : HashMap < OsString , Pointer < Tag > > ,
1616}
1717
1818impl EnvVars {
@@ -30,24 +30,23 @@ impl EnvVars {
3030 for ( name, value) in env:: vars ( ) {
3131 if !excluded_env_vars. contains ( & name) {
3232 let var_ptr =
33- alloc_env_var ( name. as_bytes ( ) , value. as_bytes ( ) , & mut ecx. memory ) ;
34- ecx. machine . env_vars . map . insert ( name . into_bytes ( ) , var_ptr) ;
33+ alloc_env_var_as_c_str ( name. as_ref ( ) , value. as_ref ( ) , ecx) ;
34+ ecx. machine . env_vars . map . insert ( OsString :: from ( name ) , var_ptr) ;
3535 }
3636 }
3737 }
3838 }
3939}
4040
41- fn alloc_env_var < ' mir , ' tcx > (
42- name : & [ u8 ] ,
43- value : & [ u8 ] ,
44- memory : & mut Memory < ' mir , ' tcx , Evaluator < ' tcx > > ,
41+ fn alloc_env_var_as_c_str < ' mir , ' tcx > (
42+ name : & OsStr ,
43+ value : & OsStr ,
44+ ecx : & mut InterpCx < ' mir , ' tcx , Evaluator < ' tcx > > ,
4545) -> Pointer < Tag > {
46- let mut bytes = name. to_vec ( ) ;
47- bytes. push ( b'=' ) ;
48- bytes. extend_from_slice ( value) ;
49- bytes. push ( 0 ) ;
50- memory. allocate_static_bytes ( bytes. as_slice ( ) , MiriMemoryKind :: Env . into ( ) )
46+ let mut name_osstring = name. to_os_string ( ) ;
47+ name_osstring. push ( "=" ) ;
48+ name_osstring. push ( value) ;
49+ ecx. alloc_os_str_as_c_str ( name_osstring. as_os_str ( ) , MiriMemoryKind :: Env . into ( ) )
5150}
5251
5352impl < ' mir , ' tcx > EvalContextExt < ' mir , ' tcx > for crate :: MiriEvalContext < ' mir , ' tcx > { }
@@ -56,7 +55,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
5655 let this = self . eval_context_mut ( ) ;
5756
5857 let name_ptr = this. read_scalar ( name_op) ?. not_undef ( ) ?;
59- let name = this. memory . read_c_str ( name_ptr) ?;
58+ let name = this. read_os_str_from_c_str ( name_ptr) ?;
6059 Ok ( match this. machine . env_vars . map . get ( name) {
6160 // The offset is used to strip the "{name}=" part of the string.
6261 Some ( var_ptr) => {
@@ -71,20 +70,20 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
7170 name_op : OpTy < ' tcx , Tag > ,
7271 value_op : OpTy < ' tcx , Tag > ,
7372 ) -> InterpResult < ' tcx , i32 > {
74- let this = self . eval_context_mut ( ) ;
73+ let mut this = self . eval_context_mut ( ) ;
7574
7675 let name_ptr = this. read_scalar ( name_op) ?. not_undef ( ) ?;
7776 let value_ptr = this. read_scalar ( value_op) ?. not_undef ( ) ?;
78- let value = this. memory . read_c_str ( value_ptr) ?;
77+ let value = this. read_os_str_from_c_str ( value_ptr) ?;
7978 let mut new = None ;
8079 if !this. is_null ( name_ptr) ? {
81- let name = this. memory . read_c_str ( name_ptr) ?;
82- if !name. is_empty ( ) && !name. contains ( & b '=') {
80+ let name = this. read_os_str_from_c_str ( name_ptr) ?;
81+ if !name. is_empty ( ) && !name. to_string_lossy ( ) . contains ( '=' ) {
8382 new = Some ( ( name. to_owned ( ) , value. to_owned ( ) ) ) ;
8483 }
8584 }
8685 if let Some ( ( name, value) ) = new {
87- let var_ptr = alloc_env_var ( & name, & value, & mut this. memory ) ;
86+ let var_ptr = alloc_env_var_as_c_str ( & name, & value, & mut this) ;
8887 if let Some ( var) = this. machine . env_vars . map . insert ( name. to_owned ( ) , var_ptr) {
8988 this. memory
9089 . deallocate ( var, None , MiriMemoryKind :: Env . into ( ) ) ?;
@@ -101,8 +100,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
101100 let name_ptr = this. read_scalar ( name_op) ?. not_undef ( ) ?;
102101 let mut success = None ;
103102 if !this. is_null ( name_ptr) ? {
104- let name = this. memory . read_c_str ( name_ptr) ?. to_owned ( ) ;
105- if !name. is_empty ( ) && !name. contains ( & b '=') {
103+ let name = this. read_os_str_from_c_str ( name_ptr) ?. to_owned ( ) ;
104+ if !name. is_empty ( ) && !name. to_string_lossy ( ) . contains ( '=' ) {
106105 success = Some ( this. machine . env_vars . map . remove ( & name) ) ;
107106 }
108107 }
0 commit comments