mirror of https://github.com/python/cpython
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.
This commit is contained in:
parent
d6e0032768
commit
10c7e86454
|
@ -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:
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue