LibJS: Fix that constant declaration in for loop was mutable in body

This commit is contained in:
davidot 2022-11-30 01:45:35 +01:00 committed by Andreas Kling
parent 714f0c3dce
commit 8319d7ac06
3 changed files with 34 additions and 4 deletions

View file

@ -921,12 +921,22 @@ struct ForInOfHeadState {
else {
VERIFY(expression_lhs && is<VariableDeclaration>(*expression_lhs));
iteration_environment = new_declarative_environment(*interpreter.lexical_environment());
auto& for_declaration = static_cast<VariableDeclaration const&>(*expression_lhs);
// 14.7.5.4 Runtime Semantics: ForDeclarationBindingInstantiation, https://tc39.es/ecma262/#sec-runtime-semantics-fordeclarationbindinginstantiation
// 1. For each element name of the BoundNames of ForBinding, do
for_declaration.for_each_bound_name([&](auto const& name) {
if (for_declaration.declaration_kind() == DeclarationKind::Const)
MUST(iteration_environment->create_immutable_binding(vm, name, false));
else
MUST(iteration_environment->create_mutable_binding(vm, name, true));
// a. If IsConstantDeclaration of LetOrConst is true, then
if (for_declaration.is_constant_declaration()) {
// i. Perform ! environment.CreateImmutableBinding(name, true).
MUST(iteration_environment->create_immutable_binding(vm, name, true));
}
// b. Else,
else {
// i. Perform ! environment.CreateMutableBinding(name, false).
MUST(iteration_environment->create_mutable_binding(vm, name, false));
}
});
interpreter.vm().running_execution_context().lexical_environment = iteration_environment;

View file

@ -98,6 +98,16 @@ describe("special left hand sides", () => {
eval("for (f() in [0]) { expect().fail() }");
}).toThrowWithMessage(ReferenceError, "Invalid left-hand side in assignment");
});
test("Cannot change constant declaration in body", () => {
const vals = [];
for (const v in [1, 2]) {
expect(() => v++).toThrowWithMessage(TypeError, "Invalid assignment to const variable");
vals.push(v);
}
expect(vals).toEqual(["0", "1"]);
});
});
test("remove properties while iterating", () => {

View file

@ -142,4 +142,14 @@ describe("special left hand sides", () => {
eval("for (f() of [0]) { expect().fail() }");
}).toThrowWithMessage(ReferenceError, "Invalid left-hand side in assignment");
});
test("Cannot change constant declaration in body", () => {
const vals = [];
for (const v of [1, 2]) {
expect(() => v++).toThrowWithMessage(TypeError, "Invalid assignment to const variable");
vals.push(v);
}
expect(vals).toEqual([1, 2]);
});
});