mirror of
https://github.com/python/cpython
synced 2024-09-05 00:05:39 +00:00
gh-113297: Fix segfault in compiler for with statement with 19 context managers (#113327)
This commit is contained in:
parent
9afb0e1606
commit
c31943af16
|
@ -2017,6 +2017,7 @@ def f(x: *b)
|
|||
|
||||
import re
|
||||
import doctest
|
||||
import textwrap
|
||||
import unittest
|
||||
|
||||
from test import support
|
||||
|
@ -2279,6 +2280,31 @@ def test_nested_named_except_blocks(self):
|
|||
code += f"{' '*4*12}pass"
|
||||
self._check_error(code, "too many statically nested blocks")
|
||||
|
||||
@support.cpython_only
|
||||
def test_with_statement_many_context_managers(self):
|
||||
# See gh-113297
|
||||
|
||||
def get_code(n):
|
||||
code = textwrap.dedent("""
|
||||
def bug():
|
||||
with (
|
||||
a
|
||||
""")
|
||||
for i in range(n):
|
||||
code += f" as a{i}, a\n"
|
||||
code += "): yield a"
|
||||
return code
|
||||
|
||||
CO_MAXBLOCKS = 20 # static nesting limit of the compiler
|
||||
|
||||
for n in range(CO_MAXBLOCKS):
|
||||
with self.subTest(f"within range: {n=}"):
|
||||
compile(get_code(n), "<string>", "exec")
|
||||
|
||||
for n in range(CO_MAXBLOCKS, CO_MAXBLOCKS + 5):
|
||||
with self.subTest(f"out of range: {n=}"):
|
||||
self._check_error(get_code(n), "too many statically nested blocks")
|
||||
|
||||
def test_barry_as_flufl_with_syntax_errors(self):
|
||||
# The "barry_as_flufl" rule can produce some "bugs-at-a-distance" if
|
||||
# is reading the wrong token in the presence of syntax errors later
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
Fix segfault in the compiler on with statement with 19 context managers.
|
|
@ -648,7 +648,7 @@ mark_except_handlers(basicblock *entryblock) {
|
|||
|
||||
|
||||
struct _PyCfgExceptStack {
|
||||
basicblock *handlers[CO_MAXBLOCKS+1];
|
||||
basicblock *handlers[CO_MAXBLOCKS+2];
|
||||
int depth;
|
||||
};
|
||||
|
||||
|
@ -661,6 +661,7 @@ push_except_block(struct _PyCfgExceptStack *stack, cfg_instr *setup) {
|
|||
if (opcode == SETUP_WITH || opcode == SETUP_CLEANUP) {
|
||||
target->b_preserve_lasti = 1;
|
||||
}
|
||||
assert(stack->depth <= CO_MAXBLOCKS);
|
||||
stack->handlers[++stack->depth] = target;
|
||||
return target;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue