As crazy as it is, redefinition of global properties should work

Furthermore, some of the ES6 tests do check for this behavior (this
fixes at least 9 of the tests in /test/built-ins/Object/, maybe more
elsewhere).

createMutableBinding used hasProperty(String*) to determine whether or
not it needs to actually define a property, which checks the prototype
chain.

This would be fine, but when writing values to properties, we used find() on
the InternalClass (which is equivilent to Object::hasOwnProperty), which
would fail as the property doesn't "really" exist on the object, it's somewhere
in the prototype chain. Thus, we'd incorrectly throw an exception in strict mode.

I see no regressions in ES5 from this change.

Change-Id: I3b097306f220a891955ec11eea860264746bc0ee
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
This commit is contained in:
Robin Burchell 2017-02-09 00:42:30 +01:00
parent 62268fb2a0
commit bdb20c74eb
2 changed files with 16 additions and 1 deletions

View File

@ -155,7 +155,7 @@ void ExecutionContext::createMutableBinding(String *name, bool deletable)
ctx = ctx->d()->outer;
}
if (activation->hasProperty(name))
if (activation->hasOwnProperty(name))
return;
ScopedProperty desc(scope);
PropertyAttributes attrs(Attr_Data);

View File

@ -336,6 +336,7 @@ private slots:
void instanceof();
void constkw_data();
void constkw();
void redefineGlobalProp();
private:
// static void propertyVarWeakRefCallback(v8::Persistent<v8::Value> object, void* parameter);
@ -8273,6 +8274,20 @@ void tst_qqmlecmascript::constkw()
}
}
// Redefine a property found on the global object. It shouldn't throw.
void tst_qqmlecmascript::redefineGlobalProp()
{
{
QJSEngine engine;
QJSValue ret = engine.evaluate("\"use strict\"\n var toString = 1;");
QVERIFY2(!ret.isError(), qPrintable(ret.toString()));
}
{
QJSEngine engine;
QJSValue ret = engine.evaluate("var toString = 1;");
QVERIFY2(!ret.isError(), qPrintable(ret.toString()));
}
}
QTEST_MAIN(tst_qqmlecmascript)