fix(link-understanding): strip markdown links whose label contains brackets

stripMarkdownLinks used /\[[^\]]*]\(.../ for the link text, which cannot
match a label containing ']' (e.g. "[my notes [v2]](https://...)"). Such
markdown links survived stripping and their URL was then extracted by
BARE_LINK_RE as a bare link — including a stray trailing ')'. This turned a
display-only citation into a fetched link.

Allow ']' in the label as long as it is not the closing '](' boundary so the
markdown link is stripped and its URL is suppressed.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
ly-wang19
2026-06-24 20:42:31 +08:00
parent ae9474b5fd
commit cf0920d7ab
2 changed files with 13 additions and 1 deletions
+9
View File
@@ -20,6 +20,15 @@ describe("extractLinksFromMessage", () => {
expect(links).toEqual(["https://bare.example"]);
});
it("ignores markdown links whose label contains brackets", () => {
// The closing "]" inside the label must not break markdown stripping, otherwise
// the citation URL leaks out as a bare link (with a stray trailing ")").
const links = extractLinksFromMessage(
"Check [my notes [v2]](https://internal.example/doc) for details",
);
expect(links).toStrictEqual([]);
});
it("blocks 127.0.0.1", () => {
const links = extractLinksFromMessage("http://127.0.0.1/test https://ok.test");
expect(links).toEqual(["https://ok.test"]);
+4 -1
View File
@@ -3,7 +3,10 @@ import { isBlockedHostnameOrIp } from "../infra/net/ssrf.js";
import { DEFAULT_MAX_LINKS } from "./defaults.js";
// Remove markdown link syntax so only bare URLs are considered.
const MARKDOWN_LINK_RE = /\[[^\]]*]\((https?:\/\/\S+?)\)/gi;
// The link-text portion allows "]" that is not the closing "](" boundary so
// markdown links whose label contains brackets (e.g. "[my notes [v2]](...)")
// are still stripped instead of leaking their URL to BARE_LINK_RE.
const MARKDOWN_LINK_RE = /\[(?:[^\]]|](?!\())*]\((https?:\/\/\S+?)\)/gi;
const BARE_LINK_RE = /https?:\/\/\S+/gi;
function stripMarkdownLinks(message: string): string {