Browse Source

LibWeb/SVG: Ensure SVG transform has an inverse before using it

This avoids a crash that occurred when calling `getBBox()` on an SVG
element that had a transform with no inverse.

Found by Domato.
Tim Ledbetter 11 months ago
parent
commit
d417b75683

+ 1 - 0
Tests/LibWeb/Text/expected/SVG/svg-getbbox-transform-with-no-inverse.txt

@@ -0,0 +1 @@
+    PASS (didn't crash)

+ 12 - 0
Tests/LibWeb/Text/input/SVG/svg-getbbox-transform-with-no-inverse.html

@@ -0,0 +1,12 @@
+<!DOCTYPE html>
+<script src="../include.js"></script>
+<svg xmlns="http://www.w3.org/2000/svg">
+    <rect id="rectElement" x="0" y="0" width="100" height="100" transform="scale(0)" />
+</svg>
+<script>
+    test(() => {
+        const rectElement = document.getElementById("rectElement");
+        rectElement.getBBox();
+        println("PASS (didn't crash)");
+    });
+</script>

+ 4 - 3
Userland/Libraries/LibWeb/SVG/SVGGraphicsElement.cpp

@@ -273,9 +273,10 @@ JS::NonnullGCPtr<Geometry::DOMRect> SVGGraphicsElement::get_b_box(Optional<SVGBo
     // Invert the SVG -> screen space transform.
     auto svg_element_rect = shadow_including_first_ancestor_of_type<SVG::SVGSVGElement>()->paintable_box()->absolute_rect();
     auto inverse_transform = static_cast<Painting::SVGGraphicsPaintable&>(*paintable_box()).computed_transforms().svg_to_css_pixels_transform().inverse();
-    return Geometry::DOMRect::create(realm(),
-        inverse_transform->map(
-            paintable_box()->absolute_rect().to_type<float>().translated(-svg_element_rect.location().to_type<float>())));
+    auto translated_rect = paintable_box()->absolute_rect().to_type<float>().translated(-svg_element_rect.location().to_type<float>());
+    if (inverse_transform.has_value())
+        translated_rect = inverse_transform->map(translated_rect);
+    return Geometry::DOMRect::create(realm(), translated_rect);
 }
 
 JS::NonnullGCPtr<SVGAnimatedTransformList> SVGGraphicsElement::transform() const