diff options
Diffstat (limited to 'Python/errors.c')
| -rw-r--r-- | Python/errors.c | 85 | 
1 files changed, 46 insertions, 39 deletions
| diff --git a/Python/errors.c b/Python/errors.c index b0ad9aa..e151cab 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;      } @@ -736,9 +727,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 +737,9 @@ PyErr_SetImportError(PyObject *msg, PyObject *name, PyObject *path)          Py_DECREF(error);      } +done:      Py_DECREF(args);      Py_DECREF(kwargs); -      return NULL;  } @@ -773,34 +764,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 +900,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 +950,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 +1124,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);  } | 
