File tree 3 files changed +24
-1
lines changed 3 files changed +24
-1
lines changed Original file line number Diff line number Diff line change @@ -2336,6 +2336,7 @@ fn path_to_file_url_segments_windows(
2336
2336
}
2337
2337
let mut components = path. components ( ) ;
2338
2338
2339
+ let host_start = serialization. len ( ) + 1 ;
2339
2340
let host_end;
2340
2341
let host_internal;
2341
2342
match components. next ( ) {
@@ -2362,15 +2363,24 @@ fn path_to_file_url_segments_windows(
2362
2363
_ => return Err ( ( ) ) ,
2363
2364
}
2364
2365
2366
+ let mut path_only_has_prefix = true ;
2365
2367
for component in components {
2366
2368
if component == Component :: RootDir {
2367
2369
continue ;
2368
2370
}
2371
+ path_only_has_prefix = false ;
2369
2372
// FIXME: somehow work with non-unicode?
2370
2373
let component = component. as_os_str ( ) . to_str ( ) . ok_or ( ( ) ) ?;
2371
2374
serialization. push ( '/' ) ;
2372
2375
serialization. extend ( percent_encode ( component. as_bytes ( ) , PATH_SEGMENT ) ) ;
2373
2376
}
2377
+ // A windows drive letter must end with a slash.
2378
+ if serialization. len ( ) > host_start
2379
+ && parser:: is_windows_drive_letter ( & serialization[ host_start..] )
2380
+ && path_only_has_prefix
2381
+ {
2382
+ serialization. push ( '/' ) ;
2383
+ }
2374
2384
Ok ( ( host_end, host_internal) )
2375
2385
}
2376
2386
Original file line number Diff line number Diff line change @@ -1393,7 +1393,8 @@ pub fn to_u32(i: usize) -> ParseResult<u32> {
1393
1393
1394
1394
/// Wether the scheme is file:, the path has a single segment, and that segment
1395
1395
/// is a Windows drive letter
1396
- fn is_windows_drive_letter ( segment : & str ) -> bool {
1396
+ #[ inline]
1397
+ pub fn is_windows_drive_letter ( segment : & str ) -> bool {
1397
1398
segment. len ( ) == 2 && starts_with_windows_drive_letter ( segment)
1398
1399
}
1399
1400
Original file line number Diff line number Diff line change @@ -549,3 +549,15 @@ fn test_options_reuse() {
549
549
assert_eq ! ( url. as_str( ) , "http://mozilla.org/sub/path" ) ;
550
550
assert_eq ! ( * violations. borrow( ) , vec!( ExpectedDoubleSlash , Backslash ) ) ;
551
551
}
552
+
553
+ /// https://github.com/servo/rust-url/issues/505
554
+ #[ test]
555
+ fn test_url_from_file_path ( ) {
556
+ use std:: path:: PathBuf ;
557
+ use url:: Url ;
558
+
559
+ let p = PathBuf :: from ( "c:///" ) ;
560
+ let u = Url :: from_file_path ( p) . unwrap ( ) ;
561
+ let path = u. to_file_path ( ) . unwrap ( ) ;
562
+ assert_eq ! ( "C:\\ " , path. to_str( ) . unwrap( ) ) ;
563
+ }
You can’t perform that action at this time.
0 commit comments