kopia lustrzana https://github.com/micropython/micropython
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
rodzic
16b89c3c8e
commit
7568b3b105
|
@ -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;
|
return o;
|
||||||
} else if (mp_get_buffer(args[0], &bufinfo, MP_BUFFER_READ)) {
|
} else if (mp_get_buffer(args[0], &bufinfo, MP_BUFFER_READ)) {
|
||||||
// a textual representation, parse it
|
// 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
|
#if MICROPY_PY_BUILTINS_FLOAT
|
||||||
} else if (mp_obj_is_float(args[0])) {
|
} else if (mp_obj_is_float(args[0])) {
|
||||||
return mp_obj_new_int_from_float(mp_obj_float_get(args[0]));
|
return mp_obj_new_int_from_float(mp_obj_float_get(args[0]));
|
||||||
|
|
|
@ -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
|
// string should be an integer number
|
||||||
mp_int_t int_val = 0;
|
mp_int_t int_val = 0;
|
||||||
const byte *restrict str_val_start = str;
|
const byte *restrict str_val_start = str;
|
||||||
|
if (base == 0) {
|
||||||
|
goto value_error;
|
||||||
|
}
|
||||||
for (; str < top; str++) {
|
for (; str < top; str++) {
|
||||||
// get next digit as a value
|
// get next digit as a value
|
||||||
mp_uint_t dig = *str;
|
mp_uint_t dig = *str;
|
||||||
|
|
|
@ -27,9 +27,20 @@
|
||||||
#include "py/mpconfig.h"
|
#include "py/mpconfig.h"
|
||||||
#include "py/misc.h"
|
#include "py/misc.h"
|
||||||
#include "py/parsenumbase.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'
|
// 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 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) {
|
size_t mp_parse_num_base(const char *str, size_t len, int *base) {
|
||||||
const byte *p = (const byte *)str;
|
const byte *p = (const byte *)str;
|
||||||
if (len <= 1) {
|
if (len <= 1) {
|
||||||
|
@ -49,6 +60,9 @@ size_t mp_parse_num_base(const char *str, size_t len, int *base) {
|
||||||
*base = 10;
|
*base = 10;
|
||||||
}
|
}
|
||||||
p -= 2;
|
p -= 2;
|
||||||
|
if (!is_all_zeros(str, len)) {
|
||||||
|
*base = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else if (*base == 8 && c == '0') {
|
} else if (*base == 8 && c == '0') {
|
||||||
c = *(p++);
|
c = *(p++);
|
||||||
|
|
|
@ -13,6 +13,7 @@ print(int('1'))
|
||||||
print(int('+1'))
|
print(int('+1'))
|
||||||
print(int('-1'))
|
print(int('-1'))
|
||||||
print(int('01'))
|
print(int('01'))
|
||||||
|
print(int('00'))
|
||||||
print(int('9'))
|
print(int('9'))
|
||||||
print(int('10'))
|
print(int('10'))
|
||||||
print(int('+10'))
|
print(int('+10'))
|
||||||
|
@ -31,6 +32,7 @@ print(int(' -3 '))
|
||||||
print(int('0', 10))
|
print(int('0', 10))
|
||||||
print(int('1', 10))
|
print(int('1', 10))
|
||||||
print(int(' \t 1 \t ', 10))
|
print(int(' \t 1 \t ', 10))
|
||||||
|
print(int(' \t 00 \t ', 10))
|
||||||
print(int('11', 10))
|
print(int('11', 10))
|
||||||
print(int('11', 16))
|
print(int('11', 16))
|
||||||
print(int('11', 8))
|
print(int('11', 8))
|
||||||
|
@ -79,6 +81,7 @@ test('0o8', 8)
|
||||||
test('0xg', 16)
|
test('0xg', 16)
|
||||||
test('1 1', 16)
|
test('1 1', 16)
|
||||||
test('123', 37)
|
test('123', 37)
|
||||||
|
test('01', 0)
|
||||||
|
|
||||||
# check that we don't parse this as a floating point number
|
# check that we don't parse this as a floating point number
|
||||||
print(0x1e+1)
|
print(0x1e+1)
|
||||||
|
|
|
@ -83,3 +83,11 @@ try:
|
||||||
exec(r"'\U0000000'")
|
exec(r"'\U0000000'")
|
||||||
except SyntaxError:
|
except SyntaxError:
|
||||||
print("SyntaxError")
|
print("SyntaxError")
|
||||||
|
|
||||||
|
# Properly formed integer literals
|
||||||
|
print(eval("00"))
|
||||||
|
# badly formed integer literals
|
||||||
|
try:
|
||||||
|
eval("01")
|
||||||
|
except SyntaxError:
|
||||||
|
print("SyntaxError")
|
||||||
|
|
Ładowanie…
Reference in New Issue