From d87b3030a7d1098b22604e55eaf0deaf507ca280 Mon Sep 17 00:00:00 2001 From: Jelle Raaijmakers Date: Thu, 28 Aug 2025 21:35:21 +0200 Subject: [PATCH] LibWeb: Prevent creation of new UsedValues for nested inline nodes In LayoutState, used_values_per_layout_node should not be modified in order to determine inline nodes' dimensions - all the required values should already be in there. In 2585f2da0d1d2e3577f1b62aefcc14ca75216c73 we did accidentally create new values, causing the code further down to try and get a PaintableBox from an anonymous container and crashing. Fixes #6015. --- Libraries/LibWeb/Layout/LayoutState.cpp | 15 ++++++--------- ...button-display-inline-with-nested-inlines.html | 2 ++ 2 files changed, 8 insertions(+), 9 deletions(-) create mode 100644 Tests/LibWeb/Crash/Layout/button-display-inline-with-nested-inlines.html diff --git a/Libraries/LibWeb/Layout/LayoutState.cpp b/Libraries/LibWeb/Layout/LayoutState.cpp index 5f3673c2e9d..b19d24056bb 100644 --- a/Libraries/LibWeb/Layout/LayoutState.cpp +++ b/Libraries/LibWeb/Layout/LayoutState.cpp @@ -398,19 +398,16 @@ void LayoutState::commit(Box& root) if (paintable.line_index() != line_index) return TraversalDecision::Continue; - if (&paintable != paintable_with_lines) { - auto const& used_values = get(paintable.layout_node_with_style_and_box_metrics()); - size.set_width(size.width() + used_values.margin_box_left() + used_values.margin_box_right()); - } + auto used_values = used_values_per_layout_node.get(paintable.layout_node_with_style_and_box_metrics()); + if (&paintable != paintable_with_lines && used_values.has_value()) + size.set_width(size.width() + used_values.value()->margin_box_left() + used_values.value()->margin_box_right()); auto const& fragments = paintable.fragments(); if (!fragments.is_empty()) { - if (!offset.has_value() || (fragments.first().offset().x() < offset.value().x())) + if (!offset.has_value() || (fragments.first().offset().x() < offset->x())) offset = fragments.first().offset(); - if (&paintable == paintable_with_lines->first_child()) { - auto const& used_values = get(paintable.layout_node_with_style_and_box_metrics()); - offset->translate_by(-used_values.margin_box_left(), 0); - } + if (&paintable == paintable_with_lines->first_child() && used_values.has_value()) + offset->translate_by(-used_values.value()->margin_box_left(), 0); } for (auto const& fragment : fragments) size.set_width(size.width() + fragment.width()); diff --git a/Tests/LibWeb/Crash/Layout/button-display-inline-with-nested-inlines.html b/Tests/LibWeb/Crash/Layout/button-display-inline-with-nested-inlines.html new file mode 100644 index 00000000000..a24141464e3 --- /dev/null +++ b/Tests/LibWeb/Crash/Layout/button-display-inline-with-nested-inlines.html @@ -0,0 +1,2 @@ + +