@@ -141,6 +141,10 @@ mod parser {
141
141
use winnow:: stream:: StreamIsPartial ;
142
142
use winnow:: token:: { one_of, take_while} ;
143
143
144
+ /// Avoid worst-case parse times by limiting how much a `take_while` can take if something
145
+ /// later may cause it to fail.
146
+ const NON_TERMINATING_CAP : usize = 1024 ;
147
+
144
148
pub ( crate ) fn next_identifier < T > ( input : & mut T ) -> PResult < <T as Stream >:: Slice , ( ) >
145
149
where
146
150
T : Compare < char > ,
@@ -446,7 +450,7 @@ mod parser {
446
450
trace (
447
451
"email" ,
448
452
(
449
- take_while ( 1 .., is_localport_char) ,
453
+ take_while ( 1 ..NON_TERMINATING_CAP , is_localport_char) ,
450
454
'@' ,
451
455
take_while ( 1 .., is_domain_char) ,
452
456
)
@@ -466,15 +470,18 @@ mod parser {
466
470
"url" ,
467
471
(
468
472
opt ( (
469
- take_while ( 1 .., is_scheme_char) ,
473
+ take_while ( 1 ..NON_TERMINATING_CAP , is_scheme_char) ,
470
474
// HACK: Technically you can skip `//` if you don't have a domain but that would
471
475
// get messy to support.
472
476
( ':' , '/' , '/' ) ,
473
477
) ) ,
474
478
(
475
479
opt ( ( url_userinfo, '@' ) ) ,
476
- take_while ( 1 .., is_domain_char) ,
477
- opt ( ( ':' , take_while ( 1 .., AsChar :: is_dec_digit) ) ) ,
480
+ take_while ( 1 ..NON_TERMINATING_CAP , is_domain_char) ,
481
+ opt ( (
482
+ ':' ,
483
+ take_while ( 1 ..NON_TERMINATING_CAP , AsChar :: is_dec_digit) ,
484
+ ) ) ,
478
485
) ,
479
486
'/' ,
480
487
// HACK: Too lazy to enumerate
@@ -495,8 +502,8 @@ mod parser {
495
502
trace (
496
503
"userinfo" ,
497
504
(
498
- take_while ( 1 .., is_localport_char) ,
499
- opt ( ( ':' , take_while ( 0 .., is_localport_char) ) ) ,
505
+ take_while ( 1 ..NON_TERMINATING_CAP , is_localport_char) ,
506
+ opt ( ( ':' , take_while ( 0 ..NON_TERMINATING_CAP , is_localport_char) ) ) ,
500
507
)
501
508
. take ( ) ,
502
509
)
@@ -515,7 +522,11 @@ mod parser {
515
522
// incorrectly, we opt for just not evaluating it at all.
516
523
trace (
517
524
"escape" ,
518
- ( take_while ( 1 .., is_escape) , take_while ( 0 .., is_xid_continue) ) . take ( ) ,
525
+ (
526
+ take_while ( 1 ..NON_TERMINATING_CAP , is_escape) ,
527
+ take_while ( 0 .., is_xid_continue) ,
528
+ )
529
+ . take ( ) ,
519
530
)
520
531
. parse_next ( input)
521
532
}
0 commit comments