@@ -456,13 +456,15 @@ impl Url {
456456
457457 if self . slice ( self . scheme_end + 1 ..) . starts_with ( "//" ) {
458458 // URL with authority
459- match self . byte_at ( self . username_end ) {
460- b':' => {
461- assert ! ( self . host_start >= self . username_end + 2 ) ;
462- assert_eq ! ( self . byte_at( self . host_start - 1 ) , b'@' ) ;
459+ if self . username_end != self . serialization . len ( ) as u32 {
460+ match self . byte_at ( self . username_end ) {
461+ b':' => {
462+ assert ! ( self . host_start >= self . username_end + 2 ) ;
463+ assert_eq ! ( self . byte_at( self . host_start - 1 ) , b'@' ) ;
464+ }
465+ b'@' => assert ! ( self . host_start == self . username_end + 1 ) ,
466+ _ => assert_eq ! ( self . username_end, self . scheme_end + 3 ) ,
463467 }
464- b'@' => assert ! ( self . host_start == self . username_end + 1 ) ,
465- _ => assert_eq ! ( self . username_end, self . scheme_end + 3 ) ,
466468 }
467469 assert ! ( self . host_start >= self . username_end) ;
468470 assert ! ( self . host_end >= self . host_start) ;
@@ -490,7 +492,10 @@ impl Url {
490492 Some ( port_str. parse:: <u16 >( ) . expect( "Couldn't parse port?" ) )
491493 ) ;
492494 }
493- assert_eq ! ( self . byte_at( self . path_start) , b'/' ) ;
495+ assert ! (
496+ self . path_start as usize == self . serialization. len( )
497+ || matches!( self . byte_at( self . path_start) , b'/' | b'#' | b'?' )
498+ ) ;
494499 } else {
495500 // Anarchist URL (no authority)
496501 assert_eq ! ( self . username_end, self . scheme_end + 1 ) ;
@@ -501,11 +506,11 @@ impl Url {
501506 assert_eq ! ( self . path_start, self . scheme_end + 1 ) ;
502507 }
503508 if let Some ( start) = self . query_start {
504- assert ! ( start > self . path_start) ;
509+ assert ! ( start >= self . path_start) ;
505510 assert_eq ! ( self . byte_at( start) , b'?' ) ;
506511 }
507512 if let Some ( start) = self . fragment_start {
508- assert ! ( start > self . path_start) ;
513+ assert ! ( start >= self . path_start) ;
509514 assert_eq ! ( self . byte_at( start) , b'#' ) ;
510515 }
511516 if let ( Some ( query_start) , Some ( fragment_start) ) = ( self . query_start , self . fragment_start ) {
@@ -745,7 +750,10 @@ impl Url {
745750 pub fn password ( & self ) -> Option < & str > {
746751 // This ':' is not the one marking a port number since a host can not be empty.
747752 // (Except for file: URLs, which do not have port numbers.)
748- if self . has_authority ( ) && self . byte_at ( self . username_end ) == b':' {
753+ if self . has_authority ( )
754+ && self . username_end != self . serialization . len ( ) as u32
755+ && self . byte_at ( self . username_end ) == b':'
756+ {
749757 debug_assert ! ( self . byte_at( self . host_start - 1 ) == b'@' ) ;
750758 Some ( self . slice ( self . username_end + 1 ..self . host_start - 1 ) )
751759 } else {
@@ -1226,7 +1234,7 @@ impl Url {
12261234 if let Some ( input) = fragment {
12271235 self . fragment_start = Some ( to_u32 ( self . serialization . len ( ) ) . unwrap ( ) ) ;
12281236 self . serialization . push ( '#' ) ;
1229- self . mutate ( |parser| parser. parse_fragment ( parser:: Input :: new ( input) ) )
1237+ self . mutate ( |parser| parser. parse_fragment ( parser:: Input :: no_trim ( input) ) )
12301238 } else {
12311239 self . fragment_start = None
12321240 }
@@ -1284,7 +1292,12 @@ impl Url {
12841292 let scheme_type = SchemeType :: from ( self . scheme ( ) ) ;
12851293 let scheme_end = self . scheme_end ;
12861294 self . mutate ( |parser| {
1287- parser. parse_query ( scheme_type, scheme_end, parser:: Input :: new ( input) )
1295+ let vfn = parser. violation_fn ;
1296+ parser. parse_query (
1297+ scheme_type,
1298+ scheme_end,
1299+ parser:: Input :: trim_tab_and_newlines ( input, vfn) ,
1300+ )
12881301 } ) ;
12891302 }
12901303
@@ -1390,8 +1403,12 @@ impl Url {
13901403 }
13911404 parser. parse_cannot_be_a_base_path ( parser:: Input :: new ( path) ) ;
13921405 } else {
1406+ let path_start = parser. serialization . len ( ) ;
13931407 let mut has_host = true ; // FIXME
13941408 parser. parse_path_start ( scheme_type, & mut has_host, parser:: Input :: new ( path) ) ;
1409+ if scheme_type. is_file ( ) {
1410+ parser:: trim_path ( & mut parser. serialization , path_start) ;
1411+ }
13951412 }
13961413 } ) ;
13971414 self . restore_after_path ( old_after_path_pos, & after_path) ;
0 commit comments