@@ -1797,6 +1797,29 @@ delta_to_microseconds(PyDateTime_Delta *self)
17971797 return result ;
17981798}
17991799
1800+ static PyObject *
1801+ checked_divmod (PyObject * a , PyObject * b )
1802+ {
1803+ PyObject * result = PyNumber_Divmod (a , b );
1804+ if (result != NULL ) {
1805+ if (!PyTuple_Check (result )) {
1806+ PyErr_Format (PyExc_TypeError ,
1807+ "divmod() returned non-tuple (type %.200s)" ,
1808+ result -> ob_type -> tp_name );
1809+ Py_DECREF (result );
1810+ return NULL ;
1811+ }
1812+ if (PyTuple_GET_SIZE (result ) != 2 ) {
1813+ PyErr_Format (PyExc_TypeError ,
1814+ "divmod() returned a tuple of size %zd" ,
1815+ PyTuple_GET_SIZE (result ));
1816+ Py_DECREF (result );
1817+ return NULL ;
1818+ }
1819+ }
1820+ return result ;
1821+ }
1822+
18001823/* Convert a number of us (as a Python int) to a timedelta.
18011824 */
18021825static PyObject *
@@ -1805,70 +1828,49 @@ microseconds_to_delta_ex(PyObject *pyus, PyTypeObject *type)
18051828 int us ;
18061829 int s ;
18071830 int d ;
1808- long temp ;
18091831
18101832 PyObject * tuple = NULL ;
18111833 PyObject * num = NULL ;
18121834 PyObject * result = NULL ;
18131835
1814- assert (PyLong_CheckExact (pyus ));
1815- tuple = PyNumber_Divmod (pyus , us_per_second );
1816- if (tuple == NULL )
1836+ tuple = checked_divmod (pyus , us_per_second );
1837+ if (tuple == NULL ) {
18171838 goto Done ;
1839+ }
18181840
1819- num = PyTuple_GetItem (tuple , 1 ); /* us */
1820- if (num == NULL )
1821- goto Done ;
1822- temp = PyLong_AsLong (num );
1841+ num = PyTuple_GET_ITEM (tuple , 1 ); /* us */
1842+ us = _PyLong_AsInt (num );
18231843 num = NULL ;
1824- if (temp == -1 && PyErr_Occurred ())
1825- goto Done ;
1826- assert (0 <= temp && temp < 1000000 );
1827- us = (int )temp ;
1828- if (us < 0 ) {
1829- /* The divisor was positive, so this must be an error. */
1830- assert (PyErr_Occurred ());
1844+ if (us == -1 && PyErr_Occurred ()) {
18311845 goto Done ;
18321846 }
1847+ if (!(0 <= us && us < 1000000 )) {
1848+ goto BadDivmod ;
1849+ }
18331850
1834- num = PyTuple_GetItem (tuple , 0 ); /* leftover seconds */
1835- if (num == NULL )
1836- goto Done ;
1851+ num = PyTuple_GET_ITEM (tuple , 0 ); /* leftover seconds */
18371852 Py_INCREF (num );
18381853 Py_DECREF (tuple );
18391854
1840- tuple = PyNumber_Divmod (num , seconds_per_day );
1855+ tuple = checked_divmod (num , seconds_per_day );
18411856 if (tuple == NULL )
18421857 goto Done ;
18431858 Py_DECREF (num );
18441859
1845- num = PyTuple_GetItem (tuple , 1 ); /* seconds */
1846- if (num == NULL )
1847- goto Done ;
1848- temp = PyLong_AsLong (num );
1860+ num = PyTuple_GET_ITEM (tuple , 1 ); /* seconds */
1861+ s = _PyLong_AsInt (num );
18491862 num = NULL ;
1850- if (temp == -1 && PyErr_Occurred ())
1851- goto Done ;
1852- assert (0 <= temp && temp < 24 * 3600 );
1853- s = (int )temp ;
1854-
1855- if (s < 0 ) {
1856- /* The divisor was positive, so this must be an error. */
1857- assert (PyErr_Occurred ());
1863+ if (s == -1 && PyErr_Occurred ()) {
18581864 goto Done ;
18591865 }
1866+ if (!(0 <= s && s < 24 * 3600 )) {
1867+ goto BadDivmod ;
1868+ }
18601869
1861- num = PyTuple_GetItem (tuple , 0 ); /* leftover days */
1862- if (num == NULL )
1863- goto Done ;
1870+ num = PyTuple_GET_ITEM (tuple , 0 ); /* leftover days */
18641871 Py_INCREF (num );
1865- temp = PyLong_AsLong (num );
1866- if (temp == -1 && PyErr_Occurred ())
1867- goto Done ;
1868- d = (int )temp ;
1869- if ((long )d != temp ) {
1870- PyErr_SetString (PyExc_OverflowError , "normalized days too "
1871- "large to fit in a C int" );
1872+ d = _PyLong_AsInt (num );
1873+ if (d == -1 && PyErr_Occurred ()) {
18721874 goto Done ;
18731875 }
18741876 result = new_delta_ex (d , s , us , 0 , type );
@@ -1877,6 +1879,11 @@ microseconds_to_delta_ex(PyObject *pyus, PyTypeObject *type)
18771879 Py_XDECREF (tuple );
18781880 Py_XDECREF (num );
18791881 return result ;
1882+
1883+ BadDivmod :
1884+ PyErr_SetString (PyExc_TypeError ,
1885+ "divmod() returned a value out of range" );
1886+ goto Done ;
18801887}
18811888
18821889#define microseconds_to_delta (pymicros ) \
@@ -1893,7 +1900,7 @@ multiply_int_timedelta(PyObject *intobj, PyDateTime_Delta *delta)
18931900 if (pyus_in == NULL )
18941901 return NULL ;
18951902
1896- pyus_out = PyNumber_Multiply (pyus_in , intobj );
1903+ pyus_out = PyNumber_Multiply (intobj , pyus_in );
18971904 Py_DECREF (pyus_in );
18981905 if (pyus_out == NULL )
18991906 return NULL ;
@@ -2297,13 +2304,12 @@ delta_divmod(PyObject *left, PyObject *right)
22972304 return NULL ;
22982305 }
22992306
2300- divmod = PyNumber_Divmod (pyus_left , pyus_right );
2307+ divmod = checked_divmod (pyus_left , pyus_right );
23012308 Py_DECREF (pyus_left );
23022309 Py_DECREF (pyus_right );
23032310 if (divmod == NULL )
23042311 return NULL ;
23052312
2306- assert (PyTuple_Size (divmod ) == 2 );
23072313 delta = microseconds_to_delta (PyTuple_GET_ITEM (divmod , 1 ));
23082314 if (delta == NULL ) {
23092315 Py_DECREF (divmod );
@@ -2334,13 +2340,11 @@ accum(const char* tag, PyObject *sofar, PyObject *num, PyObject *factor,
23342340 assert (num != NULL );
23352341
23362342 if (PyLong_Check (num )) {
2337- prod = PyNumber_Multiply (factor , num );
2343+ prod = PyNumber_Multiply (num , factor );
23382344 if (prod == NULL )
23392345 return NULL ;
2340- assert (PyLong_CheckExact (prod ));
23412346 sum = PyNumber_Add (sofar , prod );
23422347 Py_DECREF (prod );
2343- assert (sum == NULL || PyLong_CheckExact (sum ));
23442348 return sum ;
23452349 }
23462350
@@ -2398,7 +2402,6 @@ accum(const char* tag, PyObject *sofar, PyObject *num, PyObject *factor,
23982402 Py_DECREF (sum );
23992403 Py_DECREF (x );
24002404 * leftover += fracpart ;
2401- assert (y == NULL || PyLong_CheckExact (y ));
24022405 return y ;
24032406 }
24042407
0 commit comments