Title: [239347] trunk
Revision
239347
Author
[email protected]
Date
2018-12-18 12:09:32 -0800 (Tue, 18 Dec 2018)

Log Message

Synchronous media query evaluation could destroy current Frame/FrameView.
https://bugs.webkit.org/show_bug.cgi?id=192781
<rdar://problem/34416793>

Reviewed by Chris Dumez.

Source/WebCore:

Protect Frame and FrameView when coming back from printing and check if the current Frame/FrameView/FrameLoader objects are still valid.

Test: printing/print-with-media-query-destory.html

* loader/DocumentLoader.cpp:
(WebCore::DocumentLoader::finishedLoading):
* page/Frame.cpp:
(WebCore::Frame::setPrinting):
* page/FrameView.cpp:
(WebCore::FrameView::forceLayoutForPagination):

LayoutTests:

* printing/print-with-media-query-destory-expected.txt: Added.
* printing/print-with-media-query-destory.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (239346 => 239347)


--- trunk/LayoutTests/ChangeLog	2018-12-18 19:45:24 UTC (rev 239346)
+++ trunk/LayoutTests/ChangeLog	2018-12-18 20:09:32 UTC (rev 239347)
@@ -1,3 +1,14 @@
+2018-12-18  Zalan Bujtas  <[email protected]>
+
+        Synchronous media query evaluation could destroy current Frame/FrameView.
+        https://bugs.webkit.org/show_bug.cgi?id=192781
+        <rdar://problem/34416793>
+
+        Reviewed by Chris Dumez.
+
+        * printing/print-with-media-query-destory-expected.txt: Added.
+        * printing/print-with-media-query-destory.html: Added.
+
 2018-12-18  Joseph Pecoraro  <[email protected]>
 
         Web Inspector: m3u8 content not shown, it should be text

Added: trunk/LayoutTests/printing/print-with-media-query-destory-expected.txt (0 => 239347)


--- trunk/LayoutTests/printing/print-with-media-query-destory-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/printing/print-with-media-query-destory-expected.txt	2018-12-18 20:09:32 UTC (rev 239347)
@@ -0,0 +1,2 @@
+Pass if no crash or assert
+

Added: trunk/LayoutTests/printing/print-with-media-query-destory.html (0 => 239347)


--- trunk/LayoutTests/printing/print-with-media-query-destory.html	                        (rev 0)
+++ trunk/LayoutTests/printing/print-with-media-query-destory.html	2018-12-18 20:09:32 UTC (rev 239347)
@@ -0,0 +1,28 @@
+<div>Pass if no crash or assert</div>
+<script>
+if (window.testRunner)
+    testRunner.dumpAsText();
+    
+function wait() {
+if (window.testRunner)
+    testRunner.waitUntilDone();
+}
+
+function done() {
+if (window.testRunner)
+    testRunner.notifyDone();
+}
+</script>
+<iframe srcdoc="<script>
+window.matchMedia('print').addListener(function(mql) {
+    let parentWindow = window.parent;
+    window.frameElement.remove();
+    parentWindow.done();
+});
+
+if (window.internals) {
+    internals.setPrinting(800, 600);
+    window.parent.wait();
+} else
+    print();
+</script>">

Modified: trunk/Source/WebCore/ChangeLog (239346 => 239347)


--- trunk/Source/WebCore/ChangeLog	2018-12-18 19:45:24 UTC (rev 239346)
+++ trunk/Source/WebCore/ChangeLog	2018-12-18 20:09:32 UTC (rev 239347)
@@ -1,3 +1,22 @@
+2018-12-18  Zalan Bujtas  <[email protected]>
+
+        Synchronous media query evaluation could destroy current Frame/FrameView.
+        https://bugs.webkit.org/show_bug.cgi?id=192781
+        <rdar://problem/34416793>
+
+        Reviewed by Chris Dumez.
+
+        Protect Frame and FrameView when coming back from printing and check if the current Frame/FrameView/FrameLoader objects are still valid.
+
+        Test: printing/print-with-media-query-destory.html
+
+        * loader/DocumentLoader.cpp:
+        (WebCore::DocumentLoader::finishedLoading):
+        * page/Frame.cpp:
+        (WebCore::Frame::setPrinting):
+        * page/FrameView.cpp:
+        (WebCore::FrameView::forceLayoutForPagination):
+
 2018-12-18  Joseph Pecoraro  <[email protected]>
 
         Web Inspector: m3u8 content not shown, it should be text

Modified: trunk/Source/WebCore/loader/DocumentLoader.cpp (239346 => 239347)


--- trunk/Source/WebCore/loader/DocumentLoader.cpp	2018-12-18 19:45:24 UTC (rev 239346)
+++ trunk/Source/WebCore/loader/DocumentLoader.cpp	2018-12-18 20:09:32 UTC (rev 239347)
@@ -435,6 +435,8 @@
     if (!m_mainDocumentError.isNull())
         return;
     clearMainResourceLoader();
+    if (!frameLoader())
+        return;
     if (!frameLoader()->stateMachine().creatingInitialEmptyDocument())
         frameLoader()->checkLoadComplete();
 

Modified: trunk/Source/WebCore/page/Frame.cpp (239346 => 239347)


--- trunk/Source/WebCore/page/Frame.cpp	2018-12-18 19:45:24 UTC (rev 239346)
+++ trunk/Source/WebCore/page/Frame.cpp	2018-12-18 20:09:32 UTC (rev 239347)
@@ -661,22 +661,23 @@
 
 void Frame::setPrinting(bool printing, const FloatSize& pageSize, const FloatSize& originalPageSize, float maximumShrinkRatio, AdjustViewSizeOrNot shouldAdjustViewSize)
 {
+    if (!view())
+        return;
     // In setting printing, we should not validate resources already cached for the document.
     // See https://bugs.webkit.org/show_bug.cgi?id=43704
     ResourceCacheValidationSuppressor validationSuppressor(m_doc->cachedResourceLoader());
 
     m_doc->setPrinting(printing);
-    if (auto* frameView = view()) {
-        frameView->adjustMediaTypeForPrinting(printing);
+    auto& frameView = *view();
+    frameView.adjustMediaTypeForPrinting(printing);
 
-        m_doc->styleScope().didChangeStyleSheetEnvironment();
-        if (shouldUsePrintingLayout())
-            frameView->forceLayoutForPagination(pageSize, originalPageSize, maximumShrinkRatio, shouldAdjustViewSize);
-        else {
-            frameView->forceLayout();
-            if (shouldAdjustViewSize == AdjustViewSize)
-                frameView->adjustViewSize();
-        }
+    m_doc->styleScope().didChangeStyleSheetEnvironment();
+    if (shouldUsePrintingLayout())
+        frameView.forceLayoutForPagination(pageSize, originalPageSize, maximumShrinkRatio, shouldAdjustViewSize);
+    else {
+        frameView.forceLayout();
+        if (shouldAdjustViewSize == AdjustViewSize)
+            frameView.adjustViewSize();
     }
 
     // Subframes of the one we're printing don't lay out to the page size.

Modified: trunk/Source/WebCore/page/FrameView.cpp (239346 => 239347)


--- trunk/Source/WebCore/page/FrameView.cpp	2018-12-18 19:45:24 UTC (rev 239346)
+++ trunk/Source/WebCore/page/FrameView.cpp	2018-12-18 20:09:32 UTC (rev 239347)
@@ -4586,48 +4586,56 @@
 
 void FrameView::forceLayoutForPagination(const FloatSize& pageSize, const FloatSize& originalPageSize, float maximumShrinkFactor, AdjustViewSizeOrNot shouldAdjustViewSize)
 {
+    if (!renderView())
+        return;
+
+    Ref<FrameView> protectedThis(*this);
+    auto& renderView = *this->renderView();
+
     // Dumping externalRepresentation(frame().renderer()).ascii() is a good trick to see
     // the state of things before and after the layout
-    if (RenderView* renderView = this->renderView()) {
-        float pageLogicalWidth = renderView->style().isHorizontalWritingMode() ? pageSize.width() : pageSize.height();
-        float pageLogicalHeight = renderView->style().isHorizontalWritingMode() ? pageSize.height() : pageSize.width();
+    float pageLogicalWidth = renderView.style().isHorizontalWritingMode() ? pageSize.width() : pageSize.height();
+    float pageLogicalHeight = renderView.style().isHorizontalWritingMode() ? pageSize.height() : pageSize.width();
 
-        renderView->setPageLogicalSize({ floor(pageLogicalWidth), floor(pageLogicalHeight) });
-        renderView->setNeedsLayoutAndPrefWidthsRecalc();
-        forceLayout();
+    renderView.setPageLogicalSize({ floor(pageLogicalWidth), floor(pageLogicalHeight) });
+    renderView.setNeedsLayoutAndPrefWidthsRecalc();
+    forceLayout();
+    if (hasOneRef())
+        return;
 
-        // If we don't fit in the given page width, we'll lay out again. If we don't fit in the
-        // page width when shrunk, we will lay out at maximum shrink and clip extra content.
-        // FIXME: We are assuming a shrink-to-fit printing implementation.  A cropping
-        // implementation should not do this!
-        bool horizontalWritingMode = renderView->style().isHorizontalWritingMode();
-        const LayoutRect& documentRect = renderView->documentRect();
-        LayoutUnit docLogicalWidth = horizontalWritingMode ? documentRect.width() : documentRect.height();
-        if (docLogicalWidth > pageLogicalWidth) {
-            int expectedPageWidth = std::min<float>(documentRect.width(), pageSize.width() * maximumShrinkFactor);
-            int expectedPageHeight = std::min<float>(documentRect.height(), pageSize.height() * maximumShrinkFactor);
-            FloatSize maxPageSize = frame().resizePageRectsKeepingRatio(FloatSize(originalPageSize.width(), originalPageSize.height()), FloatSize(expectedPageWidth, expectedPageHeight));
-            pageLogicalWidth = horizontalWritingMode ? maxPageSize.width() : maxPageSize.height();
-            pageLogicalHeight = horizontalWritingMode ? maxPageSize.height() : maxPageSize.width();
+    // If we don't fit in the given page width, we'll lay out again. If we don't fit in the
+    // page width when shrunk, we will lay out at maximum shrink and clip extra content.
+    // FIXME: We are assuming a shrink-to-fit printing implementation. A cropping
+    // implementation should not do this!
+    bool horizontalWritingMode = renderView.style().isHorizontalWritingMode();
+    const LayoutRect& documentRect = renderView.documentRect();
+    LayoutUnit docLogicalWidth = horizontalWritingMode ? documentRect.width() : documentRect.height();
+    if (docLogicalWidth > pageLogicalWidth) {
+        int expectedPageWidth = std::min<float>(documentRect.width(), pageSize.width() * maximumShrinkFactor);
+        int expectedPageHeight = std::min<float>(documentRect.height(), pageSize.height() * maximumShrinkFactor);
+        FloatSize maxPageSize = frame().resizePageRectsKeepingRatio(FloatSize(originalPageSize.width(), originalPageSize.height()), FloatSize(expectedPageWidth, expectedPageHeight));
+        pageLogicalWidth = horizontalWritingMode ? maxPageSize.width() : maxPageSize.height();
+        pageLogicalHeight = horizontalWritingMode ? maxPageSize.height() : maxPageSize.width();
 
-            renderView->setPageLogicalSize({ floor(pageLogicalWidth), floor(pageLogicalHeight) });
-            renderView->setNeedsLayoutAndPrefWidthsRecalc();
-            forceLayout();
+        renderView.setPageLogicalSize({ floor(pageLogicalWidth), floor(pageLogicalHeight) });
+        renderView.setNeedsLayoutAndPrefWidthsRecalc();
+        forceLayout();
+        if (hasOneRef())
+            return;
 
-            const LayoutRect& updatedDocumentRect = renderView->documentRect();
-            LayoutUnit docLogicalHeight = horizontalWritingMode ? updatedDocumentRect.height() : updatedDocumentRect.width();
-            LayoutUnit docLogicalTop = horizontalWritingMode ? updatedDocumentRect.y() : updatedDocumentRect.x();
-            LayoutUnit docLogicalRight = horizontalWritingMode ? updatedDocumentRect.maxX() : updatedDocumentRect.maxY();
-            LayoutUnit clippedLogicalLeft;
-            if (!renderView->style().isLeftToRightDirection())
-                clippedLogicalLeft = docLogicalRight - pageLogicalWidth;
-            LayoutRect overflow(clippedLogicalLeft, docLogicalTop, pageLogicalWidth, docLogicalHeight);
+        const LayoutRect& updatedDocumentRect = renderView.documentRect();
+        LayoutUnit docLogicalHeight = horizontalWritingMode ? updatedDocumentRect.height() : updatedDocumentRect.width();
+        LayoutUnit docLogicalTop = horizontalWritingMode ? updatedDocumentRect.y() : updatedDocumentRect.x();
+        LayoutUnit docLogicalRight = horizontalWritingMode ? updatedDocumentRect.maxX() : updatedDocumentRect.maxY();
+        LayoutUnit clippedLogicalLeft;
+        if (!renderView.style().isLeftToRightDirection())
+            clippedLogicalLeft = docLogicalRight - pageLogicalWidth;
+        LayoutRect overflow(clippedLogicalLeft, docLogicalTop, pageLogicalWidth, docLogicalHeight);
 
-            if (!horizontalWritingMode)
-                overflow = overflow.transposedRect();
-            renderView->clearLayoutOverflow();
-            renderView->addLayoutOverflow(overflow); // This is how we clip in case we overflow again.
-        }
+        if (!horizontalWritingMode)
+            overflow = overflow.transposedRect();
+        renderView.clearLayoutOverflow();
+        renderView.addLayoutOverflow(overflow); // This is how we clip in case we overflow again.
     }
 
     if (shouldAdjustViewSize)
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to