Title: [103697] trunk
Revision
103697
Author
[email protected]
Date
2011-12-26 20:56:37 -0800 (Mon, 26 Dec 2011)

Log Message

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.

Source/_javascript_Core: 

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:

LayoutTests: 

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.

Modified Paths

Added Paths

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;
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to