LibWeb: Don't infer SVG viewBox if width and/or height is zero

The fix here has two parts:
1. Don't use the fallback viewBox at all if we're not in SVG-as-image.
2. Don't make a fallback viewBox with zero width and/or height.

This fixes a crash on Bandcamp pages. Thanks Tim Flynn for reporting!
This commit is contained in:
Andreas Kling 2023-06-20 19:55:53 +02:00
parent ffd5b3da16
commit 0ec522ab54
Notes: sideshowbarker 2024-07-17 01:46:43 +09:00
4 changed files with 31 additions and 2 deletions

View file

@ -0,0 +1,21 @@
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 784x17.46875 children: inline
line 0 width: 8, height: 17.46875, bottom: 17.46875, baseline: 13.53125
frag 0 from ImageBox start: 0, length: 0, rect: [8,21 0x0]
frag 1 from TextNode start: 0, length: 1, rect: [8,8 8x17.46875]
" "
frag 2 from SVGSVGBox start: 0, length: 0, rect: [16,21 0x0]
ImageBox <img> at (8,21) content-size 0x0 children: not-inline
(SVG-as-image isolated context)
Viewport <#document> at (0,0) content-size 0x0 children: inline
SVGSVGBox <svg> at (0,0) content-size 0x0 [SVG] children: inline
TextNode <#text>
SVGGeometryBox <rect> at (0,0) content-size 1x1 children: not-inline
TextNode <#text>
TextNode <#text>
SVGSVGBox <svg> at (16,21) content-size 0x0 [SVG] children: inline
TextNode <#text>
SVGGeometryBox <rect> at (16,21) content-size 1x1 children: not-inline
TextNode <#text>
TextNode <#text>

View file

@ -0,0 +1,4 @@
<img src="svg-with-zero-intrinsic-size-and-no-viewbox.svg">
<svg width=0 height=0>
<rect x=0 y=0 width=1 height=1 />
</svg>

View file

@ -0,0 +1,3 @@
<svg width=0 height=0>
<rect x=0 y=0 width=1 height=1 />
</svg>

After

Width:  |  Height:  |  Size: 68 B

View file

@ -104,7 +104,7 @@ void SVGSVGElement::update_fallback_view_box_for_svg_as_image()
height = height_value->as_length().length().absolute_length_to_px().to_double();
}
if (width.has_value() && height.has_value()) {
if (width.has_value() && width.value() > 0 && height.has_value() && height.value() > 0) {
m_fallback_view_box_for_svg_as_image = ViewBox { 0, 0, width.value(), height.value() };
} else {
m_fallback_view_box_for_svg_as_image = {};
@ -121,7 +121,8 @@ Optional<ViewBox> SVGSVGElement::view_box() const
if (m_view_box.has_value())
return m_view_box;
if (m_fallback_view_box_for_svg_as_image.has_value())
// NOTE: If the parent is a document, we're an <svg> element used as an image.
if (parent() && parent()->is_document() && m_fallback_view_box_for_svg_as_image.has_value())
return m_fallback_view_box_for_svg_as_image;
return {};