aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/Python/traceback.c
diff options
context:
space:
mode:
authorBénédikt Tran <10796600+picnixz@users.noreply.github.com>2025-01-27 15:07:39 +0100
committerGitHub <noreply@github.com>2025-01-27 15:07:39 +0100
commitced296d2c0483ad74988b263921917f107a1da04 (patch)
tree514a7bf84873c0e7321f1e375ce2470c86f5fd5d /Python/traceback.c
parent6bb03c74907492f2315f39a342e1e47bbd5e1a56 (diff)
downloadcpython-ced296d2c0483ad74988b263921917f107a1da04.tar.gz
cpython-ced296d2c0483ad74988b263921917f107a1da04.zip
gh-111178: fix UBSan failures in `Python/traceback.c` (GH-128259)
Diffstat (limited to 'Python/traceback.c')
-rw-r--r--Python/traceback.c42
1 files changed, 26 insertions, 16 deletions
diff --git a/Python/traceback.c b/Python/traceback.c
index 62387f12392..870ae5bcefe 100644
--- a/Python/traceback.c
+++ b/Python/traceback.c
@@ -38,6 +38,8 @@ class traceback "PyTracebackObject *" "&PyTraceback_Type"
[clinic start generated code]*/
/*[clinic end generated code: output=da39a3ee5e6b4b0d input=cf96294b2bebc811]*/
+#define _PyTracebackObject_CAST(op) ((PyTracebackObject *)(op))
+
#include "clinic/traceback.c.h"
static PyObject *
@@ -91,15 +93,16 @@ tb_new_impl(PyTypeObject *type, PyObject *tb_next, PyFrameObject *tb_frame,
}
static PyObject *
-tb_dir(PyTracebackObject *self, PyObject *Py_UNUSED(ignored))
+tb_dir(PyObject *Py_UNUSED(self), PyObject *Py_UNUSED(ignored))
{
return Py_BuildValue("[ssss]", "tb_frame", "tb_next",
"tb_lasti", "tb_lineno");
}
static PyObject *
-tb_next_get(PyTracebackObject *self, void *Py_UNUSED(_))
+tb_next_get(PyObject *op, void *Py_UNUSED(_))
{
+ PyTracebackObject *self = _PyTracebackObject_CAST(op);
PyObject* ret = (PyObject*)self->tb_next;
if (!ret) {
ret = Py_None;
@@ -108,18 +111,21 @@ tb_next_get(PyTracebackObject *self, void *Py_UNUSED(_))
}
static int
-tb_get_lineno(PyTracebackObject* tb) {
+tb_get_lineno(PyObject *op)
+{
+ PyTracebackObject *tb = _PyTracebackObject_CAST(op);
_PyInterpreterFrame* frame = tb->tb_frame->f_frame;
assert(frame != NULL);
return PyCode_Addr2Line(_PyFrame_GetCode(frame), tb->tb_lasti);
}
static PyObject *
-tb_lineno_get(PyTracebackObject *self, void *Py_UNUSED(_))
+tb_lineno_get(PyObject *op, void *Py_UNUSED(_))
{
+ PyTracebackObject *self = _PyTracebackObject_CAST(op);
int lineno = self->tb_lineno;
if (lineno == -1) {
- lineno = tb_get_lineno(self);
+ lineno = tb_get_lineno(op);
if (lineno < 0) {
Py_RETURN_NONE;
}
@@ -128,7 +134,7 @@ tb_lineno_get(PyTracebackObject *self, void *Py_UNUSED(_))
}
static int
-tb_next_set(PyTracebackObject *self, PyObject *new_next, void *Py_UNUSED(_))
+tb_next_set(PyObject *op, PyObject *new_next, void *Py_UNUSED(_))
{
if (!new_next) {
PyErr_Format(PyExc_TypeError, "can't delete tb_next attribute");
@@ -147,6 +153,7 @@ tb_next_set(PyTracebackObject *self, PyObject *new_next, void *Py_UNUSED(_))
}
/* Check for loops */
+ PyTracebackObject *self = _PyTracebackObject_CAST(op);
PyTracebackObject *cursor = (PyTracebackObject *)new_next;
while (cursor) {
if (cursor == self) {
@@ -163,7 +170,7 @@ tb_next_set(PyTracebackObject *self, PyObject *new_next, void *Py_UNUSED(_))
static PyMethodDef tb_methods[] = {
- {"__dir__", _PyCFunction_CAST(tb_dir), METH_NOARGS},
+ {"__dir__", tb_dir, METH_NOARGS, NULL},
{NULL, NULL, 0, NULL},
};
@@ -174,14 +181,15 @@ static PyMemberDef tb_memberlist[] = {
};
static PyGetSetDef tb_getsetters[] = {
- {"tb_next", (getter)tb_next_get, (setter)tb_next_set, NULL, NULL},
- {"tb_lineno", (getter)tb_lineno_get, NULL, NULL, NULL},
+ {"tb_next", tb_next_get, tb_next_set, NULL, NULL},
+ {"tb_lineno", tb_lineno_get, NULL, NULL, NULL},
{NULL} /* Sentinel */
};
static void
-tb_dealloc(PyTracebackObject *tb)
+tb_dealloc(PyObject *op)
{
+ PyTracebackObject *tb = _PyTracebackObject_CAST(op);
PyObject_GC_UnTrack(tb);
Py_TRASHCAN_BEGIN(tb, tb_dealloc)
Py_XDECREF(tb->tb_next);
@@ -191,16 +199,18 @@ tb_dealloc(PyTracebackObject *tb)
}
static int
-tb_traverse(PyTracebackObject *tb, visitproc visit, void *arg)
+tb_traverse(PyObject *op, visitproc visit, void *arg)
{
+ PyTracebackObject *tb = _PyTracebackObject_CAST(op);
Py_VISIT(tb->tb_next);
Py_VISIT(tb->tb_frame);
return 0;
}
static int
-tb_clear(PyTracebackObject *tb)
+tb_clear(PyObject *op)
{
+ PyTracebackObject *tb = _PyTracebackObject_CAST(op);
Py_CLEAR(tb->tb_next);
Py_CLEAR(tb->tb_frame);
return 0;
@@ -211,7 +221,7 @@ PyTypeObject PyTraceBack_Type = {
"traceback",
sizeof(PyTracebackObject),
0,
- (destructor)tb_dealloc, /*tp_dealloc*/
+ tb_dealloc, /*tp_dealloc*/
0, /*tp_vectorcall_offset*/
0, /*tp_getattr*/
0, /*tp_setattr*/
@@ -228,8 +238,8 @@ PyTypeObject PyTraceBack_Type = {
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */
tb_new__doc__, /* tp_doc */
- (traverseproc)tb_traverse, /* tp_traverse */
- (inquiry)tb_clear, /* tp_clear */
+ tb_traverse, /* tp_traverse */
+ tb_clear, /* tp_clear */
0, /* tp_richcompare */
0, /* tp_weaklistoffset */
0, /* tp_iter */
@@ -663,7 +673,7 @@ tb_printinternal(PyTracebackObject *tb, PyObject *f, long limit)
code = PyFrame_GetCode(tb->tb_frame);
int tb_lineno = tb->tb_lineno;
if (tb_lineno == -1) {
- tb_lineno = tb_get_lineno(tb);
+ tb_lineno = tb_get_lineno((PyObject *)tb);
}
if (last_file == NULL ||
code->co_filename != last_file ||