@@ -218,12 +218,14 @@ pub enum ReadConsoleError {
218218}
219219
220220pub fn access ( path : & Path , mode : u8 ) -> bool {
221- let wide = path. as_os_str ( ) . to_wide_with_nul ( ) ;
221+ let Ok ( wide) = path. as_os_str ( ) . to_wide_with_nul ( ) else {
222+ return false ;
223+ } ;
222224 let attr = unsafe { GetFileAttributesW ( wide. as_ptr ( ) ) } ;
223- attr != INVALID_FILE_ATTRIBUTES
225+ Ok ( attr != INVALID_FILE_ATTRIBUTES
224226 && ( mode & 2 == 0
225227 || attr & FILE_ATTRIBUTE_READONLY == 0
226- || attr & windows_sys:: Win32 :: Storage :: FileSystem :: FILE_ATTRIBUTE_DIRECTORY != 0 )
228+ || attr & windows_sys:: Win32 :: Storage :: FileSystem :: FILE_ATTRIBUTE_DIRECTORY != 0 ) )
227229}
228230
229231pub fn remove ( path : & Path ) -> io:: Result < ( ) > {
@@ -234,7 +236,10 @@ pub fn remove(path: &Path) -> io::Result<()> {
234236 IO_REPARSE_TAG_MOUNT_POINT , IO_REPARSE_TAG_SYMLINK ,
235237 } ;
236238
237- let wide_path = path. as_os_str ( ) . to_wide_with_nul ( ) ;
239+ let wide_path = path
240+ . as_os_str ( )
241+ . to_wide_with_nul ( )
242+ . map_err ( io:: Error :: other) ?;
238243 let attrs = unsafe { GetFileAttributesW ( wide_path. as_ptr ( ) ) } ;
239244
240245 let mut is_directory = false ;
@@ -381,7 +386,7 @@ pub fn fchmod(fd: i32, mode: u32, write_bit: u32) -> io::Result<()> {
381386}
382387
383388pub fn win32_lchmod ( path : & OsStr , mode : u32 , write_bit : u32 ) -> io:: Result < ( ) > {
384- let wide = path. to_wide_with_nul ( ) ;
389+ let wide = path. to_wide_with_nul ( ) ? ;
385390 let attr = unsafe { GetFileAttributesW ( wide. as_ptr ( ) ) } . check_ne ( INVALID_FILE_ATTRIBUTES ) ?;
386391 let new_attr = if mode & write_bit != 0 {
387392 attr & !FILE_ATTRIBUTE_READONLY
@@ -414,7 +419,7 @@ pub fn chmod_follow(path: &widestring::WideCStr, mode: u32, write_bit: u32) -> i
414419}
415420
416421pub fn find_first_file_name ( path : & Path ) -> io:: Result < OsString > {
417- let wide_path = path. as_os_str ( ) . to_wide_with_nul ( ) ;
422+ let wide_path = path. as_os_str ( ) . to_wide_with_nul ( ) ? ;
418423 let mut find_data: WIN32_FIND_DATAW = unsafe { core:: mem:: zeroed ( ) } ;
419424
420425 let handle = unsafe { FindFirstFileW ( wide_path. as_ptr ( ) , & mut find_data) } . check_valid ( ) ?;
@@ -446,7 +451,7 @@ pub fn path_isdevdrive(path: &Path) -> io::Result<bool> {
446451 reserved : u32 ,
447452 }
448453
449- let wide_path = path. as_os_str ( ) . to_wide_with_nul ( ) ;
454+ let wide_path = path. as_os_str ( ) . to_wide_with_nul ( ) ? ;
450455 let mut volume = [ 0u16 ; MAX_PATH as usize ] ;
451456 unsafe { GetVolumePathNameW ( wide_path. as_ptr ( ) , volume. as_mut_ptr ( ) , volume. len ( ) as _ ) }
452457 . check_win32_bool ( ) ?;
@@ -613,7 +618,7 @@ fn win32_xstat_attributes_from_dir(
613618 BY_HANDLE_FILE_INFORMATION , FILE_ATTRIBUTE_REPARSE_POINT ,
614619 } ;
615620
616- let wide: Vec < u16 > = path. to_wide_with_nul ( ) ;
621+ let wide: Vec < u16 > = path. to_wide_with_nul ( ) ? ;
617622 let mut find_data: WIN32_FIND_DATAW = unsafe { core:: mem:: zeroed ( ) } ;
618623
619624 let handle = unsafe { FindFirstFileW ( wide. as_ptr ( ) , & mut find_data) } . check_valid ( ) ?;
@@ -651,7 +656,7 @@ fn win32_xstat_slow_impl(path: &OsStr, traverse: bool) -> io::Result<StatStruct>
651656 } ,
652657 } ;
653658
654- let wide: Vec < u16 > = path. to_wide_with_nul ( ) ;
659+ let wide: Vec < u16 > = path. to_wide_with_nul ( ) ? ;
655660 let access = FILE_READ_ATTRIBUTES ;
656661 let mut flags = FILE_FLAG_BACKUP_SEMANTICS ;
657662 if !traverse {
@@ -922,7 +927,9 @@ pub fn test_file_type_by_name(path: &Path, tested_type: TestType) -> bool {
922927 if !matches ! ( tested_type, TestType :: RegularFile | TestType :: Directory ) {
923928 flags |= FILE_FLAG_OPEN_REPARSE_POINT ;
924929 }
925- 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+ } ;
926933 let handle = unsafe {
927934 CreateFileW (
928935 wide_path. as_ptr ( ) ,
@@ -988,7 +995,9 @@ pub fn test_file_exists_by_name(path: &Path, follow_links: bool) -> bool {
988995 }
989996 }
990997
991- 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+ } ;
9921001 let mut flags = FILE_FLAG_BACKUP_SEMANTICS ;
9931002 if !follow_links {
9941003 flags |= FILE_FLAG_OPEN_REPARSE_POINT ;
@@ -1046,7 +1055,9 @@ pub fn test_file_exists_by_name(path: &Path, follow_links: bool) -> bool {
10461055}
10471056
10481057pub fn path_exists_via_open ( path : & Path , follow_links : bool ) -> bool {
1049- 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+ } ;
10501061 let mut flags = FILE_FLAG_BACKUP_SEMANTICS ;
10511062 if !follow_links {
10521063 flags |= FILE_FLAG_OPEN_REPARSE_POINT ;
@@ -1270,7 +1281,10 @@ pub fn readlink(path: &Path) -> Result<OsString, ReadlinkError> {
12701281 IO_REPARSE_TAG_MOUNT_POINT , IO_REPARSE_TAG_SYMLINK ,
12711282 } ;
12721283
1273- let wide_path = path. as_os_str ( ) . to_wide_with_nul ( ) ;
1284+ let wide_path = path
1285+ . as_os_str ( )
1286+ . to_wide_with_nul ( )
1287+ . map_err ( ReadlinkError :: Io ) ?;
12741288 let handle = unsafe {
12751289 CreateFileW (
12761290 wide_path. as_ptr ( ) ,
@@ -1369,7 +1383,7 @@ pub fn kill(pid: u32, sig: u32) -> io::Result<()> {
13691383pub fn getfinalpathname ( path : & Path ) -> io:: Result < OsString > {
13701384 use windows_sys:: Win32 :: Storage :: FileSystem :: { GetFinalPathNameByHandleW , VOLUME_NAME_DOS } ;
13711385
1372- let wide = path. as_os_str ( ) . to_wide_with_nul ( ) ;
1386+ let wide = path. as_os_str ( ) . to_wide_with_nul ( ) ? ;
13731387 let handle = unsafe {
13741388 CreateFileW (
13751389 wide. as_ptr ( ) ,
@@ -1407,7 +1421,7 @@ pub fn getfinalpathname(path: &Path) -> io::Result<OsString> {
14071421}
14081422
14091423pub fn getfullpathname ( path : & Path ) -> io:: Result < OsString > {
1410- let wide = path. as_os_str ( ) . to_wide_with_nul ( ) ;
1424+ let wide = path. as_os_str ( ) . to_wide_with_nul ( ) ? ;
14111425 let mut buffer = vec ! [ 0u16 ; MAX_PATH as usize ] ;
14121426 let mut ret = unsafe {
14131427 windows_sys:: Win32 :: Storage :: FileSystem :: GetFullPathNameW (
@@ -1435,7 +1449,7 @@ pub fn getfullpathname(path: &Path) -> io::Result<OsString> {
14351449}
14361450
14371451pub fn getvolumepathname ( path : & Path ) -> io:: Result < OsString > {
1438- let wide = path. as_os_str ( ) . to_wide_with_nul ( ) ;
1452+ let wide = path. as_os_str ( ) . to_wide_with_nul ( ) ? ;
14391453 let buflen = core:: cmp:: max ( wide. len ( ) , MAX_PATH as usize ) ;
14401454 let mut buffer = vec ! [ 0u16 ; buflen] ;
14411455 unsafe {
@@ -1452,7 +1466,7 @@ pub fn getvolumepathname(path: &Path) -> io::Result<OsString> {
14521466pub fn getdiskusage ( path : & Path ) -> io:: Result < ( u64 , u64 ) > {
14531467 use windows_sys:: Win32 :: Storage :: FileSystem :: GetDiskFreeSpaceExW ;
14541468
1455- let wide = path. as_os_str ( ) . to_wide_with_nul ( ) ;
1469+ let wide = path. as_os_str ( ) . to_wide_with_nul ( ) ? ;
14561470 let mut free_to_me = 0u64 ;
14571471 let mut total = 0u64 ;
14581472 let mut free = 0u64 ;
@@ -1584,7 +1598,7 @@ pub fn listvolumes() -> io::Result<Vec<OsString>> {
15841598}
15851599
15861600pub fn listmounts ( volume : & Path ) -> io:: Result < Vec < OsString > > {
1587- let wide = volume. as_os_str ( ) . to_wide_with_nul ( ) ;
1601+ let wide = volume. as_os_str ( ) . to_wide_with_nul ( ) ? ;
15881602 let mut buflen: u32 = MAX_PATH + 1 ;
15891603 let mut buffer = vec ! [ 0u16 ; buflen as usize ] ;
15901604
@@ -1676,6 +1690,7 @@ pub fn getppid() -> u32 {
16761690
16771691pub fn path_skip_root ( path : & widestring:: WideCStr ) -> Option < usize > {
16781692 let mut end: * const u16 = core:: ptr:: null ( ) ;
1693+ // SAFETY: `path` is a valid pointer to a nul terminated wide string without interior nuls.
16791694 let hr = unsafe { windows_sys:: Win32 :: UI :: Shell :: PathCchSkipRoot ( path. as_ptr ( ) , & mut end) } ;
16801695 if hr >= 0 {
16811696 assert ! ( !end. is_null( ) ) ;
0 commit comments