Diff
Modified: trunk/LayoutTests/ChangeLog (103696 => 103697)
--- trunk/LayoutTests/ChangeLog 2011-12-27 04:38:33 UTC (rev 103696)
+++ trunk/LayoutTests/ChangeLog 2011-12-27 04:56:37 UTC (rev 103697)
@@ -1,3 +1,19 @@
+2011-12-26 Gavin Barraclough <[email protected]>
+
+ https://bugs.webkit.org/show_bug.cgi?id=75231
+ Fail to throw in strict mode on assign to read only static properties
+
+ Reviewed by Filip Pizlo.
+
+ Added test cases / updated now-passing results.
+
+ * fast/js/mozilla/strict/15.10.7-expected.txt:
+ * fast/js/script-tests/strict-readonly-statics.js: Added.
+ (testWindowUndefined):
+ (testNumberMAX_VALUE):
+ * fast/js/strict-readonly-statics-expected.txt: Added.
+ * fast/js/strict-readonly-statics.html: Added.
+
2011-12-26 Ryosuke Niwa <[email protected]>
Update Chromium test expectations.
Modified: trunk/LayoutTests/fast/js/mozilla/strict/15.10.7-expected.txt (103696 => 103697)
--- trunk/LayoutTests/fast/js/mozilla/strict/15.10.7-expected.txt 2011-12-27 04:38:33 UTC (rev 103696)
+++ trunk/LayoutTests/fast/js/mozilla/strict/15.10.7-expected.txt 2011-12-27 04:56:37 UTC (rev 103697)
@@ -1,22 +1,22 @@
-FAIL 'use strict'; var r = /foo/; r.source = "bar"; r.source should throw an instance of TypeError
+PASS 'use strict'; var r = /foo/; r.source = "bar"; r.source threw exception of type TypeError.
PASS var r = /foo/; r.source = "bar"; r.source is "foo"
PASS true === true
PASS 'use strict'; var r = /foo/; delete r.source threw exception of type TypeError.
PASS var r = /foo/; delete r.source is false
PASS true === true
-FAIL 'use strict'; var r = /foo/; r.global = true; r.global should throw an instance of TypeError
+PASS 'use strict'; var r = /foo/; r.global = true; r.global threw exception of type TypeError.
PASS var r = /foo/; r.global = true; r.global is false
PASS true === true
PASS 'use strict'; var r = /foo/; delete r.global threw exception of type TypeError.
PASS var r = /foo/; delete r.global is false
PASS true === true
-FAIL 'use strict'; var r = /foo/; r.ignoreCase = true; r.ignoreCase should throw an instance of TypeError
+PASS 'use strict'; var r = /foo/; r.ignoreCase = true; r.ignoreCase threw exception of type TypeError.
PASS var r = /foo/; r.ignoreCase = true; r.ignoreCase is false
PASS true === true
PASS 'use strict'; var r = /foo/; delete r.ignoreCase threw exception of type TypeError.
PASS var r = /foo/; delete r.ignoreCase is false
PASS true === true
-FAIL 'use strict'; var r = /foo/; r.multiline = true; r.multiline should throw an instance of TypeError
+PASS 'use strict'; var r = /foo/; r.multiline = true; r.multiline threw exception of type TypeError.
PASS var r = /foo/; r.multiline = true; r.multiline is false
PASS true === true
PASS 'use strict'; var r = /foo/; delete r.multiline threw exception of type TypeError.
Added: trunk/LayoutTests/fast/js/script-tests/strict-readonly-statics.js (0 => 103697)
--- trunk/LayoutTests/fast/js/script-tests/strict-readonly-statics.js (rev 0)
+++ trunk/LayoutTests/fast/js/script-tests/strict-readonly-statics.js 2011-12-27 04:56:37 UTC (rev 103697)
@@ -0,0 +1,28 @@
+description(
+"This tests that a assigning to a readonly property in a static or symbol table throws in strict mode."
+);
+
+function testWindowUndefined()
+{
+ "use strict";
+ try {
+ window.undefined = 42;
+ } catch (e) {
+ return e instanceof TypeError;
+ }
+ return false;
+}
+
+function testNumberMAX_VALUE()
+{
+ "use strict";
+ try {
+ Number.MAX_VALUE = 42;
+ } catch (e) {
+ return e instanceof TypeError;
+ }
+ return false;
+}
+
+shouldBeTrue('testWindowUndefined()');
+shouldBeTrue('testNumberMAX_VALUE()');
Added: trunk/LayoutTests/fast/js/strict-readonly-statics-expected.txt (0 => 103697)
--- trunk/LayoutTests/fast/js/strict-readonly-statics-expected.txt (rev 0)
+++ trunk/LayoutTests/fast/js/strict-readonly-statics-expected.txt 2011-12-27 04:56:37 UTC (rev 103697)
@@ -0,0 +1,11 @@
+This tests that a assigning to a readonly property in a static or symbol table throws in strict mode.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS testWindowUndefined() is true
+PASS testNumberMAX_VALUE() is true
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
Added: trunk/LayoutTests/fast/js/strict-readonly-statics.html (0 => 103697)
--- trunk/LayoutTests/fast/js/strict-readonly-statics.html (rev 0)
+++ trunk/LayoutTests/fast/js/strict-readonly-statics.html 2011-12-27 04:56:37 UTC (rev 103697)
@@ -0,0 +1,10 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<script src=""
+</head>
+<body>
+<script src=""
+<script src=""
+</body>
+</html>
Modified: trunk/Source/_javascript_Core/ChangeLog (103696 => 103697)
--- trunk/Source/_javascript_Core/ChangeLog 2011-12-27 04:38:33 UTC (rev 103696)
+++ trunk/Source/_javascript_Core/ChangeLog 2011-12-27 04:56:37 UTC (rev 103697)
@@ -1,5 +1,33 @@
2011-12-26 Gavin Barraclough <[email protected]>
+ https://bugs.webkit.org/show_bug.cgi?id=75231
+ Fail to throw in strict mode on assign to read only static properties
+
+ Reviewed by Filip Pizlo.
+
+ There are three bugs here:
+ * symbolTablePut should throw for strict mode accesses.
+ * lookupPut should throw for strict mode accesses.
+ * NumberConstructor should override put to call lookupPut, to trap assignment to readonly properties.
+
+ * runtime/JSActivation.cpp:
+ (JSC::JSActivation::symbolTablePut):
+ (JSC::JSActivation::put):
+ * runtime/JSActivation.h:
+ * runtime/JSGlobalObject.cpp:
+ (JSC::JSGlobalObject::put):
+ * runtime/JSStaticScopeObject.cpp:
+ (JSC::JSStaticScopeObject::put):
+ * runtime/JSVariableObject.h:
+ (JSC::JSVariableObject::symbolTablePut):
+ * runtime/Lookup.h:
+ (JSC::lookupPut):
+ * runtime/NumberConstructor.cpp:
+ (JSC::NumberConstructor::put):
+ * runtime/NumberConstructor.h:
+
+2011-12-26 Gavin Barraclough <[email protected]>
+
Fix miss-commit of utf8 change.
Reviewed by Filip Pizlo
Modified: trunk/Source/_javascript_Core/runtime/JSActivation.cpp (103696 => 103697)
--- trunk/Source/_javascript_Core/runtime/JSActivation.cpp 2011-12-27 04:38:33 UTC (rev 103696)
+++ trunk/Source/_javascript_Core/runtime/JSActivation.cpp 2011-12-27 04:56:37 UTC (rev 103697)
@@ -97,15 +97,19 @@
return true;
}
-inline bool JSActivation::symbolTablePut(JSGlobalData& globalData, const Identifier& propertyName, JSValue value)
+inline bool JSActivation::symbolTablePut(ExecState* exec, const Identifier& propertyName, JSValue value, bool shouldThrow)
{
+ JSGlobalData& globalData = exec->globalData();
ASSERT(!Heap::heap(value) || Heap::heap(value) == Heap::heap(this));
SymbolTableEntry entry = symbolTable().inlineGet(propertyName.impl());
if (entry.isNull())
return false;
- if (entry.isReadOnly())
+ if (entry.isReadOnly()) {
+ if (shouldThrow)
+ throwTypeError(exec, StrictModeReadonlyPropertyWriteError);
return true;
+ }
if (entry.getIndex() >= m_numCapturedVars)
return false;
@@ -173,7 +177,7 @@
JSActivation* thisObject = jsCast<JSActivation*>(cell);
ASSERT(!Heap::heap(value) || Heap::heap(value) == Heap::heap(thisObject));
- if (thisObject->symbolTablePut(exec->globalData(), propertyName, value))
+ if (thisObject->symbolTablePut(exec, propertyName, value, slot.isStrictMode()))
return;
// We don't call through to JSObject because __proto__ and getter/setter
Modified: trunk/Source/_javascript_Core/runtime/JSActivation.h (103696 => 103697)
--- trunk/Source/_javascript_Core/runtime/JSActivation.h 2011-12-27 04:38:33 UTC (rev 103696)
+++ trunk/Source/_javascript_Core/runtime/JSActivation.h 2011-12-27 04:56:37 UTC (rev 103697)
@@ -83,7 +83,7 @@
bool symbolTableGet(const Identifier&, PropertySlot&);
bool symbolTableGet(const Identifier&, PropertyDescriptor&);
bool symbolTableGet(const Identifier&, PropertySlot&, bool& slotIsWriteable);
- bool symbolTablePut(JSGlobalData&, const Identifier&, JSValue);
+ bool symbolTablePut(ExecState*, const Identifier&, JSValue, bool shouldThrow);
bool symbolTablePutWithAttributes(JSGlobalData&, const Identifier&, JSValue, unsigned attributes);
static JSValue argumentsGetter(ExecState*, JSValue, const Identifier&);
Modified: trunk/Source/_javascript_Core/runtime/JSGlobalObject.cpp (103696 => 103697)
--- trunk/Source/_javascript_Core/runtime/JSGlobalObject.cpp 2011-12-27 04:38:33 UTC (rev 103696)
+++ trunk/Source/_javascript_Core/runtime/JSGlobalObject.cpp 2011-12-27 04:56:37 UTC (rev 103697)
@@ -148,7 +148,7 @@
JSGlobalObject* thisObject = jsCast<JSGlobalObject*>(cell);
ASSERT(!Heap::heap(value) || Heap::heap(value) == Heap::heap(thisObject));
- if (thisObject->symbolTablePut(exec->globalData(), propertyName, value))
+ if (thisObject->symbolTablePut(exec, propertyName, value, slot.isStrictMode()))
return;
JSVariableObject::put(thisObject, exec, propertyName, value, slot);
}
Modified: trunk/Source/_javascript_Core/runtime/JSStaticScopeObject.cpp (103696 => 103697)
--- trunk/Source/_javascript_Core/runtime/JSStaticScopeObject.cpp 2011-12-27 04:38:33 UTC (rev 103696)
+++ trunk/Source/_javascript_Core/runtime/JSStaticScopeObject.cpp 2011-12-27 04:56:37 UTC (rev 103697)
@@ -72,7 +72,7 @@
return;
}
}
- if (thisObject->symbolTablePut(exec->globalData(), propertyName, value))
+ if (thisObject->symbolTablePut(exec, propertyName, value, slot.isStrictMode()))
return;
ASSERT_NOT_REACHED();
Modified: trunk/Source/_javascript_Core/runtime/JSVariableObject.h (103696 => 103697)
--- trunk/Source/_javascript_Core/runtime/JSVariableObject.h 2011-12-27 04:38:33 UTC (rev 103696)
+++ trunk/Source/_javascript_Core/runtime/JSVariableObject.h 2011-12-27 04:56:37 UTC (rev 103697)
@@ -90,7 +90,7 @@
bool symbolTableGet(const Identifier&, PropertySlot&);
bool symbolTableGet(const Identifier&, PropertyDescriptor&);
bool symbolTableGet(const Identifier&, PropertySlot&, bool& slotIsWriteable);
- bool symbolTablePut(JSGlobalData&, const Identifier&, JSValue);
+ bool symbolTablePut(ExecState*, const Identifier&, JSValue, bool shouldThrow);
bool symbolTablePutWithAttributes(JSGlobalData&, const Identifier&, JSValue, unsigned attributes);
SymbolTable* m_symbolTable; // Maps name -> offset from "r" in register file.
@@ -119,15 +119,19 @@
return false;
}
- inline bool JSVariableObject::symbolTablePut(JSGlobalData& globalData, const Identifier& propertyName, JSValue value)
+ inline bool JSVariableObject::symbolTablePut(ExecState* exec, const Identifier& propertyName, JSValue value, bool shouldThrow)
{
+ JSGlobalData& globalData = exec->globalData();
ASSERT(!Heap::heap(value) || Heap::heap(value) == Heap::heap(this));
SymbolTableEntry entry = symbolTable().inlineGet(propertyName.impl());
if (entry.isNull())
return false;
- if (entry.isReadOnly())
+ if (entry.isReadOnly()) {
+ if (shouldThrow)
+ throwTypeError(exec, StrictModeReadonlyPropertyWriteError);
return true;
+ }
registerAt(entry.getIndex()).set(globalData, this, value);
return true;
}
Modified: trunk/Source/_javascript_Core/runtime/Lookup.h (103696 => 103697)
--- trunk/Source/_javascript_Core/runtime/Lookup.h 2011-12-27 04:38:33 UTC (rev 103696)
+++ trunk/Source/_javascript_Core/runtime/Lookup.h 2011-12-27 04:56:37 UTC (rev 103697)
@@ -348,10 +348,10 @@
* is found it sets the value and returns true, else it returns false.
*/
template <class ThisImp>
- inline bool lookupPut(ExecState* exec, const Identifier& propertyName, JSValue value, const HashTable* table, ThisImp* thisObj)
+ inline bool lookupPut(ExecState* exec, const Identifier& propertyName, JSValue value, const HashTable* table, ThisImp* thisObj, bool shouldThrow = false)
{
const HashEntry* entry = table->entry(exec, propertyName);
-
+
if (!entry)
return false;
@@ -360,6 +360,8 @@
thisObj->putDirect(exec->globalData(), propertyName, value);
else if (!(entry->attributes() & ReadOnly))
entry->propertyPutter()(exec, thisObj, value);
+ else if (shouldThrow)
+ throwTypeError(exec, StrictModeReadonlyPropertyWriteError);
return true;
}
@@ -373,7 +375,7 @@
template <class ThisImp, class ParentImp>
inline void lookupPut(ExecState* exec, const Identifier& propertyName, JSValue value, const HashTable* table, ThisImp* thisObj, PutPropertySlot& slot)
{
- if (!lookupPut<ThisImp>(exec, propertyName, value, table, thisObj))
+ if (!lookupPut<ThisImp>(exec, propertyName, value, table, thisObj, slot.isStrictMode()))
ParentImp::put(thisObj, exec, propertyName, value, slot); // not found: forward to parent
}
Modified: trunk/Source/_javascript_Core/runtime/NumberConstructor.cpp (103696 => 103697)
--- trunk/Source/_javascript_Core/runtime/NumberConstructor.cpp 2011-12-27 04:38:33 UTC (rev 103696)
+++ trunk/Source/_javascript_Core/runtime/NumberConstructor.cpp 2011-12-27 04:56:37 UTC (rev 103697)
@@ -83,6 +83,11 @@
return getStaticValueDescriptor<NumberConstructor, InternalFunction>(exec, ExecState::numberConstructorTable(exec), jsCast<NumberConstructor*>(object), propertyName, descriptor);
}
+void NumberConstructor::put(JSCell* cell, ExecState* exec, const Identifier& propertyName, JSValue value, PutPropertySlot& slot)
+{
+ lookupPut<NumberConstructor, InternalFunction>(exec, propertyName, value, ExecState::numberConstructorTable(exec), jsCast<NumberConstructor*>(cell), slot);
+}
+
static JSValue numberConstructorNaNValue(ExecState*, JSValue, const Identifier&)
{
return jsNaN();
Modified: trunk/Source/_javascript_Core/runtime/NumberConstructor.h (103696 => 103697)
--- trunk/Source/_javascript_Core/runtime/NumberConstructor.h 2011-12-27 04:38:33 UTC (rev 103696)
+++ trunk/Source/_javascript_Core/runtime/NumberConstructor.h 2011-12-27 04:56:37 UTC (rev 103697)
@@ -38,6 +38,8 @@
return constructor;
}
+ static void put(JSCell*, ExecState*, const Identifier& propertyName, JSValue, PutPropertySlot&);
+
static bool getOwnPropertySlot(JSCell*, ExecState*, const Identifier&, PropertySlot&);
static bool getOwnPropertyDescriptor(JSObject*, ExecState*, const Identifier&, PropertyDescriptor&);
JSValue getValueProperty(ExecState*, int token) const;