Pārlūkot izejas kodu

LibWeb: Remove early continue in size parsing

Step 5 of parsing was always skipped because step 4 continues.

Running step 5 causes some of the denominators to be 0 and causes
divide by zero error in CSSPixelFraction.

SVG Image with height of 0 will cause divide by zero error when
calculating intrinsic aspect ratio of SVGDecoderImageData.

We also get a divide by zero error in AlignContent::SpaceBetween of the
FlexFormatingContext.

During auto track stretching in GridFormatingContext there is a
possibility for count_of_auto_max_sizing_tracks to stay 0.
Bastian Neumann 1 gadu atpakaļ
vecāks
revīzija
7cd489d6aa

+ 0 - 2
Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp

@@ -6688,8 +6688,6 @@ LengthOrCalculated Parser::Parser::parse_as_sizes_attribute()
         auto context_window = m_context.window();
         auto context_window = m_context.window();
         if (context_window && media_condition && media_condition->evaluate(*context_window) == MatchResult::True) {
         if (context_window && media_condition && media_condition->evaluate(*context_window) == MatchResult::True) {
             return size.value();
             return size.value();
-        } else {
-            continue;
         }
         }
 
 
         // 5. If size is not auto, then return size.
         // 5. If size is not auto, then return size.

+ 3 - 2
Userland/Libraries/LibWeb/Layout/FlexFormattingContext.cpp

@@ -1488,8 +1488,9 @@ void FlexFormattingContext::align_all_flex_lines()
             start_of_current_line = 0;
             start_of_current_line = 0;
 
 
             auto leftover_free_space = cross_size_of_flex_container - sum_of_flex_line_cross_sizes;
             auto leftover_free_space = cross_size_of_flex_container - sum_of_flex_line_cross_sizes;
-            if (leftover_free_space >= 0) {
-                int gap_count = m_flex_lines.size() - 1;
+            auto leftover_flex_lines_size = m_flex_lines.size();
+            if (leftover_free_space >= 0 && leftover_flex_lines_size > 1) {
+                int gap_count = leftover_flex_lines_size - 1;
                 gap_size = leftover_free_space / gap_count;
                 gap_size = leftover_free_space / gap_count;
             }
             }
             break;
             break;

+ 3 - 0
Userland/Libraries/LibWeb/Layout/GridFormattingContext.cpp

@@ -1339,6 +1339,9 @@ void GridFormattingContext::stretch_auto_tracks(GridDimension const dimension)
             count_of_auto_max_sizing_tracks++;
             count_of_auto_max_sizing_tracks++;
     }
     }
 
 
+    if (count_of_auto_max_sizing_tracks == 0)
+        return;
+
     CSSPixels remaining_space = get_free_space(*m_available_space, dimension).to_px_or_zero();
     CSSPixels remaining_space = get_free_space(*m_available_space, dimension).to_px_or_zero();
     auto remaining_space_to_distribute_per_track = remaining_space / count_of_auto_max_sizing_tracks;
     auto remaining_space_to_distribute_per_track = remaining_space / count_of_auto_max_sizing_tracks;
     for (auto& track : tracks_and_gaps) {
     for (auto& track : tracks_and_gaps) {

+ 4 - 4
Userland/Libraries/LibWeb/Layout/LayoutState.cpp

@@ -224,10 +224,10 @@ static Painting::BorderRadiiData normalized_border_radii_data(Layout::Node const
     auto s_bottom = (bottom_left_radius_px.horizontal_radius + bottom_right_radius_px.horizontal_radius);
     auto s_bottom = (bottom_left_radius_px.horizontal_radius + bottom_right_radius_px.horizontal_radius);
     auto s_left = (top_left_radius_px.vertical_radius + bottom_left_radius_px.vertical_radius);
     auto s_left = (top_left_radius_px.vertical_radius + bottom_left_radius_px.vertical_radius);
     CSSPixelFraction f = 1;
     CSSPixelFraction f = 1;
-    f = min(f, l_top / s_top);
-    f = min(f, l_right / s_right);
-    f = min(f, l_bottom / s_bottom);
-    f = min(f, l_left / s_left);
+    f = (s_top != 0) ? min(f, l_top / s_top) : f;
+    f = (s_right != 0) ? min(f, l_right / s_right) : f;
+    f = (s_bottom != 0) ? min(f, l_bottom / s_bottom) : f;
+    f = (s_left != 0) ? min(f, l_left / s_left) : f;
 
 
     // If f < 1, then all corner radii are reduced by multiplying them by f.
     // If f < 1, then all corner radii are reduced by multiplying them by f.
     if (f < 1) {
     if (f < 1) {

+ 2 - 0
Userland/Libraries/LibWeb/PixelUnits.h

@@ -294,6 +294,7 @@ public:
         : m_numerator(numerator)
         : m_numerator(numerator)
         , m_denominator(denominator)
         , m_denominator(denominator)
     {
     {
+        VERIFY(denominator != 0);
     }
     }
 
 
     explicit constexpr CSSPixelFraction(CSSPixels value)
     explicit constexpr CSSPixelFraction(CSSPixels value)
@@ -307,6 +308,7 @@ public:
         : m_numerator(numerator)
         : m_numerator(numerator)
         , m_denominator(denominator)
         , m_denominator(denominator)
     {
     {
+        VERIFY(denominator != 0);
     }
     }
 
 
     constexpr operator CSSPixels() const
     constexpr operator CSSPixels() const

+ 3 - 0
Userland/Libraries/LibWeb/SVG/SVGDecodedImageData.cpp

@@ -181,6 +181,9 @@ Optional<CSSPixelFraction> SVGDecodedImageData::intrinsic_aspect_ratio() const
     // https://www.w3.org/TR/SVG2/coords.html#SizingSVGInCSS
     // https://www.w3.org/TR/SVG2/coords.html#SizingSVGInCSS
     auto width = intrinsic_width();
     auto width = intrinsic_width();
     auto height = intrinsic_height();
     auto height = intrinsic_height();
+    if (height.has_value() && *height == 0)
+        return {};
+
     if (width.has_value() && height.has_value())
     if (width.has_value() && height.has_value())
         return *width / *height;
         return *width / *height;