mirror of https://github.com/python/cpython
gh-115733: Fix crash involving exhausted list iterator (#115740)
* gh-115733: Fix crash involving exhausted iterator * Add blurb
This commit is contained in:
parent
494739e1f7
commit
520403ed4c
|
@ -562,3 +562,8 @@ class CommonTest(seq_tests.CommonTest):
|
||||||
self.assertEqual(list(exhit), [])
|
self.assertEqual(list(exhit), [])
|
||||||
self.assertEqual(list(empit), [9])
|
self.assertEqual(list(empit), [9])
|
||||||
self.assertEqual(a, self.type2test([1, 2, 3, 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)
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
Fix crash when calling ``next()`` on exhausted list iterators.
|
|
@ -3537,13 +3537,13 @@ listreviter_next(PyObject *self)
|
||||||
{
|
{
|
||||||
listreviterobject *it = (listreviterobject *)self;
|
listreviterobject *it = (listreviterobject *)self;
|
||||||
assert(it != NULL);
|
assert(it != NULL);
|
||||||
PyListObject *seq = it->it_seq;
|
|
||||||
assert(PyList_Check(seq));
|
|
||||||
|
|
||||||
Py_ssize_t index = LOAD_SSIZE(it->it_index);
|
Py_ssize_t index = LOAD_SSIZE(it->it_index);
|
||||||
if (index < 0) {
|
if (index < 0) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PyListObject *seq = it->it_seq;
|
||||||
|
assert(PyList_Check(seq));
|
||||||
PyObject *item = list_get_item_ref(seq, index);
|
PyObject *item = list_get_item_ref(seq, index);
|
||||||
if (item != NULL) {
|
if (item != NULL) {
|
||||||
STORE_SSIZE(it->it_index, index - 1);
|
STORE_SSIZE(it->it_index, index - 1);
|
||||||
|
|
|
@ -2612,7 +2612,7 @@ dummy_func(
|
||||||
assert(Py_TYPE(iter) == &PyListIter_Type);
|
assert(Py_TYPE(iter) == &PyListIter_Type);
|
||||||
STAT_INC(FOR_ITER, hit);
|
STAT_INC(FOR_ITER, hit);
|
||||||
PyListObject *seq = it->it_seq;
|
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;
|
it->it_index = -1;
|
||||||
#ifndef Py_GIL_DISABLED
|
#ifndef Py_GIL_DISABLED
|
||||||
if (seq != NULL) {
|
if (seq != NULL) {
|
||||||
|
@ -2633,6 +2633,7 @@ dummy_func(
|
||||||
_PyListIterObject *it = (_PyListIterObject *)iter;
|
_PyListIterObject *it = (_PyListIterObject *)iter;
|
||||||
assert(Py_TYPE(iter) == &PyListIter_Type);
|
assert(Py_TYPE(iter) == &PyListIter_Type);
|
||||||
PyListObject *seq = it->it_seq;
|
PyListObject *seq = it->it_seq;
|
||||||
|
DEOPT_IF(seq == NULL);
|
||||||
DEOPT_IF((size_t)it->it_index >= (size_t)PyList_GET_SIZE(seq));
|
DEOPT_IF((size_t)it->it_index >= (size_t)PyList_GET_SIZE(seq));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2427,6 +2427,7 @@
|
||||||
_PyListIterObject *it = (_PyListIterObject *)iter;
|
_PyListIterObject *it = (_PyListIterObject *)iter;
|
||||||
assert(Py_TYPE(iter) == &PyListIter_Type);
|
assert(Py_TYPE(iter) == &PyListIter_Type);
|
||||||
PyListObject *seq = it->it_seq;
|
PyListObject *seq = it->it_seq;
|
||||||
|
if (seq == NULL) goto deoptimize;
|
||||||
if ((size_t)it->it_index >= (size_t)PyList_GET_SIZE(seq)) goto deoptimize;
|
if ((size_t)it->it_index >= (size_t)PyList_GET_SIZE(seq)) goto deoptimize;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2560,7 +2560,7 @@
|
||||||
assert(Py_TYPE(iter) == &PyListIter_Type);
|
assert(Py_TYPE(iter) == &PyListIter_Type);
|
||||||
STAT_INC(FOR_ITER, hit);
|
STAT_INC(FOR_ITER, hit);
|
||||||
PyListObject *seq = it->it_seq;
|
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;
|
it->it_index = -1;
|
||||||
#ifndef Py_GIL_DISABLED
|
#ifndef Py_GIL_DISABLED
|
||||||
if (seq != NULL) {
|
if (seq != NULL) {
|
||||||
|
|
Loading…
Reference in New Issue