diff --git a/library/std/src/sys/unix/fs.rs b/library/std/src/sys/unix/fs.rs index 8bd0b9b14af..3d0162940a6 100644 --- a/library/std/src/sys/unix/fs.rs +++ b/library/std/src/sys/unix/fs.rs @@ -491,14 +491,18 @@ fn next(&mut self) -> Option> { // Only d_reclen bytes of *entry_ptr are valid, so we can't just copy the // whole thing (#93384). Instead, copy everything except the name. + let mut copy: dirent64 = mem::zeroed(); + // Can't dereference entry_ptr, so use the local entry to get + // offsetof(struct dirent, d_name) + let copy_bytes = &mut copy as *mut _ as *mut u8; + let copy_name = &mut copy.d_name as *mut _ as *mut u8; + let name_offset = copy_name.offset_from(copy_bytes) as usize; let entry_bytes = entry_ptr as *const u8; - let entry_name = ptr::addr_of!((*entry_ptr).d_name) as *const u8; - let name_offset = entry_name.offset_from(entry_bytes) as usize; - let mut entry: dirent64 = mem::zeroed(); - ptr::copy_nonoverlapping(entry_bytes, &mut entry as *mut _ as *mut u8, name_offset); + let entry_name = entry_bytes.add(name_offset); + ptr::copy_nonoverlapping(entry_bytes, copy_bytes, name_offset); let ret = DirEntry { - entry, + entry: copy, // d_name is guaranteed to be null-terminated. name: CStr::from_ptr(entry_name as *const _).to_owned(), dir: Arc::clone(&self.inner),