Title: [239600] trunk
Revision
239600
Author
[email protected]
Date
2019-01-03 15:25:57 -0800 (Thu, 03 Jan 2019)

Log Message

Potential infinite recursion in isFrameFamiliarWith(Frame&, Frame&)
https://bugs.webkit.org/show_bug.cgi?id=192997
<rdar://problem/46217271>

Reviewed by Antti Koivisto.

Source/WebCore:

isFrameFamiliarWith(Frame&, Frame&) was called recursively using the passed frames' openers.
The issue is that a Frame can be its opener. There could also be a cycle in the opener chain.

To address the issue, simplify isFrameFamiliarWith() so that it is no longer recursive. We now
only check if the frames belong to the same pages or if their openers do. We no longer check
openers' opener and up.

Note that this function is used to check if a frame is allowed to target another. In practice,
it is unlikely to be useful to navigate an opener's opener and an openee's openee.

Tests: fast/dom/Window/window-open-opener-cycle.html
       fast/dom/Window/window-open-self-as-opener.html

* page/FrameTree.cpp:
(WebCore::isFrameFamiliarWith):

LayoutTests:

Add layout test coverage.

* fast/dom/Window/resources/window-open-opener-cycle2.html: Added.
* fast/dom/Window/resources/window-open-opener-cycle3.html: Added.
* fast/dom/Window/resources/window-opens-self.html: Added.
* fast/dom/Window/window-open-opener-cycle-expected.txt: Added.
* fast/dom/Window/window-open-opener-cycle.html: Added.
* fast/dom/Window/window-open-self-as-opener-expected.txt: Added.
* fast/dom/Window/window-open-self-as-opener.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (239599 => 239600)


--- trunk/LayoutTests/ChangeLog	2019-01-03 21:58:33 UTC (rev 239599)
+++ trunk/LayoutTests/ChangeLog	2019-01-03 23:25:57 UTC (rev 239600)
@@ -1,3 +1,21 @@
+2019-01-03  Chris Dumez  <[email protected]>
+
+        Potential infinite recursion in isFrameFamiliarWith(Frame&, Frame&)
+        https://bugs.webkit.org/show_bug.cgi?id=192997
+        <rdar://problem/46217271>
+
+        Reviewed by Antti Koivisto.
+
+        Add layout test coverage.
+
+        * fast/dom/Window/resources/window-open-opener-cycle2.html: Added.
+        * fast/dom/Window/resources/window-open-opener-cycle3.html: Added.
+        * fast/dom/Window/resources/window-opens-self.html: Added.
+        * fast/dom/Window/window-open-opener-cycle-expected.txt: Added.
+        * fast/dom/Window/window-open-opener-cycle.html: Added.
+        * fast/dom/Window/window-open-self-as-opener-expected.txt: Added.
+        * fast/dom/Window/window-open-self-as-opener.html: Added.
+
 2019-01-03  Devin Rousso  <[email protected]>
 
         Web Inspector: conic-gradient color picker doesn't accurately show color when saturation value is not 100%

Added: trunk/LayoutTests/fast/dom/Window/resources/window-open-opener-cycle2.html (0 => 239600)


--- trunk/LayoutTests/fast/dom/Window/resources/window-open-opener-cycle2.html	                        (rev 0)
+++ trunk/LayoutTests/fast/dom/Window/resources/window-open-opener-cycle2.html	2019-01-03 23:25:57 UTC (rev 239600)
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<html>
+<body>
+<script>
+if (window.testRunner)
+    testRunner.setCanOpenWindows();
+
+_onload_ = function() {
+    w = open("window-open-opener-cycle3.html", "bar");
+}
+</script>
+</body>
+</html>

Added: trunk/LayoutTests/fast/dom/Window/resources/window-open-opener-cycle3.html (0 => 239600)


--- trunk/LayoutTests/fast/dom/Window/resources/window-open-opener-cycle3.html	                        (rev 0)
+++ trunk/LayoutTests/fast/dom/Window/resources/window-open-opener-cycle3.html	2019-01-03 23:25:57 UTC (rev 239600)
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<html>
+<body>
+<script>
+
+if (window.testRunner)
+    testRunner.setCanOpenWindows();
+
+_onload_ = function() {
+    root = opener.opener;
+    open("", "foo");
+    if (opener.opener === self)
+        root.testPassed("opener.opener === self");
+    else
+        root.testFailed("opener.opener !== self");
+    root.tryNavigateFoo();
+}
+</script>
+</body>
+</html>

Added: trunk/LayoutTests/fast/dom/Window/resources/window-opens-self.html (0 => 239600)


--- trunk/LayoutTests/fast/dom/Window/resources/window-opens-self.html	                        (rev 0)
+++ trunk/LayoutTests/fast/dom/Window/resources/window-opens-self.html	2019-01-03 23:25:57 UTC (rev 239600)
@@ -0,0 +1,10 @@
+<!DOCTYPE html>
+<html>
+<body>
+<script>
+function setOpenerAsSelf() {
+    open("", "_self");
+}
+</script>
+</body>
+</html>

Added: trunk/LayoutTests/fast/dom/Window/window-open-opener-cycle-expected.txt (0 => 239600)


--- trunk/LayoutTests/fast/dom/Window/window-open-opener-cycle-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/fast/dom/Window/window-open-opener-cycle-expected.txt	2019-01-03 23:25:57 UTC (rev 239600)
@@ -0,0 +1,10 @@
+Tests navigating a window which has an opener cycle.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS opener.opener === self
+PASS successfullyParsed is true
+
+TEST COMPLETE
+

Added: trunk/LayoutTests/fast/dom/Window/window-open-opener-cycle.html (0 => 239600)


--- trunk/LayoutTests/fast/dom/Window/window-open-opener-cycle.html	                        (rev 0)
+++ trunk/LayoutTests/fast/dom/Window/window-open-opener-cycle.html	2019-01-03 23:25:57 UTC (rev 239600)
@@ -0,0 +1,22 @@
+<!DOCTYPE html>
+<html>
+<body>
+<script src=""
+<script>
+description("Tests navigating a window which has an opener cycle.");
+jsTestIsAsync = true;
+if (window.testRunner)
+    testRunner.setCanOpenWindows();
+
+function tryNavigateFoo()
+{
+    open("about:blank", "foo");
+    finishJSTest();
+}
+
+_onload_ = function() {
+    w = window.open("resources/window-open-opener-cycle2.html", "foo");
+}
+</script>
+</body>
+</html>

Added: trunk/LayoutTests/fast/dom/Window/window-open-self-as-opener-expected.txt (0 => 239600)


--- trunk/LayoutTests/fast/dom/Window/window-open-self-as-opener-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/fast/dom/Window/window-open-self-as-opener-expected.txt	2019-01-03 23:25:57 UTC (rev 239600)
@@ -0,0 +1,12 @@
+Tests navigating a window whose opener is itself
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS w.opener is self
+PASS w.opener is w
+PASS w.opener is self
+PASS successfullyParsed is true
+
+TEST COMPLETE
+

Added: trunk/LayoutTests/fast/dom/Window/window-open-self-as-opener.html (0 => 239600)


--- trunk/LayoutTests/fast/dom/Window/window-open-self-as-opener.html	                        (rev 0)
+++ trunk/LayoutTests/fast/dom/Window/window-open-self-as-opener.html	2019-01-03 23:25:57 UTC (rev 239600)
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<html>
+<body>
+<script src=""
+<script>
+description("Tests navigating a window whose opener is itself");
+jsTestIsAsync = true;
+if (window.testRunner)
+    testRunner.setCanOpenWindows();
+
+_onload_ = function() {
+    w = window.open("resources/window-opens-self.html", "foo");
+    shouldBe("w.opener", "self");
+    w._onload_ = function() {
+        w.setOpenerAsSelf();
+        shouldBe("w.opener", "w");
+
+        w = window.open("about:blank", "foo");
+        shouldBe("w.opener", "self");
+
+        finishJSTest();
+    }
+}
+</script>
+</body>
+</html>

Modified: trunk/Source/WebCore/ChangeLog (239599 => 239600)


--- trunk/Source/WebCore/ChangeLog	2019-01-03 21:58:33 UTC (rev 239599)
+++ trunk/Source/WebCore/ChangeLog	2019-01-03 23:25:57 UTC (rev 239600)
@@ -1,3 +1,27 @@
+2019-01-03  Chris Dumez  <[email protected]>
+
+        Potential infinite recursion in isFrameFamiliarWith(Frame&, Frame&)
+        https://bugs.webkit.org/show_bug.cgi?id=192997
+        <rdar://problem/46217271>
+
+        Reviewed by Antti Koivisto.
+
+        isFrameFamiliarWith(Frame&, Frame&) was called recursively using the passed frames' openers.
+        The issue is that a Frame can be its opener. There could also be a cycle in the opener chain.
+
+        To address the issue, simplify isFrameFamiliarWith() so that it is no longer recursive. We now
+        only check if the frames belong to the same pages or if their openers do. We no longer check
+        openers' opener and up.
+
+        Note that this function is used to check if a frame is allowed to target another. In practice,
+        it is unlikely to be useful to navigate an opener's opener and an openee's openee.
+
+        Tests: fast/dom/Window/window-open-opener-cycle.html
+               fast/dom/Window/window-open-self-as-opener.html
+
+        * page/FrameTree.cpp:
+        (WebCore::isFrameFamiliarWith):
+
 2019-01-02  Simon Fraser  <[email protected]>
 
         REGRESSION (r239306): Don't disable font smoothing in transparent layers on macOS Mojave and later

Modified: trunk/Source/WebCore/page/FrameTree.cpp (239599 => 239600)


--- trunk/Source/WebCore/page/FrameTree.cpp	2019-01-03 21:58:33 UTC (rev 239599)
+++ trunk/Source/WebCore/page/FrameTree.cpp	2019-01-03 23:25:57 UTC (rev 239600)
@@ -215,13 +215,9 @@
     if (frameA.page() == frameB.page())
         return true;
 
-    if (auto* frameAOpener = frameA.mainFrame().loader().opener())
-        return isFrameFamiliarWith(*frameAOpener, frameB);
-
-    if (auto* frameBOpener = frameB.mainFrame().loader().opener())
-        return isFrameFamiliarWith(frameA, *frameBOpener);
-
-    return false;
+    auto* frameAOpener = frameA.mainFrame().loader().opener();
+    auto* frameBOpener = frameB.mainFrame().loader().opener();
+    return (frameAOpener && frameAOpener->page() == frameB.page()) || (frameBOpener && frameBOpener->page() == frameA.page()) || (frameAOpener && frameBOpener && frameAOpener->page() == frameBOpener->page());
 }
 
 Frame* FrameTree::find(const AtomicString& name, Frame& activeFrame) const
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to