gh-111178: fix UBSan failures in Modules/_zoneinfo.c (GH-129798)

Fix UBSan failures for `PyZoneInfo_ZoneInfo`

Fix semantic naming
This commit is contained in:
Bénédikt Tran 2025-02-26 09:36:59 +01:00 committed by GitHub
parent b536e37104
commit 18bc5b7839
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -56,6 +56,8 @@ typedef struct {
unsigned char source;
} PyZoneInfo_ZoneInfo;
#define PyZoneInfo_ZoneInfo_CAST(op) ((PyZoneInfo_ZoneInfo *)(op))
struct TransitionRuleType {
int64_t (*year_to_timestamp)(TransitionRuleType *, int);
};
@ -238,7 +240,7 @@ zoneinfo_new_instance(zoneinfo_state *state, PyTypeObject *type, PyObject *key)
}
}
PyObject *self = (PyObject *)(type->tp_alloc(type, 0));
PyObject *self = type->tp_alloc(type, 0);
if (self == NULL) {
goto error;
}
@ -251,7 +253,8 @@ zoneinfo_new_instance(zoneinfo_state *state, PyTypeObject *type, PyObject *key)
}
}
if (load_data(state, (PyZoneInfo_ZoneInfo *)self, file_obj)) {
PyZoneInfo_ZoneInfo *self_zinfo = (PyZoneInfo_ZoneInfo *)self;
if (load_data(state, self_zinfo, file_obj)) {
goto error;
}
@ -262,7 +265,7 @@ zoneinfo_new_instance(zoneinfo_state *state, PyTypeObject *type, PyObject *key)
}
Py_DECREF(rv);
((PyZoneInfo_ZoneInfo *)self)->key = Py_NewRef(key);
self_zinfo->key = Py_NewRef(key);
goto cleanup;
error:
@ -346,16 +349,18 @@ zoneinfo_ZoneInfo_impl(PyTypeObject *type, PyObject *key)
}
static int
zoneinfo_traverse(PyZoneInfo_ZoneInfo *self, visitproc visit, void *arg)
zoneinfo_traverse(PyObject *op, visitproc visit, void *arg)
{
PyZoneInfo_ZoneInfo *self = PyZoneInfo_ZoneInfo_CAST(op);
Py_VISIT(Py_TYPE(self));
Py_VISIT(self->key);
return 0;
}
static int
zoneinfo_clear(PyZoneInfo_ZoneInfo *self)
zoneinfo_clear(PyObject *op)
{
PyZoneInfo_ZoneInfo *self = PyZoneInfo_ZoneInfo_CAST(op);
Py_CLEAR(self->key);
Py_CLEAR(self->file_repr);
return 0;
@ -364,7 +369,7 @@ zoneinfo_clear(PyZoneInfo_ZoneInfo *self)
static void
zoneinfo_dealloc(PyObject *obj_self)
{
PyZoneInfo_ZoneInfo *self = (PyZoneInfo_ZoneInfo *)obj_self;
PyZoneInfo_ZoneInfo *self = PyZoneInfo_ZoneInfo_CAST(obj_self);
PyTypeObject *tp = Py_TYPE(self);
PyObject_GC_UnTrack(self);
@ -395,7 +400,7 @@ zoneinfo_dealloc(PyObject *obj_self)
free_tzrule(&(self->tzrule_after));
zoneinfo_clear(self);
(void)zoneinfo_clear(obj_self);
tp->tp_free(obj_self);
Py_DECREF(tp);
}
@ -420,8 +425,7 @@ zoneinfo_ZoneInfo_from_file_impl(PyTypeObject *type, PyTypeObject *cls,
PyObject *file_repr = NULL;
PyZoneInfo_ZoneInfo *self = NULL;
PyObject *obj_self = (PyObject *)(type->tp_alloc(type, 0));
self = (PyZoneInfo_ZoneInfo *)obj_self;
self = (PyZoneInfo_ZoneInfo *)type->tp_alloc(type, 0);
if (self == NULL) {
return NULL;
}
@ -439,7 +443,7 @@ zoneinfo_ZoneInfo_from_file_impl(PyTypeObject *type, PyTypeObject *cls,
self->source = SOURCE_FILE;
self->file_repr = file_repr;
self->key = Py_NewRef(key);
return obj_self;
return (PyObject *)self;
error:
Py_XDECREF(file_repr);
@ -466,7 +470,7 @@ zoneinfo_ZoneInfo_no_cache_impl(PyTypeObject *type, PyTypeObject *cls,
zoneinfo_state *state = zoneinfo_get_state_by_cls(cls);
PyObject *out = zoneinfo_new_instance(state, type, key);
if (out != NULL) {
((PyZoneInfo_ZoneInfo *)out)->source = SOURCE_NOCACHE;
PyZoneInfo_ZoneInfo_CAST(out)->source = SOURCE_NOCACHE;
}
return out;
@ -558,7 +562,7 @@ zoneinfo_ZoneInfo_utcoffset_impl(PyObject *self, PyTypeObject *cls,
/*[clinic end generated code: output=b71016c319ba1f91 input=2bb6c5364938f19c]*/
{
zoneinfo_state *state = zoneinfo_get_state_by_cls(cls);
_ttinfo *tti = find_ttinfo(state, (PyZoneInfo_ZoneInfo *)self, dt);
_ttinfo *tti = find_ttinfo(state, PyZoneInfo_ZoneInfo_CAST(self), dt);
if (tti == NULL) {
return NULL;
}
@ -580,7 +584,7 @@ zoneinfo_ZoneInfo_dst_impl(PyObject *self, PyTypeObject *cls, PyObject *dt)
/*[clinic end generated code: output=cb6168d7723a6ae6 input=2167fb80cf8645c6]*/
{
zoneinfo_state *state = zoneinfo_get_state_by_cls(cls);
_ttinfo *tti = find_ttinfo(state, (PyZoneInfo_ZoneInfo *)self, dt);
_ttinfo *tti = find_ttinfo(state, PyZoneInfo_ZoneInfo_CAST(self), dt);
if (tti == NULL) {
return NULL;
}
@ -603,7 +607,7 @@ zoneinfo_ZoneInfo_tzname_impl(PyObject *self, PyTypeObject *cls,
/*[clinic end generated code: output=3b6ae6c3053ea75a input=15a59a4f92ed1f1f]*/
{
zoneinfo_state *state = zoneinfo_get_state_by_cls(cls);
_ttinfo *tti = find_ttinfo(state, (PyZoneInfo_ZoneInfo *)self, dt);
_ttinfo *tti = find_ttinfo(state, PyZoneInfo_ZoneInfo_CAST(self), dt);
if (tti == NULL) {
return NULL;
}
@ -627,7 +631,7 @@ zoneinfo_fromutc(PyObject *obj_self, PyObject *dt)
return NULL;
}
PyZoneInfo_ZoneInfo *self = (PyZoneInfo_ZoneInfo *)obj_self;
PyZoneInfo_ZoneInfo *self = PyZoneInfo_ZoneInfo_CAST(obj_self);
int64_t timestamp;
if (get_local_timestamp(dt, &timestamp)) {
@ -736,31 +740,24 @@ zoneinfo_fromutc(PyObject *obj_self, PyObject *dt)
}
static PyObject *
zoneinfo_repr(PyZoneInfo_ZoneInfo *self)
zoneinfo_repr(PyObject *op)
{
PyObject *rv = NULL;
const char *type_name = Py_TYPE((PyObject *)self)->tp_name;
if (!(self->key == Py_None)) {
rv = PyUnicode_FromFormat("%s(key=%R)", type_name, self->key);
PyZoneInfo_ZoneInfo *self = PyZoneInfo_ZoneInfo_CAST(op);
if (self->key != Py_None) {
return PyUnicode_FromFormat("%T(key=%R)", self, self->key);
}
else {
assert(PyUnicode_Check(self->file_repr));
rv = PyUnicode_FromFormat("%s.from_file(%U)", type_name,
self->file_repr);
}
return rv;
assert(PyUnicode_Check(self->file_repr));
return PyUnicode_FromFormat("%T.from_file(%U)", self, self->file_repr);
}
static PyObject *
zoneinfo_str(PyZoneInfo_ZoneInfo *self)
zoneinfo_str(PyObject *op)
{
if (!(self->key == Py_None)) {
PyZoneInfo_ZoneInfo *self = PyZoneInfo_ZoneInfo_CAST(op);
if (self->key != Py_None) {
return Py_NewRef(self->key);
}
else {
return zoneinfo_repr(self);
}
return zoneinfo_repr(op);
}
/* Pickles the ZoneInfo object by key and source.
@ -776,9 +773,9 @@ zoneinfo_str(PyZoneInfo_ZoneInfo *self)
* Objects constructed from ZoneInfo.from_file cannot be pickled.
*/
static PyObject *
zoneinfo_reduce(PyObject *obj_self, PyObject *unused)
zoneinfo_reduce(PyObject *obj_self, PyObject *Py_UNUSED(dummy))
{
PyZoneInfo_ZoneInfo *self = (PyZoneInfo_ZoneInfo *)obj_self;
PyZoneInfo_ZoneInfo *self = PyZoneInfo_ZoneInfo_CAST(obj_self);
if (self->source == SOURCE_FILE) {
// Objects constructed from files cannot be pickled.
PyObject *pickle_error =