Skip to content

Commit

Permalink
Cherry-pick 265870.61@safari-7616-branch (9ff2ba0). https://bugs.webk…
Browse files Browse the repository at this point in the history
…it.org/show_bug.cgi?id=258675

    Legends could be valid non-spanner siblings of RenderMultiColumnSet
    https://bugs.webkit.org/show_bug.cgi?id=258675
    <rdar://111221306>

    Reviewed by Antti Koivisto.

    We usually construct one RenderMultiColumnSet renderer for a multi-column context.

    e.g:
    <div style="column-count: 2">
      <div></div>
      <div></div>
      <div></div>
    </div>

    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.
    <div style="column-count: 2">
      <div style="column-span: all"></div>
      <div></div>
      <div></div>
    </div>

    where the spanner is moved out of the column context indicating it spans all the columns

    DIV RenderBlockFlow
      RenderMultiColumnFlowThread
        RenderMultiColumnSpannerPlaceholder (this is the <div>'s original insertion point)
        DIV RenderBlockFlow
        DIV RenderBlockFlow
      RenderMultiColumnSet
      DIV RenderBlockFlow (moved out column spanner)
      RenderMultiColumnSet

    However since <legend> 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
  • Loading branch information
alanbaradlay authored and mcatanzaro committed Sep 26, 2023
1 parent 49fd397 commit a9b939e
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 1 deletion.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
or assert
16 changes: 16 additions & 0 deletions LayoutTests/fast/multicol/crash-when-legend-is-present.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<style>
html {
outline-style: auto;
}
fieldset {
overflow-y: -webkit-paged-y;
}
</style>
<fieldset id=container><legend></legend><label id=child></label></fieldset><script>
if (window.testRunner)
testRunner.dumpAsText();
document.body.offsetHeight;
child.innerText = "pass if no crash";
document.body.offsetHeight;
container.innerText = "or assert";
</script>
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
}
Expand Down

0 comments on commit a9b939e

Please sign in to comment.