summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakub KulĂ­k <Kulikjak@gmail.com>2022-04-07 22:54:03 +0200
committerStefan Behnel <stefan_ml@behnel.de>2022-04-07 22:54:40 +0200
commit569a06370db2f5367df6a530fce116da172d7b91 (patch)
treeea93b06e64e3df4024052014bae1b9727ffb9863
parent94f409ed1164e3c85ebd829a264ae325b05ab1e6 (diff)
downloadcython-569a06370db2f5367df6a530fce116da172d7b91.tar.gz
Prevent Python call with exception set in __Pyx_AddTraceback() (GH-4723)
Closes https://github.com/cython/cython/issues/4722
-rw-r--r--Cython/Utility/Exceptions.c12
1 files changed, 11 insertions, 1 deletions
diff --git a/Cython/Utility/Exceptions.c b/Cython/Utility/Exceptions.c
index cc6aa7841..2cd4b604e 100644
--- a/Cython/Utility/Exceptions.c
+++ b/Cython/Utility/Exceptions.c
@@ -778,6 +778,7 @@ static void __Pyx_AddTraceback(const char *funcname, int c_line,
PyCodeObject *py_code = 0;
PyFrameObject *py_frame = 0;
PyThreadState *tstate = __Pyx_PyThreadState_Current;
+ PyObject *ptype, *pvalue, *ptraceback;
if (c_line) {
c_line = __Pyx_CLineForTraceback(tstate, c_line);
@@ -786,9 +787,18 @@ static void __Pyx_AddTraceback(const char *funcname, int c_line,
// Negate to avoid collisions between py and c lines.
py_code = $global_code_object_cache_find(c_line ? -c_line : py_line);
if (!py_code) {
+ __Pyx_ErrFetchInState(tstate, &ptype, &pvalue, &ptraceback);
py_code = __Pyx_CreateCodeObjectForTraceback(
funcname, c_line, py_line, filename);
- if (!py_code) goto bad;
+ if (!py_code) {
+ /* If the code object creation fails, then we should clear the
+ fetched exception references and propagate the new exception */
+ Py_XDECREF(ptype);
+ Py_XDECREF(pvalue);
+ Py_XDECREF(ptraceback);
+ goto bad;
+ }
+ __Pyx_ErrRestoreInState(tstate, ptype, pvalue, ptraceback);
$global_code_object_cache_insert(c_line ? -c_line : py_line, py_code);
}
py_frame = PyFrame_New(