From 393cfdd66016c5b0ddb7ac6cda397dedede6fa9b Mon Sep 17 00:00:00 2001 From: Diego Rodrigues de Sa e Souza Date: Thu, 10 Sep 2026 13:27:02 -0300 Subject: [PATCH] fix(test): make the ToS heading guard actually require the parentheses (#13228) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit CodeQL js/useless-regexp-character-escape (#994-#997) on one line, and it is a real defect rather than the usual query noise. The assertion built its pattern in a TEMPLATE literal: new RegExp(`\(\s*${String(tos?.actual)}\s*\)`) JavaScript resolves the escapes before RegExp ever sees the string: `\(` becomes "(" and `\s` becomes the LETTER "s". The compiled pattern was `(s*16s*)` — a capture group around optional "s" characters — so it matched any heading merely CONTAINING the number. The literal parentheses this guard exists to require were never checked, and it passed on exactly the headings it was written to reject: /(s*16s*)/.test("### Caution — clauses worth checking 16") // true Doubled the backslashes so they survive the template literal, and routed the interpolated value through an `escapeRegExp` helper — the count is a number today, but interpolating an unescaped value into a regex source is the same class of bug one refactor away. Added a second test that pins the behaviour rather than the spelling: the pattern must REJECT a heading carrying the count without parentheses, and accept it with them (including inner whitespace). Before this fix that test fails. 4/4 green against the real docs/reference/FREE_TIERS.md heading. --- .../check-docs-counts-tos-heading.test.ts | 24 ++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/tests/unit/check-docs-counts-tos-heading.test.ts b/tests/unit/check-docs-counts-tos-heading.test.ts index bc01288d3d..a7ea382b5c 100644 --- a/tests/unit/check-docs-counts-tos-heading.test.ts +++ b/tests/unit/check-docs-counts-tos-heading.test.ts @@ -13,6 +13,11 @@ type Check = { validate?: (content: string, claim?: string) => { ok: boolean; detail: string }; }; +/** Escape a value that is interpolated into a RegExp source. */ +function escapeRegExp(value: string): string { + return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); +} + describe("ToS caution heading count", () => { it("the Caution heading carries the count the gate checks", () => { const txt = readFileSync(join(process.cwd(), "docs/reference/FREE_TIERS.md"), "utf8"); @@ -21,7 +26,24 @@ describe("ToS caution heading count", () => { const tos = (buildChecks() as Check[]).find((c) => String(c.docKey ?? "").includes("ToS caution") ); - assert.match(heading, new RegExp(`\(\s*${String(tos?.actual)}\s*\)`)); + // The backslashes must survive the TEMPLATE LITERAL to reach the regex. + // Written as `\(\s*…` they did not: JS resolves `\(` to "(" and `\s` to the + // LETTER "s" before RegExp ever sees them, so the pattern compiled to + // `(s*16s*)` — a capture group around optional "s" characters. That matched + // any heading merely containing the number, with no literal parentheses + // required at all, so this guard passed on headings it was written to reject + // (CodeQL js/useless-regexp-character-escape #994-#997). + const count = escapeRegExp(String(tos?.actual)); + assert.match(heading, new RegExp(`\\(\\s*${count}\\s*\\)`)); + }); + + it("the heading guard actually requires the parentheses", () => { + // Pins the defect above: the pattern this test builds must REJECT a heading + // that carries the count without parentheses. Before the fix it accepted it. + const pattern = new RegExp(`\\(\\s*${escapeRegExp("16")}\\s*\\)`); + assert.equal(pattern.test("### Caution — clauses worth checking 16"), false); + assert.equal(pattern.test("### Caution — clauses worth checking (16)"), true); + assert.equal(pattern.test("### Caution — clauses worth checking ( 16 )"), true); }); it("buildChecks exposes a soft ToS entry on FREE_TIERS.md with requireClaim", () => { const checks = buildChecks() as Check[];