@@ -3,7 +3,7 @@ use crate::os::windows::prelude::*;
33use crate :: ffi:: OsString ;
44use crate :: fmt;
55use crate :: io:: { self , BorrowedCursor , Error , IoSlice , IoSliceMut , SeekFrom } ;
6- use crate :: mem;
6+ use crate :: mem:: { self , MaybeUninit } ;
77use crate :: os:: windows:: io:: { AsHandle , BorrowedHandle } ;
88use crate :: path:: { Path , PathBuf } ;
99use crate :: ptr;
@@ -326,7 +326,8 @@ impl File {
326326 cvt ( c:: GetFileInformationByHandle ( self . handle . as_raw_handle ( ) , & mut info) ) ?;
327327 let mut reparse_tag = 0 ;
328328 if info. dwFileAttributes & c:: FILE_ATTRIBUTE_REPARSE_POINT != 0 {
329- let mut b = Align8 ( [ 0u8 ; c:: MAXIMUM_REPARSE_DATA_BUFFER_SIZE ] ) ;
329+ let mut b =
330+ Align8 ( [ MaybeUninit :: < u8 > :: uninit ( ) ; c:: MAXIMUM_REPARSE_DATA_BUFFER_SIZE ] ) ;
330331 if let Ok ( ( _, buf) ) = self . reparse_point ( & mut b) {
331332 reparse_tag = ( * buf) . ReparseTag ;
332333 }
@@ -389,7 +390,8 @@ impl File {
389390 attr. file_size = info. AllocationSize as u64 ;
390391 attr. number_of_links = Some ( info. NumberOfLinks ) ;
391392 if attr. file_type ( ) . is_reparse_point ( ) {
392- let mut b = Align8 ( [ 0 ; c:: MAXIMUM_REPARSE_DATA_BUFFER_SIZE ] ) ;
393+ let mut b =
394+ Align8 ( [ MaybeUninit :: < u8 > :: uninit ( ) ; c:: MAXIMUM_REPARSE_DATA_BUFFER_SIZE ] ) ;
393395 if let Ok ( ( _, buf) ) = self . reparse_point ( & mut b) {
394396 attr. reparse_tag = ( * buf) . ReparseTag ;
395397 }
@@ -463,7 +465,7 @@ impl File {
463465 // avoid narrowing provenance to the actual `REPARSE_DATA_BUFFER`.
464466 fn reparse_point (
465467 & self ,
466- space : & mut Align8 < [ u8 ] > ,
468+ space : & mut Align8 < [ MaybeUninit < u8 > ] > ,
467469 ) -> io:: Result < ( c:: DWORD , * const c:: REPARSE_DATA_BUFFER ) > {
468470 unsafe {
469471 let mut bytes = 0 ;
@@ -488,7 +490,7 @@ impl File {
488490 }
489491
490492 fn readlink ( & self ) -> io:: Result < PathBuf > {
491- let mut space = Align8 ( [ 0u8 ; c:: MAXIMUM_REPARSE_DATA_BUFFER_SIZE ] ) ;
493+ let mut space = Align8 ( [ MaybeUninit :: < u8 > :: uninit ( ) ; c:: MAXIMUM_REPARSE_DATA_BUFFER_SIZE ] ) ;
492494 let ( _bytes, buf) = self . reparse_point ( & mut space) ?;
493495 unsafe {
494496 let ( path_buffer, subst_off, subst_len, relative) = match ( * buf) . ReparseTag {
@@ -658,12 +660,16 @@ impl File {
658660
659661/// A buffer for holding directory entries.
660662struct DirBuff {
661- buffer : Box < Align8 < [ u8 ; Self :: BUFFER_SIZE ] > > ,
663+ buffer : Box < Align8 < [ MaybeUninit < u8 > ; Self :: BUFFER_SIZE ] > > ,
662664}
663665impl DirBuff {
664666 const BUFFER_SIZE : usize = 1024 ;
665667 fn new ( ) -> Self {
666- Self { buffer : Box :: new ( Align8 ( [ 0u8 ; Self :: BUFFER_SIZE ] ) ) }
668+ Self {
669+ // Safety: `Align8<[MaybeUninit<u8>; N]>` does not need
670+ // initialization.
671+ buffer : unsafe { Box :: new_uninit ( ) . assume_init ( ) } ,
672+ }
667673 }
668674 fn capacity ( & self ) -> usize {
669675 self . buffer . 0 . len ( )
@@ -676,8 +682,8 @@ impl DirBuff {
676682 DirBuffIter :: new ( self )
677683 }
678684}
679- impl AsRef < [ u8 ] > for DirBuff {
680- fn as_ref ( & self ) -> & [ u8 ] {
685+ impl AsRef < [ MaybeUninit < u8 > ] > for DirBuff {
686+ fn as_ref ( & self ) -> & [ MaybeUninit < u8 > ] {
681687 & self . buffer . 0
682688 }
683689}
@@ -686,7 +692,7 @@ impl AsRef<[u8]> for DirBuff {
686692///
687693/// Currently only returns file names (UTF-16 encoded).
688694struct DirBuffIter < ' a > {
689- buffer : Option < & ' a [ u8 ] > ,
695+ buffer : Option < & ' a [ MaybeUninit < u8 > ] > ,
690696 cursor : usize ,
691697}
692698impl < ' a > DirBuffIter < ' a > {
@@ -701,9 +707,13 @@ impl<'a> Iterator for DirBuffIter<'a> {
701707 let buffer = & self . buffer ?[ self . cursor ..] ;
702708
703709 // Get the name and next entry from the buffer.
704- // SAFETY: The buffer contains a `FILE_ID_BOTH_DIR_INFO` struct but the
705- // last field (the file name) is unsized. So an offset has to be
706- // used to get the file name slice.
710+ // SAFETY:
711+ // - The buffer contains a `FILE_ID_BOTH_DIR_INFO` struct but the last
712+ // field (the file name) is unsized. So an offset has to be used to
713+ // get the file name slice.
714+ // - The OS has guaranteed initialization of the fields of
715+ // `FILE_ID_BOTH_DIR_INFO` and the trailing filename (for at least
716+ // `FileNameLength` bytes)
707717 let ( name, is_directory, next_entry) = unsafe {
708718 let info = buffer. as_ptr ( ) . cast :: < c:: FILE_ID_BOTH_DIR_INFO > ( ) ;
709719 // Guaranteed to be aligned in documentation for
@@ -1349,7 +1359,7 @@ fn symlink_junction_inner(original: &Path, junction: &Path) -> io::Result<()> {
13491359 let h = f. as_inner ( ) . as_raw_handle ( ) ;
13501360
13511361 unsafe {
1352- let mut data = Align8 ( [ 0u8 ; c:: MAXIMUM_REPARSE_DATA_BUFFER_SIZE ] ) ;
1362+ let mut data = Align8 ( [ MaybeUninit :: < u8 > :: uninit ( ) ; c:: MAXIMUM_REPARSE_DATA_BUFFER_SIZE ] ) ;
13531363 let data_ptr = data. 0 . as_mut_ptr ( ) ;
13541364 let db = data_ptr. cast :: < c:: REPARSE_MOUNTPOINT_DATA_BUFFER > ( ) ;
13551365 let buf = ptr:: addr_of_mut!( ( * db) . ReparseTarget ) . cast :: < c:: WCHAR > ( ) ;
0 commit comments