From b881f66cf9c0882047708c4af34571a27eac28f3 Mon Sep 17 00:00:00 2001 From: Thom Chiovoloni Date: Thu, 17 Nov 2022 16:14:44 -0800 Subject: [PATCH] Don't assume `FILE_ID_BOTH_DIR_INFO` will be aligned --- library/std/src/sys/windows/fs.rs | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/library/std/src/sys/windows/fs.rs b/library/std/src/sys/windows/fs.rs index ade00750c959c..cb569e5ba8399 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::(); - // 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::(), - (*info).FileNameLength as usize / size_of::(), + length / size_of::(), ); - let is_directory = ((*info).FileAttributes & c::FILE_ATTRIBUTE_DIRECTORY) != 0; + let is_directory = (attrs & c::FILE_ATTRIBUTE_DIRECTORY) != 0; (name, is_directory, next_entry) };