@@ -1542,6 +1542,29 @@ delta_to_microseconds(PyDateTime_Delta *self)
15421542 return result ;
15431543}
15441544
1545+ static PyObject *
1546+ checked_divmod (PyObject * a , PyObject * b )
1547+ {
1548+ PyObject * result = PyNumber_Divmod (a , b );
1549+ if (result != NULL ) {
1550+ if (!PyTuple_Check (result )) {
1551+ PyErr_Format (PyExc_TypeError ,
1552+ "divmod() returned non-tuple (type %.200s)" ,
1553+ result -> ob_type -> tp_name );
1554+ Py_DECREF (result );
1555+ return NULL ;
1556+ }
1557+ if (PyTuple_GET_SIZE (result ) != 2 ) {
1558+ PyErr_Format (PyExc_TypeError ,
1559+ "divmod() returned a tuple of size %zd" ,
1560+ PyTuple_GET_SIZE (result ));
1561+ Py_DECREF (result );
1562+ return NULL ;
1563+ }
1564+ }
1565+ return result ;
1566+ }
1567+
15451568/* Convert a number of us (as a Python int) to a timedelta.
15461569 */
15471570static PyObject *
@@ -1550,70 +1573,49 @@ microseconds_to_delta_ex(PyObject *pyus, PyTypeObject *type)
15501573 int us ;
15511574 int s ;
15521575 int d ;
1553- long temp ;
15541576
15551577 PyObject * tuple = NULL ;
15561578 PyObject * num = NULL ;
15571579 PyObject * result = NULL ;
15581580
1559- assert (PyLong_CheckExact (pyus ));
1560- tuple = PyNumber_Divmod (pyus , us_per_second );
1561- if (tuple == NULL )
1581+ tuple = checked_divmod (pyus , us_per_second );
1582+ if (tuple == NULL ) {
15621583 goto Done ;
1584+ }
15631585
1564- num = PyTuple_GetItem (tuple , 1 ); /* us */
1565- if (num == NULL )
1566- goto Done ;
1567- temp = PyLong_AsLong (num );
1586+ num = PyTuple_GET_ITEM (tuple , 1 ); /* us */
1587+ us = _PyLong_AsInt (num );
15681588 num = NULL ;
1569- if (temp == -1 && PyErr_Occurred ())
1570- goto Done ;
1571- assert (0 <= temp && temp < 1000000 );
1572- us = (int )temp ;
1573- if (us < 0 ) {
1574- /* The divisor was positive, so this must be an error. */
1575- assert (PyErr_Occurred ());
1589+ if (us == -1 && PyErr_Occurred ()) {
15761590 goto Done ;
15771591 }
1592+ if (!(0 <= us && us < 1000000 )) {
1593+ goto BadDivmod ;
1594+ }
15781595
1579- num = PyTuple_GetItem (tuple , 0 ); /* leftover seconds */
1580- if (num == NULL )
1581- goto Done ;
1596+ num = PyTuple_GET_ITEM (tuple , 0 ); /* leftover seconds */
15821597 Py_INCREF (num );
15831598 Py_DECREF (tuple );
15841599
1585- tuple = PyNumber_Divmod (num , seconds_per_day );
1600+ tuple = checked_divmod (num , seconds_per_day );
15861601 if (tuple == NULL )
15871602 goto Done ;
15881603 Py_DECREF (num );
15891604
1590- num = PyTuple_GetItem (tuple , 1 ); /* seconds */
1591- if (num == NULL )
1592- goto Done ;
1593- temp = PyLong_AsLong (num );
1605+ num = PyTuple_GET_ITEM (tuple , 1 ); /* seconds */
1606+ s = _PyLong_AsInt (num );
15941607 num = NULL ;
1595- if (temp == -1 && PyErr_Occurred ())
1596- goto Done ;
1597- assert (0 <= temp && temp < 24 * 3600 );
1598- s = (int )temp ;
1599-
1600- if (s < 0 ) {
1601- /* The divisor was positive, so this must be an error. */
1602- assert (PyErr_Occurred ());
1608+ if (s == -1 && PyErr_Occurred ()) {
16031609 goto Done ;
16041610 }
1611+ if (!(0 <= s && s < 24 * 3600 )) {
1612+ goto BadDivmod ;
1613+ }
16051614
1606- num = PyTuple_GetItem (tuple , 0 ); /* leftover days */
1607- if (num == NULL )
1608- goto Done ;
1615+ num = PyTuple_GET_ITEM (tuple , 0 ); /* leftover days */
16091616 Py_INCREF (num );
1610- temp = PyLong_AsLong (num );
1611- if (temp == -1 && PyErr_Occurred ())
1612- goto Done ;
1613- d = (int )temp ;
1614- if ((long )d != temp ) {
1615- PyErr_SetString (PyExc_OverflowError , "normalized days too "
1616- "large to fit in a C int" );
1617+ d = _PyLong_AsInt (num );
1618+ if (d == -1 && PyErr_Occurred ()) {
16171619 goto Done ;
16181620 }
16191621 result = new_delta_ex (d , s , us , 0 , type );
@@ -1622,6 +1624,11 @@ microseconds_to_delta_ex(PyObject *pyus, PyTypeObject *type)
16221624 Py_XDECREF (tuple );
16231625 Py_XDECREF (num );
16241626 return result ;
1627+
1628+ BadDivmod :
1629+ PyErr_SetString (PyExc_TypeError ,
1630+ "divmod() returned a value out of range" );
1631+ goto Done ;
16251632}
16261633
16271634#define microseconds_to_delta (pymicros ) \
@@ -1638,7 +1645,7 @@ multiply_int_timedelta(PyObject *intobj, PyDateTime_Delta *delta)
16381645 if (pyus_in == NULL )
16391646 return NULL ;
16401647
1641- pyus_out = PyNumber_Multiply (pyus_in , intobj );
1648+ pyus_out = PyNumber_Multiply (intobj , pyus_in );
16421649 Py_DECREF (pyus_in );
16431650 if (pyus_out == NULL )
16441651 return NULL ;
@@ -2073,13 +2080,12 @@ delta_divmod(PyObject *left, PyObject *right)
20732080 return NULL ;
20742081 }
20752082
2076- divmod = PyNumber_Divmod (pyus_left , pyus_right );
2083+ divmod = checked_divmod (pyus_left , pyus_right );
20772084 Py_DECREF (pyus_left );
20782085 Py_DECREF (pyus_right );
20792086 if (divmod == NULL )
20802087 return NULL ;
20812088
2082- assert (PyTuple_Size (divmod ) == 2 );
20832089 delta = microseconds_to_delta (PyTuple_GET_ITEM (divmod , 1 ));
20842090 if (delta == NULL ) {
20852091 Py_DECREF (divmod );
@@ -2110,13 +2116,11 @@ accum(const char* tag, PyObject *sofar, PyObject *num, PyObject *factor,
21102116 assert (num != NULL );
21112117
21122118 if (PyLong_Check (num )) {
2113- prod = PyNumber_Multiply (factor , num );
2119+ prod = PyNumber_Multiply (num , factor );
21142120 if (prod == NULL )
21152121 return NULL ;
2116- assert (PyLong_CheckExact (prod ));
21172122 sum = PyNumber_Add (sofar , prod );
21182123 Py_DECREF (prod );
2119- assert (sum == NULL || PyLong_CheckExact (sum ));
21202124 return sum ;
21212125 }
21222126
@@ -2174,7 +2178,6 @@ accum(const char* tag, PyObject *sofar, PyObject *num, PyObject *factor,
21742178 Py_DECREF (sum );
21752179 Py_DECREF (x );
21762180 * leftover += fracpart ;
2177- assert (y == NULL || PyLong_CheckExact (y ));
21782181 return y ;
21792182 }
21802183
0 commit comments