← WebKit — 2026-W35
19a32ddd271368e7c6c774883950f1ac119b64f0 [LBSE] Collecting pattern attributes walks an xlink:href cycle forever
severity low
class LogicError
confidence 0.35
signal score 8.56
Source/WebCore/svg
Primitive: SVG pattern href chain had no cycle detection, allowing an unbounded href loop
Triage note: Rewrites gradient/pattern attribute collection and gives SVGPatternElement::collectPatternAttributes a processedPatterns HashSet with cycle detection (gradients already had it). Adds a missing cycle guard for attacker-controlled SVG pattern href chains (potential hang), but it is embedded in a large SaferCPP refactor and is not memory-safety.
Triage note: Rewrites gradient/pattern attribute collection and gives SVGPatternElement::collectPatternAttributes a processedPatterns HashSet with cycle detection (gradients already had it). Adds a missing cycle guard for attacker-controlled SVG pattern href chains (potential hang), but it is embedded in a large SaferCPP refactor and is not memory-safety.
Structural signals: smartptr_member_added (+6.47), null_guard (+2.59), msg_noise (-2.5), area:Source/WebCore/svg (+2.0)
Commit message
[LBSE] Collecting pattern attributes walks an xlink:href cycle forever
https://bugs.webkit.org/show_bug.cgi?id=321882
Reviewed by Rob Buis.
RenderSVGResourcePattern::collectPatternAttributesIfNeeded() followed the
xlink:href chain without remembering where it had been, so two patterns pointing
at each other, or one pointing at itself, hang the WebContent process on the
first paint.
Gradients never had that problem, their walk and its cycle detection live in
SVGLinearGradientElement::collectGradientAttributes(). Switch patterns to the
same kind of logic: move the walk into SVGPatternElement::collectPatternAttributes(),
which now returns whether the pattern can be rendered. The legacy renderer keeps its
SVGResourcesCache walk and only follows the rename.
Two further differences turned out to be accidental and now follow the gradient
rule: patterns kept the attributes collected so far when the chain reached an
element without a renderer aand they resolved each href in the tree scope of the
element holding it, not the one the walk started from which is incorrect.
Finally, unify both code paths as much as possible, so gradient/pattern attribute
collection has the very same shape - less confusing this way.
Update expectations, and add new fast/shadow-dom tests to cover the tree scope
change.
* LayoutTests/TestExpectations:
* LayoutTests/fast/shadow-dom/svg-multiple-references-in-multiple-shadows-pattern-expected.html: Added.
* LayoutTests/fast/shadow-dom/svg-multiple-references-in-multiple-shadows-pattern.html: Added.
* LayoutTests/fast/shadow-dom/svg-pattern-dynamic-update-href-in-shadow-tree-expected.html: Added.
* LayoutTests/fast/shadow-dom/svg-pattern-dynamic-update-href-in-shadow-tree.html: Added.
* LayoutTests/fast/shadow-dom/svg-pattern-href-in-shadow-tree-expected.html: Added.
* LayoutTests/fast/shadow-dom/svg-pattern-href-in-shadow-tree.html: Added.
* LayoutTests/platform/mac-tahoe-wk2-lbse-text/TestExpectations:
* LayoutTests/svg/custom/pattern-href-cycle-detection-expected.svg: Added.
* LayoutTests/svg/custom/pattern-href-cycle-detection.svg: Added.
* Source/WebCore/SaferCPPExpectations/UncountedCallArgsCheckerExpectations:
* Source/WebCore/rendering/svg/RenderSVGResourcePattern.cpp:
(WebCore::RenderSVGResourcePattern::collectPatternAttributesIfNeeded):
* Source/WebCore/rendering/svg/legacy/LegacyRenderSVGResourcePattern.cpp:
(WebCore::LegacyRenderSVGResourcePattern::collectPatternAttributes const):
* Source/WebCore/svg/SVGLinearGradientElement.cpp:
(WebCore::setGradientAttributes):
(WebCore::SVGLinearGradientElement::collectGradientAttributes):
* Source/WebCore/svg/SVGPatternElement.cpp:
(WebCore::SVGPatternElement::collectPatternAttributes):
(WebCore::SVGPatternElement::collectOwnPatternAttributes const):
(WebCore::SVGPatternElement::collectPatternAttributes const): Deleted.
* Source/WebCore/svg/SVGPatternElement.h:
* Source/WebCore/svg/SVGRadialGradientElement.cpp:
(WebCore::setGradientAttributes):
(WebCore::SVGRadialGradientElement::collectGradientAttributes):
Canonical link: https://commits.webkit.org/319850@main
Before / after
Loading diff…
On This Page