Skip to content

Commit 9d72a5c

Browse files
authored
[3.12] pythongh-113297: Fix segfault in compiler for with statement with 19 context managers (python#113327) (python#113404)
1 parent 4882d50 commit 9d72a5c

File tree

4 files changed

+29
-1
lines changed

4 files changed

+29
-1
lines changed

Include/internal/pycore_flowgraph.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ typedef struct {
2626

2727

2828
typedef struct {
29-
struct _PyCfgBasicblock_ *handlers[CO_MAXBLOCKS+1];
29+
struct _PyCfgBasicblock_ *handlers[CO_MAXBLOCKS+2];
3030
int depth;
3131
} _PyCfgExceptStack;
3232

Lib/test/test_syntax.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1995,6 +1995,7 @@ def f(x: *b)
19951995

19961996
import re
19971997
import doctest
1998+
import textwrap
19981999
import unittest
19992000

20002001
from test import support
@@ -2241,6 +2242,31 @@ def test_nested_named_except_blocks(self):
22412242
code += f"{' '*4*12}pass"
22422243
self._check_error(code, "too many statically nested blocks")
22432244

2245+
@support.cpython_only
2246+
def test_with_statement_many_context_managers(self):
2247+
# See gh-113297
2248+
2249+
def get_code(n):
2250+
code = textwrap.dedent("""
2251+
def bug():
2252+
with (
2253+
a
2254+
""")
2255+
for i in range(n):
2256+
code += f" as a{i}, a\n"
2257+
code += "): yield a"
2258+
return code
2259+
2260+
CO_MAXBLOCKS = 20 # static nesting limit of the compiler
2261+
2262+
for n in range(CO_MAXBLOCKS):
2263+
with self.subTest(f"within range: {n=}"):
2264+
compile(get_code(n), "<string>", "exec")
2265+
2266+
for n in range(CO_MAXBLOCKS, CO_MAXBLOCKS + 5):
2267+
with self.subTest(f"out of range: {n=}"):
2268+
self._check_error(get_code(n), "too many statically nested blocks")
2269+
22442270
def test_barry_as_flufl_with_syntax_errors(self):
22452271
# The "barry_as_flufl" rule can produce some "bugs-at-a-distance" if
22462272
# is reading the wrong token in the presence of syntax errors later
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Fix segfault in the compiler on with statement with 19 context managers.

Python/flowgraph.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -645,6 +645,7 @@ push_except_block(ExceptStack *stack, cfg_instr *setup) {
645645
if (opcode == SETUP_WITH || opcode == SETUP_CLEANUP) {
646646
target->b_preserve_lasti = 1;
647647
}
648+
assert(stack->depth <= CO_MAXBLOCKS);
648649
stack->handlers[++stack->depth] = target;
649650
return target;
650651
}

0 commit comments

Comments
 (0)