Title: [197576] trunk
Revision
197576
Author
cdu...@apple.com
Date
2016-03-04 11:30:36 -0800 (Fri, 04 Mar 2016)

Log Message

Location.reload should not be writable
https://bugs.webkit.org/show_bug.cgi?id=154989

Reviewed by Gavin Barraclough.

Source/_javascript_Core:

After r196770, operations marked as [Unforgeable] in the IDL (such as
Location.reload) are correctly reported as not writable by
Object.getOwnPropertyDescriptor(). Trying to set such property in JS
is correctly ignored (or throws in strict mode) if the object has
previously been reified. However, due to a bug in putEntry(), it was
still possible to override the property if the object was not reified
yet. This patch fixes the issue by checking in putEntry() that entries
that are functions are not ReadOnly before calling putDirect().

* runtime/Lookup.h:
(JSC::putEntry):

LayoutTests:

Add a layout test to verify that operations marked as [Unforgeable] in
IDL are indeed not writable.

* fast/html/unforgeable-operations-readonly-expected.txt: Added.
* fast/html/unforgeable-operations-readonly.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (197575 => 197576)


--- trunk/LayoutTests/ChangeLog	2016-03-04 19:26:23 UTC (rev 197575)
+++ trunk/LayoutTests/ChangeLog	2016-03-04 19:30:36 UTC (rev 197576)
@@ -1,3 +1,16 @@
+2016-03-04  Chris Dumez  <cdu...@apple.com>
+
+        Location.reload should not be writable
+        https://bugs.webkit.org/show_bug.cgi?id=154989
+
+        Reviewed by Gavin Barraclough.
+
+        Add a layout test to verify that operations marked as [Unforgeable] in
+        IDL are indeed not writable.
+
+        * fast/html/unforgeable-operations-readonly-expected.txt: Added.
+        * fast/html/unforgeable-operations-readonly.html: Added.
+
 2016-03-04  Ryan Haddad  <ryanhad...@apple.com>
 
         Rebaseline inspector/model/remote-object.html for mac after r197539

Added: trunk/LayoutTests/fast/html/unforgeable-operations-readonly-expected.txt (0 => 197576)


--- trunk/LayoutTests/fast/html/unforgeable-operations-readonly-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/fast/html/unforgeable-operations-readonly-expected.txt	2016-03-04 19:30:36 UTC (rev 197576)
@@ -0,0 +1,55 @@
+Tests that operations marked as [Unforgeable] are indeed readonly.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+* Location (non refied)
+
+- Location.reload
+PASS Object.getOwnPropertyDescriptor(testObject, testPropertyName).writable is false
+PASS testObject[testPropertyName] = false did not throw exception.
+PASS testObject[testPropertyName] is not false
+PASS 'use strict'; testObject[testPropertyName] = 3 threw exception TypeError: Attempted to assign to readonly property..
+PASS testObject[testPropertyName] is not 3
+
+- Location.assign
+PASS Object.getOwnPropertyDescriptor(testObject, testPropertyName).writable is false
+PASS testObject[testPropertyName] = false did not throw exception.
+PASS testObject[testPropertyName] is not false
+PASS 'use strict'; testObject[testPropertyName] = 3 threw exception TypeError: Attempted to assign to readonly property..
+PASS testObject[testPropertyName] is not 3
+
+- Location.replace
+PASS Object.getOwnPropertyDescriptor(testObject, testPropertyName).writable is false
+PASS testObject[testPropertyName] = false did not throw exception.
+PASS testObject[testPropertyName] is not false
+PASS 'use strict'; testObject[testPropertyName] = 3 threw exception TypeError: Attempted to assign to readonly property..
+PASS testObject[testPropertyName] is not 3
+
+* Location (reified)
+
+- Location.reload
+PASS Object.getOwnPropertyDescriptor(testObject, testPropertyName).writable is false
+PASS testObject[testPropertyName] = false did not throw exception.
+PASS testObject[testPropertyName] is not false
+PASS 'use strict'; testObject[testPropertyName] = 3 threw exception TypeError: Attempted to assign to readonly property..
+PASS testObject[testPropertyName] is not 3
+
+- Location.assign
+PASS Object.getOwnPropertyDescriptor(testObject, testPropertyName).writable is false
+PASS testObject[testPropertyName] = false did not throw exception.
+PASS testObject[testPropertyName] is not false
+PASS 'use strict'; testObject[testPropertyName] = 3 threw exception TypeError: Attempted to assign to readonly property..
+PASS testObject[testPropertyName] is not 3
+
+- Location.replace
+PASS Object.getOwnPropertyDescriptor(testObject, testPropertyName).writable is false
+PASS testObject[testPropertyName] = false did not throw exception.
+PASS testObject[testPropertyName] is not false
+PASS 'use strict'; testObject[testPropertyName] = 3 threw exception TypeError: Attempted to assign to readonly property..
+PASS testObject[testPropertyName] is not 3
+
+PASS successfullyParsed is true
+
+TEST COMPLETE
+

Added: trunk/LayoutTests/fast/html/unforgeable-operations-readonly.html (0 => 197576)


--- trunk/LayoutTests/fast/html/unforgeable-operations-readonly.html	                        (rev 0)
+++ trunk/LayoutTests/fast/html/unforgeable-operations-readonly.html	2016-03-04 19:30:36 UTC (rev 197576)
@@ -0,0 +1,43 @@
+<!DOCTYPE html>
+<script src=""
+<script>
+description("Tests that operations marked as [Unforgeable] are indeed readonly.");
+
+function className(object) {
+    return Object.prototype.toString.call(object).match(/^\[object\s(.*)\]$/)[1];
+}
+
+function checkReadOnly(object, propertyName)
+{
+    testObject = object;
+    testPropertyName = propertyName;
+
+    debug("");
+    debug("- " + className(object) + "." + propertyName);
+    shouldBeFalse("Object.getOwnPropertyDescriptor(testObject, testPropertyName).writable");
+    // Non strict mode.
+    shouldNotThrow("testObject[testPropertyName] = false");
+    shouldNotBe("testObject[testPropertyName]", "false");
+    // Strict mode.
+    shouldThrow("'use strict'; testObject[testPropertyName] = 3", "'TypeError: Attempted to assign to readonly property.'");
+    shouldNotBe("testObject[testPropertyName]", "3");
+}
+
+debug("* Location (non refied)");
+checkReadOnly(location, "reload");
+checkReadOnly(location, "assign");
+checkReadOnly(location, "replace");
+
+debug("");
+debug("* Location (reified)");
+// Reify location.
+location.newProperty = true;
+delete location.newProperty;
+// Test again.
+checkReadOnly(location, "reload");
+checkReadOnly(location, "assign");
+checkReadOnly(location, "replace");
+
+debug("");
+</script>
+<script src=""

Modified: trunk/Source/_javascript_Core/ChangeLog (197575 => 197576)


--- trunk/Source/_javascript_Core/ChangeLog	2016-03-04 19:26:23 UTC (rev 197575)
+++ trunk/Source/_javascript_Core/ChangeLog	2016-03-04 19:30:36 UTC (rev 197576)
@@ -1,3 +1,22 @@
+2016-03-04  Chris Dumez  <cdu...@apple.com>
+
+        Location.reload should not be writable
+        https://bugs.webkit.org/show_bug.cgi?id=154989
+
+        Reviewed by Gavin Barraclough.
+
+        After r196770, operations marked as [Unforgeable] in the IDL (such as
+        Location.reload) are correctly reported as not writable by
+        Object.getOwnPropertyDescriptor(). Trying to set such property in JS
+        is correctly ignored (or throws in strict mode) if the object has
+        previously been reified. However, due to a bug in putEntry(), it was
+        still possible to override the property if the object was not reified
+        yet. This patch fixes the issue by checking in putEntry() that entries
+        that are functions are not ReadOnly before calling putDirect().
+
+        * runtime/Lookup.h:
+        (JSC::putEntry):
+
 2016-03-04  Skachkov Oleksandr  <gskach...@gmail.com>
 
         [ES6] Arrow function syntax. Lexical bind "super" inside of the arrow function in generator.

Modified: trunk/Source/_javascript_Core/runtime/Lookup.h (197575 => 197576)


--- trunk/Source/_javascript_Core/runtime/Lookup.h	2016-03-04 19:26:23 UTC (rev 197575)
+++ trunk/Source/_javascript_Core/runtime/Lookup.h	2016-03-04 19:30:36 UTC (rev 197576)
@@ -286,10 +286,13 @@
 // 'slot.thisValue()' is the object the put was originally performed on (in the case of a proxy, the proxy itself).
 inline void putEntry(ExecState* exec, const HashTableValue* entry, JSObject* base, JSObject* thisValue, PropertyName propertyName, JSValue value, PutPropertySlot& slot)
 {
-    // If this is a function put it as an override property.
     if (entry->attributes() & BuiltinOrFunction) {
-        if (JSObject* thisObject = jsDynamicCast<JSObject*>(thisValue))
-            thisObject->putDirect(exec->vm(), propertyName, value);
+        if (!(entry->attributes() & ReadOnly)) {
+            // If this is a function put it as an override property.
+            if (JSObject* thisObject = jsDynamicCast<JSObject*>(thisValue))
+                thisObject->putDirect(exec->vm(), propertyName, value);
+        } else if (slot.isStrictMode())
+            throwTypeError(exec, StrictModeReadonlyPropertyWriteError);
     } else if (entry->attributes() & Accessor) {
         if (slot.isStrictMode())
             throwTypeError(exec, StrictModeReadonlyPropertyWriteError);
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to