]> granicus.if.org Git - python/commitdiff
Fix for SF bug [ #492403 ] exec() segfaults on closure's func_code
authorJeremy Hylton <jeremy@alum.mit.edu>
Thu, 13 Dec 2001 19:51:56 +0000 (19:51 +0000)
committerJeremy Hylton <jeremy@alum.mit.edu>
Thu, 13 Dec 2001 19:51:56 +0000 (19:51 +0000)
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
Python/ceval.c
Python/compile.c

index 8e4ca2ec5a1d908eb9a3380adb53795f3a2e049c..f5ce74975c10f2119c0ac0063b8e1b1fbf059066 100644 (file)
@@ -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;
index 29d70826f2b9a89dcedc67c4d9f991a6d3c84c23..3e41b9a148d795b8f90cde00a1247dabdcdd981e 100644 (file)
@@ -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)) {
index d76769c446ee5e6d9bc5f21a2e48f2749eaa3f3a..442128495d2dbbcfbb7a465a380d511b1e224d6d 100644 (file)
@@ -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);