Changeset 209259 in webkit


Ignore:
Timestamp:
Dec 2, 2016 1:25:15 PM (7 years ago)
Author:
Alan Bujtas
Message:

ASSERTION FAILED: flowThread->regionInRange(region, startRegion, endRegion) in WebCore::RenderBox::borderBoxRectInRegion
https://bugs.webkit.org/show_bug.cgi?id=152113
<rdar://problem/27720221>

Reviewed by David Hyatt.

Source/WebCore:

In a nested column context, do not process a spanner if it belongs to an inner column.

While populating a flow, we search for possible spanners and construct multicolumnsets accordingly.
However due to the top-down nature of populating flows, a descendant spanner could belong to an inner
flow which hasn't been populated yet.
This patch checks if a potential spanner has an ancestor (which is also a descendant
of the flow that we are populating -> nested) that will eventually create a flow context.

Test: fast/multicol/assert-with-nested-columns-and-spanner.html

  • rendering/RenderBlockFlow.cpp:

(WebCore::RenderBlockFlow::computeColumnCountAndWidth):
(WebCore::RenderBlockFlow::willCreateColumns):

  • rendering/RenderBlockFlow.h:
  • rendering/RenderMultiColumnFlowThread.cpp:

(WebCore::isValidColumnSpanner):

LayoutTests:

  • fast/multicol/assert-with-nested-columns-and-spanner-expected.txt: Added.
  • fast/multicol/assert-with-nested-columns-and-spanner.html: Added.
Location:
trunk
Files:
2 added
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r209258 r209259  
     12016-12-02  Zalan Bujtas  <zalan@apple.com>
     2
     3        ASSERTION FAILED: flowThread->regionInRange(region, startRegion, endRegion) in WebCore::RenderBox::borderBoxRectInRegion
     4        https://bugs.webkit.org/show_bug.cgi?id=152113
     5        <rdar://problem/27720221>
     6
     7        Reviewed by David Hyatt.
     8
     9        * fast/multicol/assert-with-nested-columns-and-spanner-expected.txt: Added.
     10        * fast/multicol/assert-with-nested-columns-and-spanner.html: Added.
     11
    1122016-12-02  Dave Hyatt  <hyatt@apple.com>
    213
  • trunk/Source/WebCore/ChangeLog

    r209258 r209259  
     12016-12-02  Zalan Bujtas  <zalan@apple.com>
     2
     3        ASSERTION FAILED: flowThread->regionInRange(region, startRegion, endRegion) in WebCore::RenderBox::borderBoxRectInRegion
     4        https://bugs.webkit.org/show_bug.cgi?id=152113
     5        <rdar://problem/27720221>
     6
     7        Reviewed by David Hyatt.
     8
     9        In a nested column context, do not process a spanner if it belongs to an inner column.
     10
     11        While populating a flow, we search for possible spanners and construct multicolumnsets accordingly.
     12        However due to the top-down nature of populating flows, a descendant spanner could belong to an inner
     13        flow which hasn't been populated yet.
     14        This patch checks if a potential spanner has an ancestor (which is also a descendant
     15        of the flow that we are populating -> nested) that will eventually create a flow context.
     16
     17        Test: fast/multicol/assert-with-nested-columns-and-spanner.html
     18
     19        * rendering/RenderBlockFlow.cpp:
     20        (WebCore::RenderBlockFlow::computeColumnCountAndWidth):
     21        (WebCore::RenderBlockFlow::willCreateColumns):
     22        * rendering/RenderBlockFlow.h:
     23        * rendering/RenderMultiColumnFlowThread.cpp:
     24        (WebCore::isValidColumnSpanner):
     25
    1262016-12-02  Dave Hyatt  <hyatt@apple.com>
    227
  • trunk/Source/WebCore/rendering/RenderBlockFlow.cpp

    r208985 r209259  
    399399
    400400void RenderBlockFlow::computeColumnCountAndWidth()
    401 {   
     401{
    402402    // Calculate our column width and column count.
    403403    // FIXME: Can overflow on fast/block/float/float-not-removed-from-next-sibling4.html, see https://bugs.webkit.org/show_bug.cgi?id=68744
     
    427427    }
    428428    setComputedColumnCountAndWidth(desiredColumnCount, desiredColumnWidth);
     429}
     430
     431bool RenderBlockFlow::willCreateColumns()
     432{
     433    if (!firstChild())
     434        return false;
     435
     436    if (!style().specifiesColumns())
     437        return false;
     438
     439    // column-axis initiates MultiColumnFlowThread.
     440    if (!style().hasInlineColumnAxis())
     441        return true;
     442
     443    // Non-auto column-width always initiates MultiColumnFlowThread.
     444    if (!style().hasAutoColumnWidth())
     445        return true;
     446
     447    // column-count > 1 always initiates MultiColumnFlowThread.
     448    if (!style().hasAutoColumnCount())
     449        return style().columnCount() > 1;
     450
     451    ASSERT_NOT_REACHED();
     452    return false;
    429453}
    430454
  • trunk/Source/WebCore/rendering/RenderBlockFlow.h

    r208985 r209259  
    283283    RenderMultiColumnFlowThread* multiColumnFlowThread() const { return hasRareBlockFlowData() ? rareBlockFlowData()->m_multiColumnFlowThread : nullptr; }
    284284    void setMultiColumnFlowThread(RenderMultiColumnFlowThread*);
     285    bool willCreateColumns();
    285286   
    286287    bool containsFloats() const override { return m_floatingObjects && !m_floatingObjects->set().isEmpty(); }
  • trunk/Source/WebCore/rendering/RenderMultiColumnFlowThread.cpp

    r208731 r209259  
    241241    // We assume that we're inside the flow thread. This function is not to be called otherwise.
    242242    ASSERT(descendant.isDescendantOf(&flowThread));
    243 
    244243    // First make sure that the renderer itself has the right properties for becoming a spanner.
    245     auto& style = descendant.style();
    246     if (style.columnSpan() != ColumnSpanAll || !is<RenderBox>(descendant) || descendant.isFloatingOrOutOfFlowPositioned())
     244    if (!is<RenderBox>(descendant))
    247245        return false;
    248246
    249     RenderElement* container = descendant.parent();
    250     if (!is<RenderBlockFlow>(*container) || container->childrenInline()) {
     247    auto& descendantBox = downcast<RenderBox>(descendant);
     248    if (descendantBox.isFloatingOrOutOfFlowPositioned())
     249        return false;
     250
     251    if (descendantBox.style().columnSpan() != ColumnSpanAll)
     252        return false;
     253
     254    auto* parent = descendantBox.parent();
     255    if (!is<RenderBlockFlow>(*parent) || parent->childrenInline()) {
    251256        // Needs to be block-level.
    252257        return false;
     
    254259   
    255260    // We need to have the flow thread as the containing block. A spanner cannot break out of the flow thread.
    256     RenderFlowThread* enclosingFlowThread = descendant.flowThreadContainingBlock();
     261    auto* enclosingFlowThread = descendantBox.flowThreadContainingBlock();
    257262    if (enclosingFlowThread != &flowThread)
    258263        return false;
    259264
    260265    // This looks like a spanner, but if we're inside something unbreakable, it's not to be treated as one.
    261     for (auto* ancestor = downcast<RenderBox>(descendant).containingBlock(); ancestor && !is<RenderView>(*ancestor); ancestor = ancestor->containingBlock()) {
    262         if (ancestor->isRenderFlowThread()) {
     266    for (auto* ancestor = descendantBox.containingBlock(); ancestor; ancestor = ancestor->containingBlock()) {
     267        if (is<RenderView>(*ancestor))
     268            return false;
     269        if (is<RenderFlowThread>(*ancestor)) {
    263270            // Don't allow any intervening non-multicol fragmentation contexts. The spec doesn't say
    264271            // anything about disallowing this, but it's just going to be too complicated to
     
    266273            return ancestor == &flowThread;
    267274        }
     275        // This ancestor (descendent of the flowThread) will create columns later. The spanner belongs to it.
     276        if (is<RenderBlockFlow>(*ancestor) && downcast<RenderBlockFlow>(*ancestor).willCreateColumns())
     277            return false;
    268278        ASSERT(ancestor->style().columnSpan() != ColumnSpanAll || !isValidColumnSpanner(flowThread, *ancestor));
    269279        if (ancestor->isUnsplittableForPagination())
Note: See TracChangeset for help on using the changeset viewer.