1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-30 23:28:12 +00:00

LibJS: "-->" preceded by token on same line isn't start of HTML-like comment

B.1.3 HTML-like Comments

The syntax and semantics of 11.4 is extended as follows except that this
extension is not allowed when parsing source code using the goal symbol
Module:

Syntax (only relevant part included)

    SingleLineHTMLCloseComment ::
        LineTerminatorSequence HTMLCloseComment

    HTMLCloseComment ::
        WhiteSpaceSequence[opt] SingleLineDelimitedCommentSequence[opt] --> SingleLineCommentChars[opt]

Fixes #3810.
This commit is contained in:
Linus Groh 2020-10-29 17:55:24 +00:00 committed by Andreas Kling
parent a10d09faba
commit 69845ae460
3 changed files with 27 additions and 12 deletions

View file

@ -321,9 +321,14 @@ bool Lexer::is_identifier_middle() const
return is_identifier_start() || isdigit(m_current_char); return is_identifier_start() || isdigit(m_current_char);
} }
bool Lexer::is_line_comment_start() const bool Lexer::is_line_comment_start(bool line_has_token_yet) const
{ {
return match('/', '/') || match('<', '!', '-', '-') || match('-', '-', '>'); return match('/', '/')
|| match('<', '!', '-', '-')
// "-->" is considered a line comment start if the current line is only whitespace and/or
// other block comment(s); or in other words: the current line does not have a token or
// ongoing line comment yet
|| (match('-', '-', '>') && !line_has_token_yet);
} }
bool Lexer::is_block_comment_start() const bool Lexer::is_block_comment_start() const
@ -362,16 +367,22 @@ Token Lexer::next()
{ {
size_t trivia_start = m_position; size_t trivia_start = m_position;
auto in_template = !m_template_states.is_empty(); auto in_template = !m_template_states.is_empty();
bool line_has_token_yet = m_line_column > 1;
bool unterminated_comment = false; bool unterminated_comment = false;
if (!in_template || m_template_states.last().in_expr) { if (!in_template || m_template_states.last().in_expr) {
// consume whitespace and comments // consume whitespace and comments
while (true) { while (true) {
if (isspace(m_current_char) || is_line_terminator()) { if (is_line_terminator()) {
line_has_token_yet = false;
do { do {
consume(); consume();
} while (isspace(m_current_char) || is_line_terminator()); } while (is_line_terminator());
} else if (is_line_comment_start()) { } else if (isspace(m_current_char)) {
do {
consume();
} while (isspace(m_current_char));
} else if (is_line_comment_start(line_has_token_yet)) {
consume(); consume();
do { do {
consume(); consume();

View file

@ -50,7 +50,7 @@ private:
bool is_line_terminator() const; bool is_line_terminator() const;
bool is_identifier_start() const; bool is_identifier_start() const;
bool is_identifier_middle() const; bool is_identifier_middle() const;
bool is_line_comment_start() const; bool is_line_comment_start(bool line_has_token_yet) const;
bool is_block_comment_start() const; bool is_block_comment_start() const;
bool is_block_comment_end() const; bool is_block_comment_end() const;
bool is_numeric_literal_start() const; bool is_numeric_literal_start() const;

View file

@ -1,25 +1,29 @@
test("regular comments", () => { test("regular comments", () => {
const source = `var i = 0; const source = `
var i = 0;
// i++; // i++;
/* i++; */ /* i++; */
/* /*
i++; i++;
*/ */
/**/ i++;
return i;`; return i;`;
expect(source).toEvalTo(0); expect(source).toEvalTo(1);
}); });
test("html comments", () => { test("html comments", () => {
const source = `var i = 0; const source = `
var i = 0;
var j = 0;
<!-- i++; --> i++; <!-- i++; --> i++;
<!-- i++; <!-- i++;
i++; i++;
--> i++; --> i++;
/**/ --> i++;
j --> i++;
return i;`; return i;`;
expect(source).toEvalTo(2);
expect(source).toEvalTo(1);
}); });
test("unterminated multi-line comment", () => { test("unterminated multi-line comment", () => {