]> granicus.if.org Git - python/commitdiff
bpo-37170: Fix the cast on error in PyLong_AsUnsignedLongLongMask() (GH-13860)
authorZackery Spytz <zspytz@gmail.com>
Thu, 6 Jun 2019 20:39:23 +0000 (14:39 -0600)
committerVictor Stinner <vstinner@redhat.com>
Thu, 6 Jun 2019 20:39:23 +0000 (22:39 +0200)
Doc/c-api/long.rst
Misc/NEWS.d/next/C API/2019-06-06-08-47-04.bpo-37170.hO_fpM.rst [new file with mode: 0644]
Modules/_testcapimodule.c
Objects/longobject.c

index 6be29f9cd32eaa16bbd963bb29b1559bbaa46f81..fdaefafe21ba09e37f784d73a8f30a6734e804ae 100644 (file)
@@ -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.
@@ -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.
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 (file)
index 0000000..7a35c95
--- /dev/null
@@ -0,0 +1 @@
+Fix the cast on error in :c:func:`PyLong_AsUnsignedLongLongMask()`.
index f059b4df11b734182c05bea567f188b8adaa9aa5..c1ae237f2e6cce2f6369879e72cd837c8503b9ff 100644 (file)
@@ -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.
  */
@@ -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},
index a1103f697c7379ccd696a09a5082cddaedb374de..50ea2a4e54a4e4be538c3554ca287c2dbb322613 100644 (file)
@@ -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)) {
@@ -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)) {