]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-115733: Fix crash involving exhausted list iterator (#115740)
authorSam Gross <colesbury@gmail.com>
Tue, 20 Feb 2024 20:18:44 +0000 (15:18 -0500)
committerGitHub <noreply@github.com>
Tue, 20 Feb 2024 20:18:44 +0000 (05:18 +0900)
* gh-115733: Fix crash involving exhausted iterator

* Add blurb

Lib/test/list_tests.py
Misc/NEWS.d/next/Core and Builtins/2024-02-20-18-49-02.gh-issue-115733.51Zb85.rst [new file with mode: 0644]
Objects/listobject.c
Python/bytecodes.c
Python/executor_cases.c.h
Python/generated_cases.c.h

index d9ab21d4941cdb9b75440917746ef7e66dd21a58..26118e14bb97e08d66fd331fa6115c9be53c94dc 100644 (file)
@@ -562,3 +562,8 @@ class CommonTest(seq_tests.CommonTest):
         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)
diff --git a/Misc/NEWS.d/next/Core and Builtins/2024-02-20-18-49-02.gh-issue-115733.51Zb85.rst b/Misc/NEWS.d/next/Core and Builtins/2024-02-20-18-49-02.gh-issue-115733.51Zb85.rst
new file mode 100644 (file)
index 0000000..5cbb292
--- /dev/null
@@ -0,0 +1 @@
+Fix crash when calling ``next()`` on exhausted list iterators.
index eb466260318ec16942bdbe72885505f361402324..b07970298b8a000b3a718c9b6b72771f2053da65 100644 (file)
@@ -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);
index 9d790a9d3e6577db4df40e6eda101576c2424f24..5835b80582b3bca1fb45f2568ae3f1ab3f7d828a 100644 (file)
@@ -2612,7 +2612,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) {
@@ -2633,6 +2633,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));
         }
 
index 2ca54b6fe9cd3804b8aa3e334127c6493b898df8..974555cbba9dd6ef080774c1f42f228a42a1f700 100644 (file)
             _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;
         }
index 01e67acdc5c0e5d0099bcc8139476fb3b498543a..7f46bc8916c8d8c0edb382e22c7c147cf4ce29d5 100644 (file)
                 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) {