@@ -25,12 +25,12 @@ impl<'tcx> EnvVars<'tcx> {
25
25
ecx : & mut InterpCx < ' mir , ' tcx , Evaluator < ' tcx > > ,
26
26
mut excluded_env_vars : Vec < String > ,
27
27
) -> InterpResult < ' tcx > {
28
- if ecx. tcx . sess . target . target . target_os == "windows" {
28
+ let target_os = ecx. tcx . sess . target . target . target_os . as_str ( ) ;
29
+ if target_os == "windows" {
29
30
// Exclude `TERM` var to avoid terminfo trying to open the termcap file.
30
31
excluded_env_vars. push ( "TERM" . to_owned ( ) ) ;
31
32
}
32
33
if ecx. machine . communicate {
33
- let target_os = ecx. tcx . sess . target . target . target_os . as_str ( ) ;
34
34
for ( name, value) in env:: vars ( ) {
35
35
if !excluded_env_vars. contains ( & name) {
36
36
let var_ptr = match target_os {
@@ -68,28 +68,6 @@ fn alloc_env_var_as_wide_str<'mir, 'tcx>(
68
68
Ok ( ecx. alloc_os_str_as_wide_str ( name_osstring. as_os_str ( ) , MiriMemoryKind :: Machine . into ( ) ) )
69
69
}
70
70
71
- fn alloc_env_var_as_c_str < ' mir , ' tcx > (
72
- name : & OsStr ,
73
- value : & OsStr ,
74
- ecx : & mut InterpCx < ' mir , ' tcx , Evaluator < ' tcx > > ,
75
- ) -> InterpResult < ' tcx , Pointer < Tag > > {
76
- let mut name_osstring = name. to_os_string ( ) ;
77
- name_osstring. push ( "=" ) ;
78
- name_osstring. push ( value) ;
79
- Ok ( ecx. alloc_os_str_as_c_str ( name_osstring. as_os_str ( ) , MiriMemoryKind :: Machine . into ( ) ) )
80
- }
81
-
82
- fn alloc_env_var_as_wide_str < ' mir , ' tcx > (
83
- name : & OsStr ,
84
- value : & OsStr ,
85
- ecx : & mut InterpCx < ' mir , ' tcx , Evaluator < ' tcx > > ,
86
- ) -> InterpResult < ' tcx , Pointer < Tag > > {
87
- let mut name_osstring = name. to_os_string ( ) ;
88
- name_osstring. push ( "=" ) ;
89
- name_osstring. push ( value) ;
90
- Ok ( ecx. alloc_os_str_as_wide_str ( name_osstring. as_os_str ( ) , MiriMemoryKind :: Machine . into ( ) ) )
91
- }
92
-
93
71
impl < ' mir , ' tcx > EvalContextExt < ' mir , ' tcx > for crate :: MiriEvalContext < ' mir , ' tcx > { }
94
72
pub trait EvalContextExt < ' mir , ' tcx : ' mir > : crate :: MiriEvalContextExt < ' mir , ' tcx > {
95
73
fn getenv ( & mut self , name_op : OpTy < ' tcx , Tag > ) -> InterpResult < ' tcx , Scalar < Tag > > {
@@ -126,26 +104,26 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
126
104
let name_offset_bytes =
127
105
u64:: try_from ( name. len ( ) ) . unwrap ( ) . checked_add ( 1 ) . unwrap ( ) . checked_mul ( 2 ) . unwrap ( ) ;
128
106
let var_ptr = Scalar :: from ( var_ptr. offset ( Size :: from_bytes ( name_offset_bytes) , this) ?) ;
107
+ let var = this. read_os_str_from_wide_str ( var_ptr) ?;
129
108
130
- let var_size = u64 :: try_from ( this. read_os_str_from_wide_str ( var_ptr ) ?. len ( ) ) . unwrap ( ) ;
109
+ let buf_ptr = this. read_scalar ( buf_op ) ?. not_undef ( ) ? ;
131
110
// `buf_size` represents the size in characters.
132
111
let buf_size = u64:: try_from ( this. read_scalar ( size_op) ?. to_u32 ( ) ?) . unwrap ( ) ;
133
- let return_val = if var_size. checked_add ( 1 ) . unwrap ( ) > buf_size {
134
- // If lpBuffer is not large enough to hold the data, the return value is the buffer size, in characters,
135
- // required to hold the string and its terminating null character and the contents of lpBuffer are undefined.
136
- var_size + 1
137
- } else {
138
- let buf_ptr = this. read_scalar ( buf_op) ?. not_undef ( ) ?;
139
- let bytes_to_be_copied = var_size. checked_add ( 1 ) . unwrap ( ) . checked_mul ( 2 ) . unwrap ( ) ;
140
- this. memory . copy ( this. force_ptr ( var_ptr) ?, this. force_ptr ( buf_ptr) ?, Size :: from_bytes ( bytes_to_be_copied) , true ) ?;
112
+ let ( success, len) = this. write_os_str_to_wide_str ( & var, buf_ptr, buf_size) ?;
113
+
114
+ if success {
141
115
// If the function succeeds, the return value is the number of characters stored in the buffer pointed to by lpBuffer,
142
116
// not including the terminating null character.
143
- var_size
144
- } ;
145
- return_val
117
+ len
118
+ } else {
119
+ // If lpBuffer is not large enough to hold the data, the return value is the buffer size, in characters,
120
+ // required to hold the string and its terminating null character and the contents of lpBuffer are undefined.
121
+ len + 1
122
+ }
146
123
}
147
124
None => {
148
- this. set_last_error ( Scalar :: from_u32 ( 203 ) ) ?; // ERROR_ENVVAR_NOT_FOUND
125
+ let envvar_not_found = this. eval_path_scalar ( & [ "std" , "sys" , "windows" , "c" , "ERROR_ENVVAR_NOT_FOUND" ] ) ?;
126
+ this. set_last_error ( envvar_not_found. not_undef ( ) ?) ?;
149
127
0 // return zero upon failure
150
128
}
151
129
} )
0 commit comments