@@ -1403,24 +1403,40 @@ fn symlink_junction_inner(original: &Path, junction: &Path) -> io::Result<()> {
1403
1403
opts. custom_flags ( c:: FILE_FLAG_OPEN_REPARSE_POINT | c:: FILE_FLAG_BACKUP_SEMANTICS ) ;
1404
1404
let f = File :: open ( junction, & opts) ?;
1405
1405
let h = f. as_inner ( ) . as_raw_handle ( ) ;
1406
-
1407
1406
unsafe {
1408
1407
let mut data = Align8 ( [ MaybeUninit :: < u8 > :: uninit ( ) ; c:: MAXIMUM_REPARSE_DATA_BUFFER_SIZE ] ) ;
1409
1408
let data_ptr = data. 0 . as_mut_ptr ( ) ;
1409
+ let data_end = data_ptr. add ( c:: MAXIMUM_REPARSE_DATA_BUFFER_SIZE ) ;
1410
1410
let db = data_ptr. cast :: < c:: REPARSE_MOUNTPOINT_DATA_BUFFER > ( ) ;
1411
1411
// Zero the header to ensure it's fully initialized, including reserved parameters.
1412
1412
* db = mem:: zeroed ( ) ;
1413
- let buf = ptr:: addr_of_mut!( ( * db) . ReparseTarget ) . cast :: < c:: WCHAR > ( ) ;
1414
- let mut i = 0 ;
1413
+ let reparse_target_slice = {
1414
+ let buf_start = ptr:: addr_of_mut!( ( * db) . ReparseTarget ) . cast :: < c:: WCHAR > ( ) ;
1415
+ // Compute offset in bytes and then divide so that we round down
1416
+ // rather than hit any UB (admittedly this arithmetic should work
1417
+ // out so that this isn't necessary)
1418
+ let buf_len_bytes = usize:: try_from ( data_end. byte_offset_from ( buf_start) ) . unwrap ( ) ;
1419
+ let buf_len_wchars = buf_len_bytes / core:: mem:: size_of :: < c:: WCHAR > ( ) ;
1420
+ core:: slice:: from_raw_parts_mut ( buf_start, buf_len_wchars)
1421
+ } ;
1422
+
1415
1423
// FIXME: this conversion is very hacky
1416
- let v = br"\??\" ;
1417
- let v = v. iter ( ) . map ( |x| * x as u16 ) ;
1418
- for c in v. chain ( original. as_os_str ( ) . encode_wide ( ) ) {
1419
- * buf. add ( i) = c;
1424
+ let iter = br"\??\"
1425
+ . iter ( )
1426
+ . map ( |x| * x as u16 )
1427
+ . chain ( original. as_os_str ( ) . encode_wide ( ) )
1428
+ . chain ( core:: iter:: once ( 0 ) ) ;
1429
+ let mut i = 0 ;
1430
+ for c in iter {
1431
+ if i >= reparse_target_slice. len ( ) {
1432
+ return Err ( crate :: io:: const_io_error!(
1433
+ crate :: io:: ErrorKind :: InvalidFilename ,
1434
+ "Input filename is too long"
1435
+ ) ) ;
1436
+ }
1437
+ reparse_target_slice[ i] = c;
1420
1438
i += 1 ;
1421
1439
}
1422
- * buf. add ( i) = 0 ;
1423
- i += 1 ;
1424
1440
( * db) . ReparseTag = c:: IO_REPARSE_TAG_MOUNT_POINT ;
1425
1441
( * db) . ReparseTargetMaximumLength = ( i * 2 ) as c:: WORD ;
1426
1442
( * db) . ReparseTargetLength = ( ( i - 1 ) * 2 ) as c:: WORD ;
0 commit comments