@@ -3,7 +3,7 @@ use crate::os::windows::prelude::*;
3
3
use crate :: ffi:: OsString ;
4
4
use crate :: fmt;
5
5
use crate :: io:: { self , BorrowedCursor , Error , IoSlice , IoSliceMut , SeekFrom } ;
6
- use crate :: mem;
6
+ use crate :: mem:: { self , MaybeUninit } ;
7
7
use crate :: os:: windows:: io:: { AsHandle , BorrowedHandle } ;
8
8
use crate :: path:: { Path , PathBuf } ;
9
9
use crate :: ptr;
@@ -326,7 +326,8 @@ impl File {
326
326
cvt ( c:: GetFileInformationByHandle ( self . handle . as_raw_handle ( ) , & mut info) ) ?;
327
327
let mut reparse_tag = 0 ;
328
328
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 ] ) ;
330
331
if let Ok ( ( _, buf) ) = self . reparse_point ( & mut b) {
331
332
reparse_tag = ( * buf) . ReparseTag ;
332
333
}
@@ -389,7 +390,8 @@ impl File {
389
390
attr. file_size = info. AllocationSize as u64 ;
390
391
attr. number_of_links = Some ( info. NumberOfLinks ) ;
391
392
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 ] ) ;
393
395
if let Ok ( ( _, buf) ) = self . reparse_point ( & mut b) {
394
396
attr. reparse_tag = ( * buf) . ReparseTag ;
395
397
}
@@ -463,7 +465,7 @@ impl File {
463
465
// avoid narrowing provenance to the actual `REPARSE_DATA_BUFFER`.
464
466
fn reparse_point (
465
467
& self ,
466
- space : & mut Align8 < [ u8 ] > ,
468
+ space : & mut Align8 < [ MaybeUninit < u8 > ] > ,
467
469
) -> io:: Result < ( c:: DWORD , * const c:: REPARSE_DATA_BUFFER ) > {
468
470
unsafe {
469
471
let mut bytes = 0 ;
@@ -488,7 +490,7 @@ impl File {
488
490
}
489
491
490
492
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 ] ) ;
492
494
let ( _bytes, buf) = self . reparse_point ( & mut space) ?;
493
495
unsafe {
494
496
let ( path_buffer, subst_off, subst_len, relative) = match ( * buf) . ReparseTag {
@@ -658,12 +660,16 @@ impl File {
658
660
659
661
/// A buffer for holding directory entries.
660
662
struct DirBuff {
661
- buffer : Box < Align8 < [ u8 ; Self :: BUFFER_SIZE ] > > ,
663
+ buffer : Box < Align8 < [ MaybeUninit < u8 > ; Self :: BUFFER_SIZE ] > > ,
662
664
}
663
665
impl DirBuff {
664
666
const BUFFER_SIZE : usize = 1024 ;
665
667
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
+ }
667
673
}
668
674
fn capacity ( & self ) -> usize {
669
675
self . buffer . 0 . len ( )
@@ -676,8 +682,8 @@ impl DirBuff {
676
682
DirBuffIter :: new ( self )
677
683
}
678
684
}
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 > ] {
681
687
& self . buffer . 0
682
688
}
683
689
}
@@ -686,7 +692,7 @@ impl AsRef<[u8]> for DirBuff {
686
692
///
687
693
/// Currently only returns file names (UTF-16 encoded).
688
694
struct DirBuffIter < ' a > {
689
- buffer : Option < & ' a [ u8 ] > ,
695
+ buffer : Option < & ' a [ MaybeUninit < u8 > ] > ,
690
696
cursor : usize ,
691
697
}
692
698
impl < ' a > DirBuffIter < ' a > {
@@ -701,9 +707,13 @@ impl<'a> Iterator for DirBuffIter<'a> {
701
707
let buffer = & self . buffer ?[ self . cursor ..] ;
702
708
703
709
// 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)
707
717
let ( name, is_directory, next_entry) = unsafe {
708
718
let info = buffer. as_ptr ( ) . cast :: < c:: FILE_ID_BOTH_DIR_INFO > ( ) ;
709
719
// Guaranteed to be aligned in documentation for
@@ -1349,7 +1359,7 @@ fn symlink_junction_inner(original: &Path, junction: &Path) -> io::Result<()> {
1349
1359
let h = f. as_inner ( ) . as_raw_handle ( ) ;
1350
1360
1351
1361
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 ] ) ;
1353
1363
let data_ptr = data. 0 . as_mut_ptr ( ) ;
1354
1364
let db = data_ptr. cast :: < c:: REPARSE_MOUNTPOINT_DATA_BUFFER > ( ) ;
1355
1365
let buf = ptr:: addr_of_mut!( ( * db) . ReparseTarget ) . cast :: < c:: WCHAR > ( ) ;
0 commit comments