Page MenuHomePhabricator

librsvg has broken attribute handling for masks
Open, LowPublic


Compare the two versions of File:BSicon tvÜWBrq.svg. In Firefox and Safari they are identical, but librsvg does not render the older version correctly (PNG thumbnail of the older version; thumbnail of the current version).

As far as I can tell, this is because librsvg incorrectly applies styling from parent elements onto the elements inside a mask (due to the mask being used somewhere inside the parent element), even though the expected behaviour is that only the elements that are actually inside the parent element should be styled. I believe this may be related to a number of other SVG mask-related issues, including T55899 and T46016, and it has caused issues with several other BSicons (I have had to fix at least a dozen of these over the last few years, but I don't think I filed a bug report).

What appears to be happening in the older revision of the file is that the attributes stroke="#BE2D2C" stroke-width="100" fill="none" are being incorrectly applied to the constituent elements of mask 2. As a result, a faint red ring can be seen in the middle of the older thumbnail (the red parts are where the ring overlaps with the first <path/> element). In the current version, the latter two attributes are still being (incorrectly) applied, but because the stroke attribute is undefined the ring is not rendered.

In terms of the actual SVG code, the issue is caused by the nesting of <g mask="url(#2)">...</g> inside <g mask="url(#1)" stroke="#BE2D2C" stroke-width="100" fill="none">...</g>. The attributes inside the parent <g/> should only be applied to <path d="m 0,0 m 500,0 M 125,-25 V 0 c 0,250 250,250 250,500" stroke-dasharray="50,46.291"/>, and not to the children of <mask id="2">...</mask>. Copying stroke="#BE2D2C" to both <path/> elements and removing it from the parent <g/> element is enough to resolve the issue, but this is reliant on the stroke attribute not being set for the second circle in mask 2.

Event Timeline

Other examples of this problem (probably simpler examples, in fact, since there's only one mask in each image) are File:BSicon uetkKRZ3+lto.svg and File:BSicon evKRZ3+1o.svg. In the original revisions of both images, attributes on a <g/> element result in the opacity of a <path/> element being inadvertently reduced.

You might notice that the <g/> elements in both images appear to be redundant, since they each only have one child. This bug is the reason that the elements are necessary in the first place; the effect also occurs if e.g. the stroke-dasharray and mask attributes are used on the same <path/>. One of the earliest examples of this issue being a problem is an early version of File:BSicon tSTR2.svg (SVG; PNG thumbnail), uploaded on 23 March 2011 by Peterwhy. Archived discussions indicate that it took more than two years for BSicon authors to find a workaround to the librsvg bugs preventing masks from being used.

I don't think it is. Only one of the issues in the search has been updated in the past six months, and it seems to be completely unrelated.

I closed the upstream task as I cannot reproduce the issue locally with librsvg2 version 2.46.3.

This is due to Wikimedia having an older librsvg2 version (the one shipped by Debian) on its servers - see T193352 blocked by T216815 (though I'm not sure if the fix for this is already in 2.44.10 included in Debian Buster).

AntiCompositeNumber moved this task from Backlog to Upstream (librsvg) on the Thumbor board.

Confirmed fixed in rsvg-convert version 2.44.10.