1
1
use std:: collections:: HashMap ;
2
- use std:: ffi:: OsString ;
2
+ use std:: ffi:: { OsString , OsStr } ;
3
3
use std:: env;
4
4
5
5
use crate :: stacked_borrows:: Tag ;
6
6
use crate :: * ;
7
7
8
8
use rustc:: ty:: layout:: Size ;
9
- use rustc_mir:: interpret:: { Memory , Pointer } ;
9
+ use rustc_mir:: interpret:: Pointer ;
10
10
11
11
#[ derive( Default ) ]
12
12
pub struct EnvVars {
13
13
/// Stores pointers to the environment variables. These variables must be stored as
14
14
/// null-terminated C strings with the `"{name}={value}"` format.
15
- map : HashMap < Vec < u8 > , Pointer < Tag > > ,
15
+ map : HashMap < OsString , Pointer < Tag > > ,
16
16
}
17
17
18
18
impl EnvVars {
@@ -30,24 +30,23 @@ impl EnvVars {
30
30
for ( name, value) in env:: vars ( ) {
31
31
if !excluded_env_vars. contains ( & name) {
32
32
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) ;
35
35
}
36
36
}
37
37
}
38
38
}
39
39
}
40
40
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 > > ,
45
45
) -> 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 ( ) )
51
50
}
52
51
53
52
impl < ' mir , ' tcx > EvalContextExt < ' mir , ' tcx > for crate :: MiriEvalContext < ' mir , ' tcx > { }
@@ -56,7 +55,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
56
55
let this = self . eval_context_mut ( ) ;
57
56
58
57
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) ?;
60
59
Ok ( match this. machine . env_vars . map . get ( name) {
61
60
// The offset is used to strip the "{name}=" part of the string.
62
61
Some ( var_ptr) => {
@@ -71,20 +70,20 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
71
70
name_op : OpTy < ' tcx , Tag > ,
72
71
value_op : OpTy < ' tcx , Tag > ,
73
72
) -> InterpResult < ' tcx , i32 > {
74
- let this = self . eval_context_mut ( ) ;
73
+ let mut this = self . eval_context_mut ( ) ;
75
74
76
75
let name_ptr = this. read_scalar ( name_op) ?. not_undef ( ) ?;
77
76
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) ?;
79
78
let mut new = None ;
80
79
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 ( '=' ) {
83
82
new = Some ( ( name. to_owned ( ) , value. to_owned ( ) ) ) ;
84
83
}
85
84
}
86
85
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) ;
88
87
if let Some ( var) = this. machine . env_vars . map . insert ( name. to_owned ( ) , var_ptr) {
89
88
this. memory
90
89
. deallocate ( var, None , MiriMemoryKind :: Env . into ( ) ) ?;
@@ -101,8 +100,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
101
100
let name_ptr = this. read_scalar ( name_op) ?. not_undef ( ) ?;
102
101
let mut success = None ;
103
102
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 ( '=' ) {
106
105
success = Some ( this. machine . env_vars . map . remove ( & name) ) ;
107
106
}
108
107
}
0 commit comments