Diff
Modified: trunk/LayoutTests/ChangeLog (237104 => 237105)
--- trunk/LayoutTests/ChangeLog 2018-10-15 14:31:39 UTC (rev 237104)
+++ trunk/LayoutTests/ChangeLog 2018-10-15 14:54:21 UTC (rev 237105)
@@ -1,3 +1,29 @@
+2018-10-15 Chris Dumez <[email protected]>
+
+ Window's properties such as 'location' should not become null when it loses its browsing context
+ https://bugs.webkit.org/show_bug.cgi?id=190539
+
+ Reviewed by Alex Christensen.
+
+ * http/tests/dom/cross-origin-detached-window-properties-expected.txt: Added.
+ * http/tests/dom/cross-origin-detached-window-properties.html: Added.
+ * http/tests/dom/resources/post-message-to-parent-when-loaded.html: Added.
+ * http/tests/dom/same-origin-detached-window-properties-expected.txt: Added.
+ * http/tests/dom/same-origin-detached-window-properties.html: Added.
+ Add layout test coverage.
+
+ * fast/frames/detached-frame-property-expected.txt:
+ * fast/frames/detached-frame-property.html:
+ * http/tests/security/named-window-property-from-same-origin-inactive-document-expected.txt:
+ * http/tests/security/named-window-property-from-same-origin-inactive-document.html:
+ * http/tests/security/xss-DENIED-named-window-property-from-cross-origin-inactive-document-expected.txt:
+ * http/tests/security/xss-DENIED-named-window-property-from-cross-origin-inactive-document.html:
+ * http/tests/security/xss-DENIED-script-inject-into-inactive-window.html:
+ * http/tests/security/xss-DENIED-script-inject-into-inactive-window2-pson.html:
+ * http/tests/security/xss-DENIED-script-inject-into-inactive-window2.html:
+ * http/tests/security/xss-DENIED-script-inject-into-inactive-window3.html:
+ Update existing layout tests to reflect behavior change.
+
2018-10-15 Claudio Saavedra <[email protected]>
[GStreamer] MediaStream test failing since r236877
Modified: trunk/LayoutTests/fast/frames/detached-frame-property-expected.txt (237104 => 237105)
--- trunk/LayoutTests/fast/frames/detached-frame-property-expected.txt 2018-10-15 14:31:39 UTC (rev 237104)
+++ trunk/LayoutTests/fast/frames/detached-frame-property-expected.txt 2018-10-15 14:54:21 UTC (rev 237105)
@@ -5,6 +5,10 @@
PASS !!detachedWindow.postMessage is true
PASS !!detachedWindow.close is true
+PASS !!detachedWindow.locationbar is true
+PASS !!detachedWindow.history is true
+PASS !!detachedWindow.screen is true
+PASS !!detachedWindow.location is true
PASS detachedWindow.closed is true
PASS detachedWindow.top is null
PASS detachedWindow.opener is null
@@ -14,16 +18,12 @@
PASS detachedWindow.frames is null
PASS detachedWindow.self is null
PASS !detachedWindow.navigator is true
-PASS !detachedWindow.locationbar is true
-PASS !detachedWindow.history is true
PASS !detachedWindow.localStorage is true
PASS !!detachedWindow.document is true
PASS !!detachedWindow.XMLHttpRequest is true
PASS !!detachedWindow.getComputedStyle is true
-PASS !detachedWindow.screen is true
PASS detachedWindow.innerHeight is 0
PASS detachedWindow.innerWidth is 0
-PASS !detachedWindow.location is true
PASS successfullyParsed is true
TEST COMPLETE
Modified: trunk/LayoutTests/fast/frames/detached-frame-property.html (237104 => 237105)
--- trunk/LayoutTests/fast/frames/detached-frame-property.html 2018-10-15 14:31:39 UTC (rev 237104)
+++ trunk/LayoutTests/fast/frames/detached-frame-property.html 2018-10-15 14:54:21 UTC (rev 237105)
@@ -9,12 +9,15 @@
// Chrome and Firefox agree with us.
shouldBeTrue("!!detachedWindow.postMessage");
shouldBeTrue("!!detachedWindow.close");
+ shouldBeTrue("!!detachedWindow.locationbar");
+ shouldBeTrue("!!detachedWindow.history");
+ shouldBeTrue("!!detachedWindow.screen");
+ shouldBeTrue("!!detachedWindow.location");
shouldBeTrue("detachedWindow.closed");
shouldBeNull("detachedWindow.top");
shouldBeNull("detachedWindow.opener");
shouldBeNull("detachedWindow.parent");
shouldBeNull("detachedWindow.frameElement"); // Technically, Chrome returns undefined here, not null.
-
// Chrome agrees with us but Firefox returns the detachedWindow.
shouldBeNull("detachedWindow.window");
shouldBeNull("detachedWindow.frames");
@@ -22,8 +25,6 @@
// Chrome returns undefined but Firefox has a valid object.
shouldBeTrue("!detachedWindow.navigator");
- shouldBeTrue("!detachedWindow.locationbar");
- shouldBeTrue("!detachedWindow.history");
shouldBeTrue("!detachedWindow.localStorage");
shouldBeTrue("!!detachedWindow.document");
shouldBeTrue("!!detachedWindow.XMLHttpRequest");
@@ -30,12 +31,8 @@
shouldBeTrue("!!detachedWindow.getComputedStyle");
// Chrome returns undefined but Firefox throws an exception.
- shouldBeTrue("!detachedWindow.screen");
shouldBe("detachedWindow.innerHeight", "0");
shouldBe("detachedWindow.innerWidth", "0");
-
- // Both Chrome and Firefox disagree with us and return a valid object.
- shouldBeTrue("!detachedWindow.location");
}
</script>
<iframe src=""
Added: trunk/LayoutTests/http/tests/dom/cross-origin-detached-window-properties-expected.txt (0 => 237105)
--- trunk/LayoutTests/http/tests/dom/cross-origin-detached-window-properties-expected.txt (rev 0)
+++ trunk/LayoutTests/http/tests/dom/cross-origin-detached-window-properties-expected.txt 2018-10-15 14:54:21 UTC (rev 237105)
@@ -0,0 +1,66 @@
+Validate the properties of a detached Window object.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+* Before GC
+PASS !!w.location is true
+PASS w.location.href threw exception SecurityError: Blocked a frame with origin "http://127.0.0.1:8000" from accessing a cross-origin frame. Protocols, domains, and ports must match..
+PASS w.location.protocol threw exception SecurityError: Blocked a frame with origin "http://127.0.0.1:8000" from accessing a cross-origin frame. Protocols, domains, and ports must match..
+PASS w.location.host threw exception SecurityError: Blocked a frame with origin "http://127.0.0.1:8000" from accessing a cross-origin frame. Protocols, domains, and ports must match..
+PASS w.location.hostname threw exception SecurityError: Blocked a frame with origin "http://127.0.0.1:8000" from accessing a cross-origin frame. Protocols, domains, and ports must match..
+PASS w.location.port threw exception SecurityError: Blocked a frame with origin "http://127.0.0.1:8000" from accessing a cross-origin frame. Protocols, domains, and ports must match..
+PASS w.location.pathname threw exception SecurityError: Blocked a frame with origin "http://127.0.0.1:8000" from accessing a cross-origin frame. Protocols, domains, and ports must match..
+PASS w.location.search threw exception SecurityError: Blocked a frame with origin "http://127.0.0.1:8000" from accessing a cross-origin frame. Protocols, domains, and ports must match..
+PASS w.location.hash threw exception SecurityError: Blocked a frame with origin "http://127.0.0.1:8000" from accessing a cross-origin frame. Protocols, domains, and ports must match..
+PASS w.location.origin threw exception SecurityError: Blocked a frame with origin "http://127.0.0.1:8000" from accessing a cross-origin frame. Protocols, domains, and ports must match..
+PASS w.location.assign('') threw exception SecurityError: Blocked a frame with origin "http://127.0.0.1:8000" from accessing a cross-origin frame. Protocols, domains, and ports must match..
+PASS w.location.replace('') did not throw exception.
+PASS w.location.reload('') threw exception SecurityError: Blocked a frame with origin "http://127.0.0.1:8000" from accessing a cross-origin frame. Protocols, domains, and ports must match..
+PASS w.screen threw exception SecurityError: Blocked a frame with origin "http://127.0.0.1:8000" from accessing a cross-origin frame. Protocols, domains, and ports must match..
+PASS w.history threw exception SecurityError: Blocked a frame with origin "http://127.0.0.1:8000" from accessing a cross-origin frame. Protocols, domains, and ports must match..
+PASS w.crypto threw exception SecurityError: Blocked a frame with origin "http://127.0.0.1:8000" from accessing a cross-origin frame. Protocols, domains, and ports must match..
+PASS w.locationbar threw exception SecurityError: Blocked a frame with origin "http://127.0.0.1:8000" from accessing a cross-origin frame. Protocols, domains, and ports must match..
+PASS w.menubar threw exception SecurityError: Blocked a frame with origin "http://127.0.0.1:8000" from accessing a cross-origin frame. Protocols, domains, and ports must match..
+PASS w.personalbar threw exception SecurityError: Blocked a frame with origin "http://127.0.0.1:8000" from accessing a cross-origin frame. Protocols, domains, and ports must match..
+PASS w.scrollbars threw exception SecurityError: Blocked a frame with origin "http://127.0.0.1:8000" from accessing a cross-origin frame. Protocols, domains, and ports must match..
+PASS w.statusbar threw exception SecurityError: Blocked a frame with origin "http://127.0.0.1:8000" from accessing a cross-origin frame. Protocols, domains, and ports must match..
+PASS w.toolbar threw exception SecurityError: Blocked a frame with origin "http://127.0.0.1:8000" from accessing a cross-origin frame. Protocols, domains, and ports must match..
+PASS w.applicationCache threw exception SecurityError: Blocked a frame with origin "http://127.0.0.1:8000" from accessing a cross-origin frame. Protocols, domains, and ports must match..
+PASS w.visualViewport threw exception SecurityError: Blocked a frame with origin "http://127.0.0.1:8000" from accessing a cross-origin frame. Protocols, domains, and ports must match..
+PASS w.styleMedia threw exception SecurityError: Blocked a frame with origin "http://127.0.0.1:8000" from accessing a cross-origin frame. Protocols, domains, and ports must match..
+PASS w.foo threw exception SecurityError: Blocked a frame with origin "http://127.0.0.1:8000" from accessing a cross-origin frame. Protocols, domains, and ports must match..
+PASS w.location.foo threw exception SecurityError: Blocked a frame with origin "http://127.0.0.1:8000" from accessing a cross-origin frame. Protocols, domains, and ports must match..
+
+* After GC
+PASS !!w.location is true
+PASS w.location.href threw exception SecurityError: Blocked a frame with origin "http://127.0.0.1:8000" from accessing a cross-origin frame. Protocols, domains, and ports must match..
+PASS w.location.protocol threw exception SecurityError: Blocked a frame with origin "http://127.0.0.1:8000" from accessing a cross-origin frame. Protocols, domains, and ports must match..
+PASS w.location.host threw exception SecurityError: Blocked a frame with origin "http://127.0.0.1:8000" from accessing a cross-origin frame. Protocols, domains, and ports must match..
+PASS w.location.hostname threw exception SecurityError: Blocked a frame with origin "http://127.0.0.1:8000" from accessing a cross-origin frame. Protocols, domains, and ports must match..
+PASS w.location.port threw exception SecurityError: Blocked a frame with origin "http://127.0.0.1:8000" from accessing a cross-origin frame. Protocols, domains, and ports must match..
+PASS w.location.pathname threw exception SecurityError: Blocked a frame with origin "http://127.0.0.1:8000" from accessing a cross-origin frame. Protocols, domains, and ports must match..
+PASS w.location.search threw exception SecurityError: Blocked a frame with origin "http://127.0.0.1:8000" from accessing a cross-origin frame. Protocols, domains, and ports must match..
+PASS w.location.hash threw exception SecurityError: Blocked a frame with origin "http://127.0.0.1:8000" from accessing a cross-origin frame. Protocols, domains, and ports must match..
+PASS w.location.origin threw exception SecurityError: Blocked a frame with origin "http://127.0.0.1:8000" from accessing a cross-origin frame. Protocols, domains, and ports must match..
+PASS w.location.assign('') threw exception SecurityError: Blocked a frame with origin "http://127.0.0.1:8000" from accessing a cross-origin frame. Protocols, domains, and ports must match..
+PASS w.location.replace('') did not throw exception.
+PASS w.location.reload('') threw exception SecurityError: Blocked a frame with origin "http://127.0.0.1:8000" from accessing a cross-origin frame. Protocols, domains, and ports must match..
+PASS w.screen threw exception SecurityError: Blocked a frame with origin "http://127.0.0.1:8000" from accessing a cross-origin frame. Protocols, domains, and ports must match..
+PASS w.history threw exception SecurityError: Blocked a frame with origin "http://127.0.0.1:8000" from accessing a cross-origin frame. Protocols, domains, and ports must match..
+PASS w.crypto threw exception SecurityError: Blocked a frame with origin "http://127.0.0.1:8000" from accessing a cross-origin frame. Protocols, domains, and ports must match..
+PASS w.locationbar threw exception SecurityError: Blocked a frame with origin "http://127.0.0.1:8000" from accessing a cross-origin frame. Protocols, domains, and ports must match..
+PASS w.menubar threw exception SecurityError: Blocked a frame with origin "http://127.0.0.1:8000" from accessing a cross-origin frame. Protocols, domains, and ports must match..
+PASS w.personalbar threw exception SecurityError: Blocked a frame with origin "http://127.0.0.1:8000" from accessing a cross-origin frame. Protocols, domains, and ports must match..
+PASS w.scrollbars threw exception SecurityError: Blocked a frame with origin "http://127.0.0.1:8000" from accessing a cross-origin frame. Protocols, domains, and ports must match..
+PASS w.statusbar threw exception SecurityError: Blocked a frame with origin "http://127.0.0.1:8000" from accessing a cross-origin frame. Protocols, domains, and ports must match..
+PASS w.toolbar threw exception SecurityError: Blocked a frame with origin "http://127.0.0.1:8000" from accessing a cross-origin frame. Protocols, domains, and ports must match..
+PASS w.applicationCache threw exception SecurityError: Blocked a frame with origin "http://127.0.0.1:8000" from accessing a cross-origin frame. Protocols, domains, and ports must match..
+PASS w.visualViewport threw exception SecurityError: Blocked a frame with origin "http://127.0.0.1:8000" from accessing a cross-origin frame. Protocols, domains, and ports must match..
+PASS w.styleMedia threw exception SecurityError: Blocked a frame with origin "http://127.0.0.1:8000" from accessing a cross-origin frame. Protocols, domains, and ports must match..
+PASS w.foo threw exception SecurityError: Blocked a frame with origin "http://127.0.0.1:8000" from accessing a cross-origin frame. Protocols, domains, and ports must match..
+PASS w.location.foo threw exception SecurityError: Blocked a frame with origin "http://127.0.0.1:8000" from accessing a cross-origin frame. Protocols, domains, and ports must match..
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
Added: trunk/LayoutTests/http/tests/dom/cross-origin-detached-window-properties.html (0 => 237105)
--- trunk/LayoutTests/http/tests/dom/cross-origin-detached-window-properties.html (rev 0)
+++ trunk/LayoutTests/http/tests/dom/cross-origin-detached-window-properties.html 2018-10-15 14:54:21 UTC (rev 237105)
@@ -0,0 +1,76 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src=""
+</head>
+<body>
+<script>
+description("Validate the properties of a detached Window object.");
+jsTestIsAsync = true;
+
+function validateWindow(_w)
+{
+ w = _w;
+
+ try {
+ shouldBeTrue("!!w.location");
+ if (w.location) {
+ shouldThrowErrorName("w.location.href", "SecurityError");
+ shouldThrowErrorName("w.location.protocol", "SecurityError");
+ shouldThrowErrorName("w.location.host", "SecurityError");
+ shouldThrowErrorName("w.location.hostname", "SecurityError");
+ shouldThrowErrorName("w.location.port", "SecurityError");
+ shouldThrowErrorName("w.location.pathname", "SecurityError");
+ shouldThrowErrorName("w.location.search", "SecurityError");
+ shouldThrowErrorName("w.location.hash", "SecurityError");
+ shouldThrowErrorName("w.location.origin", "SecurityError");
+ shouldThrowErrorName("w.location.assign('')", "SecurityError");
+ shouldNotThrow("w.location.replace('')");
+ shouldThrowErrorName("w.location.reload('')", "SecurityError");
+ }
+ } catch (e) {
+ debug(e);
+ }
+
+ shouldThrowErrorName("w.screen", "SecurityError");
+ shouldThrowErrorName("w.history", "SecurityError");
+ shouldThrowErrorName("w.crypto", "SecurityError");
+
+ let bars = ['locationbar', 'menubar', 'personalbar', 'scrollbars', 'statusbar', 'toolbar'];
+ for (let bar of bars) {
+ shouldThrowErrorName("w." + bar, "SecurityError");
+ }
+
+ shouldThrowErrorName("w.applicationCache", "SecurityError");
+ shouldThrowErrorName("w.visualViewport", "SecurityError");
+ shouldThrowErrorName("w.styleMedia", "SecurityError");
+
+ shouldThrowErrorName("w.foo", "SecurityError");
+ shouldThrowErrorName("w.location.foo", "SecurityError");
+}
+
+_onmessage_ = function() {
+ let w = f.contentWindow;
+ f.remove();
+ f = null;
+
+ debug("* Before GC");
+ validateWindow(w);
+ gc();
+ setTimeout(() => {
+ gc();
+ debug("");
+ debug("* After GC");
+ validateWindow(w);
+ finishJSTest();
+ }, 0);
+}
+
+_onload_ = function() {
+ f = document.createElement("iframe");
+ f.src = "" // Cross-origin.
+ document.body.appendChild(f);
+}
+</script>
+</body>
+</html>
Added: trunk/LayoutTests/http/tests/dom/resources/post-message-to-parent-when-loaded.html (0 => 237105)
--- trunk/LayoutTests/http/tests/dom/resources/post-message-to-parent-when-loaded.html (rev 0)
+++ trunk/LayoutTests/http/tests/dom/resources/post-message-to-parent-when-loaded.html 2018-10-15 14:54:21 UTC (rev 237105)
@@ -0,0 +1,10 @@
+<!DOCTYPE html>
+<html>
+<body>
+<script>
+_onload_ = () => {
+ parent.postMessage("loaded", "*");
+}
+</script>
+</body>
+</html>
Added: trunk/LayoutTests/http/tests/dom/same-origin-detached-window-properties-expected.txt (0 => 237105)
--- trunk/LayoutTests/http/tests/dom/same-origin-detached-window-properties-expected.txt (rev 0)
+++ trunk/LayoutTests/http/tests/dom/same-origin-detached-window-properties-expected.txt 2018-10-15 14:54:21 UTC (rev 237105)
@@ -0,0 +1,134 @@
+Validate the properties of a detached Window object.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+* Before GC
+PASS !!w.location is true
+PASS w.location.href is ""
+PASS w.location.protocol is ""
+PASS w.location.host is ""
+PASS w.location.hostname is ""
+PASS w.location.port is ""
+PASS w.location.pathname is ""
+PASS w.location.search is ""
+PASS w.location.hash is ""
+PASS w.location.origin is ""
+PASS w.location.assign('') did not throw exception.
+PASS w.location.replace('') did not throw exception.
+PASS w.location.reload('') did not throw exception.
+PASS !!w.screen is true
+PASS w.screen.height is 0
+PASS w.screen.width is 0
+PASS w.screen.colorDepth is 0
+PASS w.screen.pixelDepth is 0
+PASS w.screen.availLeft is 0
+PASS w.screen.availTop is 0
+PASS w.screen.availHeight is 0
+PASS w.screen.availWidth is 0
+PASS !!w.history is true
+PASS w.history.length is 0
+PASS w.history.state is null
+PASS w.history.back() did not throw exception.
+PASS w.history.forward() did not throw exception.
+PASS w.history.go(-1) did not throw exception.
+PASS w.history.pushState({}, null) did not throw exception.
+PASS w.history.replaceState({}, null) did not throw exception.
+PASS !!w.crypto is true
+PASS !!w.locationbar is true
+PASS w.locationbar.visible is false
+PASS !!w.menubar is true
+PASS w.menubar.visible is false
+PASS !!w.personalbar is true
+PASS w.personalbar.visible is false
+PASS !!w.scrollbars is true
+PASS w.scrollbars.visible is false
+PASS !!w.statusbar is true
+PASS w.statusbar.visible is false
+PASS !!w.toolbar is true
+PASS w.toolbar.visible is false
+PASS !!w.applicationCache is true
+PASS w.applicationCache.status is ApplicationCache.UNCACHED
+PASS w.applicationCache.update() threw exception InvalidStateError: The object is in an invalid state..
+PASS w.applicationCache.swapCache() threw exception InvalidStateError: The object is in an invalid state..
+PASS w.applicationCache.abort() did not throw exception.
+PASS !!w.visualViewport is true
+PASS w.visualViewport.offsetLeft is 0
+PASS w.visualViewport.offsetTop is 0
+PASS w.visualViewport.pageLeft is 0
+PASS w.visualViewport.pageTop is 0
+PASS w.visualViewport.width is 0
+PASS w.visualViewport.height is 0
+PASS w.visualViewport.scale is 1
+PASS !!w.styleMedia is true
+PASS w.styleMedia.type is ""
+PASS w.styleMedia.matchMedium('foo') is false
+PASS w.foo is undefined.
+PASS w.location.foo is undefined.
+
+* After GC
+PASS !!w.location is true
+PASS w.location.href is ""
+PASS w.location.protocol is ""
+PASS w.location.host is ""
+PASS w.location.hostname is ""
+PASS w.location.port is ""
+PASS w.location.pathname is ""
+PASS w.location.search is ""
+PASS w.location.hash is ""
+PASS w.location.origin is ""
+PASS w.location.assign('') did not throw exception.
+PASS w.location.replace('') did not throw exception.
+PASS w.location.reload('') did not throw exception.
+PASS !!w.screen is true
+PASS w.screen.height is 0
+PASS w.screen.width is 0
+PASS w.screen.colorDepth is 0
+PASS w.screen.pixelDepth is 0
+PASS w.screen.availLeft is 0
+PASS w.screen.availTop is 0
+PASS w.screen.availHeight is 0
+PASS w.screen.availWidth is 0
+PASS !!w.history is true
+PASS w.history.length is 0
+PASS w.history.state is null
+PASS w.history.back() did not throw exception.
+PASS w.history.forward() did not throw exception.
+PASS w.history.go(-1) did not throw exception.
+PASS w.history.pushState({}, null) did not throw exception.
+PASS w.history.replaceState({}, null) did not throw exception.
+PASS !!w.crypto is true
+PASS !!w.locationbar is true
+PASS w.locationbar.visible is false
+PASS !!w.menubar is true
+PASS w.menubar.visible is false
+PASS !!w.personalbar is true
+PASS w.personalbar.visible is false
+PASS !!w.scrollbars is true
+PASS w.scrollbars.visible is false
+PASS !!w.statusbar is true
+PASS w.statusbar.visible is false
+PASS !!w.toolbar is true
+PASS w.toolbar.visible is false
+PASS !!w.applicationCache is true
+PASS w.applicationCache.status is ApplicationCache.UNCACHED
+PASS w.applicationCache.update() threw exception InvalidStateError: The object is in an invalid state..
+PASS w.applicationCache.swapCache() threw exception InvalidStateError: The object is in an invalid state..
+PASS w.applicationCache.abort() did not throw exception.
+PASS !!w.visualViewport is true
+PASS w.visualViewport.offsetLeft is 0
+PASS w.visualViewport.offsetTop is 0
+PASS w.visualViewport.pageLeft is 0
+PASS w.visualViewport.pageTop is 0
+PASS w.visualViewport.width is 0
+PASS w.visualViewport.height is 0
+PASS w.visualViewport.scale is 1
+PASS !!w.styleMedia is true
+PASS w.styleMedia.type is ""
+PASS w.styleMedia.matchMedium('foo') is false
+PASS w.foo is undefined.
+PASS w.location.foo is undefined.
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
Added: trunk/LayoutTests/http/tests/dom/same-origin-detached-window-properties.html (0 => 237105)
--- trunk/LayoutTests/http/tests/dom/same-origin-detached-window-properties.html (rev 0)
+++ trunk/LayoutTests/http/tests/dom/same-origin-detached-window-properties.html 2018-10-15 14:54:21 UTC (rev 237105)
@@ -0,0 +1,148 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src=""
+</head>
+<body>
+<script>
+description("Validate the properties of a detached Window object.");
+jsTestIsAsync = true;
+
+function validateWindow(_w)
+{
+ w = _w;
+
+ try {
+ shouldBeTrue("!!w.location");
+ if (w.location) {
+ shouldBeEqualToString("w.location.href", "");
+ shouldBeEqualToString("w.location.protocol", "");
+ shouldBeEqualToString("w.location.host", "");
+ shouldBeEqualToString("w.location.hostname", "");
+ shouldBeEqualToString("w.location.port", "");
+ shouldBeEqualToString("w.location.pathname", "");
+ shouldBeEqualToString("w.location.search", "");
+ shouldBeEqualToString("w.location.hash", "");
+ shouldBeEqualToString("w.location.origin", "");
+ shouldNotThrow("w.location.assign('')");
+ shouldNotThrow("w.location.replace('')");
+ shouldNotThrow("w.location.reload('')");
+ }
+ } catch (e) {
+ debug(e);
+ }
+
+ try {
+ shouldBeTrue("!!w.screen");
+ if (w.screen) {
+ shouldBe("w.screen.height", "0");
+ shouldBe("w.screen.width", "0");
+ shouldBe("w.screen.colorDepth", "0");
+ shouldBe("w.screen.pixelDepth", "0");
+ shouldBe("w.screen.availLeft", "0");
+ shouldBe("w.screen.availTop", "0");
+ shouldBe("w.screen.availHeight", "0");
+ shouldBe("w.screen.availWidth", "0");
+ }
+ } catch (e) {
+ debug(e);
+ }
+
+ try {
+ shouldBeTrue("!!w.history");
+ if (w.history) {
+ shouldBe("w.history.length", "0");
+ shouldBeNull("w.history.state");
+ shouldNotThrow("w.history.back()");
+ shouldNotThrow("w.history.forward()");
+ shouldNotThrow("w.history.go(-1)");
+ shouldNotThrow("w.history.pushState({}, null)");
+ shouldNotThrow("w.history.replaceState({}, null)");
+ }
+ } catch (e) {
+ debug(e);
+ }
+
+ try {
+ shouldBeTrue("!!w.crypto");
+ } catch (e) {
+ debug(e);
+ }
+
+ let bars = ['locationbar', 'menubar', 'personalbar', 'scrollbars', 'statusbar', 'toolbar'];
+ for (let bar of bars) {
+ try {
+ shouldBeTrue("!!w." + bar);
+ if (w[bar]) {
+ shouldBeFalse("w." + bar + ".visible");
+ }
+ } catch (e) {
+ debug(e);
+ }
+ }
+
+ try {
+ shouldBeTrue("!!w.applicationCache");
+ if (w.applicationCache) {
+ shouldBe("w.applicationCache.status", "ApplicationCache.UNCACHED");
+ shouldThrowErrorName("w.applicationCache.update()", "InvalidStateError");
+ shouldThrowErrorName("w.applicationCache.swapCache()", "InvalidStateError");
+ shouldNotThrow("w.applicationCache.abort()");
+ }
+ } catch (e) {
+ debug(e);
+ }
+
+ try {
+ shouldBeTrue("!!w.visualViewport");
+ if (w.visualViewport) {
+ shouldBe("w.visualViewport.offsetLeft", "0");
+ shouldBe("w.visualViewport.offsetTop", "0");
+ shouldBe("w.visualViewport.pageLeft", "0");
+ shouldBe("w.visualViewport.pageTop", "0");
+ shouldBe("w.visualViewport.width", "0");
+ shouldBe("w.visualViewport.height", "0");
+ shouldBe("w.visualViewport.scale", "1");
+ }
+ } catch (e) {
+ debug(e);
+ }
+
+ try {
+ shouldBeTrue("!!w.styleMedia");
+ if (w.styleMedia) {
+ shouldBeEqualToString("w.styleMedia.type", "");
+ shouldBeFalse("w.styleMedia.matchMedium('foo')");
+ }
+ } catch (e) {
+ debug(e);
+ }
+
+ try {
+ shouldBeUndefined("w.foo");
+ shouldBeUndefined("w.location.foo");
+ } catch (e) {
+ debug(e);
+ }
+}
+
+_onload_ = function() {
+ let f = document.createElement("iframe");
+ document.body.appendChild(f);
+ let w = f.contentWindow;
+ f.remove();
+ f = null;
+ debug("* Before GC");
+ validateWindow(w);
+ gc();
+ setTimeout(() => {
+ gc();
+ debug("");
+ debug("* After GC");
+ validateWindow(w);
+ finishJSTest();
+ }, 0);
+}
+</script>
+</body>
+</html>
Modified: trunk/LayoutTests/http/tests/security/named-window-property-from-same-origin-inactive-document-expected.txt (237104 => 237105)
--- trunk/LayoutTests/http/tests/security/named-window-property-from-same-origin-inactive-document-expected.txt 2018-10-15 14:31:39 UTC (rev 237104)
+++ trunk/LayoutTests/http/tests/security/named-window-property-from-same-origin-inactive-document-expected.txt 2018-10-15 14:54:21 UTC (rev 237105)
@@ -5,7 +5,7 @@
Lookup named element whose name corresponds to an element in the initial about:blank document:
PASS frame.contentDocument.getElementById('A') is not elementAInInactiveDocument
-PASS elementAInDetachedWindowFunction() threw exception ReferenceError: Can't find variable: A.
+PASS elementAInDetachedWindowFunction() is elementAInInactiveDocument
Lookup named element whose name does not correspond to an element in the initial about:blank document:
PASS elementBInDetachedWindowFunction() threw exception ReferenceError: Can't find variable: B.
Modified: trunk/LayoutTests/http/tests/security/named-window-property-from-same-origin-inactive-document.html (237104 => 237105)
--- trunk/LayoutTests/http/tests/security/named-window-property-from-same-origin-inactive-document.html 2018-10-15 14:31:39 UTC (rev 237104)
+++ trunk/LayoutTests/http/tests/security/named-window-property-from-same-origin-inactive-document.html 2018-10-15 14:54:21 UTC (rev 237105)
@@ -24,7 +24,7 @@
{
debug("Lookup named element whose name corresponds to an element in the initial about:blank document:");
shouldNotBe("frame.contentDocument.getElementById('A')", "elementAInInactiveDocument");
- shouldThrowErrorName("elementAInDetachedWindowFunction()", "ReferenceError");
+ shouldBe("elementAInDetachedWindowFunction()", "elementAInInactiveDocument");
debug("<br>Lookup named element whose name does not correspond to an element in the initial about:blank document:");
shouldThrowErrorName("elementBInDetachedWindowFunction()", "ReferenceError");
Modified: trunk/LayoutTests/http/tests/security/xss-DENIED-named-window-property-from-cross-origin-inactive-document-expected.txt (237104 => 237105)
--- trunk/LayoutTests/http/tests/security/xss-DENIED-named-window-property-from-cross-origin-inactive-document-expected.txt 2018-10-15 14:31:39 UTC (rev 237104)
+++ trunk/LayoutTests/http/tests/security/xss-DENIED-named-window-property-from-cross-origin-inactive-document-expected.txt 2018-10-15 14:54:21 UTC (rev 237105)
@@ -4,7 +4,7 @@
Lookup named element whose name corresponds to an element in the initial about:blank document:
-PASS elementAInDetachedWindowFunction() threw exception ReferenceError: Can't find variable: A.
+PASS elementAInDetachedWindowFunction() is elementAInInactiveDocument
Lookup named element whose name does not correspond to an element in the initial about:blank document:
PASS elementBInDetachedWindowFunction() threw exception ReferenceError: Can't find variable: B.
Modified: trunk/LayoutTests/http/tests/security/xss-DENIED-named-window-property-from-cross-origin-inactive-document.html (237104 => 237105)
--- trunk/LayoutTests/http/tests/security/xss-DENIED-named-window-property-from-cross-origin-inactive-document.html 2018-10-15 14:31:39 UTC (rev 237104)
+++ trunk/LayoutTests/http/tests/security/xss-DENIED-named-window-property-from-cross-origin-inactive-document.html 2018-10-15 14:54:21 UTC (rev 237105)
@@ -23,7 +23,7 @@
frame._onload_ = function ()
{
debug("Lookup named element whose name corresponds to an element in the initial about:blank document:")
- shouldThrowErrorName("elementAInDetachedWindowFunction()", 'ReferenceError');
+ shouldBe("elementAInDetachedWindowFunction()", 'elementAInInactiveDocument');
debug("<br>Lookup named element whose name does not correspond to an element in the initial about:blank document:");
shouldThrowErrorName("elementBInDetachedWindowFunction()", 'ReferenceError');
Modified: trunk/LayoutTests/http/tests/security/xss-DENIED-script-inject-into-inactive-window.html (237104 => 237105)
--- trunk/LayoutTests/http/tests/security/xss-DENIED-script-inject-into-inactive-window.html 2018-10-15 14:31:39 UTC (rev 237104)
+++ trunk/LayoutTests/http/tests/security/xss-DENIED-script-inject-into-inactive-window.html 2018-10-15 14:54:21 UTC (rev 237105)
@@ -16,9 +16,7 @@
function checkDidLoadVictim()
{
- try {
- _openedWindowDocument.location.href
- } catch (e) {
+ if (_openedWindowDocument.location.href == "") {
// Victim loaded; |_openedWindowDocument| is an inactive document.
window.clearInterval(intervalId);
Modified: trunk/LayoutTests/http/tests/security/xss-DENIED-script-inject-into-inactive-window2-pson.html (237104 => 237105)
--- trunk/LayoutTests/http/tests/security/xss-DENIED-script-inject-into-inactive-window2-pson.html 2018-10-15 14:31:39 UTC (rev 237104)
+++ trunk/LayoutTests/http/tests/security/xss-DENIED-script-inject-into-inactive-window2-pson.html 2018-10-15 14:54:21 UTC (rev 237105)
@@ -41,9 +41,7 @@
function checkDidLoadVictim()
{
- try {
- openerDocument.location.href
- } catch (e) {
+ if (openerDocument.location.href == "") {
// Victim loaded.
window.clearInterval(intervalId);
Modified: trunk/LayoutTests/http/tests/security/xss-DENIED-script-inject-into-inactive-window2.html (237104 => 237105)
--- trunk/LayoutTests/http/tests/security/xss-DENIED-script-inject-into-inactive-window2.html 2018-10-15 14:31:39 UTC (rev 237104)
+++ trunk/LayoutTests/http/tests/security/xss-DENIED-script-inject-into-inactive-window2.html 2018-10-15 14:54:21 UTC (rev 237105)
@@ -41,9 +41,7 @@
function checkDidLoadVictim()
{
- try {
- openerDocument.location.href
- } catch (e) {
+ if (openerDocument.location.href == "") {
// Victim loaded.
window.clearInterval(intervalId);
Modified: trunk/LayoutTests/http/tests/security/xss-DENIED-script-inject-into-inactive-window3.html (237104 => 237105)
--- trunk/LayoutTests/http/tests/security/xss-DENIED-script-inject-into-inactive-window3.html 2018-10-15 14:31:39 UTC (rev 237104)
+++ trunk/LayoutTests/http/tests/security/xss-DENIED-script-inject-into-inactive-window3.html 2018-10-15 14:54:21 UTC (rev 237105)
@@ -60,9 +60,7 @@
function checkDidLoadVictim()
{
- try {
- secondOpenerDocument.location.href
- } catch (e) {
+ if (secondOpenerDocument.location.href == "") {
// Victim loaded.
window.clearInterval(intervalId);
Modified: trunk/LayoutTests/imported/w3c/ChangeLog (237104 => 237105)
--- trunk/LayoutTests/imported/w3c/ChangeLog 2018-10-15 14:31:39 UTC (rev 237104)
+++ trunk/LayoutTests/imported/w3c/ChangeLog 2018-10-15 14:54:21 UTC (rev 237105)
@@ -1,3 +1,14 @@
+2018-10-15 Chris Dumez <[email protected]>
+
+ Window's properties such as 'location' should not become null when it loses its browsing context
+ https://bugs.webkit.org/show_bug.cgi?id=190539
+
+ Reviewed by Alex Christensen.
+
+ Rebaseline WPT test whose output has changed.
+
+ * web-platform-tests/html/webappapis/dynamic-markup-insertion/opening-the-input-stream/url.window-expected.txt:
+
2018-10-08 Yusuke Suzuki <[email protected]>
[JSC] JSC should have "parseFunction" to optimize Function constructor
Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/html/webappapis/dynamic-markup-insertion/opening-the-input-stream/url.window-expected.txt (237104 => 237105)
--- trunk/LayoutTests/imported/w3c/web-platform-tests/html/webappapis/dynamic-markup-insertion/opening-the-input-stream/url.window-expected.txt 2018-10-15 14:31:39 UTC (rev 237104)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/html/webappapis/dynamic-markup-insertion/opening-the-input-stream/url.window-expected.txt 2018-10-15 14:54:21 UTC (rev 237105)
@@ -1,6 +1,6 @@
PASS document.open() changes document's URL (fully active document)
-FAIL document.open() does not change document's URL (active but not fully active document) null is not an object (evaluating 'childWin.location.href')
+FAIL document.open() does not change document's URL (active but not fully active document) assert_equals: expected "http://localhost:8800/common/blank.html" but got ""
PASS document.open() does not change document's URL (non-active document with an associated Window object; frame is removed)
PASS document.open() does not change document's URL (non-active document with an associated Window object; navigated away)
PASS document.open() does not change document's URL (non-active document without an associated Window object)
Modified: trunk/Source/WebCore/ChangeLog (237104 => 237105)
--- trunk/Source/WebCore/ChangeLog 2018-10-15 14:31:39 UTC (rev 237104)
+++ trunk/Source/WebCore/ChangeLog 2018-10-15 14:54:21 UTC (rev 237105)
@@ -1,3 +1,73 @@
+2018-10-15 Chris Dumez <[email protected]>
+
+ Window's properties such as 'location' should not become null when it loses its browsing context
+ https://bugs.webkit.org/show_bug.cgi?id=190539
+
+ Reviewed by Alex Christensen.
+
+ Window's properties such as 'location' should not become null when it loses its browsing context.
+ This Webkit behavior is not standard and does not match other browsers so this patch makes it so
+ that those properties persist.
+
+ Tests: http/tests/dom/cross-origin-detached-window-properties.html
+ http/tests/dom/same-origin-detached-window-properties.html
+
+ * bindings/js/JSDOMBindingSecurity.cpp:
+ (WebCore::BindingSecurity::shouldAllowAccessToDOMWindow):
+ * bindings/js/JSDOMBindingSecurity.h:
+ * bindings/js/JSDOMWindowProperties.cpp:
+ (WebCore::jsDOMWindowPropertiesGetOwnPropertySlotNamedItemGetter):
+ (WebCore::JSDOMWindowProperties::getOwnPropertySlot):
+ * bindings/js/JSLocationCustom.cpp:
+ (WebCore::getOwnPropertySlotCommon):
+ (WebCore::putCommon):
+ (WebCore::JSLocation::deleteProperty):
+ (WebCore::JSLocation::deletePropertyByIndex):
+ (WebCore::JSLocation::getOwnPropertyNames):
+ (WebCore::JSLocation::defineOwnProperty):
+ (WebCore::JSLocation::getPrototype):
+ (WebCore::JSLocation::toStringName):
+ * bindings/scripts/CodeGeneratorJS.pm:
+ (GenerateAttributeGetterBodyDefinition):
+ (GenerateAttributeSetterBodyDefinition):
+ (GenerateOperationBodyDefinition):
+ * bindings/scripts/test/JS/JSTestActiveDOMObject.cpp:
+ (WebCore::jsTestActiveDOMObjectExcitingAttrGetter):
+ (WebCore::jsTestActiveDOMObjectPrototypeFunctionExcitingFunctionBody):
+ * crypto/SubtleCrypto.cpp:
+ (WebCore::SubtleCrypto::SubtleCrypto):
+ * crypto/SubtleCrypto.h:
+ (WebCore::SubtleCrypto::create):
+ * dom/Document.cpp:
+ (WebCore::Document::~Document):
+ * page/Crypto.cpp:
+ (WebCore::Crypto::Crypto):
+ * page/Crypto.h:
+ (WebCore::Crypto::create):
+ * page/DOMWindow.cpp:
+ (WebCore::DOMWindow::~DOMWindow):
+ (WebCore::DOMWindow::frameDestroyed):
+ (WebCore::DOMWindow::screen):
+ (WebCore::DOMWindow::history):
+ (WebCore::DOMWindow::crypto):
+ (WebCore::DOMWindow::locationbar):
+ (WebCore::DOMWindow::menubar):
+ (WebCore::DOMWindow::personalbar):
+ (WebCore::DOMWindow::scrollbars):
+ (WebCore::DOMWindow::statusbar):
+ (WebCore::DOMWindow::toolbar):
+ (WebCore::DOMWindow::console const):
+ (WebCore::DOMWindow::applicationCache):
+ (WebCore::DOMWindow::navigator):
+ (WebCore::DOMWindow::performance const):
+ (WebCore::DOMWindow::location):
+ (WebCore::DOMWindow::visualViewport):
+ (WebCore::DOMWindow::styleMedia):
+ * page/DOMWindow.h:
+ * page/DOMWindow.idl:
+ * workers/WorkerGlobalScope.cpp:
+ (WebCore::WorkerGlobalScope::crypto):
+
2018-10-15 Alex Christensen <[email protected]>
Include EnumTraits.h less
Modified: trunk/Source/WebCore/bindings/js/JSDOMBindingSecurity.cpp (237104 => 237105)
--- trunk/Source/WebCore/bindings/js/JSDOMBindingSecurity.cpp 2018-10-15 14:31:39 UTC (rev 237104)
+++ trunk/Source/WebCore/bindings/js/JSDOMBindingSecurity.cpp 2018-10-15 14:54:21 UTC (rev 237105)
@@ -77,6 +77,11 @@
return false;
}
+bool BindingSecurity::shouldAllowAccessToDOMWindow(ExecState& state, DOMWindow* globalObject, String& message)
+{
+ return globalObject && shouldAllowAccessToDOMWindow(state, *globalObject, message);
+}
+
bool BindingSecurity::shouldAllowAccessToDOMWindow(ExecState& state, DOMWindow& globalObject, String& message)
{
if (BindingSecurity::shouldAllowAccessToDOMWindow(&state, globalObject, DoNotReportSecurityError))
@@ -90,6 +95,11 @@
return canAccessDocument(state, target.document(), reportingOption);
}
+bool BindingSecurity::shouldAllowAccessToDOMWindow(JSC::ExecState* state, DOMWindow* target, SecurityReportingOption reportingOption)
+{
+ return target && shouldAllowAccessToDOMWindow(state, *target, reportingOption);
+}
+
bool BindingSecurity::shouldAllowAccessToFrame(JSC::ExecState* state, Frame* target, SecurityReportingOption reportingOption)
{
return target && canAccessDocument(state, target->document(), reportingOption);
Modified: trunk/Source/WebCore/bindings/js/JSDOMBindingSecurity.h (237104 => 237105)
--- trunk/Source/WebCore/bindings/js/JSDOMBindingSecurity.h 2018-10-15 14:31:39 UTC (rev 237104)
+++ trunk/Source/WebCore/bindings/js/JSDOMBindingSecurity.h 2018-10-15 14:54:21 UTC (rev 237105)
@@ -49,6 +49,8 @@
bool shouldAllowAccessToDOMWindow(JSC::ExecState*, DOMWindow&, SecurityReportingOption = LogSecurityError);
bool shouldAllowAccessToDOMWindow(JSC::ExecState&, DOMWindow&, String& message);
+bool shouldAllowAccessToDOMWindow(JSC::ExecState*, DOMWindow*, SecurityReportingOption = LogSecurityError);
+bool shouldAllowAccessToDOMWindow(JSC::ExecState&, DOMWindow*, String& message);
bool shouldAllowAccessToFrame(JSC::ExecState*, Frame*, SecurityReportingOption = LogSecurityError);
bool shouldAllowAccessToFrame(JSC::ExecState&, Frame&, String& message);
bool shouldAllowAccessToNode(JSC::ExecState&, Node*);
Modified: trunk/Source/WebCore/bindings/js/JSDOMWindowProperties.cpp (237104 => 237105)
--- trunk/Source/WebCore/bindings/js/JSDOMWindowProperties.cpp 2018-10-15 14:31:39 UTC (rev 237104)
+++ trunk/Source/WebCore/bindings/js/JSDOMWindowProperties.cpp 2018-10-15 14:54:21 UTC (rev 237105)
@@ -41,18 +41,20 @@
const ClassInfo JSDOMWindowProperties::s_info = { "WindowProperties", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSDOMWindowProperties) };
-static bool jsDOMWindowPropertiesGetOwnPropertySlotNamedItemGetter(JSDOMWindowProperties* thisObject, Frame& frame, ExecState* exec, PropertyName propertyName, PropertySlot& slot)
+static bool jsDOMWindowPropertiesGetOwnPropertySlotNamedItemGetter(JSDOMWindowProperties* thisObject, DOMWindow& window, ExecState* exec, PropertyName propertyName, PropertySlot& slot)
{
// Check for child frames by name before built-in properties to match Mozilla. This does
// not match IE, but some sites end up naming frames things that conflict with window
// properties that are in Moz but not IE. Since we have some of these, we have to do it
// the Moz way.
- if (auto* scopedChild = frame.tree().scopedChild(propertyNameToAtomicString(propertyName))) {
- slot.setValue(thisObject, JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontDelete | JSC::PropertyAttribute::DontEnum, toJS(exec, scopedChild->document()->domWindow()));
- return true;
+ if (auto* frame = window.frame()) {
+ if (auto* scopedChild = frame->tree().scopedChild(propertyNameToAtomicString(propertyName))) {
+ slot.setValue(thisObject, JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontDelete | JSC::PropertyAttribute::DontEnum, toJS(exec, scopedChild->document()->domWindow()));
+ return true;
+ }
}
- if (!BindingSecurity::shouldAllowAccessToFrame(exec, &frame, ThrowSecurityError))
+ if (!BindingSecurity::shouldAllowAccessToDOMWindow(exec, window, ThrowSecurityError))
return false;
// FIXME: Search the whole frame hierarchy somewhere around here.
@@ -59,8 +61,8 @@
// We need to test the correct priority order.
// Allow shortcuts like 'Image1' instead of document.images.Image1
- Document* document = frame.document();
- if (is<HTMLDocument>(*document)) {
+ auto* document = window.document();
+ if (is<HTMLDocument>(document)) {
auto& htmlDocument = downcast<HTMLDocument>(*document);
auto* atomicPropertyName = propertyName.publicName();
if (atomicPropertyName && htmlDocument.hasWindowNamedItem(*atomicPropertyName)) {
@@ -97,11 +99,7 @@
return false;
auto& window = jsWindow->wrapped();
-
- if (auto* frame = window.frame())
- return jsDOMWindowPropertiesGetOwnPropertySlotNamedItemGetter(thisObject, *frame, state, propertyName, slot);
-
- return false;
+ return jsDOMWindowPropertiesGetOwnPropertySlotNamedItemGetter(thisObject, window, state, propertyName, slot);
}
bool JSDOMWindowProperties::getOwnPropertySlotByIndex(JSObject* object, ExecState* state, unsigned index, PropertySlot& slot)
Modified: trunk/Source/WebCore/bindings/js/JSLocationCustom.cpp (237104 => 237105)
--- trunk/Source/WebCore/bindings/js/JSLocationCustom.cpp 2018-10-15 14:31:39 UTC (rev 237104)
+++ trunk/Source/WebCore/bindings/js/JSLocationCustom.cpp 2018-10-15 14:54:21 UTC (rev 237105)
@@ -39,11 +39,7 @@
VM& vm = state.vm();
auto scope = DECLARE_THROW_SCOPE(vm);
- Frame* frame = thisObject.wrapped().frame();
- if (!frame) {
- slot.setUndefined();
- return true;
- }
+ auto* window = thisObject.wrapped().window();
// When accessing Location cross-domain, functions are always the native built-in ones.
// See JSDOMWindow::getOwnPropertySlotDelegate for additional details.
@@ -51,7 +47,7 @@
// Our custom code is only needed to implement the Window cross-domain scheme, so if access is
// allowed, return false so the normal lookup will take place.
String message;
- if (BindingSecurity::shouldAllowAccessToFrame(state, *frame, message))
+ if (BindingSecurity::shouldAllowAccessToDOMWindow(state, window, message))
return false;
// https://html.spec.whatwg.org/#crossorigingetownpropertyhelper-(-o,-p-)
@@ -101,10 +97,6 @@
static bool putCommon(JSLocation& thisObject, ExecState& state, PropertyName propertyName)
{
- Frame* frame = thisObject.wrapped().frame();
- if (!frame)
- return true;
-
VM& vm = state.vm();
// Silently block access to toString and valueOf.
if (propertyName == vm.propertyNames->toString || propertyName == vm.propertyNames->valueOf)
@@ -117,7 +109,7 @@
return false;
// Block access and throw if there is a security error.
- if (!BindingSecurity::shouldAllowAccessToFrame(&state, frame, ThrowSecurityError))
+ if (!BindingSecurity::shouldAllowAccessToDOMWindow(&state, thisObject.wrapped().window(), ThrowSecurityError))
return true;
return false;
@@ -149,7 +141,7 @@
{
JSLocation* thisObject = jsCast<JSLocation*>(cell);
// Only allow deleting by frames in the same origin.
- if (!BindingSecurity::shouldAllowAccessToFrame(exec, thisObject->wrapped().frame(), ThrowSecurityError))
+ if (!BindingSecurity::shouldAllowAccessToDOMWindow(exec, thisObject->wrapped().window(), ThrowSecurityError))
return false;
return Base::deleteProperty(thisObject, exec, propertyName);
}
@@ -158,7 +150,7 @@
{
JSLocation* thisObject = jsCast<JSLocation*>(cell);
// Only allow deleting by frames in the same origin.
- if (!BindingSecurity::shouldAllowAccessToFrame(exec, thisObject->wrapped().frame(), ThrowSecurityError))
+ if (!BindingSecurity::shouldAllowAccessToDOMWindow(exec, thisObject->wrapped().window(), ThrowSecurityError))
return false;
return Base::deletePropertyByIndex(thisObject, exec, propertyName);
}
@@ -166,7 +158,7 @@
void JSLocation::getOwnPropertyNames(JSObject* object, ExecState* exec, PropertyNameArray& propertyNames, EnumerationMode mode)
{
JSLocation* thisObject = jsCast<JSLocation*>(object);
- if (!BindingSecurity::shouldAllowAccessToFrame(exec, thisObject->wrapped().frame(), DoNotReportSecurityError)) {
+ if (!BindingSecurity::shouldAllowAccessToDOMWindow(exec, thisObject->wrapped().window(), DoNotReportSecurityError)) {
if (mode.includeDontEnumProperties())
addCrossOriginOwnPropertyNames<CrossOriginObject::Location>(*exec, propertyNames);
return;
@@ -177,7 +169,7 @@
bool JSLocation::defineOwnProperty(JSObject* object, ExecState* exec, PropertyName propertyName, const PropertyDescriptor& descriptor, bool throwException)
{
JSLocation* thisObject = jsCast<JSLocation*>(object);
- if (!BindingSecurity::shouldAllowAccessToFrame(exec, thisObject->wrapped().frame(), ThrowSecurityError))
+ if (!BindingSecurity::shouldAllowAccessToDOMWindow(exec, thisObject->wrapped().window(), ThrowSecurityError))
return false;
VM& vm = exec->vm();
@@ -189,7 +181,7 @@
JSValue JSLocation::getPrototype(JSObject* object, ExecState* exec)
{
JSLocation* thisObject = jsCast<JSLocation*>(object);
- if (!BindingSecurity::shouldAllowAccessToFrame(exec, thisObject->wrapped().frame(), DoNotReportSecurityError))
+ if (!BindingSecurity::shouldAllowAccessToDOMWindow(exec, thisObject->wrapped().window(), DoNotReportSecurityError))
return jsNull();
return Base::getPrototype(object, exec);
@@ -206,7 +198,7 @@
String JSLocation::toStringName(const JSObject* object, ExecState* exec)
{
auto* thisObject = jsCast<const JSLocation*>(object);
- if (!BindingSecurity::shouldAllowAccessToFrame(exec, thisObject->wrapped().frame(), DoNotReportSecurityError))
+ if (!BindingSecurity::shouldAllowAccessToDOMWindow(exec, thisObject->wrapped().window(), DoNotReportSecurityError))
return "Object"_s;
return "Location"_s;
}
Modified: trunk/Source/WebCore/bindings/scripts/CodeGeneratorJS.pm (237104 => 237105)
--- trunk/Source/WebCore/bindings/scripts/CodeGeneratorJS.pm 2018-10-15 14:31:39 UTC (rev 237104)
+++ trunk/Source/WebCore/bindings/scripts/CodeGeneratorJS.pm 2018-10-15 14:54:21 UTC (rev 237105)
@@ -4777,7 +4777,7 @@
if ($interface->type->name eq "DOMWindow") {
push(@$outputArray, " if (!BindingSecurity::shouldAllowAccessToDOMWindow(&state, thisObject.wrapped(), ThrowSecurityError))\n");
} else {
- push(@$outputArray, " if (!BindingSecurity::shouldAllowAccessToFrame(&state, thisObject.wrapped().frame(), ThrowSecurityError))\n");
+ push(@$outputArray, " if (!BindingSecurity::shouldAllowAccessToDOMWindow(&state, thisObject.wrapped().window(), ThrowSecurityError))\n");
}
push(@$outputArray, " return jsUndefined();\n");
}
@@ -4905,7 +4905,7 @@
if ($interface->type->name eq "DOMWindow") {
push(@$outputArray, " if (!BindingSecurity::shouldAllowAccessToDOMWindow(&state, thisObject.wrapped(), ThrowSecurityError))\n");
} else {
- push(@$outputArray, " if (!BindingSecurity::shouldAllowAccessToFrame(&state, thisObject.wrapped().frame(), ThrowSecurityError))\n");
+ push(@$outputArray, " if (!BindingSecurity::shouldAllowAccessToDOMWindow(&state, thisObject.wrapped().window(), ThrowSecurityError))\n");
}
push(@$outputArray, " return false;\n");
}
@@ -5124,7 +5124,7 @@
push(@$outputArray, " if (!BindingSecurity::shouldAllowAccessToDOMWindow(state, castedThis->wrapped(), ThrowSecurityError))\n");
push(@$outputArray, " return JSValue::encode(jsUndefined());\n");
} else {
- push(@$outputArray, " if (!BindingSecurity::shouldAllowAccessToFrame(state, castedThis->wrapped().frame(), ThrowSecurityError))\n");
+ push(@$outputArray, " if (!BindingSecurity::shouldAllowAccessToDOMWindow(state, castedThis->wrapped().window(), ThrowSecurityError))\n");
push(@$outputArray, " return JSValue::encode(jsUndefined());\n");
}
}
Modified: trunk/Source/WebCore/bindings/scripts/test/JS/JSTestActiveDOMObject.cpp (237104 => 237105)
--- trunk/Source/WebCore/bindings/scripts/test/JS/JSTestActiveDOMObject.cpp 2018-10-15 14:31:39 UTC (rev 237104)
+++ trunk/Source/WebCore/bindings/scripts/test/JS/JSTestActiveDOMObject.cpp 2018-10-15 14:54:21 UTC (rev 237105)
@@ -200,7 +200,7 @@
{
UNUSED_PARAM(throwScope);
UNUSED_PARAM(state);
- if (!BindingSecurity::shouldAllowAccessToFrame(&state, thisObject.wrapped().frame(), ThrowSecurityError))
+ if (!BindingSecurity::shouldAllowAccessToDOMWindow(&state, thisObject.wrapped().window(), ThrowSecurityError))
return jsUndefined();
auto& impl = thisObject.wrapped();
JSValue result = toJS<IDLLong>(state, throwScope, impl.excitingAttr());
@@ -216,7 +216,7 @@
{
UNUSED_PARAM(state);
UNUSED_PARAM(throwScope);
- if (!BindingSecurity::shouldAllowAccessToFrame(state, castedThis->wrapped().frame(), ThrowSecurityError))
+ if (!BindingSecurity::shouldAllowAccessToDOMWindow(state, castedThis->wrapped().window(), ThrowSecurityError))
return JSValue::encode(jsUndefined());
auto& impl = castedThis->wrapped();
if (UNLIKELY(state->argumentCount() < 1))
Modified: trunk/Source/WebCore/crypto/SubtleCrypto.cpp (237104 => 237105)
--- trunk/Source/WebCore/crypto/SubtleCrypto.cpp 2018-10-15 14:31:39 UTC (rev 237104)
+++ trunk/Source/WebCore/crypto/SubtleCrypto.cpp 2018-10-15 14:54:21 UTC (rev 237105)
@@ -56,8 +56,8 @@
namespace WebCore {
using namespace JSC;
-SubtleCrypto::SubtleCrypto(ScriptExecutionContext& context)
- : ContextDestructionObserver(&context)
+SubtleCrypto::SubtleCrypto(ScriptExecutionContext* context)
+ : ContextDestructionObserver(context)
, m_workQueue(WorkQueue::create("com.apple.WebKit.CryptoQueue"))
{
}
Modified: trunk/Source/WebCore/crypto/SubtleCrypto.h (237104 => 237105)
--- trunk/Source/WebCore/crypto/SubtleCrypto.h 2018-10-15 14:31:39 UTC (rev 237104)
+++ trunk/Source/WebCore/crypto/SubtleCrypto.h 2018-10-15 14:54:21 UTC (rev 237105)
@@ -54,7 +54,7 @@
class SubtleCrypto : public ContextDestructionObserver, public RefCounted<SubtleCrypto>, public CanMakeWeakPtr<SubtleCrypto> {
public:
- static Ref<SubtleCrypto> create(ScriptExecutionContext& context) { return adoptRef(*new SubtleCrypto(context)); }
+ static Ref<SubtleCrypto> create(ScriptExecutionContext* context) { return adoptRef(*new SubtleCrypto(context)); }
~SubtleCrypto();
using KeyFormat = CryptoKeyFormat;
@@ -76,7 +76,7 @@
void unwrapKey(JSC::ExecState&, KeyFormat, BufferSource&& wrappedKey, CryptoKey& unwrappingKey, AlgorithmIdentifier&& unwrapAlgorithm, AlgorithmIdentifier&& unwrappedKeyAlgorithm, bool extractable, Vector<CryptoKeyUsage>&&, Ref<DeferredPromise>&&);
private:
- explicit SubtleCrypto(ScriptExecutionContext&);
+ explicit SubtleCrypto(ScriptExecutionContext*);
inline friend RefPtr<DeferredPromise> getPromise(DeferredPromise*, WeakPtr<SubtleCrypto>);
Modified: trunk/Source/WebCore/page/Crypto.cpp (237104 => 237105)
--- trunk/Source/WebCore/page/Crypto.cpp 2018-10-15 14:31:39 UTC (rev 237104)
+++ trunk/Source/WebCore/page/Crypto.cpp 2018-10-15 14:54:21 UTC (rev 237105)
@@ -42,8 +42,8 @@
namespace WebCore {
-Crypto::Crypto(ScriptExecutionContext& context)
- : ContextDestructionObserver(&context)
+Crypto::Crypto(ScriptExecutionContext* context)
+ : ContextDestructionObserver(context)
#if ENABLE(SUBTLE_CRYPTO)
, m_subtle(SubtleCrypto::create(context))
#endif
Modified: trunk/Source/WebCore/page/Crypto.h (237104 => 237105)
--- trunk/Source/WebCore/page/Crypto.h 2018-10-15 14:31:39 UTC (rev 237104)
+++ trunk/Source/WebCore/page/Crypto.h 2018-10-15 14:54:21 UTC (rev 237105)
@@ -42,7 +42,7 @@
class Crypto : public ContextDestructionObserver, public RefCounted<Crypto> {
public:
- static Ref<Crypto> create(ScriptExecutionContext& context) { return adoptRef(*new Crypto(context)); }
+ static Ref<Crypto> create(ScriptExecutionContext* context) { return adoptRef(*new Crypto(context)); }
virtual ~Crypto();
ExceptionOr<void> getRandomValues(JSC::ArrayBufferView&);
@@ -52,7 +52,7 @@
#endif
private:
- Crypto(ScriptExecutionContext&);
+ Crypto(ScriptExecutionContext*);
#if ENABLE(SUBTLE_CRYPTO)
Ref<SubtleCrypto> m_subtle;
Modified: trunk/Source/WebCore/page/DOMWindow.cpp (237104 => 237105)
--- trunk/Source/WebCore/page/DOMWindow.cpp 2018-10-15 14:31:39 UTC (rev 237104)
+++ trunk/Source/WebCore/page/DOMWindow.cpp 2018-10-15 14:54:21 UTC (rev 237105)
@@ -418,37 +418,11 @@
DOMWindow::~DOMWindow()
{
-#ifndef NDEBUG
- if (!m_suspendedForDocumentSuspension) {
- ASSERT(!m_screen);
- ASSERT(!m_history);
- ASSERT(!m_crypto);
- ASSERT(!m_locationbar);
- ASSERT(!m_menubar);
- ASSERT(!m_personalbar);
- ASSERT(!m_scrollbars);
- ASSERT(!m_statusbar);
- ASSERT(!m_toolbar);
- ASSERT(!m_navigator);
- ASSERT(!m_performance);
- ASSERT(!m_location);
- ASSERT(!m_media);
- ASSERT(!m_sessionStorage);
- ASSERT(!m_localStorage);
- ASSERT(!m_applicationCache);
- ASSERT(!m_visualViewport);
- }
-#endif
-
if (m_suspendedForDocumentSuspension)
willDestroyCachedFrame();
else
willDestroyDocumentInFrame();
- // As the ASSERTs above indicate, this reset should only be necessary if this DOMWindow is suspended for the page cache.
- // But we don't want to risk any of these objects hanging around after we've been destroyed.
- resetDOMWindowProperties();
-
removeAllUnloadEventListeners(this);
removeAllBeforeUnloadEventListeners(this);
@@ -475,7 +449,6 @@
Ref<DOMWindow> protectedThis(*this);
willDestroyDocumentInFrame();
- resetDOMWindowProperties();
JSDOMWindowBase::fireFrameClearedWatchpointsForWindow(this);
}
@@ -664,8 +637,6 @@
Screen* DOMWindow::screen()
{
- if (!isCurrentlyDisplayedInFrame())
- return nullptr;
if (!m_screen)
m_screen = Screen::create(*this);
return m_screen.get();
@@ -673,8 +644,6 @@
History* DOMWindow::history()
{
- if (!isCurrentlyDisplayedInFrame())
- return nullptr;
if (!m_history)
m_history = History::create(*this);
return m_history.get();
@@ -682,18 +651,13 @@
Crypto* DOMWindow::crypto() const
{
- // FIXME: Why is crypto not available when the window is not currently displayed in a frame?
- if (!isCurrentlyDisplayedInFrame())
- return nullptr;
if (!m_crypto)
- m_crypto = Crypto::create(*document());
+ m_crypto = Crypto::create(document());
return m_crypto.get();
}
BarProp* DOMWindow::locationbar()
{
- if (!isCurrentlyDisplayedInFrame())
- return nullptr;
if (!m_locationbar)
m_locationbar = BarProp::create(*this, BarProp::Locationbar);
return m_locationbar.get();
@@ -701,8 +665,6 @@
BarProp* DOMWindow::menubar()
{
- if (!isCurrentlyDisplayedInFrame())
- return nullptr;
if (!m_menubar)
m_menubar = BarProp::create(*this, BarProp::Menubar);
return m_menubar.get();
@@ -710,8 +672,6 @@
BarProp* DOMWindow::personalbar()
{
- if (!isCurrentlyDisplayedInFrame())
- return nullptr;
if (!m_personalbar)
m_personalbar = BarProp::create(*this, BarProp::Personalbar);
return m_personalbar.get();
@@ -719,8 +679,6 @@
BarProp* DOMWindow::scrollbars()
{
- if (!isCurrentlyDisplayedInFrame())
- return nullptr;
if (!m_scrollbars)
m_scrollbars = BarProp::create(*this, BarProp::Scrollbars);
return m_scrollbars.get();
@@ -728,8 +686,6 @@
BarProp* DOMWindow::statusbar()
{
- if (!isCurrentlyDisplayedInFrame())
- return nullptr;
if (!m_statusbar)
m_statusbar = BarProp::create(*this, BarProp::Statusbar);
return m_statusbar.get();
@@ -737,8 +693,6 @@
BarProp* DOMWindow::toolbar()
{
- if (!isCurrentlyDisplayedInFrame())
- return nullptr;
if (!m_toolbar)
m_toolbar = BarProp::create(*this, BarProp::Toolbar);
return m_toolbar.get();
@@ -746,6 +700,7 @@
PageConsoleClient* DOMWindow::console() const
{
+ // FIXME: This should not return nullptr when frameless.
if (!isCurrentlyDisplayedInFrame())
return nullptr;
auto* frame = this->frame();
@@ -754,8 +709,6 @@
DOMApplicationCache* DOMWindow::applicationCache()
{
- if (!isCurrentlyDisplayedInFrame())
- return nullptr;
if (!m_applicationCache)
m_applicationCache = DOMApplicationCache::create(*this);
return m_applicationCache.get();
@@ -763,6 +716,7 @@
Navigator* DOMWindow::navigator()
{
+ // FIXME: This should not return nullptr when frameless.
if (!isCurrentlyDisplayedInFrame())
return nullptr;
@@ -776,8 +730,10 @@
Performance* DOMWindow::performance() const
{
+ // FIXME: This should not return nullptr when frameless.
if (!isCurrentlyDisplayedInFrame())
return nullptr;
+
if (!m_performance) {
MonotonicTime timeOrigin = document()->loader() ? document()->loader()->timing().referenceMonotonicTime() : MonotonicTime::now();
m_performance = Performance::create(*document(), timeOrigin);
@@ -792,8 +748,6 @@
Location* DOMWindow::location()
{
- if (!isCurrentlyDisplayedInFrame())
- return nullptr;
if (!m_location)
m_location = Location::create(*this);
return m_location.get();
@@ -801,9 +755,7 @@
VisualViewport* DOMWindow::visualViewport()
{
- if (!isCurrentlyDisplayedInFrame())
- return nullptr;
- if (!m_visualViewport && !m_suspendedForDocumentSuspension)
+ if (!m_visualViewport)
m_visualViewport = VisualViewport::create(*this);
return m_visualViewport.get();
}
@@ -1493,8 +1445,6 @@
RefPtr<StyleMedia> DOMWindow::styleMedia()
{
- if (!isCurrentlyDisplayedInFrame())
- return nullptr;
if (!m_media)
m_media = StyleMedia::create(*this);
return m_media;
Modified: trunk/Source/WebCore/page/DOMWindow.h (237104 => 237105)
--- trunk/Source/WebCore/page/DOMWindow.h 2018-10-15 14:31:39 UTC (rev 237104)
+++ trunk/Source/WebCore/page/DOMWindow.h 2018-10-15 14:54:21 UTC (rev 237105)
@@ -334,6 +334,7 @@
void enableSuddenTermination();
void disableSuddenTermination();
+ void willDestroyDocumentInFrame();
void frameDestroyed();
private:
@@ -351,7 +352,6 @@
bool isInsecureScriptAccess(DOMWindow& activeWindow, const String& urlString);
void resetDOMWindowProperties();
- void willDestroyDocumentInFrame();
bool isSameSecurityOriginAsMainFrame() const;
Modified: trunk/Source/WebCore/page/DOMWindow.idl (237104 => 237105)
--- trunk/Source/WebCore/page/DOMWindow.idl 2018-10-15 14:31:39 UTC (rev 237104)
+++ trunk/Source/WebCore/page/DOMWindow.idl 2018-10-15 14:54:21 UTC (rev 237105)
@@ -54,7 +54,7 @@
[Replaceable, DoNotCheckSecurityOnGetter] readonly attribute WindowProxy self;
[Unforgeable] readonly attribute Document document;
attribute DOMString name;
- [DoNotCheckSecurity, PutForwards=href, Unforgeable] readonly attribute Location? location; // FIXME: Should not be nullable.
+ [DoNotCheckSecurity, PutForwards=href, Unforgeable] readonly attribute Location location;
readonly attribute History history;
[EnabledAtRuntime=CustomElements, ImplementedAs=ensureCustomElementRegistry] readonly attribute CustomElementRegistry customElements;
[Replaceable] readonly attribute BarProp locationbar;
Modified: trunk/Source/WebCore/workers/WorkerGlobalScope.cpp (237104 => 237105)
--- trunk/Source/WebCore/workers/WorkerGlobalScope.cpp 2018-10-15 14:31:39 UTC (rev 237104)
+++ trunk/Source/WebCore/workers/WorkerGlobalScope.cpp 2018-10-15 14:54:21 UTC (rev 237105)
@@ -421,7 +421,7 @@
Crypto& WorkerGlobalScope::crypto()
{
if (!m_crypto)
- m_crypto = Crypto::create(*this);
+ m_crypto = Crypto::create(this);
return *m_crypto;
}