Skip to content

Commit 749eede

Browse files
committed
Respond to review comments
1 parent 39126cc commit 749eede

File tree

2 files changed

+44
-12
lines changed

2 files changed

+44
-12
lines changed

src/shims/windows/fs.rs

Lines changed: 36 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -388,21 +388,21 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
388388

389389
let class = this.read_scalar(class)?.to_u32()?;
390390
let buffer_size = this.read_scalar(buffer_size)?.to_u32()?;
391-
let file_info = this.read_pointer(file_information)?;
391+
let file_information = this.read_pointer(file_information)?;
392392
this.check_ptr_access(
393-
file_info,
393+
file_information,
394394
Size::from_bytes(buffer_size),
395395
CheckInAllocMsg::MemoryAccess,
396396
)?;
397397

398-
let file = this.read_handle(file, "GetFileInformationByHandle")?;
398+
let file = this.read_handle(file, "SetFileInformationByHandle")?;
399399
let fd_num = if let Handle::File(fd_num) = file {
400400
fd_num
401401
} else {
402-
this.invalid_handle("GetFileInformationByHandle")?
402+
this.invalid_handle("SetFileInformationByHandle")?
403403
};
404404
let Some(desc) = this.machine.fds.get(fd_num) else {
405-
this.invalid_handle("GetFileInformationByHandle")?
405+
this.invalid_handle("SetFileInformationByHandle")?
406406
};
407407
let file = desc.downcast::<FileHandle>().ok_or_else(|| {
408408
err_unsup_format!(
@@ -411,10 +411,8 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
411411
})?;
412412

413413
if class == this.eval_windows_u32("c", "FileEndOfFileInfo") {
414-
let ptr = this.deref_pointer_as(
415-
file_information,
416-
this.windows_ty_layout("FILE_END_OF_FILE_INFO"),
417-
)?;
414+
let ptr = this
415+
.ptr_to_mplace(file_information, this.windows_ty_layout("FILE_END_OF_FILE_INFO"));
418416
let new_len =
419417
this.read_scalar(&this.project_field_named(&ptr, "EndOfFile")?)?.to_i64()?;
420418
match file.file.set_len(new_len.try_into().unwrap()) {
@@ -424,6 +422,35 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
424422
interp_ok(this.eval_windows("c", "FALSE"))
425423
}
426424
}
425+
} else if class == this.eval_windows_u32("c", "FileAllocationInfo") {
426+
// File allocation size is independent of file EOF position on Windows, except that
427+
// EOF must be <= allocation size. So we only do something if the file is bigger than
428+
// the requested allocation size.
429+
let ptr = this
430+
.ptr_to_mplace(file_information, this.windows_ty_layout("FILE_ALLOCATION_INFO"));
431+
let new_alloc_size: u64 = this
432+
.read_scalar(&this.project_field_named(&ptr, "AllocationSize")?)?
433+
.to_i64()?
434+
.try_into()
435+
.unwrap();
436+
let old_len = match file.file.metadata() {
437+
Ok(m) => m.len(),
438+
Err(e) => {
439+
this.set_last_error(e)?;
440+
return interp_ok(this.eval_windows("c", "FALSE"));
441+
}
442+
};
443+
if new_alloc_size < old_len {
444+
match file.file.set_len(new_alloc_size) {
445+
Ok(_) => interp_ok(this.eval_windows("c", "TRUE")),
446+
Err(e) => {
447+
this.set_last_error(e)?;
448+
interp_ok(this.eval_windows("c", "FALSE"))
449+
}
450+
}
451+
} else {
452+
interp_ok(this.eval_windows("c", "TRUE"))
453+
}
427454
} else {
428455
throw_unsup_format!(
429456
"SetFileInformationByHandle: Unsupported `FileInformationClass` value {}",

tests/pass/shims/fs.rs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,9 @@ fn test_file() {
7676
// However, writing 0 bytes can succeed or fail.
7777
let _ignore = file.write(&[]);
7878

79+
// Test calling File::create on an existing file, since that uses a different code path
80+
File::create(&path).unwrap();
81+
7982
// Removing file should succeed.
8083
remove_file(&path).unwrap();
8184
}
@@ -208,9 +211,11 @@ fn test_file_set_len() {
208211

209212
// Can't use set_len on a file not opened for writing
210213
let file = OpenOptions::new().read(true).open(&path).unwrap();
211-
assert_eq!(
212-
if cfg!(windows) { ErrorKind::PermissionDenied } else { ErrorKind::InvalidInput },
213-
file.set_len(14).unwrap_err().kind()
214+
// Due to https://github.com/rust-lang/miri/issues/4457, we have to assume the failure could
215+
// be either of the Windows or Unix kind, no matter which platform we're on.
216+
assert!(
217+
[ErrorKind::PermissionDenied, ErrorKind::InvalidInput]
218+
.contains(&file.set_len(14).unwrap_err().kind())
214219
);
215220

216221
remove_file(&path).unwrap();

0 commit comments

Comments
 (0)