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", () => {