]> granicus.if.org Git - python/commitdiff
Prevent a crash with nested scopes, again caused by calling Py_DECREF when the pointer
authorAmaury Forgeot d'Arc <amauryfa@gmail.com>
Sat, 16 Feb 2008 20:55:24 +0000 (20:55 +0000)
committerAmaury Forgeot d'Arc <amauryfa@gmail.com>
Sat, 16 Feb 2008 20:55:24 +0000 (20:55 +0000)
is still present in the containing structure.

Lib/test/test_scope.py
Misc/NEWS
Objects/cellobject.c

index db88dbd5130da8a5087240ca754ee8818e76325b..cd2d98c075c4634fd42da28caf855d034fe3f8b1 100644 (file)
@@ -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)
index 74466d69143dbc793d1fec20bca4daed6186f211..c8c4a0347c6f15bf3706436a416e453d6a8ba513 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -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.
index dc684d5b67189a5bf0815e3d01031c5696bf7312..b72d43be67c70fb804587b1dd918528afec05ceb 100644 (file)
@@ -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;
 }