`cmdVerifyKeyLinks` compiled `must_haves.key_links[].pattern` from plan frontmatter with `new RegExp()` and tested it against whole file contents, so a nested-quantifier pattern such as `(a+)+$` hung `verify-phase` indefinitely (CWE-1333). JavaScript has no regex-execution timeout.
Untrusted patterns now run on RE2 (re2js), whose match time is linear in input length — the class is closed by the engine, not by a heuristic screen. The screen lost in the ADR-0174 consolidation was deliberately NOT restored: it never worked, since `(a|a)*$`, `((a+))+$`, `(a+){2,}$` and `(a{1,3})+$` all evade it. A refused pattern's matcher returns false for every input, so it cannot report a match no matter what the caller does.
The engine is vendored at gsd-core/bin/lib/vendor/re2js.cjs because gsd-core/bin/** is copied into installed trees with no node_modules; runtime dependencies are unchanged. New ESLint rule local/no-external-require-in-bin enforces that invariant, which had been documented in a comment since the #3024/#2071 bug class and enforced nowhere.
Backreferences and look-around are unsupported by RE2 by construction — disclosed in a Changed changeset.
Closes #3477
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
35 lines
2.1 KiB
JSON
35 lines
2.1 KiB
JSON
[
|
|
{
|
|
"path": "gsd-core/bin/lib/vendor/re2js.d.cts",
|
|
"reason": "Vendored third-party type declaration (#3477): a .d.cts carries no executable code, so no ESLint rule is meaningful; the vendored .cjs it describes is globally ignored as verbatim upstream output. Freshness is enforced by scripts/lint-vendored-deps.cjs, not by lint rules."
|
|
},
|
|
{
|
|
"path": "src/vendor/re2js.d.cts",
|
|
"reason": "Vendored third-party type declaration (#3477): a .d.cts carries no executable code, so no ESLint rule is meaningful; the vendored .cjs it describes is globally ignored as verbatim upstream output. Freshness is enforced by scripts/lint-vendored-deps.cjs, not by lint rules."
|
|
},
|
|
{
|
|
"path": "tests/fixtures/brand-typing/bad-calibrated-as-sample-basis.cts",
|
|
"reason": "Deliberate MUST-NOT-COMPILE type-error fixture (#3059): type-aware linting would fail by design; it exists to prove the compiler rejects it."
|
|
},
|
|
{
|
|
"path": "tests/fixtures/brand-typing/bad-double-calibration.cts",
|
|
"reason": "Deliberate MUST-NOT-COMPILE type-error fixture (#3059): type-aware linting would fail by design; it exists to prove the compiler rejects it."
|
|
},
|
|
{
|
|
"path": "tests/fixtures/brand-typing/bad-raw-against-budget.cts",
|
|
"reason": "Deliberate MUST-NOT-COMPILE type-error fixture (#3059): type-aware linting would fail by design; it exists to prove the compiler rejects it."
|
|
},
|
|
{
|
|
"path": "tests/fixtures/brand-typing/bad-rebrand-calibrated-as-raw.cts",
|
|
"reason": "Deliberate MUST-NOT-COMPILE type-error fixture (#3059): type-aware linting would fail by design; it exists to prove the compiler rejects it."
|
|
},
|
|
{
|
|
"path": "tests/fixtures/brand-typing/bad-unbranded-number-as-raw.cts",
|
|
"reason": "Deliberate MUST-NOT-COMPILE type-error fixture (#3059): type-aware linting would fail by design; it exists to prove the compiler rejects it."
|
|
},
|
|
{
|
|
"path": "tests/fixtures/brand-typing/ok-correct-composition.cts",
|
|
"reason": "Positive-control counterpart to the bad-* must-not-compile fixtures (#3059); kept in the same exemption so the pair stays together."
|
|
}
|
|
]
|