@@ -1542,6 +1542,29 @@ delta_to_microseconds(PyDateTime_Delta *self)
1542
1542
return result ;
1543
1543
}
1544
1544
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
+
1545
1568
/* Convert a number of us (as a Python int) to a timedelta.
1546
1569
*/
1547
1570
static PyObject *
@@ -1550,70 +1573,49 @@ microseconds_to_delta_ex(PyObject *pyus, PyTypeObject *type)
1550
1573
int us ;
1551
1574
int s ;
1552
1575
int d ;
1553
- long temp ;
1554
1576
1555
1577
PyObject * tuple = NULL ;
1556
1578
PyObject * num = NULL ;
1557
1579
PyObject * result = NULL ;
1558
1580
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 ) {
1562
1583
goto Done ;
1584
+ }
1563
1585
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 );
1568
1588
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 ()) {
1576
1590
goto Done ;
1577
1591
}
1592
+ if (!(0 <= us && us < 1000000 )) {
1593
+ goto BadDivmod ;
1594
+ }
1578
1595
1579
- num = PyTuple_GetItem (tuple , 0 ); /* leftover seconds */
1580
- if (num == NULL )
1581
- goto Done ;
1596
+ num = PyTuple_GET_ITEM (tuple , 0 ); /* leftover seconds */
1582
1597
Py_INCREF (num );
1583
1598
Py_DECREF (tuple );
1584
1599
1585
- tuple = PyNumber_Divmod (num , seconds_per_day );
1600
+ tuple = checked_divmod (num , seconds_per_day );
1586
1601
if (tuple == NULL )
1587
1602
goto Done ;
1588
1603
Py_DECREF (num );
1589
1604
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 );
1594
1607
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 ()) {
1603
1609
goto Done ;
1604
1610
}
1611
+ if (!(0 <= s && s < 24 * 3600 )) {
1612
+ goto BadDivmod ;
1613
+ }
1605
1614
1606
- num = PyTuple_GetItem (tuple , 0 ); /* leftover days */
1607
- if (num == NULL )
1608
- goto Done ;
1615
+ num = PyTuple_GET_ITEM (tuple , 0 ); /* leftover days */
1609
1616
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 ()) {
1617
1619
goto Done ;
1618
1620
}
1619
1621
result = new_delta_ex (d , s , us , 0 , type );
@@ -1622,6 +1624,11 @@ microseconds_to_delta_ex(PyObject *pyus, PyTypeObject *type)
1622
1624
Py_XDECREF (tuple );
1623
1625
Py_XDECREF (num );
1624
1626
return result ;
1627
+
1628
+ BadDivmod :
1629
+ PyErr_SetString (PyExc_TypeError ,
1630
+ "divmod() returned a value out of range" );
1631
+ goto Done ;
1625
1632
}
1626
1633
1627
1634
#define microseconds_to_delta (pymicros ) \
@@ -1638,7 +1645,7 @@ multiply_int_timedelta(PyObject *intobj, PyDateTime_Delta *delta)
1638
1645
if (pyus_in == NULL )
1639
1646
return NULL ;
1640
1647
1641
- pyus_out = PyNumber_Multiply (pyus_in , intobj );
1648
+ pyus_out = PyNumber_Multiply (intobj , pyus_in );
1642
1649
Py_DECREF (pyus_in );
1643
1650
if (pyus_out == NULL )
1644
1651
return NULL ;
@@ -2073,13 +2080,12 @@ delta_divmod(PyObject *left, PyObject *right)
2073
2080
return NULL ;
2074
2081
}
2075
2082
2076
- divmod = PyNumber_Divmod (pyus_left , pyus_right );
2083
+ divmod = checked_divmod (pyus_left , pyus_right );
2077
2084
Py_DECREF (pyus_left );
2078
2085
Py_DECREF (pyus_right );
2079
2086
if (divmod == NULL )
2080
2087
return NULL ;
2081
2088
2082
- assert (PyTuple_Size (divmod ) == 2 );
2083
2089
delta = microseconds_to_delta (PyTuple_GET_ITEM (divmod , 1 ));
2084
2090
if (delta == NULL ) {
2085
2091
Py_DECREF (divmod );
@@ -2110,13 +2116,11 @@ accum(const char* tag, PyObject *sofar, PyObject *num, PyObject *factor,
2110
2116
assert (num != NULL );
2111
2117
2112
2118
if (PyLong_Check (num )) {
2113
- prod = PyNumber_Multiply (factor , num );
2119
+ prod = PyNumber_Multiply (num , factor );
2114
2120
if (prod == NULL )
2115
2121
return NULL ;
2116
- assert (PyLong_CheckExact (prod ));
2117
2122
sum = PyNumber_Add (sofar , prod );
2118
2123
Py_DECREF (prod );
2119
- assert (sum == NULL || PyLong_CheckExact (sum ));
2120
2124
return sum ;
2121
2125
}
2122
2126
@@ -2174,7 +2178,6 @@ accum(const char* tag, PyObject *sofar, PyObject *num, PyObject *factor,
2174
2178
Py_DECREF (sum );
2175
2179
Py_DECREF (x );
2176
2180
* leftover += fracpart ;
2177
- assert (y == NULL || PyLong_CheckExact (y ));
2178
2181
return y ;
2179
2182
}
2180
2183
0 commit comments