From 92a578409b70b5b9dabc9e55d4d13dd8239fe2f5 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Sat, 19 Aug 2023 15:22:13 +0300 Subject: [3.11] gh-107915: Handle errors in C API functions PyErr_Set*() and PyErr_Format() (GH-107918) (GH-108135) Such C API functions as PyErr_SetString(), PyErr_Format(), PyErr_SetFromErrnoWithFilename() and many others no longer crash or ignore errors if it failed to format the error message or decode the filename. Instead, they keep a corresponding error. (cherry picked from commit 633ea217a85f6b6ba5bdbc73094254d5811b3485) --- .../2023-08-13-12-33-00.gh-issue-107915.jQ0wOi.rst | 4 +++ Python/errors.c | 37 +++++++++++++++++----- 2 files changed, 33 insertions(+), 8 deletions(-) create mode 100644 Misc/NEWS.d/next/C API/2023-08-13-12-33-00.gh-issue-107915.jQ0wOi.rst diff --git a/Misc/NEWS.d/next/C API/2023-08-13-12-33-00.gh-issue-107915.jQ0wOi.rst b/Misc/NEWS.d/next/C API/2023-08-13-12-33-00.gh-issue-107915.jQ0wOi.rst new file mode 100644 index 0000000..58ee3f1 --- /dev/null +++ b/Misc/NEWS.d/next/C API/2023-08-13-12-33-00.gh-issue-107915.jQ0wOi.rst @@ -0,0 +1,4 @@ +Such C API functions as ``PyErr_SetString()``, ``PyErr_Format()``, +``PyErr_SetFromErrnoWithFilename()`` and many others no longer crash or +ignore errors if it failed to format the error message or decode the +filename. Instead, they keep a corresponding error. diff --git a/Python/errors.c b/Python/errors.c index 3eb8a5e..d693f3a 100644 --- a/Python/errors.c +++ b/Python/errors.c @@ -225,8 +225,10 @@ _PyErr_SetString(PyThreadState *tstate, PyObject *exception, const char *string) { PyObject *value = PyUnicode_FromString(string); - _PyErr_SetObject(tstate, exception, value); - Py_XDECREF(value); + if (value != NULL) { + _PyErr_SetObject(tstate, exception, value); + Py_DECREF(value); + } } void @@ -852,7 +854,13 @@ PyErr_SetFromErrnoWithFilenameObjects(PyObject *exc, PyObject *filenameObject, P PyObject * PyErr_SetFromErrnoWithFilename(PyObject *exc, const char *filename) { - PyObject *name = filename ? PyUnicode_DecodeFSDefault(filename) : NULL; + PyObject *name = NULL; + if (filename) { + name = PyUnicode_DecodeFSDefault(filename); + if (name == NULL) { + return NULL; + } + } PyObject *result = PyErr_SetFromErrnoWithFilenameObjects(exc, name, NULL); Py_XDECREF(name); return result; @@ -949,7 +957,13 @@ PyObject *PyErr_SetExcFromWindowsErrWithFilename( int ierr, const char *filename) { - PyObject *name = filename ? PyUnicode_DecodeFSDefault(filename) : NULL; + PyObject *name = NULL; + if (filename) { + name = PyUnicode_DecodeFSDefault(filename); + if (name == NULL) { + return NULL; + } + } PyObject *ret = PyErr_SetExcFromWindowsErrWithFilenameObjects(exc, ierr, name, @@ -973,7 +987,13 @@ PyObject *PyErr_SetFromWindowsErrWithFilename( int ierr, const char *filename) { - PyObject *name = filename ? PyUnicode_DecodeFSDefault(filename) : NULL; + PyObject *name = NULL; + if (filename) { + name = PyUnicode_DecodeFSDefault(filename); + if (name == NULL) { + return NULL; + } + } PyObject *result = PyErr_SetExcFromWindowsErrWithFilenameObjects( PyExc_OSError, ierr, name, NULL); @@ -1076,9 +1096,10 @@ _PyErr_FormatV(PyThreadState *tstate, PyObject *exception, _PyErr_Clear(tstate); string = PyUnicode_FromFormatV(format, vargs); - - _PyErr_SetObject(tstate, exception, string); - Py_XDECREF(string); + if (string != NULL) { + _PyErr_SetObject(tstate, exception, string); + Py_DECREF(string); + } return NULL; } -- cgit v0.12