From: Mark Dickinson Date: Sat, 14 Mar 2020 11:51:53 +0000 (+0000) Subject: [3.7] bpo-39871: Fix possible SystemError in atan2, copysign and remainder (GH-18806... X-Git-Tag: v3.7.8rc1~143 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=4dcfe5f2e4bad8e03990de75d8d4ec20e8aa23b3;p=thirdparty%2FPython%2Fcpython.git [3.7] bpo-39871: Fix possible SystemError in atan2, copysign and remainder (GH-18806) (GH-18990) In math_2(), the first PyFloat_AsDouble() call should be checked for failure before the second call. Co-authored-by: Mark Dickinson . (cherry picked from commit 5208b4b37953a406db0ed6a9db545c2948dde989) Co-authored-by: Zackery Spytz --- diff --git a/Lib/test/test_math.py b/Lib/test/test_math.py index 44785d3e49a2..4a61260f0453 100644 --- a/Lib/test/test_math.py +++ b/Lib/test/test_math.py @@ -1415,6 +1415,22 @@ class MathTests(unittest.TestCase): self.fail('Failures in test_mtestfile:\n ' + '\n '.join(failures)) + 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 index 000000000000..0b4c2e5f4cc9 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2020-03-06-06-12-37.bpo-39871.dCAj_2.rst @@ -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. diff --git a/Modules/mathmodule.c b/Modules/mathmodule.c index 8eedca8a30b9..8bf0ab0bcb11 100644 --- a/Modules/mathmodule.c +++ b/Modules/mathmodule.c @@ -1004,9 +1004,13 @@ math_2(PyObject *args, double (*func) (double, double), const char *funcname) if (! PyArg_UnpackTuple(args, funcname, 2, 2, &ox, &oy)) return NULL; x = PyFloat_AsDouble(ox); + if (x == -1.0 && PyErr_Occurred()) { + return NULL; + } y = PyFloat_AsDouble(oy); - if ((x == -1.0 || y == -1.0) && PyErr_Occurred()) + if (y == -1.0 && PyErr_Occurred()) { return NULL; + } errno = 0; PyFPE_START_PROTECT("in math_2", return 0); r = (*func)(x, y);