From e36ed475ea429f7cc80a4d65f80b44686a74b246 Mon Sep 17 00:00:00 2001 From: Zackery Spytz Date: Fri, 7 Jun 2019 09:41:10 -0600 Subject: [PATCH] [3.7] bpo-37170: Fix the cast on error in PyLong_AsUnsignedLongLongMask() (GH-13860) (GH-13896) (cherry picked from commit dc2476500d91082f0c907772c83a044bf49af279) Co-authored-by: Zackery Spytz --- Doc/c-api/long.rst | 6 +++-- .../2019-06-06-08-47-04.bpo-37170.hO_fpM.rst | 1 + Modules/_testcapimodule.c | 22 +++++++++++++++++++ Objects/longobject.c | 4 ++-- 4 files changed, 29 insertions(+), 4 deletions(-) create mode 100644 Misc/NEWS.d/next/C API/2019-06-06-08-47-04.bpo-37170.hO_fpM.rst diff --git a/Doc/c-api/long.rst b/Doc/c-api/long.rst index 5b1f386fb7e..71144f16e39 100644 --- a/Doc/c-api/long.rst +++ b/Doc/c-api/long.rst @@ -259,7 +259,8 @@ distinguished from a number. Use :c:func:`PyErr_Occurred` to disambiguate. If the value of *obj* is out of range for an :c:type:`unsigned long`, return the reduction of that value modulo ``ULONG_MAX + 1``. - Returns ``-1`` on error. Use :c:func:`PyErr_Occurred` to disambiguate. + Returns ``(unsigned long)-1`` on error. Use :c:func:`PyErr_Occurred` to + disambiguate. .. c:function:: unsigned long long PyLong_AsUnsignedLongLongMask(PyObject *obj) @@ -271,7 +272,8 @@ distinguished from a number. Use :c:func:`PyErr_Occurred` to disambiguate. If the value of *obj* is out of range for an :c:type:`unsigned long long`, return the reduction of that value modulo ``PY_ULLONG_MAX + 1``. - Returns ``-1`` on error. Use :c:func:`PyErr_Occurred` to disambiguate. + Returns ``(unsigned long long)-1`` on error. Use :c:func:`PyErr_Occurred` + to disambiguate. .. c:function:: double PyLong_AsDouble(PyObject *pylong) diff --git a/Misc/NEWS.d/next/C API/2019-06-06-08-47-04.bpo-37170.hO_fpM.rst b/Misc/NEWS.d/next/C API/2019-06-06-08-47-04.bpo-37170.hO_fpM.rst new file mode 100644 index 00000000000..7a35c9583d6 --- /dev/null +++ b/Misc/NEWS.d/next/C API/2019-06-06-08-47-04.bpo-37170.hO_fpM.rst @@ -0,0 +1 @@ +Fix the cast on error in :c:func:`PyLong_AsUnsignedLongLongMask()`. diff --git a/Modules/_testcapimodule.c b/Modules/_testcapimodule.c index b864f9270e9..64b7b690493 100644 --- a/Modules/_testcapimodule.c +++ b/Modules/_testcapimodule.c @@ -816,6 +816,26 @@ test_long_as_size_t(PyObject *self) return Py_None; } +static PyObject * +test_long_as_unsigned_long_long_mask(PyObject *self, + PyObject *Py_UNUSED(ignored)) +{ + unsigned long long res = PyLong_AsUnsignedLongLongMask(NULL); + + if (res != (unsigned long long)-1 || !PyErr_Occurred()) { + return raiseTestError("test_long_as_unsigned_long_long_mask", + "PyLong_AsUnsignedLongLongMask(NULL) didn't " + "complain"); + } + if (!PyErr_ExceptionMatches(PyExc_SystemError)) { + return raiseTestError("test_long_as_unsigned_long_long_mask", + "PyLong_AsUnsignedLongLongMask(NULL) raised " + "something other than SystemError"); + } + PyErr_Clear(); + Py_RETURN_NONE; +} + /* Test the PyLong_AsDouble API. At present this just tests that non-integer arguments are handled correctly. */ @@ -4663,6 +4683,8 @@ static PyMethodDef TestMethods[] = { METH_NOARGS}, {"test_long_as_double", (PyCFunction)test_long_as_double,METH_NOARGS}, {"test_long_as_size_t", (PyCFunction)test_long_as_size_t,METH_NOARGS}, + {"test_long_as_unsigned_long_long_mask", + (PyCFunction)test_long_as_unsigned_long_long_mask, METH_NOARGS}, {"test_long_numbits", (PyCFunction)test_long_numbits, METH_NOARGS}, {"test_k_code", (PyCFunction)test_k_code, METH_NOARGS}, {"test_empty_argparse", (PyCFunction)test_empty_argparse,METH_NOARGS}, diff --git a/Objects/longobject.c b/Objects/longobject.c index 59c7efbfee2..7628a114e38 100644 --- a/Objects/longobject.c +++ b/Objects/longobject.c @@ -1309,7 +1309,7 @@ _PyLong_AsUnsignedLongLongMask(PyObject *vv) if (vv == NULL || !PyLong_Check(vv)) { PyErr_BadInternalCall(); - return (unsigned long) -1; + return (unsigned long long) -1; } v = (PyLongObject *)vv; switch(Py_SIZE(v)) { @@ -1337,7 +1337,7 @@ PyLong_AsUnsignedLongLongMask(PyObject *op) if (op == NULL) { PyErr_BadInternalCall(); - return (unsigned long)-1; + return (unsigned long long)-1; } if (PyLong_Check(op)) {