@@ -1797,6 +1797,29 @@ delta_to_microseconds(PyDateTime_Delta *self)
1797
1797
return result ;
1798
1798
}
1799
1799
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
+
1800
1823
/* Convert a number of us (as a Python int) to a timedelta.
1801
1824
*/
1802
1825
static PyObject *
@@ -1805,70 +1828,49 @@ microseconds_to_delta_ex(PyObject *pyus, PyTypeObject *type)
1805
1828
int us ;
1806
1829
int s ;
1807
1830
int d ;
1808
- long temp ;
1809
1831
1810
1832
PyObject * tuple = NULL ;
1811
1833
PyObject * num = NULL ;
1812
1834
PyObject * result = NULL ;
1813
1835
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 ) {
1817
1838
goto Done ;
1839
+ }
1818
1840
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 );
1823
1843
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 ()) {
1831
1845
goto Done ;
1832
1846
}
1847
+ if (!(0 <= us && us < 1000000 )) {
1848
+ goto BadDivmod ;
1849
+ }
1833
1850
1834
- num = PyTuple_GetItem (tuple , 0 ); /* leftover seconds */
1835
- if (num == NULL )
1836
- goto Done ;
1851
+ num = PyTuple_GET_ITEM (tuple , 0 ); /* leftover seconds */
1837
1852
Py_INCREF (num );
1838
1853
Py_DECREF (tuple );
1839
1854
1840
- tuple = PyNumber_Divmod (num , seconds_per_day );
1855
+ tuple = checked_divmod (num , seconds_per_day );
1841
1856
if (tuple == NULL )
1842
1857
goto Done ;
1843
1858
Py_DECREF (num );
1844
1859
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 );
1849
1862
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 ()) {
1858
1864
goto Done ;
1859
1865
}
1866
+ if (!(0 <= s && s < 24 * 3600 )) {
1867
+ goto BadDivmod ;
1868
+ }
1860
1869
1861
- num = PyTuple_GetItem (tuple , 0 ); /* leftover days */
1862
- if (num == NULL )
1863
- goto Done ;
1870
+ num = PyTuple_GET_ITEM (tuple , 0 ); /* leftover days */
1864
1871
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 ()) {
1872
1874
goto Done ;
1873
1875
}
1874
1876
result = new_delta_ex (d , s , us , 0 , type );
@@ -1877,6 +1879,11 @@ microseconds_to_delta_ex(PyObject *pyus, PyTypeObject *type)
1877
1879
Py_XDECREF (tuple );
1878
1880
Py_XDECREF (num );
1879
1881
return result ;
1882
+
1883
+ BadDivmod :
1884
+ PyErr_SetString (PyExc_TypeError ,
1885
+ "divmod() returned a value out of range" );
1886
+ goto Done ;
1880
1887
}
1881
1888
1882
1889
#define microseconds_to_delta (pymicros ) \
@@ -1893,7 +1900,7 @@ multiply_int_timedelta(PyObject *intobj, PyDateTime_Delta *delta)
1893
1900
if (pyus_in == NULL )
1894
1901
return NULL ;
1895
1902
1896
- pyus_out = PyNumber_Multiply (pyus_in , intobj );
1903
+ pyus_out = PyNumber_Multiply (intobj , pyus_in );
1897
1904
Py_DECREF (pyus_in );
1898
1905
if (pyus_out == NULL )
1899
1906
return NULL ;
@@ -2297,13 +2304,12 @@ delta_divmod(PyObject *left, PyObject *right)
2297
2304
return NULL ;
2298
2305
}
2299
2306
2300
- divmod = PyNumber_Divmod (pyus_left , pyus_right );
2307
+ divmod = checked_divmod (pyus_left , pyus_right );
2301
2308
Py_DECREF (pyus_left );
2302
2309
Py_DECREF (pyus_right );
2303
2310
if (divmod == NULL )
2304
2311
return NULL ;
2305
2312
2306
- assert (PyTuple_Size (divmod ) == 2 );
2307
2313
delta = microseconds_to_delta (PyTuple_GET_ITEM (divmod , 1 ));
2308
2314
if (delta == NULL ) {
2309
2315
Py_DECREF (divmod );
@@ -2334,13 +2340,11 @@ accum(const char* tag, PyObject *sofar, PyObject *num, PyObject *factor,
2334
2340
assert (num != NULL );
2335
2341
2336
2342
if (PyLong_Check (num )) {
2337
- prod = PyNumber_Multiply (factor , num );
2343
+ prod = PyNumber_Multiply (num , factor );
2338
2344
if (prod == NULL )
2339
2345
return NULL ;
2340
- assert (PyLong_CheckExact (prod ));
2341
2346
sum = PyNumber_Add (sofar , prod );
2342
2347
Py_DECREF (prod );
2343
- assert (sum == NULL || PyLong_CheckExact (sum ));
2344
2348
return sum ;
2345
2349
}
2346
2350
@@ -2398,7 +2402,6 @@ accum(const char* tag, PyObject *sofar, PyObject *num, PyObject *factor,
2398
2402
Py_DECREF (sum );
2399
2403
Py_DECREF (x );
2400
2404
* leftover += fracpart ;
2401
- assert (y == NULL || PyLong_CheckExact (y ));
2402
2405
return y ;
2403
2406
}
2404
2407
0 commit comments