• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 
2 /* Error handling */
3 
4 #include "Python.h"
5 #include "pycore_initconfig.h"
6 #include "pycore_pyerrors.h"
7 #include "pycore_pystate.h"    // _PyThreadState_GET()
8 #include "pycore_sysmodule.h"
9 #include "pycore_traceback.h"
10 
11 #ifndef __STDC__
12 #ifndef MS_WINDOWS
13 extern char *strerror(int);
14 #endif
15 #endif
16 
17 #ifdef MS_WINDOWS
18 #include <windows.h>
19 #include <winbase.h>
20 #endif
21 
22 #include <ctype.h>
23 
24 #ifdef __cplusplus
25 extern "C" {
26 #endif
27 
28 _Py_IDENTIFIER(__module__);
29 _Py_IDENTIFIER(builtins);
30 _Py_IDENTIFIER(stderr);
31 _Py_IDENTIFIER(flush);
32 
33 /* Forward declarations */
34 static PyObject *
35 _PyErr_FormatV(PyThreadState *tstate, PyObject *exception,
36                const char *format, va_list vargs);
37 
38 
39 void
_PyErr_Restore(PyThreadState * tstate,PyObject * type,PyObject * value,PyObject * traceback)40 _PyErr_Restore(PyThreadState *tstate, PyObject *type, PyObject *value,
41                PyObject *traceback)
42 {
43     PyObject *oldtype, *oldvalue, *oldtraceback;
44 
45     if (traceback != NULL && !PyTraceBack_Check(traceback)) {
46         /* XXX Should never happen -- fatal error instead? */
47         /* Well, it could be None. */
48         Py_DECREF(traceback);
49         traceback = NULL;
50     }
51 
52     /* Save these in locals to safeguard against recursive
53        invocation through Py_XDECREF */
54     oldtype = tstate->curexc_type;
55     oldvalue = tstate->curexc_value;
56     oldtraceback = tstate->curexc_traceback;
57 
58     tstate->curexc_type = type;
59     tstate->curexc_value = value;
60     tstate->curexc_traceback = traceback;
61 
62     Py_XDECREF(oldtype);
63     Py_XDECREF(oldvalue);
64     Py_XDECREF(oldtraceback);
65 }
66 
67 void
PyErr_Restore(PyObject * type,PyObject * value,PyObject * traceback)68 PyErr_Restore(PyObject *type, PyObject *value, PyObject *traceback)
69 {
70     PyThreadState *tstate = _PyThreadState_GET();
71     _PyErr_Restore(tstate, type, value, traceback);
72 }
73 
74 
75 _PyErr_StackItem *
_PyErr_GetTopmostException(PyThreadState * tstate)76 _PyErr_GetTopmostException(PyThreadState *tstate)
77 {
78     _PyErr_StackItem *exc_info = tstate->exc_info;
79     while ((exc_info->exc_type == NULL || exc_info->exc_type == Py_None) &&
80            exc_info->previous_item != NULL)
81     {
82         exc_info = exc_info->previous_item;
83     }
84     return exc_info;
85 }
86 
87 static PyObject*
_PyErr_CreateException(PyObject * exception,PyObject * value)88 _PyErr_CreateException(PyObject *exception, PyObject *value)
89 {
90     if (value == NULL || value == Py_None) {
91         return _PyObject_CallNoArg(exception);
92     }
93     else if (PyTuple_Check(value)) {
94         return PyObject_Call(exception, value, NULL);
95     }
96     else {
97         return PyObject_CallOneArg(exception, value);
98     }
99 }
100 
101 void
_PyErr_SetObject(PyThreadState * tstate,PyObject * exception,PyObject * value)102 _PyErr_SetObject(PyThreadState *tstate, PyObject *exception, PyObject *value)
103 {
104     PyObject *exc_value;
105     PyObject *tb = NULL;
106 
107     if (exception != NULL &&
108         !PyExceptionClass_Check(exception)) {
109         _PyErr_Format(tstate, PyExc_SystemError,
110                       "_PyErr_SetObject: "
111                       "exception %R is not a BaseException subclass",
112                       exception);
113         return;
114     }
115 
116     Py_XINCREF(value);
117     exc_value = _PyErr_GetTopmostException(tstate)->exc_value;
118     if (exc_value != NULL && exc_value != Py_None) {
119         /* Implicit exception chaining */
120         Py_INCREF(exc_value);
121         if (value == NULL || !PyExceptionInstance_Check(value)) {
122             /* We must normalize the value right now */
123             PyObject *fixed_value;
124 
125             /* Issue #23571: functions must not be called with an
126                exception set */
127             _PyErr_Clear(tstate);
128 
129             fixed_value = _PyErr_CreateException(exception, value);
130             Py_XDECREF(value);
131             if (fixed_value == NULL) {
132                 Py_DECREF(exc_value);
133                 return;
134             }
135 
136             value = fixed_value;
137         }
138 
139         /* Avoid reference cycles through the context chain.
140            This is O(chain length) but context chains are
141            usually very short. Sensitive readers may try
142            to inline the call to PyException_GetContext. */
143         if (exc_value != value) {
144             PyObject *o = exc_value, *context;
145             while ((context = PyException_GetContext(o))) {
146                 Py_DECREF(context);
147                 if (context == value) {
148                     PyException_SetContext(o, NULL);
149                     break;
150                 }
151                 o = context;
152             }
153             PyException_SetContext(value, exc_value);
154         }
155         else {
156             Py_DECREF(exc_value);
157         }
158     }
159     if (value != NULL && PyExceptionInstance_Check(value))
160         tb = PyException_GetTraceback(value);
161     Py_XINCREF(exception);
162     _PyErr_Restore(tstate, exception, value, tb);
163 }
164 
165 void
PyErr_SetObject(PyObject * exception,PyObject * value)166 PyErr_SetObject(PyObject *exception, PyObject *value)
167 {
168     PyThreadState *tstate = _PyThreadState_GET();
169     _PyErr_SetObject(tstate, exception, value);
170 }
171 
172 /* Set a key error with the specified argument, wrapping it in a
173  * tuple automatically so that tuple keys are not unpacked as the
174  * exception arguments. */
175 void
_PyErr_SetKeyError(PyObject * arg)176 _PyErr_SetKeyError(PyObject *arg)
177 {
178     PyThreadState *tstate = _PyThreadState_GET();
179     PyObject *tup = PyTuple_Pack(1, arg);
180     if (!tup) {
181         /* caller will expect error to be set anyway */
182         return;
183     }
184     _PyErr_SetObject(tstate, PyExc_KeyError, tup);
185     Py_DECREF(tup);
186 }
187 
188 void
_PyErr_SetNone(PyThreadState * tstate,PyObject * exception)189 _PyErr_SetNone(PyThreadState *tstate, PyObject *exception)
190 {
191     _PyErr_SetObject(tstate, exception, (PyObject *)NULL);
192 }
193 
194 
195 void
PyErr_SetNone(PyObject * exception)196 PyErr_SetNone(PyObject *exception)
197 {
198     PyThreadState *tstate = _PyThreadState_GET();
199     _PyErr_SetNone(tstate, exception);
200 }
201 
202 
203 void
_PyErr_SetString(PyThreadState * tstate,PyObject * exception,const char * string)204 _PyErr_SetString(PyThreadState *tstate, PyObject *exception,
205                  const char *string)
206 {
207     PyObject *value = PyUnicode_FromString(string);
208     _PyErr_SetObject(tstate, exception, value);
209     Py_XDECREF(value);
210 }
211 
212 void
PyErr_SetString(PyObject * exception,const char * string)213 PyErr_SetString(PyObject *exception, const char *string)
214 {
215     PyThreadState *tstate = _PyThreadState_GET();
216     _PyErr_SetString(tstate, exception, string);
217 }
218 
219 
220 PyObject* _Py_HOT_FUNCTION
PyErr_Occurred(void)221 PyErr_Occurred(void)
222 {
223     /* The caller must hold the GIL. */
224     assert(PyGILState_Check());
225 
226     PyThreadState *tstate = _PyThreadState_GET();
227     return _PyErr_Occurred(tstate);
228 }
229 
230 
231 int
PyErr_GivenExceptionMatches(PyObject * err,PyObject * exc)232 PyErr_GivenExceptionMatches(PyObject *err, PyObject *exc)
233 {
234     if (err == NULL || exc == NULL) {
235         /* maybe caused by "import exceptions" that failed early on */
236         return 0;
237     }
238     if (PyTuple_Check(exc)) {
239         Py_ssize_t i, n;
240         n = PyTuple_Size(exc);
241         for (i = 0; i < n; i++) {
242             /* Test recursively */
243              if (PyErr_GivenExceptionMatches(
244                  err, PyTuple_GET_ITEM(exc, i)))
245              {
246                  return 1;
247              }
248         }
249         return 0;
250     }
251     /* err might be an instance, so check its class. */
252     if (PyExceptionInstance_Check(err))
253         err = PyExceptionInstance_Class(err);
254 
255     if (PyExceptionClass_Check(err) && PyExceptionClass_Check(exc)) {
256         return PyType_IsSubtype((PyTypeObject *)err, (PyTypeObject *)exc);
257     }
258 
259     return err == exc;
260 }
261 
262 
263 int
_PyErr_ExceptionMatches(PyThreadState * tstate,PyObject * exc)264 _PyErr_ExceptionMatches(PyThreadState *tstate, PyObject *exc)
265 {
266     return PyErr_GivenExceptionMatches(_PyErr_Occurred(tstate), exc);
267 }
268 
269 
270 int
PyErr_ExceptionMatches(PyObject * exc)271 PyErr_ExceptionMatches(PyObject *exc)
272 {
273     PyThreadState *tstate = _PyThreadState_GET();
274     return _PyErr_ExceptionMatches(tstate, exc);
275 }
276 
277 
278 #ifndef Py_NORMALIZE_RECURSION_LIMIT
279 #define Py_NORMALIZE_RECURSION_LIMIT 32
280 #endif
281 
282 /* Used in many places to normalize a raised exception, including in
283    eval_code2(), do_raise(), and PyErr_Print()
284 
285    XXX: should PyErr_NormalizeException() also call
286             PyException_SetTraceback() with the resulting value and tb?
287 */
288 void
_PyErr_NormalizeException(PyThreadState * tstate,PyObject ** exc,PyObject ** val,PyObject ** tb)289 _PyErr_NormalizeException(PyThreadState *tstate, PyObject **exc,
290                           PyObject **val, PyObject **tb)
291 {
292     int recursion_depth = 0;
293     PyObject *type, *value, *initial_tb;
294 
295   restart:
296     type = *exc;
297     if (type == NULL) {
298         /* There was no exception, so nothing to do. */
299         return;
300     }
301 
302     value = *val;
303     /* If PyErr_SetNone() was used, the value will have been actually
304        set to NULL.
305     */
306     if (!value) {
307         value = Py_None;
308         Py_INCREF(value);
309     }
310 
311     /* Normalize the exception so that if the type is a class, the
312        value will be an instance.
313     */
314     if (PyExceptionClass_Check(type)) {
315         PyObject *inclass = NULL;
316         int is_subclass = 0;
317 
318         if (PyExceptionInstance_Check(value)) {
319             inclass = PyExceptionInstance_Class(value);
320             is_subclass = PyObject_IsSubclass(inclass, type);
321             if (is_subclass < 0) {
322                 goto error;
323             }
324         }
325 
326         /* If the value was not an instance, or is not an instance
327            whose class is (or is derived from) type, then use the
328            value as an argument to instantiation of the type
329            class.
330         */
331         if (!is_subclass) {
332             PyObject *fixed_value = _PyErr_CreateException(type, value);
333             if (fixed_value == NULL) {
334                 goto error;
335             }
336             Py_DECREF(value);
337             value = fixed_value;
338         }
339         /* If the class of the instance doesn't exactly match the
340            class of the type, believe the instance.
341         */
342         else if (inclass != type) {
343             Py_INCREF(inclass);
344             Py_DECREF(type);
345             type = inclass;
346         }
347     }
348     *exc = type;
349     *val = value;
350     return;
351 
352   error:
353     Py_DECREF(type);
354     Py_DECREF(value);
355     recursion_depth++;
356     if (recursion_depth == Py_NORMALIZE_RECURSION_LIMIT) {
357         _PyErr_SetString(tstate, PyExc_RecursionError,
358                          "maximum recursion depth exceeded "
359                          "while normalizing an exception");
360     }
361     /* If the new exception doesn't set a traceback and the old
362        exception had a traceback, use the old traceback for the
363        new exception.  It's better than nothing.
364     */
365     initial_tb = *tb;
366     _PyErr_Fetch(tstate, exc, val, tb);
367     assert(*exc != NULL);
368     if (initial_tb != NULL) {
369         if (*tb == NULL)
370             *tb = initial_tb;
371         else
372             Py_DECREF(initial_tb);
373     }
374     /* Abort when Py_NORMALIZE_RECURSION_LIMIT has been exceeded, and the
375        corresponding RecursionError could not be normalized, and the
376        MemoryError raised when normalize this RecursionError could not be
377        normalized. */
378     if (recursion_depth >= Py_NORMALIZE_RECURSION_LIMIT + 2) {
379         if (PyErr_GivenExceptionMatches(*exc, PyExc_MemoryError)) {
380             Py_FatalError("Cannot recover from MemoryErrors "
381                           "while normalizing exceptions.");
382         }
383         else {
384             Py_FatalError("Cannot recover from the recursive normalization "
385                           "of an exception.");
386         }
387     }
388     goto restart;
389 }
390 
391 
392 void
PyErr_NormalizeException(PyObject ** exc,PyObject ** val,PyObject ** tb)393 PyErr_NormalizeException(PyObject **exc, PyObject **val, PyObject **tb)
394 {
395     PyThreadState *tstate = _PyThreadState_GET();
396     _PyErr_NormalizeException(tstate, exc, val, tb);
397 }
398 
399 
400 void
_PyErr_Fetch(PyThreadState * tstate,PyObject ** p_type,PyObject ** p_value,PyObject ** p_traceback)401 _PyErr_Fetch(PyThreadState *tstate, PyObject **p_type, PyObject **p_value,
402              PyObject **p_traceback)
403 {
404     *p_type = tstate->curexc_type;
405     *p_value = tstate->curexc_value;
406     *p_traceback = tstate->curexc_traceback;
407 
408     tstate->curexc_type = NULL;
409     tstate->curexc_value = NULL;
410     tstate->curexc_traceback = NULL;
411 }
412 
413 
414 void
PyErr_Fetch(PyObject ** p_type,PyObject ** p_value,PyObject ** p_traceback)415 PyErr_Fetch(PyObject **p_type, PyObject **p_value, PyObject **p_traceback)
416 {
417     PyThreadState *tstate = _PyThreadState_GET();
418     _PyErr_Fetch(tstate, p_type, p_value, p_traceback);
419 }
420 
421 
422 void
_PyErr_Clear(PyThreadState * tstate)423 _PyErr_Clear(PyThreadState *tstate)
424 {
425     _PyErr_Restore(tstate, NULL, NULL, NULL);
426 }
427 
428 
429 void
PyErr_Clear(void)430 PyErr_Clear(void)
431 {
432     PyThreadState *tstate = _PyThreadState_GET();
433     _PyErr_Clear(tstate);
434 }
435 
436 
437 void
_PyErr_GetExcInfo(PyThreadState * tstate,PyObject ** p_type,PyObject ** p_value,PyObject ** p_traceback)438 _PyErr_GetExcInfo(PyThreadState *tstate,
439                   PyObject **p_type, PyObject **p_value, PyObject **p_traceback)
440 {
441     _PyErr_StackItem *exc_info = _PyErr_GetTopmostException(tstate);
442     *p_type = exc_info->exc_type;
443     *p_value = exc_info->exc_value;
444     *p_traceback = exc_info->exc_traceback;
445 
446     Py_XINCREF(*p_type);
447     Py_XINCREF(*p_value);
448     Py_XINCREF(*p_traceback);
449 }
450 
451 
452 void
PyErr_GetExcInfo(PyObject ** p_type,PyObject ** p_value,PyObject ** p_traceback)453 PyErr_GetExcInfo(PyObject **p_type, PyObject **p_value, PyObject **p_traceback)
454 {
455     PyThreadState *tstate = _PyThreadState_GET();
456     _PyErr_GetExcInfo(tstate, p_type, p_value, p_traceback);
457 }
458 
459 void
PyErr_SetExcInfo(PyObject * p_type,PyObject * p_value,PyObject * p_traceback)460 PyErr_SetExcInfo(PyObject *p_type, PyObject *p_value, PyObject *p_traceback)
461 {
462     PyObject *oldtype, *oldvalue, *oldtraceback;
463     PyThreadState *tstate = _PyThreadState_GET();
464 
465     oldtype = tstate->exc_info->exc_type;
466     oldvalue = tstate->exc_info->exc_value;
467     oldtraceback = tstate->exc_info->exc_traceback;
468 
469     tstate->exc_info->exc_type = p_type;
470     tstate->exc_info->exc_value = p_value;
471     tstate->exc_info->exc_traceback = p_traceback;
472 
473     Py_XDECREF(oldtype);
474     Py_XDECREF(oldvalue);
475     Py_XDECREF(oldtraceback);
476 }
477 
478 /* Like PyErr_Restore(), but if an exception is already set,
479    set the context associated with it.
480 
481    The caller is responsible for ensuring that this call won't create
482    any cycles in the exception context chain. */
483 void
_PyErr_ChainExceptions(PyObject * exc,PyObject * val,PyObject * tb)484 _PyErr_ChainExceptions(PyObject *exc, PyObject *val, PyObject *tb)
485 {
486     if (exc == NULL)
487         return;
488 
489     PyThreadState *tstate = _PyThreadState_GET();
490 
491     if (!PyExceptionClass_Check(exc)) {
492         _PyErr_Format(tstate, PyExc_SystemError,
493                       "_PyErr_ChainExceptions: "
494                       "exception %R is not a BaseException subclass",
495                       exc);
496         return;
497     }
498 
499     if (_PyErr_Occurred(tstate)) {
500         PyObject *exc2, *val2, *tb2;
501         _PyErr_Fetch(tstate, &exc2, &val2, &tb2);
502         _PyErr_NormalizeException(tstate, &exc, &val, &tb);
503         if (tb != NULL) {
504             PyException_SetTraceback(val, tb);
505             Py_DECREF(tb);
506         }
507         Py_DECREF(exc);
508         _PyErr_NormalizeException(tstate, &exc2, &val2, &tb2);
509         PyException_SetContext(val2, val);
510         _PyErr_Restore(tstate, exc2, val2, tb2);
511     }
512     else {
513         _PyErr_Restore(tstate, exc, val, tb);
514     }
515 }
516 
517 /* Set the currently set exception's context to the given exception.
518 
519    If the provided exc_info is NULL, then the current Python thread state's
520    exc_info will be used for the context instead.
521 
522    This function can only be called when _PyErr_Occurred() is true.
523    Also, this function won't create any cycles in the exception context
524    chain to the extent that _PyErr_SetObject ensures this. */
525 void
_PyErr_ChainStackItem(_PyErr_StackItem * exc_info)526 _PyErr_ChainStackItem(_PyErr_StackItem *exc_info)
527 {
528     PyThreadState *tstate = _PyThreadState_GET();
529     assert(_PyErr_Occurred(tstate));
530 
531     int exc_info_given;
532     if (exc_info == NULL) {
533         exc_info_given = 0;
534         exc_info = tstate->exc_info;
535     } else {
536         exc_info_given = 1;
537     }
538     if (exc_info->exc_type == NULL || exc_info->exc_type == Py_None) {
539         return;
540     }
541 
542     _PyErr_StackItem *saved_exc_info;
543     if (exc_info_given) {
544         /* Temporarily set the thread state's exc_info since this is what
545            _PyErr_SetObject uses for implicit exception chaining. */
546         saved_exc_info = tstate->exc_info;
547         tstate->exc_info = exc_info;
548     }
549 
550     PyObject *exc, *val, *tb;
551     _PyErr_Fetch(tstate, &exc, &val, &tb);
552 
553     PyObject *exc2, *val2, *tb2;
554     exc2 = exc_info->exc_type;
555     val2 = exc_info->exc_value;
556     tb2 = exc_info->exc_traceback;
557     _PyErr_NormalizeException(tstate, &exc2, &val2, &tb2);
558     if (tb2 != NULL) {
559         PyException_SetTraceback(val2, tb2);
560     }
561 
562     /* _PyErr_SetObject sets the context from PyThreadState. */
563     _PyErr_SetObject(tstate, exc, val);
564     Py_DECREF(exc);  // since _PyErr_Occurred was true
565     Py_XDECREF(val);
566     Py_XDECREF(tb);
567 
568     if (exc_info_given) {
569         tstate->exc_info = saved_exc_info;
570     }
571 }
572 
573 static PyObject *
_PyErr_FormatVFromCause(PyThreadState * tstate,PyObject * exception,const char * format,va_list vargs)574 _PyErr_FormatVFromCause(PyThreadState *tstate, PyObject *exception,
575                         const char *format, va_list vargs)
576 {
577     PyObject *exc, *val, *val2, *tb;
578 
579     assert(_PyErr_Occurred(tstate));
580     _PyErr_Fetch(tstate, &exc, &val, &tb);
581     _PyErr_NormalizeException(tstate, &exc, &val, &tb);
582     if (tb != NULL) {
583         PyException_SetTraceback(val, tb);
584         Py_DECREF(tb);
585     }
586     Py_DECREF(exc);
587     assert(!_PyErr_Occurred(tstate));
588 
589     _PyErr_FormatV(tstate, exception, format, vargs);
590 
591     _PyErr_Fetch(tstate, &exc, &val2, &tb);
592     _PyErr_NormalizeException(tstate, &exc, &val2, &tb);
593     Py_INCREF(val);
594     PyException_SetCause(val2, val);
595     PyException_SetContext(val2, val);
596     _PyErr_Restore(tstate, exc, val2, tb);
597 
598     return NULL;
599 }
600 
601 PyObject *
_PyErr_FormatFromCauseTstate(PyThreadState * tstate,PyObject * exception,const char * format,...)602 _PyErr_FormatFromCauseTstate(PyThreadState *tstate, PyObject *exception,
603                              const char *format, ...)
604 {
605     va_list vargs;
606 #ifdef HAVE_STDARG_PROTOTYPES
607     va_start(vargs, format);
608 #else
609     va_start(vargs);
610 #endif
611     _PyErr_FormatVFromCause(tstate, exception, format, vargs);
612     va_end(vargs);
613     return NULL;
614 }
615 
616 PyObject *
_PyErr_FormatFromCause(PyObject * exception,const char * format,...)617 _PyErr_FormatFromCause(PyObject *exception, const char *format, ...)
618 {
619     PyThreadState *tstate = _PyThreadState_GET();
620     va_list vargs;
621 #ifdef HAVE_STDARG_PROTOTYPES
622     va_start(vargs, format);
623 #else
624     va_start(vargs);
625 #endif
626     _PyErr_FormatVFromCause(tstate, exception, format, vargs);
627     va_end(vargs);
628     return NULL;
629 }
630 
631 /* Convenience functions to set a type error exception and return 0 */
632 
633 int
PyErr_BadArgument(void)634 PyErr_BadArgument(void)
635 {
636     PyThreadState *tstate = _PyThreadState_GET();
637     _PyErr_SetString(tstate, PyExc_TypeError,
638                      "bad argument type for built-in operation");
639     return 0;
640 }
641 
642 PyObject *
_PyErr_NoMemory(PyThreadState * tstate)643 _PyErr_NoMemory(PyThreadState *tstate)
644 {
645     if (Py_IS_TYPE(PyExc_MemoryError, NULL)) {
646         /* PyErr_NoMemory() has been called before PyExc_MemoryError has been
647            initialized by _PyExc_Init() */
648         Py_FatalError("Out of memory and PyExc_MemoryError is not "
649                       "initialized yet");
650     }
651     _PyErr_SetNone(tstate, PyExc_MemoryError);
652     return NULL;
653 }
654 
655 PyObject *
PyErr_NoMemory(void)656 PyErr_NoMemory(void)
657 {
658     PyThreadState *tstate = _PyThreadState_GET();
659     return _PyErr_NoMemory(tstate);
660 }
661 
662 PyObject *
PyErr_SetFromErrnoWithFilenameObject(PyObject * exc,PyObject * filenameObject)663 PyErr_SetFromErrnoWithFilenameObject(PyObject *exc, PyObject *filenameObject)
664 {
665     return PyErr_SetFromErrnoWithFilenameObjects(exc, filenameObject, NULL);
666 }
667 
668 PyObject *
PyErr_SetFromErrnoWithFilenameObjects(PyObject * exc,PyObject * filenameObject,PyObject * filenameObject2)669 PyErr_SetFromErrnoWithFilenameObjects(PyObject *exc, PyObject *filenameObject, PyObject *filenameObject2)
670 {
671     PyThreadState *tstate = _PyThreadState_GET();
672     PyObject *message;
673     PyObject *v, *args;
674     int i = errno;
675 #ifdef MS_WINDOWS
676     WCHAR *s_buf = NULL;
677 #endif /* Unix/Windows */
678 
679 #ifdef EINTR
680     if (i == EINTR && PyErr_CheckSignals())
681         return NULL;
682 #endif
683 
684 #ifndef MS_WINDOWS
685     if (i != 0) {
686         const char *s = strerror(i);
687         message = PyUnicode_DecodeLocale(s, "surrogateescape");
688     }
689     else {
690         /* Sometimes errno didn't get set */
691         message = PyUnicode_FromString("Error");
692     }
693 #else
694     if (i == 0)
695         message = PyUnicode_FromString("Error"); /* Sometimes errno didn't get set */
696     else
697     {
698         /* Note that the Win32 errors do not lineup with the
699            errno error.  So if the error is in the MSVC error
700            table, we use it, otherwise we assume it really _is_
701            a Win32 error code
702         */
703         if (i > 0 && i < _sys_nerr) {
704             message = PyUnicode_FromString(_sys_errlist[i]);
705         }
706         else {
707             int len = FormatMessageW(
708                 FORMAT_MESSAGE_ALLOCATE_BUFFER |
709                 FORMAT_MESSAGE_FROM_SYSTEM |
710                 FORMAT_MESSAGE_IGNORE_INSERTS,
711                 NULL,                   /* no message source */
712                 i,
713                 MAKELANGID(LANG_NEUTRAL,
714                            SUBLANG_DEFAULT),
715                            /* Default language */
716                 (LPWSTR) &s_buf,
717                 0,                      /* size not used */
718                 NULL);                  /* no args */
719             if (len==0) {
720                 /* Only ever seen this in out-of-mem
721                    situations */
722                 s_buf = NULL;
723                 message = PyUnicode_FromFormat("Windows Error 0x%x", i);
724             } else {
725                 /* remove trailing cr/lf and dots */
726                 while (len > 0 && (s_buf[len-1] <= L' ' || s_buf[len-1] == L'.'))
727                     s_buf[--len] = L'\0';
728                 message = PyUnicode_FromWideChar(s_buf, len);
729             }
730         }
731     }
732 #endif /* Unix/Windows */
733 
734     if (message == NULL)
735     {
736 #ifdef MS_WINDOWS
737         LocalFree(s_buf);
738 #endif
739         return NULL;
740     }
741 
742     if (filenameObject != NULL) {
743         if (filenameObject2 != NULL)
744             args = Py_BuildValue("(iOOiO)", i, message, filenameObject, 0, filenameObject2);
745         else
746             args = Py_BuildValue("(iOO)", i, message, filenameObject);
747     } else {
748         assert(filenameObject2 == NULL);
749         args = Py_BuildValue("(iO)", i, message);
750     }
751     Py_DECREF(message);
752 
753     if (args != NULL) {
754         v = PyObject_Call(exc, args, NULL);
755         Py_DECREF(args);
756         if (v != NULL) {
757             _PyErr_SetObject(tstate, (PyObject *) Py_TYPE(v), v);
758             Py_DECREF(v);
759         }
760     }
761 #ifdef MS_WINDOWS
762     LocalFree(s_buf);
763 #endif
764     return NULL;
765 }
766 
767 PyObject *
PyErr_SetFromErrnoWithFilename(PyObject * exc,const char * filename)768 PyErr_SetFromErrnoWithFilename(PyObject *exc, const char *filename)
769 {
770     PyObject *name = filename ? PyUnicode_DecodeFSDefault(filename) : NULL;
771     PyObject *result = PyErr_SetFromErrnoWithFilenameObjects(exc, name, NULL);
772     Py_XDECREF(name);
773     return result;
774 }
775 
776 #ifdef MS_WINDOWS
777 PyObject *
PyErr_SetFromErrnoWithUnicodeFilename(PyObject * exc,const Py_UNICODE * filename)778 PyErr_SetFromErrnoWithUnicodeFilename(PyObject *exc, const Py_UNICODE *filename)
779 {
780     PyObject *name = filename ? PyUnicode_FromWideChar(filename, -1) : NULL;
781     PyObject *result = PyErr_SetFromErrnoWithFilenameObjects(exc, name, NULL);
782     Py_XDECREF(name);
783     return result;
784 }
785 #endif /* MS_WINDOWS */
786 
787 PyObject *
PyErr_SetFromErrno(PyObject * exc)788 PyErr_SetFromErrno(PyObject *exc)
789 {
790     return PyErr_SetFromErrnoWithFilenameObjects(exc, NULL, NULL);
791 }
792 
793 #ifdef MS_WINDOWS
794 /* Windows specific error code handling */
PyErr_SetExcFromWindowsErrWithFilenameObject(PyObject * exc,int ierr,PyObject * filenameObject)795 PyObject *PyErr_SetExcFromWindowsErrWithFilenameObject(
796     PyObject *exc,
797     int ierr,
798     PyObject *filenameObject)
799 {
800     return PyErr_SetExcFromWindowsErrWithFilenameObjects(exc, ierr,
801         filenameObject, NULL);
802 }
803 
PyErr_SetExcFromWindowsErrWithFilenameObjects(PyObject * exc,int ierr,PyObject * filenameObject,PyObject * filenameObject2)804 PyObject *PyErr_SetExcFromWindowsErrWithFilenameObjects(
805     PyObject *exc,
806     int ierr,
807     PyObject *filenameObject,
808     PyObject *filenameObject2)
809 {
810     PyThreadState *tstate = _PyThreadState_GET();
811     int len;
812     WCHAR *s_buf = NULL; /* Free via LocalFree */
813     PyObject *message;
814     PyObject *args, *v;
815 
816     DWORD err = (DWORD)ierr;
817     if (err==0) {
818         err = GetLastError();
819     }
820 
821     len = FormatMessageW(
822         /* Error API error */
823         FORMAT_MESSAGE_ALLOCATE_BUFFER |
824         FORMAT_MESSAGE_FROM_SYSTEM |
825         FORMAT_MESSAGE_IGNORE_INSERTS,
826         NULL,           /* no message source */
827         err,
828         MAKELANGID(LANG_NEUTRAL,
829         SUBLANG_DEFAULT), /* Default language */
830         (LPWSTR) &s_buf,
831         0,              /* size not used */
832         NULL);          /* no args */
833     if (len==0) {
834         /* Only seen this in out of mem situations */
835         message = PyUnicode_FromFormat("Windows Error 0x%x", err);
836         s_buf = NULL;
837     } else {
838         /* remove trailing cr/lf and dots */
839         while (len > 0 && (s_buf[len-1] <= L' ' || s_buf[len-1] == L'.'))
840             s_buf[--len] = L'\0';
841         message = PyUnicode_FromWideChar(s_buf, len);
842     }
843 
844     if (message == NULL)
845     {
846         LocalFree(s_buf);
847         return NULL;
848     }
849 
850     if (filenameObject == NULL) {
851         assert(filenameObject2 == NULL);
852         filenameObject = filenameObject2 = Py_None;
853     }
854     else if (filenameObject2 == NULL)
855         filenameObject2 = Py_None;
856     /* This is the constructor signature for OSError.
857        The POSIX translation will be figured out by the constructor. */
858     args = Py_BuildValue("(iOOiO)", 0, message, filenameObject, err, filenameObject2);
859     Py_DECREF(message);
860 
861     if (args != NULL) {
862         v = PyObject_Call(exc, args, NULL);
863         Py_DECREF(args);
864         if (v != NULL) {
865             _PyErr_SetObject(tstate, (PyObject *) Py_TYPE(v), v);
866             Py_DECREF(v);
867         }
868     }
869     LocalFree(s_buf);
870     return NULL;
871 }
872 
PyErr_SetExcFromWindowsErrWithFilename(PyObject * exc,int ierr,const char * filename)873 PyObject *PyErr_SetExcFromWindowsErrWithFilename(
874     PyObject *exc,
875     int ierr,
876     const char *filename)
877 {
878     PyObject *name = filename ? PyUnicode_DecodeFSDefault(filename) : NULL;
879     PyObject *ret = PyErr_SetExcFromWindowsErrWithFilenameObjects(exc,
880                                                                  ierr,
881                                                                  name,
882                                                                  NULL);
883     Py_XDECREF(name);
884     return ret;
885 }
886 
PyErr_SetExcFromWindowsErrWithUnicodeFilename(PyObject * exc,int ierr,const Py_UNICODE * filename)887 PyObject *PyErr_SetExcFromWindowsErrWithUnicodeFilename(
888     PyObject *exc,
889     int ierr,
890     const Py_UNICODE *filename)
891 {
892     PyObject *name = filename ? PyUnicode_FromWideChar(filename, -1) : NULL;
893     PyObject *ret = PyErr_SetExcFromWindowsErrWithFilenameObjects(exc,
894                                                                  ierr,
895                                                                  name,
896                                                                  NULL);
897     Py_XDECREF(name);
898     return ret;
899 }
900 
PyErr_SetExcFromWindowsErr(PyObject * exc,int ierr)901 PyObject *PyErr_SetExcFromWindowsErr(PyObject *exc, int ierr)
902 {
903     return PyErr_SetExcFromWindowsErrWithFilename(exc, ierr, NULL);
904 }
905 
PyErr_SetFromWindowsErr(int ierr)906 PyObject *PyErr_SetFromWindowsErr(int ierr)
907 {
908     return PyErr_SetExcFromWindowsErrWithFilename(PyExc_OSError,
909                                                   ierr, NULL);
910 }
911 
PyErr_SetFromWindowsErrWithFilename(int ierr,const char * filename)912 PyObject *PyErr_SetFromWindowsErrWithFilename(
913     int ierr,
914     const char *filename)
915 {
916     PyObject *name = filename ? PyUnicode_DecodeFSDefault(filename) : NULL;
917     PyObject *result = PyErr_SetExcFromWindowsErrWithFilenameObjects(
918                                                   PyExc_OSError,
919                                                   ierr, name, NULL);
920     Py_XDECREF(name);
921     return result;
922 }
923 
PyErr_SetFromWindowsErrWithUnicodeFilename(int ierr,const Py_UNICODE * filename)924 PyObject *PyErr_SetFromWindowsErrWithUnicodeFilename(
925     int ierr,
926     const Py_UNICODE *filename)
927 {
928     PyObject *name = filename ? PyUnicode_FromWideChar(filename, -1) : NULL;
929     PyObject *result = PyErr_SetExcFromWindowsErrWithFilenameObjects(
930                                                   PyExc_OSError,
931                                                   ierr, name, NULL);
932     Py_XDECREF(name);
933     return result;
934 }
935 #endif /* MS_WINDOWS */
936 
937 PyObject *
PyErr_SetImportErrorSubclass(PyObject * exception,PyObject * msg,PyObject * name,PyObject * path)938 PyErr_SetImportErrorSubclass(PyObject *exception, PyObject *msg,
939     PyObject *name, PyObject *path)
940 {
941     PyThreadState *tstate = _PyThreadState_GET();
942     int issubclass;
943     PyObject *kwargs, *error;
944 
945     issubclass = PyObject_IsSubclass(exception, PyExc_ImportError);
946     if (issubclass < 0) {
947         return NULL;
948     }
949     else if (!issubclass) {
950         _PyErr_SetString(tstate, PyExc_TypeError,
951                          "expected a subclass of ImportError");
952         return NULL;
953     }
954 
955     if (msg == NULL) {
956         _PyErr_SetString(tstate, PyExc_TypeError,
957                          "expected a message argument");
958         return NULL;
959     }
960 
961     if (name == NULL) {
962         name = Py_None;
963     }
964     if (path == NULL) {
965         path = Py_None;
966     }
967 
968     kwargs = PyDict_New();
969     if (kwargs == NULL) {
970         return NULL;
971     }
972     if (PyDict_SetItemString(kwargs, "name", name) < 0) {
973         goto done;
974     }
975     if (PyDict_SetItemString(kwargs, "path", path) < 0) {
976         goto done;
977     }
978 
979     error = PyObject_VectorcallDict(exception, &msg, 1, kwargs);
980     if (error != NULL) {
981         _PyErr_SetObject(tstate, (PyObject *)Py_TYPE(error), error);
982         Py_DECREF(error);
983     }
984 
985 done:
986     Py_DECREF(kwargs);
987     return NULL;
988 }
989 
990 PyObject *
PyErr_SetImportError(PyObject * msg,PyObject * name,PyObject * path)991 PyErr_SetImportError(PyObject *msg, PyObject *name, PyObject *path)
992 {
993     return PyErr_SetImportErrorSubclass(PyExc_ImportError, msg, name, path);
994 }
995 
996 void
_PyErr_BadInternalCall(const char * filename,int lineno)997 _PyErr_BadInternalCall(const char *filename, int lineno)
998 {
999     PyThreadState *tstate = _PyThreadState_GET();
1000     _PyErr_Format(tstate, PyExc_SystemError,
1001                   "%s:%d: bad argument to internal function",
1002                   filename, lineno);
1003 }
1004 
1005 /* Remove the preprocessor macro for PyErr_BadInternalCall() so that we can
1006    export the entry point for existing object code: */
1007 #undef PyErr_BadInternalCall
1008 void
PyErr_BadInternalCall(void)1009 PyErr_BadInternalCall(void)
1010 {
1011     assert(0 && "bad argument to internal function");
1012     PyThreadState *tstate = _PyThreadState_GET();
1013     _PyErr_SetString(tstate, PyExc_SystemError,
1014                      "bad argument to internal function");
1015 }
1016 #define PyErr_BadInternalCall() _PyErr_BadInternalCall(__FILE__, __LINE__)
1017 
1018 
1019 static PyObject *
_PyErr_FormatV(PyThreadState * tstate,PyObject * exception,const char * format,va_list vargs)1020 _PyErr_FormatV(PyThreadState *tstate, PyObject *exception,
1021                const char *format, va_list vargs)
1022 {
1023     PyObject* string;
1024 
1025     /* Issue #23571: PyUnicode_FromFormatV() must not be called with an
1026        exception set, it calls arbitrary Python code like PyObject_Repr() */
1027     _PyErr_Clear(tstate);
1028 
1029     string = PyUnicode_FromFormatV(format, vargs);
1030 
1031     _PyErr_SetObject(tstate, exception, string);
1032     Py_XDECREF(string);
1033     return NULL;
1034 }
1035 
1036 
1037 PyObject *
PyErr_FormatV(PyObject * exception,const char * format,va_list vargs)1038 PyErr_FormatV(PyObject *exception, const char *format, va_list vargs)
1039 {
1040     PyThreadState *tstate = _PyThreadState_GET();
1041     return _PyErr_FormatV(tstate, exception, format, vargs);
1042 }
1043 
1044 
1045 PyObject *
_PyErr_Format(PyThreadState * tstate,PyObject * exception,const char * format,...)1046 _PyErr_Format(PyThreadState *tstate, PyObject *exception,
1047               const char *format, ...)
1048 {
1049     va_list vargs;
1050 #ifdef HAVE_STDARG_PROTOTYPES
1051     va_start(vargs, format);
1052 #else
1053     va_start(vargs);
1054 #endif
1055     _PyErr_FormatV(tstate, exception, format, vargs);
1056     va_end(vargs);
1057     return NULL;
1058 }
1059 
1060 
1061 PyObject *
PyErr_Format(PyObject * exception,const char * format,...)1062 PyErr_Format(PyObject *exception, const char *format, ...)
1063 {
1064     PyThreadState *tstate = _PyThreadState_GET();
1065     va_list vargs;
1066 #ifdef HAVE_STDARG_PROTOTYPES
1067     va_start(vargs, format);
1068 #else
1069     va_start(vargs);
1070 #endif
1071     _PyErr_FormatV(tstate, exception, format, vargs);
1072     va_end(vargs);
1073     return NULL;
1074 }
1075 
1076 
1077 PyObject *
PyErr_NewException(const char * name,PyObject * base,PyObject * dict)1078 PyErr_NewException(const char *name, PyObject *base, PyObject *dict)
1079 {
1080     PyThreadState *tstate = _PyThreadState_GET();
1081     PyObject *modulename = NULL;
1082     PyObject *classname = NULL;
1083     PyObject *mydict = NULL;
1084     PyObject *bases = NULL;
1085     PyObject *result = NULL;
1086 
1087     const char *dot = strrchr(name, '.');
1088     if (dot == NULL) {
1089         _PyErr_SetString(tstate, PyExc_SystemError,
1090                          "PyErr_NewException: name must be module.class");
1091         return NULL;
1092     }
1093     if (base == NULL) {
1094         base = PyExc_Exception;
1095     }
1096     if (dict == NULL) {
1097         dict = mydict = PyDict_New();
1098         if (dict == NULL)
1099             goto failure;
1100     }
1101 
1102     if (_PyDict_GetItemIdWithError(dict, &PyId___module__) == NULL) {
1103         if (_PyErr_Occurred(tstate)) {
1104             goto failure;
1105         }
1106         modulename = PyUnicode_FromStringAndSize(name,
1107                                              (Py_ssize_t)(dot-name));
1108         if (modulename == NULL)
1109             goto failure;
1110         if (_PyDict_SetItemId(dict, &PyId___module__, modulename) != 0)
1111             goto failure;
1112     }
1113     if (PyTuple_Check(base)) {
1114         bases = base;
1115         /* INCREF as we create a new ref in the else branch */
1116         Py_INCREF(bases);
1117     } else {
1118         bases = PyTuple_Pack(1, base);
1119         if (bases == NULL)
1120             goto failure;
1121     }
1122     /* Create a real class. */
1123     result = PyObject_CallFunction((PyObject *)&PyType_Type, "sOO",
1124                                    dot+1, bases, dict);
1125   failure:
1126     Py_XDECREF(bases);
1127     Py_XDECREF(mydict);
1128     Py_XDECREF(classname);
1129     Py_XDECREF(modulename);
1130     return result;
1131 }
1132 
1133 
1134 /* Create an exception with docstring */
1135 PyObject *
PyErr_NewExceptionWithDoc(const char * name,const char * doc,PyObject * base,PyObject * dict)1136 PyErr_NewExceptionWithDoc(const char *name, const char *doc,
1137                           PyObject *base, PyObject *dict)
1138 {
1139     int result;
1140     PyObject *ret = NULL;
1141     PyObject *mydict = NULL; /* points to the dict only if we create it */
1142     PyObject *docobj;
1143 
1144     if (dict == NULL) {
1145         dict = mydict = PyDict_New();
1146         if (dict == NULL) {
1147             return NULL;
1148         }
1149     }
1150 
1151     if (doc != NULL) {
1152         docobj = PyUnicode_FromString(doc);
1153         if (docobj == NULL)
1154             goto failure;
1155         result = PyDict_SetItemString(dict, "__doc__", docobj);
1156         Py_DECREF(docobj);
1157         if (result < 0)
1158             goto failure;
1159     }
1160 
1161     ret = PyErr_NewException(name, base, dict);
1162   failure:
1163     Py_XDECREF(mydict);
1164     return ret;
1165 }
1166 
1167 
1168 PyDoc_STRVAR(UnraisableHookArgs__doc__,
1169 "UnraisableHookArgs\n\
1170 \n\
1171 Type used to pass arguments to sys.unraisablehook.");
1172 
1173 static PyTypeObject UnraisableHookArgsType;
1174 
1175 static PyStructSequence_Field UnraisableHookArgs_fields[] = {
1176     {"exc_type", "Exception type"},
1177     {"exc_value", "Exception value"},
1178     {"exc_traceback", "Exception traceback"},
1179     {"err_msg", "Error message"},
1180     {"object", "Object causing the exception"},
1181     {0}
1182 };
1183 
1184 static PyStructSequence_Desc UnraisableHookArgs_desc = {
1185     .name = "UnraisableHookArgs",
1186     .doc = UnraisableHookArgs__doc__,
1187     .fields = UnraisableHookArgs_fields,
1188     .n_in_sequence = 5
1189 };
1190 
1191 
1192 PyStatus
_PyErr_Init(void)1193 _PyErr_Init(void)
1194 {
1195     if (UnraisableHookArgsType.tp_name == NULL) {
1196         if (PyStructSequence_InitType2(&UnraisableHookArgsType,
1197                                        &UnraisableHookArgs_desc) < 0) {
1198             return _PyStatus_ERR("failed to initialize UnraisableHookArgs type");
1199         }
1200     }
1201     return _PyStatus_OK();
1202 }
1203 
1204 
1205 static PyObject *
make_unraisable_hook_args(PyThreadState * tstate,PyObject * exc_type,PyObject * exc_value,PyObject * exc_tb,PyObject * err_msg,PyObject * obj)1206 make_unraisable_hook_args(PyThreadState *tstate, PyObject *exc_type,
1207                           PyObject *exc_value, PyObject *exc_tb,
1208                           PyObject *err_msg, PyObject *obj)
1209 {
1210     PyObject *args = PyStructSequence_New(&UnraisableHookArgsType);
1211     if (args == NULL) {
1212         return NULL;
1213     }
1214 
1215     Py_ssize_t pos = 0;
1216 #define ADD_ITEM(exc_type) \
1217         do { \
1218             if (exc_type == NULL) { \
1219                 exc_type = Py_None; \
1220             } \
1221             Py_INCREF(exc_type); \
1222             PyStructSequence_SET_ITEM(args, pos++, exc_type); \
1223         } while (0)
1224 
1225 
1226     ADD_ITEM(exc_type);
1227     ADD_ITEM(exc_value);
1228     ADD_ITEM(exc_tb);
1229     ADD_ITEM(err_msg);
1230     ADD_ITEM(obj);
1231 #undef ADD_ITEM
1232 
1233     if (_PyErr_Occurred(tstate)) {
1234         Py_DECREF(args);
1235         return NULL;
1236     }
1237     return args;
1238 }
1239 
1240 
1241 
1242 /* Default implementation of sys.unraisablehook.
1243 
1244    It can be called to log the exception of a custom sys.unraisablehook.
1245 
1246    Do nothing if sys.stderr attribute doesn't exist or is set to None. */
1247 static int
write_unraisable_exc_file(PyThreadState * tstate,PyObject * exc_type,PyObject * exc_value,PyObject * exc_tb,PyObject * err_msg,PyObject * obj,PyObject * file)1248 write_unraisable_exc_file(PyThreadState *tstate, PyObject *exc_type,
1249                           PyObject *exc_value, PyObject *exc_tb,
1250                           PyObject *err_msg, PyObject *obj, PyObject *file)
1251 {
1252     if (obj != NULL && obj != Py_None) {
1253         if (err_msg != NULL && err_msg != Py_None) {
1254             if (PyFile_WriteObject(err_msg, file, Py_PRINT_RAW) < 0) {
1255                 return -1;
1256             }
1257             if (PyFile_WriteString(": ", file) < 0) {
1258                 return -1;
1259             }
1260         }
1261         else {
1262             if (PyFile_WriteString("Exception ignored in: ", file) < 0) {
1263                 return -1;
1264             }
1265         }
1266 
1267         if (PyFile_WriteObject(obj, file, 0) < 0) {
1268             _PyErr_Clear(tstate);
1269             if (PyFile_WriteString("<object repr() failed>", file) < 0) {
1270                 return -1;
1271             }
1272         }
1273         if (PyFile_WriteString("\n", file) < 0) {
1274             return -1;
1275         }
1276     }
1277     else if (err_msg != NULL && err_msg != Py_None) {
1278         if (PyFile_WriteObject(err_msg, file, Py_PRINT_RAW) < 0) {
1279             return -1;
1280         }
1281         if (PyFile_WriteString(":\n", file) < 0) {
1282             return -1;
1283         }
1284     }
1285 
1286     if (exc_tb != NULL && exc_tb != Py_None) {
1287         if (PyTraceBack_Print(exc_tb, file) < 0) {
1288             /* continue even if writing the traceback failed */
1289             _PyErr_Clear(tstate);
1290         }
1291     }
1292 
1293     if (exc_type == NULL || exc_type == Py_None) {
1294         return -1;
1295     }
1296 
1297     assert(PyExceptionClass_Check(exc_type));
1298     const char *className = PyExceptionClass_Name(exc_type);
1299     if (className != NULL) {
1300         const char *dot = strrchr(className, '.');
1301         if (dot != NULL) {
1302             className = dot+1;
1303         }
1304     }
1305 
1306     PyObject *moduleName = _PyObject_GetAttrId(exc_type, &PyId___module__);
1307     if (moduleName == NULL || !PyUnicode_Check(moduleName)) {
1308         Py_XDECREF(moduleName);
1309         _PyErr_Clear(tstate);
1310         if (PyFile_WriteString("<unknown>", file) < 0) {
1311             return -1;
1312         }
1313     }
1314     else {
1315         if (!_PyUnicode_EqualToASCIIId(moduleName, &PyId_builtins)) {
1316             if (PyFile_WriteObject(moduleName, file, Py_PRINT_RAW) < 0) {
1317                 Py_DECREF(moduleName);
1318                 return -1;
1319             }
1320             Py_DECREF(moduleName);
1321             if (PyFile_WriteString(".", file) < 0) {
1322                 return -1;
1323             }
1324         }
1325         else {
1326             Py_DECREF(moduleName);
1327         }
1328     }
1329     if (className == NULL) {
1330         if (PyFile_WriteString("<unknown>", file) < 0) {
1331             return -1;
1332         }
1333     }
1334     else {
1335         if (PyFile_WriteString(className, file) < 0) {
1336             return -1;
1337         }
1338     }
1339 
1340     if (exc_value && exc_value != Py_None) {
1341         if (PyFile_WriteString(": ", file) < 0) {
1342             return -1;
1343         }
1344         if (PyFile_WriteObject(exc_value, file, Py_PRINT_RAW) < 0) {
1345             _PyErr_Clear(tstate);
1346             if (PyFile_WriteString("<exception str() failed>", file) < 0) {
1347                 return -1;
1348             }
1349         }
1350     }
1351 
1352     if (PyFile_WriteString("\n", file) < 0) {
1353         return -1;
1354     }
1355 
1356     /* Explicitly call file.flush() */
1357     PyObject *res = _PyObject_CallMethodIdNoArgs(file, &PyId_flush);
1358     if (!res) {
1359         return -1;
1360     }
1361     Py_DECREF(res);
1362 
1363     return 0;
1364 }
1365 
1366 
1367 static int
write_unraisable_exc(PyThreadState * tstate,PyObject * exc_type,PyObject * exc_value,PyObject * exc_tb,PyObject * err_msg,PyObject * obj)1368 write_unraisable_exc(PyThreadState *tstate, PyObject *exc_type,
1369                      PyObject *exc_value, PyObject *exc_tb, PyObject *err_msg,
1370                      PyObject *obj)
1371 {
1372     PyObject *file = _PySys_GetObjectId(&PyId_stderr);
1373     if (file == NULL || file == Py_None) {
1374         return 0;
1375     }
1376 
1377     /* Hold a strong reference to ensure that sys.stderr doesn't go away
1378        while we use it */
1379     Py_INCREF(file);
1380     int res = write_unraisable_exc_file(tstate, exc_type, exc_value, exc_tb,
1381                                         err_msg, obj, file);
1382     Py_DECREF(file);
1383 
1384     return res;
1385 }
1386 
1387 
1388 PyObject*
_PyErr_WriteUnraisableDefaultHook(PyObject * args)1389 _PyErr_WriteUnraisableDefaultHook(PyObject *args)
1390 {
1391     PyThreadState *tstate = _PyThreadState_GET();
1392 
1393     if (!Py_IS_TYPE(args, &UnraisableHookArgsType)) {
1394         _PyErr_SetString(tstate, PyExc_TypeError,
1395                          "sys.unraisablehook argument type "
1396                          "must be UnraisableHookArgs");
1397         return NULL;
1398     }
1399 
1400     /* Borrowed references */
1401     PyObject *exc_type = PyStructSequence_GET_ITEM(args, 0);
1402     PyObject *exc_value = PyStructSequence_GET_ITEM(args, 1);
1403     PyObject *exc_tb = PyStructSequence_GET_ITEM(args, 2);
1404     PyObject *err_msg = PyStructSequence_GET_ITEM(args, 3);
1405     PyObject *obj = PyStructSequence_GET_ITEM(args, 4);
1406 
1407     if (write_unraisable_exc(tstate, exc_type, exc_value, exc_tb, err_msg, obj) < 0) {
1408         return NULL;
1409     }
1410     Py_RETURN_NONE;
1411 }
1412 
1413 
1414 /* Call sys.unraisablehook().
1415 
1416    This function can be used when an exception has occurred but there is no way
1417    for Python to handle it. For example, when a destructor raises an exception
1418    or during garbage collection (gc.collect()).
1419 
1420    If err_msg_str is non-NULL, the error message is formatted as:
1421    "Exception ignored %s" % err_msg_str. Otherwise, use "Exception ignored in"
1422    error message.
1423 
1424    An exception must be set when calling this function. */
1425 void
_PyErr_WriteUnraisableMsg(const char * err_msg_str,PyObject * obj)1426 _PyErr_WriteUnraisableMsg(const char *err_msg_str, PyObject *obj)
1427 {
1428     PyThreadState *tstate = _PyThreadState_GET();
1429     _Py_EnsureTstateNotNULL(tstate);
1430 
1431     PyObject *err_msg = NULL;
1432     PyObject *exc_type, *exc_value, *exc_tb;
1433     _PyErr_Fetch(tstate, &exc_type, &exc_value, &exc_tb);
1434 
1435     assert(exc_type != NULL);
1436 
1437     if (exc_type == NULL) {
1438         /* sys.unraisablehook requires that at least exc_type is set */
1439         goto default_hook;
1440     }
1441 
1442     if (exc_tb == NULL) {
1443         PyFrameObject *frame = tstate->frame;
1444         if (frame != NULL) {
1445             exc_tb = _PyTraceBack_FromFrame(NULL, frame);
1446             if (exc_tb == NULL) {
1447                 _PyErr_Clear(tstate);
1448             }
1449         }
1450     }
1451 
1452     _PyErr_NormalizeException(tstate, &exc_type, &exc_value, &exc_tb);
1453 
1454     if (exc_tb != NULL && exc_tb != Py_None && PyTraceBack_Check(exc_tb)) {
1455         if (PyException_SetTraceback(exc_value, exc_tb) < 0) {
1456             _PyErr_Clear(tstate);
1457         }
1458     }
1459 
1460     if (err_msg_str != NULL) {
1461         err_msg = PyUnicode_FromFormat("Exception ignored %s", err_msg_str);
1462         if (err_msg == NULL) {
1463             PyErr_Clear();
1464         }
1465     }
1466 
1467     PyObject *hook_args = make_unraisable_hook_args(
1468         tstate, exc_type, exc_value, exc_tb, err_msg, obj);
1469     if (hook_args == NULL) {
1470         err_msg_str = ("Exception ignored on building "
1471                        "sys.unraisablehook arguments");
1472         goto error;
1473     }
1474 
1475     _Py_IDENTIFIER(unraisablehook);
1476     PyObject *hook = _PySys_GetObjectId(&PyId_unraisablehook);
1477     if (hook == NULL) {
1478         Py_DECREF(hook_args);
1479         goto default_hook;
1480     }
1481 
1482     if (_PySys_Audit(tstate, "sys.unraisablehook", "OO", hook, hook_args) < 0) {
1483         Py_DECREF(hook_args);
1484         err_msg_str = "Exception ignored in audit hook";
1485         obj = NULL;
1486         goto error;
1487     }
1488 
1489     if (hook == Py_None) {
1490         Py_DECREF(hook_args);
1491         goto default_hook;
1492     }
1493 
1494     PyObject *res = PyObject_CallOneArg(hook, hook_args);
1495     Py_DECREF(hook_args);
1496     if (res != NULL) {
1497         Py_DECREF(res);
1498         goto done;
1499     }
1500 
1501     /* sys.unraisablehook failed: log its error using default hook */
1502     obj = hook;
1503     err_msg_str = NULL;
1504 
1505 error:
1506     /* err_msg_str and obj have been updated and we have a new exception */
1507     Py_XSETREF(err_msg, PyUnicode_FromString(err_msg_str ?
1508         err_msg_str : "Exception ignored in sys.unraisablehook"));
1509     Py_XDECREF(exc_type);
1510     Py_XDECREF(exc_value);
1511     Py_XDECREF(exc_tb);
1512     _PyErr_Fetch(tstate, &exc_type, &exc_value, &exc_tb);
1513 
1514 default_hook:
1515     /* Call the default unraisable hook (ignore failure) */
1516     (void)write_unraisable_exc(tstate, exc_type, exc_value, exc_tb,
1517                                err_msg, obj);
1518 
1519 done:
1520     Py_XDECREF(exc_type);
1521     Py_XDECREF(exc_value);
1522     Py_XDECREF(exc_tb);
1523     Py_XDECREF(err_msg);
1524     _PyErr_Clear(tstate); /* Just in case */
1525 }
1526 
1527 
1528 void
PyErr_WriteUnraisable(PyObject * obj)1529 PyErr_WriteUnraisable(PyObject *obj)
1530 {
1531     _PyErr_WriteUnraisableMsg(NULL, obj);
1532 }
1533 
1534 
1535 extern PyObject *PyModule_GetWarningsModule(void);
1536 
1537 
1538 void
PyErr_SyntaxLocation(const char * filename,int lineno)1539 PyErr_SyntaxLocation(const char *filename, int lineno)
1540 {
1541     PyErr_SyntaxLocationEx(filename, lineno, -1);
1542 }
1543 
1544 
1545 /* Set file and line information for the current exception.
1546    If the exception is not a SyntaxError, also sets additional attributes
1547    to make printing of exceptions believe it is a syntax error. */
1548 
1549 void
PyErr_SyntaxLocationObject(PyObject * filename,int lineno,int col_offset)1550 PyErr_SyntaxLocationObject(PyObject *filename, int lineno, int col_offset)
1551 {
1552     PyObject *exc, *v, *tb, *tmp;
1553     _Py_IDENTIFIER(filename);
1554     _Py_IDENTIFIER(lineno);
1555     _Py_IDENTIFIER(msg);
1556     _Py_IDENTIFIER(offset);
1557     _Py_IDENTIFIER(print_file_and_line);
1558     _Py_IDENTIFIER(text);
1559     PyThreadState *tstate = _PyThreadState_GET();
1560 
1561     /* add attributes for the line number and filename for the error */
1562     _PyErr_Fetch(tstate, &exc, &v, &tb);
1563     _PyErr_NormalizeException(tstate, &exc, &v, &tb);
1564     /* XXX check that it is, indeed, a syntax error. It might not
1565      * be, though. */
1566     tmp = PyLong_FromLong(lineno);
1567     if (tmp == NULL)
1568         _PyErr_Clear(tstate);
1569     else {
1570         if (_PyObject_SetAttrId(v, &PyId_lineno, tmp)) {
1571             _PyErr_Clear(tstate);
1572         }
1573         Py_DECREF(tmp);
1574     }
1575     tmp = NULL;
1576     if (col_offset >= 0) {
1577         tmp = PyLong_FromLong(col_offset);
1578         if (tmp == NULL) {
1579             _PyErr_Clear(tstate);
1580         }
1581     }
1582     if (_PyObject_SetAttrId(v, &PyId_offset, tmp ? tmp : Py_None)) {
1583         _PyErr_Clear(tstate);
1584     }
1585     Py_XDECREF(tmp);
1586     if (filename != NULL) {
1587         if (_PyObject_SetAttrId(v, &PyId_filename, filename)) {
1588             _PyErr_Clear(tstate);
1589         }
1590 
1591         tmp = PyErr_ProgramTextObject(filename, lineno);
1592         if (tmp) {
1593             if (_PyObject_SetAttrId(v, &PyId_text, tmp)) {
1594                 _PyErr_Clear(tstate);
1595             }
1596             Py_DECREF(tmp);
1597         }
1598     }
1599     if (exc != PyExc_SyntaxError) {
1600         if (!_PyObject_HasAttrId(v, &PyId_msg)) {
1601             tmp = PyObject_Str(v);
1602             if (tmp) {
1603                 if (_PyObject_SetAttrId(v, &PyId_msg, tmp)) {
1604                     _PyErr_Clear(tstate);
1605                 }
1606                 Py_DECREF(tmp);
1607             }
1608             else {
1609                 _PyErr_Clear(tstate);
1610             }
1611         }
1612         if (!_PyObject_HasAttrId(v, &PyId_print_file_and_line)) {
1613             if (_PyObject_SetAttrId(v, &PyId_print_file_and_line,
1614                                     Py_None)) {
1615                 _PyErr_Clear(tstate);
1616             }
1617         }
1618     }
1619     _PyErr_Restore(tstate, exc, v, tb);
1620 }
1621 
1622 void
PyErr_SyntaxLocationEx(const char * filename,int lineno,int col_offset)1623 PyErr_SyntaxLocationEx(const char *filename, int lineno, int col_offset)
1624 {
1625     PyThreadState *tstate = _PyThreadState_GET();
1626     PyObject *fileobj;
1627     if (filename != NULL) {
1628         fileobj = PyUnicode_DecodeFSDefault(filename);
1629         if (fileobj == NULL) {
1630             _PyErr_Clear(tstate);
1631         }
1632     }
1633     else {
1634         fileobj = NULL;
1635     }
1636     PyErr_SyntaxLocationObject(fileobj, lineno, col_offset);
1637     Py_XDECREF(fileobj);
1638 }
1639 
1640 /* Attempt to load the line of text that the exception refers to.  If it
1641    fails, it will return NULL but will not set an exception.
1642 
1643    XXX The functionality of this function is quite similar to the
1644    functionality in tb_displayline() in traceback.c. */
1645 
1646 static PyObject *
err_programtext(PyThreadState * tstate,FILE * fp,int lineno)1647 err_programtext(PyThreadState *tstate, FILE *fp, int lineno)
1648 {
1649     int i;
1650     char linebuf[1000];
1651     if (fp == NULL) {
1652         return NULL;
1653     }
1654 
1655     for (i = 0; i < lineno; i++) {
1656         char *pLastChar = &linebuf[sizeof(linebuf) - 2];
1657         do {
1658             *pLastChar = '\0';
1659             if (Py_UniversalNewlineFgets(linebuf, sizeof linebuf,
1660                                          fp, NULL) == NULL) {
1661                 goto after_loop;
1662             }
1663             /* fgets read *something*; if it didn't get as
1664                far as pLastChar, it must have found a newline
1665                or hit the end of the file; if pLastChar is \n,
1666                it obviously found a newline; else we haven't
1667                yet seen a newline, so must continue */
1668         } while (*pLastChar != '\0' && *pLastChar != '\n');
1669     }
1670 
1671 after_loop:
1672     fclose(fp);
1673     if (i == lineno) {
1674         PyObject *res;
1675         res = PyUnicode_FromString(linebuf);
1676         if (res == NULL)
1677             _PyErr_Clear(tstate);
1678         return res;
1679     }
1680     return NULL;
1681 }
1682 
1683 PyObject *
PyErr_ProgramText(const char * filename,int lineno)1684 PyErr_ProgramText(const char *filename, int lineno)
1685 {
1686     FILE *fp;
1687     if (filename == NULL || *filename == '\0' || lineno <= 0) {
1688         return NULL;
1689     }
1690     PyThreadState *tstate = _PyThreadState_GET();
1691     fp = _Py_fopen(filename, "r" PY_STDIOTEXTMODE);
1692     return err_programtext(tstate, fp, lineno);
1693 }
1694 
1695 PyObject *
PyErr_ProgramTextObject(PyObject * filename,int lineno)1696 PyErr_ProgramTextObject(PyObject *filename, int lineno)
1697 {
1698     if (filename == NULL || lineno <= 0) {
1699         return NULL;
1700     }
1701 
1702     PyThreadState *tstate = _PyThreadState_GET();
1703     FILE *fp = _Py_fopen_obj(filename, "r" PY_STDIOTEXTMODE);
1704     if (fp == NULL) {
1705         _PyErr_Clear(tstate);
1706         return NULL;
1707     }
1708     return err_programtext(tstate, fp, lineno);
1709 }
1710 
1711 #ifdef __cplusplus
1712 }
1713 #endif
1714