siyuan-note/siyuan · error

svg nesting depth exceeds %d

Error message

svg nesting depth exceeds %d

What it means

SanitizeSVG tracks element nesting depth and rejects input once depth exceeds maxSVGDepth (256, kernel/util/misc.go:321). Deep nesting is a classic parser-stack-exhaustion / DoS vector, so the sanitizer caps it. Legitimate SVG icons nest only a handful of levels; exceeding 256 indicates pathological or malicious input.

Source

Thrown at kernel/util/misc.go:370

	for {
		token, err := decoder.RawToken()
		if err == io.EOF {
			break
		}
		if err != nil {
			return "", fmt.Errorf("parse svg failed: %w", err)
		}
		tokenCount++
		if tokenCount > maxSVGTokens {
			return "", fmt.Errorf("svg contains too many tokens")
		}

		switch typed := token.(type) {
		case xml.StartElement:
			elementStack = append(elementStack, typed.Name)
			depth++
			if depth > maxSVGDepth {
				return "", fmt.Errorf("svg nesting depth exceeds %d", maxSVGDepth)
			}
			if rootClosed {
				return "", fmt.Errorf("svg contains multiple root elements")
			}
			if !rootSeen {
				if !strings.EqualFold(typed.Name.Local, "svg") {
					return "", fmt.Errorf("root element is not svg")
				}
				rootSeen = true
			}

			if skipDepth > 0 {
				skipDepth++
				continue
			}
			if _, unsafe := unsafeSVGElements[strings.ToLower(typed.Name.Local)]; unsafe {
				skipDepth = 1
				continue

View on GitHub (pinned to 8641553a1f)

Solutions

  1. Flatten the SVG structure (unwrap redundant <g> groups, run an SVG optimizer) before sanitizing
  2. Regenerate the asset from the original source instead of re-exporting repeatedly
  3. Treat the input as malicious if untrusted: reject it rather than raising the limit
  4. If a legitimate deep structure is required, raise maxSVGDepth deliberately with matching stack-safety review

Example fix

// before
svg := strings.Repeat("<g>", 1000) + content + strings.Repeat("</g>", 1000)
out, err := util.SanitizeSVG(svg) // fails at depth 257
// after
svg := flattenGroups(source) // unwrap nested <g> wrappers
out, err := util.SanitizeSVG(svg)
Defensive patterns

Strategy: validation

Validate before calling

if strings.Count(svg, "<g")+strings.Count(svg, "<svg") > 200 { return errors.New("svg nesting too deep") }

Try / catch

out, err := util.SanitizeSVG(svg)
if err != nil && strings.Contains(err.Error(), "nesting depth exceeds") {
    // reject or flatten the SVG before retrying
}

Prevention

When it happens

Trigger: Calling SanitizeSVG with an SVG whose elements nest more than 256 levels deep — recursively generated SVG, a crafted <g><g><g>... bomb, or deeply nested XML produced by repeated wrapping during transformations.

Common situations: Algorithmically generated SVGs (fractals, recursion demos), icons passed through multiple export/import cycles that each wrapped content in extra groups, or malicious uploads targeting XML parser recursion.

Understand the failure class

Background: payload too large / request exceeds maximum size: why libraries cap bytes and how to fix oversize payloads — this error's family across 50 libraries.

Related errors


AI-assisted analysis of siyuan-note/siyuan@8641553a1f (2026-09-11). Data as JSON: /api/errors/e8a954569abcd8f0. Report an issue: GitHub.