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.

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: http://svn.webkit.org/repository/webkit/trunk@245361 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog
index 89618da..976a1a0 100644
--- a/LayoutTests/ChangeLog
+++ b/LayoutTests/ChangeLog
@@ -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
index 0000000..4ef250d
--- /dev/null
+++ b/LayoutTests/fast/block/float/float-with-shape-outside-crash-expected.txt
@@ -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
index 0000000..0839024
--- /dev/null
+++ b/LayoutTests/fast/block/float/float-with-shape-outside-crash.html
@@ -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>
diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog
index 44c0aff..9ed9c6c 100644
--- a/Source/WebCore/ChangeLog
+++ b/Source/WebCore/ChangeLog
@@ -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
diff --git a/Source/WebCore/rendering/FloatingObjects.cpp b/Source/WebCore/rendering/FloatingObjects.cpp
index 53b8d5c..4cdd139 100644
--- a/Source/WebCore/rendering/FloatingObjects.cpp
+++ b/Source/WebCore/rendering/FloatingObjects.cpp
@@ -479,7 +479,7 @@
     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 @@
     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();
diff --git a/Source/WebCore/rendering/shapes/ShapeOutsideInfo.cpp b/Source/WebCore/rendering/shapes/ShapeOutsideInfo.cpp
index ed4b8a9..25f79e9 100644
--- a/Source/WebCore/rendering/shapes/ShapeOutsideInfo.cpp
+++ b/Source/WebCore/rendering/shapes/ShapeOutsideInfo.cpp
@@ -38,6 +38,7 @@
 #include "RenderBox.h"
 #include "RenderFragmentContainer.h"
 #include "RenderImage.h"
+#include "RenderView.h"
 
 namespace WebCore {
 
@@ -320,6 +321,10 @@
 
 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;