@@ -11,7 +11,7 @@ use crate::slice;
1111use crate :: sync:: Arc ;
1212use crate :: sys:: handle:: Handle ;
1313use crate :: sys:: time:: SystemTime ;
14- use crate :: sys:: { c, cvt} ;
14+ use crate :: sys:: { c, cvt, AlignedAs } ;
1515use crate :: sys_common:: { AsInner , FromInner , IntoInner } ;
1616use crate :: thread;
1717
@@ -47,6 +47,9 @@ pub struct ReadDir {
4747 first : Option < c:: WIN32_FIND_DATAW > ,
4848}
4949
50+ type AlignedReparseBuf =
51+ AlignedAs < c:: REPARSE_DATA_BUFFER , [ u8 ; c:: MAXIMUM_REPARSE_DATA_BUFFER_SIZE ] > ;
52+
5053struct FindNextFileHandle ( c:: HANDLE ) ;
5154
5255unsafe impl Send for FindNextFileHandle { }
@@ -326,9 +329,9 @@ impl File {
326329 cvt ( c:: GetFileInformationByHandle ( self . handle . as_raw_handle ( ) , & mut info) ) ?;
327330 let mut reparse_tag = 0 ;
328331 if info. dwFileAttributes & c:: FILE_ATTRIBUTE_REPARSE_POINT != 0 {
329- let mut b = [ 0 ; c:: MAXIMUM_REPARSE_DATA_BUFFER_SIZE ] ;
332+ let mut b = AlignedReparseBuf :: new ( [ 0u8 ; c:: MAXIMUM_REPARSE_DATA_BUFFER_SIZE ] ) ;
330333 if let Ok ( ( _, buf) ) = self . reparse_point ( & mut b) {
331- reparse_tag = buf. ReparseTag ;
334+ reparse_tag = ( * buf) . ReparseTag ;
332335 }
333336 }
334337 Ok ( FileAttr {
@@ -389,7 +392,7 @@ impl File {
389392 attr. file_size = info. AllocationSize as u64 ;
390393 attr. number_of_links = Some ( info. NumberOfLinks ) ;
391394 if attr. file_type ( ) . is_reparse_point ( ) {
392- let mut b = [ 0 ; c:: MAXIMUM_REPARSE_DATA_BUFFER_SIZE ] ;
395+ let mut b = AlignedReparseBuf :: new ( [ 0 ; c:: MAXIMUM_REPARSE_DATA_BUFFER_SIZE ] ) ;
393396 if let Ok ( ( _, buf) ) = self . reparse_point ( & mut b) {
394397 attr. reparse_tag = buf. ReparseTag ;
395398 }
@@ -458,10 +461,13 @@ impl File {
458461 Ok ( Self { handle : self . handle . try_clone ( ) ? } )
459462 }
460463
461- fn reparse_point < ' a > (
464+ // NB: returned pointer is derived from `space`, and has provenance to
465+ // match. A raw pointer is returned rather than a reference in order to
466+ // avoid narrowing provenance to the actual `REPARSE_DATA_BUFFER`.
467+ fn reparse_point (
462468 & self ,
463- space : & ' a mut [ u8 ; c :: MAXIMUM_REPARSE_DATA_BUFFER_SIZE ] ,
464- ) -> io:: Result < ( c:: DWORD , & ' a c:: REPARSE_DATA_BUFFER ) > {
469+ space : & mut AlignedReparseBuf ,
470+ ) -> io:: Result < ( c:: DWORD , * const c:: REPARSE_DATA_BUFFER ) > {
465471 unsafe {
466472 let mut bytes = 0 ;
467473 cvt ( {
@@ -470,36 +476,38 @@ impl File {
470476 c:: FSCTL_GET_REPARSE_POINT ,
471477 ptr:: null_mut ( ) ,
472478 0 ,
473- space. as_mut_ptr ( ) as * mut _ ,
474- space. len ( ) as c:: DWORD ,
479+ space. value . as_mut_ptr ( ) as * mut _ ,
480+ space. value . len ( ) as c:: DWORD ,
475481 & mut bytes,
476482 ptr:: null_mut ( ) ,
477483 )
478484 } ) ?;
479- Ok ( ( bytes, & * ( space. as_ptr ( ) as * const c:: REPARSE_DATA_BUFFER ) ) )
485+ Ok ( ( bytes, space. value . as_ptr ( ) . cast :: < c:: REPARSE_DATA_BUFFER > ( ) ) )
480486 }
481487 }
482488
483489 fn readlink ( & self ) -> io:: Result < PathBuf > {
484- let mut space = [ 0u8 ; c:: MAXIMUM_REPARSE_DATA_BUFFER_SIZE ] ;
490+ let mut space = AlignedReparseBuf :: new ( [ 0u8 ; c:: MAXIMUM_REPARSE_DATA_BUFFER_SIZE ] ) ;
485491 let ( _bytes, buf) = self . reparse_point ( & mut space) ?;
486492 unsafe {
487- let ( path_buffer, subst_off, subst_len, relative) = match buf. ReparseTag {
493+ let ( path_buffer, subst_off, subst_len, relative) = match ( * buf) . ReparseTag {
488494 c:: IO_REPARSE_TAG_SYMLINK => {
489495 let info: * const c:: SYMBOLIC_LINK_REPARSE_BUFFER =
490- & buf. rest as * const _ as * const _ ;
496+ ptr:: addr_of!( ( * buf) . rest) . cast ( ) ;
497+ assert ! ( info. is_aligned( ) ) ;
491498 (
492- & ( * info) . PathBuffer as * const _ as * const u16 ,
499+ ptr :: addr_of! ( ( * info) . PathBuffer ) . cast :: < u16 > ( ) ,
493500 ( * info) . SubstituteNameOffset / 2 ,
494501 ( * info) . SubstituteNameLength / 2 ,
495502 ( * info) . Flags & c:: SYMLINK_FLAG_RELATIVE != 0 ,
496503 )
497504 }
498505 c:: IO_REPARSE_TAG_MOUNT_POINT => {
499506 let info: * const c:: MOUNT_POINT_REPARSE_BUFFER =
500- & buf. rest as * const _ as * const _ ;
507+ ptr:: addr_of!( ( * buf) . rest) . cast ( ) ;
508+ assert ! ( info. is_aligned( ) ) ;
501509 (
502- & ( * info) . PathBuffer as * const _ as * const u16 ,
510+ ptr :: addr_of! ( ( * info) . PathBuffer ) . cast :: < u16 > ( ) ,
503511 ( * info) . SubstituteNameOffset / 2 ,
504512 ( * info) . SubstituteNameLength / 2 ,
505513 false ,
0 commit comments