py/parsenum: Avoid undefined behavior parsing floats with large exponents.
Fuzz testing combined with the undefined behavior sanitizer found that parsing unreasonable float literals like 1e+9999999999999 resulted in undefined behavior due to overflow in signed integer arithmetic, and a wrong result being returned.
This commit is contained in:
parent
5efc575067
commit
4f71a2a75a
|
@ -234,7 +234,12 @@ mp_obj_t mp_parse_num_decimal(const char *str, size_t len, bool allow_imag, bool
|
||||||
if ('0' <= dig && dig <= '9') {
|
if ('0' <= dig && dig <= '9') {
|
||||||
dig -= '0';
|
dig -= '0';
|
||||||
if (in == PARSE_DEC_IN_EXP) {
|
if (in == PARSE_DEC_IN_EXP) {
|
||||||
exp_val = 10 * exp_val + dig;
|
// don't overflow exp_val when adding next digit, instead just truncate
|
||||||
|
// it and the resulting float will still be correct, either inf or 0.0
|
||||||
|
// (use INT_MAX/2 to allow adding exp_extra at the end without overflow)
|
||||||
|
if (exp_val < (INT_MAX / 2 - 9) / 10) {
|
||||||
|
exp_val = 10 * exp_val + dig;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
if (dec_val < DEC_VAL_MAX) {
|
if (dec_val < DEC_VAL_MAX) {
|
||||||
// dec_val won't overflow so keep accumulating
|
// dec_val won't overflow so keep accumulating
|
||||||
|
|
Loading…
Reference in New Issue