]> granicus.if.org Git - python/commitdiff
deque_traverse(): If the deque had one block, and its rightindex was
authorTim Peters <tim.peters@gmail.com>
Fri, 1 Oct 2004 02:01:04 +0000 (02:01 +0000)
committerTim Peters <tim.peters@gmail.com>
Fri, 1 Oct 2004 02:01:04 +0000 (02:01 +0000)
BLOCKLEN-1, this assert-failed in a debug build, or went wild with a
NULL pointer in a release build.  Reported on c.l.py by Stefan Behnel.

Lib/test/test_deque.py
Modules/collectionsmodule.c

index c0024acefe3031071cd6329a187d1cab85f906b8..300e9af9fcfd5294c0bcaf7f269461f0dd2e6333 100644 (file)
@@ -324,6 +324,15 @@ class TestBasic(unittest.TestCase):
         for s in ('abcd', xrange(2000)):
             self.assertEqual(list(reversed(deque(s))), list(reversed(s)))
 
+    def test_gc_doesnt_blowup(self):
+        import gc
+        # This used to assert-fail in deque_traverse() under a debug
+        # build, or run wild with a NULL pointer in a release build.
+        d = deque()
+        for i in xrange(100):
+            d.append(1)
+            gc.collect()
+
 def R(seqn):
     'Regular generator'
     for i in seqn:
index f8a6f612205f0ff4e2f633e4fa627a19cb198e20..196cbe2244abdad18afa010f297b568d3118f2d3 100644 (file)
@@ -478,19 +478,22 @@ deque_dealloc(dequeobject *deque)
 static int
 deque_traverse(dequeobject *deque, visitproc visit, void *arg)
 {
-       block * b = deque->leftblock;
-       int index = deque->leftindex;
+       block *b;
        PyObject *item;
+       int index;
+       int indexlo = deque->leftindex;
 
-       while (b != deque->rightblock || index <= deque->rightindex) {
-               item = b->data[index];
-               index++;
-               if (index == BLOCKLEN ) {
-                       assert(b->rightlink != NULL);
-                       b = b->rightlink;
-                       index = 0;
+       assert(deque->leftblock != NULL);
+       for (b = deque->leftblock; b != NULL; b = b->rightlink) {
+               const int indexhi = b == deque->rightblock ?
+                                        deque->rightindex :
+                                        BLOCKLEN - 1;
+
+               for (index = indexlo; index <= indexhi; ++index) {
+                       item = b->data[index];
+                       Py_VISIT(item);
                }
-               Py_VISIT(item);
+               indexlo = 0;
        }
        return 0;
 }