@@ -443,12 +443,19 @@ impl OutboundUrl {
443
443
// we can always url encode the authority even if it is already encoded.
444
444
if let Some ( at) = url. find ( '@' ) {
445
445
let scheme_end = url. find ( "://" ) . map ( |e| e + 3 ) . unwrap_or ( 0 ) ;
446
- let userinfo = & url[ scheme_end..at] ;
447
-
448
- let encoded = urlencoding:: encode ( userinfo) ;
449
- let prefix = & url[ ..scheme_end] ;
450
- let suffix = & url[ scheme_end + userinfo. len ( ) ..] ;
451
- url = format ! ( "{prefix}{encoded}{suffix}" ) ;
446
+ let path_start = url[ scheme_end..]
447
+ . find ( '/' ) // This can calculate the wrong index if the username or password contains a '/'
448
+ . map ( |e| e + scheme_end)
449
+ . unwrap_or ( usize:: MAX ) ;
450
+
451
+ if at < path_start {
452
+ let userinfo = & url[ scheme_end..at] ;
453
+
454
+ let encoded = urlencoding:: encode ( userinfo) ;
455
+ let prefix = & url[ ..scheme_end] ;
456
+ let suffix = & url[ scheme_end + userinfo. len ( ) ..] ;
457
+ url = format ! ( "{prefix}{encoded}{suffix}" ) ;
458
+ }
452
459
}
453
460
454
461
let parsed = match url:: Url :: parse ( & url) {
@@ -562,6 +569,25 @@ mod test {
562
569
use super :: * ;
563
570
use std:: net:: { Ipv4Addr , Ipv6Addr } ;
564
571
572
+ #[ test]
573
+ fn outbound_url_handles_at_in_paths ( ) {
574
+ let url =
"https://example.com/[email protected] " ;
575
+ let url = OutboundUrl :: parse ( url, "https" ) . expect ( "should have parsed url" ) ;
576
+ assert_eq ! ( "example.com" , url. host) ;
577
+
578
+
579
+ let url = OutboundUrl :: parse ( url, "https" ) . expect ( "should have parsed url" ) ;
580
+ assert_eq ! ( "example.com" , url. host) ;
581
+
582
+
583
+ let url = OutboundUrl :: parse ( url, "https" ) . expect ( "should have parsed url" ) ;
584
+ assert_eq ! ( "example.com" , url. host) ;
585
+
586
+ let url =
"https://user:[email protected] " ;
587
+ let url = OutboundUrl :: parse ( url, "https" ) . expect ( "should have parsed url" ) ;
588
+ assert_eq ! ( "example.com" , url. host) ;
589
+ }
590
+
565
591
#[ test]
566
592
fn test_allowed_hosts_accepts_url_without_port ( ) {
567
593
assert_eq ! (
0 commit comments