@@ -2508,6 +2508,7 @@ fn path_to_file_url_segments_windows(
25082508 }
25092509 let mut components = path. components ( ) ;
25102510
2511+ let host_start = serialization. len ( ) + 1 ;
25112512 let host_end;
25122513 let host_internal;
25132514 match components. next ( ) {
@@ -2534,15 +2535,24 @@ fn path_to_file_url_segments_windows(
25342535 _ => return Err ( ( ) ) ,
25352536 }
25362537
2538+ let mut path_only_has_prefix = true ;
25372539 for component in components {
25382540 if component == Component :: RootDir {
25392541 continue ;
25402542 }
2543+ path_only_has_prefix = false ;
25412544 // FIXME: somehow work with non-unicode?
25422545 let component = component. as_os_str ( ) . to_str ( ) . ok_or ( ( ) ) ?;
25432546 serialization. push ( '/' ) ;
25442547 serialization. extend ( percent_encode ( component. as_bytes ( ) , PATH_SEGMENT ) ) ;
25452548 }
2549+ // A windows drive letter must end with a slash.
2550+ if serialization. len ( ) > host_start
2551+ && parser:: is_windows_drive_letter ( & serialization[ host_start..] )
2552+ && path_only_has_prefix
2553+ {
2554+ serialization. push ( '/' ) ;
2555+ }
25462556 Ok ( ( host_end, host_internal) )
25472557}
25482558
@@ -2567,6 +2577,14 @@ fn file_url_segments_to_pathbuf(
25672577 bytes. push ( b'/' ) ;
25682578 bytes. extend ( percent_decode ( segment. as_bytes ( ) ) ) ;
25692579 }
2580+ // A windows drive letter must end with a slash.
2581+ if bytes. len ( ) > 2 {
2582+ if matches ! ( bytes[ bytes. len( ) -2 ] , b'a' ..=b'z' | b'A' ..=b'Z' )
2583+ && matches ! ( bytes[ bytes. len( ) - 1 ] , b':' | b'|' )
2584+ {
2585+ bytes. push ( b'/' ) ;
2586+ }
2587+ }
25702588 let os_str = OsStr :: from_bytes ( & bytes) ;
25712589 let path = PathBuf :: from ( os_str) ;
25722590 debug_assert ! (
0 commit comments