ASSERTION FAILED: hasLayer() in RenderLayer::enclosingOverflowClipLayer
https://bugs.webkit.org/show_bug.cgi?id=205474

Patch by Jack Lee <shihchieh_lee@apple.com> on 2020-01-06
Reviewed by Simon Fraser.

Source/WebCore:

Test: fast/css/sticky/sticky-tablecol-crash.html

* rendering/RenderBoxModelObject.cpp:
(WebCore::RenderBoxModelObject::enclosingClippingBoxForStickyPosition const):
(WebCore::RenderBoxModelObject::constrainingRectForStickyPosition const):
(WebCore::RenderBoxModelObject::stickyPositionOffset const):

LayoutTests:

* fast/css/sticky/sticky-tablecol-crash-expected.txt: Added.
* fast/css/sticky/sticky-tablecol-crash.html: Added.

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@254086 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog
index 86d811c..fac5152 100644
--- a/LayoutTests/ChangeLog
+++ b/LayoutTests/ChangeLog
@@ -1,3 +1,13 @@
+2020-01-06  Jack Lee  <shihchieh_lee@apple.com>
+
+        ASSERTION FAILED: hasLayer() in RenderLayer::enclosingOverflowClipLayer
+        https://bugs.webkit.org/show_bug.cgi?id=205474
+
+        Reviewed by Simon Fraser.
+
+        * fast/css/sticky/sticky-tablecol-crash-expected.txt: Added.
+        * fast/css/sticky/sticky-tablecol-crash.html: Added.
+
 2020-01-06  Antoine Quint  <graouts@apple.com>
 
         REGRESSION: [ iOS ] imported/w3c/web-platform-tests/dom/events/Event-dispatch-on-disabled-elements.html is failing
diff --git a/LayoutTests/fast/css/sticky/sticky-tablecol-crash-expected.txt b/LayoutTests/fast/css/sticky/sticky-tablecol-crash-expected.txt
new file mode 100644
index 0000000..8d6429d
--- /dev/null
+++ b/LayoutTests/fast/css/sticky/sticky-tablecol-crash-expected.txt
@@ -0,0 +1,5 @@
+Tests position:sticky on a table column.
+
+The test passes if WebKit doesn't crash or hit an assertion.
+
+
diff --git a/LayoutTests/fast/css/sticky/sticky-tablecol-crash.html b/LayoutTests/fast/css/sticky/sticky-tablecol-crash.html
new file mode 100644
index 0000000..a3ad653
--- /dev/null
+++ b/LayoutTests/fast/css/sticky/sticky-tablecol-crash.html
@@ -0,0 +1,22 @@
+<style>
+    body {
+        height: 1000px;
+    }
+    col {
+        position: sticky;
+    }
+</style>
+<body onload="runTest()">
+<script>
+if (window.testRunner)
+    testRunner.dumpAsText();
+
+function runTest() {
+   tableCol.scrollIntoViewIfNeeded(true);
+}
+</script>
+<table>
+<col id="tableCol"></col>
+<p>Tests position:sticky on a table column.</p>
+<p>The test passes if WebKit doesn't crash or hit an assertion.</p>
+</body>
diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog
index 5d01fe8..8b12e5e 100644
--- a/Source/WebCore/ChangeLog
+++ b/Source/WebCore/ChangeLog
@@ -1,3 +1,17 @@
+2020-01-06  Jack Lee  <shihchieh_lee@apple.com>
+
+        ASSERTION FAILED: hasLayer() in RenderLayer::enclosingOverflowClipLayer
+        https://bugs.webkit.org/show_bug.cgi?id=205474
+
+        Reviewed by Simon Fraser.
+
+        Test: fast/css/sticky/sticky-tablecol-crash.html
+
+        * rendering/RenderBoxModelObject.cpp:
+        (WebCore::RenderBoxModelObject::enclosingClippingBoxForStickyPosition const):
+        (WebCore::RenderBoxModelObject::constrainingRectForStickyPosition const):
+        (WebCore::RenderBoxModelObject::stickyPositionOffset const):
+
 2020-01-06  Alex Christensen  <achristensen@webkit.org>
 
         Allow wildcard scheme in UserContentURLPattern
diff --git a/Source/WebCore/rendering/RenderBoxModelObject.cpp b/Source/WebCore/rendering/RenderBoxModelObject.cpp
index c8c7bf1..785a123 100644
--- a/Source/WebCore/rendering/RenderBoxModelObject.cpp
+++ b/Source/WebCore/rendering/RenderBoxModelObject.cpp
@@ -445,7 +445,8 @@
 {
     ASSERT(isStickilyPositioned());
 
-    auto* clipLayer = layer()->enclosingOverflowClipLayer(ExcludeSelf);
+    RenderLayer* clipLayer = hasLayer() ? layer()->enclosingOverflowClipLayer(ExcludeSelf) : nullptr;
+
     if (enclosingClippingLayer)
         *enclosingClippingLayer = clipLayer;
 
@@ -536,7 +537,8 @@
 
 FloatRect RenderBoxModelObject::constrainingRectForStickyPosition() const
 {
-    RenderLayer* enclosingClippingLayer = layer()->enclosingOverflowClipLayer(ExcludeSelf);
+    RenderLayer* enclosingClippingLayer = hasLayer() ? layer()->enclosingOverflowClipLayer(ExcludeSelf) : nullptr;
+
     if (enclosingClippingLayer) {
         RenderBox& enclosingClippingBox = downcast<RenderBox>(enclosingClippingLayer->renderer());
         LayoutRect clipRect = enclosingClippingBox.overflowClipRect(LayoutPoint(), nullptr); // FIXME: make this work in regions.
@@ -560,8 +562,6 @@
 
 LayoutSize RenderBoxModelObject::stickyPositionOffset() const
 {
-    ASSERT(hasLayer());
-    
     FloatRect constrainingRect = constrainingRectForStickyPosition();
     StickyPositionViewportConstraints constraints;
     computeStickyPositionConstraints(constraints, constrainingRect);