1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-10 06:47:34 +00:00

LibWeb: Fix infinite loop in GFC growth limit distribution

This change is bd85e1b30b ported from
base size to growth limit distribution.

Fixes https://github.com/SerenityOS/serenity/issues/21056
This commit is contained in:
Aliaksandr Kalenik 2023-09-14 17:15:11 +02:00 committed by Andreas Kling
parent 9b4ddff6a9
commit 693d602b2f
3 changed files with 45 additions and 11 deletions

View file

@ -935,7 +935,7 @@ void GridFormattingContext::distribute_extra_space_across_spanned_tracks_growth_
auto extra_space = max(CSSPixels(0), item_size_contribution - spanned_tracks_sizes_sum);
// 2. Distribute space up to limits:
while (true) {
while (extra_space > 0) {
auto all_frozen = all_of(affected_tracks, [](auto const& track) { return track.growth_limit_frozen; });
if (all_frozen)
break;
@ -943,23 +943,24 @@ void GridFormattingContext::distribute_extra_space_across_spanned_tracks_growth_
// Find the item-incurred increase for each spanned track with an affected size by: distributing the space
// equally among such tracks, freezing a tracks item-incurred increase as its affected size + item-incurred
// increase reaches its limit
CSSPixels increase_per_track = extra_space / affected_tracks.size();
if (increase_per_track == 0)
break;
CSSPixels increase_per_track = max(CSSPixels::smallest_positive_value(), extra_space / affected_tracks.size());
for (auto& track : affected_tracks) {
if (track.growth_limit_frozen)
continue;
auto increase = min(increase_per_track, extra_space);
// For growth limits, the limit is infinity if it is marked as infinitely growable, and equal to the
// growth limit otherwise.
if (track.infinitely_growable || !track.growth_limit.has_value()) {
track.item_incurred_increase += increase_per_track;
extra_space -= increase_per_track;
} else if (track.growth_limit.has_value() && increase_per_track >= track.growth_limit.value()) {
track.growth_limit_frozen = true;
track.item_incurred_increase = track.growth_limit.value();
extra_space -= track.growth_limit.value();
if (!track.infinitely_growable && track.growth_limit.has_value()) {
auto maximum_increase = track.growth_limit.value() - track.base_size;
if (track.item_incurred_increase + increase >= maximum_increase) {
track.growth_limit_frozen = true;
increase = maximum_increase - track.item_incurred_increase;
}
}
track.item_incurred_increase += increase;
extra_space -= increase;
}
}