Skip to content

Commit 1671977

Browse files
jeplerdpgeorge
authored andcommitted
py/parsenum: Fix parsing LLONG_MIN in longlong configuration.
Re-organize `mp_parse_num_integer()` (for longlong) slightly so that the most negative 64-bit integer can be parsed. Fixes issue #17932. Signed-off-by: Jeff Epler <jepler@gmail.com>
1 parent f4f7fbf commit 1671977

File tree

3 files changed

+15
-4
lines changed

3 files changed

+15
-4
lines changed

py/objint.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -247,7 +247,7 @@ char *mp_obj_int_formatted(char **buf, size_t *buf_size, size_t *fmt_size, mp_co
247247

248248
char sign = '\0';
249249
if (num < 0) {
250-
num = -num;
250+
num = -(fmt_uint_t)num;
251251
sign = '-';
252252
}
253253

py/parsenum.c

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ typedef mp_int_t parsed_int_t;
6464
typedef unsigned long long parsed_int_t;
6565

6666
#define PARSED_INT_MUL_OVERFLOW mp_mul_ull_overflow
67-
#define PARSED_INT_FITS(I) ((I) <= (unsigned long long)LLONG_MAX)
67+
#define PARSED_INT_FITS(I) ((I) <= (unsigned long long)LLONG_MAX + 1)
6868
#endif
6969

7070
mp_obj_t mp_parse_num_integer(const char *restrict str_, size_t len, int base, mp_lexer_t *lex) {
@@ -135,8 +135,11 @@ mp_obj_t mp_parse_num_integer(const char *restrict str_, size_t len, int base, m
135135
have_ret_val:
136136
#else
137137
// The PARSED_INT_FITS check above ensures parsed_val won't overflow signed long long
138-
long long signed_val = parsed_val;
139-
if (neg) {
138+
long long signed_val = -parsed_val;
139+
if (!neg) {
140+
if (signed_val == LLONG_MIN) {
141+
goto overflow;
142+
}
140143
signed_val = -signed_val;
141144
}
142145
ret_val = mp_obj_new_int_from_ll(signed_val); // Could be large or small int

tests/basics/int_64_basics.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,3 +151,11 @@
151151
print((1 << 48) << -6)
152152
except ValueError as e:
153153
print(e)
154+
155+
# Test that the most extreme 64 bit integer values all parse with int()
156+
print(int("-9223372036854775807"))
157+
print(int("-9223372036854775808"))
158+
print(int("9223372036854775807"))
159+
160+
# Test that the most negative 64 bit integer can be formed via arithmetic
161+
print(-9223372036854775807-1)

0 commit comments

Comments
 (0)