Skip to content

Commit 92a5784

Browse files
[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 633ea21)
1 parent 0673d4c commit 92a5784

File tree

2 files changed

+33
-8
lines changed

2 files changed

+33
-8
lines changed
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
Such C API functions as ``PyErr_SetString()``, ``PyErr_Format()``,
2+
``PyErr_SetFromErrnoWithFilename()`` and many others no longer crash or
3+
ignore errors if it failed to format the error message or decode the
4+
filename. Instead, they keep a corresponding error.

Python/errors.c

Lines changed: 29 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -225,8 +225,10 @@ _PyErr_SetString(PyThreadState *tstate, PyObject *exception,
225225
const char *string)
226226
{
227227
PyObject *value = PyUnicode_FromString(string);
228-
_PyErr_SetObject(tstate, exception, value);
229-
Py_XDECREF(value);
228+
if (value != NULL) {
229+
_PyErr_SetObject(tstate, exception, value);
230+
Py_DECREF(value);
231+
}
230232
}
231233

232234
void
@@ -852,7 +854,13 @@ PyErr_SetFromErrnoWithFilenameObjects(PyObject *exc, PyObject *filenameObject, P
852854
PyObject *
853855
PyErr_SetFromErrnoWithFilename(PyObject *exc, const char *filename)
854856
{
855-
PyObject *name = filename ? PyUnicode_DecodeFSDefault(filename) : NULL;
857+
PyObject *name = NULL;
858+
if (filename) {
859+
name = PyUnicode_DecodeFSDefault(filename);
860+
if (name == NULL) {
861+
return NULL;
862+
}
863+
}
856864
PyObject *result = PyErr_SetFromErrnoWithFilenameObjects(exc, name, NULL);
857865
Py_XDECREF(name);
858866
return result;
@@ -949,7 +957,13 @@ PyObject *PyErr_SetExcFromWindowsErrWithFilename(
949957
int ierr,
950958
const char *filename)
951959
{
952-
PyObject *name = filename ? PyUnicode_DecodeFSDefault(filename) : NULL;
960+
PyObject *name = NULL;
961+
if (filename) {
962+
name = PyUnicode_DecodeFSDefault(filename);
963+
if (name == NULL) {
964+
return NULL;
965+
}
966+
}
953967
PyObject *ret = PyErr_SetExcFromWindowsErrWithFilenameObjects(exc,
954968
ierr,
955969
name,
@@ -973,7 +987,13 @@ PyObject *PyErr_SetFromWindowsErrWithFilename(
973987
int ierr,
974988
const char *filename)
975989
{
976-
PyObject *name = filename ? PyUnicode_DecodeFSDefault(filename) : NULL;
990+
PyObject *name = NULL;
991+
if (filename) {
992+
name = PyUnicode_DecodeFSDefault(filename);
993+
if (name == NULL) {
994+
return NULL;
995+
}
996+
}
977997
PyObject *result = PyErr_SetExcFromWindowsErrWithFilenameObjects(
978998
PyExc_OSError,
979999
ierr, name, NULL);
@@ -1076,9 +1096,10 @@ _PyErr_FormatV(PyThreadState *tstate, PyObject *exception,
10761096
_PyErr_Clear(tstate);
10771097

10781098
string = PyUnicode_FromFormatV(format, vargs);
1079-
1080-
_PyErr_SetObject(tstate, exception, string);
1081-
Py_XDECREF(string);
1099+
if (string != NULL) {
1100+
_PyErr_SetObject(tstate, exception, string);
1101+
Py_DECREF(string);
1102+
}
10821103
return NULL;
10831104
}
10841105

0 commit comments

Comments
 (0)