From 10c7e86454db59ece9d5ed028dd9d104ac766bdf Mon Sep 17 00:00:00 2001 From: Tim Peters Date: Fri, 1 Oct 2004 02:01:04 +0000 Subject: deque_traverse(): If the deque had one block, and its rightindex was 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 | 9 +++++++++ Modules/collectionsmodule.c | 23 +++++++++++++---------- 2 files changed, 22 insertions(+), 10 deletions(-) diff --git a/Lib/test/test_deque.py b/Lib/test/test_deque.py index c0024ac..300e9af 100644 --- a/Lib/test/test_deque.py +++ b/Lib/test/test_deque.py @@ -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: diff --git a/Modules/collectionsmodule.c b/Modules/collectionsmodule.c index f8a6f61..196cbe2 100644 --- a/Modules/collectionsmodule.c +++ b/Modules/collectionsmodule.c @@ -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; } -- cgit v0.12