Skip to content

Commit 6cf3175

Browse files
authored
gh-111178: fix UBSan failures in Objects/complexobject.c (GH-128241)
fix UBSan failures for `PyComplexObject`
1 parent 65b484d commit 6cf3175

File tree

1 file changed

+29
-25
lines changed

1 file changed

+29
-25
lines changed

Objects/complexobject.c

Lines changed: 29 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414
#include "pycore_pymath.h" // _Py_ADJUST_ERANGE2()
1515

1616

17+
#define _PyComplexObject_CAST(op) ((PyComplexObject *)(op))
18+
1719

1820
/*[clinic input]
1921
class complex "PyComplexObject *" "&PyComplex_Type"
@@ -553,11 +555,12 @@ PyComplex_AsCComplex(PyObject *op)
553555
}
554556

555557
static PyObject *
556-
complex_repr(PyComplexObject *v)
558+
complex_repr(PyObject *op)
557559
{
558560
int precision = 0;
559561
char format_code = 'r';
560562
PyObject *result = NULL;
563+
PyComplexObject *v = _PyComplexObject_CAST(op);
561564

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

611614
static Py_hash_t
612-
complex_hash(PyComplexObject *v)
615+
complex_hash(PyObject *op)
613616
{
614617
Py_uhash_t hashreal, hashimag, combined;
615-
hashreal = (Py_uhash_t)_Py_HashDouble((PyObject *) v, v->cval.real);
618+
PyComplexObject *v = _PyComplexObject_CAST(op);
619+
hashreal = (Py_uhash_t)_Py_HashDouble(op, v->cval.real);
616620
if (hashreal == (Py_uhash_t)-1)
617621
return -1;
618-
hashimag = (Py_uhash_t)_Py_HashDouble((PyObject *)v, v->cval.imag);
622+
hashimag = (Py_uhash_t)_Py_HashDouble(op, v->cval.imag);
619623
if (hashimag == (Py_uhash_t)-1)
620624
return -1;
621625
/* Note: if the imaginary part is 0, hashimag is 0 now,
@@ -753,31 +757,30 @@ complex_pow(PyObject *v, PyObject *w, PyObject *z)
753757
}
754758

755759
static PyObject *
756-
complex_neg(PyComplexObject *v)
760+
complex_neg(PyObject *op)
757761
{
762+
PyComplexObject *v = _PyComplexObject_CAST(op);
758763
Py_complex neg;
759764
neg.real = -v->cval.real;
760765
neg.imag = -v->cval.imag;
761766
return PyComplex_FromCComplex(neg);
762767
}
763768

764769
static PyObject *
765-
complex_pos(PyComplexObject *v)
770+
complex_pos(PyObject *op)
766771
{
772+
PyComplexObject *v = _PyComplexObject_CAST(op);
767773
if (PyComplex_CheckExact(v)) {
768774
return Py_NewRef(v);
769775
}
770-
else
771-
return PyComplex_FromCComplex(v->cval);
776+
return PyComplex_FromCComplex(v->cval);
772777
}
773778

774779
static PyObject *
775-
complex_abs(PyComplexObject *v)
780+
complex_abs(PyObject *op)
776781
{
777-
double result;
778-
779-
result = _Py_c_abs(v->cval);
780-
782+
PyComplexObject *v = _PyComplexObject_CAST(op);
783+
double result = _Py_c_abs(v->cval);
781784
if (errno == ERANGE) {
782785
PyErr_SetString(PyExc_OverflowError,
783786
"absolute value too large");
@@ -787,8 +790,9 @@ complex_abs(PyComplexObject *v)
787790
}
788791

789792
static int
790-
complex_bool(PyComplexObject *v)
793+
complex_bool(PyObject *op)
791794
{
795+
PyComplexObject *v = _PyComplexObject_CAST(op);
792796
return v->cval.real != 0.0 || v->cval.imag != 0.0;
793797
}
794798

@@ -1339,16 +1343,16 @@ static PyMemberDef complex_members[] = {
13391343
};
13401344

13411345
static PyNumberMethods complex_as_number = {
1342-
(binaryfunc)complex_add, /* nb_add */
1343-
(binaryfunc)complex_sub, /* nb_subtract */
1344-
(binaryfunc)complex_mul, /* nb_multiply */
1346+
complex_add, /* nb_add */
1347+
complex_sub, /* nb_subtract */
1348+
complex_mul, /* nb_multiply */
13451349
0, /* nb_remainder */
13461350
0, /* nb_divmod */
1347-
(ternaryfunc)complex_pow, /* nb_power */
1348-
(unaryfunc)complex_neg, /* nb_negative */
1349-
(unaryfunc)complex_pos, /* nb_positive */
1350-
(unaryfunc)complex_abs, /* nb_absolute */
1351-
(inquiry)complex_bool, /* nb_bool */
1351+
complex_pow, /* nb_power */
1352+
complex_neg, /* nb_negative */
1353+
complex_pos, /* nb_positive */
1354+
complex_abs, /* nb_absolute */
1355+
complex_bool, /* nb_bool */
13521356
0, /* nb_invert */
13531357
0, /* nb_lshift */
13541358
0, /* nb_rshift */
@@ -1369,7 +1373,7 @@ static PyNumberMethods complex_as_number = {
13691373
0, /* nb_inplace_xor */
13701374
0, /* nb_inplace_or */
13711375
0, /* nb_floor_divide */
1372-
(binaryfunc)complex_div, /* nb_true_divide */
1376+
complex_div, /* nb_true_divide */
13731377
0, /* nb_inplace_floor_divide */
13741378
0, /* nb_inplace_true_divide */
13751379
};
@@ -1384,11 +1388,11 @@ PyTypeObject PyComplex_Type = {
13841388
0, /* tp_getattr */
13851389
0, /* tp_setattr */
13861390
0, /* tp_as_async */
1387-
(reprfunc)complex_repr, /* tp_repr */
1391+
complex_repr, /* tp_repr */
13881392
&complex_as_number, /* tp_as_number */
13891393
0, /* tp_as_sequence */
13901394
0, /* tp_as_mapping */
1391-
(hashfunc)complex_hash, /* tp_hash */
1395+
complex_hash, /* tp_hash */
13921396
0, /* tp_call */
13931397
0, /* tp_str */
13941398
PyObject_GenericGetAttr, /* tp_getattro */

0 commit comments

Comments
 (0)