11use std:: convert:: Infallible ;
22
3- use bstr:: { BStr , BString , ByteSlice } ;
4-
53use crate :: Scheme ;
4+ use bstr:: { BStr , BString , ByteSlice } ;
5+ use percent_encoding:: percent_decode_str;
66
77/// The error returned by [parse()](crate::parse()).
88#[ derive( Debug , thiserror:: Error ) ]
@@ -115,13 +115,20 @@ pub(crate) fn url(input: &BStr, protocol_end: usize) -> Result<crate::Url, Error
115115 serialize_alternative_form : false ,
116116 scheme,
117117 user : url_user ( & url) ,
118- password : url. password ( ) . map ( Into :: into ) ,
118+ password : url. password ( ) . map ( percent_decoded_utf8 ) ,
119119 host : url. host_str ( ) . map ( Into :: into) ,
120120 port : url. port ( ) ,
121121 path : url. path ( ) . into ( ) ,
122122 } )
123123}
124124
125+ fn percent_decoded_utf8 ( s : & str ) -> String {
126+ percent_decode_str ( s)
127+ . decode_utf8 ( )
128+ . expect ( "it's not possible to sneak illegal UTF8 into a URL" )
129+ . into_owned ( )
130+ }
131+
125132pub ( crate ) fn scp ( input : & BStr , colon : usize ) -> Result < crate :: Url , Error > {
126133 let input = input_to_utf8 ( input, UrlKind :: Scp ) ?;
127134
@@ -151,7 +158,7 @@ pub(crate) fn scp(input: &BStr, colon: usize) -> Result<crate::Url, Error> {
151158 serialize_alternative_form : true ,
152159 scheme : url. scheme ( ) . into ( ) ,
153160 user : url_user ( & url) ,
154- password : url. password ( ) . map ( Into :: into ) ,
161+ password : url. password ( ) . map ( percent_decoded_utf8 ) ,
155162 host : url. host_str ( ) . map ( Into :: into) ,
156163 port : url. port ( ) ,
157164 path : path. into ( ) ,
@@ -162,7 +169,7 @@ fn url_user(url: &url::Url) -> Option<String> {
162169 if url. username ( ) . is_empty ( ) && url. password ( ) . is_none ( ) {
163170 None
164171 } else {
165- Some ( url. username ( ) . into ( ) )
172+ Some ( percent_decoded_utf8 ( url. username ( ) ) )
166173 }
167174}
168175
0 commit comments