]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
bpo-39871: Fix possible SystemError in atan2, copysign and remainder (GH-18806)
authorZackery Spytz <zspytz@gmail.com>
Sat, 14 Mar 2020 10:45:32 +0000 (04:45 -0600)
committerGitHub <noreply@github.com>
Sat, 14 Mar 2020 10:45:32 +0000 (10:45 +0000)
In math_2(), the first PyFloat_AsDouble() call should be checked
for failure before the second call.

Co-authored-by: Mark Dickinson <dickinsm@gmail.com>
Lib/test/test_math.py
Misc/NEWS.d/next/Core and Builtins/2020-03-06-06-12-37.bpo-39871.dCAj_2.rst [new file with mode: 0644]
Modules/mathmodule.c

index cc39402b3c60b17b72d84bb404cebc2676dea674..4b848a5e7e5f85107c9a42c2415182475407b7e9 100644 (file)
@@ -1992,6 +1992,22 @@ class MathTests(unittest.TestCase):
             with self.subTest(x=x):
                 self.assertEqual(math.ulp(-x), math.ulp(x))
 
+    def test_issue39871(self):
+        # A SystemError should not be raised if the first arg to atan2(),
+        # copysign(), or remainder() cannot be converted to a float.
+        class F:
+            def __float__(self):
+                self.converted = True
+                1/0
+        for func in math.atan2, math.copysign, math.remainder:
+            y = F()
+            with self.assertRaises(TypeError):
+                func("not a number", y)
+
+            # There should not have been any attempt to convert the second
+            # argument to a float.
+            self.assertFalse(getattr(y, "converted", False))
+
     # Custom assertions.
 
     def assertIsNaN(self, value):
diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-03-06-06-12-37.bpo-39871.dCAj_2.rst b/Misc/NEWS.d/next/Core and Builtins/2020-03-06-06-12-37.bpo-39871.dCAj_2.rst
new file mode 100644 (file)
index 0000000..0b4c2e5
--- /dev/null
@@ -0,0 +1,3 @@
+Fix a possible :exc:`SystemError` in ``math.{atan2,copysign,remainder}()``
+when the first argument cannot be converted to a :class:`float`. Patch by
+Zachary Spytz.
index 77e325cf0c63d36f8be1b556de68962d752a268c..2a73a983f56d2d656966ece1ca9c2bbdbe13c61e 100644 (file)
@@ -1106,9 +1106,13 @@ math_2(PyObject *const *args, Py_ssize_t nargs,
     if (!_PyArg_CheckPositional(funcname, nargs, 2, 2))
         return NULL;
     x = PyFloat_AsDouble(args[0]);
+    if (x == -1.0 && PyErr_Occurred()) {
+        return NULL;
+    }
     y = PyFloat_AsDouble(args[1]);
-    if ((x == -1.0 || y == -1.0) && PyErr_Occurred())
+    if (y == -1.0 && PyErr_Occurred()) {
         return NULL;
+    }
     errno = 0;
     r = (*func)(x, y);
     if (Py_IS_NAN(r)) {