@@ -1783,6 +1783,29 @@ delta_to_microseconds(PyDateTime_Delta *self)
1783
1783
return result ;
1784
1784
}
1785
1785
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
+
1786
1809
/* Convert a number of us (as a Python int) to a timedelta.
1787
1810
*/
1788
1811
static PyObject *
@@ -1791,70 +1814,49 @@ microseconds_to_delta_ex(PyObject *pyus, PyTypeObject *type)
1791
1814
int us ;
1792
1815
int s ;
1793
1816
int d ;
1794
- long temp ;
1795
1817
1796
1818
PyObject * tuple = NULL ;
1797
1819
PyObject * num = NULL ;
1798
1820
PyObject * result = NULL ;
1799
1821
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 ) {
1803
1824
goto Done ;
1825
+ }
1804
1826
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 );
1809
1829
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 ()) {
1817
1831
goto Done ;
1818
1832
}
1833
+ if (!(0 <= us && us < 1000000 )) {
1834
+ goto BadDivmod ;
1835
+ }
1819
1836
1820
- num = PyTuple_GetItem (tuple , 0 ); /* leftover seconds */
1821
- if (num == NULL )
1822
- goto Done ;
1837
+ num = PyTuple_GET_ITEM (tuple , 0 ); /* leftover seconds */
1823
1838
Py_INCREF (num );
1824
1839
Py_DECREF (tuple );
1825
1840
1826
- tuple = PyNumber_Divmod (num , seconds_per_day );
1841
+ tuple = checked_divmod (num , seconds_per_day );
1827
1842
if (tuple == NULL )
1828
1843
goto Done ;
1829
1844
Py_DECREF (num );
1830
1845
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 );
1835
1848
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 ()) {
1844
1850
goto Done ;
1845
1851
}
1852
+ if (!(0 <= s && s < 24 * 3600 )) {
1853
+ goto BadDivmod ;
1854
+ }
1846
1855
1847
- num = PyTuple_GetItem (tuple , 0 ); /* leftover days */
1848
- if (num == NULL )
1849
- goto Done ;
1856
+ num = PyTuple_GET_ITEM (tuple , 0 ); /* leftover days */
1850
1857
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 ()) {
1858
1860
goto Done ;
1859
1861
}
1860
1862
result = new_delta_ex (d , s , us , 0 , type );
@@ -1863,6 +1865,11 @@ microseconds_to_delta_ex(PyObject *pyus, PyTypeObject *type)
1863
1865
Py_XDECREF (tuple );
1864
1866
Py_XDECREF (num );
1865
1867
return result ;
1868
+
1869
+ BadDivmod :
1870
+ PyErr_SetString (PyExc_TypeError ,
1871
+ "divmod() returned a value out of range" );
1872
+ goto Done ;
1866
1873
}
1867
1874
1868
1875
#define microseconds_to_delta (pymicros ) \
@@ -1879,7 +1886,7 @@ multiply_int_timedelta(PyObject *intobj, PyDateTime_Delta *delta)
1879
1886
if (pyus_in == NULL )
1880
1887
return NULL ;
1881
1888
1882
- pyus_out = PyNumber_Multiply (pyus_in , intobj );
1889
+ pyus_out = PyNumber_Multiply (intobj , pyus_in );
1883
1890
Py_DECREF (pyus_in );
1884
1891
if (pyus_out == NULL )
1885
1892
return NULL ;
@@ -2283,13 +2290,12 @@ delta_divmod(PyObject *left, PyObject *right)
2283
2290
return NULL ;
2284
2291
}
2285
2292
2286
- divmod = PyNumber_Divmod (pyus_left , pyus_right );
2293
+ divmod = checked_divmod (pyus_left , pyus_right );
2287
2294
Py_DECREF (pyus_left );
2288
2295
Py_DECREF (pyus_right );
2289
2296
if (divmod == NULL )
2290
2297
return NULL ;
2291
2298
2292
- assert (PyTuple_Size (divmod ) == 2 );
2293
2299
delta = microseconds_to_delta (PyTuple_GET_ITEM (divmod , 1 ));
2294
2300
if (delta == NULL ) {
2295
2301
Py_DECREF (divmod );
@@ -2320,13 +2326,11 @@ accum(const char* tag, PyObject *sofar, PyObject *num, PyObject *factor,
2320
2326
assert (num != NULL );
2321
2327
2322
2328
if (PyLong_Check (num )) {
2323
- prod = PyNumber_Multiply (factor , num );
2329
+ prod = PyNumber_Multiply (num , factor );
2324
2330
if (prod == NULL )
2325
2331
return NULL ;
2326
- assert (PyLong_CheckExact (prod ));
2327
2332
sum = PyNumber_Add (sofar , prod );
2328
2333
Py_DECREF (prod );
2329
- assert (sum == NULL || PyLong_CheckExact (sum ));
2330
2334
return sum ;
2331
2335
}
2332
2336
@@ -2384,7 +2388,6 @@ accum(const char* tag, PyObject *sofar, PyObject *num, PyObject *factor,
2384
2388
Py_DECREF (sum );
2385
2389
Py_DECREF (x );
2386
2390
* leftover += fracpart ;
2387
- assert (y == NULL || PyLong_CheckExact (y ));
2388
2391
return y ;
2389
2392
}
2390
2393
0 commit comments