core: Throw an exception for invalid int literals like "01".

This includes making int("01") parse in base 10 like standard Python.

The new error message is different from cpython. It says e.g.,
`SyntaxError: invalid syntax for integer with base 0: '09'`

Signed-off-by: Jeff Epler <jepler@gmail.com>
pull/13576/head
Jeff Epler 2024-01-03 19:31:35 -06:00
rodzic 16b89c3c8e
commit 7568b3b105
5 zmienionych plików z 29 dodań i 1 usunięć

Wyświetl plik

@ -55,7 +55,7 @@ STATIC mp_obj_t mp_obj_int_make_new(const mp_obj_type_t *type_in, size_t n_args,
return o;
} else if (mp_get_buffer(args[0], &bufinfo, MP_BUFFER_READ)) {
// a textual representation, parse it
return mp_parse_num_integer(bufinfo.buf, bufinfo.len, 0, NULL);
return mp_parse_num_integer(bufinfo.buf, bufinfo.len, 10, NULL);
#if MICROPY_PY_BUILTINS_FLOAT
} else if (mp_obj_is_float(args[0])) {
return mp_obj_new_int_from_float(mp_obj_float_get(args[0]));

Wyświetl plik

@ -78,6 +78,9 @@ mp_obj_t mp_parse_num_integer(const char *restrict str_, size_t len, int base, m
// string should be an integer number
mp_int_t int_val = 0;
const byte *restrict str_val_start = str;
if (base == 0) {
goto value_error;
}
for (; str < top; str++) {
// get next digit as a value
mp_uint_t dig = *str;

Wyświetl plik

@ -27,9 +27,20 @@
#include "py/mpconfig.h"
#include "py/misc.h"
#include "py/parsenumbase.h"
#include "py/runtime.h"
static bool is_all_zeros(const char *str, size_t len) {
while (len-- && unichar_isdigit(*str)) {
if (*str++ != '0') {
return false;
}
}
return true;
}
// find real radix base, and strip preceding '0x', '0o' and '0b'
// puts base in *base, and returns number of bytes to skip the prefix
// puts 0 in *base to indicate an invalid C-style octal literal
size_t mp_parse_num_base(const char *str, size_t len, int *base) {
const byte *p = (const byte *)str;
if (len <= 1) {
@ -49,6 +60,9 @@ size_t mp_parse_num_base(const char *str, size_t len, int *base) {
*base = 10;
}
p -= 2;
if (!is_all_zeros(str, len)) {
*base = 0;
}
}
} else if (*base == 8 && c == '0') {
c = *(p++);

Wyświetl plik

@ -13,6 +13,7 @@ print(int('1'))
print(int('+1'))
print(int('-1'))
print(int('01'))
print(int('00'))
print(int('9'))
print(int('10'))
print(int('+10'))
@ -31,6 +32,7 @@ print(int(' -3 '))
print(int('0', 10))
print(int('1', 10))
print(int(' \t 1 \t ', 10))
print(int(' \t 00 \t ', 10))
print(int('11', 10))
print(int('11', 16))
print(int('11', 8))
@ -79,6 +81,7 @@ test('0o8', 8)
test('0xg', 16)
test('1 1', 16)
test('123', 37)
test('01', 0)
# check that we don't parse this as a floating point number
print(0x1e+1)

Wyświetl plik

@ -83,3 +83,11 @@ try:
exec(r"'\U0000000'")
except SyntaxError:
print("SyntaxError")
# Properly formed integer literals
print(eval("00"))
# badly formed integer literals
try:
eval("01")
except SyntaxError:
print("SyntaxError")