]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-126366: Fix crash if `__iter__` raises an exception during `yield from` (#126369)
authorPeter Bierma <zintensitydev@gmail.com>
Tue, 5 Nov 2024 09:56:36 +0000 (04:56 -0500)
committerGitHub <noreply@github.com>
Tue, 5 Nov 2024 09:56:36 +0000 (15:26 +0530)
Lib/test/test_yield_from.py
Misc/NEWS.d/next/Core_and_Builtins/2024-11-03-15-15-36.gh-issue-126366.8BBdGU.rst [new file with mode: 0644]
Python/bytecodes.c
Python/executor_cases.c.h
Python/generated_cases.c.h
Tools/jit/ignore-tests-emulated-linux.txt

index 1a60357a1bcd629a20320518cb9d1adea7b4662e..b90e15e20027dcd75e9cc8b000bf08ea2b47ef41 100644 (file)
@@ -1576,6 +1576,19 @@ class TestInterestingEdgeCases(unittest.TestCase):
             self.assertIsNone(caught.exception.__context__)
             self.assert_stop_iteration(g)
 
+    def test_throws_in_iter(self):
+        # See GH-126366: NULL pointer dereference if __iter__
+        # threw an exception.
+        class Silly:
+            def __iter__(self):
+                raise RuntimeError("nobody expects the spanish inquisition")
+
+        def my_generator():
+            yield from Silly()
+
+        with self.assertRaisesRegex(RuntimeError, "nobody expects the spanish inquisition"):
+            next(iter(my_generator()))
+
 
 if __name__ == '__main__':
     unittest.main()
diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2024-11-03-15-15-36.gh-issue-126366.8BBdGU.rst b/Misc/NEWS.d/next/Core_and_Builtins/2024-11-03-15-15-36.gh-issue-126366.8BBdGU.rst
new file mode 100644 (file)
index 0000000..a472336
--- /dev/null
@@ -0,0 +1,2 @@
+Fix crash when using ``yield from`` on an object that raises an exception in
+its ``__iter__``.
index 81b527e8c050b9506a551d79a16390198b7c45ad..8c52db6ab684369579b3d9a7c0a80da726caa78d 100644 (file)
@@ -2811,11 +2811,12 @@ dummy_func(
             }
             else {
                 /* `iterable` is not a generator. */
-                iter = PyStackRef_FromPyObjectSteal(PyObject_GetIter(iterable_o));
+                PyObject *iter_o = PyObject_GetIter(iterable_o);
                 DEAD(iterable);
-                if (PyStackRef_IsNull(iter)) {
+                if (iter_o == NULL) {
                     ERROR_NO_POP();
                 }
+                iter = PyStackRef_FromPyObjectSteal(iter_o);
                 DECREF_INPUTS();
             }
         }
index 9fac4e881b81e25b13373f48641cd22d59b75760..1d63402214db5d29c17f395527c72c01fdeb3095 100644 (file)
                 else {
                     /* `iterable` is not a generator. */
                     _PyFrame_SetStackPointer(frame, stack_pointer);
-                    iter = PyStackRef_FromPyObjectSteal(PyObject_GetIter(iterable_o));
+                    PyObject *iter_o = PyObject_GetIter(iterable_o);
                     stack_pointer = _PyFrame_GetStackPointer(frame);
-                    if (PyStackRef_IsNull(iter)) {
+                    if (iter_o == NULL) {
                         JUMP_TO_ERROR();
                     }
+                    iter = PyStackRef_FromPyObjectSteal(iter_o);
                     PyStackRef_CLOSE(iterable);
                 }
             }
index c6b8fbc50f388af9fbf450bac1772d64b43a94f6..d346875ea4455f0780f592745c457db4c4452bdb 100644 (file)
                 else {
                     /* `iterable` is not a generator. */
                     _PyFrame_SetStackPointer(frame, stack_pointer);
-                    iter = PyStackRef_FromPyObjectSteal(PyObject_GetIter(iterable_o));
+                    PyObject *iter_o = PyObject_GetIter(iterable_o);
                     stack_pointer = _PyFrame_GetStackPointer(frame);
-                    if (PyStackRef_IsNull(iter)) {
+                    if (iter_o == NULL) {
                         goto error;
                     }
+                    iter = PyStackRef_FromPyObjectSteal(iter_o);
                     PyStackRef_CLOSE(iterable);
                 }
             }
index e379e39def0eaf4a9113e172a3fdcd138488046f..080a569574470cb173bb4f76e2b3425a45be4bfd 100644 (file)
@@ -71,6 +71,7 @@ test.test_socket.RecvmsgSCMRightsStreamTest.testCmsgTruncLen1
 test.test_socket.RecvmsgSCMRightsStreamTest.testCmsgTruncLen2Minus1
 test.test_subprocess.POSIXProcessTestCase.test_exception_bad_args_0
 test.test_subprocess.POSIXProcessTestCase.test_exception_bad_executable
+test.test_subprocess.POSIXProcessTestCase.test_vfork_used_when_expected
 test.test_subprocess.ProcessTestCase.test_cwd_with_relative_arg
 test.test_subprocess.ProcessTestCase.test_cwd_with_relative_executable
 test.test_subprocess.ProcessTestCase.test_empty_env