bpo-35021: Fix assertion failures in _datetimemodule.c. (GH-10039) · python/cpython@d57ab8a (original) (raw)
`@@ -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
``