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)
--- /dev/null
+Fix crash when calling ``next()`` on exhausted list iterators.
{
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);
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) {
_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));
}
_PyListIterObject *it = (_PyListIterObject *)iter;
assert(Py_TYPE(iter) == &PyListIter_Type);
PyListObject *seq = it->it_seq;
+ if (seq == NULL) goto deoptimize;
if ((size_t)it->it_index >= (size_t)PyList_GET_SIZE(seq)) goto deoptimize;
break;
}
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) {