Skip to content

Commit 520403e

Browse files
authored
gh-115733: Fix crash involving exhausted list iterator (#115740)
* gh-115733: Fix crash involving exhausted iterator * Add blurb
1 parent 494739e commit 520403e

File tree

6 files changed

+13
-5
lines changed

6 files changed

+13
-5
lines changed

Lib/test/list_tests.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -562,3 +562,8 @@ def test_exhausted_iterator(self):
562562
self.assertEqual(list(exhit), [])
563563
self.assertEqual(list(empit), [9])
564564
self.assertEqual(a, self.type2test([1, 2, 3, 9]))
565+
566+
# gh-115733: Crash when iterating over exhausted iterator
567+
exhit = iter(self.type2test([1, 2, 3]))
568+
for _ in exhit:
569+
next(exhit, 1)
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Fix crash when calling ``next()`` on exhausted list iterators.

Objects/listobject.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3537,13 +3537,13 @@ listreviter_next(PyObject *self)
35373537
{
35383538
listreviterobject *it = (listreviterobject *)self;
35393539
assert(it != NULL);
3540-
PyListObject *seq = it->it_seq;
3541-
assert(PyList_Check(seq));
3542-
35433540
Py_ssize_t index = LOAD_SSIZE(it->it_index);
35443541
if (index < 0) {
35453542
return NULL;
35463543
}
3544+
3545+
PyListObject *seq = it->it_seq;
3546+
assert(PyList_Check(seq));
35473547
PyObject *item = list_get_item_ref(seq, index);
35483548
if (item != NULL) {
35493549
STORE_SSIZE(it->it_index, index - 1);

Python/bytecodes.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2612,7 +2612,7 @@ dummy_func(
26122612
assert(Py_TYPE(iter) == &PyListIter_Type);
26132613
STAT_INC(FOR_ITER, hit);
26142614
PyListObject *seq = it->it_seq;
2615-
if ((size_t)it->it_index >= (size_t)PyList_GET_SIZE(seq)) {
2615+
if (seq == NULL || (size_t)it->it_index >= (size_t)PyList_GET_SIZE(seq)) {
26162616
it->it_index = -1;
26172617
#ifndef Py_GIL_DISABLED
26182618
if (seq != NULL) {
@@ -2633,6 +2633,7 @@ dummy_func(
26332633
_PyListIterObject *it = (_PyListIterObject *)iter;
26342634
assert(Py_TYPE(iter) == &PyListIter_Type);
26352635
PyListObject *seq = it->it_seq;
2636+
DEOPT_IF(seq == NULL);
26362637
DEOPT_IF((size_t)it->it_index >= (size_t)PyList_GET_SIZE(seq));
26372638
}
26382639

Python/executor_cases.c.h

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Python/generated_cases.c.h

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)