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]