Paginated mode: Infinite recursion in RenderTable::layout
authorzalan@apple.com <zalan@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 12 Jul 2017 15:37:52 +0000 (15:37 +0000)
committerzalan@apple.com <zalan@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 12 Jul 2017 15:37:52 +0000 (15:37 +0000)
https://bugs.webkit.org/show_bug.cgi?id=174413

Reviewed by Simon Fraser.

This patch is a workaround for avoiding infinite recursion when the table layout does not stabilize.
Apparently we leak some context (computed padding in this case) from the current to the subsequent layout.
The subsequent layouts always end up producing different line heights for some of the cells in the <thead>.
In paginated mode, when the section moves (<thead>, <tbody> etc) we call layout again recursively.
This could lead to infinite recursion for unstable table layout.

Unable to come up with a reduction yet.

* rendering/RenderTable.cpp:
(WebCore::RenderTable::layout):
* rendering/RenderTable.h:

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

Source/WebCore/ChangeLog
Source/WebCore/rendering/RenderTable.cpp
Source/WebCore/rendering/RenderTable.h

index 59a6fd2..e905590 100644 (file)
@@ -1,3 +1,22 @@
+2017-07-12  Zalan Bujtas  <zalan@apple.com>
+
+        Paginated mode: Infinite recursion in RenderTable::layout
+        https://bugs.webkit.org/show_bug.cgi?id=174413
+
+        Reviewed by Simon Fraser.
+
+        This patch is a workaround for avoiding infinite recursion when the table layout does not stabilize.
+        Apparently we leak some context (computed padding in this case) from the current to the subsequent layout.
+        The subsequent layouts always end up producing different line heights for some of the cells in the <thead>.
+        In paginated mode, when the section moves (<thead>, <tbody> etc) we call layout again recursively.
+        This could lead to infinite recursion for unstable table layout.
+
+        Unable to come up with a reduction yet.
+
+        * rendering/RenderTable.cpp:
+        (WebCore::RenderTable::layout):
+        * rendering/RenderTable.h:
+
 2017-07-12  Youenn Fablet  <youenn@apple.com>
 
         WebRTC: Incorrect sdpMLineIndex for video breaks Firefox interop
index 43ab625..150b8ac 100644 (file)
@@ -47,6 +47,7 @@
 #include "RenderTableSection.h"
 #include "RenderView.h"
 #include "StyleInheritedData.h"
+#include <wtf/SetForScope.h>
 #include <wtf/StackStats.h>
 
 namespace WebCore {
@@ -601,8 +602,13 @@ void RenderTable::layout()
 
     bool paginated = view().layoutState() && view().layoutState()->isPaginated();
     if (sectionMoved && paginated) {
-        markForPaginationRelayoutIfNeeded();
-        layoutIfNeeded();
+        // FIXME: Table layout should always stabilize even when section moves (see webkit.org/b/174412).
+        if (!m_inRecursiveSectionMovedWithPagination) {
+            SetForScope<bool> paginatedSectionMoved(m_inRecursiveSectionMovedWithPagination, true);
+            markForPaginationRelayoutIfNeeded();
+            layoutIfNeeded();
+        } else
+            ASSERT_NOT_REACHED();
     }
     
     // FIXME: This value isn't the intrinsic content logical height, but we need
index 88c417e..4da849b 100644 (file)
@@ -366,6 +366,7 @@ private:
     LayoutUnit m_borderEnd;
     mutable LayoutUnit m_columnOffsetTop;
     mutable LayoutUnit m_columnOffsetHeight;
+    bool m_inRecursiveSectionMovedWithPagination { false };
 };
 
 inline RenderTableSection* RenderTable::topSection() const