summaryrefslogtreecommitdiffstats
path: root/Modules
diff options
context:
space:
mode:
authorVictor Stinner <victor.stinner@gmail.com>2013-08-01 22:47:47 (GMT)
committerVictor Stinner <victor.stinner@gmail.com>2013-08-01 22:47:47 (GMT)
commit044c516854fa93de4417518bd406498844a2c450 (patch)
tree7fb36a370179aa3802252c64f07802fc3d6d9113 /Modules
parent362532bc48f868b24162e32987dad307b2090060 (diff)
downloadcpython-044c516854fa93de4417518bd406498844a2c450.zip
cpython-044c516854fa93de4417518bd406498844a2c450.tar.gz
cpython-044c516854fa93de4417518bd406498844a2c450.tar.bz2
Issue #18609, #18408: _ctypes_add_traceback() now clears the current exception
while adding the traceback, because it may call indirectly a Python function and Python functions must not be called with an exception set. In the case of the issue #18609, _ctypes_add_traceback() called the iso8859-1 decoder which is implemented in Python. Python has a ISO-8859-1 codec implemented in C. It is not used because PyUnicode_Decode() only uses the C codec for other names (aliases) of this codec ("latin-1", "latin1" and "iso-8859-1").
Diffstat (limited to 'Modules')
-rw-r--r--Modules/_ctypes/callbacks.c23
1 files changed, 20 insertions, 3 deletions
diff --git a/Modules/_ctypes/callbacks.c b/Modules/_ctypes/callbacks.c
index 34c46ad..8623239 100644
--- a/Modules/_ctypes/callbacks.c
+++ b/Modules/_ctypes/callbacks.c
@@ -98,20 +98,37 @@ void _ctypes_add_traceback(char *funcname, char *filename, int lineno)
PyObject *py_globals = 0;
PyCodeObject *py_code = 0;
PyFrameObject *py_frame = 0;
+ PyObject *exception, *value, *tb;
+
+ /* (Save and) Clear the current exception. Python functions must not be
+ called with an exception set. Calling Python functions happens when
+ the codec of the filesystem encoding is implemented in pure Python. */
+ PyErr_Fetch(&exception, &value, &tb);
py_globals = PyDict_New();
- if (!py_globals) goto bad;
+ if (!py_globals)
+ goto bad;
py_code = PyCode_NewEmpty(filename, funcname, lineno);
- if (!py_code) goto bad;
+ if (!py_code)
+ goto bad;
py_frame = PyFrame_New(
PyThreadState_Get(), /*PyThreadState *tstate,*/
py_code, /*PyCodeObject *code,*/
py_globals, /*PyObject *globals,*/
0 /*PyObject *locals*/
);
- if (!py_frame) goto bad;
+ if (!py_frame)
+ goto bad;
py_frame->f_lineno = lineno;
+
+ PyErr_Restore(exception, value, tb);
PyTraceBack_Here(py_frame);
+
+ Py_DECREF(py_globals);
+ Py_DECREF(py_code);
+ Py_DECREF(py_frame);
+ return;
+
bad:
Py_XDECREF(py_globals);
Py_XDECREF(py_code);