@@ -480,12 +480,12 @@ impl<'s> Parser<'s> {
480480 }
481481 _ => return Err ( Invalid ) ,
482482 }
483+
484+ self . pop_depth ( ) ;
483485 Ok ( ( ) )
484486 }
485487
486488 fn skip_generic_arg ( & mut self ) -> Result < ( ) , Invalid > {
487- self . push_depth ( ) ?;
488-
489489 if self . eat ( b'L' ) {
490490 self . integer_62 ( ) ?;
491491 Ok ( ( ) )
@@ -558,6 +558,8 @@ impl<'s> Parser<'s> {
558558 self . skip_path ( ) ?;
559559 }
560560 }
561+
562+ self . pop_depth ( ) ;
561563 Ok ( ( ) )
562564 }
563565
@@ -594,6 +596,8 @@ impl<'s> Parser<'s> {
594596 }
595597
596598 self . hex_nibbles ( ) ?;
599+
600+ self . pop_depth ( ) ;
597601 Ok ( ( ) )
598602 }
599603}
@@ -1783,4 +1787,27 @@ RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRB_E"
17831787 )
17841788 ) ;
17851789 }
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+ }
17861813}
0 commit comments