From 58df9c45b9b6dfdb5cead01bb7630ee578ee80ce Mon Sep 17 00:00:00 2001 From: Tim Ledbetter Date: Sat, 20 Jan 2024 22:57:45 +0000 Subject: [PATCH] LibWeb: Avoid division by zero when computing table width Previously, a crash could occur when computing the width of a table with cells that had a percentage width of 0. --- .../zero_percent_width_nested_table.txt | 28 +++++++++++++++++++ .../zero_percent_width_nested_table.html | 1 + .../LibWeb/Layout/TableFormattingContext.cpp | 6 ++-- 3 files changed, 33 insertions(+), 2 deletions(-) create mode 100644 Tests/LibWeb/Layout/expected/zero_percent_width_nested_table.txt create mode 100644 Tests/LibWeb/Layout/input/zero_percent_width_nested_table.html diff --git a/Tests/LibWeb/Layout/expected/zero_percent_width_nested_table.txt b/Tests/LibWeb/Layout/expected/zero_percent_width_nested_table.txt new file mode 100644 index 0000000000..eee9d9d237 --- /dev/null +++ b/Tests/LibWeb/Layout/expected/zero_percent_width_nested_table.txt @@ -0,0 +1,28 @@ +Viewport <#document> at (0,0) content-size 800x600 children: not-inline + BlockContainer at (0,0) content-size 800x28 [BFC] children: not-inline + BlockContainer at (8,8) content-size 784x12 children: not-inline + TableWrapper <(anonymous)> at (8,8) content-size 12x12 [BFC] children: not-inline + Box at (8,8) content-size 12x12 table-box [TFC] children: not-inline + Box at (8,8) content-size 8x8 table-row-group children: not-inline + Box at (10,10) content-size 8x8 table-row children: not-inline + BlockContainer
at (11,11) content-size 6x6 table-cell [BFC] children: not-inline + TableWrapper <(anonymous)> at (11,11) content-size 6x6 [BFC] children: not-inline + Box at (11,11) content-size 6x6 table-box [TFC] children: not-inline + Box at (11,11) content-size 2x2 table-row-group children: not-inline + Box at (13,13) content-size 2x2 table-row children: not-inline + BlockContainer
at (14,14) content-size 0x0 table-cell [BFC] children: inline + TextNode <#text> + +ViewportPaintable (Viewport<#document>) [0,0 800x600] + PaintableWithLines (BlockContainer) [0,0 800x28] + PaintableWithLines (BlockContainer) [8,8 784x12] + PaintableWithLines (TableWrapper(anonymous)) [8,8 12x12] + PaintableBox (Box) [8,8 12x12] + PaintableBox (Box) [8,8 8x8] overflow: [8,8 10x10] + PaintableBox (Box) [10,10 8x8] + PaintableWithLines (BlockContainer
) [10,10 8x8] + PaintableWithLines (TableWrapper(anonymous)) [11,11 6x6] + PaintableBox (Box) [11,11 6x6] + PaintableBox (Box) [11,11 2x2] overflow: [11,11 4x4] + PaintableBox (Box) [13,13 2x2] + PaintableWithLines (BlockContainer
) [13,13 2x2] diff --git a/Tests/LibWeb/Layout/input/zero_percent_width_nested_table.html b/Tests/LibWeb/Layout/input/zero_percent_width_nested_table.html new file mode 100644 index 0000000000..9a80945eca --- /dev/null +++ b/Tests/LibWeb/Layout/input/zero_percent_width_nested_table.html @@ -0,0 +1 @@ +
diff --git a/Userland/Libraries/LibWeb/Layout/TableFormattingContext.cpp b/Userland/Libraries/LibWeb/Layout/TableFormattingContext.cpp index 8c6452a142..1fb51ac649 100644 --- a/Userland/Libraries/LibWeb/Layout/TableFormattingContext.cpp +++ b/Userland/Libraries/LibWeb/Layout/TableFormattingContext.cpp @@ -492,11 +492,13 @@ void TableFormattingContext::compute_table_width() // https://www.w3.org/TR/CSS22/tables.html#auto-table-layout // A percentage value for a column width is relative to the table width. If the table has 'width: auto', // a percentage represents a constraint on the column's width, which a UA should try to satisfy. - CSSPixels adjusted_used_width = 0; for (auto& cell : m_cells) { auto const& cell_width = cell.box->computed_values().width(); if (cell_width.is_percentage()) { - adjusted_used_width = CSSPixels::nearest_value_for(ceil(100 / cell_width.percentage().value() * cell.outer_max_width.to_double())) + undistributable_space; + CSSPixels adjusted_used_width = undistributable_space; + if (cell_width.percentage().value() != 0) + adjusted_used_width += CSSPixels::nearest_value_for(ceil(100 / cell_width.percentage().value() * cell.outer_max_width)); + if (width_of_table_containing_block.is_definite()) used_width = min(max(used_width, adjusted_used_width), width_of_table_containing_block.to_px_or_zero()); else