diff options
author | Miss Islington (bot) <31488909+miss-islington@users.noreply.github.com> | 2017-09-19 14:00:44 (GMT) |
---|---|---|
committer | Serhiy Storchaka <storchaka@gmail.com> | 2017-09-19 14:00:44 (GMT) |
commit | f37dd11f0d4832c15d49c2ddc83d533ddaa36e74 (patch) | |
tree | 44c1ef9d26aedc095e5820113bf0dfe8100aa324 /Modules/_datetimemodule.c | |
parent | 99a51d4e5b154a7b8d971090fecc1e34769a3ca1 (diff) | |
download | cpython-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.c | 37 |
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; |