From 7a8e75266ff2c138f212a301de9774eafb2b3143 Mon Sep 17 00:00:00 2001 From: Martin Robinson Date: Wed, 16 Apr 2025 17:32:48 +0200 Subject: [PATCH] layout: Throw away nested marker elements instead of storing them in a `BoxSlot` (#36568) `::before` and `::after` pseudo-elements can have their own `::marker` pseudo-element. Since this case wasn't taken into account, they were being stored in main element's `::marker` `BoxSlot`. This could cause problems where two layout boxes would try to use the same `BoxSlot`. For now, just don't store the nested version of the marker. Later, we'll need to figure out how to store these layout objects without causing too much memory usage. Testing: This is covered by `/css/css-lists/nested-marker-styling.html`. In addition, we also made a test case that always causes this crash, but since it had to create 100000 `
`s it's probably not appropriate for a test suite. Fixes: #36551 Signed-off-by: Martin Robinson Co-authored-by: Oriol Brufau --- components/layout_2020/flow/construct.rs | 39 +++++++++++++++++++----- 1 file changed, 31 insertions(+), 8 deletions(-) diff --git a/components/layout_2020/flow/construct.rs b/components/layout_2020/flow/construct.rs index 07b2bbb5e0a..a6471756db8 100644 --- a/components/layout_2020/flow/construct.rs +++ b/components/layout_2020/flow/construct.rs @@ -169,10 +169,11 @@ impl BlockContainer { if let Some((marker_info, marker_contents)) = crate::lists::make_marker(context, info) { match marker_info.style.clone_list_style_position() { ListStylePosition::Inside => { - builder.handle_list_item_marker_inside(&marker_info, marker_contents) + builder.handle_list_item_marker_inside(&marker_info, info, marker_contents) }, ListStylePosition::Outside => builder.handle_list_item_marker_outside( &marker_info, + info, marker_contents, info.style.clone(), ), @@ -384,28 +385,50 @@ where { fn handle_list_item_marker_inside( &mut self, - info: &NodeAndStyleInfo, + marker_info: &NodeAndStyleInfo, + container_info: &NodeAndStyleInfo, contents: Vec, ) { + // TODO: We do not currently support saving box slots for ::marker pseudo-elements + // that are part nested in ::before and ::after pseudo elements. For now, just + // forget about them once they are built. + let box_slot = match container_info.pseudo_element_type { + Some(_) => BoxSlot::dummy(), + None => marker_info + .node + .pseudo_element_box_slot(PseudoElement::Marker), + }; + self.handle_inline_level_element( - info, + marker_info, DisplayInside::Flow { is_list_item: false, }, NonReplacedContents::OfPseudoElement(contents).into(), - info.node.pseudo_element_box_slot(PseudoElement::Marker), + box_slot, ); } fn handle_list_item_marker_outside( &mut self, - info: &NodeAndStyleInfo, + marker_info: &NodeAndStyleInfo, + container_info: &NodeAndStyleInfo, contents: Vec, list_item_style: Arc, ) { + // TODO: We do not currently support saving box slots for ::marker pseudo-elements + // that are part nested in ::before and ::after pseudo elements. For now, just + // forget about them once they are built. + let box_slot = match container_info.pseudo_element_type { + Some(_) => BoxSlot::dummy(), + None => marker_info + .node + .pseudo_element_box_slot(PseudoElement::Marker), + }; + self.block_level_boxes.push(BlockLevelJob { - info: info.clone(), - box_slot: info.node.pseudo_element_box_slot(PseudoElement::Marker), + info: marker_info.clone(), + box_slot, kind: BlockLevelCreator::OutsideMarker { contents, list_item_style, @@ -452,7 +475,7 @@ where // Ignore `list-style-position` here: // “If the list item is an inline box: this value is equivalent to `inside`.” // https://drafts.csswg.org/css-lists/#list-style-position-outside - self.handle_list_item_marker_inside(&marker_info, marker_contents) + self.handle_list_item_marker_inside(&marker_info, info, marker_contents) } }