@@ -8,6 +8,10 @@ mod tests;
8
8
pub const MAIN_SEP_STR : & str = "\\ " ;
9
9
pub const MAIN_SEP : char = '\\' ;
10
10
11
+ // The unsafety here stems from converting between `&OsStr` and `&[u8]`
12
+ // and back. This is safe to do because (1) we only look at ASCII
13
+ // contents of the encoding and (2) new &OsStr values are produced
14
+ // only from ASCII-bounded slices of existing &OsStr values.
11
15
fn os_str_as_u8_slice ( s : & OsStr ) -> & [ u8 ] {
12
16
unsafe { mem:: transmute ( s) }
13
17
}
@@ -33,62 +37,57 @@ pub fn is_valid_drive_letter(disk: u8) -> bool {
33
37
34
38
pub fn parse_prefix ( path : & OsStr ) -> Option < Prefix < ' _ > > {
35
39
use Prefix :: { DeviceNS , Disk , Verbatim , VerbatimDisk , VerbatimUNC , UNC } ;
36
- unsafe {
37
- // The unsafety here stems from converting between &OsStr and &[u8]
38
- // and back. This is safe to do because (1) we only look at ASCII
39
- // contents of the encoding and (2) new &OsStr values are produced
40
- // only from ASCII-bounded slices of existing &OsStr values.
41
- let path = os_str_as_u8_slice ( path) ;
42
40
43
- // \\
44
- if let Some ( path) = path. strip_prefix ( br"\\" ) {
45
- // \\?\
46
- if let Some ( path) = path. strip_prefix ( br"?\" ) {
47
- // \\?\UNC\server\share
48
- if let Some ( path) = path. strip_prefix ( br"UNC\" ) {
49
- let ( server, share) = match get_first_two_components ( path, is_verbatim_sep) {
50
- Some ( ( server, share) ) => {
51
- ( u8_slice_as_os_str ( server) , u8_slice_as_os_str ( share) )
52
- }
53
- None => ( u8_slice_as_os_str ( path) , OsStr :: new ( "" ) ) ,
54
- } ;
55
- return Some ( VerbatimUNC ( server, share) ) ;
56
- } else {
57
- // \\?\path
58
- match path {
59
- // \\?\C:\path
60
- [ c, b':' , b'\\' , ..] if is_valid_drive_letter ( * c) => {
61
- return Some ( VerbatimDisk ( c. to_ascii_uppercase ( ) ) ) ;
62
- }
63
- // \\?\cat_pics
64
- _ => {
65
- let idx = path. iter ( ) . position ( |& b| b == b'\\' ) . unwrap_or ( path. len ( ) ) ;
66
- let slice = & path[ ..idx] ;
67
- return Some ( Verbatim ( u8_slice_as_os_str ( slice) ) ) ;
68
- }
41
+ let path = os_str_as_u8_slice ( path) ;
42
+
43
+ // \\
44
+ if let Some ( path) = path. strip_prefix ( br"\\" ) {
45
+ // \\?\
46
+ if let Some ( path) = path. strip_prefix ( br"?\" ) {
47
+ // \\?\UNC\server\share
48
+ if let Some ( path) = path. strip_prefix ( br"UNC\" ) {
49
+ let ( server, share) = match get_first_two_components ( path, is_verbatim_sep) {
50
+ Some ( ( server, share) ) => unsafe {
51
+ ( u8_slice_as_os_str ( server) , u8_slice_as_os_str ( share) )
52
+ } ,
53
+ None => ( unsafe { u8_slice_as_os_str ( path) } , OsStr :: new ( "" ) ) ,
54
+ } ;
55
+ return Some ( VerbatimUNC ( server, share) ) ;
56
+ } else {
57
+ // \\?\path
58
+ match path {
59
+ // \\?\C:\path
60
+ [ c, b':' , b'\\' , ..] if is_valid_drive_letter ( * c) => {
61
+ return Some ( VerbatimDisk ( c. to_ascii_uppercase ( ) ) ) ;
62
+ }
63
+ // \\?\cat_pics
64
+ _ => {
65
+ let idx = path. iter ( ) . position ( |& b| b == b'\\' ) . unwrap_or ( path. len ( ) ) ;
66
+ let slice = & path[ ..idx] ;
67
+ return Some ( Verbatim ( unsafe { u8_slice_as_os_str ( slice) } ) ) ;
69
68
}
70
69
}
71
- } else if let Some ( path) = path. strip_prefix ( b".\\ " ) {
72
- // \\.\COM42
73
- let idx = path. iter ( ) . position ( |& b| b == b'\\' ) . unwrap_or ( path. len ( ) ) ;
74
- let slice = & path[ ..idx] ;
75
- return Some ( DeviceNS ( u8_slice_as_os_str ( slice) ) ) ;
76
- }
77
- match get_first_two_components ( path, is_sep_byte) {
78
- Some ( ( server, share) ) if !server. is_empty ( ) && !share. is_empty ( ) => {
79
- // \\server\share
80
- return Some ( UNC ( u8_slice_as_os_str ( server) , u8_slice_as_os_str ( share) ) ) ;
81
- }
82
- _ => { }
83
70
}
84
- } else if let [ c, b':' , ..] = path {
85
- // C:
86
- if is_valid_drive_letter ( * c) {
87
- return Some ( Disk ( c. to_ascii_uppercase ( ) ) ) ;
71
+ } else if let Some ( path) = path. strip_prefix ( b".\\ " ) {
72
+ // \\.\COM42
73
+ let idx = path. iter ( ) . position ( |& b| b == b'\\' ) . unwrap_or ( path. len ( ) ) ;
74
+ let slice = & path[ ..idx] ;
75
+ return Some ( DeviceNS ( unsafe { u8_slice_as_os_str ( slice) } ) ) ;
76
+ }
77
+ match get_first_two_components ( path, is_sep_byte) {
78
+ Some ( ( server, share) ) if !server. is_empty ( ) && !share. is_empty ( ) => {
79
+ // \\server\share
80
+ return Some ( unsafe { UNC ( u8_slice_as_os_str ( server) , u8_slice_as_os_str ( share) ) } ) ;
88
81
}
82
+ _ => { }
83
+ }
84
+ } else if let [ c, b':' , ..] = path {
85
+ // C:
86
+ if is_valid_drive_letter ( * c) {
87
+ return Some ( Disk ( c. to_ascii_uppercase ( ) ) ) ;
89
88
}
90
- return None ;
91
89
}
90
+ None
92
91
}
93
92
94
93
/// Returns the first two path components with predicate `f`.
0 commit comments