From 313fe246f66ff453df3fe6a2ed8b433f04365ed1 Mon Sep 17 00:00:00 2001 From: jun Date: Thu, 3 Sep 2026 18:09:40 +0900 Subject: [PATCH] fix(ci): close the carry gate on an unclosed HTML comment The carry-attribution scanner stripped HTML comments with a pattern that required the closing delimiter. An unterminated `|$)` alternative for exactly this reason - so this is the two files agreeing rather than a new rule. CodeQL raised it as js/incomplete-multi-character-sanitization (high) on the v2.41.0 promotion. Its own framing does not apply: this output is fed to a regex, never to a renderer, so there is no HTML element injection here. The underlying observation is still correct for what the strip is actually for. Two regression tests, one per direction: carry language after an unclosed comment is ignored, and carry language after a properly closed one is still read - the guard must not swallow the body wholesale. Verification: node --test .github/scripts/*.test.cjs 543 pass 0 fail; bun test tests/ci-workflows.test.ts 135 pass 0 fail. --- .github/scripts/pr-carry-attribution.cjs | 18 +++++++++++- .github/scripts/pr-carry-attribution.test.cjs | 29 +++++++++++++++++++ 2 files changed, 46 insertions(+), 1 deletion(-) diff --git a/.github/scripts/pr-carry-attribution.cjs b/.github/scripts/pr-carry-attribution.cjs index 9e0ad1cabc..2886449102 100644 --- a/.github/scripts/pr-carry-attribution.cjs +++ b/.github/scripts/pr-carry-attribution.cjs @@ -56,7 +56,23 @@ const TRAILER_RE = /^[ \t]*co-authored-by:[ \t]*(.+)$/gim; const FENCED_CODE_RE = /^[ \t]*(\u0060{3,}|~{3,})[\s\S]*?^[ \t]*\1[ \t]*$/gm; const INLINE_CODE_RE = /\u0060[^\u0060\n]*\u0060/g; -const HTML_COMMENT_RE = //g; +/** + * HTML comments, which GitHub never renders. + * + * The `(?:-->|$)` alternative is load-bearing and matches `pr-quality.cjs`: an + * UNCLOSED comment runs to the end of the text, because that is what GitHub + * does with it. Without the alternative, `|$)/g; /** * Carry language inside a fenced block, an inline span, or an HTML comment is diff --git a/.github/scripts/pr-carry-attribution.test.cjs b/.github/scripts/pr-carry-attribution.test.cjs index 187469071e..08010a18d2 100644 --- a/.github/scripts/pr-carry-attribution.test.cjs +++ b/.github/scripts/pr-carry-attribution.test.cjs @@ -120,6 +120,35 @@ describe("assessCarryAttribution", () => { ); }); + it("ignores carry language after an unclosed HTML comment", () => { + // GitHub renders nothing after an unterminated ``, and a real claim after it + // is still a claim. + assert.equal( + assessCarryAttribution( + base({ + body: ["", "", "Supersedes #2797."].join("\n"), + }), + ).length, + 1, + ); + }); + it("passes an ordinary pull request with no carry language", () => { assert.deepEqual( assessCarryAttribution(base({ body: "Closes #2797." })),