Skip to content

Commit 3a9e67a

Browse files
authored
gh-115376: fix segfault in _testinternalcapi.compiler_codegen on bad input (#115379)
1 parent 94f1334 commit 3a9e67a

File tree

3 files changed

+35
-15
lines changed

3 files changed

+35
-15
lines changed

Lib/test/test_compiler_codegen.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ class IsolatedCodeGenTests(CodegenTestCase):
88

99
def codegen_test(self, snippet, expected_insts):
1010
import ast
11-
a = ast.parse(snippet, "my_file.py", "exec");
11+
a = ast.parse(snippet, "my_file.py", "exec")
1212
insts = self.generate_code(a)
1313
self.assertInstructionsMatch(insts, expected_insts)
1414

@@ -54,3 +54,8 @@ def test_for_loop(self):
5454
('RETURN_VALUE', None),
5555
]
5656
self.codegen_test(snippet, expected)
57+
58+
def test_syntax_error__return_not_in_function(self):
59+
snippet = "return 42"
60+
with self.assertRaisesRegex(SyntaxError, "'return' outside function"):
61+
self.codegen_test(snippet, None)
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Fix segfault in ``_testinternalcapi.compiler_codegen`` on bad input.

Python/compile.c

Lines changed: 28 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1735,16 +1735,10 @@ compiler_body(struct compiler *c, location loc, asdl_stmt_seq *stmts)
17351735
static int
17361736
compiler_codegen(struct compiler *c, mod_ty mod)
17371737
{
1738-
_Py_DECLARE_STR(anon_module, "<module>");
1739-
RETURN_IF_ERROR(
1740-
compiler_enter_scope(c, &_Py_STR(anon_module), COMPILER_SCOPE_MODULE,
1741-
mod, 1));
1742-
17431738
location loc = LOCATION(1, 1, 0, 0);
17441739
switch (mod->kind) {
17451740
case Module_kind:
17461741
if (compiler_body(c, loc, mod->v.Module.body) < 0) {
1747-
compiler_exit_scope(c);
17481742
return ERROR;
17491743
}
17501744
break;
@@ -1753,10 +1747,10 @@ compiler_codegen(struct compiler *c, mod_ty mod)
17531747
ADDOP(c, loc, SETUP_ANNOTATIONS);
17541748
}
17551749
c->c_interactive = 1;
1756-
VISIT_SEQ_IN_SCOPE(c, stmt, mod->v.Interactive.body);
1750+
VISIT_SEQ(c, stmt, mod->v.Interactive.body);
17571751
break;
17581752
case Expression_kind:
1759-
VISIT_IN_SCOPE(c, expr, mod->v.Expression.body);
1753+
VISIT(c, expr, mod->v.Expression.body);
17601754
break;
17611755
default:
17621756
PyErr_Format(PyExc_SystemError,
@@ -1767,14 +1761,29 @@ compiler_codegen(struct compiler *c, mod_ty mod)
17671761
return SUCCESS;
17681762
}
17691763

1764+
static int
1765+
compiler_enter_anonymous_scope(struct compiler* c, mod_ty mod)
1766+
{
1767+
_Py_DECLARE_STR(anon_module, "<module>");
1768+
RETURN_IF_ERROR(
1769+
compiler_enter_scope(c, &_Py_STR(anon_module), COMPILER_SCOPE_MODULE,
1770+
mod, 1));
1771+
return SUCCESS;
1772+
}
1773+
17701774
static PyCodeObject *
17711775
compiler_mod(struct compiler *c, mod_ty mod)
17721776
{
1777+
PyCodeObject *co = NULL;
17731778
int addNone = mod->kind != Expression_kind;
1774-
if (compiler_codegen(c, mod) < 0) {
1779+
if (compiler_enter_anonymous_scope(c, mod) < 0) {
17751780
return NULL;
17761781
}
1777-
PyCodeObject *co = optimize_and_assemble(c, addNone);
1782+
if (compiler_codegen(c, mod) < 0) {
1783+
goto finally;
1784+
}
1785+
co = optimize_and_assemble(c, addNone);
1786+
finally:
17781787
compiler_exit_scope(c);
17791788
return co;
17801789
}
@@ -7920,15 +7929,20 @@ _PyCompile_CodeGen(PyObject *ast, PyObject *filename, PyCompilerFlags *pflags,
79207929
return NULL;
79217930
}
79227931

7932+
metadata = PyDict_New();
7933+
if (metadata == NULL) {
7934+
return NULL;
7935+
}
7936+
7937+
if (compiler_enter_anonymous_scope(c, mod) < 0) {
7938+
return NULL;
7939+
}
79237940
if (compiler_codegen(c, mod) < 0) {
79247941
goto finally;
79257942
}
79267943

79277944
_PyCompile_CodeUnitMetadata *umd = &c->u->u_metadata;
7928-
metadata = PyDict_New();
7929-
if (metadata == NULL) {
7930-
goto finally;
7931-
}
7945+
79327946
#define SET_MATADATA_ITEM(key, value) \
79337947
if (value != NULL) { \
79347948
if (PyDict_SetItemString(metadata, key, value) < 0) goto finally; \

0 commit comments

Comments
 (0)