New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Py_BuildValue() can call Python code with an exception set #64223
Comments
In Python 3.4, an assertion now checks that no exception is set when arbitrary Python code is called. Python code may suppress the exception. When Py_BuildValue() is used to build a tuple and an error when the creation of an item failed, the function may execute indirectly Python code with an exception set. Attached patch works around the issue by storing the current exception in a variable and then restore it. It changes the behaviour if more than one exception is raised: at the end, its the first exception which is passed to the caller. I prefer to get the first exception instead of the following exceptions, because following exceptions may be caused by the first exception. See for example the parser bug below for an example of a second exception caused by the first exception. -- Example with the parser module: PyObject *err = Py_BuildValue("os", elem,
"Illegal node construct.");
PyErr_SetObject(parser_error, err); The "o" is not a valid format and so a SystemError is raised, but then the UTF-8 decoder tries to raise a second exception, an UnicodeDecodeError, because the decoders is called with an invalid bytes string (elem variable, instead of the "Illegal node construct." string, because "o" format didn't increment the argument pointer). The bug is obvious in the parser module, but the problem is more general than that. Gdb traceback of the parser bug: python: Objects/typeobject.c:741: type_call: Assertion `!PyErr_Occurred()' failed. Program received signal SIGABRT, Aborted. |
parsermodule.patch: fix usage of Py_BuildValue() in the parser module. |
LGTM. I have searched the sources and have not found any use of Py_BuildValue() which can be used for test. Py_BuildValue() can fail only due to memory error. It can also can fail with non-UTF8 string, but all uses of Py_BuildValue() with a string in a tuple proceeds only ASCII strings. |
parsermodule.patch was applied as 91cb83f895cf (Python 3.3) and cd952e92c180 (3.4). |
New changeset 29b4eb47f65e by Victor Stinner in branch 'default': |
Thanks for the review Serhiy. |
Committed patch fixed the issue only for tuples, but not for lists or dicts. See more general patch in bpo-26168. |
Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
GitHub fields:
bugs.python.org fields:
The text was updated successfully, but these errors were encountered: