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