@@ -226,7 +226,7 @@ impl File {
226
226
}
227
227
228
228
pub fn open ( path : & Path , opts : & OpenOptions ) -> io:: Result < File > {
229
- let path = to_utf16 ( path) ;
229
+ let path = try! ( to_u16s ( path) ) ;
230
230
let handle = unsafe {
231
231
c:: CreateFileW ( path. as_ptr ( ) ,
232
232
opts. get_desired_access ( ) ,
@@ -377,8 +377,13 @@ impl fmt::Debug for File {
377
377
}
378
378
}
379
379
380
- pub fn to_utf16 ( s : & Path ) -> Vec < u16 > {
381
- s. as_os_str ( ) . encode_wide ( ) . chain ( Some ( 0 ) ) . collect ( )
380
+ pub fn to_u16s ( s : & Path ) -> io:: Result < Vec < u16 > > {
381
+ let mut maybe_result = s. as_os_str ( ) . encode_wide ( ) . collect ( ) ;
382
+ if maybe_result. iter ( ) . any ( |& u| u == 0 ) {
383
+ return Err ( io:: Error :: new ( io:: ErrorKind :: InvalidInput , "paths cannot contain NULs" ) ) ;
384
+ }
385
+ maybe_result. push ( 0 ) ;
386
+ Ok ( maybe_result)
382
387
}
383
388
384
389
impl FileAttr {
@@ -449,7 +454,7 @@ impl DirBuilder {
449
454
pub fn new ( ) -> DirBuilder { DirBuilder }
450
455
451
456
pub fn mkdir ( & self , p : & Path ) -> io:: Result < ( ) > {
452
- let p = to_utf16 ( p ) ;
457
+ let p = try! ( to_u16s ( p ) ) ;
453
458
try!( cvt ( unsafe {
454
459
c:: CreateDirectoryW ( p. as_ptr ( ) , ptr:: null_mut ( ) )
455
460
} ) ) ;
@@ -460,7 +465,7 @@ impl DirBuilder {
460
465
pub fn readdir ( p : & Path ) -> io:: Result < ReadDir > {
461
466
let root = p. to_path_buf ( ) ;
462
467
let star = p. join ( "*" ) ;
463
- let path = to_utf16 ( & star) ;
468
+ let path = try! ( to_u16s ( & star) ) ;
464
469
465
470
unsafe {
466
471
let mut wfd = mem:: zeroed ( ) ;
@@ -478,22 +483,22 @@ pub fn readdir(p: &Path) -> io::Result<ReadDir> {
478
483
}
479
484
480
485
pub fn unlink ( p : & Path ) -> io:: Result < ( ) > {
481
- let p_utf16 = to_utf16 ( p ) ;
482
- try!( cvt ( unsafe { c:: DeleteFileW ( p_utf16 . as_ptr ( ) ) } ) ) ;
486
+ let p_u16s = try! ( to_u16s ( p ) ) ;
487
+ try!( cvt ( unsafe { c:: DeleteFileW ( p_u16s . as_ptr ( ) ) } ) ) ;
483
488
Ok ( ( ) )
484
489
}
485
490
486
491
pub fn rename ( old : & Path , new : & Path ) -> io:: Result < ( ) > {
487
- let old = to_utf16 ( old) ;
488
- let new = to_utf16 ( new) ;
492
+ let old = try! ( to_u16s ( old) ) ;
493
+ let new = try! ( to_u16s ( new) ) ;
489
494
try!( cvt ( unsafe {
490
495
c:: MoveFileExW ( old. as_ptr ( ) , new. as_ptr ( ) , c:: MOVEFILE_REPLACE_EXISTING )
491
496
} ) ) ;
492
497
Ok ( ( ) )
493
498
}
494
499
495
500
pub fn rmdir ( p : & Path ) -> io:: Result < ( ) > {
496
- let p = to_utf16 ( p ) ;
501
+ let p = try! ( to_u16s ( p ) ) ;
497
502
try!( cvt ( unsafe { c:: RemoveDirectoryW ( p. as_ptr ( ) ) } ) ) ;
498
503
Ok ( ( ) )
499
504
}
@@ -508,8 +513,8 @@ pub fn symlink(src: &Path, dst: &Path) -> io::Result<()> {
508
513
}
509
514
510
515
pub fn symlink_inner ( src : & Path , dst : & Path , dir : bool ) -> io:: Result < ( ) > {
511
- let src = to_utf16 ( src) ;
512
- let dst = to_utf16 ( dst) ;
516
+ let src = try! ( to_u16s ( src) ) ;
517
+ let dst = try! ( to_u16s ( dst) ) ;
513
518
let flags = if dir { c:: SYMBOLIC_LINK_FLAG_DIRECTORY } else { 0 } ;
514
519
try!( cvt ( unsafe {
515
520
c:: CreateSymbolicLinkW ( dst. as_ptr ( ) , src. as_ptr ( ) , flags) as c:: BOOL
@@ -518,8 +523,8 @@ pub fn symlink_inner(src: &Path, dst: &Path, dir: bool) -> io::Result<()> {
518
523
}
519
524
520
525
pub fn link ( src : & Path , dst : & Path ) -> io:: Result < ( ) > {
521
- let src = to_utf16 ( src) ;
522
- let dst = to_utf16 ( dst) ;
526
+ let src = try! ( to_u16s ( src) ) ;
527
+ let dst = try! ( to_u16s ( dst) ) ;
523
528
try!( cvt ( unsafe {
524
529
c:: CreateHardLinkW ( dst. as_ptr ( ) , src. as_ptr ( ) , ptr:: null_mut ( ) )
525
530
} ) ) ;
@@ -545,10 +550,10 @@ pub fn stat(p: &Path) -> io::Result<FileAttr> {
545
550
}
546
551
547
552
pub fn lstat ( p : & Path ) -> io:: Result < FileAttr > {
548
- let utf16 = to_utf16 ( p ) ;
553
+ let u16s = try! ( to_u16s ( p ) ) ;
549
554
unsafe {
550
555
let mut attr: FileAttr = mem:: zeroed ( ) ;
551
- try!( cvt ( c:: GetFileAttributesExW ( utf16 . as_ptr ( ) ,
556
+ try!( cvt ( c:: GetFileAttributesExW ( u16s . as_ptr ( ) ,
552
557
c:: GetFileExInfoStandard ,
553
558
& mut attr. data as * mut _ as * mut _ ) ) ) ;
554
559
if attr. is_reparse_point ( ) {
@@ -562,7 +567,7 @@ pub fn lstat(p: &Path) -> io::Result<FileAttr> {
562
567
}
563
568
564
569
pub fn set_perm ( p : & Path , perm : FilePermissions ) -> io:: Result < ( ) > {
565
- let p = to_utf16 ( p ) ;
570
+ let p = try! ( to_u16s ( p ) ) ;
566
571
unsafe {
567
572
try!( cvt ( c:: SetFileAttributesW ( p. as_ptr ( ) , perm. attrs ) ) ) ;
568
573
Ok ( ( ) )
@@ -602,8 +607,8 @@ pub fn copy(from: &Path, to: &Path) -> io::Result<u64> {
602
607
* ( lpData as * mut i64 ) = TotalBytesTransferred ;
603
608
c:: PROGRESS_CONTINUE
604
609
}
605
- let pfrom = to_utf16 ( from) ;
606
- let pto = to_utf16 ( to ) ;
610
+ let pfrom = try! ( to_u16s ( from) ) ;
611
+ let pto = try! ( to_u16s ( to ) ) ;
607
612
let mut size = 0i64 ;
608
613
try!( cvt ( unsafe {
609
614
c:: CopyFileExW ( pfrom. as_ptr ( ) , pto. as_ptr ( ) , Some ( callback) ,
0 commit comments