diff --git a/packages/app/src/components/markdown/html-ish.test.ts b/packages/app/src/components/markdown/html-ish.test.ts index ac6f2ad8b..c47a718fe 100644 --- a/packages/app/src/components/markdown/html-ish.test.ts +++ b/packages/app/src/components/markdown/html-ish.test.ts @@ -256,6 +256,12 @@ describe("splitHtmlishMarkdown", () => { expect(splitHtmlishMarkdown(source)).toEqual([{ kind: "markdown", text: source }]); }); + it("terminates when an unmatched backtick follows a closed inline code span", () => { + const source = "Use `
ExampleBody
` before `dangling"; + + expect(splitHtmlishMarkdown(source)).toEqual([{ kind: "markdown", text: source }]); + }); + it("still parses normal details outside code", () => { expect(splitHtmlishMarkdown("`code`\n
RealBody
")).toEqual([ { kind: "markdown", text: "`code`\n" }, diff --git a/packages/app/src/components/markdown/html-ish.ts b/packages/app/src/components/markdown/html-ish.ts index b68e734b5..7a92f0d20 100644 --- a/packages/app/src/components/markdown/html-ish.ts +++ b/packages/app/src/components/markdown/html-ish.ts @@ -651,8 +651,13 @@ function getInlineCodeRanges( } const marker = open[0]; - const close = findClosingBacktickRun(source, BACKTICK_RUN_RE.lastIndex, marker, fencedRanges); + const afterOpen = BACKTICK_RUN_RE.lastIndex; + const close = findClosingBacktickRun(source, afterOpen, marker, fencedRanges); if (!close) { + // Unmatched backtick run — skip past it so the loop doesn't restart from 0. + // findClosingBacktickRun exhausts the global regex, which resets lastIndex + // to 0 when exec() returns null (ECMAScript §22.2.7.2). + BACKTICK_RUN_RE.lastIndex = afterOpen; continue; }