tamperward 2.23.13 → 2.23.15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/cli/index.js +56 -37
  2. package/package.json +1 -1
package/dist/cli/index.js CHANGED
@@ -1610,7 +1610,30 @@ function loadTs() {
1610
1610
  }
1611
1611
  return loaded;
1612
1612
  }
1613
- var loaded, handler, ts;
1613
+ function nestsWithinCeiling(src) {
1614
+ let depth = 0;
1615
+ for (let i = 0; i < src.length; i++) {
1616
+ const c = src.charCodeAt(i);
1617
+ if (c === 40 || c === 91 || c === 123) {
1618
+ if (++depth > MAX_PARSE_DEPTH) return false;
1619
+ } else if (c === 41 || c === 93 || c === 125) {
1620
+ if (depth > 0) depth--;
1621
+ }
1622
+ }
1623
+ return true;
1624
+ }
1625
+ function parseSource(fileName, src, kind) {
1626
+ if (Buffer.byteLength(src) > MAX_PARSE_BYTES) return null;
1627
+ if (!nestsWithinCeiling(src)) return null;
1628
+ const t = loadTs();
1629
+ try {
1630
+ return t.createSourceFile(fileName, src, t.ScriptTarget.Latest, true, kind ?? t.ScriptKind.TS);
1631
+ } catch (e) {
1632
+ if (e instanceof RangeError) return null;
1633
+ throw e;
1634
+ }
1635
+ }
1636
+ var loaded, handler, ts, MAX_PARSE_BYTES, MAX_PARSE_DEPTH;
1614
1637
  var init_ts_lazy = __esm({
1615
1638
  "src/ts-lazy.ts"() {
1616
1639
  "use strict";
@@ -1631,6 +1654,8 @@ var init_ts_lazy = __esm({
1631
1654
  }
1632
1655
  };
1633
1656
  ts = new Proxy(/* @__PURE__ */ Object.create(null), handler);
1657
+ MAX_PARSE_BYTES = 4 * 1024 * 1024;
1658
+ MAX_PARSE_DEPTH = 256;
1634
1659
  }
1635
1660
  });
1636
1661
 
@@ -1750,12 +1775,8 @@ function isDoubleCast(node) {
1750
1775
  return (ts.isAsExpression(inner) || ts.isTypeAssertionExpression(inner)) && assertedType(inner).kind === ts.SyntaxKind.UnknownKeyword;
1751
1776
  }
1752
1777
  function surfaceOf(path, src) {
1753
- let sf;
1754
- try {
1755
- sf = ts.createSourceFile(path, src, ts.ScriptTarget.Latest, true, scriptKind(path));
1756
- } catch {
1757
- return null;
1758
- }
1778
+ const sf = parseSource(path, src, scriptKind(path));
1779
+ if (!sf) return null;
1759
1780
  const diagnostics = "parseDiagnostics" in sf && Array.isArray(sf.parseDiagnostics) ? sf.parseDiagnostics : [];
1760
1781
  if (diagnostics.length > 0) return null;
1761
1782
  const surface = { type: 0, nonNull: 0, assertions: [] };
@@ -1866,7 +1887,8 @@ var init_ts_cast_growth = __esm({
1866
1887
  function countAny(src) {
1867
1888
  const r = { cast: 0, broad: 0, double: 0 };
1868
1889
  try {
1869
- const sf = ts.createSourceFile("f.ts", src, ts.ScriptTarget.Latest, true, ts.ScriptKind.TS);
1890
+ const sf = parseSource("f.ts", src);
1891
+ if (!sf) return r;
1870
1892
  const visit = (node) => {
1871
1893
  if ((ts.isAsExpression(node) || ts.isTypeAssertionExpression(node)) && isDoubleCast(node)) r.double++;
1872
1894
  if (node.kind === ts.SyntaxKind.AnyKeyword) {
@@ -1888,12 +1910,8 @@ function countAny(src) {
1888
1910
  return r;
1889
1911
  }
1890
1912
  function lineHasDoubleCast(line) {
1891
- let sf;
1892
- try {
1893
- sf = ts.createSourceFile("line.ts", line, ts.ScriptTarget.Latest, true, ts.ScriptKind.TS);
1894
- } catch {
1895
- return false;
1896
- }
1913
+ const sf = parseSource("line.ts", line);
1914
+ if (!sf) return false;
1897
1915
  let found = false;
1898
1916
  const visit = (n) => {
1899
1917
  if (found) return;
@@ -2261,13 +2279,8 @@ function requiredModule(expr) {
2261
2279
  }
2262
2280
  function astContext(path, source) {
2263
2281
  const rootName = path.startsWith("/") ? path : "/tamperward/" + path;
2264
- const sf = ts.createSourceFile(
2265
- rootName,
2266
- source,
2267
- ts.ScriptTarget.Latest,
2268
- true,
2269
- scriptKind2(path)
2270
- );
2282
+ const sf = parseSource(rootName, source, scriptKind2(path));
2283
+ if (!sf) return null;
2271
2284
  const diagnostics = "parseDiagnostics" in sf && Array.isArray(sf.parseDiagnostics) ? sf.parseDiagnostics : [];
2272
2285
  if (diagnostics.length > 0) return null;
2273
2286
  const options = {
@@ -3035,7 +3048,7 @@ function asExpression(src) {
3035
3048
  return t.startsWith("{") ? `(${t})` : src;
3036
3049
  }
3037
3050
  function sourceOf(src) {
3038
- return ts.createSourceFile("cfg.ts", asExpression(src), ts.ScriptTarget.Latest, true, ts.ScriptKind.TS);
3051
+ return parseSource("cfg.ts", asExpression(src));
3039
3052
  }
3040
3053
  function resolverFor(sf) {
3041
3054
  const consts = /* @__PURE__ */ new Map();
@@ -3057,6 +3070,7 @@ function parseThresholds(src) {
3057
3070
  const res = { paths: /* @__PURE__ */ new Map(), present: false, opaque: false };
3058
3071
  try {
3059
3072
  const sf = sourceOf(src);
3073
+ if (!sf) return res;
3060
3074
  const resolve16 = resolverFor(sf);
3061
3075
  const visit = (node) => {
3062
3076
  if (ts.isPropertyAssignment(node)) {
@@ -3114,6 +3128,7 @@ function parseLists(src) {
3114
3128
  const res = { collectFrom: null, collectKey: "collectCoverageFrom", ignore: [], opaqueCollect: false, opaqueIgnore: false };
3115
3129
  try {
3116
3130
  const sf = sourceOf(src);
3131
+ if (!sf) return res;
3117
3132
  const resolve16 = resolverFor(sf);
3118
3133
  const visit = (node) => {
3119
3134
  if (ts.isPropertyAssignment(node)) {
@@ -3141,6 +3156,7 @@ function parseSwitches(src) {
3141
3156
  const res = {};
3142
3157
  try {
3143
3158
  const sf = sourceOf(src);
3159
+ if (!sf) return res;
3144
3160
  const bool2 = (e) => e.kind === ts.SyntaxKind.TrueKeyword ? true : e.kind === ts.SyntaxKind.FalseKeyword ? false : void 0;
3145
3161
  const visit = (node) => {
3146
3162
  if (ts.isPropertyAssignment(node)) {
@@ -3159,6 +3175,7 @@ function parseSwitches(src) {
3159
3175
  function sectionText(src, key2) {
3160
3176
  try {
3161
3177
  const sf = sourceOf(src);
3178
+ if (!sf) return "";
3162
3179
  let out3 = "";
3163
3180
  const visit = (node) => {
3164
3181
  if (out3) return;
@@ -6244,7 +6261,8 @@ function parseSelection(src, runner, path = "") {
6244
6261
  let sel = empty();
6245
6262
  if (runner === "pytest") return pytestSelection(src);
6246
6263
  try {
6247
- const sf = ts.createSourceFile("cfg.ts", asExpression2(src), ts.ScriptTarget.Latest, true, ts.ScriptKind.TS);
6264
+ const sf = parseSource("cfg.ts", asExpression2(src));
6265
+ if (!sf) return sel;
6248
6266
  if (runner === "vitest" && isWorkspaceFile(path)) {
6249
6267
  const arr = workspaceArray(sf);
6250
6268
  if (arr) {
@@ -7486,7 +7504,8 @@ function countTests(src, path = "spec.ts", substantiveOnly = false) {
7486
7504
  for (const line of src.split("\n")) if (re.test(line)) n2++;
7487
7505
  return { min: n2, open: false };
7488
7506
  }
7489
- const sf = ts.createSourceFile("spec.ts", src, ts.ScriptTarget.Latest, true, ts.ScriptKind.TS);
7507
+ const sf = parseSource("spec.ts", src);
7508
+ if (!sf) return { min: 0, open: true };
7490
7509
  let n = 0;
7491
7510
  let open = false;
7492
7511
  const visit = (node, mult) => {
@@ -7900,7 +7919,8 @@ function eachTables(src, path) {
7900
7919
  let open = false;
7901
7920
  if (langOf(path) !== "js" && langOf(path) !== null) return { rows, open };
7902
7921
  try {
7903
- const sf = ts.createSourceFile("spec.ts", src, ts.ScriptTarget.Latest, true, ts.ScriptKind.TS);
7922
+ const sf = parseSource("spec.ts", src);
7923
+ if (!sf) return { rows, open };
7904
7924
  const visit = (node) => {
7905
7925
  if (ts.isCallExpression(node) && ts.isPropertyAccessExpression(node.expression) && /^(?:each|for)$/.test(node.expression.name.text) && ts.isIdentifier(node.expression.expression) && /^(?:it|test|describe)$/.test(node.expression.expression.text)) {
7906
7926
  const arg = node.arguments[0];
@@ -8204,7 +8224,8 @@ function blocks(src, path) {
8204
8224
  const out3 = /* @__PURE__ */ new Map();
8205
8225
  if (langOf(path) !== "js") return out3;
8206
8226
  try {
8207
- const sf = ts.createSourceFile(path, src, ts.ScriptTarget.Latest, true, scriptKindForPath(path));
8227
+ const sf = parseSource(path, src, scriptKindForPath(path));
8228
+ if (!sf) return out3;
8208
8229
  const visit = (node, suites) => {
8209
8230
  if (ts.isCallExpression(node)) {
8210
8231
  const call = simpleCallName(node);
@@ -8408,17 +8429,15 @@ function evaluate(changes, policy, detectors = allDetectors, view, ctx) {
8408
8429
  } catch (e) {
8409
8430
  process.stderr.write(`tamperward: detector "${d.id}" errored: ${String(e)}
8410
8431
  `);
8411
- if (view === "staged" || view === "worktree" || view === "range") {
8412
- const failed2 = {
8413
- rule: "detector-error",
8414
- severity: "block",
8415
- message: `Detector "${d.id}" failed to run; the verdict is incomplete.`,
8416
- evidence: String(e).slice(0, 200),
8417
- remediation: "A rule that cannot run is not a rule that passed. Fix the input or the detector; do not read this as clean.",
8418
- signoff: { required: true, command: `tamperward allow detector-error --reason "..."` }
8419
- };
8420
- out3.push(failed2);
8421
- }
8432
+ const failed2 = {
8433
+ rule: "detector-error",
8434
+ severity: "block",
8435
+ message: `Detector "${d.id}" failed to run; the verdict is incomplete.`,
8436
+ evidence: String(e).slice(0, 200),
8437
+ remediation: "A rule that cannot run is not a rule that passed. Fix the input or the detector; do not read this as clean.",
8438
+ signoff: { required: true, command: `tamperward allow detector-error --reason "..."` }
8439
+ };
8440
+ out3.push(failed2);
8422
8441
  }
8423
8442
  }
8424
8443
  const seen = /* @__PURE__ */ new Set();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tamperward",
3
- "version": "2.23.13",
3
+ "version": "2.23.15",
4
4
  "description": "The deterministic agent-integrity gate. One ruleset, evaluated on the actual diff/commands as a verdict, enforced everywhere a change can be made.",
5
5
  "license": "Apache-2.0",
6
6
  "author": "hexrift",