From a9b939ea6c6bf2128ef67b017b9298efa3e17137 Mon Sep 17 00:00:00 2001 From: Alan Baradlay Date: Wed, 12 Jul 2023 20:06:31 -0700 Subject: [PATCH] Cherry-pick 265870.61@safari-7616-branch (9ff2ba06a74f). https://bugs.webkit.org/show_bug.cgi?id=258675 Legends could be valid non-spanner siblings of RenderMultiColumnSet https://bugs.webkit.org/show_bug.cgi?id=258675 Reviewed by Antti Koivisto. We usually construct one RenderMultiColumnSet renderer for a multi-column context. e.g:
generates the following render tree structure: DIV RenderBlockFlow RenderMultiColumnFlowThread DIV RenderBlockFlow DIV RenderBlockFlow DIV RenderBlockFlow RenderMultiColumnSet We also construct RenderMultiColumnSets for column spanners e.g.
where the spanner is moved out of the column context indicating it spans all the columns DIV RenderBlockFlow RenderMultiColumnFlowThread RenderMultiColumnSpannerPlaceholder (this is the
's original insertion point) DIV RenderBlockFlow DIV RenderBlockFlow RenderMultiColumnSet DIV RenderBlockFlow (moved out column spanner) RenderMultiColumnSet However since does not participate in multi-column, it does _not_ get moved under RenderMultiColumnFlowThread when constructing the multi-column context and ends up being a sibling of the RenderMultiColumnSet. e.g. FIELDSET RenderFieldSet RenderMultiColumnFlowThread RenderBlock RenderMultiColumnSet LEGEND RenderBlock and later it gets mistaken for a column spanner and as the result we construct a redundant RenderMultiColumnSet. This patch handles this case by checking against legend siblings. * LayoutTests/fast/multicol/crash-when-legend-is-present-expected.txt: Added. * LayoutTests/fast/multicol/crash-when-legend-is-present.html: Added. * Source/WebCore/rendering/updating/RenderTreeBuilderMultiColumn.cpp: (WebCore::RenderTreeBuilder::MultiColumn::processPossibleSpannerDescendant): Canonical link: https://commits.webkit.org/265870.61@safari-7616-branch --- .../crash-when-legend-is-present-expected.txt | 1 + .../multicol/crash-when-legend-is-present.html | 16 ++++++++++++++++ .../updating/RenderTreeBuilderMultiColumn.cpp | 5 ++++- 3 files changed, 21 insertions(+), 1 deletion(-) create mode 100644 LayoutTests/fast/multicol/crash-when-legend-is-present-expected.txt create mode 100644 LayoutTests/fast/multicol/crash-when-legend-is-present.html diff --git a/LayoutTests/fast/multicol/crash-when-legend-is-present-expected.txt b/LayoutTests/fast/multicol/crash-when-legend-is-present-expected.txt new file mode 100644 index 000000000000..e2cd60100314 --- /dev/null +++ b/LayoutTests/fast/multicol/crash-when-legend-is-present-expected.txt @@ -0,0 +1 @@ +or assert diff --git a/LayoutTests/fast/multicol/crash-when-legend-is-present.html b/LayoutTests/fast/multicol/crash-when-legend-is-present.html new file mode 100644 index 000000000000..9eeb40e25a0f --- /dev/null +++ b/LayoutTests/fast/multicol/crash-when-legend-is-present.html @@ -0,0 +1,16 @@ + +
diff --git a/Source/WebCore/rendering/updating/RenderTreeBuilderMultiColumn.cpp b/Source/WebCore/rendering/updating/RenderTreeBuilderMultiColumn.cpp index 68799907eea2..07b16eead1df 100644 --- a/Source/WebCore/rendering/updating/RenderTreeBuilderMultiColumn.cpp +++ b/Source/WebCore/rendering/updating/RenderTreeBuilderMultiColumn.cpp @@ -373,7 +373,10 @@ RenderObject* RenderTreeBuilder::MultiColumn::processPossibleSpannerDescendant(R // column set at the end of the multicol container. We don't really check here if the // child inserted precedes any spanner or not (as that's an expensive operation). Just // make sure we have a column set at the end. It's no big deal if it remains unused. - if (!lastSet->nextSibling()) + + // Legends are siblings of RenderMultiColumnSets not because they are spanners, but because they don't participate in multi-column context. + auto hasMultiColumnSet = !lastSet->nextSibling() || lastSet->nextSibling()->isLegend(); + if (hasMultiColumnSet) return nextDescendant; } }