Prevent a crash with nested scopes, again caused by calling Py_DECREF when the pointer

is still present in the containing structure.
This commit is contained in:
Amaury Forgeot d'Arc 2008-02-16 20:55:24 +00:00
parent 588ff93f13
commit 632fad3933
3 changed files with 24 additions and 1 deletions

View File

@ -597,6 +597,24 @@ self.assert_(X.passed)
f(4)() 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(): def test_main():
run_unittest(ScopeTests) run_unittest(ScopeTests)

View File

@ -12,6 +12,9 @@ What's New in Python 2.6 alpha 1?
Core and builtins 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 - Issue #2115: Important speedup in setting __slot__ attributes. Also
prevent a possible crash: an Abstract Base Class would try to access a slot prevent a possible crash: an Abstract Base Class would try to access a slot
on a registered virtual subclass. on a registered virtual subclass.

View File

@ -31,13 +31,15 @@ PyCell_Get(PyObject *op)
int int
PyCell_Set(PyObject *op, PyObject *obj) PyCell_Set(PyObject *op, PyObject *obj)
{ {
PyObject* oldobj;
if (!PyCell_Check(op)) { if (!PyCell_Check(op)) {
PyErr_BadInternalCall(); PyErr_BadInternalCall();
return -1; return -1;
} }
Py_XDECREF(((PyCellObject*)op)->ob_ref); oldobj = PyCell_GET(op);
Py_XINCREF(obj); Py_XINCREF(obj);
PyCell_SET(op, obj); PyCell_SET(op, obj);
Py_XDECREF(oldobj);
return 0; return 0;
} }