Diff
Modified: trunk/LayoutTests/ChangeLog (205296 => 205297)
--- trunk/LayoutTests/ChangeLog 2016-09-01 17:33:50 UTC (rev 205296)
+++ trunk/LayoutTests/ChangeLog 2016-09-01 17:48:25 UTC (rev 205297)
@@ -1,3 +1,17 @@
+2016-09-01 Chris Dumez <[email protected]>
+
+ Align cross-origin proto getter / setter behavior with the specification
+ https://bugs.webkit.org/show_bug.cgi?id=161455
+
+ Reviewed by Mark Lam.
+
+ Add layout test coverage.
+
+ * http/tests/security/cross-frame-access-object-getPrototypeOf-expected.txt:
+ * http/tests/security/cross-frame-access-object-getPrototypeOf.html:
+ * http/tests/security/cross-frame-access-object-setPrototypeOf-expected.txt:
+ * http/tests/security/cross-frame-access-object-setPrototypeOf.html:
+
2016-09-01 Ryan Haddad <[email protected]>
Marking media/video-main-content-allow-then-scroll.html as flaky on ios-simulator-wk2.
Modified: trunk/LayoutTests/http/tests/security/cross-frame-access-object-getPrototypeOf-expected.txt (205296 => 205297)
--- trunk/LayoutTests/http/tests/security/cross-frame-access-object-getPrototypeOf-expected.txt 2016-09-01 17:33:50 UTC (rev 205296)
+++ trunk/LayoutTests/http/tests/security/cross-frame-access-object-getPrototypeOf-expected.txt 2016-09-01 17:48:25 UTC (rev 205297)
@@ -1,9 +1,13 @@
CONSOLE MESSAGE: line 1: Blocked a frame with origin "http://127.0.0.1:8000" from accessing a frame with origin "http://localhost:8000". Protocols, domains, and ports must match.
CONSOLE MESSAGE: line 1: Blocked a frame with origin "http://127.0.0.1:8000" from accessing a frame with origin "http://localhost:8000". Protocols, domains, and ports must match.
+CONSOLE MESSAGE: line 1: Blocked a frame with origin "http://127.0.0.1:8000" from accessing a frame with origin "http://localhost:8000". Protocols, domains, and ports must match.
+CONSOLE MESSAGE: line 1: Blocked a frame with origin "http://127.0.0.1:8000" from accessing a frame with origin "http://localhost:8000". Protocols, domains, and ports must match.
This tests that you can't get the prototype of the window or history objects cross-origin using Object.getPrototypeOf().
PASS: Object.getPrototypeOf(targetWindow) should be 'null' and is.
PASS: Object.getPrototypeOf(targetWindow.location) should be 'null' and is.
+PASS: protoGetter.call(targetWindow) should be 'null' and is.
+PASS: protoGetter.call(targetWindow.location) should be 'null' and is.
PASS targetWindow.history threw exception SecurityError (DOM Exception 18): Blocked a frame with origin "http://127.0.0.1:8000" from accessing a frame with origin "http://localhost:8000". Protocols, domains, and ports must match..
PASS: successfullyParsed should be 'true' and is.
Modified: trunk/LayoutTests/http/tests/security/cross-frame-access-object-getPrototypeOf.html (205296 => 205297)
--- trunk/LayoutTests/http/tests/security/cross-frame-access-object-getPrototypeOf.html 2016-09-01 17:33:50 UTC (rev 205296)
+++ trunk/LayoutTests/http/tests/security/cross-frame-access-object-getPrototypeOf.html 2016-09-01 17:48:25 UTC (rev 205297)
@@ -18,6 +18,10 @@
shouldBeNull("Object.getPrototypeOf(targetWindow)");
shouldBeNull("Object.getPrototypeOf(targetWindow.location)");
+ protoGetter = Object.getOwnPropertyDescriptor(Object.prototype, '__proto__').get;
+ shouldBeNull("protoGetter.call(targetWindow)");
+ shouldBeNull("protoGetter.call(targetWindow.location)");
+
shouldThrowErrorName("targetWindow.history", "SecurityError");
finishJSTest();
Modified: trunk/LayoutTests/http/tests/security/cross-frame-access-object-setPrototypeOf-expected.txt (205296 => 205297)
--- trunk/LayoutTests/http/tests/security/cross-frame-access-object-setPrototypeOf-expected.txt 2016-09-01 17:33:50 UTC (rev 205296)
+++ trunk/LayoutTests/http/tests/security/cross-frame-access-object-setPrototypeOf-expected.txt 2016-09-01 17:48:25 UTC (rev 205297)
@@ -1,5 +1,7 @@
CONSOLE MESSAGE: line 1: Blocked a frame with origin "http://127.0.0.1:8000" from accessing a frame with origin "http://localhost:8000". Protocols, domains, and ports must match.
CONSOLE MESSAGE: line 1: Blocked a frame with origin "http://127.0.0.1:8000" from accessing a frame with origin "http://localhost:8000". Protocols, domains, and ports must match.
+CONSOLE MESSAGE: line 1: Blocked a frame with origin "http://127.0.0.1:8000" from accessing a frame with origin "http://localhost:8000". Protocols, domains, and ports must match.
+CONSOLE MESSAGE: line 1: Blocked a frame with origin "http://127.0.0.1:8000" from accessing a frame with origin "http://localhost:8000". Protocols, domains, and ports must match.
This tests that you can't set the prototype of the window or location objects cross-origin using Object.setPrototypeOf()
On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
@@ -11,6 +13,12 @@
PASS: targetWindow.location instanceof Array should be 'false' and is.
PASS Object.setPrototypeOf(targetWindow.location, Array.prototype) threw exception TypeError: Permission denied.
PASS: targetWindow.location instanceof Array should be 'false' and is.
+PASS: targetWindow instanceof Array should be 'false' and is.
+PASS protoSetter.call(targetWindow, Array.prototype) threw exception TypeError: Permission denied.
+PASS: targetWindow instanceof Array should be 'false' and is.
+PASS: targetWindow.location instanceof Array should be 'false' and is.
+PASS protoSetter.call(targetWindow.location, Array.prototype) threw exception TypeError: Permission denied.
+PASS: targetWindow.location instanceof Array should be 'false' and is.
PASS: successfullyParsed should be 'true' and is.
TEST COMPLETE
Modified: trunk/LayoutTests/http/tests/security/cross-frame-access-object-setPrototypeOf.html (205296 => 205297)
--- trunk/LayoutTests/http/tests/security/cross-frame-access-object-setPrototypeOf.html 2016-09-01 17:33:50 UTC (rev 205296)
+++ trunk/LayoutTests/http/tests/security/cross-frame-access-object-setPrototypeOf.html 2016-09-01 17:48:25 UTC (rev 205297)
@@ -24,6 +24,15 @@
shouldThrowErrorName("Object.setPrototypeOf(targetWindow.location, Array.prototype)", "TypeError");
shouldBeFalse("targetWindow.location instanceof Array");
+ protoSetter = Object.getOwnPropertyDescriptor(Object.prototype, '__proto__').set;
+ shouldBeFalse("targetWindow instanceof Array");
+ shouldThrowErrorName("protoSetter.call(targetWindow, Array.prototype)", "TypeError");
+ shouldBeFalse("targetWindow instanceof Array");
+
+ shouldBeFalse("targetWindow.location instanceof Array");
+ shouldThrowErrorName("protoSetter.call(targetWindow.location, Array.prototype)", "TypeError");
+ shouldBeFalse("targetWindow.location instanceof Array");
+
finishJSTest();
}
</script>
Modified: trunk/Source/_javascript_Core/ChangeLog (205296 => 205297)
--- trunk/Source/_javascript_Core/ChangeLog 2016-09-01 17:33:50 UTC (rev 205296)
+++ trunk/Source/_javascript_Core/ChangeLog 2016-09-01 17:48:25 UTC (rev 205297)
@@ -1,3 +1,27 @@
+2016-09-01 Chris Dumez <[email protected]>
+
+ Align cross-origin proto getter / setter behavior with the specification
+ https://bugs.webkit.org/show_bug.cgi?id=161455
+
+ Reviewed by Mark Lam.
+
+ Align cross-origin proto getter / setter behavior with the specification:
+
+ The setter should throw a TypeError:
+ - https://html.spec.whatwg.org/#windowproxy-setprototypeof
+ - https://html.spec.whatwg.org/#location-setprototypeof
+ - https://tc39.github.io/ecma262/#sec-object.setprototypeof (step 5)
+
+ The getter should return null:
+ - https://html.spec.whatwg.org/#windowproxy-getprototypeof
+ - https://html.spec.whatwg.org/#location-getprototypeof
+
+ I have verified that this aligns our behavior with Firefox and Chrome.
+
+ * runtime/JSGlobalObjectFunctions.cpp:
+ (JSC::GlobalFuncProtoGetterFunctor::operator()):
+ (JSC::globalFuncProtoSetter):
+
2016-09-01 Csaba Osztrogonác <[email protected]>
Unreviewed ARM buildfix after r205283.
Modified: trunk/Source/_javascript_Core/runtime/JSGlobalObjectFunctions.cpp (205296 => 205297)
--- trunk/Source/_javascript_Core/runtime/JSGlobalObjectFunctions.cpp 2016-09-01 17:33:50 UTC (rev 205296)
+++ trunk/Source/_javascript_Core/runtime/JSGlobalObjectFunctions.cpp 2016-09-01 17:48:25 UTC (rev 205297)
@@ -887,6 +887,8 @@
if (m_thisObject->allowsAccessFrom(visitor->callFrame()))
m_result = JSValue::encode(m_thisObject->getPrototype(m_exec->vm(), m_exec));
+ else
+ m_result = JSValue::encode(jsNull());
return StackVisitor::Done;
}
@@ -974,8 +976,10 @@
if (!thisObject)
return JSValue::encode(jsUndefined());
- if (!checkProtoSetterAccessAllowed(exec, thisObject))
+ if (!checkProtoSetterAccessAllowed(exec, thisObject)) {
+ throwTypeError(exec, scope, ASCIILiteral("Permission denied"));
return JSValue::encode(jsUndefined());
+ }
// Setting __proto__ to a non-object, non-null value is silently ignored to match Mozilla.
if (!value.isObject() && !value.isNull())