mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-09-13 18:32:12 +03:00
fix(test): make the ToS heading guard actually require the parentheses (#13228)
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.
This commit is contained in:
committed by
GitHub
parent
d86cf75aef
commit
393cfdd660
@@ -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[];
|
||||
|
||||
Reference in New Issue
Block a user