diff options
-rw-r--r-- | Lib/test/test_scope.py | 18 | ||||
-rw-r--r-- | Misc/NEWS | 3 | ||||
-rw-r--r-- | Objects/cellobject.c | 4 |
3 files changed, 24 insertions, 1 deletions
diff --git a/Lib/test/test_scope.py b/Lib/test/test_scope.py index db88dbd..cd2d98c 100644 --- a/Lib/test/test_scope.py +++ b/Lib/test/test_scope.py @@ -597,6 +597,24 @@ self.assert_(X.passed) f(4)() + def testFreeingCell(self): + # Test what happens when a finalizer accesses + # the cell where the object was stored. + class Special: + def __del__(self): + nestedcell_get() + + def f(): + global nestedcell_get + def nestedcell_get(): + return c + + c = (Special(),) + c = 2 + + f() # used to crash the interpreter... + + def test_main(): run_unittest(ScopeTests) @@ -12,6 +12,9 @@ What's New in Python 2.6 alpha 1? Core and builtins ----------------- +- Fixed several potential crashes, all caused by specially crafted __del__ + methods exploiting objects in temporarily inconsistent state. + - Issue #2115: Important speedup in setting __slot__ attributes. Also prevent a possible crash: an Abstract Base Class would try to access a slot on a registered virtual subclass. diff --git a/Objects/cellobject.c b/Objects/cellobject.c index dc684d5..b72d43b 100644 --- a/Objects/cellobject.c +++ b/Objects/cellobject.c @@ -31,13 +31,15 @@ PyCell_Get(PyObject *op) int PyCell_Set(PyObject *op, PyObject *obj) { + PyObject* oldobj; if (!PyCell_Check(op)) { PyErr_BadInternalCall(); return -1; } - Py_XDECREF(((PyCellObject*)op)->ob_ref); + oldobj = PyCell_GET(op); Py_XINCREF(obj); PyCell_SET(op, obj); + Py_XDECREF(oldobj); return 0; } |