Skip to content

Commit 00acfab

Browse files
committed
windows buffer size protocol: turns out std resets last_error to 0; let's require that in general
1 parent 342943b commit 00acfab

File tree

2 files changed

+15
-11
lines changed

2 files changed

+15
-11
lines changed

src/tools/miri/src/shims/env.rs

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -160,10 +160,12 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
160160
this.assert_target_os("windows", "GetEnvironmentVariableW");
161161

162162
let name_ptr = this.read_pointer(name_op)?;
163+
let buf_ptr = this.read_pointer(buf_op)?;
164+
let buf_size = this.read_scalar(size_op)?.to_u32()?; // in characters
165+
163166
let name = this.read_os_str_from_wide_str(name_ptr)?;
164167
Ok(match this.machine.env_vars.map.get(&name) {
165168
Some(&var_ptr) => {
166-
this.set_last_error(Scalar::from_u32(0))?; // make sure this is unambiguously not an error
167169
// The offset is used to strip the "{name}=" part of the string.
168170
#[rustfmt::skip]
169171
let name_offset_bytes = u64::try_from(name.len()).unwrap()
@@ -172,14 +174,14 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
172174
let var_ptr = var_ptr.offset(Size::from_bytes(name_offset_bytes), this)?;
173175
let var = this.read_os_str_from_wide_str(var_ptr)?;
174176

175-
let buf_ptr = this.read_pointer(buf_op)?;
176-
// `buf_size` represents the size in characters.
177-
let buf_size = u64::from(this.read_scalar(size_op)?.to_u32()?);
178-
Scalar::from_u32(windows_check_buffer_size(
179-
this.write_os_str_to_wide_str(
180-
&var, buf_ptr, buf_size, /*truncate*/ false,
181-
)?,
182-
))
177+
Scalar::from_u32(windows_check_buffer_size(this.write_os_str_to_wide_str(
178+
&var,
179+
buf_ptr,
180+
buf_size.into(),
181+
/*truncate*/ false,
182+
)?))
183+
// This can in fact return 0. It is up to the caller to set last_error to 0
184+
// beforehand and check it afterwards to exclude that case.
183185
}
184186
None => {
185187
let envvar_not_found = this.eval_windows("c", "ERROR_ENVVAR_NOT_FOUND");
@@ -375,7 +377,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
375377
// If we cannot get the current directory, we return 0
376378
match env::current_dir() {
377379
Ok(cwd) => {
378-
this.set_last_error(Scalar::from_u32(0))?; // make sure this is unambiguously not an error
380+
// This can in fact return 0. It is up to the caller to set last_error to 0
381+
// beforehand and check it afterwards to exclude that case.
379382
return Ok(Scalar::from_u32(windows_check_buffer_size(
380383
this.write_path_to_wide_str(&cwd, buf, size, /*truncate*/ false)?,
381384
)));

src/tools/miri/src/shims/windows/foreign_items.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -231,7 +231,6 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
231231
Scalar::from_u32(0) // return zero upon failure
232232
}
233233
Ok(abs_filename) => {
234-
this.set_last_error(Scalar::from_u32(0))?; // make sure this is unambiguously not an error
235234
Scalar::from_u32(helpers::windows_check_buffer_size(
236235
this.write_path_to_wide_str(
237236
&abs_filename,
@@ -240,6 +239,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
240239
/*truncate*/ false,
241240
)?,
242241
))
242+
// This can in fact return 0. It is up to the caller to set last_error to 0
243+
// beforehand and check it afterwards to exclude that case.
243244
}
244245
};
245246
this.write_scalar(result, dest)?;

0 commit comments

Comments
 (0)