Skip to content

Commit

Permalink
gh-111178: fix UBSan failures in Objects/complexobject.c (GH-128241)
Browse files Browse the repository at this point in the history
fix UBSan failures for `PyComplexObject`
  • Loading branch information
picnixz authored Jan 10, 2025
1 parent 65b484d commit 6cf3175
Showing 1 changed file with 29 additions and 25 deletions.
54 changes: 29 additions & 25 deletions Objects/complexobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
#include "pycore_pymath.h" // _Py_ADJUST_ERANGE2()


#define _PyComplexObject_CAST(op) ((PyComplexObject *)(op))


/*[clinic input]
class complex "PyComplexObject *" "&PyComplex_Type"
Expand Down Expand Up @@ -553,11 +555,12 @@ PyComplex_AsCComplex(PyObject *op)
}

static PyObject *
complex_repr(PyComplexObject *v)
complex_repr(PyObject *op)
{
int precision = 0;
char format_code = 'r';
PyObject *result = NULL;
PyComplexObject *v = _PyComplexObject_CAST(op);

/* If these are non-NULL, they'll need to be freed. */
char *pre = NULL;
Expand Down Expand Up @@ -609,13 +612,14 @@ complex_repr(PyComplexObject *v)
}

static Py_hash_t
complex_hash(PyComplexObject *v)
complex_hash(PyObject *op)
{
Py_uhash_t hashreal, hashimag, combined;
hashreal = (Py_uhash_t)_Py_HashDouble((PyObject *) v, v->cval.real);
PyComplexObject *v = _PyComplexObject_CAST(op);
hashreal = (Py_uhash_t)_Py_HashDouble(op, v->cval.real);
if (hashreal == (Py_uhash_t)-1)
return -1;
hashimag = (Py_uhash_t)_Py_HashDouble((PyObject *)v, v->cval.imag);
hashimag = (Py_uhash_t)_Py_HashDouble(op, v->cval.imag);
if (hashimag == (Py_uhash_t)-1)
return -1;
/* Note: if the imaginary part is 0, hashimag is 0 now,
Expand Down Expand Up @@ -753,31 +757,30 @@ complex_pow(PyObject *v, PyObject *w, PyObject *z)
}

static PyObject *
complex_neg(PyComplexObject *v)
complex_neg(PyObject *op)
{
PyComplexObject *v = _PyComplexObject_CAST(op);
Py_complex neg;
neg.real = -v->cval.real;
neg.imag = -v->cval.imag;
return PyComplex_FromCComplex(neg);
}

static PyObject *
complex_pos(PyComplexObject *v)
complex_pos(PyObject *op)
{
PyComplexObject *v = _PyComplexObject_CAST(op);
if (PyComplex_CheckExact(v)) {
return Py_NewRef(v);
}
else
return PyComplex_FromCComplex(v->cval);
return PyComplex_FromCComplex(v->cval);
}

static PyObject *
complex_abs(PyComplexObject *v)
complex_abs(PyObject *op)
{
double result;

result = _Py_c_abs(v->cval);

PyComplexObject *v = _PyComplexObject_CAST(op);
double result = _Py_c_abs(v->cval);
if (errno == ERANGE) {
PyErr_SetString(PyExc_OverflowError,
"absolute value too large");
Expand All @@ -787,8 +790,9 @@ complex_abs(PyComplexObject *v)
}

static int
complex_bool(PyComplexObject *v)
complex_bool(PyObject *op)
{
PyComplexObject *v = _PyComplexObject_CAST(op);
return v->cval.real != 0.0 || v->cval.imag != 0.0;
}

Expand Down Expand Up @@ -1339,16 +1343,16 @@ static PyMemberDef complex_members[] = {
};

static PyNumberMethods complex_as_number = {
(binaryfunc)complex_add, /* nb_add */
(binaryfunc)complex_sub, /* nb_subtract */
(binaryfunc)complex_mul, /* nb_multiply */
complex_add, /* nb_add */
complex_sub, /* nb_subtract */
complex_mul, /* nb_multiply */
0, /* nb_remainder */
0, /* nb_divmod */
(ternaryfunc)complex_pow, /* nb_power */
(unaryfunc)complex_neg, /* nb_negative */
(unaryfunc)complex_pos, /* nb_positive */
(unaryfunc)complex_abs, /* nb_absolute */
(inquiry)complex_bool, /* nb_bool */
complex_pow, /* nb_power */
complex_neg, /* nb_negative */
complex_pos, /* nb_positive */
complex_abs, /* nb_absolute */
complex_bool, /* nb_bool */
0, /* nb_invert */
0, /* nb_lshift */
0, /* nb_rshift */
Expand All @@ -1369,7 +1373,7 @@ static PyNumberMethods complex_as_number = {
0, /* nb_inplace_xor */
0, /* nb_inplace_or */
0, /* nb_floor_divide */
(binaryfunc)complex_div, /* nb_true_divide */
complex_div, /* nb_true_divide */
0, /* nb_inplace_floor_divide */
0, /* nb_inplace_true_divide */
};
Expand All @@ -1384,11 +1388,11 @@ PyTypeObject PyComplex_Type = {
0, /* tp_getattr */
0, /* tp_setattr */
0, /* tp_as_async */
(reprfunc)complex_repr, /* tp_repr */
complex_repr, /* tp_repr */
&complex_as_number, /* tp_as_number */
0, /* tp_as_sequence */
0, /* tp_as_mapping */
(hashfunc)complex_hash, /* tp_hash */
complex_hash, /* tp_hash */
0, /* tp_call */
0, /* tp_str */
PyObject_GenericGetAttr, /* tp_getattro */
Expand Down

0 comments on commit 6cf3175

Please sign in to comment.