mirror of
https://github.com/python/cpython.git
synced 2025-10-09 16:34:44 +00:00
gh-115376: fix segfault in _testinternalcapi.compiler_codegen on bad input (#115379)
This commit is contained in:
parent
94f1334e52
commit
3a9e67a9fd
3 changed files with 35 additions and 15 deletions
|
@ -8,7 +8,7 @@ class IsolatedCodeGenTests(CodegenTestCase):
|
||||||
|
|
||||||
def codegen_test(self, snippet, expected_insts):
|
def codegen_test(self, snippet, expected_insts):
|
||||||
import ast
|
import ast
|
||||||
a = ast.parse(snippet, "my_file.py", "exec");
|
a = ast.parse(snippet, "my_file.py", "exec")
|
||||||
insts = self.generate_code(a)
|
insts = self.generate_code(a)
|
||||||
self.assertInstructionsMatch(insts, expected_insts)
|
self.assertInstructionsMatch(insts, expected_insts)
|
||||||
|
|
||||||
|
@ -54,3 +54,8 @@ class IsolatedCodeGenTests(CodegenTestCase):
|
||||||
('RETURN_VALUE', None),
|
('RETURN_VALUE', None),
|
||||||
]
|
]
|
||||||
self.codegen_test(snippet, expected)
|
self.codegen_test(snippet, expected)
|
||||||
|
|
||||||
|
def test_syntax_error__return_not_in_function(self):
|
||||||
|
snippet = "return 42"
|
||||||
|
with self.assertRaisesRegex(SyntaxError, "'return' outside function"):
|
||||||
|
self.codegen_test(snippet, None)
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
Fix segfault in ``_testinternalcapi.compiler_codegen`` on bad input.
|
|
@ -1735,16 +1735,10 @@ compiler_body(struct compiler *c, location loc, asdl_stmt_seq *stmts)
|
||||||
static int
|
static int
|
||||||
compiler_codegen(struct compiler *c, mod_ty mod)
|
compiler_codegen(struct compiler *c, mod_ty mod)
|
||||||
{
|
{
|
||||||
_Py_DECLARE_STR(anon_module, "<module>");
|
|
||||||
RETURN_IF_ERROR(
|
|
||||||
compiler_enter_scope(c, &_Py_STR(anon_module), COMPILER_SCOPE_MODULE,
|
|
||||||
mod, 1));
|
|
||||||
|
|
||||||
location loc = LOCATION(1, 1, 0, 0);
|
location loc = LOCATION(1, 1, 0, 0);
|
||||||
switch (mod->kind) {
|
switch (mod->kind) {
|
||||||
case Module_kind:
|
case Module_kind:
|
||||||
if (compiler_body(c, loc, mod->v.Module.body) < 0) {
|
if (compiler_body(c, loc, mod->v.Module.body) < 0) {
|
||||||
compiler_exit_scope(c);
|
|
||||||
return ERROR;
|
return ERROR;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -1753,10 +1747,10 @@ compiler_codegen(struct compiler *c, mod_ty mod)
|
||||||
ADDOP(c, loc, SETUP_ANNOTATIONS);
|
ADDOP(c, loc, SETUP_ANNOTATIONS);
|
||||||
}
|
}
|
||||||
c->c_interactive = 1;
|
c->c_interactive = 1;
|
||||||
VISIT_SEQ_IN_SCOPE(c, stmt, mod->v.Interactive.body);
|
VISIT_SEQ(c, stmt, mod->v.Interactive.body);
|
||||||
break;
|
break;
|
||||||
case Expression_kind:
|
case Expression_kind:
|
||||||
VISIT_IN_SCOPE(c, expr, mod->v.Expression.body);
|
VISIT(c, expr, mod->v.Expression.body);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
PyErr_Format(PyExc_SystemError,
|
PyErr_Format(PyExc_SystemError,
|
||||||
|
@ -1767,14 +1761,29 @@ compiler_codegen(struct compiler *c, mod_ty mod)
|
||||||
return SUCCESS;
|
return SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
compiler_enter_anonymous_scope(struct compiler* c, mod_ty mod)
|
||||||
|
{
|
||||||
|
_Py_DECLARE_STR(anon_module, "<module>");
|
||||||
|
RETURN_IF_ERROR(
|
||||||
|
compiler_enter_scope(c, &_Py_STR(anon_module), COMPILER_SCOPE_MODULE,
|
||||||
|
mod, 1));
|
||||||
|
return SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
static PyCodeObject *
|
static PyCodeObject *
|
||||||
compiler_mod(struct compiler *c, mod_ty mod)
|
compiler_mod(struct compiler *c, mod_ty mod)
|
||||||
{
|
{
|
||||||
|
PyCodeObject *co = NULL;
|
||||||
int addNone = mod->kind != Expression_kind;
|
int addNone = mod->kind != Expression_kind;
|
||||||
if (compiler_codegen(c, mod) < 0) {
|
if (compiler_enter_anonymous_scope(c, mod) < 0) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
PyCodeObject *co = optimize_and_assemble(c, addNone);
|
if (compiler_codegen(c, mod) < 0) {
|
||||||
|
goto finally;
|
||||||
|
}
|
||||||
|
co = optimize_and_assemble(c, addNone);
|
||||||
|
finally:
|
||||||
compiler_exit_scope(c);
|
compiler_exit_scope(c);
|
||||||
return co;
|
return co;
|
||||||
}
|
}
|
||||||
|
@ -7920,15 +7929,20 @@ _PyCompile_CodeGen(PyObject *ast, PyObject *filename, PyCompilerFlags *pflags,
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
metadata = PyDict_New();
|
||||||
|
if (metadata == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (compiler_enter_anonymous_scope(c, mod) < 0) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
if (compiler_codegen(c, mod) < 0) {
|
if (compiler_codegen(c, mod) < 0) {
|
||||||
goto finally;
|
goto finally;
|
||||||
}
|
}
|
||||||
|
|
||||||
_PyCompile_CodeUnitMetadata *umd = &c->u->u_metadata;
|
_PyCompile_CodeUnitMetadata *umd = &c->u->u_metadata;
|
||||||
metadata = PyDict_New();
|
|
||||||
if (metadata == NULL) {
|
|
||||||
goto finally;
|
|
||||||
}
|
|
||||||
#define SET_MATADATA_ITEM(key, value) \
|
#define SET_MATADATA_ITEM(key, value) \
|
||||||
if (value != NULL) { \
|
if (value != NULL) { \
|
||||||
if (PyDict_SetItemString(metadata, key, value) < 0) goto finally; \
|
if (PyDict_SetItemString(metadata, key, value) < 0) goto finally; \
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue