https://github.com/python/cpython/commit/1371295e678f00a7c89dc5bb2ab61ede9adbc094
commit: 1371295e678f00a7c89dc5bb2ab61ede9adbc094
branch: main
author: Peter Bierma <[email protected]>
committer: kumaraditya303 <[email protected]>
date: 2024-11-05T15:26:36+05:30
summary:

gh-126366: Fix crash if `__iter__` raises an exception during `yield from` 
(#126369)

files:
A 
Misc/NEWS.d/next/Core_and_Builtins/2024-11-03-15-15-36.gh-issue-126366.8BBdGU.rst
M Lib/test/test_yield_from.py
M Python/bytecodes.c
M Python/executor_cases.c.h
M Python/generated_cases.c.h
M Tools/jit/ignore-tests-emulated-linux.txt

diff --git a/Lib/test/test_yield_from.py b/Lib/test/test_yield_from.py
index 1a60357a1bcd62..b90e15e20027dc 100644
--- a/Lib/test/test_yield_from.py
+++ b/Lib/test/test_yield_from.py
@@ -1576,6 +1576,19 @@ def outer():
             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
index 00000000000000..a47233602e4eff
--- /dev/null
+++ 
b/Misc/NEWS.d/next/Core_and_Builtins/2024-11-03-15-15-36.gh-issue-126366.8BBdGU.rst
@@ -0,0 +1,2 @@
+Fix crash when using ``yield from`` on an object that raises an exception in
+its ``__iter__``.
diff --git a/Python/bytecodes.c b/Python/bytecodes.c
index 81b527e8c050b9..8c52db6ab68436 100644
--- a/Python/bytecodes.c
+++ b/Python/bytecodes.c
@@ -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();
             }
         }
diff --git a/Python/executor_cases.c.h b/Python/executor_cases.c.h
index 9fac4e881b81e2..1d63402214db5d 100644
--- a/Python/executor_cases.c.h
+++ b/Python/executor_cases.c.h
@@ -3437,11 +3437,12 @@
                 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);
                 }
             }
diff --git a/Python/generated_cases.c.h b/Python/generated_cases.c.h
index c6b8fbc50f388a..d346875ea4455f 100644
--- a/Python/generated_cases.c.h
+++ b/Python/generated_cases.c.h
@@ -4304,11 +4304,12 @@
                 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);
                 }
             }
diff --git a/Tools/jit/ignore-tests-emulated-linux.txt 
b/Tools/jit/ignore-tests-emulated-linux.txt
index e379e39def0eaf..080a569574470c 100644
--- a/Tools/jit/ignore-tests-emulated-linux.txt
+++ b/Tools/jit/ignore-tests-emulated-linux.txt
@@ -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

_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3/lists/python-checkins.python.org/
Member address: [email protected]

Reply via email to