[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 633ea217a8)
This commit is contained in:
Serhiy Storchaka 2023-08-19 15:22:13 +03:00 committed by GitHub
parent 0673d4c762
commit 92a578409b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 33 additions and 8 deletions

View file

@ -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.

View file

@ -225,8 +225,10 @@ _PyErr_SetString(PyThreadState *tstate, PyObject *exception,
const char *string) const char *string)
{ {
PyObject *value = PyUnicode_FromString(string); PyObject *value = PyUnicode_FromString(string);
_PyErr_SetObject(tstate, exception, value); if (value != NULL) {
Py_XDECREF(value); _PyErr_SetObject(tstate, exception, value);
Py_DECREF(value);
}
} }
void void
@ -852,7 +854,13 @@ PyErr_SetFromErrnoWithFilenameObjects(PyObject *exc, PyObject *filenameObject, P
PyObject * PyObject *
PyErr_SetFromErrnoWithFilename(PyObject *exc, const char *filename) 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); PyObject *result = PyErr_SetFromErrnoWithFilenameObjects(exc, name, NULL);
Py_XDECREF(name); Py_XDECREF(name);
return result; return result;
@ -949,7 +957,13 @@ PyObject *PyErr_SetExcFromWindowsErrWithFilename(
int ierr, int ierr,
const char *filename) 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, PyObject *ret = PyErr_SetExcFromWindowsErrWithFilenameObjects(exc,
ierr, ierr,
name, name,
@ -973,7 +987,13 @@ PyObject *PyErr_SetFromWindowsErrWithFilename(
int ierr, int ierr,
const char *filename) 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( PyObject *result = PyErr_SetExcFromWindowsErrWithFilenameObjects(
PyExc_OSError, PyExc_OSError,
ierr, name, NULL); ierr, name, NULL);
@ -1076,9 +1096,10 @@ _PyErr_FormatV(PyThreadState *tstate, PyObject *exception,
_PyErr_Clear(tstate); _PyErr_Clear(tstate);
string = PyUnicode_FromFormatV(format, vargs); string = PyUnicode_FromFormatV(format, vargs);
if (string != NULL) {
_PyErr_SetObject(tstate, exception, string); _PyErr_SetObject(tstate, exception, string);
Py_XDECREF(string); Py_DECREF(string);
}
return NULL; return NULL;
} }