bpo-35021: Fix assertion failures in _datetimemodule.c. (GH-10039) · python/cpython@7a0d964 (original) (raw)

`@@ -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

``