summaryrefslogtreecommitdiffstats
path: root/Modules/_datetimemodule.c
diff options
context:
space:
mode:
authorMiss Islington (bot) <31488909+miss-islington@users.noreply.github.com>2017-09-19 14:00:44 (GMT)
committerSerhiy Storchaka <storchaka@gmail.com>2017-09-19 14:00:44 (GMT)
commitf37dd11f0d4832c15d49c2ddc83d533ddaa36e74 (patch)
tree44c1ef9d26aedc095e5820113bf0dfe8100aa324 /Modules/_datetimemodule.c
parent99a51d4e5b154a7b8d971090fecc1e34769a3ca1 (diff)
downloadcpython-f37dd11f0d4832c15d49c2ddc83d533ddaa36e74.zip
cpython-f37dd11f0d4832c15d49c2ddc83d533ddaa36e74.tar.gz
cpython-f37dd11f0d4832c15d49c2ddc83d533ddaa36e74.tar.bz2
[3.6] bpo-31293: Fix crashes in truediv and mul of a timedelta by a float with a bad as_integer_ratio() method. (GH-3227) (#3654)
(cherry picked from commit 865e4b4f630e2ae91e61239258abb58b488f1d65)
Diffstat (limited to 'Modules/_datetimemodule.c')
-rw-r--r--Modules/_datetimemodule.c37
1 files changed, 33 insertions, 4 deletions
diff --git a/Modules/_datetimemodule.c b/Modules/_datetimemodule.c
index c2ad9a2..d44bb3e 100644
--- a/Modules/_datetimemodule.c
+++ b/Modules/_datetimemodule.c
@@ -1647,6 +1647,33 @@ multiply_int_timedelta(PyObject *intobj, PyDateTime_Delta *delta)
}
static PyObject *
+get_float_as_integer_ratio(PyObject *floatobj)
+{
+ PyObject *ratio;
+
+ assert(floatobj && PyFloat_Check(floatobj));
+ ratio = _PyObject_CallMethodId(floatobj, &PyId_as_integer_ratio, NULL);
+ if (ratio == NULL) {
+ return NULL;
+ }
+ if (!PyTuple_Check(ratio)) {
+ PyErr_Format(PyExc_TypeError,
+ "unexpected return type from as_integer_ratio(): "
+ "expected tuple, got '%.200s'",
+ Py_TYPE(ratio)->tp_name);
+ Py_DECREF(ratio);
+ return NULL;
+ }
+ if (PyTuple_Size(ratio) != 2) {
+ PyErr_SetString(PyExc_ValueError,
+ "as_integer_ratio() must return a 2-tuple");
+ Py_DECREF(ratio);
+ return NULL;
+ }
+ return ratio;
+}
+
+static PyObject *
multiply_float_timedelta(PyObject *floatobj, PyDateTime_Delta *delta)
{
PyObject *result = NULL;
@@ -1656,9 +1683,10 @@ multiply_float_timedelta(PyObject *floatobj, PyDateTime_Delta *delta)
pyus_in = delta_to_microseconds(delta);
if (pyus_in == NULL)
return NULL;
- ratio = _PyObject_CallMethodId(floatobj, &PyId_as_integer_ratio, NULL);
- if (ratio == NULL)
+ ratio = get_float_as_integer_ratio(floatobj);
+ if (ratio == NULL) {
goto error;
+ }
temp = PyNumber_Multiply(pyus_in, PyTuple_GET_ITEM(ratio, 0));
Py_DECREF(pyus_in);
pyus_in = NULL;
@@ -1754,9 +1782,10 @@ truedivide_timedelta_float(PyDateTime_Delta *delta, PyObject *f)
pyus_in = delta_to_microseconds(delta);
if (pyus_in == NULL)
return NULL;
- ratio = _PyObject_CallMethodId(f, &PyId_as_integer_ratio, NULL);
- if (ratio == NULL)
+ ratio = get_float_as_integer_ratio(f);
+ if (ratio == NULL) {
goto error;
+ }
temp = PyNumber_Multiply(pyus_in, PyTuple_GET_ITEM(ratio, 1));
Py_DECREF(pyus_in);
pyus_in = NULL;