gh-111178: fix UBSan failures in Objects/capsule.c (GH-128239)

fix UBSan failures for `PyCapsule`
This commit is contained in:
Bénédikt Tran 2025-01-08 14:55:04 +01:00 committed by GitHub
parent 1da0901894
commit 845d924efb
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -18,6 +18,8 @@ typedef struct {
} PyCapsule; } PyCapsule;
#define _PyCapsule_CAST(op) ((PyCapsule *)(op))
static int static int
_is_legal_capsule(PyObject *op, const char *invalid_capsule) _is_legal_capsule(PyObject *op, const char *invalid_capsule)
@ -284,7 +286,7 @@ EXIT:
static void static void
capsule_dealloc(PyObject *op) capsule_dealloc(PyObject *op)
{ {
PyCapsule *capsule = (PyCapsule *)op; PyCapsule *capsule = _PyCapsule_CAST(op);
PyObject_GC_UnTrack(op); PyObject_GC_UnTrack(op);
if (capsule->destructor) { if (capsule->destructor) {
capsule->destructor(op); capsule->destructor(op);
@ -296,7 +298,7 @@ capsule_dealloc(PyObject *op)
static PyObject * static PyObject *
capsule_repr(PyObject *o) capsule_repr(PyObject *o)
{ {
PyCapsule *capsule = (PyCapsule *)o; PyCapsule *capsule = _PyCapsule_CAST(o);
const char *name; const char *name;
const char *quote; const char *quote;
@ -314,28 +316,27 @@ capsule_repr(PyObject *o)
static int static int
capsule_traverse(PyCapsule *capsule, visitproc visit, void *arg) capsule_traverse(PyObject *self, visitproc visit, void *arg)
{ {
// Capsule object is only tracked by the GC // Capsule object is only tracked by the GC
// if _PyCapsule_SetTraverse() is called, but // if _PyCapsule_SetTraverse() is called, but
// this can still be manually triggered by gc.get_referents() // this can still be manually triggered by gc.get_referents()
PyCapsule *capsule = _PyCapsule_CAST(self);
if (capsule->traverse_func != NULL) { if (capsule->traverse_func != NULL) {
return capsule->traverse_func((PyObject*)capsule, visit, arg); return capsule->traverse_func(self, visit, arg);
} }
return 0; return 0;
} }
static int static int
capsule_clear(PyCapsule *capsule) capsule_clear(PyObject *self)
{ {
// Capsule object is only tracked by the GC // Capsule object is only tracked by the GC
// if _PyCapsule_SetTraverse() is called // if _PyCapsule_SetTraverse() is called
PyCapsule *capsule = _PyCapsule_CAST(self);
assert(capsule->clear_func != NULL); assert(capsule->clear_func != NULL);
return capsule->clear_func(self);
return capsule->clear_func((PyObject*)capsule);
} }
@ -358,8 +359,8 @@ PyTypeObject PyCapsule_Type = {
.tp_dealloc = capsule_dealloc, .tp_dealloc = capsule_dealloc,
.tp_repr = capsule_repr, .tp_repr = capsule_repr,
.tp_doc = PyCapsule_Type__doc__, .tp_doc = PyCapsule_Type__doc__,
.tp_traverse = (traverseproc)capsule_traverse, .tp_traverse = capsule_traverse,
.tp_clear = (inquiry)capsule_clear, .tp_clear = capsule_clear,
}; };