@@ -480,12 +480,12 @@ impl<'s> Parser<'s> {
480
480
}
481
481
_ => return Err ( Invalid ) ,
482
482
}
483
+
484
+ self . pop_depth ( ) ;
483
485
Ok ( ( ) )
484
486
}
485
487
486
488
fn skip_generic_arg ( & mut self ) -> Result < ( ) , Invalid > {
487
- self . push_depth ( ) ?;
488
-
489
489
if self . eat ( b'L' ) {
490
490
self . integer_62 ( ) ?;
491
491
Ok ( ( ) )
@@ -558,6 +558,8 @@ impl<'s> Parser<'s> {
558
558
self . skip_path ( ) ?;
559
559
}
560
560
}
561
+
562
+ self . pop_depth ( ) ;
561
563
Ok ( ( ) )
562
564
}
563
565
@@ -594,6 +596,8 @@ impl<'s> Parser<'s> {
594
596
}
595
597
596
598
self . hex_nibbles ( ) ?;
599
+
600
+ self . pop_depth ( ) ;
597
601
Ok ( ( ) )
598
602
}
599
603
}
@@ -1783,4 +1787,27 @@ RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRB_E"
1783
1787
)
1784
1788
) ;
1785
1789
}
1790
+
1791
+ #[ test]
1792
+ fn recursion_limit_leaks ( ) {
1793
+ // NOTE(eddyb) this test checks that both paths and types support the
1794
+ // recursion limit correctly, i.e. matching `push_depth` and `pop_depth`,
1795
+ // and don't leak "recursion levels" and trip the limit.
1796
+ // The test inputs are generated on the fly, using a repeated pattern,
1797
+ // as hardcoding the actual strings would be too verbose.
1798
+ // Also, `MAX_DEPTH` can be directly used, instead of assuming its value.
1799
+ for & ( sym_leaf, expected_leaf) in & [ ( "p" , "_" ) , ( "Rp" , "&_" ) , ( "C1x" , "x" ) ] {
1800
+ let mut sym = format ! ( "_RIC0p" ) ;
1801
+ let mut expected = format ! ( "::<_" ) ;
1802
+ for _ in 0 ..( super :: MAX_DEPTH * 2 ) {
1803
+ sym. push_str ( sym_leaf) ;
1804
+ expected. push_str ( ", " ) ;
1805
+ expected. push_str ( expected_leaf) ;
1806
+ }
1807
+ sym. push ( 'E' ) ;
1808
+ expected. push ( '>' ) ;
1809
+
1810
+ t_nohash ! ( & sym, expected) ;
1811
+ }
1812
+ }
1786
1813
}
0 commit comments