Rollup merge of #93459 - tavianator:dirent-copy-only-reclen, r=cuviper
fs: Don't copy d_name from struct dirent The dirent returned from readdir() is only guaranteed to be valid for d_reclen bytes on common platforms. Since we copy the name separately anyway, we can copy everything except d_name into DirEntry::entry. Fixes #93384.
This commit is contained in:
@@ -489,10 +489,18 @@ impl Iterator for ReadDir {
|
||||
};
|
||||
}
|
||||
|
||||
// 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 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 ret = DirEntry {
|
||||
entry: *entry_ptr,
|
||||
entry,
|
||||
// d_name is guaranteed to be null-terminated.
|
||||
name: CStr::from_ptr((*entry_ptr).d_name.as_ptr()).to_owned(),
|
||||
name: CStr::from_ptr(entry_name as *const _).to_owned(),
|
||||
dir: Arc::clone(&self.inner),
|
||||
};
|
||||
if ret.name_bytes() != b"." && ret.name_bytes() != b".." {
|
||||
|
||||
Reference in New Issue
Block a user