Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

gh-111178: fix UBSan failures in Objects/descrobject.c #128245

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 10 additions & 7 deletions Objects/descrobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -1508,6 +1508,8 @@ PyWrapper_New(PyObject *d, PyObject *self)

/* A built-in 'property' type */

#define _propertyobject_CAST(op) ((propertyobject *)(op))

/*
class property(object):

Expand Down Expand Up @@ -1911,8 +1913,9 @@ property_init_impl(propertyobject *self, PyObject *fget, PyObject *fset,
}

static PyObject *
property_get__name__(propertyobject *prop, void *Py_UNUSED(ignored))
property_get__name__(PyObject *op, void *Py_UNUSED(ignored))
{
propertyobject *prop = _propertyobject_CAST(op);
PyObject *name;
if (property_name(prop, &name) < 0) {
return NULL;
Expand All @@ -1925,16 +1928,17 @@ property_get__name__(propertyobject *prop, void *Py_UNUSED(ignored))
}

static int
property_set__name__(propertyobject *prop, PyObject *value,
void *Py_UNUSED(ignored))
property_set__name__(PyObject *op, PyObject *value, void *Py_UNUSED(ignored))
{
propertyobject *prop = _propertyobject_CAST(op);
Py_XSETREF(prop->prop_name, Py_XNewRef(value));
return 0;
}

static PyObject *
property_get___isabstractmethod__(propertyobject *prop, void *closure)
property_get___isabstractmethod__(PyObject *op, void *closure)
{
propertyobject *prop = _propertyobject_CAST(op);
int res = _PyObject_IsAbstract(prop->prop_get);
if (res == -1) {
return NULL;
Expand Down Expand Up @@ -1962,9 +1966,8 @@ property_get___isabstractmethod__(propertyobject *prop, void *closure)
}

static PyGetSetDef property_getsetlist[] = {
{"__name__", (getter)property_get__name__, (setter)property_set__name__},
{"__isabstractmethod__",
(getter)property_get___isabstractmethod__, NULL,
{"__name__", property_get__name__, property_set__name__, NULL, NULL},
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This makes me wonder: what's your reason for adding the NULLs?
(C only needs one value and zeroes the rest, and many of these structs have more rarely used stuff at the end -- though perhaps the reasons for that are more historical than ergonomic.)

Copy link
Contributor Author

@picnixz picnixz Jan 3, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I feel that if we have a half-initialized object, it's somewhat harder for new readers to know that there's still the NULL doc field and closure. I think I'm unfortunately not constant in where I'm adding those NULLs so feel free to remove them (but since I was anyway modifying the line, I took the initiative of keeping them).

{"__isabstractmethod__", property_get___isabstractmethod__, NULL,
NULL,
NULL},
{NULL} /* Sentinel */
Expand Down
Loading