[Zodb-checkins] SVN: ZODB/branches/3.9/src/ Bug Fixed:

Jim Fulton jim at zope.com
Mon Sep 20 13:28:58 EDT 2010


Log message for revision 116671:
  Bug Fixed:
  
  - BTree sets and tree sets didn't correctly check values passed to
    update or to constructors, causing Python to exit under certain
    circumstances.
  

Changed:
  U   ZODB/branches/3.9/src/BTrees/intkeymacros.h
  U   ZODB/branches/3.9/src/BTrees/intvaluemacros.h
  U   ZODB/branches/3.9/src/BTrees/tests/testBTrees.py
  U   ZODB/branches/3.9/src/CHANGES.txt

-=-
Modified: ZODB/branches/3.9/src/BTrees/intkeymacros.h
===================================================================
--- ZODB/branches/3.9/src/BTrees/intkeymacros.h	2010-09-20 17:22:37 UTC (rev 116670)
+++ ZODB/branches/3.9/src/BTrees/intkeymacros.h	2010-09-20 17:28:58 UTC (rev 116671)
@@ -21,9 +21,16 @@
 #define KEY_TYPE int
 #define KEY_CHECK PyInt_Check
 #define COPY_KEY_TO_OBJECT(O, K) O=PyInt_FromLong(K)
-#define COPY_KEY_FROM_ARG(TARGET, ARG, STATUS) \
-  if (PyInt_Check(ARG)) TARGET=PyInt_AS_LONG(ARG); else { \
-      PyErr_SetString(PyExc_TypeError, "expected integer key"); \
+#define COPY_KEY_FROM_ARG(TARGET, ARG, STATUS)                    \
+  if (PyInt_Check(ARG)) {                                         \
+      long vcopy = PyInt_AS_LONG(ARG);                            \
+      if ((int)vcopy != vcopy) {                                  \
+        PyErr_SetObject(PyExc_OverflowError, ARG);                \
+        (STATUS)=0; (TARGET)=0;                                   \
+      }                                                           \
+      else TARGET = vcopy;                                        \
+  } else {                                                        \
+      PyErr_SetString(PyExc_TypeError, "expected integer key");   \
       (STATUS)=0; (TARGET)=0; }
 #endif
 

Modified: ZODB/branches/3.9/src/BTrees/intvaluemacros.h
===================================================================
--- ZODB/branches/3.9/src/BTrees/intvaluemacros.h	2010-09-20 17:22:37 UTC (rev 116670)
+++ ZODB/branches/3.9/src/BTrees/intvaluemacros.h	2010-09-20 17:28:58 UTC (rev 116671)
@@ -18,11 +18,20 @@
 #else
 #define VALUE_TYPE int
 #define VALUE_PARSE "i"
-#define COPY_VALUE_TO_OBJECT(O, K) O=PyInt_FromLong(K) 
-#define COPY_VALUE_FROM_ARG(TARGET, ARG, STATUS) \
-  if (PyInt_Check(ARG)) TARGET=PyInt_AsLong(ARG); else { \
-      PyErr_SetString(PyExc_TypeError, "expected integer value"); \
-      (STATUS)=0; (TARGET)=0; } 
+#define COPY_VALUE_TO_OBJECT(O, K) O=PyInt_FromLong(K)
+
+#define COPY_VALUE_FROM_ARG(TARGET, ARG, STATUS)                  \
+  if (PyInt_Check(ARG)) {                                         \
+      long vcopy = PyInt_AS_LONG(ARG);                            \
+      if ((int)vcopy != vcopy) {                                  \
+        PyErr_SetObject(PyExc_OverflowError, ARG);                \
+        (STATUS)=0; (TARGET)=0;                                   \
+      }                                                           \
+      else TARGET = vcopy;                                        \
+  } else {                                                        \
+      PyErr_SetString(PyExc_TypeError, "expected integer key");   \
+      (STATUS)=0; (TARGET)=0; }
+
 #endif
 
 #undef VALUE_TYPE_IS_PYOBJECT

Modified: ZODB/branches/3.9/src/BTrees/tests/testBTrees.py
===================================================================
--- ZODB/branches/3.9/src/BTrees/tests/testBTrees.py	2010-09-20 17:22:37 UTC (rev 116670)
+++ ZODB/branches/3.9/src/BTrees/tests/testBTrees.py	2010-09-20 17:28:58 UTC (rev 116671)
@@ -1805,6 +1805,28 @@
 class IIBTreeTest(BTreeTests):
     def setUp(self):
         self.t = IIBTree()
+
+    def testIIBTreeOverflow(self):
+        good = set()
+        b = self.t
+
+        def trial(i):
+            try:
+                b[i] = 0
+            except (OverflowError, TypeError), v:
+                self.assertRaises(v.__class__, b.__setitem__, 0, i)
+            else:
+                good.add(i)
+                b[0] = i
+                self.assertEqual(b[0], i)
+
+        for i in range((1<<31) - 3, (1<<31) + 3):
+            trial(i)
+            trial(-i)
+
+        del b[0]
+        self.assertEqual(sorted(good), sorted(b))
+
 class IFBTreeTest(BTreeTests):
     def setUp(self):
         self.t = IFBTree()
@@ -1934,14 +1956,9 @@
             self.assertRaises(TypeError, s.insert, big)
             self.assertRaises(TypeError, s.insert, BTrees.family32.minint - 1)
         else: # 64 bit Python
-            s.insert(BTrees.family32.maxint + 1)
-            self.assert_(BTrees.family32.maxint + 1 not in list(s))
-            # yeah, it's len of 1 now, and rolled over to the minint...
-            # don't look...don't look...
-            s = IOTreeSet()
-            s.insert(BTrees.family32.minint - 1)
-            self.assert_(BTrees.family32.minint - 1 not in list(s))
-            # similarly, this is a len of 1, rolling over to the maxint...
+            self.assertRaises(OverflowError, s.insert, big)
+            self.assertRaises(OverflowError, s.insert,
+                              BTrees.family32.minint - 1)
         self.check_pickling(BTrees.family32)
 
     def test64(self):

Modified: ZODB/branches/3.9/src/CHANGES.txt
===================================================================
--- ZODB/branches/3.9/src/CHANGES.txt	2010-09-20 17:22:37 UTC (rev 116670)
+++ ZODB/branches/3.9/src/CHANGES.txt	2010-09-20 17:28:58 UTC (rev 116671)
@@ -22,6 +22,12 @@
 
   Fixes: https://bugs.launchpad.net/zodb/+bug/135108
 
+- Passing keys or values outside the range of 32-bit ints on 64-bit
+  platforms led to undetected overflow errors. Now these cases cause
+  Overflow errors to be raised.
+
+  https://bugs.launchpad.net/zodb/+bug/143237
+
 - BTree sets and tree sets didn't correctly check values passed to
   update or to constructors, causing Python to exit under certain
   circumstances.



More information about the Zodb-checkins mailing list