@@ -25,12 +25,12 @@ impl<'tcx> EnvVars<'tcx> {
2525 ecx : & mut InterpCx < ' mir , ' tcx , Evaluator < ' tcx > > ,
2626 mut excluded_env_vars : Vec < String > ,
2727 ) -> 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" {
2930 // Exclude `TERM` var to avoid terminfo trying to open the termcap file.
3031 excluded_env_vars. push ( "TERM" . to_owned ( ) ) ;
3132 }
3233 if ecx. machine . communicate {
33- let target_os = ecx. tcx . sess . target . target . target_os . as_str ( ) ;
3434 for ( name, value) in env:: vars ( ) {
3535 if !excluded_env_vars. contains ( & name) {
3636 let var_ptr = match target_os {
@@ -68,28 +68,6 @@ fn alloc_env_var_as_wide_str<'mir, 'tcx>(
6868 Ok ( ecx. alloc_os_str_as_wide_str ( name_osstring. as_os_str ( ) , MiriMemoryKind :: Machine . into ( ) ) )
6969}
7070
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-
9371impl < ' mir , ' tcx > EvalContextExt < ' mir , ' tcx > for crate :: MiriEvalContext < ' mir , ' tcx > { }
9472pub trait EvalContextExt < ' mir , ' tcx : ' mir > : crate :: MiriEvalContextExt < ' mir , ' tcx > {
9573 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
126104 let name_offset_bytes =
127105 u64:: try_from ( name. len ( ) ) . unwrap ( ) . checked_add ( 1 ) . unwrap ( ) . checked_mul ( 2 ) . unwrap ( ) ;
128106 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) ?;
129108
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 ( ) ? ;
131110 // `buf_size` represents the size in characters.
132111 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 {
141115 // If the function succeeds, the return value is the number of characters stored in the buffer pointed to by lpBuffer,
142116 // 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+ }
146123 }
147124 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 ( ) ?) ?;
149127 0 // return zero upon failure
150128 }
151129 } )
0 commit comments