Coverage Report

Created: 2025-07-11 06:59

/src/Python-3.8.3/Python/errors.c
Line
Count
Source (jump to first uncovered line)
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
39
_PyErr_Restore(PyThreadState *tstate, PyObject *type, PyObject *value,
40
               PyObject *traceback)
41
35.0k
{
42
35.0k
    PyObject *oldtype, *oldvalue, *oldtraceback;
43
44
35.0k
    if (traceback != NULL && !PyTraceBack_Check(traceback)) {
45
        /* XXX Should never happen -- fatal error instead? */
46
        /* Well, it could be None. */
47
0
        Py_DECREF(traceback);
48
0
        traceback = NULL;
49
0
    }
50
51
    /* Save these in locals to safeguard against recursive
52
       invocation through Py_XDECREF */
53
35.0k
    oldtype = tstate->curexc_type;
54
35.0k
    oldvalue = tstate->curexc_value;
55
35.0k
    oldtraceback = tstate->curexc_traceback;
56
57
35.0k
    tstate->curexc_type = type;
58
35.0k
    tstate->curexc_value = value;
59
35.0k
    tstate->curexc_traceback = traceback;
60
61
35.0k
    Py_XDECREF(oldtype);
62
35.0k
    Py_XDECREF(oldvalue);
63
35.0k
    Py_XDECREF(oldtraceback);
64
35.0k
}
65
66
void
67
PyErr_Restore(PyObject *type, PyObject *value, PyObject *traceback)
68
4.50k
{
69
4.50k
    PyThreadState *tstate = _PyThreadState_GET();
70
4.50k
    _PyErr_Restore(tstate, type, value, traceback);
71
4.50k
}
72
73
74
_PyErr_StackItem *
75
_PyErr_GetTopmostException(PyThreadState *tstate)
76
8.81k
{
77
8.81k
    _PyErr_StackItem *exc_info = tstate->exc_info;
78
8.83k
    while ((exc_info->exc_type == NULL || exc_info->exc_type == Py_None) &&
79
8.83k
           exc_info->previous_item != NULL)
80
14
    {
81
14
        exc_info = exc_info->previous_item;
82
14
    }
83
8.81k
    return exc_info;
84
8.81k
}
85
86
static PyObject*
87
_PyErr_CreateException(PyObject *exception, PyObject *value)
88
2.75k
{
89
2.75k
    if (value == NULL || value == Py_None) {
90
208
        return _PyObject_CallNoArg(exception);
91
208
    }
92
2.54k
    else if (PyTuple_Check(value)) {
93
505
        return PyObject_Call(exception, value, NULL);
94
505
    }
95
2.04k
    else {
96
2.04k
        return PyObject_CallFunctionObjArgs(exception, value, NULL);
97
2.04k
    }
98
2.75k
}
99
100
void
101
_PyErr_SetObject(PyThreadState *tstate, PyObject *exception, PyObject *value)
102
8.80k
{
103
8.80k
    PyObject *exc_value;
104
8.80k
    PyObject *tb = NULL;
105
106
8.80k
    if (exception != NULL &&
107
8.80k
        !PyExceptionClass_Check(exception)) {
108
0
        _PyErr_Format(tstate, PyExc_SystemError,
109
0
                      "exception %R not a BaseException subclass",
110
0
                      exception);
111
0
        return;
112
0
    }
113
114
8.80k
    Py_XINCREF(value);
115
8.80k
    exc_value = _PyErr_GetTopmostException(tstate)->exc_value;
116
8.80k
    if (exc_value != NULL && exc_value != Py_None) {
117
        /* Implicit exception chaining */
118
1.23k
        Py_INCREF(exc_value);
119
1.23k
        if (value == NULL || !PyExceptionInstance_Check(value)) {
120
            /* We must normalize the value right now */
121
963
            PyObject *fixed_value;
122
123
            /* Issue #23571: functions must not be called with an
124
               exception set */
125
963
            _PyErr_Clear(tstate);
126
127
963
            fixed_value = _PyErr_CreateException(exception, value);
128
963
            Py_XDECREF(value);
129
963
            if (fixed_value == NULL) {
130
0
                Py_DECREF(exc_value);
131
0
                return;
132
0
            }
133
134
963
            value = fixed_value;
135
963
        }
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
1.23k
        if (exc_value != value) {
142
1.23k
            PyObject *o = exc_value, *context;
143
1.23k
            while ((context = PyException_GetContext(o))) {
144
4
                Py_DECREF(context);
145
4
                if (context == value) {
146
0
                    PyException_SetContext(o, NULL);
147
0
                    break;
148
0
                }
149
4
                o = context;
150
4
            }
151
1.23k
            PyException_SetContext(value, exc_value);
152
1.23k
        }
153
0
        else {
154
0
            Py_DECREF(exc_value);
155
0
        }
156
1.23k
    }
157
8.80k
    if (value != NULL && PyExceptionInstance_Check(value))
158
1.99k
        tb = PyException_GetTraceback(value);
159
8.80k
    Py_XINCREF(exception);
160
8.80k
    _PyErr_Restore(tstate, exception, value, tb);
161
8.80k
}
162
163
void
164
PyErr_SetObject(PyObject *exception, PyObject *value)
165
914
{
166
914
    PyThreadState *tstate = _PyThreadState_GET();
167
914
    _PyErr_SetObject(tstate, exception, value);
168
914
}
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
174
_PyErr_SetKeyError(PyObject *arg)
175
505
{
176
505
    PyThreadState *tstate = _PyThreadState_GET();
177
505
    PyObject *tup = PyTuple_Pack(1, arg);
178
505
    if (!tup) {
179
        /* caller will expect error to be set anyway */
180
0
        return;
181
0
    }
182
505
    _PyErr_SetObject(tstate, PyExc_KeyError, tup);
183
505
    Py_DECREF(tup);
184
505
}
185
186
void
187
_PyErr_SetNone(PyThreadState *tstate, PyObject *exception)
188
228
{
189
228
    _PyErr_SetObject(tstate, exception, (PyObject *)NULL);
190
228
}
191
192
193
void
194
PyErr_SetNone(PyObject *exception)
195
228
{
196
228
    PyThreadState *tstate = _PyThreadState_GET();
197
228
    _PyErr_SetNone(tstate, exception);
198
228
}
199
200
201
void
202
_PyErr_SetString(PyThreadState *tstate, PyObject *exception,
203
                 const char *string)
204
665
{
205
665
    PyObject *value = PyUnicode_FromString(string);
206
665
    _PyErr_SetObject(tstate, exception, value);
207
665
    Py_XDECREF(value);
208
665
}
209
210
void
211
PyErr_SetString(PyObject *exception, const char *string)
212
665
{
213
665
    PyThreadState *tstate = _PyThreadState_GET();
214
665
    _PyErr_SetString(tstate, exception, string);
215
665
}
216
217
218
PyObject* _Py_HOT_FUNCTION
219
PyErr_Occurred(void)
220
821k
{
221
821k
    PyThreadState *tstate = _PyThreadState_GET();
222
821k
    return _PyErr_Occurred(tstate);
223
821k
}
224
225
226
int
227
PyErr_GivenExceptionMatches(PyObject *err, PyObject *exc)
228
7.47k
{
229
7.47k
    if (err == NULL || exc == NULL) {
230
        /* maybe caused by "import exceptions" that failed early on */
231
26
        return 0;
232
26
    }
233
7.45k
    if (PyTuple_Check(exc)) {
234
140
        Py_ssize_t i, n;
235
140
        n = PyTuple_Size(exc);
236
140
        for (i = 0; i < n; i++) {
237
            /* Test recursively */
238
140
             if (PyErr_GivenExceptionMatches(
239
140
                 err, PyTuple_GET_ITEM(exc, i)))
240
140
             {
241
140
                 return 1;
242
140
             }
243
140
        }
244
0
        return 0;
245
140
    }
246
    /* err might be an instance, so check its class. */
247
7.31k
    if (PyExceptionInstance_Check(err))
248
0
        err = PyExceptionInstance_Class(err);
249
250
7.31k
    if (PyExceptionClass_Check(err) && PyExceptionClass_Check(exc)) {
251
7.31k
        return PyType_IsSubtype((PyTypeObject *)err, (PyTypeObject *)exc);
252
7.31k
    }
253
254
0
    return err == exc;
255
7.31k
}
256
257
258
int
259
_PyErr_ExceptionMatches(PyThreadState *tstate, PyObject *exc)
260
3.95k
{
261
3.95k
    return PyErr_GivenExceptionMatches(_PyErr_Occurred(tstate), exc);
262
3.95k
}
263
264
265
int
266
PyErr_ExceptionMatches(PyObject *exc)
267
3.84k
{
268
3.84k
    PyThreadState *tstate = _PyThreadState_GET();
269
3.84k
    return _PyErr_ExceptionMatches(tstate, exc);
270
3.84k
}
271
272
273
#ifndef Py_NORMALIZE_RECURSION_LIMIT
274
0
#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
284
_PyErr_NormalizeException(PyThreadState *tstate, PyObject **exc,
285
                          PyObject **val, PyObject **tb)
286
3.16k
{
287
3.16k
    int recursion_depth = 0;
288
3.16k
    PyObject *type, *value, *initial_tb;
289
290
3.16k
  restart:
291
3.16k
    type = *exc;
292
3.16k
    if (type == NULL) {
293
        /* There was no exception, so nothing to do. */
294
0
        return;
295
0
    }
296
297
3.16k
    value = *val;
298
    /* If PyErr_SetNone() was used, the value will have been actually
299
       set to NULL.
300
    */
301
3.16k
    if (!value) {
302
36
        value = Py_None;
303
36
        Py_INCREF(value);
304
36
    }
305
306
    /* Normalize the exception so that if the type is a class, the
307
       value will be an instance.
308
    */
309
3.16k
    if (PyExceptionClass_Check(type)) {
310
3.16k
        PyObject *inclass = NULL;
311
3.16k
        int is_subclass = 0;
312
313
3.16k
        if (PyExceptionInstance_Check(value)) {
314
1.37k
            inclass = PyExceptionInstance_Class(value);
315
1.37k
            is_subclass = PyObject_IsSubclass(inclass, type);
316
1.37k
            if (is_subclass < 0) {
317
0
                goto error;
318
0
            }
319
1.37k
        }
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
3.16k
        if (!is_subclass) {
327
1.79k
            PyObject *fixed_value = _PyErr_CreateException(type, value);
328
1.79k
            if (fixed_value == NULL) {
329
0
                goto error;
330
0
            }
331
1.79k
            Py_DECREF(value);
332
1.79k
            value = fixed_value;
333
1.79k
        }
334
        /* If the class of the instance doesn't exactly match the
335
           class of the type, believe the instance.
336
        */
337
1.37k
        else if (inclass != type) {
338
0
            Py_INCREF(inclass);
339
0
            Py_DECREF(type);
340
0
            type = inclass;
341
0
        }
342
3.16k
    }
343
3.16k
    *exc = type;
344
3.16k
    *val = value;
345
3.16k
    return;
346
347
0
  error:
348
0
    Py_DECREF(type);
349
0
    Py_DECREF(value);
350
0
    recursion_depth++;
351
0
    if (recursion_depth == Py_NORMALIZE_RECURSION_LIMIT) {
352
0
        _PyErr_SetString(tstate, PyExc_RecursionError,
353
0
                         "maximum recursion depth exceeded "
354
0
                         "while normalizing an exception");
355
0
    }
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
0
    initial_tb = *tb;
361
0
    _PyErr_Fetch(tstate, exc, val, tb);
362
0
    assert(*exc != NULL);
363
0
    if (initial_tb != NULL) {
364
0
        if (*tb == NULL)
365
0
            *tb = initial_tb;
366
0
        else
367
0
            Py_DECREF(initial_tb);
368
0
    }
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
0
    if (recursion_depth >= Py_NORMALIZE_RECURSION_LIMIT + 2) {
374
0
        if (PyErr_GivenExceptionMatches(*exc, PyExc_MemoryError)) {
375
0
            Py_FatalError("Cannot recover from MemoryErrors "
376
0
                          "while normalizing exceptions.");
377
0
        }
378
0
        else {
379
0
            Py_FatalError("Cannot recover from the recursive normalization "
380
0
                          "of an exception.");
381
0
        }
382
0
    }
383
0
    goto restart;
384
0
}
385
386
387
void
388
PyErr_NormalizeException(PyObject **exc, PyObject **val, PyObject **tb)
389
0
{
390
0
    PyThreadState *tstate = _PyThreadState_GET();
391
0
    _PyErr_NormalizeException(tstate, exc, val, tb);
392
0
}
393
394
395
void
396
_PyErr_Fetch(PyThreadState *tstate, PyObject **p_type, PyObject **p_value,
397
             PyObject **p_traceback)
398
7.92k
{
399
7.92k
    *p_type = tstate->curexc_type;
400
7.92k
    *p_value = tstate->curexc_value;
401
7.92k
    *p_traceback = tstate->curexc_traceback;
402
403
7.92k
    tstate->curexc_type = NULL;
404
7.92k
    tstate->curexc_value = NULL;
405
7.92k
    tstate->curexc_traceback = NULL;
406
7.92k
}
407
408
409
void
410
PyErr_Fetch(PyObject **p_type, PyObject **p_value, PyObject **p_traceback)
411
4.75k
{
412
4.75k
    PyThreadState *tstate = _PyThreadState_GET();
413
4.75k
    _PyErr_Fetch(tstate, p_type, p_value, p_traceback);
414
4.75k
}
415
416
417
void
418
_PyErr_Clear(PyThreadState *tstate)
419
21.6k
{
420
21.6k
    _PyErr_Restore(tstate, NULL, NULL, NULL);
421
21.6k
}
422
423
424
void
425
PyErr_Clear(void)
426
14.4k
{
427
14.4k
    PyThreadState *tstate = _PyThreadState_GET();
428
14.4k
    _PyErr_Clear(tstate);
429
14.4k
}
430
431
432
void
433
PyErr_GetExcInfo(PyObject **p_type, PyObject **p_value, PyObject **p_traceback)
434
0
{
435
0
    PyThreadState *tstate = _PyThreadState_GET();
436
437
0
    _PyErr_StackItem *exc_info = _PyErr_GetTopmostException(tstate);
438
0
    *p_type = exc_info->exc_type;
439
0
    *p_value = exc_info->exc_value;
440
0
    *p_traceback = exc_info->exc_traceback;
441
442
443
0
    Py_XINCREF(*p_type);
444
0
    Py_XINCREF(*p_value);
445
0
    Py_XINCREF(*p_traceback);
446
0
}
447
448
void
449
PyErr_SetExcInfo(PyObject *p_type, PyObject *p_value, PyObject *p_traceback)
450
0
{
451
0
    PyObject *oldtype, *oldvalue, *oldtraceback;
452
0
    PyThreadState *tstate = _PyThreadState_GET();
453
454
0
    oldtype = tstate->exc_info->exc_type;
455
0
    oldvalue = tstate->exc_info->exc_value;
456
0
    oldtraceback = tstate->exc_info->exc_traceback;
457
458
0
    tstate->exc_info->exc_type = p_type;
459
0
    tstate->exc_info->exc_value = p_value;
460
0
    tstate->exc_info->exc_traceback = p_traceback;
461
462
0
    Py_XDECREF(oldtype);
463
0
    Py_XDECREF(oldvalue);
464
0
    Py_XDECREF(oldtraceback);
465
0
}
466
467
/* Like PyErr_Restore(), but if an exception is already set,
468
   set the context associated with it.
469
 */
470
void
471
_PyErr_ChainExceptions(PyObject *exc, PyObject *val, PyObject *tb)
472
236
{
473
236
    if (exc == NULL)
474
236
        return;
475
476
0
    PyThreadState *tstate = _PyThreadState_GET();
477
0
    if (_PyErr_Occurred(tstate)) {
478
0
        PyObject *exc2, *val2, *tb2;
479
0
        _PyErr_Fetch(tstate, &exc2, &val2, &tb2);
480
0
        _PyErr_NormalizeException(tstate, &exc, &val, &tb);
481
0
        if (tb != NULL) {
482
0
            PyException_SetTraceback(val, tb);
483
0
            Py_DECREF(tb);
484
0
        }
485
0
        Py_DECREF(exc);
486
0
        _PyErr_NormalizeException(tstate, &exc2, &val2, &tb2);
487
0
        PyException_SetContext(val2, val);
488
0
        _PyErr_Restore(tstate, exc2, val2, tb2);
489
0
    }
490
0
    else {
491
0
        _PyErr_Restore(tstate, exc, val, tb);
492
0
    }
493
0
}
494
495
static PyObject *
496
_PyErr_FormatVFromCause(PyThreadState *tstate, PyObject *exception,
497
                        const char *format, va_list vargs)
498
0
{
499
0
    PyObject *exc, *val, *val2, *tb;
500
501
0
    assert(_PyErr_Occurred(tstate));
502
0
    _PyErr_Fetch(tstate, &exc, &val, &tb);
503
0
    _PyErr_NormalizeException(tstate, &exc, &val, &tb);
504
0
    if (tb != NULL) {
505
0
        PyException_SetTraceback(val, tb);
506
0
        Py_DECREF(tb);
507
0
    }
508
0
    Py_DECREF(exc);
509
0
    assert(!_PyErr_Occurred(tstate));
510
511
0
    _PyErr_FormatV(tstate, exception, format, vargs);
512
513
0
    _PyErr_Fetch(tstate, &exc, &val2, &tb);
514
0
    _PyErr_NormalizeException(tstate, &exc, &val2, &tb);
515
0
    Py_INCREF(val);
516
0
    PyException_SetCause(val2, val);
517
0
    PyException_SetContext(val2, val);
518
0
    _PyErr_Restore(tstate, exc, val2, tb);
519
520
0
    return NULL;
521
0
}
522
523
PyObject *
524
_PyErr_FormatFromCause(PyObject *exception, const char *format, ...)
525
0
{
526
0
    PyThreadState *tstate = _PyThreadState_GET();
527
0
    va_list vargs;
528
0
#ifdef HAVE_STDARG_PROTOTYPES
529
0
    va_start(vargs, format);
530
#else
531
    va_start(vargs);
532
#endif
533
0
    _PyErr_FormatVFromCause(tstate, exception, format, vargs);
534
0
    va_end(vargs);
535
0
    return NULL;
536
0
}
537
538
/* Convenience functions to set a type error exception and return 0 */
539
540
int
541
PyErr_BadArgument(void)
542
0
{
543
0
    PyThreadState *tstate = _PyThreadState_GET();
544
0
    _PyErr_SetString(tstate, PyExc_TypeError,
545
0
                     "bad argument type for built-in operation");
546
0
    return 0;
547
0
}
548
549
PyObject *
550
PyErr_NoMemory(void)
551
0
{
552
0
    PyThreadState *tstate = _PyThreadState_GET();
553
0
    if (Py_TYPE(PyExc_MemoryError) == NULL) {
554
        /* PyErr_NoMemory() has been called before PyExc_MemoryError has been
555
           initialized by _PyExc_Init() */
556
0
        Py_FatalError("Out of memory and PyExc_MemoryError is not "
557
0
                      "initialized yet");
558
0
    }
559
0
    _PyErr_SetNone(tstate, PyExc_MemoryError);
560
0
    return NULL;
561
0
}
562
563
PyObject *
564
PyErr_SetFromErrnoWithFilenameObject(PyObject *exc, PyObject *filenameObject)
565
230
{
566
230
    return PyErr_SetFromErrnoWithFilenameObjects(exc, filenameObject, NULL);
567
230
}
568
569
PyObject *
570
PyErr_SetFromErrnoWithFilenameObjects(PyObject *exc, PyObject *filenameObject, PyObject *filenameObject2)
571
230
{
572
230
    PyThreadState *tstate = _PyThreadState_GET();
573
230
    PyObject *message;
574
230
    PyObject *v, *args;
575
230
    int i = errno;
576
#ifdef MS_WINDOWS
577
    WCHAR *s_buf = NULL;
578
#endif /* Unix/Windows */
579
580
230
#ifdef EINTR
581
230
    if (i == EINTR && PyErr_CheckSignals())
582
0
        return NULL;
583
230
#endif
584
585
230
#ifndef MS_WINDOWS
586
230
    if (i != 0) {
587
230
        const char *s = strerror(i);
588
230
        message = PyUnicode_DecodeLocale(s, "surrogateescape");
589
230
    }
590
0
    else {
591
        /* Sometimes errno didn't get set */
592
0
        message = PyUnicode_FromString("Error");
593
0
    }
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
230
    if (message == NULL)
636
0
    {
637
#ifdef MS_WINDOWS
638
        LocalFree(s_buf);
639
#endif
640
0
        return NULL;
641
0
    }
642
643
230
    if (filenameObject != NULL) {
644
230
        if (filenameObject2 != NULL)
645
0
            args = Py_BuildValue("(iOOiO)", i, message, filenameObject, 0, filenameObject2);
646
230
        else
647
230
            args = Py_BuildValue("(iOO)", i, message, filenameObject);
648
230
    } else {
649
0
        assert(filenameObject2 == NULL);
650
0
        args = Py_BuildValue("(iO)", i, message);
651
0
    }
652
230
    Py_DECREF(message);
653
654
230
    if (args != NULL) {
655
230
        v = PyObject_Call(exc, args, NULL);
656
230
        Py_DECREF(args);
657
230
        if (v != NULL) {
658
230
            _PyErr_SetObject(tstate, (PyObject *) Py_TYPE(v), v);
659
230
            Py_DECREF(v);
660
230
        }
661
230
    }
662
#ifdef MS_WINDOWS
663
    LocalFree(s_buf);
664
#endif
665
230
    return NULL;
666
230
}
667
668
PyObject *
669
PyErr_SetFromErrnoWithFilename(PyObject *exc, const char *filename)
670
0
{
671
0
    PyObject *name = filename ? PyUnicode_DecodeFSDefault(filename) : NULL;
672
0
    PyObject *result = PyErr_SetFromErrnoWithFilenameObjects(exc, name, NULL);
673
0
    Py_XDECREF(name);
674
0
    return result;
675
0
}
676
677
#ifdef MS_WINDOWS
678
PyObject *
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 *
689
PyErr_SetFromErrno(PyObject *exc)
690
0
{
691
0
    return PyErr_SetFromErrnoWithFilenameObjects(exc, NULL, NULL);
692
0
}
693
694
#ifdef MS_WINDOWS
695
/* Windows specific error code handling */
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
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
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
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
802
PyObject *PyErr_SetExcFromWindowsErr(PyObject *exc, int ierr)
803
{
804
    return PyErr_SetExcFromWindowsErrWithFilename(exc, ierr, NULL);
805
}
806
807
PyObject *PyErr_SetFromWindowsErr(int ierr)
808
{
809
    return PyErr_SetExcFromWindowsErrWithFilename(PyExc_OSError,
810
                                                  ierr, NULL);
811
}
812
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
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 *
839
PyErr_SetImportErrorSubclass(PyObject *exception, PyObject *msg,
840
    PyObject *name, PyObject *path)
841
14
{
842
14
    PyThreadState *tstate = _PyThreadState_GET();
843
14
    int issubclass;
844
14
    PyObject *kwargs, *error;
845
846
14
    issubclass = PyObject_IsSubclass(exception, PyExc_ImportError);
847
14
    if (issubclass < 0) {
848
0
        return NULL;
849
0
    }
850
14
    else if (!issubclass) {
851
0
        _PyErr_SetString(tstate, PyExc_TypeError,
852
0
                         "expected a subclass of ImportError");
853
0
        return NULL;
854
0
    }
855
856
14
    if (msg == NULL) {
857
0
        _PyErr_SetString(tstate, PyExc_TypeError,
858
0
                         "expected a message argument");
859
0
        return NULL;
860
0
    }
861
862
14
    if (name == NULL) {
863
0
        name = Py_None;
864
0
    }
865
14
    if (path == NULL) {
866
14
        path = Py_None;
867
14
    }
868
869
14
    kwargs = PyDict_New();
870
14
    if (kwargs == NULL) {
871
0
        return NULL;
872
0
    }
873
14
    if (PyDict_SetItemString(kwargs, "name", name) < 0) {
874
0
        goto done;
875
0
    }
876
14
    if (PyDict_SetItemString(kwargs, "path", path) < 0) {
877
0
        goto done;
878
0
    }
879
880
14
    error = _PyObject_FastCallDict(exception, &msg, 1, kwargs);
881
14
    if (error != NULL) {
882
14
        _PyErr_SetObject(tstate, (PyObject *)Py_TYPE(error), error);
883
14
        Py_DECREF(error);
884
14
    }
885
886
14
done:
887
14
    Py_DECREF(kwargs);
888
14
    return NULL;
889
14
}
890
891
PyObject *
892
PyErr_SetImportError(PyObject *msg, PyObject *name, PyObject *path)
893
14
{
894
14
    return PyErr_SetImportErrorSubclass(PyExc_ImportError, msg, name, path);
895
14
}
896
897
void
898
_PyErr_BadInternalCall(const char *filename, int lineno)
899
0
{
900
0
    PyThreadState *tstate = _PyThreadState_GET();
901
0
    _PyErr_Format(tstate, PyExc_SystemError,
902
0
                  "%s:%d: bad argument to internal function",
903
0
                  filename, lineno);
904
0
}
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
910
PyErr_BadInternalCall(void)
911
0
{
912
0
    assert(0 && "bad argument to internal function");
913
0
    PyThreadState *tstate = _PyThreadState_GET();
914
0
    _PyErr_SetString(tstate, PyExc_SystemError,
915
0
                     "bad argument to internal function");
916
0
}
917
#define PyErr_BadInternalCall() _PyErr_BadInternalCall(__FILE__, __LINE__)
918
919
920
static PyObject *
921
_PyErr_FormatV(PyThreadState *tstate, PyObject *exception,
922
               const char *format, va_list vargs)
923
6.08k
{
924
6.08k
    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
6.08k
    _PyErr_Clear(tstate);
929
930
6.08k
    string = PyUnicode_FromFormatV(format, vargs);
931
932
6.08k
    _PyErr_SetObject(tstate, exception, string);
933
6.08k
    Py_XDECREF(string);
934
6.08k
    return NULL;
935
6.08k
}
936
937
938
PyObject *
939
PyErr_FormatV(PyObject *exception, const char *format, va_list vargs)
940
0
{
941
0
    PyThreadState *tstate = _PyThreadState_GET();
942
0
    return _PyErr_FormatV(tstate, exception, format, vargs);
943
0
}
944
945
946
PyObject *
947
_PyErr_Format(PyThreadState *tstate, PyObject *exception,
948
              const char *format, ...)
949
213
{
950
213
    va_list vargs;
951
213
#ifdef HAVE_STDARG_PROTOTYPES
952
213
    va_start(vargs, format);
953
#else
954
    va_start(vargs);
955
#endif
956
213
    _PyErr_FormatV(tstate, exception, format, vargs);
957
213
    va_end(vargs);
958
213
    return NULL;
959
213
}
960
961
962
PyObject *
963
PyErr_Format(PyObject *exception, const char *format, ...)
964
5.86k
{
965
5.86k
    PyThreadState *tstate = _PyThreadState_GET();
966
5.86k
    va_list vargs;
967
5.86k
#ifdef HAVE_STDARG_PROTOTYPES
968
5.86k
    va_start(vargs, format);
969
#else
970
    va_start(vargs);
971
#endif
972
5.86k
    _PyErr_FormatV(tstate, exception, format, vargs);
973
5.86k
    va_end(vargs);
974
5.86k
    return NULL;
975
5.86k
}
976
977
978
PyObject *
979
PyErr_NewException(const char *name, PyObject *base, PyObject *dict)
980
1
{
981
1
    PyThreadState *tstate = _PyThreadState_GET();
982
1
    _Py_IDENTIFIER(__module__);
983
1
    PyObject *modulename = NULL;
984
1
    PyObject *classname = NULL;
985
1
    PyObject *mydict = NULL;
986
1
    PyObject *bases = NULL;
987
1
    PyObject *result = NULL;
988
989
1
    const char *dot = strrchr(name, '.');
990
1
    if (dot == NULL) {
991
0
        _PyErr_SetString(tstate, PyExc_SystemError,
992
0
                         "PyErr_NewException: name must be module.class");
993
0
        return NULL;
994
0
    }
995
1
    if (base == NULL) {
996
1
        base = PyExc_Exception;
997
1
    }
998
1
    if (dict == NULL) {
999
1
        dict = mydict = PyDict_New();
1000
1
        if (dict == NULL)
1001
0
            goto failure;
1002
1
    }
1003
1004
1
    if (_PyDict_GetItemIdWithError(dict, &PyId___module__) == NULL) {
1005
1
        if (_PyErr_Occurred(tstate)) {
1006
0
            goto failure;
1007
0
        }
1008
1
        modulename = PyUnicode_FromStringAndSize(name,
1009
1
                                             (Py_ssize_t)(dot-name));
1010
1
        if (modulename == NULL)
1011
0
            goto failure;
1012
1
        if (_PyDict_SetItemId(dict, &PyId___module__, modulename) != 0)
1013
0
            goto failure;
1014
1
    }
1015
1
    if (PyTuple_Check(base)) {
1016
0
        bases = base;
1017
        /* INCREF as we create a new ref in the else branch */
1018
0
        Py_INCREF(bases);
1019
1
    } else {
1020
1
        bases = PyTuple_Pack(1, base);
1021
1
        if (bases == NULL)
1022
0
            goto failure;
1023
1
    }
1024
    /* Create a real class. */
1025
1
    result = PyObject_CallFunction((PyObject *)&PyType_Type, "sOO",
1026
1
                                   dot+1, bases, dict);
1027
1
  failure:
1028
1
    Py_XDECREF(bases);
1029
1
    Py_XDECREF(mydict);
1030
1
    Py_XDECREF(classname);
1031
1
    Py_XDECREF(modulename);
1032
1
    return result;
1033
1
}
1034
1035
1036
/* Create an exception with docstring */
1037
PyObject *
1038
PyErr_NewExceptionWithDoc(const char *name, const char *doc,
1039
                          PyObject *base, PyObject *dict)
1040
0
{
1041
0
    int result;
1042
0
    PyObject *ret = NULL;
1043
0
    PyObject *mydict = NULL; /* points to the dict only if we create it */
1044
0
    PyObject *docobj;
1045
1046
0
    if (dict == NULL) {
1047
0
        dict = mydict = PyDict_New();
1048
0
        if (dict == NULL) {
1049
0
            return NULL;
1050
0
        }
1051
0
    }
1052
1053
0
    if (doc != NULL) {
1054
0
        docobj = PyUnicode_FromString(doc);
1055
0
        if (docobj == NULL)
1056
0
            goto failure;
1057
0
        result = PyDict_SetItemString(dict, "__doc__", docobj);
1058
0
        Py_DECREF(docobj);
1059
0
        if (result < 0)
1060
0
            goto failure;
1061
0
    }
1062
1063
0
    ret = PyErr_NewException(name, base, dict);
1064
0
  failure:
1065
0
    Py_XDECREF(mydict);
1066
0
    return ret;
1067
0
}
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
1095
_PyErr_Init(void)
1096
14
{
1097
14
    if (UnraisableHookArgsType.tp_name == NULL) {
1098
14
        if (PyStructSequence_InitType2(&UnraisableHookArgsType,
1099
14
                                       &UnraisableHookArgs_desc) < 0) {
1100
0
            return _PyStatus_ERR("failed to initialize UnraisableHookArgs type");
1101
0
        }
1102
14
    }
1103
14
    return _PyStatus_OK();
1104
14
}
1105
1106
1107
static PyObject *
1108
make_unraisable_hook_args(PyThreadState *tstate, PyObject *exc_type,
1109
                          PyObject *exc_value, PyObject *exc_tb,
1110
                          PyObject *err_msg, PyObject *obj)
1111
0
{
1112
0
    PyObject *args = PyStructSequence_New(&UnraisableHookArgsType);
1113
0
    if (args == NULL) {
1114
0
        return NULL;
1115
0
    }
1116
1117
0
    Py_ssize_t pos = 0;
1118
0
#define ADD_ITEM(exc_type) \
1119
0
        do { \
1120
0
            if (exc_type == NULL) { \
1121
0
                exc_type = Py_None; \
1122
0
            } \
1123
0
            Py_INCREF(exc_type); \
1124
0
            PyStructSequence_SET_ITEM(args, pos++, exc_type); \
1125
0
        } while (0)
1126
1127
1128
0
    ADD_ITEM(exc_type);
1129
0
    ADD_ITEM(exc_value);
1130
0
    ADD_ITEM(exc_tb);
1131
0
    ADD_ITEM(err_msg);
1132
0
    ADD_ITEM(obj);
1133
0
#undef ADD_ITEM
1134
1135
0
    if (_PyErr_Occurred(tstate)) {
1136
0
        Py_DECREF(args);
1137
0
        return NULL;
1138
0
    }
1139
0
    return args;
1140
0
}
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
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
0
{
1154
0
    if (obj != NULL && obj != Py_None) {
1155
0
        if (err_msg != NULL && err_msg != Py_None) {
1156
0
            if (PyFile_WriteObject(err_msg, file, Py_PRINT_RAW) < 0) {
1157
0
                return -1;
1158
0
            }
1159
0
            if (PyFile_WriteString(": ", file) < 0) {
1160
0
                return -1;
1161
0
            }
1162
0
        }
1163
0
        else {
1164
0
            if (PyFile_WriteString("Exception ignored in: ", file) < 0) {
1165
0
                return -1;
1166
0
            }
1167
0
        }
1168
1169
0
        if (PyFile_WriteObject(obj, file, 0) < 0) {
1170
0
            _PyErr_Clear(tstate);
1171
0
            if (PyFile_WriteString("<object repr() failed>", file) < 0) {
1172
0
                return -1;
1173
0
            }
1174
0
        }
1175
0
        if (PyFile_WriteString("\n", file) < 0) {
1176
0
            return -1;
1177
0
        }
1178
0
    }
1179
0
    else if (err_msg != NULL && err_msg != Py_None) {
1180
0
        if (PyFile_WriteObject(err_msg, file, Py_PRINT_RAW) < 0) {
1181
0
            return -1;
1182
0
        }
1183
0
        if (PyFile_WriteString(":\n", file) < 0) {
1184
0
            return -1;
1185
0
        }
1186
0
    }
1187
1188
0
    if (exc_tb != NULL && exc_tb != Py_None) {
1189
0
        if (PyTraceBack_Print(exc_tb, file) < 0) {
1190
            /* continue even if writing the traceback failed */
1191
0
            _PyErr_Clear(tstate);
1192
0
        }
1193
0
    }
1194
1195
0
    if (exc_type == NULL || exc_type == Py_None) {
1196
0
        return -1;
1197
0
    }
1198
1199
0
    assert(PyExceptionClass_Check(exc_type));
1200
0
    const char *className = PyExceptionClass_Name(exc_type);
1201
0
    if (className != NULL) {
1202
0
        const char *dot = strrchr(className, '.');
1203
0
        if (dot != NULL) {
1204
0
            className = dot+1;
1205
0
        }
1206
0
    }
1207
1208
0
    _Py_IDENTIFIER(__module__);
1209
0
    PyObject *moduleName = _PyObject_GetAttrId(exc_type, &PyId___module__);
1210
0
    if (moduleName == NULL || !PyUnicode_Check(moduleName)) {
1211
0
        Py_XDECREF(moduleName);
1212
0
        _PyErr_Clear(tstate);
1213
0
        if (PyFile_WriteString("<unknown>", file) < 0) {
1214
0
            return -1;
1215
0
        }
1216
0
    }
1217
0
    else {
1218
0
        if (!_PyUnicode_EqualToASCIIId(moduleName, &PyId_builtins)) {
1219
0
            if (PyFile_WriteObject(moduleName, file, Py_PRINT_RAW) < 0) {
1220
0
                Py_DECREF(moduleName);
1221
0
                return -1;
1222
0
            }
1223
0
            Py_DECREF(moduleName);
1224
0
            if (PyFile_WriteString(".", file) < 0) {
1225
0
                return -1;
1226
0
            }
1227
0
        }
1228
0
        else {
1229
0
            Py_DECREF(moduleName);
1230
0
        }
1231
0
    }
1232
0
    if (className == NULL) {
1233
0
        if (PyFile_WriteString("<unknown>", file) < 0) {
1234
0
            return -1;
1235
0
        }
1236
0
    }
1237
0
    else {
1238
0
        if (PyFile_WriteString(className, file) < 0) {
1239
0
            return -1;
1240
0
        }
1241
0
    }
1242
1243
0
    if (exc_value && exc_value != Py_None) {
1244
0
        if (PyFile_WriteString(": ", file) < 0) {
1245
0
            return -1;
1246
0
        }
1247
0
        if (PyFile_WriteObject(exc_value, file, Py_PRINT_RAW) < 0) {
1248
0
            _PyErr_Clear(tstate);
1249
0
            if (PyFile_WriteString("<exception str() failed>", file) < 0) {
1250
0
                return -1;
1251
0
            }
1252
0
        }
1253
0
    }
1254
1255
0
    if (PyFile_WriteString("\n", file) < 0) {
1256
0
        return -1;
1257
0
    }
1258
1259
    /* Explicitly call file.flush() */
1260
0
    PyObject *res = _PyObject_CallMethodId(file, &PyId_flush, NULL);
1261
0
    if (!res) {
1262
0
        return -1;
1263
0
    }
1264
0
    Py_DECREF(res);
1265
1266
0
    return 0;
1267
0
}
1268
1269
1270
static int
1271
write_unraisable_exc(PyThreadState *tstate, PyObject *exc_type,
1272
                     PyObject *exc_value, PyObject *exc_tb, PyObject *err_msg,
1273
                     PyObject *obj)
1274
0
{
1275
0
    PyObject *file = _PySys_GetObjectId(&PyId_stderr);
1276
0
    if (file == NULL || file == Py_None) {
1277
0
        return 0;
1278
0
    }
1279
1280
    /* Hold a strong reference to ensure that sys.stderr doesn't go away
1281
       while we use it */
1282
0
    Py_INCREF(file);
1283
0
    int res = write_unraisable_exc_file(tstate, exc_type, exc_value, exc_tb,
1284
0
                                        err_msg, obj, file);
1285
0
    Py_DECREF(file);
1286
1287
0
    return res;
1288
0
}
1289
1290
1291
PyObject*
1292
_PyErr_WriteUnraisableDefaultHook(PyObject *args)
1293
0
{
1294
0
    PyThreadState *tstate = _PyThreadState_GET();
1295
1296
0
    if (Py_TYPE(args) != &UnraisableHookArgsType) {
1297
0
        _PyErr_SetString(tstate, PyExc_TypeError,
1298
0
                         "sys.unraisablehook argument type "
1299
0
                         "must be UnraisableHookArgs");
1300
0
        return NULL;
1301
0
    }
1302
1303
    /* Borrowed references */
1304
0
    PyObject *exc_type = PyStructSequence_GET_ITEM(args, 0);
1305
0
    PyObject *exc_value = PyStructSequence_GET_ITEM(args, 1);
1306
0
    PyObject *exc_tb = PyStructSequence_GET_ITEM(args, 2);
1307
0
    PyObject *err_msg = PyStructSequence_GET_ITEM(args, 3);
1308
0
    PyObject *obj = PyStructSequence_GET_ITEM(args, 4);
1309
1310
0
    if (write_unraisable_exc(tstate, exc_type, exc_value, exc_tb, err_msg, obj) < 0) {
1311
0
        return NULL;
1312
0
    }
1313
0
    Py_RETURN_NONE;
1314
0
}
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
1329
_PyErr_WriteUnraisableMsg(const char *err_msg_str, PyObject *obj)
1330
0
{
1331
0
    PyThreadState *tstate = _PyThreadState_GET();
1332
0
    assert(tstate != NULL);
1333
1334
0
    PyObject *err_msg = NULL;
1335
0
    PyObject *exc_type, *exc_value, *exc_tb;
1336
0
    _PyErr_Fetch(tstate, &exc_type, &exc_value, &exc_tb);
1337
1338
0
    assert(exc_type != NULL);
1339
1340
0
    if (exc_type == NULL) {
1341
        /* sys.unraisablehook requires that at least exc_type is set */
1342
0
        goto default_hook;
1343
0
    }
1344
1345
0
    if (exc_tb == NULL) {
1346
0
        struct _frame *frame = tstate->frame;
1347
0
        if (frame != NULL) {
1348
0
            exc_tb = _PyTraceBack_FromFrame(NULL, frame);
1349
0
            if (exc_tb == NULL) {
1350
0
                _PyErr_Clear(tstate);
1351
0
            }
1352
0
        }
1353
0
    }
1354
1355
0
    _PyErr_NormalizeException(tstate, &exc_type, &exc_value, &exc_tb);
1356
1357
0
    if (exc_tb != NULL && exc_tb != Py_None && PyTraceBack_Check(exc_tb)) {
1358
0
        if (PyException_SetTraceback(exc_value, exc_tb) < 0) {
1359
0
            _PyErr_Clear(tstate);
1360
0
        }
1361
0
    }
1362
1363
0
    if (err_msg_str != NULL) {
1364
0
        err_msg = PyUnicode_FromFormat("Exception ignored %s", err_msg_str);
1365
0
        if (err_msg == NULL) {
1366
0
            PyErr_Clear();
1367
0
        }
1368
0
    }
1369
1370
0
    PyObject *hook_args = make_unraisable_hook_args(
1371
0
        tstate, exc_type, exc_value, exc_tb, err_msg, obj);
1372
0
    if (hook_args == NULL) {
1373
0
        err_msg_str = ("Exception ignored on building "
1374
0
                       "sys.unraisablehook arguments");
1375
0
        goto error;
1376
0
    }
1377
1378
0
    _Py_IDENTIFIER(unraisablehook);
1379
0
    PyObject *hook = _PySys_GetObjectId(&PyId_unraisablehook);
1380
0
    if (hook == NULL) {
1381
0
        Py_DECREF(hook_args);
1382
0
        goto default_hook;
1383
0
    }
1384
1385
0
    if (PySys_Audit("sys.unraisablehook", "OO", hook, hook_args) < 0) {
1386
0
        Py_DECREF(hook_args);
1387
0
        err_msg_str = "Exception ignored in audit hook";
1388
0
        obj = NULL;
1389
0
        goto error;
1390
0
    }
1391
1392
0
    if (hook == Py_None) {
1393
0
        Py_DECREF(hook_args);
1394
0
        goto default_hook;
1395
0
    }
1396
1397
0
    PyObject *args[1] = {hook_args};
1398
0
    PyObject *res = _PyObject_FastCall(hook, args, 1);
1399
0
    Py_DECREF(hook_args);
1400
0
    if (res != NULL) {
1401
0
        Py_DECREF(res);
1402
0
        goto done;
1403
0
    }
1404
1405
    /* sys.unraisablehook failed: log its error using default hook */
1406
0
    obj = hook;
1407
0
    err_msg_str = NULL;
1408
1409
0
error:
1410
    /* err_msg_str and obj have been updated and we have a new exception */
1411
0
    Py_XSETREF(err_msg, PyUnicode_FromString(err_msg_str ?
1412
0
        err_msg_str : "Exception ignored in sys.unraisablehook"));
1413
0
    Py_XDECREF(exc_type);
1414
0
    Py_XDECREF(exc_value);
1415
0
    Py_XDECREF(exc_tb);
1416
0
    _PyErr_Fetch(tstate, &exc_type, &exc_value, &exc_tb);
1417
1418
0
default_hook:
1419
    /* Call the default unraisable hook (ignore failure) */
1420
0
    (void)write_unraisable_exc(tstate, exc_type, exc_value, exc_tb,
1421
0
                               err_msg, obj);
1422
1423
0
done:
1424
0
    Py_XDECREF(exc_type);
1425
0
    Py_XDECREF(exc_value);
1426
0
    Py_XDECREF(exc_tb);
1427
0
    Py_XDECREF(err_msg);
1428
0
    _PyErr_Clear(tstate); /* Just in case */
1429
0
}
1430
1431
1432
void
1433
PyErr_WriteUnraisable(PyObject *obj)
1434
0
{
1435
0
    _PyErr_WriteUnraisableMsg(NULL, obj);
1436
0
}
1437
1438
1439
extern PyObject *PyModule_GetWarningsModule(void);
1440
1441
1442
void
1443
PyErr_SyntaxLocation(const char *filename, int lineno)
1444
0
{
1445
0
    PyErr_SyntaxLocationEx(filename, lineno, -1);
1446
0
}
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
1454
PyErr_SyntaxLocationObject(PyObject *filename, int lineno, int col_offset)
1455
0
{
1456
0
    PyObject *exc, *v, *tb, *tmp;
1457
0
    _Py_IDENTIFIER(filename);
1458
0
    _Py_IDENTIFIER(lineno);
1459
0
    _Py_IDENTIFIER(msg);
1460
0
    _Py_IDENTIFIER(offset);
1461
0
    _Py_IDENTIFIER(print_file_and_line);
1462
0
    _Py_IDENTIFIER(text);
1463
0
    PyThreadState *tstate = _PyThreadState_GET();
1464
1465
    /* add attributes for the line number and filename for the error */
1466
0
    _PyErr_Fetch(tstate, &exc, &v, &tb);
1467
0
    _PyErr_NormalizeException(tstate, &exc, &v, &tb);
1468
    /* XXX check that it is, indeed, a syntax error. It might not
1469
     * be, though. */
1470
0
    tmp = PyLong_FromLong(lineno);
1471
0
    if (tmp == NULL)
1472
0
        _PyErr_Clear(tstate);
1473
0
    else {
1474
0
        if (_PyObject_SetAttrId(v, &PyId_lineno, tmp)) {
1475
0
            _PyErr_Clear(tstate);
1476
0
        }
1477
0
        Py_DECREF(tmp);
1478
0
    }
1479
0
    tmp = NULL;
1480
0
    if (col_offset >= 0) {
1481
0
        tmp = PyLong_FromLong(col_offset);
1482
0
        if (tmp == NULL) {
1483
0
            _PyErr_Clear(tstate);
1484
0
        }
1485
0
    }
1486
0
    if (_PyObject_SetAttrId(v, &PyId_offset, tmp ? tmp : Py_None)) {
1487
0
        _PyErr_Clear(tstate);
1488
0
    }
1489
0
    Py_XDECREF(tmp);
1490
0
    if (filename != NULL) {
1491
0
        if (_PyObject_SetAttrId(v, &PyId_filename, filename)) {
1492
0
            _PyErr_Clear(tstate);
1493
0
        }
1494
1495
0
        tmp = PyErr_ProgramTextObject(filename, lineno);
1496
0
        if (tmp) {
1497
0
            if (_PyObject_SetAttrId(v, &PyId_text, tmp)) {
1498
0
                _PyErr_Clear(tstate);
1499
0
            }
1500
0
            Py_DECREF(tmp);
1501
0
        }
1502
0
    }
1503
0
    if (exc != PyExc_SyntaxError) {
1504
0
        if (!_PyObject_HasAttrId(v, &PyId_msg)) {
1505
0
            tmp = PyObject_Str(v);
1506
0
            if (tmp) {
1507
0
                if (_PyObject_SetAttrId(v, &PyId_msg, tmp)) {
1508
0
                    _PyErr_Clear(tstate);
1509
0
                }
1510
0
                Py_DECREF(tmp);
1511
0
            }
1512
0
            else {
1513
0
                _PyErr_Clear(tstate);
1514
0
            }
1515
0
        }
1516
0
        if (!_PyObject_HasAttrId(v, &PyId_print_file_and_line)) {
1517
0
            if (_PyObject_SetAttrId(v, &PyId_print_file_and_line,
1518
0
                                    Py_None)) {
1519
0
                _PyErr_Clear(tstate);
1520
0
            }
1521
0
        }
1522
0
    }
1523
0
    _PyErr_Restore(tstate, exc, v, tb);
1524
0
}
1525
1526
void
1527
PyErr_SyntaxLocationEx(const char *filename, int lineno, int col_offset)
1528
0
{
1529
0
    PyThreadState *tstate = _PyThreadState_GET();
1530
0
    PyObject *fileobj;
1531
0
    if (filename != NULL) {
1532
0
        fileobj = PyUnicode_DecodeFSDefault(filename);
1533
0
        if (fileobj == NULL) {
1534
0
            _PyErr_Clear(tstate);
1535
0
        }
1536
0
    }
1537
0
    else {
1538
0
        fileobj = NULL;
1539
0
    }
1540
0
    PyErr_SyntaxLocationObject(fileobj, lineno, col_offset);
1541
0
    Py_XDECREF(fileobj);
1542
0
}
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 *
1551
err_programtext(PyThreadState *tstate, FILE *fp, int lineno)
1552
0
{
1553
0
    int i;
1554
0
    char linebuf[1000];
1555
1556
0
    if (fp == NULL)
1557
0
        return NULL;
1558
0
    for (i = 0; i < lineno; i++) {
1559
0
        char *pLastChar = &linebuf[sizeof(linebuf) - 2];
1560
0
        do {
1561
0
            *pLastChar = '\0';
1562
0
            if (Py_UniversalNewlineFgets(linebuf, sizeof linebuf,
1563
0
                                         fp, NULL) == NULL)
1564
0
                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
0
        } while (*pLastChar != '\0' && *pLastChar != '\n');
1571
0
    }
1572
0
    fclose(fp);
1573
0
    if (i == lineno) {
1574
0
        PyObject *res;
1575
0
        res = PyUnicode_FromString(linebuf);
1576
0
        if (res == NULL)
1577
0
            _PyErr_Clear(tstate);
1578
0
        return res;
1579
0
    }
1580
0
    return NULL;
1581
0
}
1582
1583
PyObject *
1584
PyErr_ProgramText(const char *filename, int lineno)
1585
0
{
1586
0
    FILE *fp;
1587
0
    if (filename == NULL || *filename == '\0' || lineno <= 0) {
1588
0
        return NULL;
1589
0
    }
1590
0
    PyThreadState *tstate = _PyThreadState_GET();
1591
0
    fp = _Py_fopen(filename, "r" PY_STDIOTEXTMODE);
1592
0
    return err_programtext(tstate, fp, lineno);
1593
0
}
1594
1595
PyObject *
1596
PyErr_ProgramTextObject(PyObject *filename, int lineno)
1597
0
{
1598
0
    if (filename == NULL || lineno <= 0) {
1599
0
        return NULL;
1600
0
    }
1601
1602
0
    PyThreadState *tstate = _PyThreadState_GET();
1603
0
    FILE *fp = _Py_fopen_obj(filename, "r" PY_STDIOTEXTMODE);
1604
0
    if (fp == NULL) {
1605
0
        _PyErr_Clear(tstate);
1606
0
        return NULL;
1607
0
    }
1608
0
    return err_programtext(tstate, fp, lineno);
1609
0
}
1610
1611
#ifdef __cplusplus
1612
}
1613
#endif