diff options
author | davidot <david.tuin@gmail.com> | 2021-07-12 01:25:32 +0200 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2021-07-20 23:45:28 +0200 |
commit | 2a61b90fefe2064ada003d284fc37537f9efa5c8 (patch) | |
tree | 839e37343ba9b679daa83b8c689b1eab53b6ce66 | |
parent | 41ebb12c9ef58cc31a0bb6384892df265487124e (diff) | |
download | serenity-2a61b90fefe2064ada003d284fc37537f9efa5c8.zip |
LibJS: Be less strict about 'use strict'
It is allowed to have (bogus) directives e.g.
'does nothing'; 'same'; 'use strict';
Should still trigger strict mode.
-rw-r--r-- | Userland/Libraries/LibJS/Parser.cpp | 41 |
1 files changed, 33 insertions, 8 deletions
diff --git a/Userland/Libraries/LibJS/Parser.cpp b/Userland/Libraries/LibJS/Parser.cpp index da6ab77466..9a1349affc 100644 --- a/Userland/Libraries/LibJS/Parser.cpp +++ b/Userland/Libraries/LibJS/Parser.cpp @@ -286,26 +286,36 @@ NonnullRefPtr<Program> Parser::parse_program(bool starts_in_strict_mode) m_state.strict_mode = true; } - bool first = true; + bool parsing_directives = true; while (!done()) { if (match_declaration()) { program->append(parse_declaration()); + parsing_directives = false; } else if (match_statement()) { auto statement = parse_statement(); program->append(statement); if (statement_is_use_strict_directive(statement)) { - if (first) { + if (parsing_directives) { program->set_strict_mode(); m_state.strict_mode = true; } if (m_state.string_legacy_octal_escape_sequence_in_scope) syntax_error("Octal escape sequence in string literal not allowed in strict mode"); } + + if (parsing_directives && is<ExpressionStatement>(*statement)) { + auto& expression_statement = static_cast<ExpressionStatement&>(*statement); + auto& expression = expression_statement.expression(); + parsing_directives = is<StringLiteral>(expression); + } else { + parsing_directives = false; + } + } else { expected("statement or declaration"); consume(); + parsing_directives = false; } - first = false; } if (m_state.var_scopes.size() == 1) { scope.add_to_scope_node(program); @@ -1511,30 +1521,45 @@ NonnullRefPtr<BlockStatement> Parser::parse_block_statement(bool& is_strict) auto block = create_ast_node<BlockStatement>({ m_state.current_token.filename(), rule_start.position(), position() }); consume(TokenType::CurlyOpen); - bool first = true; bool initial_strict_mode_state = m_state.strict_mode; if (initial_strict_mode_state) is_strict = true; + bool parsing_directives = true; while (!done() && !match(TokenType::CurlyClose)) { if (match_declaration()) { block->append(parse_declaration()); + parsing_directives = false; } else if (match_statement()) { auto statement = parse_statement(); block->append(statement); if (statement_is_use_strict_directive(statement)) { - if (first && !initial_strict_mode_state) { - is_strict = true; - m_state.strict_mode = true; + if (parsing_directives) { + if (!initial_strict_mode_state) { + is_strict = true; + m_state.strict_mode = true; + } } if (m_state.string_legacy_octal_escape_sequence_in_scope) syntax_error("Octal escape sequence in string literal not allowed in strict mode"); + + if (has_binding) { + syntax_error("Illegal 'use strict' directive in function with non-simple parameter list"); + } + } + + if (parsing_directives && is<ExpressionStatement>(*statement)) { + auto& expression_statement = static_cast<ExpressionStatement&>(*statement); + auto& expression = expression_statement.expression(); + parsing_directives = is<StringLiteral>(expression); + } else { + parsing_directives = false; } } else { expected("statement or declaration"); consume(); + parsing_directives = false; } - first = false; } m_state.strict_mode = initial_strict_mode_state; m_state.string_legacy_octal_escape_sequence_in_scope = false; |