8000 fix UBSan failures for `PyBaseExceptionObject` · python/cpython@2683a25 · GitHub
[go: up one dir, main page]

Skip to content

Commit 2683a25

Browse files
committed
fix UBSan failures for PyBaseExceptionObject
1 parent 2a66dd3 commit 2683a25

File tree

1 file changed

+64
-52
lines changed

1 file changed

+64
-52
lines changed

Objects/exceptions.c

Lines changed: 64 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,13 @@ get_exc_state(void)
3737
* Lib/test/exception_hierarchy.txt
3838
*/
3939

40+
static inline PyBaseExceptionObject *
41+
_PyBaseExceptionObject_CAST(PyObject *exc)
42+
{
43+
assert(PyExceptionInstance_Check(exc));
44+
return (PyBaseExceptionObject *)exc;
45+
}
46+
4047
/*
4148
* BaseException
4249
*/
@@ -69,8 +76,9 @@ BaseException_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
6976
}
7077

7178
static int
72-
BaseException_init(PyBaseExceptionObject *self, PyObject *args, PyObject *kwds)
79+
BaseException_init(PyObject *op, PyObject *args, PyObject *kwds)
7380
{
81+
PyBaseExceptionObject *self = _PyBaseExceptionObject_CAST(op);
7482
if (!_PyArg_NoKeywords(Py_TYPE(self)->tp_name, kwds))
7583
return -1;
7684

@@ -113,8 +121,9 @@ BaseException_vectorcall(PyObject *type_obj, PyObject * const*args,
113121

114122

115123
static int
116-
BaseException_clear(PyBaseExceptionObject *self)
124+
BaseException_clear(PyObject *op)
117125
{
126+
PyBaseExceptionObject *self = _PyBaseExceptionObject_CAST(op);
118127
Py_CLEAR(self->dict);
119128
Py_CLEAR(self->args);
120129
Py_CLEAR(self->notes);
@@ -125,21 +134,23 @@ BaseException_clear(PyBaseExceptionObject *self)
125134
}
126135

127136
static void
128-
BaseException_dealloc(PyBaseExceptionObject *self)
137+
BaseException_dealloc(PyObject *op)
129138
{
139+
PyBaseExceptionObject *self = _PyBaseExceptionObject_CAST(op);
130140
PyObject_GC_UnTrack(self);
131141
// bpo-44348: The trashcan mechanism prevents stack overflow when deleting
132142
// long chains of exceptions. For example, exceptions can be chained
133143
// through the __context__ attributes or the __traceback__ attribute.
134144
Py_TRASHCAN_BEGIN(self, BaseException_dealloc)
135-
BaseException_clear(self);
136-
Py_TYPE(self)->tp_free((PyObject *)self);
145+
(void)BaseException_clear(op);
146+
Py_TYPE(self)->tp_free(self);
137147
Py_TRASHCAN_END
138148
}
139149

140150
static int
141-
BaseException_traverse(PyBaseExceptionObject *self, visitproc visit, void *arg)
151+
BaseException_traverse(PyObject *op, visitproc visit, void *arg)
142152
{
153+
PyBaseExceptionObject *self = _PyBaseExceptionObject_CAST(op);
143154
Py_VISIT(self->dict);
144155
Py_VISIT(self->args);
145156
Py_VISIT(self->notes);
@@ -150,8 +161,9 @@ BaseException_traverse(PyBaseExceptionObject *self, visitproc visit, void *arg)
150161
}
151162

152163
static PyObject *
153-
BaseException_str(PyBaseExceptionObject *self)
164+
BaseException_str(PyObject *op)
154165
{
166+
PyBaseExceptionObject *self = _PyBaseExceptionObject_CAST(op);
155167
switch (PyTuple_GET_SIZE(self->args)) {
156168
case 0:
157169
return Py_GetConstant(Py_CONSTANT_EMPTY_STR);
@@ -163,8 +175,9 @@ BaseException_str(PyBaseExceptionObject *self)
163175
}
164176

165177
static PyObject *
166-
BaseException_repr(PyBaseExceptionObject *self)
178+
BaseException_repr(PyObject *op)
167179
{
180+
PyBaseExceptionObject *self = _PyBaseExceptionObject_CAST(op);
168181
const char *name = _PyType_Name(Py_TYPE(self));
169182
if (PyTuple_GET_SIZE(self->args) == 1)
170183
return PyUnicode_FromFormat("%s(%R)", name,
@@ -175,8 +188,9 @@ BaseException_repr(PyBaseExceptionObject *self)
175188

176189
/* Pickling support */
177190
static PyObject *
178-
BaseException_reduce(PyBaseExceptionObject *self, PyObject *Py_UNUSED(ignored))
191+
BaseException_reduce(PyObject *op, PyObject *Py_UNUSED(ignored))
179192
{
193+
PyBaseExceptionObject *self = _PyBaseExceptionObject_CAST(op);
180194
if (self->args && self->dict)
181195
return PyTuple_Pack(3, Py_TYPE(self), self->args, self->dict);
182196
else
@@ -225,13 +239,6 @@ PyDoc_STRVAR(with_traceback_doc,
225239
"Exception.with_traceback(tb) --\n\
226240
set self.__traceback__ to tb and return self.");
227241

228-
static inline PyBaseExceptionObject*
229-
_PyBaseExceptionObject_cast(PyObject *exc)
230-
{
231-
assert(PyExceptionInstance_Check(exc));
232-
return (PyBaseExceptionObject *)exc;
233-
}
234-
235242
static PyObject *
236243
BaseException_add_note(PyObject *self, PyObject *note)
237244
{
@@ -274,26 +281,26 @@ PyDoc_STRVAR(add_note_doc,
274281
add a note to the exception");
275282

276283
static PyMethodDef BaseException_methods[] = {
277-
{"__reduce__", (PyCFunction)BaseException_reduce, METH_NOARGS },
278-
{"__setstate__", (PyCFunction)BaseException_setstate, METH_O },
279-
{"with_traceback", (PyCFunction)BaseException_with_traceback, METH_O,
284+
{"__reduce__", BaseException_reduce, METH_NOARGS},
285+
{"__setstate__", BaseException_setstate, METH_O},
286+
{"with_traceback", BaseException_with_traceback, METH_O,
280287
with_traceback_doc},
281-
{"add_note", (PyCFunction)BaseException_add_note, METH_O,
282-
add_note_doc},
288+
{"add_note", BaseException_add_note, METH_O, add_note_doc},
283289
{NULL, NULL, 0, NULL},
284290
};
285291

286292
static PyObject *
287-
BaseException_get_args(PyBaseExceptionObject *self, void *Py_UNUSED(ignored))
293+
BaseException_get_args(PyObject *op, void *Py_UNUSED(ignored))
288294
{
295+
PyBaseExceptionObject *self = _PyBaseExceptionObject_CAST(op);
289296
if (self->args == NULL) {
290297
Py_RETURN_NONE;
291298
}
292299
return Py_NewRef(self->args);
293300
}
294301

295302
static int
296-
BaseException_set_args(PyBaseExceptionObject *self, PyObject *val, void *Py_UNUSED(ignored))
303+
BaseException_set_args(PyObject *op, PyObject *val, void *Py_UNUSED(ignored))
297304
{
298305
PyObject *seq;
299306
if (val == NULL) {
@@ -303,22 +310,25 @@ BaseException_set_args(PyBaseExceptionObject *self, PyObject *val, void *Py_UNUS
303310
seq = PySequence_Tuple(val);
304311
if (!seq)
305312
return -1;
313+
PyBaseExceptionObject *self = _PyBaseExceptionObject_CAST(op);
306314
Py_XSETREF(self->args, seq);
307315
return 0;
308316
}
309317

310318
static PyObject *
311-
BaseException_get_tb(PyBaseExceptionObject *self, void *Py_UNUSED(ignored))
319+
BaseException_get_tb(PyObject *op, void *Py_UNUSED(ignored))
312320
{
321+
PyBaseExceptionObject *self = _PyBaseExceptionObject_CAST(op);
313322
if (self->traceback == NULL) {
314323
Py_RETURN_NONE;
315324
}
316325
return Py_NewRef(self->traceback);
317326
}
318327

319328
static int
320-
BaseException_set_tb(PyBaseExceptionObject *self, PyObject *tb, void *Py_UNUSED(ignored))
329+
BaseException_set_tb(PyObject *op, PyObject *tb, void *Py_UNUSED(ignored))
321330
{
331+
PyBaseExceptionObject *self = _PyBaseExceptionObject_CAST(op);
322332
if (tb == NULL) {
323333
PyErr_SetString(PyExc_TypeError, "__traceback__ may not be deleted");
324334
return -1;
@@ -398,8 +408,8 @@ BaseException_set_cause(PyObject *self, PyObject *arg, void *Py_UNUSED(ignored))
398408

399409
static PyGetSetDef BaseException_getset[] = {
400410
{"__dict__", PyObject_GenericGetDict, PyObject_GenericSetDict},
401-
{"args", (getter)BaseException_get_args, (setter)BaseException_set_args},
402-
{"__traceback__", (getter)BaseException_get_tb, (setter)BaseException_set_tb},
411+
{"args", BaseException_get_args, BaseException_set_args},
412+
{"__traceback__", BaseException_get_tb, BaseException_set_tb},
403413
{"__context__", BaseException_get_context,
404414
BaseException_set_context, PyDoc_STR("exception context")},
405415
{"__cause__", BaseException_get_cause,
@@ -411,59 +421,61 @@ static PyGetSetDef BaseException_getset[] = {
411421
PyObject *
412422
PyException_GetTraceback(PyObject *self)
413423
{
414-
PyBaseExceptionObject *base_self = _PyBaseExceptionObject_cast(self);
415-
return Py_XNewRef(base_self->traceback);
424+
PyBaseExceptionObject *exc = _PyBaseExceptionObject_CAST(self);
425+
return Py_XNewRef(exc->traceback);
416426
}
417427

418428

419429
int
420430
PyException_SetTraceback(PyObject *self, PyObject *tb)
421431
{
422-
return BaseException_set_tb(_PyBaseExceptionObject_cast(self), tb, NULL);
432+
return BaseException_set_tb(self, tb, NULL);
423433
}
424434

425435
PyObject *
426436
PyException_GetCause(PyObject *self)
427437
{
428-
PyObject *cause = _PyBaseExceptionObject_cast(self)->cause;
429-
return Py_XNewRef(cause);
438+
PyBaseExceptionObject *exc = _PyBaseExceptionObject_CAST(self);
439+
return Py_XNewRef(exc->cause);
430440
}
431441

432442
/* Steals a reference to cause */
433443
void
434444
PyException_SetCause(PyObject *self, PyObject *cause)
435445
{
436-
PyBaseExceptionObject *base_self = _PyBaseExceptionObject_cast(self);
437-
base_self->suppress_context = 1;
438-
Py_XSETREF(base_self->cause, cause);
446+
PyBaseExceptionObject *exc = _PyBaseExceptionObject_CAST(self);
447+
exc->suppress_context = 1;
448+
Py_XSETREF(exc->cause, cause);
439449
}
440450

441451
PyObject *
442452
PyException_GetContext(PyObject *self)
443453
{
444-
PyObject *context = _PyBaseExceptionObject_cast(self)->context;
445-
return Py_XNewRef(context);
454+
PyBaseExceptionObject *exc = _PyBaseExceptionObject_CAST(self);
455+
return Py_XNewRef(exc->context);
446456
}
447457

448458
/* Steals a reference to context */
449459
void
450460
PyException_SetContext(PyObject *self, PyObject *context)
451461
{
452-
Py_XSETREF(_PyBaseExceptionObject_cast(self)->context, context);
462+
PyBaseExceptionObject *exc = _PyBaseExceptionObject_CAST(self);
463+
Py_XSETREF(exc->context, context);
453464
}
454465

455466
PyObject *
456467
PyException_GetArgs(PyObject *self)
457468
{
458-
PyObject *args = _PyBaseExceptionObject_cast(self)->args;
459-
return Py_NewRef(args);
469+
PyBaseExceptionObject *exc = _PyBaseExceptionObject_CAST(self);
470+
return Py_NewRef(exc->args);
460471
}
461472

462473
void
463474
PyException_SetArgs(PyObject *self, PyObject *args)
464475
{
465476
Py_INCREF(args);
466-
Py_XSETREF(_PyBaseExceptionObject_cast(self)->args, args);
477+
PyBaseExceptionObject *exc = _PyBaseExceptionObject_CAST(self);
478+
Py_XSETREF(exc->args, args);
467479
}
468480

469481
const char *
@@ -485,26 +497,26 @@ static PyTypeObject _PyExc_BaseException = {
485497
"BaseException", /*tp_name*/
486498
sizeof(PyBaseExceptionObject), /*tp_basicsize*/
487499
0, /*tp_itemsize*/
488-
(destructor)BaseException_dealloc, /*tp_dealloc*/
500+
BaseException_dealloc, /*tp_dealloc*/
489501
0, /*tp_vectorcall_offset*/
490502
0, /*tp_getattr*/
491503
0, /*tp_setattr*/
492504
0, /*tp_as_async*/
493-
(reprfunc)BaseException_repr, /*tp_repr*/
505+
BaseException_repr, /*tp_repr*/
494506
0, /*tp_as_number*/
495507
0, /*tp_as_sequence*/
496508
0, /*tp_as_mapping*/
497509
0, /*tp_hash */
498510
0, /*tp_call*/
499-
(reprfunc)BaseException_str, /*tp_str*/
511+
BaseException_str, /*tp_str*/
500512
PyObject_GenericGetAttr, /*tp_getattro*/
501513
PyObject_GenericSetAttr, /*tp_setattro*/
502514
0, /*tp_as_buffer*/
503515
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC |
504516
Py_TPFLAGS_BASE_EXC_SUBCLASS, /*tp_flags*/
505517
PyDoc_STR("Common base class for all exceptions"), /* tp_doc */
506-
(traverseproc)BaseException_traverse, /* tp_traverse */
507-
(inquiry)BaseException_clear, /* tp_clear */
518+
BaseException_traverse, /* tp_traverse */
519+
BaseException_clear, /* tp_clear */
508520
0, /* tp_richcompare */
509521
0, /* tp_weaklistoffset */
510522
0, /* tp_iter */
@@ -517,7 +529,7 @@ static PyTypeObject _PyExc_BaseException = {
517529
0, /* tp_descr_get */
518530
0, /* tp_descr_set */
519531
offsetof(PyBaseExceptionObject, dict), /* tp_dictoffset */
520-
(initproc)BaseException_init, /* tp_init */
532+
BaseException_init, /* tp_init */
521533
0, /* tp_alloc */
522534
BaseException_new, /* tp_new */
523535
.tp_vectorcall = BaseException_vectorcall,
@@ -535,13 +547,13 @@ static PyTypeObject _PyExc_ ## EXCNAME = { \
535547
PyVarObject_HEAD_INIT(NULL, 0) \
536548
# EXCNAME, \
537549
sizeof(PyBaseExceptionObject), \
538-
0, (destructor)BaseException_dealloc, 0, 0, 0, 0, 0, 0, 0, \
550+
0, BaseException_dealloc, 0, 0, 0, 0, 0, 0, 0, \
539551
0, 0, 0, 0, 0, 0, 0, \
540552
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, \
541-
PyDoc_STR(EXCDOC), (traverseproc)BaseException_traverse, \
542-
(inquiry)BaseException_clear, 0, 0, 0, 0, 0, 0, 0, &_ ## EXCBASE, \
553+
PyDoc_STR(EXCDOC), BaseException_traverse, \
554+
BaseException_clear, 0, 0, 0, 0, 0, 0, 0, &_ ## EXCBASE, \
543555
0, 0, 0, offsetof(PyBaseExceptionObject, dict), \
544-
(initproc)BaseException_init, 0, BaseException_new,\
556+
BaseException_init, 0, BaseException_new,\
545557
}; \
546558
PyObject *PyExc_ ## EXCNAME = (PyObject *)&_PyExc_ ## EXCNAME
547559

@@ -1378,7 +1390,7 @@ _PyExc_PrepReraiseStar(PyObject *orig, PyObject *excs)
13781390
{
13791391
/* orig must be a raised & caught exception, so it has a traceback */
13801392
assert(PyExceptionInstance_Check(orig));
1381-
assert(_PyBaseExceptionObject_cast(orig)->traceback != NULL);
1393+
assert(_PyBaseExceptionObject_CAST(orig)->traceback != NULL);
13821394

13831395
assert(PyList_Check(excs));
13841396

0 commit comments

Comments
 (0)
0