Avoid crash with large table column widths (#33424)

Fixes #33423

Signed-off-by: Oriol Brufau <obrufau@igalia.com>
This commit is contained in:
Oriol Brufau 2024-09-12 17:11:22 +02:00 committed by GitHub
parent b048bf80a4
commit 52e495c1a6
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 15 additions and 14 deletions

View file

@ -882,33 +882,36 @@ impl<'a> TableLayout<'a> {
(self.assignable_width - sum_b).to_f32_px() / (sum_a - sum_b).to_f32_px(); (self.assignable_width - sum_b).to_f32_px() / (sum_a - sum_b).to_f32_px();
let weight_b = 1.0 - weight_a; let weight_b = 1.0 - weight_a;
let mut sum_accounting_for_floating_point_inaccuracy = Au::new(0); let mut remaining_assignable_width = self.assignable_width;
let mut widths: Vec<Au> = a let mut widths: Vec<Au> = a
.iter() .iter()
.zip(b.iter()) .zip(b.iter())
.map(|(guess_a, guess_b)| { .map(|(guess_a, guess_b)| {
(guess_a.scale_by(weight_a)) + (guess_b.scale_by(weight_b)) let column_width = guess_a.scale_by(weight_a) + guess_b.scale_by(weight_b);
}) // Clamp to avoid exceeding the assignable width. This could otherwise
.inspect(|&column_width| { // happen when dealing with huge values whose sum is clamped to MAX_AU.
sum_accounting_for_floating_point_inaccuracy += column_width; let column_width = column_width.min(remaining_assignable_width);
remaining_assignable_width -= column_width;
column_width
}) })
.collect(); .collect();
if sum_accounting_for_floating_point_inaccuracy != self.assignable_width { if !remaining_assignable_width.is_zero() {
// The computations above can introduce floating-point imprecisions. // The computations above can introduce floating-point imprecisions.
// Since these errors are very small (+-1Au), it's fine to simply adjust // Since these errors are very small (1Au), it's fine to simply adjust
// the first column such that the total width matches the assignable width // the first column such that the total width matches the assignable width
let difference =
self.assignable_width - sum_accounting_for_floating_point_inaccuracy;
debug_assert!( debug_assert!(
difference.abs() <= Au::new(widths.len() as i32), remaining_assignable_width >= Au::zero(),
"Sum of columns shouldn't exceed the assignable table width"
);
debug_assert!(
remaining_assignable_width <= Au::new(widths.len() as i32),
"A deviation of more than one Au per column is unlikely to be caused by float imprecision" "A deviation of more than one Au per column is unlikely to be caused by float imprecision"
); );
// We checked if the table was empty at the top of the function, so there // We checked if the table was empty at the top of the function, so there
// always is a first column // always is a first column
widths[0] += difference; widths[0] += remaining_assignable_width;
} }
debug_assert!(widths.iter().sum::<Au>() == self.assignable_width); debug_assert!(widths.iter().sum::<Au>() == self.assignable_width);

View file

@ -1,2 +0,0 @@
[large-col-widths.html]
expected: CRASH