diff options
Diffstat (limited to 'Python/errors.c')
-rw-r--r-- | Python/errors.c | 90 |
1 files changed, 50 insertions, 40 deletions
diff --git a/Python/errors.c b/Python/errors.c index b0ad9aa58b..6cc0c20cd5 100644 --- a/Python/errors.c +++ b/Python/errors.c @@ -74,11 +74,11 @@ PyErr_SetObject(PyObject *exception, PyObject *value) if (value == NULL || !PyExceptionInstance_Check(value)) { /* We must normalize the value right now */ PyObject *args, *fixed_value; -#ifdef Py_DEBUG - /* in debug mode, PyEval_EvalFrameEx() fails with an assertion - error if an exception is set when it is called */ + + /* Issue #23571: PyEval_CallObject() must not be called with an + exception set */ PyErr_Clear(); -#endif + if (value == NULL || value == Py_None) args = PyTuple_New(0); else if (PyTuple_Check(value)) { @@ -152,13 +152,7 @@ PyErr_SetString(PyObject *exception, const char *string) PyObject * PyErr_Occurred(void) { - /* If there is no thread state, PyThreadState_GET calls - Py_FatalError, which calls PyErr_Occurred. To avoid the - resulting infinite loop, we inline PyThreadState_GET here and - treat no thread as no error. */ - PyThreadState *tstate = - ((PyThreadState*)_Py_atomic_load_relaxed(&_PyThreadState_Current)); - + PyThreadState *tstate = _PyThreadState_UncheckedGet(); return tstate == NULL ? NULL : tstate->curexc_type; } @@ -315,14 +309,11 @@ finally: tstate = PyThreadState_GET(); if (++tstate->recursion_depth > Py_GetRecursionLimit()) { --tstate->recursion_depth; - /* throw away the old exception... */ - Py_DECREF(*exc); - Py_DECREF(*val); - /* ... and use the recursion error instead */ - *exc = PyExc_RuntimeError; - *val = PyExc_RecursionErrorInst; - Py_INCREF(*exc); - Py_INCREF(*val); + /* throw away the old exception and use the recursion error instead */ + Py_INCREF(PyExc_RecursionError); + Py_SETREF(*exc, PyExc_RecursionError); + Py_INCREF(PyExc_RecursionErrorInst); + Py_SETREF(*val, PyExc_RecursionErrorInst); /* just keeping the old traceback */ return; } @@ -397,8 +388,11 @@ _PyErr_ChainExceptions(PyObject *exc, PyObject *val, PyObject *tb) PyObject *exc2, *val2, *tb2; PyErr_Fetch(&exc2, &val2, &tb2); PyErr_NormalizeException(&exc, &val, &tb); + if (tb != NULL) { + PyException_SetTraceback(val, tb); + Py_DECREF(tb); + } Py_DECREF(exc); - Py_XDECREF(tb); PyErr_NormalizeException(&exc2, &val2, &tb2); PyException_SetContext(val2, val); PyErr_Restore(exc2, val2, tb2); @@ -736,9 +730,9 @@ PyErr_SetImportError(PyObject *msg, PyObject *name, PyObject *path) PyTuple_SET_ITEM(args, 0, msg); if (PyDict_SetItemString(kwargs, "name", name) < 0) - return NULL; + goto done; if (PyDict_SetItemString(kwargs, "path", path) < 0) - return NULL; + goto done; error = PyObject_Call(PyExc_ImportError, args, kwargs); if (error != NULL) { @@ -746,9 +740,9 @@ PyErr_SetImportError(PyObject *msg, PyObject *name, PyObject *path) Py_DECREF(error); } +done: Py_DECREF(args); Py_DECREF(kwargs); - return NULL; } @@ -773,34 +767,38 @@ PyErr_BadInternalCall(void) #define PyErr_BadInternalCall() _PyErr_BadInternalCall(__FILE__, __LINE__) +PyObject * +PyErr_FormatV(PyObject *exception, const char *format, va_list vargs) +{ + PyObject* string; + + /* Issue #23571: PyUnicode_FromFormatV() must not be called with an + exception set, it calls arbitrary Python code like PyObject_Repr() */ + PyErr_Clear(); + + string = PyUnicode_FromFormatV(format, vargs); + + PyErr_SetObject(exception, string); + Py_XDECREF(string); + return NULL; +} + PyObject * PyErr_Format(PyObject *exception, const char *format, ...) { va_list vargs; - PyObject* string; - #ifdef HAVE_STDARG_PROTOTYPES va_start(vargs, format); #else va_start(vargs); #endif - -#ifdef Py_DEBUG - /* in debug mode, PyEval_EvalFrameEx() fails with an assertion error - if an exception is set when it is called */ - PyErr_Clear(); -#endif - - string = PyUnicode_FromFormatV(format, vargs); - PyErr_SetObject(exception, string); - Py_XDECREF(string); + PyErr_FormatV(exception, format, vargs); va_end(vargs); return NULL; } - PyObject * PyErr_NewException(const char *name, PyObject *base, PyObject *dict) { @@ -905,8 +903,12 @@ PyErr_WriteUnraisable(PyObject *obj) if (obj) { if (PyFile_WriteString("Exception ignored in: ", f) < 0) goto done; - if (PyFile_WriteObject(obj, f, 0) < 0) - goto done; + if (PyFile_WriteObject(obj, f, 0) < 0) { + PyErr_Clear(); + if (PyFile_WriteString("<object repr() failed>", f) < 0) { + goto done; + } + } if (PyFile_WriteString("\n", f) < 0) goto done; } @@ -951,8 +953,12 @@ PyErr_WriteUnraisable(PyObject *obj) if (v && v != Py_None) { if (PyFile_WriteString(": ", f) < 0) goto done; - if (PyFile_WriteObject(v, f, Py_PRINT_RAW) < 0) - goto done; + if (PyFile_WriteObject(v, f, Py_PRINT_RAW) < 0) { + PyErr_Clear(); + if (PyFile_WriteString("<exception str() failed>", f) < 0) { + goto done; + } + } } if (PyFile_WriteString("\n", f) < 0) goto done; @@ -1121,6 +1127,10 @@ PyErr_ProgramTextObject(PyObject *filename, int lineno) if (filename == NULL || lineno <= 0) return NULL; fp = _Py_fopen_obj(filename, "r" PY_STDIOTEXTMODE); + if (fp == NULL) { + PyErr_Clear(); + return NULL; + } return err_programtext(fp, lineno); } |