SVN: ZODB/branches/3.8/ Fixed bug:

Jim Fulton <[email protected]>
Newsgroups gmane.comp.python.zope.zodb.cvs
Message-ID <20090823172109.BBABD9417B__37161.3479139798$1251048081$gmane$org@cvs.zope.org>
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(),
+        ))
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.