Title: [186632] branches/safari-600.8-branch

Diff

Modified: branches/safari-600.8-branch/LayoutTests/ChangeLog (186631 => 186632)


--- branches/safari-600.8-branch/LayoutTests/ChangeLog	2015-07-09 21:03:34 UTC (rev 186631)
+++ branches/safari-600.8-branch/LayoutTests/ChangeLog	2015-07-09 21:03:39 UTC (rev 186632)
@@ -1,5 +1,46 @@
 2015-07-09  Matthew Hanson  <matthew_han...@apple.com>
 
+        Merge r186577. rdar://problem/21533109
+
+    2015-07-08  Lucas Forschler  <lforsch...@apple.com>
+
+            Merge r186165. rdar://problem/21533207
+
+        2015-06-30  Zalan Bujtas  <za...@apple.com>
+
+                Frame flattening: Hit-testing an iframe could end up destroying the associated inline tree context.
+                https://bugs.webkit.org/show_bug.cgi?id=146447
+                rdar://problem/20613501
+
+                Reviewed by Simon Fraser.
+
+                This patch ensures that the render tree associated with the document on which
+                the hit-test is initiated does not get laid out, unless it was directly mutated prior to the hittest.
+
+                Hit-test requirements:
+                1. A clean the render tree before hit-testing gets propagated to the renderers.
+                Document::updateLayout() ensures it by calling both updateStyleIfNeeded() and layout() not only on the current tree, but also
+                on the ancestors if needed.
+
+                2. No render tree mutation while hit-testing the renderers.
+
+                When an iframe is being hit-tested, this hit-test could bubble down to the child frame's render view.
+                In order to ensure #1, we call Document::updateLayout() on the current (subframe) document.
+                If updateStyleIfNeeded() mutates the render tree, we mark it dirty for layout(). However frame flattening also
+                marks the parent renderer (RenderIFrame) dirty.
+                While calling layout() to clean the current render tree, we end up laying out the parent tree too.
+                Laying out the parent tree could end up destroying the inline tree context from where the
+                hittest just bubbled down. (InlineFlowBox -> RenderWidget -> RenderView).
+
+                This patch protects the render tree from such unintentional inline tree mutation during hittesting.
+                After the initial layout we set a layout disallow flag on the frame view to defer subsequent layouts.
+                This patch only changes behavior when frame flattening is enabled, but in future we may always want to enable this.
+
+                * fast/frames/flattening/hittest-iframe-while-style-changes-crash-expected.txt: Added.
+                * fast/frames/flattening/hittest-iframe-while-style-changes-crash.html: Added.
+
+2015-07-09  Matthew Hanson  <matthew_han...@apple.com>
+
         Merge r186575. rdar://problem/21716377
 
     2015-07-08  Lucas Forschler  <lforsch...@apple.com>

Added: branches/safari-600.8-branch/LayoutTests/fast/frames/flattening/hittest-iframe-while-style-changes-crash-expected.txt (0 => 186632)


--- branches/safari-600.8-branch/LayoutTests/fast/frames/flattening/hittest-iframe-while-style-changes-crash-expected.txt	                        (rev 0)
+++ branches/safari-600.8-branch/LayoutTests/fast/frames/flattening/hittest-iframe-while-style-changes-crash-expected.txt	2015-07-09 21:03:39 UTC (rev 186632)
@@ -0,0 +1 @@
+Pass if no crash or assert in debug. 

Added: branches/safari-600.8-branch/LayoutTests/fast/frames/flattening/hittest-iframe-while-style-changes-crash.html (0 => 186632)


--- branches/safari-600.8-branch/LayoutTests/fast/frames/flattening/hittest-iframe-while-style-changes-crash.html	                        (rev 0)
+++ branches/safari-600.8-branch/LayoutTests/fast/frames/flattening/hittest-iframe-while-style-changes-crash.html	2015-07-09 21:03:39 UTC (rev 186632)
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<html>
+<head>
+<title>This tests that hittesting an iframe when frame flattening is on does not crash.</title>
+<script>
+if (window.testRunner) {
+    testRunner.dumpAsText();
+    testRunner.waitUntilDone();
+}
+
+if (window.internals)
+    internals.settings.setFrameFlatteningEnabled(true);
+
+function runTest() {
+    setTimeout(function() {
+        document.getElementById('clickonthis').contentDocument.getElementById('foo').style.display = "none";
+        if (window.internals)
+            internals.nodesFromRect(document, 100, 100, 0, 0, 0, 0, false, false, true);
+        if (window.testRunner)
+            testRunner.notifyDone();
+    }, 0);
+}
+</script>
+<body>
+Pass if no crash or assert in debug.
+<iframe _onload_="runTest()" id=clickonthis src="" id=foo>foobar</div>">
+</body>

Modified: branches/safari-600.8-branch/Source/WebCore/ChangeLog (186631 => 186632)


--- branches/safari-600.8-branch/Source/WebCore/ChangeLog	2015-07-09 21:03:34 UTC (rev 186631)
+++ branches/safari-600.8-branch/Source/WebCore/ChangeLog	2015-07-09 21:03:39 UTC (rev 186632)
@@ -1,5 +1,54 @@
 2015-07-09  Matthew Hanson  <matthew_han...@apple.com>
 
+        Merge r186577. rdar://problem/21533109
+
+    2015-07-08  Lucas Forschler  <lforsch...@apple.com>
+
+            Merge r186165. rdar://problem/21533207
+
+        2015-06-30  Zalan Bujtas  <za...@apple.com>
+
+                Frame flattening: Hit-testing an iframe could end up destroying the associated inline tree context.
+                https://bugs.webkit.org/show_bug.cgi?id=146447
+                rdar://problem/20613501
+
+                Reviewed by Simon Fraser.
+
+                This patch ensures that the render tree associated with the document on which
+                the hit-test is initiated does not get laid out, unless it was directly mutated prior to the hittest.
+
+                Hit-test requirements:
+                1. A clean the render tree before hit-testing gets propagated to the renderers.
+                Document::updateLayout() ensures it by calling both updateStyleIfNeeded() and layout() not only on the current tree, but also
+                on the ancestors if needed.
+
+                2. No render tree mutation while hit-testing the renderers.
+
+                When an iframe is being hit-tested, this hit-test could bubble down to the child frame's render view.
+                In order to ensure #1, we call Document::updateLayout() on the current (subframe) document.
+                If updateStyleIfNeeded() mutates the render tree, we mark it dirty for layout(). However frame flattening also
+                marks the parent renderer (RenderIFrame) dirty.
+                While calling layout() to clean the current render tree, we end up laying out the parent tree too.
+                Laying out the parent tree could end up destroying the inline tree context from where the
+                hittest just bubbled down. (InlineFlowBox -> RenderWidget -> RenderView).
+
+                This patch protects the render tree from such unintentional inline tree mutation during hittesting.
+                After the initial layout we set a layout disallow flag on the frame view to defer subsequent layouts.
+                This patch only changes behavior when frame flattening is enabled, but in future we may always want to enable this.
+
+                Test: fast/frames/flattening/hittest-iframe-while-style-changes-crash.html
+
+                * page/FrameView.cpp:
+                (WebCore::FrameView::layout):
+                (WebCore::FrameView::startLayoutAtMainFrameViewIfNeeded): Deleted. -> Assertion in no longer valid.
+                * page/FrameView.h:
+                * rendering/RenderView.cpp:
+                (WebCore::FrameFlatteningLayoutDisallower::FrameFlatteningLayoutDisallower):
+                (WebCore::FrameFlatteningLayoutDisallower::~FrameFlatteningLayoutDisallower):
+                (WebCore::RenderView::hitTest): Protect the render tree from subsequent layouts.
+
+2015-07-09  Matthew Hanson  <matthew_han...@apple.com>
+
         Merge r186575. rdar://problem/21716377
 
     2015-07-08  Lucas Forschler  <lforsch...@apple.com>

Modified: branches/safari-600.8-branch/Source/WebCore/page/FrameView.cpp (186631 => 186632)


--- branches/safari-600.8-branch/Source/WebCore/page/FrameView.cpp	2015-07-09 21:03:34 UTC (rev 186631)
+++ branches/safari-600.8-branch/Source/WebCore/page/FrameView.cpp	2015-07-09 21:03:39 UTC (rev 186632)
@@ -1090,6 +1090,9 @@
     if (isInLayout())
         return;
 
+    if (layoutDisallowed())
+        return;
+
     // Protect the view from being deleted during layout (in recalcStyle).
     Ref<FrameView> protect(*this);
 
@@ -3582,9 +3585,6 @@
         parentView = parentView->parentFrameView();
 
     parentView->layout(allowSubtree);
-
-    RenderElement* root = m_layoutRoot ? m_layoutRoot : frame().document()->renderView();
-    ASSERT_UNUSED(root, !root->needsLayout());
 }
 
 void FrameView::updateControlTints()

Modified: branches/safari-600.8-branch/Source/WebCore/page/FrameView.h (186631 => 186632)


--- branches/safari-600.8-branch/Source/WebCore/page/FrameView.h	2015-07-09 21:03:34 UTC (rev 186631)
+++ branches/safari-600.8-branch/Source/WebCore/page/FrameView.h	2015-07-09 21:03:39 UTC (rev 186632)
@@ -350,6 +350,10 @@
 
     bool isInChildFrameWithFrameFlattening() const;
 
+    void startDisallowingLayout() { ++m_layoutDisallowed; }
+    void endDisallowingLayout() { ASSERT(m_layoutDisallowed > 0); --m_layoutDisallowed; }
+    bool layoutDisallowed() const { return m_layoutDisallowed; }
+
     static double currentPaintTimeStamp() { return sCurrentPaintTimeStamp; } // returns 0 if not painting
     
     void updateLayoutAndStyleIfNeededRecursive();
@@ -690,6 +694,7 @@
 
     unsigned m_deferSetNeedsLayouts;
     bool m_setNeedsLayoutWasDeferred;
+    int m_layoutDisallowed { 0 };
 
     RefPtr<Node> m_nodeToDraw;
     PaintBehavior m_paintBehavior;

Modified: branches/safari-600.8-branch/Source/WebCore/rendering/RenderView.cpp (186631 => 186632)


--- branches/safari-600.8-branch/Source/WebCore/rendering/RenderView.cpp	2015-07-09 21:03:34 UTC (rev 186631)
+++ branches/safari-600.8-branch/Source/WebCore/rendering/RenderView.cpp	2015-07-09 21:03:39 UTC (rev 186632)
@@ -54,6 +54,26 @@
 
 namespace WebCore {
 
+struct FrameFlatteningLayoutDisallower {
+    FrameFlatteningLayoutDisallower(FrameView& frameView)
+        : m_frameView(frameView)
+        , m_disallowLayout(frameView.frame().settings().frameFlatteningEnabled())
+    {
+        if (m_disallowLayout)
+            m_frameView.startDisallowingLayout();
+    }
+
+    ~FrameFlatteningLayoutDisallower()
+    {
+        if (m_disallowLayout)
+            m_frameView.endDisallowingLayout();
+    }
+
+private:
+    FrameView& m_frameView;
+    bool m_disallowLayout { false };
+};
+
 struct SelectionIterator {
     RenderObject* m_current;
     Vector<RenderMultiColumnSpannerPlaceholder*> m_spannerStack;
@@ -176,6 +196,8 @@
 
 bool RenderView::hitTest(const HitTestRequest& request, const HitTestLocation& location, HitTestResult& result)
 {
+    FrameFlatteningLayoutDisallower disallower(frameView());
+
     if (layer()->hitTest(request, location, result))
         return true;
 
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to