11use crate :: os:: windows:: prelude:: * ;
22
3+ use crate :: borrow:: Cow ;
34use crate :: ffi:: OsString ;
45use crate :: fmt;
56use crate :: io:: { self , BorrowedCursor , Error , IoSlice , IoSliceMut , SeekFrom } ;
@@ -719,7 +720,7 @@ impl<'a> DirBuffIter<'a> {
719720 }
720721}
721722impl < ' 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.
770779fn 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