Skip to content

Commit 8de34cd

Browse files
authored
[3.9] bpo-41690: Use a loop to collect args in the parser instead of recursion (GH-22053) (GH-22067)
This program can segfault the parser by stack overflow: ``` import ast code = "f(" + ",".join(['a' for _ in range(100000)]) + ")" print("Ready!") ast.parse(code) ``` the reason is that the rule for arguments has a simple recursion when collecting args: args[expr_ty]: [...] | a=named_expression b=[',' c=args { c }] { [...] }. (cherry picked from commit 4a97b15) Co-authored-by: Pablo Galindo <[email protected]>
1 parent a763ee3 commit 8de34cd

File tree

5 files changed

+628
-515
lines changed

5 files changed

+628
-515
lines changed

Grammar/python.gram

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -537,22 +537,11 @@ arguments[expr_ty] (memo):
537537
| a=args [','] &')' { a }
538538
| incorrect_arguments
539539
args[expr_ty]:
540-
| a=starred_expression b=[',' c=args { c }] {
541-
_Py_Call(_PyPegen_dummy_name(p),
542-
(b) ? CHECK(_PyPegen_seq_insert_in_front(p, a, ((expr_ty) b)->v.Call.args))
543-
: CHECK(_PyPegen_singleton_seq(p, a)),
544-
(b) ? ((expr_ty) b)->v.Call.keywords : NULL,
545-
EXTRA) }
540+
| a=','.(starred_expression | named_expression !'=')+ b=[',' k=kwargs {k}] { _PyPegen_collect_call_seqs(p, a, b) }
546541
| a=kwargs { _Py_Call(_PyPegen_dummy_name(p),
547542
CHECK_NULL_ALLOWED(_PyPegen_seq_extract_starred_exprs(p, a)),
548543
CHECK_NULL_ALLOWED(_PyPegen_seq_delete_starred_exprs(p, a)),
549544
EXTRA) }
550-
| a=named_expression b=[',' c=args { c }] {
551-
_Py_Call(_PyPegen_dummy_name(p),
552-
(b) ? CHECK(_PyPegen_seq_insert_in_front(p, a, ((expr_ty) b)->v.Call.args))
553-
: CHECK(_PyPegen_singleton_seq(p, a)),
554-
(b) ? ((expr_ty) b)->v.Call.keywords : NULL,
555-
EXTRA) }
556545
kwargs[asdl_seq*]:
557546
| a=','.kwarg_or_starred+ ',' b=','.kwarg_or_double_starred+ { _PyPegen_join_sequences(p, a, b) }
558547
| ','.kwarg_or_starred+
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Fix a possible stack overflow in the parser when parsing functions and
2+
classes with a huge ammount of arguments. Patch by Pablo Galindo.

0 commit comments

Comments
 (0)