From ded18d634f2e1615b746dca2698d6a98ff63045d Mon Sep 17 00:00:00 2001 From: Guido van Rossum Date: Thu, 28 Mar 2002 20:21:21 +0000 Subject: Backport for 2.1.3 (if we ever release it; we may have to because this is what Zope 2 will be using in the foreseeable future). Fix an issue that was reported in but unrelated to the main problem of SF bug 535905 (Evil Trashcan and GC interaction). The SETLOCAL() macro should not DECREF the local variable in-place and then store the new value; it should copy the old value to a temporary value, then store the new value, and then DECREF the temporary value. This is because it is possible that during the DECREF the frame is accessed by other code (e.g. a __del__ method or gc.collect()) and the variable would be pointing to already-freed memory. BUGFIX CANDIDATE! --- Python/ceval.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/Python/ceval.c b/Python/ceval.c index 0872c3e..27ec15b 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -414,8 +414,16 @@ eval_code2(PyCodeObject *co, PyObject *globals, PyObject *locals, /* Local variable macros */ #define GETLOCAL(i) (fastlocals[i]) -#define SETLOCAL(i, value) do { Py_XDECREF(GETLOCAL(i)); \ - GETLOCAL(i) = value; } while (0) + +/* The SETLOCAL() macro must not DECREF the local variable in-place and + then store the new value; it must copy the old value to a temporary + value, then store the new value, and then DECREF the temporary value. + This is because it is possible that during the DECREF the frame is + accessed by other code (e.g. a __del__ method or gc.collect()) and the + variable would be pointing to already-freed memory. */ +#define SETLOCAL(i, value) do { PyObject *tmp = GETLOCAL(i); \ + GETLOCAL(i) = value; \ + Py_XDECREF(tmp); } while (0) /* Start of code */ -- cgit v0.12