Skip to content

Commit

Permalink
00421: pythongh-115733: Fix crash involving exhausted list iterator (p…
Browse files Browse the repository at this point in the history
  • Loading branch information
colesbury authored and befeleme committed Feb 21, 2024
1 parent d9d7e46 commit 31a3fb0
Show file tree
Hide file tree
Showing 6 changed files with 13 additions and 5 deletions.
5 changes: 5 additions & 0 deletions Lib/test/list_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -562,3 +562,8 @@ def test_exhausted_iterator(self):
self.assertEqual(list(exhit), [])
self.assertEqual(list(empit), [9])
self.assertEqual(a, self.type2test([1, 2, 3, 9]))

# gh-115733: Crash when iterating over exhausted iterator
exhit = iter(self.type2test([1, 2, 3]))
for _ in exhit:
next(exhit, 1)
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Fix crash when calling ``next()`` on exhausted list iterators.
6 changes: 3 additions & 3 deletions Objects/listobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -3537,13 +3537,13 @@ listreviter_next(PyObject *self)
{
listreviterobject *it = (listreviterobject *)self;
assert(it != NULL);
PyListObject *seq = it->it_seq;
assert(PyList_Check(seq));

Py_ssize_t index = LOAD_SSIZE(it->it_index);
if (index < 0) {
return NULL;
}

PyListObject *seq = it->it_seq;
assert(PyList_Check(seq));
PyObject *item = list_get_item_ref(seq, index);
if (item != NULL) {
STORE_SSIZE(it->it_index, index - 1);
Expand Down
3 changes: 2 additions & 1 deletion Python/bytecodes.c
Original file line number Diff line number Diff line change
Expand Up @@ -2606,7 +2606,7 @@ dummy_func(
assert(Py_TYPE(iter) == &PyListIter_Type);
STAT_INC(FOR_ITER, hit);
PyListObject *seq = it->it_seq;
if ((size_t)it->it_index >= (size_t)PyList_GET_SIZE(seq)) {
if (seq == NULL || (size_t)it->it_index >= (size_t)PyList_GET_SIZE(seq)) {
it->it_index = -1;
#ifndef Py_GIL_DISABLED
if (seq != NULL) {
Expand All @@ -2627,6 +2627,7 @@ dummy_func(
_PyListIterObject *it = (_PyListIterObject *)iter;
assert(Py_TYPE(iter) == &PyListIter_Type);
PyListObject *seq = it->it_seq;
DEOPT_IF(seq == NULL);
DEOPT_IF((size_t)it->it_index >= (size_t)PyList_GET_SIZE(seq));
}

Expand Down
1 change: 1 addition & 0 deletions Python/executor_cases.c.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Python/generated_cases.c.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 31a3fb0

Please sign in to comment.