gh-130317: Fix PyFloat_Pack/Unpack[24] for NaN's with payload (#130452)

Co-authored-by: Victor Stinner <vstinner@python.org>
This commit is contained in:
Sergey B Kirpichev 2025-04-28 16:23:26 +03:00 committed by GitHub
parent 922049b613
commit 6157135a8d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 120 additions and 8 deletions

View file

@ -81,4 +81,13 @@ _testcapi_float_unpack(PyObject *module, PyObject *const *args, Py_ssize_t nargs
exit:
return return_value;
}
/*[clinic end generated code: output=b43dfd3a77fe04ba input=a9049054013a1b77]*/
PyDoc_STRVAR(_testcapi_float_set_snan__doc__,
"float_set_snan($module, obj, /)\n"
"--\n"
"\n"
"Make a signaling NaN.");
#define _TESTCAPI_FLOAT_SET_SNAN_METHODDEF \
{"float_set_snan", (PyCFunction)_testcapi_float_set_snan, METH_O, _testcapi_float_set_snan__doc__},
/*[clinic end generated code: output=1b0e9b05e1f50712 input=a9049054013a1b77]*/

View file

@ -157,9 +157,39 @@ test_string_to_double(PyObject *self, PyObject *Py_UNUSED(ignored))
}
/*[clinic input]
_testcapi.float_set_snan
obj: object
/
Make a signaling NaN.
[clinic start generated code]*/
static PyObject *
_testcapi_float_set_snan(PyObject *module, PyObject *obj)
/*[clinic end generated code: output=f43778a70f60aa4b input=c1269b0f88ef27ac]*/
{
if (!PyFloat_Check(obj)) {
PyErr_SetString(PyExc_ValueError, "float-point number expected");
return NULL;
}
double d = ((PyFloatObject *)obj)->ob_fval;
if (!isnan(d)) {
PyErr_SetString(PyExc_ValueError, "nan expected");
return NULL;
}
uint64_t v;
memcpy(&v, &d, 8);
v &= ~(1ULL << 51); /* make sNaN */
memcpy(&d, &v, 8);
return PyFloat_FromDouble(d);
}
static PyMethodDef test_methods[] = {
_TESTCAPI_FLOAT_PACK_METHODDEF
_TESTCAPI_FLOAT_UNPACK_METHODDEF
_TESTCAPI_FLOAT_SET_SNAN_METHODDEF
{"test_string_to_double", test_string_to_double, METH_NOARGS},
{NULL},
};