summaryrefslogtreecommitdiffstats
path: root/Python/ast_opt.c
diff options
context:
space:
mode:
authorSerhiy Storchaka <storchaka@gmail.com>2024-09-29 07:40:20 (GMT)
committerGitHub <noreply@github.com>2024-09-29 07:40:20 (GMT)
commitd08c7888229e78533648191dfe42e2d2d3ecea25 (patch)
tree4b638a62a9e80d43573856ed8f081a65ae45ab8a /Python/ast_opt.c
parente0a41a5dd12cb6e9277b05abebac5c70be684dd7 (diff)
downloadcpython-d08c7888229e78533648191dfe42e2d2d3ecea25.zip
cpython-d08c7888229e78533648191dfe42e2d2d3ecea25.tar.gz
cpython-d08c7888229e78533648191dfe42e2d2d3ecea25.tar.bz2
gh-123497: New limit for Python integers on 64-bit platforms (GH-123724)
Instead of be limited just by the size of addressable memory (2**63 bytes), Python integers are now also limited by the number of bits, so the number of bit now always fit in a 64-bit integer. Both limits are much larger than what might be available in practice, so it doesn't affect users. _PyLong_NumBits() and _PyLong_Frexp() are now always successful.
Diffstat (limited to 'Python/ast_opt.c')
-rw-r--r--Python/ast_opt.c23
1 files changed, 12 insertions, 11 deletions
diff --git a/Python/ast_opt.c b/Python/ast_opt.c
index f5b0475..01e208b 100644
--- a/Python/ast_opt.c
+++ b/Python/ast_opt.c
@@ -169,11 +169,10 @@ safe_multiply(PyObject *v, PyObject *w)
if (PyLong_Check(v) && PyLong_Check(w) &&
!_PyLong_IsZero((PyLongObject *)v) && !_PyLong_IsZero((PyLongObject *)w)
) {
- uint64_t vbits = _PyLong_NumBits(v);
- uint64_t wbits = _PyLong_NumBits(w);
- if (vbits == (uint64_t)-1 || wbits == (uint64_t)-1) {
- return NULL;
- }
+ int64_t vbits = _PyLong_NumBits(v);
+ int64_t wbits = _PyLong_NumBits(w);
+ assert(vbits >= 0);
+ assert(wbits >= 0);
if (vbits + wbits > MAX_INT_SIZE) {
return NULL;
}
@@ -215,12 +214,13 @@ safe_power(PyObject *v, PyObject *w)
if (PyLong_Check(v) && PyLong_Check(w) &&
!_PyLong_IsZero((PyLongObject *)v) && _PyLong_IsPositive((PyLongObject *)w)
) {
- uint64_t vbits = _PyLong_NumBits(v);
+ int64_t vbits = _PyLong_NumBits(v);
size_t wbits = PyLong_AsSize_t(w);
- if (vbits == (uint64_t)-1 || wbits == (size_t)-1) {
+ assert(vbits >= 0);
+ if (wbits == (size_t)-1) {
return NULL;
}
- if (vbits > MAX_INT_SIZE / wbits) {
+ if ((uint64_t)vbits > MAX_INT_SIZE / wbits) {
return NULL;
}
}
@@ -234,12 +234,13 @@ safe_lshift(PyObject *v, PyObject *w)
if (PyLong_Check(v) && PyLong_Check(w) &&
!_PyLong_IsZero((PyLongObject *)v) && !_PyLong_IsZero((PyLongObject *)w)
) {
- uint64_t vbits = _PyLong_NumBits(v);
+ int64_t vbits = _PyLong_NumBits(v);
size_t wbits = PyLong_AsSize_t(w);
- if (vbits == (uint64_t)-1 || wbits == (size_t)-1) {
+ assert(vbits >= 0);
+ if (wbits == (size_t)-1) {
return NULL;
}
- if (wbits > MAX_INT_SIZE || vbits > MAX_INT_SIZE - wbits) {
+ if (wbits > MAX_INT_SIZE || (uint64_t)vbits > MAX_INT_SIZE - wbits) {
return NULL;
}
}