@@ -221,7 +221,9 @@ pub enum ReadConsoleError {
221221}
222222
223223pub fn access ( path : & Path , mode : u8 ) -> bool {
224- let wide = path. as_os_str ( ) . to_wide_with_nul ( ) ;
224+ let Ok ( wide) = path. as_os_str ( ) . to_wide_with_nul ( ) else {
225+ return false ;
226+ } ;
225227 let attr = unsafe { GetFileAttributesW ( wide. as_ptr ( ) ) } ;
226228 attr != INVALID_FILE_ATTRIBUTES
227229 && ( mode & 2 == 0
@@ -237,7 +239,7 @@ pub fn remove(path: &Path) -> io::Result<()> {
237239 IO_REPARSE_TAG_MOUNT_POINT , IO_REPARSE_TAG_SYMLINK ,
238240 } ;
239241
240- let wide_path = path. as_os_str ( ) . to_wide_with_nul ( ) ;
242+ let wide_path = path. as_os_str ( ) . to_wide_with_nul ( ) ? ;
241243 let attrs = unsafe { GetFileAttributesW ( wide_path. as_ptr ( ) ) } ;
242244
243245 let mut is_directory = false ;
@@ -384,7 +386,7 @@ pub fn fchmod(fd: i32, mode: u32, write_bit: u32) -> io::Result<()> {
384386}
385387
386388pub fn win32_lchmod ( path : & OsStr , mode : u32 , write_bit : u32 ) -> io:: Result < ( ) > {
387- let wide = path. to_wide_with_nul ( ) ;
389+ let wide = path. to_wide_with_nul ( ) ? ;
388390 let attr = unsafe { GetFileAttributesW ( wide. as_ptr ( ) ) } . check_ne ( INVALID_FILE_ATTRIBUTES ) ?;
389391 let new_attr = if mode & write_bit != 0 {
390392 attr & !FILE_ATTRIBUTE_READONLY
@@ -417,7 +419,7 @@ pub fn chmod_follow(path: &widestring::WideCStr, mode: u32, write_bit: u32) -> i
417419}
418420
419421pub fn find_first_file_name ( path : & Path ) -> io:: Result < OsString > {
420- let wide_path = path. as_os_str ( ) . to_wide_with_nul ( ) ;
422+ let wide_path = path. as_os_str ( ) . to_wide_with_nul ( ) ? ;
421423 let mut find_data: WIN32_FIND_DATAW = unsafe { core:: mem:: zeroed ( ) } ;
422424
423425 let handle = unsafe { FindFirstFileW ( wide_path. as_ptr ( ) , & mut find_data) } . check_valid ( ) ?;
@@ -449,7 +451,7 @@ pub fn path_isdevdrive(path: &Path) -> io::Result<bool> {
449451 reserved : u32 ,
450452 }
451453
452- let wide_path = path. as_os_str ( ) . to_wide_with_nul ( ) ;
454+ let wide_path = path. as_os_str ( ) . to_wide_with_nul ( ) ? ;
453455 let mut volume = [ 0u16 ; MAX_PATH as usize ] ;
454456 unsafe { GetVolumePathNameW ( wide_path. as_ptr ( ) , volume. as_mut_ptr ( ) , volume. len ( ) as _ ) }
455457 . check_win32_bool ( ) ?;
@@ -616,7 +618,7 @@ fn win32_xstat_attributes_from_dir(
616618 BY_HANDLE_FILE_INFORMATION , FILE_ATTRIBUTE_REPARSE_POINT ,
617619 } ;
618620
619- let wide: Vec < u16 > = path. to_wide_with_nul ( ) ;
621+ let wide: Vec < u16 > = path. to_wide_with_nul ( ) ? ;
620622 let mut find_data: WIN32_FIND_DATAW = unsafe { core:: mem:: zeroed ( ) } ;
621623
622624 let handle = unsafe { FindFirstFileW ( wide. as_ptr ( ) , & mut find_data) } . check_valid ( ) ?;
@@ -654,7 +656,7 @@ fn win32_xstat_slow_impl(path: &OsStr, traverse: bool) -> io::Result<StatStruct>
654656 } ,
655657 } ;
656658
657- let wide: Vec < u16 > = path. to_wide_with_nul ( ) ;
659+ let wide: Vec < u16 > = path. to_wide_with_nul ( ) ? ;
658660 let access = FILE_READ_ATTRIBUTES ;
659661 let mut flags = FILE_FLAG_BACKUP_SEMANTICS ;
660662 if !traverse {
@@ -925,7 +927,9 @@ pub fn test_file_type_by_name(path: &Path, tested_type: TestType) -> bool {
925927 if !matches ! ( tested_type, TestType :: RegularFile | TestType :: Directory ) {
926928 flags |= FILE_FLAG_OPEN_REPARSE_POINT ;
927929 }
928- let wide_path = path. as_os_str ( ) . to_wide_with_nul ( ) ;
930+ let Ok ( wide_path) = path. as_os_str ( ) . to_wide_with_nul ( ) else {
931+ return false ;
932+ } ;
929933 let handle = unsafe {
930934 CreateFileW (
931935 wide_path. as_ptr ( ) ,
@@ -991,7 +995,9 @@ pub fn test_file_exists_by_name(path: &Path, follow_links: bool) -> bool {
991995 }
992996 }
993997
994- let wide_path = path. as_os_str ( ) . to_wide_with_nul ( ) ;
998+ let Ok ( wide_path) = path. as_os_str ( ) . to_wide_with_nul ( ) else {
999+ return false ;
1000+ } ;
9951001 let mut flags = FILE_FLAG_BACKUP_SEMANTICS ;
9961002 if !follow_links {
9971003 flags |= FILE_FLAG_OPEN_REPARSE_POINT ;
@@ -1049,7 +1055,9 @@ pub fn test_file_exists_by_name(path: &Path, follow_links: bool) -> bool {
10491055}
10501056
10511057pub fn path_exists_via_open ( path : & Path , follow_links : bool ) -> bool {
1052- let wide_path = path. as_os_str ( ) . to_wide_with_nul ( ) ;
1058+ let Ok ( wide_path) = path. as_os_str ( ) . to_wide_with_nul ( ) else {
1059+ return false ;
1060+ } ;
10531061 let mut flags = FILE_FLAG_BACKUP_SEMANTICS ;
10541062 if !follow_links {
10551063 flags |= FILE_FLAG_OPEN_REPARSE_POINT ;
@@ -1271,7 +1279,10 @@ pub fn readlink(path: &Path) -> Result<OsString, ReadlinkError> {
12711279 IO_REPARSE_TAG_MOUNT_POINT , IO_REPARSE_TAG_SYMLINK ,
12721280 } ;
12731281
1274- let wide_path = path. as_os_str ( ) . to_wide_with_nul ( ) ;
1282+ let wide_path = path
1283+ . as_os_str ( )
1284+ . to_wide_with_nul ( )
1285+ . map_err ( ReadlinkError :: Io ) ?;
12751286 let handle = unsafe {
12761287 CreateFileW (
12771288 wide_path. as_ptr ( ) ,
@@ -1372,7 +1383,7 @@ pub fn kill(pid: u32, sig: u32) -> io::Result<()> {
13721383pub fn getfinalpathname ( path : & Path ) -> io:: Result < OsString > {
13731384 use windows_sys:: Win32 :: Storage :: FileSystem :: { GetFinalPathNameByHandleW , VOLUME_NAME_DOS } ;
13741385
1375- let wide = path. as_os_str ( ) . to_wide_with_nul ( ) ;
1386+ let wide = path. as_os_str ( ) . to_wide_with_nul ( ) ? ;
13761387 let handle = unsafe {
13771388 CreateFileW (
13781389 wide. as_ptr ( ) ,
@@ -1410,7 +1421,7 @@ pub fn getfinalpathname(path: &Path) -> io::Result<OsString> {
14101421}
14111422
14121423pub fn getfullpathname ( path : & Path ) -> io:: Result < OsString > {
1413- let wide = path. as_os_str ( ) . to_wide_with_nul ( ) ;
1424+ let wide = path. as_os_str ( ) . to_wide_with_nul ( ) ? ;
14141425 let mut buffer = vec ! [ 0u16 ; MAX_PATH as usize ] ;
14151426 let mut ret = unsafe {
14161427 windows_sys:: Win32 :: Storage :: FileSystem :: GetFullPathNameW (
@@ -1438,7 +1449,7 @@ pub fn getfullpathname(path: &Path) -> io::Result<OsString> {
14381449}
14391450
14401451pub fn getvolumepathname ( path : & Path ) -> io:: Result < OsString > {
1441- let wide = path. as_os_str ( ) . to_wide_with_nul ( ) ;
1452+ let wide = path. as_os_str ( ) . to_wide_with_nul ( ) ? ;
14421453 let buflen = core:: cmp:: max ( wide. len ( ) , MAX_PATH as usize ) ;
14431454 let mut buffer = vec ! [ 0u16 ; buflen] ;
14441455 unsafe {
@@ -1455,7 +1466,7 @@ pub fn getvolumepathname(path: &Path) -> io::Result<OsString> {
14551466pub fn getdiskusage ( path : & Path ) -> io:: Result < ( u64 , u64 ) > {
14561467 use windows_sys:: Win32 :: Storage :: FileSystem :: GetDiskFreeSpaceExW ;
14571468
1458- let wide = path. as_os_str ( ) . to_wide_with_nul ( ) ;
1469+ let wide = path. as_os_str ( ) . to_wide_with_nul ( ) ? ;
14591470 let mut free_to_me = 0u64 ;
14601471 let mut total = 0u64 ;
14611472 let mut free = 0u64 ;
@@ -1587,7 +1598,7 @@ pub fn listvolumes() -> io::Result<Vec<OsString>> {
15871598}
15881599
15891600pub fn listmounts ( volume : & Path ) -> io:: Result < Vec < OsString > > {
1590- let wide = volume. as_os_str ( ) . to_wide_with_nul ( ) ;
1601+ let wide = volume. as_os_str ( ) . to_wide_with_nul ( ) ? ;
15911602 let mut buflen: u32 = MAX_PATH + 1 ;
15921603 let mut buffer = vec ! [ 0u16 ; buflen as usize ] ;
15931604
@@ -1679,6 +1690,7 @@ pub fn getppid() -> u32 {
16791690
16801691pub fn path_skip_root ( path : & widestring:: WideCStr ) -> Option < usize > {
16811692 let mut end: * const u16 = core:: ptr:: null ( ) ;
1693+ // SAFETY: `path` is a valid pointer to a nul terminated wide string without interior nuls.
16821694 let hr = unsafe { windows_sys:: Win32 :: UI :: Shell :: PathCchSkipRoot ( path. as_ptr ( ) , & mut end) } ;
16831695 if hr >= 0 {
16841696 assert ! ( !end. is_null( ) ) ;
0 commit comments