From 8ff4587f653bdebebacd1d311a3263875c660dc7 Mon Sep 17 00:00:00 2001 From: Linus Groh Date: Thu, 28 May 2020 17:48:25 +0100 Subject: [PATCH] LibJS: Throw in strict mode when assigning property to primitive value --- Libraries/LibJS/AST.cpp | 7 ++----- Libraries/LibJS/Runtime/Reference.cpp | 5 +++++ Libraries/LibJS/Tests/strict-mode-errors.js | 18 ++++++++++++++++++ 3 files changed, 25 insertions(+), 5 deletions(-) create mode 100644 Libraries/LibJS/Tests/strict-mode-errors.js diff --git a/Libraries/LibJS/AST.cpp b/Libraries/LibJS/AST.cpp index 8b713fe036..55db8784d8 100644 --- a/Libraries/LibJS/AST.cpp +++ b/Libraries/LibJS/AST.cpp @@ -559,15 +559,12 @@ Reference Identifier::to_reference(Interpreter& interpreter) const Reference MemberExpression::to_reference(Interpreter& interpreter) const { auto object_value = m_object->execute(interpreter); - if (object_value.is_empty()) - return {}; - auto* object = object_value.to_object(interpreter); - if (!object) + if (interpreter.exception()) return {}; auto property_name = computed_property_name(interpreter); if (!property_name.is_valid()) return {}; - return { object, property_name }; + return { object_value, property_name }; } Value UnaryExpression::execute(Interpreter& interpreter) const diff --git a/Libraries/LibJS/Runtime/Reference.cpp b/Libraries/LibJS/Runtime/Reference.cpp index aa2d1ac96d..1e8bbe878f 100644 --- a/Libraries/LibJS/Runtime/Reference.cpp +++ b/Libraries/LibJS/Runtime/Reference.cpp @@ -50,6 +50,11 @@ void Reference::put(Interpreter& interpreter, Value value) return; } + if (!base().is_object() && interpreter.in_strict_mode()) { + interpreter.throw_exception(String::format("Can't assign property %s to primitive value", m_name.to_string().characters())); + return; + } + auto* object = base().to_object(interpreter); if (!object) return; diff --git a/Libraries/LibJS/Tests/strict-mode-errors.js b/Libraries/LibJS/Tests/strict-mode-errors.js new file mode 100644 index 0000000000..7695957f0d --- /dev/null +++ b/Libraries/LibJS/Tests/strict-mode-errors.js @@ -0,0 +1,18 @@ +"use strict"; + +load("test-common.js") + +try { + [true, false, "foo", 123].forEach(primitive => { + assertThrowsError(() => { + primitive.foo = "bar"; + }, { + error: TypeError, + message: "Can't assign property foo to primitive value" + }); + }); + + console.log("PASS"); +} catch (e) { + console.log("FAIL: " + e); +}