From b3b2d5a02267d1b55c3e1d4faccd9f87bf182c5a Mon Sep 17 00:00:00 2001 From: Thomas Camlong Date: Fri, 7 Aug 2026 21:00:55 +0200 Subject: [PATCH] fix: SVG regex prefers terminator, add self-closing children test Use greedy ... match preferring closing tag over inner /> to prevent truncation at first self-closing child element. Self-closing root handled as separate alternative. Added test with + children asserting well-formed output. --- apps/nextjs/src/app/api/user-medias/sanitize.spec.ts | 10 ++++++++++ apps/nextjs/src/app/api/user-medias/svg-purify.ts | 2 +- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/apps/nextjs/src/app/api/user-medias/sanitize.spec.ts b/apps/nextjs/src/app/api/user-medias/sanitize.spec.ts index 17d5b40b1..d22df183e 100644 --- a/apps/nextjs/src/app/api/user-medias/sanitize.spec.ts +++ b/apps/nextjs/src/app/api/user-medias/sanitize.spec.ts @@ -66,4 +66,14 @@ describe("SVG sanitization", () => { const clean = sanitizeSvg(dirty); expect(clean).not.toContain("onbegin"); }); + + it("preserves well-formed SVG with self-closing children", () => { + const icon = ''; + const clean = sanitizeSvg(icon); + expect(clean).toContain(""); + expect(clean).not.toContain(" { // linkedom's DOMParser omits html/body for fragment-only SVG; DOMPurify needs a body root. const wrapped = `${svgText}`; const sanitized = purify.sanitize(wrapped, svgSanitizeOptions); - const svgMatch = sanitized.match(/|\/>)/i); + const svgMatch = sanitized.match(/]*\/>|/i); return svgMatch ? svgMatch[0] : ""; };