8000 [3.7] bpo-39871: Fix possible SystemError in atan2, copysign and rema… · python/cpython@4dcfe5f · GitHub
[go: up one dir, main page]

Skip to content

Commit 4dcfe5f

Browse files
[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 <dickinsm@gmail.com>. (cherry picked from commit 5208b4b) Co-authored-by: Zackery Spytz <zspytz@gmail.com>
1 parent 962c722 commit 4dcfe5f

File tree

3 files changed

+24
-1
lines changed

3 files changed

+24
-1
lines changed

Lib/test/test_math.py

Lines changed: 16 additions & 0 deletions
10000
Original file line numberDiff line numberDiff line change
@@ -1415,6 +1415,22 @@ def test_mtestfile(self):
14151415
self.fail('Failures in test_mtestfile:\n ' +
14161416
'\n '.join(failures))
14171417

1418+
def test_issue39871(self):
1419+
# A SystemError should not be raised if the first arg to atan2(),
1420+
# copysign(), or remainder() cannot be converted to a float.
1421+
class F:
1422+
def __float__(self):
1423+
self.converted = True
1424+
1/0
1425+
for func in math.atan2, math.copysign, math.remainder:
1426+
y = F()
1427+
with self.assertRaises(TypeError):
1428+
func("not a number", y)
1429+
1430+
# There should not have been any attempt to convert the second
1431+
# argument to a float.
1432+
self.assertFalse(getattr(y, "converted", False))
1433+
14181434
# Custom assertions.
14191435

14201436
def assertIsNaN(self, value):
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Fix a possible :exc:`SystemError` in ``math.{atan2,copysign,remainder}()``
2+
when the first argument cannot be converted to a :class:`float`. Patch by
3+
Zachary Spytz.

Modules/mathmodule.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1004,9 +1004,13 @@ math_2(PyObject *args, double (*func) (double, double), const char *funcname)
10041004
if (! PyArg_UnpackTuple(args, funcname, 2, 2, &ox, &oy))
10051005
return NULL;
10061006
x = PyFloat_AsDouble(ox);
1007+
if (x == -1.0 && PyErr_Occurred()) {
1008+
return NULL;
1009+
}
10071010
y = PyFloat_AsDouble(oy);
1008-
if ((x == -1.0 || y == -1.0) && PyErr_Occurred())
1011+
if (y == -1.0 && PyErr_Occurred()) {
10091012
return NULL;
1013+
}
10101014
errno = 0;
10111015
PyFPE_START_PROTECT("in math_2", return 0);
10121016
r = (*func)(x, y);

0 commit comments

Comments
 (0)
0