diff options
| author | Thom Chiovoloni <thom@shift.click> | 2022-11-17 16:14:44 -0800 |
|---|---|---|
| committer | Thom Chiovoloni <thom@shift.click> | 2022-11-17 16:14:44 -0800 |
| commit | b881f66cf9c0882047708c4af34571a27eac28f3 (patch) | |
| tree | e2f40d6bd31afd5532f9799f0d37708a5bb96265 | |
| parent | 36db030a7c3c51cb4484cbd8c8daebcf5057d61c (diff) | |
| download | rust-b881f66cf9c0882047708c4af34571a27eac28f3.tar.gz rust-b881f66cf9c0882047708c4af34571a27eac28f3.zip | |
Don't assume `FILE_ID_BOTH_DIR_INFO` will be aligned
| -rw-r--r-- | library/std/src/sys/windows/fs.rs | 14 |
1 files changed, 9 insertions, 5 deletions
diff --git a/library/std/src/sys/windows/fs.rs b/library/std/src/sys/windows/fs.rs index ade00750c95..cb569e5ba83 100644 --- a/library/std/src/sys/windows/fs.rs +++ b/library/std/src/sys/windows/fs.rs @@ -734,15 +734,19 @@ impl<'a> Iterator for DirBuffIter<'a> { // `FileNameLength` bytes) let (name, is_directory, next_entry) = unsafe { let info = buffer.as_ptr().cast::<c::FILE_ID_BOTH_DIR_INFO>(); - // Guaranteed to be aligned in documentation for + // While this is guaranteed to be aligned in documentation for // https://docs.microsoft.com/en-us/windows/win32/api/winbase/ns-winbase-file_id_both_dir_info - assert!(info.is_aligned()); - let next_entry = (*info).NextEntryOffset as usize; + // it does not seem that reality is so kind, and assuming this + // caused crashes in some cases (https://github.com/rust-lang/rust/issues/104530) + // presumably, this can be blamed on buggy filesystem drivers, but who knows. + let next_entry = ptr::addr_of!((*info).NextEntryOffset).read_unaligned() as usize; + let length = ptr::addr_of!((*info).FileNameLength).read_unaligned() as usize; + let attrs = ptr::addr_of!((*info).FileAttributes).read_unaligned(); let name = crate::slice::from_raw_parts( ptr::addr_of!((*info).FileName).cast::<u16>(), - (*info).FileNameLength as usize / size_of::<u16>(), + length / size_of::<u16>(), ); - let is_directory = ((*info).FileAttributes & c::FILE_ATTRIBUTE_DIRECTORY) != 0; + let is_directory = (attrs & c::FILE_ATTRIBUTE_DIRECTORY) != 0; (name, is_directory, next_entry) }; |
