Selaa lähdekoodia

LibWeb: Don't crash when converting small CSS::Ratio to CSSPixelFraction

Previously, a crash would occur in the if `CSSPixelFraction` was given a
denominator value less than the resolution of `CSSPixels` (1/64).

We now divide both parts of the ratio by the denominator in this case.
Tim Ledbetter 11 kuukautta sitten
vanhempi
commit
2c5d626b21

+ 1 - 0
Tests/LibWeb/Text/expected/css/small-aspect-ratio.txt

@@ -0,0 +1 @@
+element height: 10px

+ 11 - 0
Tests/LibWeb/Text/input/css/small-aspect-ratio.html

@@ -0,0 +1,11 @@
+<script src="../include.js"></script>
+<script>
+    test(() => {
+        const element = document.createElement("div");
+        element.style.width = "100px";
+        element.style.aspectRatio = ".0000000000001 / .00000000000001";
+        document.body.appendChild(element);
+        println(`element height: ${element.clientHeight}px`);
+        element.remove();
+    });
+</script>

+ 1 - 1
Userland/Libraries/LibWeb/Layout/Box.cpp

@@ -93,7 +93,7 @@ Optional<CSSPixelFraction> Box::preferred_aspect_ratio() const
     if (ratio.is_degenerate())
         return {};
 
-    return CSSPixelFraction(CSSPixels(ratio.numerator()), CSSPixels(ratio.denominator()));
+    return CSSPixelFraction(ratio.numerator(), ratio.denominator());
 }
 
 }

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

@@ -320,6 +320,20 @@ public:
         VERIFY(denominator != 0);
     }
 
+    template<FloatingPoint F>
+    constexpr CSSPixelFraction(F numerator, F denominator = 1)
+    {
+        if (CSSPixels::nearest_value_for(denominator) == 0) {
+            numerator = numerator / denominator;
+            denominator = 1;
+        }
+
+        m_numerator = CSSPixels(numerator);
+        m_denominator = CSSPixels(denominator);
+
+        VERIFY(denominator != 0);
+    }
+
     constexpr operator CSSPixels() const
     {
         i64 wide_value = m_numerator.raw_value();