]> granicus.if.org Git - python/commitdiff
Issue 3514: Fixed segfault dues to infinite loop in __getattr__.
authorAlexandre Vassalotti <alexandre@peadrop.com>
Fri, 15 Aug 2008 03:07:47 +0000 (03:07 +0000)
committerAlexandre Vassalotti <alexandre@peadrop.com>
Fri, 15 Aug 2008 03:07:47 +0000 (03:07 +0000)
Lib/test/pickletester.py
Modules/_pickle.c

index c9ebdb8dc9306894e47da017427acd26596df508..a622145a9daaad7319eb38b34aa9b8f3a9d0dbc5 100644 (file)
@@ -868,6 +868,14 @@ class AbstractPickleTests(unittest.TestCase):
             y = self.loads(s)
             self.assertEqual(y._reduce_called, 1)
 
+    def test_bad_getattr(self):
+        x = BadGetattr()
+        for proto in 0, 1:
+            self.assertRaises(RuntimeError, self.dumps, x, proto)
+        # protocol 2 don't raise a RuntimeError.
+        d = self.dumps(x, 2)
+        self.assertRaises(RuntimeError, self.loads, d)
+
 # Test classes for reduce_ex
 
 class REX_one(object):
@@ -949,6 +957,10 @@ class SimpleNewObj(object):
         # raise an error, to make sure this isn't called
         raise TypeError("SimpleNewObj.__init__() didn't expect to get called")
 
+class BadGetattr:
+    def __getattr__(self, key):
+        self.foo
+
 class AbstractPickleModuleTests(unittest.TestCase):
 
     def test_dump_closed_file(self):
index 0f5b06bea8d68ec339e38b9299d0eb241210c340..52fa15694cd6e31712fbc29d2a7eb535ff4715d7 100644 (file)
@@ -3834,8 +3834,11 @@ load_build(UnpicklerObject *self)
     inst = self->stack->data[self->stack->length - 1];
 
     setstate = PyObject_GetAttrString(inst, "__setstate__");
-    if (setstate == NULL && PyErr_ExceptionMatches(PyExc_AttributeError)) {
-        PyErr_Clear();
+    if (setstate == NULL) {
+        if (PyErr_ExceptionMatches(PyExc_AttributeError))
+            PyErr_Clear();
+        else
+            return -1;
     }
     else {
         PyObject *result;