Skip to content

Commit 2f907eb

Browse files
thomccpietroalbini
authored andcommitted
Handle the case that even the filename array is unaligned.
1 parent 2eff0c7 commit 2f907eb

File tree

1 file changed

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

1 file changed

+14
-5
lines changed

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

+14-5
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use crate::os::windows::prelude::*;
22

3+
use crate::borrow::Cow;
34
use crate::ffi::OsString;
45
use crate::fmt;
56
use crate::io::{self, BorrowedCursor, Error, IoSlice, IoSliceMut, SeekFrom};
@@ -719,7 +720,7 @@ impl<'a> DirBuffIter<'a> {
719720
}
720721
}
721722
impl<'a> Iterator for DirBuffIter<'a> {
722-
type Item = (&'a [u16], bool);
723+
type Item = (Cow<'a, [u16]>, bool);
723724
fn next(&mut self) -> Option<Self::Item> {
724725
use crate::mem::size_of;
725726
let buffer = &self.buffer?[self.cursor..];
@@ -742,7 +743,7 @@ impl<'a> Iterator for DirBuffIter<'a> {
742743
let next_entry = ptr::addr_of!((*info).NextEntryOffset).read_unaligned() as usize;
743744
let length = ptr::addr_of!((*info).FileNameLength).read_unaligned() as usize;
744745
let attrs = ptr::addr_of!((*info).FileAttributes).read_unaligned();
745-
let name = crate::slice::from_raw_parts(
746+
let name = from_maybe_unaligned(
746747
ptr::addr_of!((*info).FileName).cast::<u16>(),
747748
length / size_of::<u16>(),
748749
);
@@ -759,13 +760,21 @@ impl<'a> Iterator for DirBuffIter<'a> {
759760

760761
// Skip `.` and `..` pseudo entries.
761762
const DOT: u16 = b'.' as u16;
762-
match name {
763+
match &name[..] {
763764
[DOT] | [DOT, DOT] => self.next(),
764765
_ => Some((name, is_directory)),
765766
}
766767
}
767768
}
768769

770+
unsafe fn from_maybe_unaligned<'a>(p: *const u16, len: usize) -> Cow<'a, [u16]> {
771+
if p.is_aligned() {
772+
Cow::Borrowed(crate::slice::from_raw_parts(p, len))
773+
} else {
774+
Cow::Owned((0..len).map(|i| p.add(i).read_unaligned()).collect())
775+
}
776+
}
777+
769778
/// Open a link relative to the parent directory, ensure no symlinks are followed.
770779
fn open_link_no_reparse(parent: &File, name: &[u16], access: u32) -> io::Result<File> {
771780
// This is implemented using the lower level `NtCreateFile` function as
@@ -1121,13 +1130,13 @@ fn remove_dir_all_iterative(f: &File, delete: fn(&File) -> io::Result<()>) -> io
11211130
if is_directory {
11221131
let child_dir = open_link_no_reparse(
11231132
&dir,
1124-
name,
1133+
&name,
11251134
c::SYNCHRONIZE | c::DELETE | c::FILE_LIST_DIRECTORY,
11261135
)?;
11271136
dirlist.push(child_dir);
11281137
} else {
11291138
for i in 1..=MAX_RETRIES {
1130-
let result = open_link_no_reparse(&dir, name, c::SYNCHRONIZE | c::DELETE);
1139+
let result = open_link_no_reparse(&dir, &name, c::SYNCHRONIZE | c::DELETE);
11311140
match result {
11321141
Ok(f) => delete(&f)?,
11331142
// Already deleted, so skip.

0 commit comments

Comments
 (0)