Selaa lähdekoodia

LibWeb: Avoid division by zero when computing table measures

For malformed tables which only have cells with span greater than 1, the
content sizes for row and column aren't initialized to non-zero values.
Avoid undefined behavior in such cases, which sometimes show up on
Wikipedia.
Andi Gallo 1 vuosi sitten
vanhempi
commit
3b75b9ef1c

+ 24 - 0
Tests/LibWeb/Layout/expected/table/avoid-div-by-zero-in-table-measures.txt

@@ -0,0 +1,24 @@
+Viewport <#document> at (0,0) content-size 800x600 children: not-inline
+  BlockContainer <html> at (0,0) content-size 800x600 [BFC] children: not-inline
+    BlockContainer <body> at (8,8) content-size 784x23.46875 children: not-inline
+      TableWrapper <(anonymous)> at (8,8) content-size 6x23.46875 [BFC] children: not-inline
+        Box <table> at (8,8) content-size 6x23.46875 table-box [TFC] children: not-inline
+          BlockContainer <(anonymous)> (not painted) children: inline
+            TextNode <#text>
+          Box <tbody> at (8,8) content-size 0x19.46875 table-row-group children: not-inline
+            BlockContainer <(anonymous)> (not painted) children: inline
+              TextNode <#text>
+            Box <tr> at (10,10) content-size 0x19.46875 table-row children: not-inline
+              BlockContainer <(anonymous)> (not painted) children: inline
+                TextNode <#text>
+              BlockContainer <td> at (11,11) content-size 0x17.46875 table-cell [BFC] children: inline
+                line 0 width: 14.265625, height: 17.46875, bottom: 17.46875, baseline: 13.53125
+                  frag 0 from TextNode start: 0, length: 1, rect: [11,11 14.265625x17.46875]
+                    "A"
+                TextNode <#text>
+              BlockContainer <(anonymous)> (not painted) children: inline
+                TextNode <#text>
+            BlockContainer <(anonymous)> (not painted) children: inline
+              TextNode <#text>
+          BlockContainer <(anonymous)> (not painted) children: inline
+            TextNode <#text>

+ 7 - 0
Tests/LibWeb/Layout/input/table/avoid-div-by-zero-in-table-measures.html

@@ -0,0 +1,7 @@
+<table>
+	<tbody>
+		<tr>
+			<td colspan="2">A</td>
+		</tr>
+	</tbody>
+</table>

+ 8 - 4
Userland/Libraries/LibWeb/Layout/TableFormattingContext.cpp

@@ -495,8 +495,10 @@ void TableFormattingContext::compute_table_measures()
                     // the product of:
                     // - the ratio of the max-content size based on cells of span up to N-1 of the column to the baseline max-content size
                     // - the outer min-content size of the cell minus the baseline max-content size and baseline border spacing, or 0 if this is negative
-                    cell_min_contribution += (rows_or_columns[rc_index].max_size / static_cast<double>(baseline_max_content_size))
-                        * max(CSSPixels(0), cell_min_size<RowOrColumn>(cell) - baseline_max_content_size - baseline_border_spacing);
+                    if (baseline_max_content_size != 0) {
+                        cell_min_contribution += (rows_or_columns[rc_index].max_size / static_cast<double>(baseline_max_content_size))
+                            * max(CSSPixels(0), cell_min_size<RowOrColumn>(cell) - baseline_max_content_size - baseline_border_spacing);
+                    }
 
                     // The contribution of the cell is the sum of:
                     // the max-content size of the column based on cells of span up to N-1
@@ -504,8 +506,10 @@ void TableFormattingContext::compute_table_measures()
                     // and the product of:
                     // - the ratio of the max-content size based on cells of span up to N-1 of the column to the baseline max-content size
                     // - the outer max-content size of the cell minus the baseline max-content size and the baseline border spacing, or 0 if this is negative
-                    cell_max_contribution += (rows_or_columns[rc_index].max_size / static_cast<double>(baseline_max_content_size))
-                        * max(CSSPixels(0), cell_max_size<RowOrColumn>(cell) - baseline_max_content_size - baseline_border_spacing);
+                    if (baseline_max_content_size != 0) {
+                        cell_max_contribution += (rows_or_columns[rc_index].max_size / static_cast<double>(baseline_max_content_size))
+                            * max(CSSPixels(0), cell_max_size<RowOrColumn>(cell) - baseline_max_content_size - baseline_border_spacing);
+                    }
                     cell_min_contributions_by_rc_index[rc_index].append(cell_min_contribution);
                     cell_max_contributions_by_rc_index[rc_index].append(cell_max_contribution);
                 }