File tree 3 files changed +25
-5
lines changed
Filter options
3 files changed +25
-5
lines changed
Original file line number Diff line number Diff line change @@ -565,7 +565,23 @@ def test_fstring_nested_too_deeply(self):
565
565
self .assertAllRaise (SyntaxError ,
566
566
"f-string: expressions nested too deeply" ,
567
567
['f"{1+2:{1+2:{1+1:{1}}}}"' ])
568
+
569
+ def create_nested_fstring (n ):
570
+ if n == 0 :
571
+ return "1+1"
572
+ prev = create_nested_fstring (n - 1 )
573
+ return f'f"{{{ prev } }}"'
568
574
575
+ self .assertAllRaise (SyntaxError ,
576
+ "too many nested f-strings" ,
577
+ [create_nested_fstring (160 )])
578
+
579
+ def test_syntax_error_in_nested_fstring (self ):
580
+ # See gh-104016 for more information on this crash
581
+ self .assertAllRaise (SyntaxError ,
582
+ "invalid syntax" ,
583
+ ['f"{1 1:' + ('{f"1:' * 199 )])
584
+
569
585
def test_double_braces (self ):
570
586
self .assertEqual (f'{{' , '{' )
571
587
self .assertEqual (f'a{{' , 'a{' )
Original file line number Diff line number Diff line change 43
43
#ifdef Py_DEBUG
44
44
static inline tokenizer_mode * TOK_GET_MODE (struct tok_state * tok ) {
45
45
assert (tok -> tok_mode_stack_index >= 0 );
46
- assert (tok -> tok_mode_stack_index < MAXLEVEL );
46
+ assert (tok -> tok_mode_stack_index < MAXFSTRINGLEVEL );
47
47
return & (tok -> tok_mode_stack [tok -> tok_mode_stack_index ]);
48
48
}
49
49
static inline tokenizer_mode * TOK_NEXT_MODE (struct tok_state * tok ) {
50
50
assert (tok -> tok_mode_stack_index >= 0 );
51
- assert (tok -> tok_mode_stack_index < MAXLEVEL );
51
+ assert (tok -> tok_mode_stack_index + 1 < MAXFSTRINGLEVEL );
52
52
return & (tok -> tok_mode_stack [++ tok -> tok_mode_stack_index ]);
53
53
}
54
54
#else
@@ -2235,6 +2235,9 @@ tok_get_normal_mode(struct tok_state *tok, tokenizer_mode* current_tok, struct t
2235
2235
2236
2236
p_start = tok -> start ;
2237
2237
p_end = tok -> cur ;
2238
+ if (tok -> tok_mode_stack_index + 1 >= MAXFSTRINGLEVEL ) {
2239
+ return MAKE_TOKEN (syntaxerror (tok , "too many nested f-strings" ));
2240
+ }
2238
2241
tokenizer_mode * the_current_tok = TOK_NEXT_MODE (tok );
2239
2242
the_current_tok -> kind = TOK_FSTRING_MODE ;
2240
2243
the_current_tok -> f_string_quote = quote ;
Original file line number Diff line number Diff line change @@ -10,8 +10,9 @@ extern "C" {
10
10
11
11
#include "pycore_token.h" /* For token types */
12
12
13
- #define MAXINDENT 100 /* Max indentation level */
14
- #define MAXLEVEL 200 /* Max parentheses level */
13
+ #define MAXINDENT 100 /* Max indentation level */
14
+ #define MAXLEVEL 200 /* Max parentheses level */
15
+ #define MAXFSTRINGLEVEL 150 /* Max f-string nesting level */
15
16
16
17
enum decoding_state {
17
18
STATE_INIT ,
@@ -123,7 +124,7 @@ struct tok_state {
123
124
enum interactive_underflow_t interactive_underflow ;
124
125
int report_warnings ;
125
126
// TODO: Factor this into its own thing
126
- tokenizer_mode tok_mode_stack [MAXLEVEL ];
127
+ tokenizer_mode tok_mode_stack [MAXFSTRINGLEVEL ];
127
128
int tok_mode_stack_index ;
128
129
int tok_report_warnings ;
129
130
#ifdef Py_DEBUG
You can’t perform that action at this time.
0 commit comments