- 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);