From 733c8935f9dfd1be70c472649eb845ea22bbc878 Mon Sep 17 00:00:00 2001 From: Jeremy Hylton Date: Thu, 13 Dec 2001 19:51:56 +0000 Subject: 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. --- Python/bltinmodule.c | 2 +- Python/ceval.c | 7 ++++++- Python/compile.c | 6 +++--- 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/Python/bltinmodule.c b/Python/bltinmodule.c index 8e4ca2e..f5ce749 100644 --- a/Python/bltinmodule.c +++ b/Python/bltinmodule.c @@ -497,7 +497,7 @@ builtin_eval(PyObject *self, PyObject *args) } if (PyCode_Check(cmd)) { - if (PyTuple_GET_SIZE(((PyCodeObject *)cmd)->co_freevars) > 0) { + if (PyCode_GetNumFree((PyCodeObject *)cmd) > 0) { PyErr_SetString(PyExc_TypeError, "code object passed to eval() may not contain free variables"); return NULL; diff --git a/Python/ceval.c b/Python/ceval.c index 29d7082..3e41b9a 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -2094,7 +2094,7 @@ eval_frame(PyFrameObject *f) int nfree; v = POP(); /* code object */ x = PyFunction_New(v, f->f_globals); - nfree = PyTuple_GET_SIZE(((PyCodeObject *)v)->co_freevars); + nfree = PyCode_GetNumFree((PyCodeObject *)v); Py_DECREF(v); /* XXX Maybe this should be a separate opcode? */ if (x != NULL && nfree > 0) { @@ -3631,6 +3631,11 @@ exec_statement(PyFrameObject *f, PyObject *prog, PyObject *globals, if (PyDict_GetItemString(globals, "__builtins__") == NULL) PyDict_SetItemString(globals, "__builtins__", f->f_builtins); 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); } else if (PyFile_Check(prog)) { diff --git a/Python/compile.c b/Python/compile.c index d76769c..4421284 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -2273,7 +2273,7 @@ com_and_test(struct compiling *c, node *n) static int 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) return 0; for (i = 0; i < free; ++i) { @@ -2333,7 +2333,7 @@ com_test(struct compiling *c, node *n) com_push(c, 1); if (closure) { com_addoparg(c, MAKE_CLOSURE, ndefs); - com_pop(c, PyTuple_GET_SIZE(co->co_freevars)); + com_pop(c, PyCode_GetNumFree(co)); } else com_addoparg(c, MAKE_FUNCTION, ndefs); Py_DECREF(co); @@ -3590,7 +3590,7 @@ com_classdef(struct compiling *c, node *n) com_push(c, 1); if (closure) { com_addoparg(c, MAKE_CLOSURE, 0); - com_pop(c, PyTuple_GET_SIZE(co->co_freevars)); + com_pop(c, PyCode_GetNumFree(co)); } else com_addoparg(c, MAKE_FUNCTION, 0); com_addoparg(c, CALL_FUNCTION, 0); -- cgit v0.12