Do not create a shape object outside of the layout context
authorzalan@apple.com <zalan@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 15 May 2019 22:34:09 +0000 (22:34 +0000)
committerzalan@apple.com <zalan@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 15 May 2019 22:34:09 +0000 (22:34 +0000)
https://bugs.webkit.org/show_bug.cgi?id=197926
<rdar://problem/50627858>

Reviewed by Simon Fraser.

Source/WebCore:

ShapeOutside objects are used to compute line constrains during layout (in a strict sense, they are part of the layout context and should only be mutated during layout).
If we don't create one during layout, we probably don't need to know its geometry during paint (or any other non-layout activity) either.

Test: fast/block/float/float-with-shape-outside-crash.html

* rendering/FloatingObjects.cpp:
(WebCore::ComputeFloatOffsetForLineLayoutAdapter<FloatingObject::FloatLeft>::updateOffsetIfNeeded):
(WebCore::ComputeFloatOffsetForLineLayoutAdapter<FloatingObject::FloatRight>::updateOffsetIfNeeded):
* rendering/shapes/ShapeOutsideInfo.cpp:
(WebCore::ShapeOutsideInfo::computeDeltasForContainingBlockLine):

LayoutTests:

* fast/block/float/float-with-shape-outside-crash-expected.txt: Added.
* fast/block/float/float-with-shape-outside-crash.html: Added.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@245361 268f45cc-cd09-0410-ab3c-d52691b4dbfc

LayoutTests/ChangeLog
LayoutTests/fast/block/float/float-with-shape-outside-crash-expected.txt [new file with mode: 0644]
LayoutTests/fast/block/float/float-with-shape-outside-crash.html [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/rendering/FloatingObjects.cpp
Source/WebCore/rendering/shapes/ShapeOutsideInfo.cpp

index 89618da..976a1a0 100644 (file)
@@ -1,3 +1,14 @@
+2019-05-15  Zalan Bujtas  <zalan@apple.com>
+
+        Do not create a shape object outside of the layout context
+        https://bugs.webkit.org/show_bug.cgi?id=197926
+        <rdar://problem/50627858>
+
+        Reviewed by Simon Fraser.
+
+        * fast/block/float/float-with-shape-outside-crash-expected.txt: Added.
+        * fast/block/float/float-with-shape-outside-crash.html: Added.
+
 2019-05-15  Shawn Roberts  <sroberts@apple.com>
 
         Layout tests http/wpt/webauthn/public-key-credential-create-success-hid.https.html
diff --git a/LayoutTests/fast/block/float/float-with-shape-outside-crash-expected.txt b/LayoutTests/fast/block/float/float-with-shape-outside-crash-expected.txt
new file mode 100644 (file)
index 0000000..4ef250d
--- /dev/null
@@ -0,0 +1 @@
+PASS if no crash or ASSERT 
diff --git a/LayoutTests/fast/block/float/float-with-shape-outside-crash.html b/LayoutTests/fast/block/float/float-with-shape-outside-crash.html
new file mode 100644 (file)
index 0000000..0839024
--- /dev/null
@@ -0,0 +1,17 @@
+<style>
+q { 
+    float: left;
+}
+
+div { 
+    float: left;
+    width: 1400px;
+    height: 100px;
+    -webkit-shape-outside: filter(url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA4MCAxMjUiIHN0cm9rZT0iI2QzNiI+CiAgPHBhdGggZD0iTTQwLDczdjUwIiBzdHJva2Utd2lkdGg9IjExIi8+CiAgPHBhdGggZD0iTTE3LDk4bDQ3LDAiIHN0cm9rZS13aWR0aD0iOCIvPgogIDxjaXJjbGUgcj0iMzMiIGN4PSI0MCIgY3k9IjQwIiBmaWxsPSJub25lIiBzdHJva2Utd2lkdGg9IjEyIi8+Cjwvc3ZnPgo=), hue-rotate()); 
+}
+</style><span>PASS if no crash or ASSERT</span><q>
+<div></div></q><script>
+document.getSelection().selectAllChildren(document.body);
+if (window.testRunner)
+    testRunner.dumpAsText();
+</script>
index 44c0aff..9ed9c6c 100644 (file)
@@ -1,3 +1,22 @@
+2019-05-15  Zalan Bujtas  <zalan@apple.com>
+
+        Do not create a shape object outside of the layout context
+        https://bugs.webkit.org/show_bug.cgi?id=197926
+        <rdar://problem/50627858>
+
+        Reviewed by Simon Fraser.
+
+        ShapeOutside objects are used to compute line constrains during layout (in a strict sense, they are part of the layout context and should only be mutated during layout).
+        If we don't create one during layout, we probably don't need to know its geometry during paint (or any other non-layout activity) either.
+
+        Test: fast/block/float/float-with-shape-outside-crash.html
+
+        * rendering/FloatingObjects.cpp:
+        (WebCore::ComputeFloatOffsetForLineLayoutAdapter<FloatingObject::FloatLeft>::updateOffsetIfNeeded):
+        (WebCore::ComputeFloatOffsetForLineLayoutAdapter<FloatingObject::FloatRight>::updateOffsetIfNeeded):
+        * rendering/shapes/ShapeOutsideInfo.cpp:
+        (WebCore::ShapeOutsideInfo::computeDeltasForContainingBlockLine):
+
 2019-05-15  Youenn Fablet  <youenn@apple.com>
 
         Mark beacon and ping loads as low priority
index 53b8d5c..4cdd139 100644 (file)
@@ -479,7 +479,7 @@ inline bool ComputeFloatOffsetForLineLayoutAdapter<FloatingObject::FloatLeft>::u
     LayoutUnit logicalRight = m_renderer->logicalRightForFloat(floatingObject);
     if (ShapeOutsideInfo* shapeOutside = floatingObject.renderer().shapeOutsideInfo()) {
         ShapeOutsideDeltas shapeDeltas = shapeOutside->computeDeltasForContainingBlockLine(*m_renderer, floatingObject, m_lineTop, m_lineBottom - m_lineTop);
-        if (!shapeDeltas.lineOverlapsShape())
+        if (!shapeDeltas.isValid() || !shapeDeltas.lineOverlapsShape())
             return false;
 
         logicalRight += shapeDeltas.rightMarginBoxDelta();
@@ -498,7 +498,7 @@ inline bool ComputeFloatOffsetForLineLayoutAdapter<FloatingObject::FloatRight>::
     LayoutUnit logicalLeft = m_renderer->logicalLeftForFloat(floatingObject);
     if (ShapeOutsideInfo* shapeOutside = floatingObject.renderer().shapeOutsideInfo()) {
         ShapeOutsideDeltas shapeDeltas = shapeOutside->computeDeltasForContainingBlockLine(*m_renderer, floatingObject, m_lineTop, m_lineBottom - m_lineTop);
-        if (!shapeDeltas.lineOverlapsShape())
+        if (!shapeDeltas.isValid() || !shapeDeltas.lineOverlapsShape())
             return false;
 
         logicalLeft += shapeDeltas.leftMarginBoxDelta();
index ed4b8a9..25f79e9 100644 (file)
@@ -38,6 +38,7 @@
 #include "RenderBox.h"
 #include "RenderFragmentContainer.h"
 #include "RenderImage.h"
+#include "RenderView.h"
 
 namespace WebCore {
 
@@ -320,6 +321,10 @@ bool ShapeOutsideInfo::isEnabledFor(const RenderBox& box)
 
 ShapeOutsideDeltas ShapeOutsideInfo::computeDeltasForContainingBlockLine(const RenderBlockFlow& containingBlock, const FloatingObject& floatingObject, LayoutUnit lineTop, LayoutUnit lineHeight)
 {
+    // If we never constructed this shape during layout, we propably don't need to know about it outside of layout in the context of "containing block line".
+    if (!m_shape && !containingBlock.view().frameView().layoutContext().isInLayout())
+        return { };
+
     ASSERT(lineHeight >= 0);
     LayoutUnit borderBoxTop = containingBlock.logicalTopForFloat(floatingObject) + containingBlock.marginBeforeForChild(m_renderer);
     LayoutUnit borderBoxLineTop = lineTop - borderBoxTop;