Merge pull request #87941 from AThousandShips/num_fix

[GDScript] Prevent running `String` number functions on invalid literal
This commit is contained in:
Rémi Verschelde 2024-02-05 14:53:23 +01:00
commit 2f9ea3a505
No known key found for this signature in database
GPG Key ID: C3336907360768E1
1 changed files with 14 additions and 0 deletions

View File

@ -672,6 +672,7 @@ GDScriptTokenizer::Token GDScriptTokenizer::number() {
bool has_decimal = false; bool has_decimal = false;
bool has_exponent = false; bool has_exponent = false;
bool has_error = false; bool has_error = false;
bool need_digits = false;
bool (*digit_check_func)(char32_t) = is_digit; bool (*digit_check_func)(char32_t) = is_digit;
// Sign before hexadecimal or binary. // Sign before hexadecimal or binary.
@ -686,11 +687,13 @@ GDScriptTokenizer::Token GDScriptTokenizer::number() {
// Hexadecimal. // Hexadecimal.
base = 16; base = 16;
digit_check_func = is_hex_digit; digit_check_func = is_hex_digit;
need_digits = true;
_advance(); _advance();
} else if (_peek() == 'b') { } else if (_peek() == 'b') {
// Binary. // Binary.
base = 2; base = 2;
digit_check_func = is_binary_digit; digit_check_func = is_binary_digit;
need_digits = true;
_advance(); _advance();
} }
} }
@ -717,6 +720,7 @@ GDScriptTokenizer::Token GDScriptTokenizer::number() {
} }
previous_was_underscore = true; previous_was_underscore = true;
} else { } else {
need_digits = false;
previous_was_underscore = false; previous_was_underscore = false;
} }
_advance(); _advance();
@ -820,6 +824,16 @@ GDScriptTokenizer::Token GDScriptTokenizer::number() {
} }
} }
if (need_digits) {
// No digits in hex or bin literal.
Token error = make_error(vformat(R"(Expected %s digit after "0%c".)", (base == 16 ? "hexadecimal" : "binary"), (base == 16 ? 'x' : 'b')));
error.start_column = column;
error.leftmost_column = column;
error.end_column = column + 1;
error.rightmost_column = column + 1;
return error;
}
// Detect extra decimal point. // Detect extra decimal point.
if (!has_error && has_decimal && _peek() == '.' && _peek(1) != '.') { if (!has_error && has_decimal && _peek() == '.' && _peek(1) != '.') {
Token error = make_error("Cannot use a decimal point twice in a number."); Token error = make_error("Cannot use a decimal point twice in a number.");