Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 874eed6

Browse files
[3.12] gh-121153: Fix some errors with use of _PyLong_CompactValue() (GH-121154)
* The result has type Py_ssize_t, not intptr_t. * Type cast between unsigned and signed integer types should be explicit. * Downcasting should be explicit. * Fix integer overflow check in sum(). (cherry picked from commit 1801545)
1 parent 6a19d22 commit 874eed6

File tree

2 files changed

+57
-15
lines changed

2 files changed

+57
-15
lines changed

Objects/longobject.c

Lines changed: 55 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -484,11 +484,18 @@ PyLong_AsLongAndOverflow(PyObject *vv, int *overflow)
484484
do_decref = 1;
485485
}
486486
if (_PyLong_IsCompact(v)) {
487-
#if SIZEOF_LONG < SIZEOF_VOID_P
488-
intptr_t tmp = _PyLong_CompactValue(v);
489-
res = (long)tmp;
490-
if (res != tmp) {
491-
*overflow = tmp < 0 ? -1 : 1;
487+
#if SIZEOF_LONG < SIZEOF_SIZE_T
488+
Py_ssize_t tmp = _PyLong_CompactValue(v);
489+
if (tmp < LONG_MIN) {
490+
*overflow = -1;
491+
res = -1;
492+
}
493+
else if (tmp > LONG_MAX) {
494+
*overflow = 1;
495+
res = -1;
496+
}
497+
else {
498+
res = (long)tmp;
492499
}
493500
#else
494501
res = _PyLong_CompactValue(v);
@@ -633,14 +640,15 @@ PyLong_AsUnsignedLong(PyObject *vv)
633640

634641
v = (PyLongObject *)vv;
635642
if (_PyLong_IsNonNegativeCompact(v)) {
636-
#if SIZEOF_LONG < SIZEOF_VOID_P
637-
intptr_t tmp = _PyLong_CompactValue(v);
643+
#if SIZEOF_LONG < SIZEOF_SIZE_T
644+
size_t tmp = (size_t)_PyLong_CompactValue(v);
638645
unsigned long res = (unsigned long)tmp;
639646
if (res != tmp) {
640647
goto overflow;
641648
}
649+
return res;
642650
#else
643-
return _PyLong_CompactValue(v);
651+
return (unsigned long)(size_t)_PyLong_CompactValue(v);
644652
#endif
645653
}
646654
if (_PyLong_IsNegative(v)) {
@@ -686,7 +694,7 @@ PyLong_AsSize_t(PyObject *vv)
686694

687695
v = (PyLongObject *)vv;
688696
if (_PyLong_IsNonNegativeCompact(v)) {
689-
return _PyLong_CompactValue(v);
697+
return (size_t)_PyLong_CompactValue(v);
690698
}
691699
if (_PyLong_IsNegative(v)) {
692700
PyErr_SetString(PyExc_OverflowError,
@@ -723,7 +731,11 @@ _PyLong_AsUnsignedLongMask(PyObject *vv)
723731
}
724732
v = (PyLongObject *)vv;
725733
if (_PyLong_IsCompact(v)) {
726-
return (unsigned long)_PyLong_CompactValue(v);
734+
#if SIZEOF_LONG < SIZEOF_SIZE_T
735+
return (unsigned long)(size_t)_PyLong_CompactValue(v);
736+
#else
737+
return (unsigned long)(long)_PyLong_CompactValue(v);
738+
#endif
727739
}
728740
i = _PyLong_DigitCount(v);
729741
int sign = _PyLong_NonCompactSign(v);
@@ -1267,7 +1279,18 @@ PyLong_AsUnsignedLongLong(PyObject *vv)
12671279
v = (PyLongObject*)vv;
12681280
if (_PyLong_IsNonNegativeCompact(v)) {
12691281
res = 0;
1270-
bytes = _PyLong_CompactValue(v);
1282+
#if SIZEOF_LONG_LONG < SIZEOF_SIZE_T
1283+
size_t tmp = (size_t)_PyLong_CompactValue(v);
1284+
bytes = (unsigned long long)tmp;
1285+
if (bytes != tmp) {
1286+
PyErr_SetString(PyExc_OverflowError,
1287+
"Python int too large to convert "
1288+
"to C unsigned long long");
1289+
res = -1;
1290+
}
1291+
#else
1292+
bytes = (unsigned long long)(size_t)_PyLong_CompactValue(v);
1293+
#endif
12711294
}
12721295
else {
12731296
res = _PyLong_AsByteArray((PyLongObject *)vv, (unsigned char *)&bytes,
@@ -1298,7 +1321,11 @@ _PyLong_AsUnsignedLongLongMask(PyObject *vv)
12981321
}
12991322
v = (PyLongObject *)vv;
13001323
if (_PyLong_IsCompact(v)) {
1301-
return (unsigned long long)(signed long long)_PyLong_CompactValue(v);
1324+
#if SIZEOF_LONG_LONG < SIZEOF_SIZE_T
1325+
return (unsigned long long)(size_t)_PyLong_CompactValue(v);
1326+
#else
1327+
return (unsigned long long)(long long)_PyLong_CompactValue(v);
1328+
#endif
13021329
}
13031330
i = _PyLong_DigitCount(v);
13041331
sign = _PyLong_NonCompactSign(v);
@@ -1370,7 +1397,22 @@ PyLong_AsLongLongAndOverflow(PyObject *vv, int *overflow)
13701397
do_decref = 1;
13711398
}
13721399
if (_PyLong_IsCompact(v)) {
1400+
#if SIZEOF_LONG_LONG < SIZEOF_SIZE_T
1401+
Py_ssize_t tmp = _PyLong_CompactValue(v);
1402+
if (tmp < LLONG_MIN) {
1403+
*overflow = -1;
1404+
res = -1;
1405+
}
1406+
else if (tmp > LLONG_MAX) {
1407+
*overflow = 1;
1408+
res = -1;
1409+
}
1410+
else {
1411+
res = (long long)tmp;
1412+
}
1413+
#else
13731414
res = _PyLong_CompactValue(v);
1415+
#endif
13741416
}
13751417
else {
13761418
i = _PyLong_DigitCount(v);
@@ -3308,7 +3350,7 @@ long_hash(PyLongObject *v)
33083350
int sign;
33093351

33103352
if (_PyLong_IsCompact(v)) {
3311-
x = _PyLong_CompactValue(v);
3353+
x = (Py_uhash_t)_PyLong_CompactValue(v);
33123354
if (x == (Py_uhash_t)-1) {
33133355
x = (Py_uhash_t)-2;
33143356
}

Python/bltinmodule.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2559,8 +2559,8 @@ builtin_sum_impl(PyObject *module, PyObject *iterable, PyObject *start)
25592559
b = PyLong_AsLongAndOverflow(item, &overflow);
25602560
}
25612561
if (overflow == 0 &&
2562-
(i_result >= 0 ? (b <= LONG_MAX - i_result)
2563-
: (b >= LONG_MIN - i_result)))
2562+
(i_result >= 0 ? (b <= PY_SSIZE_T_MAX - i_result)
2563+
: (b >= PY_SSIZE_T_MIN - i_result)))
25642564
{
25652565
i_result += b;
25662566
Py_DECREF(item);

0 commit comments

Comments
 (0)