summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAmaury Forgeot d'Arc <amauryfa@gmail.com>2008-02-16 20:55:24 (GMT)
committerAmaury Forgeot d'Arc <amauryfa@gmail.com>2008-02-16 20:55:24 (GMT)
commit632fad393304db484f508d1833a9fda52b7f193a (patch)
tree47332f046dac89a7d67b08d414154015233eeb38
parent588ff93f1383436694e26c962528291913012296 (diff)
downloadcpython-632fad393304db484f508d1833a9fda52b7f193a.zip
cpython-632fad393304db484f508d1833a9fda52b7f193a.tar.gz
cpython-632fad393304db484f508d1833a9fda52b7f193a.tar.bz2
Prevent a crash with nested scopes, again caused by calling Py_DECREF when the pointer
is still present in the containing structure.
-rw-r--r--Lib/test/test_scope.py18
-rw-r--r--Misc/NEWS3
-rw-r--r--Objects/cellobject.c4
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)
diff --git a/Misc/NEWS b/Misc/NEWS
index 74466d6..c8c4a03 100644
--- 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.
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;
}