Title: [172112] trunk
Revision
172112
Author
simon.fra...@apple.com
Date
2014-08-05 17:54:04 -0700 (Tue, 05 Aug 2014)

Log Message

[iOS WK2] Crash going back on a specific tumblr blog (under ScrollingStateTree::removeNodeAndAllDescendants)
https://bugs.webkit.org/show_bug.cgi?id=135629
<rdar://problem/17802174>

Reviewed by Tim Horton.

Source/WebCore:

In r170198 I added an "orphan scrolling nodes" code path that sets aside subtrees
of scrolling nodes into an m_orphanedSubframeNodes map, which keeps them alive until
they get reparented or destroyed. The nodes in that subtree remain in m_stateNodeMap,
which holds raw pointers to them.

However, ScrollingStateTree::commit() can clear m_orphanedSubframeNodes, which is
sometimes non-empty at this point. When that happened, we would destroy nodes which
were still referenced by m_stateNodeMap, with the result that a later query for the
same nodeID would hand back a pointer to a deleted object.

Fix by calling recursiveNodeWillBeRemoved() on nodes in the m_orphanedSubframeNodes
before clearing it, which removes them and all their descendants from the state node map.

Test: platform/mac-wk2/tiled-drawing/scrolling/frames/orphaned-subtree.html

* page/scrolling/ScrollingStateTree.cpp:
(WebCore::ScrollingStateTree::clear):
(WebCore::ScrollingStateTree::commit):

LayoutTests:

Testcase with nesting of frames inside fixed inside frames, where a subframe disconnects
part of the scrolling tree.

* platform/mac-wk2/tiled-drawing/scrolling/frames/orphaned-subtree-expected.txt: Added.
* platform/mac-wk2/tiled-drawing/scrolling/frames/orphaned-subtree.html: Added.
* platform/mac-wk2/tiled-drawing/scrolling/frames/resources/leaf-frame.html: Added.
* platform/mac-wk2/tiled-drawing/scrolling/frames/resources/subframe-inside-fixed.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (172111 => 172112)


--- trunk/LayoutTests/ChangeLog	2014-08-05 23:44:24 UTC (rev 172111)
+++ trunk/LayoutTests/ChangeLog	2014-08-06 00:54:04 UTC (rev 172112)
@@ -1,3 +1,19 @@
+2014-08-05  Simon Fraser  <simon.fra...@apple.com>
+
+        [iOS WK2] Crash going back on a specific tumblr blog (under ScrollingStateTree::removeNodeAndAllDescendants)
+        https://bugs.webkit.org/show_bug.cgi?id=135629
+        <rdar://problem/17802174>
+
+        Reviewed by Tim Horton.
+        
+        Testcase with nesting of frames inside fixed inside frames, where a subframe disconnects
+        part of the scrolling tree.
+
+        * platform/mac-wk2/tiled-drawing/scrolling/frames/orphaned-subtree-expected.txt: Added.
+        * platform/mac-wk2/tiled-drawing/scrolling/frames/orphaned-subtree.html: Added.
+        * platform/mac-wk2/tiled-drawing/scrolling/frames/resources/leaf-frame.html: Added.
+        * platform/mac-wk2/tiled-drawing/scrolling/frames/resources/subframe-inside-fixed.html: Added.
+
 2014-08-05  Andreas Kling  <akl...@apple.com>
 
         The JIT should cache property lookup misses.

Added: trunk/LayoutTests/platform/mac-wk2/tiled-drawing/scrolling/frames/orphaned-subtree-expected.txt (0 => 172112)


--- trunk/LayoutTests/platform/mac-wk2/tiled-drawing/scrolling/frames/orphaned-subtree-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/platform/mac-wk2/tiled-drawing/scrolling/frames/orphaned-subtree-expected.txt	2014-08-06 00:54:04 UTC (rev 172112)
@@ -0,0 +1,3 @@
+This test passes if it does not crash on the reload.
+
+

Added: trunk/LayoutTests/platform/mac-wk2/tiled-drawing/scrolling/frames/orphaned-subtree.html (0 => 172112)


--- trunk/LayoutTests/platform/mac-wk2/tiled-drawing/scrolling/frames/orphaned-subtree.html	                        (rev 0)
+++ trunk/LayoutTests/platform/mac-wk2/tiled-drawing/scrolling/frames/orphaned-subtree.html	2014-08-06 00:54:04 UTC (rev 172112)
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <script>
+        if (window.testRunner) {
+            testRunner.waitUntilDone();
+            testRunner.dumpAsText();
+            window.internals.settings.setScrollingTreeIncludesFrames(true);
+        }
+
+        function childFrameTestDone()
+        {
+            // Avoid infinite reload in the non-DRT case.
+            if (window.location.search)
+                return;
+
+            window.location += '?done=true';
+        }
+        
+        function checkForDoneTest()
+        {
+            if (window.location.search) {
+                if (window.testRunner)
+                    testRunner.notifyDone();
+            }
+        }
+        
+        window.addEventListener('load', checkForDoneTest, false);
+    </script>
+</head>
+<body>
+    <p>This test passes if it does not crash on the reload.</p>
+    <iframe id="iframe" src="" scrolling="no" width="500" height="300"></iframe>
+</body>
+</html>

Added: trunk/LayoutTests/platform/mac-wk2/tiled-drawing/scrolling/frames/resources/leaf-frame.html (0 => 172112)


--- trunk/LayoutTests/platform/mac-wk2/tiled-drawing/scrolling/frames/resources/leaf-frame.html	                        (rev 0)
+++ trunk/LayoutTests/platform/mac-wk2/tiled-drawing/scrolling/frames/resources/leaf-frame.html	2014-08-06 00:54:04 UTC (rev 172112)
@@ -0,0 +1,17 @@
+<!DOCTYPE html>
+
+<html>
+<head>
+    <style>
+        .box {
+            height: 100px;
+            width: 100px;
+            background-color: blue;
+            position: fixed;
+        }
+    </style>
+</head>
+<body>
+<div class="box"></div>
+</body>
+</html>

Added: trunk/LayoutTests/platform/mac-wk2/tiled-drawing/scrolling/frames/resources/subframe-inside-fixed.html (0 => 172112)


--- trunk/LayoutTests/platform/mac-wk2/tiled-drawing/scrolling/frames/resources/subframe-inside-fixed.html	                        (rev 0)
+++ trunk/LayoutTests/platform/mac-wk2/tiled-drawing/scrolling/frames/resources/subframe-inside-fixed.html	2014-08-06 00:54:04 UTC (rev 172112)
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+
+<html>
+<head>
+    <style>
+        .fixed {
+            position: fixed;
+            border: 1px solid red;
+        }
+        
+        .removed {
+            display: none;
+        }
+        
+    </style>
+    <script>
+        function subframeLoaded()
+        {
+            window.setTimeout(function() {
+                document.getElementById('container').classList.add('removed');
+                window.parent.childFrameTestDone();
+            }, 0);
+        }
+    </script>
+</head>
+<body>
+    <div class="fixed" id="container">
+        <iframe _onload_="subframeLoaded()" src=""
+    </div>
+</body>
+</html>

Modified: trunk/Source/WebCore/ChangeLog (172111 => 172112)


--- trunk/Source/WebCore/ChangeLog	2014-08-05 23:44:24 UTC (rev 172111)
+++ trunk/Source/WebCore/ChangeLog	2014-08-06 00:54:04 UTC (rev 172112)
@@ -1,3 +1,30 @@
+2014-08-05  Simon Fraser  <simon.fra...@apple.com>
+
+        [iOS WK2] Crash going back on a specific tumblr blog (under ScrollingStateTree::removeNodeAndAllDescendants)
+        https://bugs.webkit.org/show_bug.cgi?id=135629
+        <rdar://problem/17802174>
+
+        Reviewed by Tim Horton.
+        
+        In r170198 I added an "orphan scrolling nodes" code path that sets aside subtrees
+        of scrolling nodes into an m_orphanedSubframeNodes map, which keeps them alive until
+        they get reparented or destroyed. The nodes in that subtree remain in m_stateNodeMap,
+        which holds raw pointers to them.
+        
+        However, ScrollingStateTree::commit() can clear m_orphanedSubframeNodes, which is
+        sometimes non-empty at this point. When that happened, we would destroy nodes which
+        were still referenced by m_stateNodeMap, with the result that a later query for the
+        same nodeID would hand back a pointer to a deleted object.
+        
+        Fix by calling recursiveNodeWillBeRemoved() on nodes in the m_orphanedSubframeNodes
+        before clearing it, which removes them and all their descendants from the state node map.
+
+        Test: platform/mac-wk2/tiled-drawing/scrolling/frames/orphaned-subtree.html
+
+        * page/scrolling/ScrollingStateTree.cpp:
+        (WebCore::ScrollingStateTree::clear):
+        (WebCore::ScrollingStateTree::commit):
+
 2014-08-05  Peyton Randolph  <prando...@apple.com>
 
         Add the ability to force text to render in white, not just black

Modified: trunk/Source/WebCore/page/scrolling/ScrollingStateTree.cpp (172111 => 172112)


--- trunk/Source/WebCore/page/scrolling/ScrollingStateTree.cpp	2014-08-05 23:44:24 UTC (rev 172111)
+++ trunk/Source/WebCore/page/scrolling/ScrollingStateTree.cpp	2014-08-06 00:54:04 UTC (rev 172112)
@@ -152,14 +152,19 @@
     if (rootStateNode())
         removeNodeAndAllDescendants(rootStateNode());
 
-    ASSERT(m_stateNodeMap.isEmpty());
     m_stateNodeMap.clear();
     m_orphanedSubframeNodes.clear();
 }
 
 PassOwnPtr<ScrollingStateTree> ScrollingStateTree::commit(LayerRepresentation::Type preferredLayerRepresentation)
 {
-    m_orphanedSubframeNodes.clear();
+    if (!m_orphanedSubframeNodes.isEmpty()) {
+        // If we still have orphaned subtrees, remove them from m_stateNodeMap since they will be deleted 
+        // when clearing m_orphanedSubframeNodes.
+        for (auto& orphanNode : m_orphanedSubframeNodes.values())
+            recursiveNodeWillBeRemoved(orphanNode.get(), SubframeNodeRemoval::Delete);
+        m_orphanedSubframeNodes.clear();
+    }
 
     // This function clones and resets the current state tree, but leaves the tree structure intact.
     OwnPtr<ScrollingStateTree> treeStateClone = ScrollingStateTree::create();
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to