Skip to content

Commit

Permalink
bpo-37170: Fix the cast on error in PyLong_AsUnsignedLongLongMask() (G…
Browse files Browse the repository at this point in the history
  • Loading branch information
ZackerySpytz authored and vstinner committed Jun 6, 2019
1 parent f6713e8 commit dc24765
Show file tree
Hide file tree
Showing 4 changed files with 29 additions and 4 deletions.
6 changes: 4 additions & 2 deletions Doc/c-api/long.rst
Original file line number Diff line number Diff line change
Expand Up @@ -288,7 +288,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.
.. versionchanged:: 3.8
Use :meth:`__index__` if available.
Expand All @@ -307,7 +308,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.
.. versionchanged:: 3.8
Use :meth:`__index__` if available.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Fix the cast on error in :c:func:`PyLong_AsUnsignedLongLongMask()`.
22 changes: 22 additions & 0 deletions Modules/_testcapimodule.c
Original file line number Diff line number Diff line change
Expand Up @@ -825,6 +825,26 @@ test_long_as_size_t(PyObject *self, PyObject *Py_UNUSED(ignored))
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.
*/
Expand Down Expand Up @@ -5070,6 +5090,8 @@ static PyMethodDef TestMethods[] = {
{"test_long_and_overflow", test_long_and_overflow, METH_NOARGS},
{"test_long_as_double", test_long_as_double, METH_NOARGS},
{"test_long_as_size_t", test_long_as_size_t, METH_NOARGS},
{"test_long_as_unsigned_long_long_mask",
test_long_as_unsigned_long_long_mask, METH_NOARGS},
{"test_long_numbits", test_long_numbits, METH_NOARGS},
{"test_k_code", test_k_code, METH_NOARGS},
{"test_empty_argparse", test_empty_argparse, METH_NOARGS},
Expand Down
4 changes: 2 additions & 2 deletions Objects/longobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -1376,7 +1376,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)) {
Expand Down Expand Up @@ -1404,7 +1404,7 @@ PyLong_AsUnsignedLongLongMask(PyObject *op)

if (op == NULL) {
PyErr_BadInternalCall();
return (unsigned long)-1;
return (unsigned long long)-1;
}

if (PyLong_Check(op)) {
Expand Down

0 comments on commit dc24765

Please sign in to comment.