diff options
author | Victor Stinner <victor.stinner@gmail.com> | 2013-08-01 22:47:47 (GMT) |
---|---|---|
committer | Victor Stinner <victor.stinner@gmail.com> | 2013-08-01 22:47:47 (GMT) |
commit | 044c516854fa93de4417518bd406498844a2c450 (patch) | |
tree | 7fb36a370179aa3802252c64f07802fc3d6d9113 | |
parent | 362532bc48f868b24162e32987dad307b2090060 (diff) | |
download | cpython-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").
-rw-r--r-- | Modules/_ctypes/callbacks.c | 23 |
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); |