@@ -212,18 +212,35 @@ pub fn symlink_dir(config: &Config, src: &Path, dest: &Path) -> io::Result<()> {
212
212
struct Align8 < T > ( T ) ;
213
213
let mut data = Align8 ( [ 0u8 ; MAXIMUM_REPARSE_DATA_BUFFER_SIZE as usize ] ) ;
214
214
let db = data. 0 . as_mut_ptr ( ) as * mut REPARSE_MOUNTPOINT_DATA_BUFFER ;
215
- let buf = core:: ptr:: addr_of_mut!( ( * db) . ReparseTarget ) as * mut u16 ;
216
- let mut i = 0 ;
215
+ let end = db. cast :: < u8 > ( ) . add ( MAXIMUM_REPARSE_DATA_BUFFER_SIZE as usize ) ;
216
+ let reparse_target_slice = {
217
+ let buf_start = core:: ptr:: addr_of_mut!( ( * db) . ReparseTarget ) . cast :: < u16 > ( ) ;
218
+ // Compute offset in bytes and then divide so that we round down
219
+ // rather than hit any UB (admittedly this arithmetic should work
220
+ // out so that this isn't necessary)
221
+ let buf_len_bytes =
222
+ usize:: try_from ( end. offset_from ( buf_start. cast :: < u8 > ( ) ) ) . unwrap ( ) ;
223
+ let buf_len_wchars = buf_len_bytes / core:: mem:: size_of :: < u16 > ( ) ;
224
+ core:: slice:: from_raw_parts_mut ( buf_start, buf_len_wchars)
225
+ } ;
226
+
217
227
// FIXME: this conversion is very hacky
218
- let v = br"\??\" ;
219
- let v = v. iter ( ) . map ( |x| * x as u16 ) ;
220
- for c in v. chain ( target. as_os_str ( ) . encode_wide ( ) . skip ( 4 ) ) {
221
- * buf. offset ( i) = c;
228
+ let iter = br"\??\"
229
+ . iter ( )
230
+ . map ( |x| * x as u16 )
231
+ . chain ( path. iter ( ) . copied ( ) )
232
+ . chain ( core:: iter:: once ( 0 ) ) ;
233
+ let mut i = 0 ;
234
+ for c in iter {
235
+ if i >= reparse_target_slice. len ( ) {
236
+ return Err ( io:: Error :: new (
237
+ io:: ErrorKind :: Other ,
238
+ format ! ( "path too long for reparse target: {target:?}" ) ,
239
+ ) ) ;
240
+ }
241
+ reparse_target_slice[ i] = c;
222
242
i += 1 ;
223
243
}
224
- * buf. offset ( i) = 0 ;
225
- i += 1 ;
226
-
227
244
( * db) . ReparseTag = IO_REPARSE_TAG_MOUNT_POINT ;
228
245
( * db) . ReparseTargetMaximumLength = ( i * 2 ) as u16 ;
229
246
( * db) . ReparseTargetLength = ( ( i - 1 ) * 2 ) as u16 ;
0 commit comments