From 5f509a1c1f196bb716ff3977478d0b7396bcc51d Mon Sep 17 00:00:00 2001 From: Humphrey Date: Wed, 15 Jul 2026 22:21:12 -0500 Subject: [PATCH] fix(sanitizer): strip alt text from reference-style markdown images (#1488) stripMarkdownImageAltText removed alt text from inline images (![alt](url)) but not reference-style images (![alt][ref]), because the regex requires the "](" of the inline form. Alt text is a hidden-instruction channel that reaches the prompt via sanitizeContent, so the reference-style form let it survive. Add a matching replace for the reference-style form (![alt][ref] -> ![][ref]), preserving the [ref] label so the image definition still resolves. Adds regression tests. Co-authored-by: Contributor Co-authored-by: Claude Opus 4.8 (1M context) --- src/github/utils/sanitizer.ts | 8 +++++++- test/sanitizer.test.ts | 16 ++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/src/github/utils/sanitizer.ts b/src/github/utils/sanitizer.ts index 486456c6..47f60abb 100644 --- a/src/github/utils/sanitizer.ts +++ b/src/github/utils/sanitizer.ts @@ -10,7 +10,13 @@ export function stripInvisibleCharacters(content: string): string { } export function stripMarkdownImageAltText(content: string): string { - return content.replace(/!\[[^\]]*\]\(/g, "![]("); + // Inline images: ![alt](url) -> ![](url) + content = content.replace(/!\[[^\]]*\]\(/g, "![]("); + // Reference-style images: ![alt][ref] -> ![][ref] (keep the label, drop the + // alt text, which is otherwise a hidden-instruction channel just like the + // inline form above). + content = content.replace(/!\[[^\]]*\](\[[^\]]*\])/g, "![]$1"); + return content; } export function stripMarkdownLinkTitles(content: string): string { diff --git a/test/sanitizer.test.ts b/test/sanitizer.test.ts index da797d0f..2cb7e301 100644 --- a/test/sanitizer.test.ts +++ b/test/sanitizer.test.ts @@ -59,6 +59,22 @@ describe("stripMarkdownImageAltText", () => { it("should handle empty alt text", () => { expect(stripMarkdownImageAltText("![](image.png)")).toBe("![](image.png)"); }); + + it("should remove alt text from reference-style images", () => { + expect(stripMarkdownImageAltText("![example alt text][img1]")).toBe( + "![][img1]", + ); + expect( + stripMarkdownImageAltText("Text ![description][ref] more text"), + ).toBe("Text ![][ref] more text"); + }); + + it("should preserve the reference label of a reference-style image", () => { + // the [ref] label must survive so the image definition still resolves; + // only the alt text (the injection channel) is removed + expect(stripMarkdownImageAltText("![alt][my-ref]")).toBe("![][my-ref]"); + expect(stripMarkdownImageAltText("![][keep]")).toBe("![][keep]"); + }); }); describe("stripMarkdownLinkTitles", () => {