From c194afd17c501195a7598e4f07c8f040d0d66221 Mon Sep 17 00:00:00 2001 From: Hendi Date: Mon, 5 Jul 2021 21:31:51 +0200 Subject: [PATCH] LibJS: Fix runaway let scope when parsing for-in/of statements This requires variables that should be exported to the script host or to other scripts to be declared as var (such as in test-common.js), since lexically-scoped variables won't be visible. --- Userland/Libraries/LibJS/Parser.cpp | 9 +++++---- Userland/Libraries/LibJS/Tests/test-common.js | 10 +++++----- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/Userland/Libraries/LibJS/Parser.cpp b/Userland/Libraries/LibJS/Parser.cpp index d488df6147..bbfceebeec 100644 --- a/Userland/Libraries/LibJS/Parser.cpp +++ b/Userland/Libraries/LibJS/Parser.cpp @@ -2033,6 +2033,11 @@ NonnullRefPtr Parser::parse_for_statement() consume(TokenType::ParenOpen); bool in_scope = false; + ScopeGuard guard([&]() { + if (in_scope) + m_state.let_scopes.take_last(); + }); + RefPtr init; if (!match(TokenType::Semicolon)) { if (match_expression()) { @@ -2075,10 +2080,6 @@ NonnullRefPtr Parser::parse_for_statement() TemporaryChange continue_change(m_state.in_continue_context, true); auto body = parse_statement(); - if (in_scope) { - m_state.let_scopes.take_last(); - } - return create_ast_node({ m_state.current_token.filename(), rule_start.position(), position() }, move(init), move(test), move(update), move(body)); } diff --git a/Userland/Libraries/LibJS/Tests/test-common.js b/Userland/Libraries/LibJS/Tests/test-common.js index 94cbbfbb4a..b192a5d9a8 100644 --- a/Userland/Libraries/LibJS/Tests/test-common.js +++ b/Userland/Libraries/LibJS/Tests/test-common.js @@ -1,10 +1,10 @@ -let describe; -let test; -let expect; +var describe; +var test; +var expect; // Stores the results of each test and suite. Has a terrible // name to avoid name collision. -let __TestResults__ = {}; +var __TestResults__ = {}; // So test names like "toString" don't automatically produce an error Object.setPrototypeOf(__TestResults__, null); @@ -12,7 +12,7 @@ Object.setPrototypeOf(__TestResults__, null); // This array is used to communicate with the C++ program. It treats // each message in this array as a separate message. Has a terrible // name to avoid name collision. -let __UserOutput__ = []; +var __UserOutput__ = []; // We also rebind console.log here to use the array above console.log = (...args) => {