{"record":{"id":"aee9595fac752222","repo":"siyuan-note/siyuan","slug":"parse-svg-failed-w","errorCode":null,"errorMessage":"parse svg failed: %w","messagePattern":"parse svg failed: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"kernel/util/misc.go","lineNumber":358,"sourceCode":"\tdecoder := xml.NewDecoder(strings.NewReader(svgInput))\n\tdecoder.Strict = true\n\n\tvar buf bytes.Buffer\n\tencoder := xml.NewEncoder(&buf)\n\trootSeen := false\n\trootClosed := false\n\tdepth := 0\n\tskipDepth := 0\n\ttokenCount := 0\n\tvar elementStack []xml.Name\n\n\tfor {\n\t\ttoken, err := decoder.RawToken()\n\t\tif err == io.EOF {\n\t\t\tbreak\n\t\t}\n\t\tif err != nil {\n\t\t\treturn \"\", fmt.Errorf(\"parse svg failed: %w\", err)\n\t\t}\n\t\ttokenCount++\n\t\tif tokenCount > maxSVGTokens {\n\t\t\treturn \"\", fmt.Errorf(\"svg contains too many tokens\")\n\t\t}\n\n\t\tswitch typed := token.(type) {\n\t\tcase xml.StartElement:\n\t\t\telementStack = append(elementStack, typed.Name)\n\t\t\tdepth++\n\t\t\tif depth > maxSVGDepth {\n\t\t\t\treturn \"\", fmt.Errorf(\"svg nesting depth exceeds %d\", maxSVGDepth)\n\t\t\t}\n\t\t\tif rootClosed {\n\t\t\t\treturn \"\", fmt.Errorf(\"svg contains multiple root elements\")\n\t\t\t}\n\t\t\tif !rootSeen {\n\t\t\t\tif !strings.EqualFold(typed.Name.Local, \"svg\") {","sourceCodeStart":340,"sourceCodeEnd":376,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/251596fc0de2f9528c00c224252fd073a99973f4/kernel/util/misc.go#L340-L376","documentation":"SanitizeSVG runs an XML decoder in Strict mode and streams tokens via RawToken. Any XML well-formedness error (invalid syntax, undeclared entity, bad encoding, mismatched tag) is wrapped with %w and returned. SVGs that are valid HTML but not valid XML (unquoted attributes, HTML entities like &nbsp;, unclosed tags) will trip this.","triggerScenarios":"Inserting/previewing an SVG asset that is not well-formed XML: unquoted attributes, HTML entities (&nbsp; &copy;), missing closing tags, BOM or <?xml encoding mismatch, namespace prefixes without declaration, stray < or & in text.","commonSituations":"SVG exported from design tools with HTML quirks; SVGs copied from web pages with HTML entities; hand-authored SVG with typos; SVG whose encoding declaration disagrees with the file bytes.","solutions":["Open the SVG in a strict XML validator and fix well-formedness errors (quote all attributes, escape &, close all tags).","Replace HTML entities (&nbsp;) with numeric XML entities (&#160;) or literal characters.","Re-save from an editor that emits well-formed XML (e.g. Inkscape 'Optimized SVG').","Ensure UTF-8 bytes match the <?xml encoding=\"utf-8\"?> declaration, or omit the declaration."],"exampleFix":"<!-- before -->\n<svg><rect width=100 height=50 fill=\"red\">&copy;</svg>\n\n<!-- after -->\n<svg xmlns=\"http://www.w3.org/2000/svg\"><rect width=\"100\" height=\"50\" fill=\"red\"/>&#169;</svg>","handlingStrategy":"try-catch","validationCode":"dec := xml.NewDecoder(strings.NewReader(svg))\ndec.Strict = true\nif _, err := dec.Token(); err != nil {\n    return errors.New(\"svg is not well-formed XML: \" + err.Error())\n}","typeGuard":null,"tryCatchPattern":"clean, err := util.SanitizeSVG(raw)\nif err != nil {\n    logging.LogWarnf(\"skip non-well-formed SVG: %s\", err)\n    return fallback // raw <img src> or placeholder\n}","preventionTips":["Treat SVG as XML, not HTML","Quote every attribute and self-close every element","Avoid HTML entities; use numeric character references","Validate SVGs in a strict XML parser before importing"],"tags":["svg","xml","sanitization","assets","go"],"backgroundTag":null,"analyzedSha":"251596fc0de2f9528c00c224252fd073a99973f4","analyzedAt":"2026-08-12T21:18:37.123Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}