Skip to content

Commit 2eff0c7

Browse files
thomccpietroalbini
authored andcommitted
Don't assume FILE_ID_BOTH_DIR_INFO will be aligned
1 parent 40aec30 commit 2eff0c7

File tree

1 file changed

+9
-5
lines changed
  • library/std/src/sys/windows

1 file changed

+9
-5
lines changed

library/std/src/sys/windows/fs.rs

+9-5
Original file line numberDiff line numberDiff line change
@@ -734,15 +734,19 @@ impl<'a> Iterator for DirBuffIter<'a> {
734734
// `FileNameLength` bytes)
735735
let (name, is_directory, next_entry) = unsafe {
736736
let info = buffer.as_ptr().cast::<c::FILE_ID_BOTH_DIR_INFO>();
737-
// Guaranteed to be aligned in documentation for
737+
// While this is guaranteed to be aligned in documentation for
738738
// https://docs.microsoft.com/en-us/windows/win32/api/winbase/ns-winbase-file_id_both_dir_info
739-
assert!(info.is_aligned());
740-
let next_entry = (*info).NextEntryOffset as usize;
739+
// it does not seem that reality is so kind, and assuming this
740+
// caused crashes in some cases (https://github.com/rust-lang/rust/issues/104530)
741+
// presumably, this can be blamed on buggy filesystem drivers, but who knows.
742+
let next_entry = ptr::addr_of!((*info).NextEntryOffset).read_unaligned() as usize;
743+
let length = ptr::addr_of!((*info).FileNameLength).read_unaligned() as usize;
744+
let attrs = ptr::addr_of!((*info).FileAttributes).read_unaligned();
741745
let name = crate::slice::from_raw_parts(
742746
ptr::addr_of!((*info).FileName).cast::<u16>(),
743-
(*info).FileNameLength as usize / size_of::<u16>(),
747+
length / size_of::<u16>(),
744748
);
745-
let is_directory = ((*info).FileAttributes & c::FILE_ATTRIBUTE_DIRECTORY) != 0;
749+
let is_directory = (attrs & c::FILE_ATTRIBUTE_DIRECTORY) != 0;
746750

747751
(name, is_directory, next_entry)
748752
};

0 commit comments

Comments
 (0)