@@ -2336,6 +2336,7 @@ fn path_to_file_url_segments_windows(
23362336 }
23372337 let mut components = path. components ( ) ;
23382338
2339+ let host_start = serialization. len ( ) + 1 ;
23392340 let host_end;
23402341 let host_internal;
23412342 match components. next ( ) {
@@ -2362,15 +2363,24 @@ fn path_to_file_url_segments_windows(
23622363 _ => return Err ( ( ) ) ,
23632364 }
23642365
2366+ let mut path_only_has_prefix = true ;
23652367 for component in components {
23662368 if component == Component :: RootDir {
23672369 continue ;
23682370 }
2371+ path_only_has_prefix = false ;
23692372 // FIXME: somehow work with non-unicode?
23702373 let component = component. as_os_str ( ) . to_str ( ) . ok_or ( ( ) ) ?;
23712374 serialization. push ( '/' ) ;
23722375 serialization. extend ( percent_encode ( component. as_bytes ( ) , PATH_SEGMENT ) ) ;
23732376 }
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+ }
23742384 Ok ( ( host_end, host_internal) )
23752385}
23762386
@@ -2395,6 +2405,14 @@ fn file_url_segments_to_pathbuf(
23952405 bytes. push ( b'/' ) ;
23962406 bytes. extend ( percent_decode ( segment. as_bytes ( ) ) ) ;
23972407 }
2408+ // A windows drive letter must end with a slash.
2409+ if bytes. len ( ) > 2 {
2410+ if matches ! ( bytes[ bytes. len( ) -2 ] , b'a' ..=b'z' | b'A' ..=b'Z' )
2411+ && matches ! ( bytes[ bytes. len( ) - 1 ] , b':' | b'|' )
2412+ {
2413+ bytes. push ( b'/' ) ;
2414+ }
2415+ }
23982416 let os_str = OsStr :: from_bytes ( & bytes) ;
23992417 let path = PathBuf :: from ( os_str) ;
24002418 debug_assert ! (
0 commit comments