mirror of
https://github.com/python/cpython.git
synced 2025-10-29 09:29:26 +00:00
Fix for SF bug [ #492403 ] exec() segfaults on closure's func_code
Based on the patch from Danny Yoo. The fix is in exec_statement() in ceval.c. There are also changes to introduce use of PyCode_GetNumFree() in several places.
This commit is contained in:
parent
3095a4c228
commit
733c8935f9
3 changed files with 10 additions and 5 deletions
|
|
@ -497,7 +497,7 @@ builtin_eval(PyObject *self, PyObject *args)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (PyCode_Check(cmd)) {
|
if (PyCode_Check(cmd)) {
|
||||||
if (PyTuple_GET_SIZE(((PyCodeObject *)cmd)->co_freevars) > 0) {
|
if (PyCode_GetNumFree((PyCodeObject *)cmd) > 0) {
|
||||||
PyErr_SetString(PyExc_TypeError,
|
PyErr_SetString(PyExc_TypeError,
|
||||||
"code object passed to eval() may not contain free variables");
|
"code object passed to eval() may not contain free variables");
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
|
||||||
|
|
@ -2094,7 +2094,7 @@ eval_frame(PyFrameObject *f)
|
||||||
int nfree;
|
int nfree;
|
||||||
v = POP(); /* code object */
|
v = POP(); /* code object */
|
||||||
x = PyFunction_New(v, f->f_globals);
|
x = PyFunction_New(v, f->f_globals);
|
||||||
nfree = PyTuple_GET_SIZE(((PyCodeObject *)v)->co_freevars);
|
nfree = PyCode_GetNumFree((PyCodeObject *)v);
|
||||||
Py_DECREF(v);
|
Py_DECREF(v);
|
||||||
/* XXX Maybe this should be a separate opcode? */
|
/* XXX Maybe this should be a separate opcode? */
|
||||||
if (x != NULL && nfree > 0) {
|
if (x != NULL && nfree > 0) {
|
||||||
|
|
@ -3631,6 +3631,11 @@ exec_statement(PyFrameObject *f, PyObject *prog, PyObject *globals,
|
||||||
if (PyDict_GetItemString(globals, "__builtins__") == NULL)
|
if (PyDict_GetItemString(globals, "__builtins__") == NULL)
|
||||||
PyDict_SetItemString(globals, "__builtins__", f->f_builtins);
|
PyDict_SetItemString(globals, "__builtins__", f->f_builtins);
|
||||||
if (PyCode_Check(prog)) {
|
if (PyCode_Check(prog)) {
|
||||||
|
if (PyCode_GetNumFree((PyCodeObject *)prog) > 0) {
|
||||||
|
PyErr_SetString(PyExc_TypeError,
|
||||||
|
"code object passed to exec may not contain free variables");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
v = PyEval_EvalCode((PyCodeObject *) prog, globals, locals);
|
v = PyEval_EvalCode((PyCodeObject *) prog, globals, locals);
|
||||||
}
|
}
|
||||||
else if (PyFile_Check(prog)) {
|
else if (PyFile_Check(prog)) {
|
||||||
|
|
|
||||||
|
|
@ -2273,7 +2273,7 @@ com_and_test(struct compiling *c, node *n)
|
||||||
static int
|
static int
|
||||||
com_make_closure(struct compiling *c, PyCodeObject *co)
|
com_make_closure(struct compiling *c, PyCodeObject *co)
|
||||||
{
|
{
|
||||||
int i, free = PyTuple_GET_SIZE(co->co_freevars);
|
int i, free = PyCode_GetNumFree(co);
|
||||||
if (free == 0)
|
if (free == 0)
|
||||||
return 0;
|
return 0;
|
||||||
for (i = 0; i < free; ++i) {
|
for (i = 0; i < free; ++i) {
|
||||||
|
|
@ -2333,7 +2333,7 @@ com_test(struct compiling *c, node *n)
|
||||||
com_push(c, 1);
|
com_push(c, 1);
|
||||||
if (closure) {
|
if (closure) {
|
||||||
com_addoparg(c, MAKE_CLOSURE, ndefs);
|
com_addoparg(c, MAKE_CLOSURE, ndefs);
|
||||||
com_pop(c, PyTuple_GET_SIZE(co->co_freevars));
|
com_pop(c, PyCode_GetNumFree(co));
|
||||||
} else
|
} else
|
||||||
com_addoparg(c, MAKE_FUNCTION, ndefs);
|
com_addoparg(c, MAKE_FUNCTION, ndefs);
|
||||||
Py_DECREF(co);
|
Py_DECREF(co);
|
||||||
|
|
@ -3590,7 +3590,7 @@ com_classdef(struct compiling *c, node *n)
|
||||||
com_push(c, 1);
|
com_push(c, 1);
|
||||||
if (closure) {
|
if (closure) {
|
||||||
com_addoparg(c, MAKE_CLOSURE, 0);
|
com_addoparg(c, MAKE_CLOSURE, 0);
|
||||||
com_pop(c, PyTuple_GET_SIZE(co->co_freevars));
|
com_pop(c, PyCode_GetNumFree(co));
|
||||||
} else
|
} else
|
||||||
com_addoparg(c, MAKE_FUNCTION, 0);
|
com_addoparg(c, MAKE_FUNCTION, 0);
|
||||||
com_addoparg(c, CALL_FUNCTION, 0);
|
com_addoparg(c, CALL_FUNCTION, 0);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue