mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-01-24 18:24:45 -05:00
LibJS: Fix parsing of invalid numeric literals
i.e. "1e" "0x" "0b" "0o" used to be parsed as valid literals. They now produce invalid tokens. Fixes #3716
This commit is contained in:
parent
3efd4c105f
commit
2c888b3c6e
Notes:
sideshowbarker
2024-07-19 01:51:31 +09:00
Author: https://github.com/sunverwerth Commit: https://github.com/SerenityOS/serenity/commit/2c888b3c6e1 Pull-request: https://github.com/SerenityOS/serenity/pull/3789 Issue: https://github.com/SerenityOS/serenity/issues/3716
3 changed files with 63 additions and 14 deletions
|
@ -172,14 +172,56 @@ void Lexer::consume()
|
|||
m_current_char = m_source[m_position++];
|
||||
}
|
||||
|
||||
void Lexer::consume_exponent()
|
||||
bool Lexer::consume_exponent()
|
||||
{
|
||||
consume();
|
||||
if (m_current_char == '-' || m_current_char == '+')
|
||||
consume();
|
||||
|
||||
if (!isdigit(m_current_char))
|
||||
return false;
|
||||
|
||||
while (isdigit(m_current_char)) {
|
||||
consume();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Lexer::consume_octal_number()
|
||||
{
|
||||
consume();
|
||||
if (!(m_current_char >= '0' && m_current_char <= '7'))
|
||||
return false;
|
||||
|
||||
while (m_current_char >= '0' && m_current_char <= '7') {
|
||||
consume();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Lexer::consume_hexadecimal_number()
|
||||
{
|
||||
consume();
|
||||
if (!isxdigit(m_current_char))
|
||||
return false;
|
||||
|
||||
while (isxdigit(m_current_char))
|
||||
consume();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Lexer::consume_binary_number()
|
||||
{
|
||||
consume();
|
||||
if (!(m_current_char == '0' || m_current_char == '1'))
|
||||
return false;
|
||||
|
||||
while (m_current_char == '0' || m_current_char == '1')
|
||||
consume();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Lexer::match(char a, char b) const
|
||||
|
@ -355,6 +397,7 @@ Token Lexer::next()
|
|||
}
|
||||
} else if (is_numeric_literal_start()) {
|
||||
token_type = TokenType::NumericLiteral;
|
||||
bool is_invalid_numeric_literal = false;
|
||||
if (m_current_char == '0') {
|
||||
consume();
|
||||
if (m_current_char == '.') {
|
||||
|
@ -363,24 +406,18 @@ Token Lexer::next()
|
|||
while (isdigit(m_current_char))
|
||||
consume();
|
||||
if (m_current_char == 'e' || m_current_char == 'E')
|
||||
consume_exponent();
|
||||
is_invalid_numeric_literal = !consume_exponent();
|
||||
} else if (m_current_char == 'e' || m_current_char == 'E') {
|
||||
consume_exponent();
|
||||
is_invalid_numeric_literal = !consume_exponent();
|
||||
} else if (m_current_char == 'o' || m_current_char == 'O') {
|
||||
// octal
|
||||
consume();
|
||||
while (m_current_char >= '0' && m_current_char <= '7')
|
||||
consume();
|
||||
is_invalid_numeric_literal = !consume_octal_number();
|
||||
} else if (m_current_char == 'b' || m_current_char == 'B') {
|
||||
// binary
|
||||
consume();
|
||||
while (m_current_char == '0' || m_current_char == '1')
|
||||
consume();
|
||||
is_invalid_numeric_literal = !consume_binary_number();
|
||||
} else if (m_current_char == 'x' || m_current_char == 'X') {
|
||||
// hexadecimal
|
||||
consume();
|
||||
while (isxdigit(m_current_char))
|
||||
consume();
|
||||
is_invalid_numeric_literal = !consume_hexadecimal_number();
|
||||
} else if (m_current_char == 'n') {
|
||||
consume();
|
||||
token_type = TokenType::BigIntLiteral;
|
||||
|
@ -405,9 +442,11 @@ Token Lexer::next()
|
|||
consume();
|
||||
}
|
||||
if (m_current_char == 'e' || m_current_char == 'E')
|
||||
consume_exponent();
|
||||
is_invalid_numeric_literal = !consume_exponent();
|
||||
}
|
||||
}
|
||||
if (is_invalid_numeric_literal)
|
||||
token_type = TokenType::Invalid;
|
||||
} else if (m_current_char == '"' || m_current_char == '\'') {
|
||||
char stop_char = m_current_char;
|
||||
consume();
|
||||
|
|
|
@ -42,7 +42,10 @@ public:
|
|||
|
||||
private:
|
||||
void consume();
|
||||
void consume_exponent();
|
||||
bool consume_exponent();
|
||||
bool consume_octal_number();
|
||||
bool consume_hexadecimal_number();
|
||||
bool consume_binary_number();
|
||||
bool is_eof() const;
|
||||
bool is_identifier_start() const;
|
||||
bool is_identifier_middle() const;
|
||||
|
|
|
@ -35,3 +35,10 @@ test("accessing properties of decimal numbers", () => {
|
|||
expect((1.1).foo).toBe("foo");
|
||||
expect((0.1).foo).toBe("foo");
|
||||
});
|
||||
|
||||
test("invalid numeric literals", () => {
|
||||
expect("1e").not.toEval();
|
||||
expect("0x").not.toEval();
|
||||
expect("0b").not.toEval();
|
||||
expect("0o").not.toEval();
|
||||
});
|
||||
|
|
Loading…
Add table
Reference in a new issue