@@ -128,6 +128,13 @@ mod test_push_and_canonicalize {
128
128
}
129
129
}
130
130
131
+ #[ inline]
132
+ fn try_percent_decode ( input : & str ) -> Cow < ' _ , str > {
133
+ percent_encoding:: percent_decode_str ( input)
134
+ . decode_utf8 ( )
135
+ . unwrap_or ( Cow :: Borrowed ( input) )
136
+ }
137
+
131
138
#[ inline]
132
139
fn try_unescape_attribute_value < ' a > ( attr : & ' a Attribute < ' _ > ) -> Cow < ' a , [ u8 ] > {
133
140
attr. unescaped_value ( ) . unwrap_or ( Cow :: Borrowed ( & attr. value ) )
@@ -220,6 +227,7 @@ impl Document {
220
227
. to_str ( )
221
228
. expect ( "Invalid unicode in path" )
222
229
. to_owned ( ) ;
230
+
223
231
if cfg ! ( windows) {
224
232
unsafe {
225
233
// safety: we replace ascii bytes only
@@ -260,7 +268,7 @@ impl Document {
260
268
href. push ( '/' ) ;
261
269
}
262
270
263
- push_and_canonicalize ( & mut href, & rel_href[ ..qs_start] ) ;
271
+ push_and_canonicalize ( & mut href, & try_percent_decode ( & rel_href[ ..qs_start] ) ) ;
264
272
265
273
if preserve_anchor {
266
274
let anchor = & rel_href[ anchor_start..] ;
@@ -458,6 +466,10 @@ fn test_document_links() {
458
466
<a href='../../go/?foo=bar&bar=baz' href='../../go/'>
459
467
<a href="ma" />
460
468
469
+ <!-- test url encoding within HTML + percent-encoding within html encoding -->
470
+ <a href="%5Bslug%5D.js" />
471
+ <a href="%5Bschlug%5D.js" />
472
+
461
473
<!-- obfuscated mailto: link -->
462
474
<a href='mailto:foo@example.com' />
463
475
"""#
@@ -484,6 +496,8 @@ fn test_document_links() {
484
496
used_link( "platforms/go" ) ,
485
497
used_link( "platforms/go" ) ,
486
498
used_link( "platforms/python/troubleshooting/ma" ) ,
499
+ used_link( "platforms/python/troubleshooting/[slug].js" ) ,
500
+ used_link( "platforms/python/troubleshooting/[schlug].js" ) ,
487
501
]
488
502
) ;
489
503
}
0 commit comments