diff --git a/LayoutTests/fast/multicol/nested-columns-out-of-flow-crash-expected.txt b/LayoutTests/fast/multicol/nested-columns-out-of-flow-crash-expected.txt
new file mode 100644
index 000000000000..ae2e3525ea4d
--- /dev/null
+++ b/LayoutTests/fast/multicol/nested-columns-out-of-flow-crash-expected.txt
@@ -0,0 +1 @@
+Pass if no crash.
diff --git a/LayoutTests/fast/multicol/nested-columns-out-of-flow-crash.html b/LayoutTests/fast/multicol/nested-columns-out-of-flow-crash.html
new file mode 100644
index 000000000000..b8b10bff6142
--- /dev/null
+++ b/LayoutTests/fast/multicol/nested-columns-out-of-flow-crash.html
@@ -0,0 +1,12 @@
+
+Pass if no crash.
+
diff --git a/Source/WebCore/rendering/RenderObject.cpp b/Source/WebCore/rendering/RenderObject.cpp
index 063f8e19a036..f3b689657ba8 100644
--- a/Source/WebCore/rendering/RenderObject.cpp
+++ b/Source/WebCore/rendering/RenderObject.cpp
@@ -223,7 +223,7 @@ bool RenderObject::isBlockContainer() const
|| display == DisplayType::TableCaption) && !isRenderReplaced();
}
-void RenderObject::setFragmentedFlowStateIncludingDescendants(FragmentedFlowState state, const RenderElement* fragmentedFlowRoot)
+void RenderObject::setFragmentedFlowStateIncludingDescendants(FragmentedFlowState state, const RenderElement* fragmentedFlowRoot, SkipDescendentFragmentedFlow skipDescendentFragmentedFlow)
{
setFragmentedFlowState(state);
@@ -232,7 +232,7 @@ void RenderObject::setFragmentedFlowStateIncludingDescendants(FragmentedFlowStat
for (auto& child : childrenOfType(downcast(*this))) {
// If the child is a fragmentation context it already updated the descendants flag accordingly.
- if (child.isRenderFragmentedFlow())
+ if (child.isRenderFragmentedFlow() && skipDescendentFragmentedFlow == SkipDescendentFragmentedFlow::Yes)
continue;
if (fragmentedFlowRoot && child.isOutOfFlowPositioned()) {
// Fragmented status propagation stops at out-of-flow boundary.
@@ -248,8 +248,8 @@ void RenderObject::setFragmentedFlowStateIncludingDescendants(FragmentedFlowStat
if (!isInsideMulticolumnFlow())
continue;
}
- ASSERT(state != child.fragmentedFlowState());
- child.setFragmentedFlowStateIncludingDescendants(state, fragmentedFlowRoot);
+ ASSERT(skipDescendentFragmentedFlow == SkipDescendentFragmentedFlow::No || state != child.fragmentedFlowState());
+ child.setFragmentedFlowStateIncludingDescendants(state, fragmentedFlowRoot, skipDescendentFragmentedFlow);
}
}
@@ -292,7 +292,7 @@ void RenderObject::initializeFragmentedFlowStateOnInsertion()
return;
auto* enclosingFragmentedFlow = locateEnclosingFragmentedFlow();
- setFragmentedFlowStateIncludingDescendants(computedState, enclosingFragmentedFlow ? enclosingFragmentedFlow->parent() : nullptr);
+ setFragmentedFlowStateIncludingDescendants(computedState, enclosingFragmentedFlow ? enclosingFragmentedFlow->parent() : nullptr, SkipDescendentFragmentedFlow::No);
}
void RenderObject::resetFragmentedFlowStateOnRemoval()
diff --git a/Source/WebCore/rendering/RenderObject.h b/Source/WebCore/rendering/RenderObject.h
index bc717fcfe3b5..2f89cbce4789 100644
--- a/Source/WebCore/rendering/RenderObject.h
+++ b/Source/WebCore/rendering/RenderObject.h
@@ -297,7 +297,8 @@ class RenderObject : public CachedImageClient {
InsideInFragmentedFlow = 1,
};
- void setFragmentedFlowStateIncludingDescendants(FragmentedFlowState, const RenderElement* fragmentedFlowRoot);
+ enum class SkipDescendentFragmentedFlow { No, Yes };
+ void setFragmentedFlowStateIncludingDescendants(FragmentedFlowState, const RenderElement* fragmentedFlowRoot, SkipDescendentFragmentedFlow = SkipDescendentFragmentedFlow::Yes);
FragmentedFlowState fragmentedFlowState() const { return m_bitfields.fragmentedFlowState(); }
void setFragmentedFlowState(FragmentedFlowState state) { m_bitfields.setFragmentedFlowState(state); }