[Zodb-checkins] SVN: ZODB/branches/3.8/ Fixed bug:

Jim Fulton jim at zope.com
Sun Aug 23 13:21:09 EDT 2009


Log message for revision 103112:
  Fixed bug:
    Calling __setstate__ on a persistent object could under certain
    uncommon cause the process to crash.
  

Changed:
  U   ZODB/branches/3.8/NEWS.txt
  U   ZODB/branches/3.8/src/persistent/cPersistence.c
  U   ZODB/branches/3.8/src/persistent/tests/test_persistent.py

-=-
Modified: ZODB/branches/3.8/NEWS.txt
===================================================================
--- ZODB/branches/3.8/NEWS.txt	2009-08-23 17:19:04 UTC (rev 103111)
+++ ZODB/branches/3.8/NEWS.txt	2009-08-23 17:21:09 UTC (rev 103112)
@@ -1,4 +1,4 @@
-Whats new in ZODB 3.8.2
+Whats new in ZODB 3.8.3
 =======================
 
 New Feature:
@@ -16,6 +16,10 @@
 - Fixed a pack test that was not compatible with storages that always
   return an object count of 0.
 
+- Calling __setstate__ on a persistent object could under certain
+  uncommon cause the process to crash.
+
+
 Whats new in ZODB 3.8.2
 =======================
 

Modified: ZODB/branches/3.8/src/persistent/cPersistence.c
===================================================================
--- ZODB/branches/3.8/src/persistent/cPersistence.c	2009-08-23 17:19:04 UTC (rev 103111)
+++ ZODB/branches/3.8/src/persistent/cPersistence.c	2009-08-23 17:21:09 UTC (rev 103112)
@@ -446,43 +446,47 @@
 "  will be cleared and updated with the value.\n\n"
 "  The items in the second element will be assigned as attributes.\n"
 ;
-
 static PyObject *
 pickle___setstate__(PyObject *self, PyObject *state)
 {
-    PyObject *slots=NULL;
+  PyObject *slots=NULL;
 
-    if (PyTuple_Check(state)) {
-	if (!PyArg_ParseTuple(state, "OO:__setstate__", &state, &slots))
-	    return NULL;
+  if (PyTuple_Check(state))
+    {
+      if (!PyArg_ParseTuple(state, "OO:__setstate__", &state, &slots))
+        return NULL;
     }
 
-    if (state != Py_None) {
-	PyObject **dict;
+  if (state != Py_None)
+    {
+      PyObject **dict;
 
-	dict = _PyObject_GetDictPtr(self);
-	if (dict) {
-	    if (!*dict) {
-		*dict = PyDict_New();
-		if (!*dict)
-		    return NULL;
-            }
+      dict = _PyObject_GetDictPtr(self);
+      
+      if (!dict)
+        {
+          PyErr_SetString(PyExc_TypeError,
+                          "this object has no instance dictionary");
+          return NULL;
         }
 
-	if (*dict) {
-	    PyDict_Clear(*dict);
-	    if (PyDict_Update(*dict, state) < 0)
-		return NULL;
+      if (!*dict)
+        {
+          *dict = PyDict_New();
+          if (!*dict)
+            return NULL;
         }
-	else if (pickle_setattrs_from_dict(self, state) < 0)
-	    return NULL;
+
+      PyDict_Clear(*dict);
+      if (PyDict_Update(*dict, state) < 0)
+        return NULL;
     }
 
-    if (slots && pickle_setattrs_from_dict(self, slots) < 0)
-	return NULL;
+  if (slots && pickle_setattrs_from_dict(self, slots) < 0)
+    return NULL;
 
-    Py_INCREF(Py_None);
-    return Py_None;
+  Py_INCREF(Py_None);
+  return Py_None;
 }
 
 static char pickle___reduce__doc[] =

Modified: ZODB/branches/3.8/src/persistent/tests/test_persistent.py
===================================================================
--- ZODB/branches/3.8/src/persistent/tests/test_persistent.py	2009-08-23 17:19:04 UTC (rev 103111)
+++ ZODB/branches/3.8/src/persistent/tests/test_persistent.py	2009-08-23 17:21:09 UTC (rev 103112)
@@ -1,16 +1,17 @@
 ##############################################################################
 #
-# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
+# Copyright (c) Zope Foundation and Contributors.
 # All Rights Reserved.
 #
 # This software is subject to the provisions of the Zope Public License,
-# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
 # THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
 # WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
 # FOR A PARTICULAR PURPOSE.
 #
 ##############################################################################
+import unittest
 from zope.testing import doctest
 from persistent import Persistent
 
@@ -20,5 +21,23 @@
     def inc(self):
         self.x += 1
 
+def cpersistent_setstate_pointer_sanity():
+    """
+    >>> Persistent().__setstate__({})
+    Traceback (most recent call last):
+    ...
+    TypeError: this object has no instance dictionary
+
+    >>> class C(Persistent): __slots__ = 'x', 'y'
+    >>> C().__setstate__(({}, {}))
+    Traceback (most recent call last):
+    ...
+    TypeError: this object has no instance dictionary
+    """
+
+
 def test_suite():
-    return doctest.DocFileSuite("persistent.txt", globs={"P": P})
+    return unittest.TestSuite((
+        doctest.DocFileSuite("persistent.txt", globs={"P": P}),
+        doctest.DocTestSuite(),
+        ))



More information about the Zodb-checkins mailing list