Selaa lähdekoodia

LibWeb: Check for invalid SVG viewBox sizes

Fixes #21825
MacDue 1 vuosi sitten
vanhempi
commit
f57b3423eb

+ 16 - 0
Tests/LibWeb/Layout/expected/svg/svg-with-zero-sized-viewBox.txt

@@ -0,0 +1,16 @@
+Viewport <#document> at (0,0) content-size 800x600 children: not-inline
+  BlockContainer <html> at (0,0) content-size 800x600 [BFC] children: not-inline
+    BlockContainer <body> at (8,8) content-size 784x100 children: inline
+      line 0 width: 100, height: 100, bottom: 100, baseline: 100
+        frag 0 from SVGSVGBox start: 0, length: 0, rect: [8,8 100x100]
+      SVGSVGBox <svg> at (8,8) content-size 100x100 [SVG] children: inline
+        TextNode <#text>
+        SVGTextBox <text> (not painted) children: inline
+          TextNode <#text>
+        TextNode <#text>
+      TextNode <#text>
+
+ViewportPaintable (Viewport<#document>) [0,0 800x600]
+  PaintableWithLines (BlockContainer<HTML>) [0,0 800x600]
+    PaintableWithLines (BlockContainer<BODY>) [8,8 784x100]
+      SVGSVGPaintable (SVGSVGBox<svg>) [8,8 100x100]

+ 3 - 0
Tests/LibWeb/Layout/input/svg/svg-with-zero-sized-viewBox.html

@@ -0,0 +1,3 @@
+<svg width="100" height="100" viewBox="0 0 0 0">
+  <text>Hello!</text>
+</svg>

+ 15 - 2
Userland/Libraries/LibWeb/Layout/SVGFormattingContext.cpp

@@ -188,11 +188,24 @@ void SVGFormattingContext::run(Box const& box, LayoutMode layout_mode, Available
     box.for_each_in_subtree([&](Node const& descendant) {
         if (is<SVGGraphicsBox>(descendant)) {
             auto const& graphics_box = static_cast<SVGGraphicsBox const&>(descendant);
-            auto& graphics_box_state = m_state.get_mutable(graphics_box);
             auto& dom_node = const_cast<SVGGraphicsBox&>(graphics_box).dom_node();
+            auto viewbox = dom_node.view_box();
+
+            // https://svgwg.org/svg2-draft/coords.html#ViewBoxAttribute
+            if (viewbox.has_value()) {
+                if (viewbox->width < 0 || viewbox->height < 0) {
+                    // A negative value for <width> or <height> is an error and invalidates the ‘viewBox’ attribute.
+                    viewbox = {};
+                } else if (viewbox->width == 0 || viewbox->height == 0) {
+                    // A value of zero disables rendering of the element.
+                    return IterationDecision::Continue;
+                }
+            }
 
+            auto& graphics_box_state = m_state.get_mutable(graphics_box);
             auto svg_transform = dom_node.get_transform();
-            Gfx::AffineTransform viewbox_transform = compute_viewbox_transform(dom_node.view_box());
+
+            Gfx::AffineTransform viewbox_transform = compute_viewbox_transform(viewbox);
             graphics_box_state.set_computed_svg_transforms(Painting::SVGGraphicsPaintable::ComputedTransforms(viewbox_transform, svg_transform));
             auto to_css_pixels_transform = Gfx::AffineTransform {}.multiply(viewbox_transform).multiply(svg_transform);