[3.12] gh-113297: Fix segfault in compiler for with statement with 19 context managers (#113327) (#113404)

This commit is contained in:
Irit Katriel 2023-12-23 13:29:11 +00:00 committed by GitHub
parent 4882d508be
commit 9d72a5cae7
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 29 additions and 1 deletions

View file

@ -26,7 +26,7 @@ typedef struct {
typedef struct {
struct _PyCfgBasicblock_ *handlers[CO_MAXBLOCKS+1];
struct _PyCfgBasicblock_ *handlers[CO_MAXBLOCKS+2];
int depth;
} _PyCfgExceptStack;

View file

@ -1995,6 +1995,7 @@ def f(x: *b)
import re
import doctest
import textwrap
import unittest
from test import support
@ -2241,6 +2242,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

View file

@ -0,0 +1 @@
Fix segfault in the compiler on with statement with 19 context managers.

View file

@ -645,6 +645,7 @@ push_except_block(ExceptStack *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;
}