@@ -1783,6 +1783,29 @@ delta_to_microseconds(PyDateTime_Delta *self)
17831783 return result ;
17841784}
17851785
1786+ static PyObject *
1787+ checked_divmod (PyObject * a , PyObject * b )
1788+ {
1789+ PyObject * result = PyNumber_Divmod (a , b );
1790+ if (result != NULL ) {
1791+ if (!PyTuple_Check (result )) {
1792+ PyErr_Format (PyExc_TypeError ,
1793+ "divmod() returned non-tuple (type %.200s)" ,
1794+ result -> ob_type -> tp_name );
1795+ Py_DECREF (result );
1796+ return NULL ;
1797+ }
1798+ if (PyTuple_GET_SIZE (result ) != 2 ) {
1799+ PyErr_Format (PyExc_TypeError ,
1800+ "divmod() returned a tuple of size %zd" ,
1801+ PyTuple_GET_SIZE (result ));
1802+ Py_DECREF (result );
1803+ return NULL ;
1804+ }
1805+ }
1806+ return result ;
1807+ }
1808+
17861809/* Convert a number of us (as a Python int) to a timedelta.
17871810 */
17881811static PyObject *
@@ -1791,70 +1814,49 @@ microseconds_to_delta_ex(PyObject *pyus, PyTypeObject *type)
17911814 int us ;
17921815 int s ;
17931816 int d ;
1794- long temp ;
17951817
17961818 PyObject * tuple = NULL ;
17971819 PyObject * num = NULL ;
17981820 PyObject * result = NULL ;
17991821
1800- assert (PyLong_CheckExact (pyus ));
1801- tuple = PyNumber_Divmod (pyus , us_per_second );
1802- if (tuple == NULL )
1822+ tuple = checked_divmod (pyus , us_per_second );
1823+ if (tuple == NULL ) {
18031824 goto Done ;
1825+ }
18041826
1805- num = PyTuple_GetItem (tuple , 1 ); /* us */
1806- if (num == NULL )
1807- goto Done ;
1808- temp = PyLong_AsLong (num );
1827+ num = PyTuple_GET_ITEM (tuple , 1 ); /* us */
1828+ us = _PyLong_AsInt (num );
18091829 num = NULL ;
1810- if (temp == -1 && PyErr_Occurred ())
1811- goto Done ;
1812- assert (0 <= temp && temp < 1000000 );
1813- us = (int )temp ;
1814- if (us < 0 ) {
1815- /* The divisor was positive, so this must be an error. */
1816- assert (PyErr_Occurred ());
1830+ if (us == -1 && PyErr_Occurred ()) {
18171831 goto Done ;
18181832 }
1833+ if (!(0 <= us && us < 1000000 )) {
1834+ goto BadDivmod ;
1835+ }
18191836
1820- num = PyTuple_GetItem (tuple , 0 ); /* leftover seconds */
1821- if (num == NULL )
1822- goto Done ;
1837+ num = PyTuple_GET_ITEM (tuple , 0 ); /* leftover seconds */
18231838 Py_INCREF (num );
18241839 Py_DECREF (tuple );
18251840
1826- tuple = PyNumber_Divmod (num , seconds_per_day );
1841+ tuple = checked_divmod (num , seconds_per_day );
18271842 if (tuple == NULL )
18281843 goto Done ;
18291844 Py_DECREF (num );
18301845
1831- num = PyTuple_GetItem (tuple , 1 ); /* seconds */
1832- if (num == NULL )
1833- goto Done ;
1834- temp = PyLong_AsLong (num );
1846+ num = PyTuple_GET_ITEM (tuple , 1 ); /* seconds */
1847+ s = _PyLong_AsInt (num );
18351848 num = NULL ;
1836- if (temp == -1 && PyErr_Occurred ())
1837- goto Done ;
1838- assert (0 <= temp && temp < 24 * 3600 );
1839- s = (int )temp ;
1840-
1841- if (s < 0 ) {
1842- /* The divisor was positive, so this must be an error. */
1843- assert (PyErr_Occurred ());
1849+ if (s == -1 && PyErr_Occurred ()) {
18441850 goto Done ;
18451851 }
1852+ if (!(0 <= s && s < 24 * 3600 )) {
1853+ goto BadDivmod ;
1854+ }
18461855
1847- num = PyTuple_GetItem (tuple , 0 ); /* leftover days */
1848- if (num == NULL )
1849- goto Done ;
1856+ num = PyTuple_GET_ITEM (tuple , 0 ); /* leftover days */
18501857 Py_INCREF (num );
1851- temp = PyLong_AsLong (num );
1852- if (temp == -1 && PyErr_Occurred ())
1853- goto Done ;
1854- d = (int )temp ;
1855- if ((long )d != temp ) {
1856- PyErr_SetString (PyExc_OverflowError , "normalized days too "
1857- "large to fit in a C int" );
1858+ d = _PyLong_AsInt (num );
1859+ if (d == -1 && PyErr_Occurred ()) {
18581860 goto Done ;
18591861 }
18601862 result = new_delta_ex (d , s , us , 0 , type );
@@ -1863,6 +1865,11 @@ microseconds_to_delta_ex(PyObject *pyus, PyTypeObject *type)
18631865 Py_XDECREF (tuple );
18641866 Py_XDECREF (num );
18651867 return result ;
1868+
1869+ BadDivmod :
1870+ PyErr_SetString (PyExc_TypeError ,
1871+ "divmod() returned a value out of range" );
1872+ goto Done ;
18661873}
18671874
18681875#define microseconds_to_delta (pymicros ) \
@@ -1879,7 +1886,7 @@ multiply_int_timedelta(PyObject *intobj, PyDateTime_Delta *delta)
18791886 if (pyus_in == NULL )
18801887 return NULL ;
18811888
1882- pyus_out = PyNumber_Multiply (pyus_in , intobj );
1889+ pyus_out = PyNumber_Multiply (intobj , pyus_in );
18831890 Py_DECREF (pyus_in );
18841891 if (pyus_out == NULL )
18851892 return NULL ;
@@ -2283,13 +2290,12 @@ delta_divmod(PyObject *left, PyObject *right)
22832290 return NULL ;
22842291 }
22852292
2286- divmod = PyNumber_Divmod (pyus_left , pyus_right );
2293+ divmod = checked_divmod (pyus_left , pyus_right );
22872294 Py_DECREF (pyus_left );
22882295 Py_DECREF (pyus_right );
22892296 if (divmod == NULL )
22902297 return NULL ;
22912298
2292- assert (PyTuple_Size (divmod ) == 2 );
22932299 delta = microseconds_to_delta (PyTuple_GET_ITEM (divmod , 1 ));
22942300 if (delta == NULL ) {
22952301 Py_DECREF (divmod );
@@ -2320,13 +2326,11 @@ accum(const char* tag, PyObject *sofar, PyObject *num, PyObject *factor,
23202326 assert (num != NULL );
23212327
23222328 if (PyLong_Check (num )) {
2323- prod = PyNumber_Multiply (factor , num );
2329+ prod = PyNumber_Multiply (num , factor );
23242330 if (prod == NULL )
23252331 return NULL ;
2326- assert (PyLong_CheckExact (prod ));
23272332 sum = PyNumber_Add (sofar , prod );
23282333 Py_DECREF (prod );
2329- assert (sum == NULL || PyLong_CheckExact (sum ));
23302334 return sum ;
23312335 }
23322336
@@ -2384,7 +2388,6 @@ accum(const char* tag, PyObject *sofar, PyObject *num, PyObject *factor,
23842388 Py_DECREF (sum );
23852389 Py_DECREF (x );
23862390 * leftover += fracpart ;
2387- assert (y == NULL || PyLong_CheckExact (y ));
23882391 return y ;
23892392 }
23902393
0 commit comments