circle-ir 4.7.0 → 4.7.1

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.
@@ -1 +1 @@
1
- {"version":3,"file":"unrestricted-file-upload-pass.d.ts","sourceRoot":"","sources":["../../../src/analysis/passes/unrestricted-file-upload-pass.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAC;AAG9E,MAAM,WAAW,4BAA4B;IAC3C,QAAQ,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAClE;AA2BD,qBAAa,0BAA2B,YAAW,YAAY,CAAC,4BAA4B,CAAC;IAC3F,QAAQ,CAAC,IAAI,8BAA8B;IAC3C,QAAQ,CAAC,QAAQ,EAAG,UAAU,CAAU;IAExC,GAAG,CAAC,GAAG,EAAE,WAAW,GAAG,4BAA4B;IAyInD,OAAO,CAAC,IAAI;CAgCb"}
1
+ {"version":3,"file":"unrestricted-file-upload-pass.d.ts","sourceRoot":"","sources":["../../../src/analysis/passes/unrestricted-file-upload-pass.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAC;AAG9E,MAAM,WAAW,4BAA4B;IAC3C,QAAQ,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAClE;AA4BD,qBAAa,0BAA2B,YAAW,YAAY,CAAC,4BAA4B,CAAC;IAC3F,QAAQ,CAAC,IAAI,8BAA8B;IAC3C,QAAQ,CAAC,QAAQ,EAAG,UAAU,CAAU;IAExC,GAAG,CAAC,GAAG,EAAE,WAAW,GAAG,4BAA4B;IA0InD,OAAO,CAAC,IAAI;CAgCb"}
@@ -34,8 +34,9 @@
34
34
  const UPLOAD_NAME_RE = /(?:getOriginalFilename|getSubmittedFileName|originalname|originalName|\.filename|\.Filename|FileHeader\.Filename|UploadFile)/;
35
35
  /** Identifier-level allow-list / canonicalization calls that defang upload paths. */
36
36
  const FILE_SAFE_CALL_RE = /(?:secure_filename|FilenameUtils\.getExtension|\.lastIndexOf\(['"]\.['"]\)|ALLOWED_EXT|ALLOWED_EXTENSIONS|allowedExtensions|\bfileFilter\b|filepath\.Ext|path\.extname)/;
37
- function lineWindow(code, startLine, endLine) {
38
- const lines = code.split('\n');
37
+ // Takes the pre-split source lines so the whole file is not re-split on every
38
+ // call (was O(methods · lines) O(n²) on large files — cognium-ai#305).
39
+ function lineWindow(lines, startLine, endLine) {
39
40
  const s = Math.max(0, startLine - 1);
40
41
  const e = Math.min(lines.length, endLine);
41
42
  return lines.slice(s, e).join('\n');
@@ -58,13 +59,14 @@ export class UnrestrictedFileUploadPass {
58
59
  const { graph, language, code } = ctx;
59
60
  const file = graph.ir.meta.file;
60
61
  const findings = [];
62
+ const codeLines = code.split('\n'); // split once; reused by every lineWindow
61
63
  // Build per-function safety windows: a function is "safe" if its body
62
64
  // contains any FILE_SAFE_CALL_RE marker. Used to suppress findings inside
63
65
  // that scope.
64
66
  const safeFunctionRanges = [];
65
67
  for (const t of graph.ir.types) {
66
68
  for (const m of t.methods) {
67
- const body = lineWindow(code, m.start_line, m.end_line);
69
+ const body = lineWindow(codeLines, m.start_line, m.end_line);
68
70
  if (FILE_SAFE_CALL_RE.test(body)) {
69
71
  safeFunctionRanges.push({ start: m.start_line, end: m.end_line });
70
72
  }
@@ -76,7 +78,7 @@ export class UnrestrictedFileUploadPass {
76
78
  return true;
77
79
  }
78
80
  // No method information — fall back to a ±20-line window around the call.
79
- const win = lineWindow(code, Math.max(1, line - 20), line + 5);
81
+ const win = lineWindow(codeLines, Math.max(1, line - 20), line + 5);
80
82
  return FILE_SAFE_CALL_RE.test(win);
81
83
  };
82
84
  // --- Per-language detection -----------------------------------------------
@@ -1 +1 @@
1
- {"version":3,"file":"unrestricted-file-upload-pass.js","sourceRoot":"","sources":["../../../src/analysis/passes/unrestricted-file-upload-pass.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"unrestricted-file-upload-pass.js","sourceRoot":"","sources":["../../../src/analysis/passes/unrestricted-file-upload-pass.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"unused-variable-pass.d.ts","sourceRoot":"","sources":["../../../src/analysis/passes/unused-variable-pass.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAC;AAa9E,MAAM,WAAW,oBAAoB;IACnC,UAAU,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACvD;AAED,qBAAa,kBAAmB,YAAW,YAAY,CAAC,oBAAoB,CAAC;IAC3E,QAAQ,CAAC,IAAI,qBAAqB;IAClC,QAAQ,CAAC,QAAQ,EAAG,aAAa,CAAU;IAE3C,GAAG,CAAC,GAAG,EAAE,WAAW,GAAG,oBAAoB;CAoH5C"}
1
+ {"version":3,"file":"unused-variable-pass.d.ts","sourceRoot":"","sources":["../../../src/analysis/passes/unused-variable-pass.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAC;AAgB9E,MAAM,WAAW,oBAAoB;IACnC,UAAU,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACvD;AAED,qBAAa,kBAAmB,YAAW,YAAY,CAAC,oBAAoB,CAAC;IAC3E,QAAQ,CAAC,IAAI,qBAAqB;IAClC,QAAQ,CAAC,QAAQ,EAAG,aAAa,CAAU;IAE3C,GAAG,CAAC,GAAG,EAAE,WAAW,GAAG,oBAAoB;CAyJ5C"}
@@ -32,6 +32,8 @@ const SKIP_NAMES = new Set([
32
32
  'boolean', 'string', 'number', 'object', 'symbol', 'undefined',
33
33
  'null', 'never', 'void', 'any', 'unknown', 'bigint',
34
34
  ]);
35
+ /** Shared empty line-index for names absent from the source text. */
36
+ const EMPTY_LINES = [];
35
37
  export class UnusedVariablePass {
36
38
  name = 'unused-variable';
37
39
  category = 'reliability';
@@ -45,6 +47,43 @@ export class UnusedVariablePass {
45
47
  const codeLines = code.split('\n');
46
48
  const unusedVars = [];
47
49
  const reported = new Set(); // deduplicate by variable+line
50
+ // Precompute two indexes ONCE so the per-def fallback is not quadratic on
51
+ // large files (cognium-ai#305): grouping defs by variable avoids an O(defs)
52
+ // rescan per candidate, and a name→line-numbers map avoids an O(lines)
53
+ // text scan per candidate. Both replace the previous O(defs²)+O(defs·lines)
54
+ // work — the dominant cost on files where the DFG surfaces few uses.
55
+ const defsByVar = new Map();
56
+ for (const d of graph.ir.dfg.defs) {
57
+ const arr = defsByVar.get(d.variable);
58
+ if (arr)
59
+ arr.push(d);
60
+ else
61
+ defsByVar.set(d.variable, [d]);
62
+ }
63
+ // 1-indexed line numbers on which each identifier token appears (deduped
64
+ // per line). Equivalent to a `\bname\b` scan for identifier names; names
65
+ // containing non-identifier chars (dotted paths, `$`) fall back to regex.
66
+ const nameLines = new Map();
67
+ const idRe = /[A-Za-z_][A-Za-z0-9_]*/g;
68
+ for (let i = 0; i < codeLines.length; i++) {
69
+ const line = codeLines[i];
70
+ idRe.lastIndex = 0;
71
+ let seen = null;
72
+ let m;
73
+ while ((m = idRe.exec(line)) !== null) {
74
+ const w = m[0];
75
+ if (seen === null)
76
+ seen = new Set();
77
+ if (seen.has(w))
78
+ continue;
79
+ seen.add(w);
80
+ const arr = nameLines.get(w);
81
+ if (arr)
82
+ arr.push(i + 1);
83
+ else
84
+ nameLines.set(w, [i + 1]);
85
+ }
86
+ }
48
87
  for (const def of graph.ir.dfg.defs) {
49
88
  if (def.kind !== 'local')
50
89
  continue;
@@ -70,13 +109,19 @@ export class UnusedVariablePass {
70
109
  // module-level constants referenced inside a class method body, or
71
110
  // conditional reassignments where the DFG links the final read only to
72
111
  // the last def so earlier defs appear unused).
73
- const otherDefs = graph.ir.dfg.defs.filter(d => d.variable === variable && d.id !== def.id);
112
+ const otherDefs = (defsByVar.get(variable) ?? []).filter(d => d.id !== def.id);
74
113
  const otherDefLines = new Set(otherDefs.map(d => d.line));
75
- const escapedName = variable.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
76
- const namePattern = new RegExp(`\\b${escapedName}\\b`);
114
+ // Plain identifier names use the precomputed index; others fall back to a
115
+ // per-line regex (rare — dotted paths / `$`).
116
+ const plainName = /^[A-Za-z_][A-Za-z0-9_]*$/.test(variable);
117
+ const idxLines = plainName ? (nameLines.get(variable) ?? EMPTY_LINES) : null;
118
+ const namePattern = plainName ? null
119
+ : new RegExp(`\\b${variable.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}\\b`);
77
120
  if (otherDefLines.size === 0) {
78
- // Single def — simple text search: any occurrence on another line suppresses.
79
- const usedElsewhere = codeLines.some((line, idx) => idx !== def.line - 1 && namePattern.test(line));
121
+ // Single def — any occurrence on another line suppresses.
122
+ const usedElsewhere = idxLines !== null
123
+ ? idxLines.some(ln => ln !== def.line)
124
+ : codeLines.some((line, idx) => idx !== def.line - 1 && namePattern.test(line));
80
125
  if (usedElsewhere)
81
126
  continue;
82
127
  }
@@ -99,26 +144,30 @@ export class UnusedVariablePass {
99
144
  || /\b[A-Z]\w*(?:<[^>]*>)?\s+\w/.test(lineText)
100
145
  || /\blet\s+(?:mut\s+)?\w/.test(lineText);
101
146
  if (isTrueDeclaration) {
102
- // Case A: suppress only if use appears before any intermediate def.
103
- const usedBeforeNextDef = codeLines.some((line, idx) => {
104
- const lineNum = idx + 1;
105
- if (lineNum === def.line || otherDefLines.has(lineNum))
106
- return false;
107
- if (!namePattern.test(line))
108
- return false;
109
- // If any other def for this variable sits between our def and this use,
110
- // the value was overwritten → this use belongs to the later def → don't suppress.
111
- return !otherDefs.some(d => d.line > def.line && d.line < lineNum);
112
- });
147
+ // Case A: suppress only if a use appears before any intermediate def
148
+ // (an intermediate def would mean the value was overwritten first).
149
+ const usedBeforeNextDef = idxLines !== null
150
+ ? idxLines.some(ln => ln !== def.line && !otherDefLines.has(ln) &&
151
+ !otherDefs.some(d => d.line > def.line && d.line < ln))
152
+ : codeLines.some((line, idx) => {
153
+ const lineNum = idx + 1;
154
+ if (lineNum === def.line || otherDefLines.has(lineNum))
155
+ return false;
156
+ if (!namePattern.test(line))
157
+ return false;
158
+ return !otherDefs.some(d => d.line > def.line && d.line < lineNum);
159
+ });
113
160
  if (usedBeforeNextDef)
114
161
  continue;
115
162
  }
116
163
  else {
117
164
  // Case B: bare reassignment — suppress if used on any non-def line.
118
- const usedOnNonDefLine = codeLines.some((line, idx) => {
119
- const lineNum = idx + 1;
120
- return lineNum !== def.line && !otherDefLines.has(lineNum) && namePattern.test(line);
121
- });
165
+ const usedOnNonDefLine = idxLines !== null
166
+ ? idxLines.some(ln => ln !== def.line && !otherDefLines.has(ln))
167
+ : codeLines.some((line, idx) => {
168
+ const lineNum = idx + 1;
169
+ return lineNum !== def.line && !otherDefLines.has(lineNum) && namePattern.test(line);
170
+ });
122
171
  if (usedOnNonDefLine)
123
172
  continue;
124
173
  }
@@ -1 +1 @@
1
- {"version":3,"file":"unused-variable-pass.js","sourceRoot":"","sources":["../../../src/analysis/passes/unused-variable-pass.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"unused-variable-pass.js","sourceRoot":"","sources":["../../../src/analysis/passes/unused-variable-pass.ts"],"names":[],"mappings":"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"}
@@ -9918,15 +9918,15 @@ function computeChains(defs, uses) {
9918
9918
  existing.push(use);
9919
9919
  usesByLine.set(use.line, existing);
9920
9920
  }
9921
+ const seenChains = /* @__PURE__ */ new Set();
9921
9922
  for (const def of defs) {
9922
9923
  if (def.kind === "local") {
9923
9924
  const usesOnLine = usesByLine.get(def.line) ?? [];
9924
9925
  for (const use of usesOnLine) {
9925
9926
  if (use.def_id !== null && use.def_id !== def.id) {
9926
- const exists = chains.some(
9927
- (c) => c.from_def === use.def_id && c.to_def === def.id && c.via === use.variable
9928
- );
9929
- if (!exists) {
9927
+ const key = `${use.def_id}\0${def.id}\0${use.variable}`;
9928
+ if (!seenChains.has(key)) {
9929
+ seenChains.add(key);
9930
9930
  chains.push({
9931
9931
  from_def: use.def_id,
9932
9932
  to_def: def.id,
@@ -12501,8 +12501,11 @@ var DEFAULT_SINKS = [
12501
12501
  // SAX handler sinks (can lead to XSS in parsed content)
12502
12502
  { method: "startElement", class: "ContentHandler", type: "xss", cwe: "CWE-79", severity: "high", arg_positions: [0, 1, 2] },
12503
12503
  { method: "characters", class: "ContentHandler", type: "xss", cwe: "CWE-79", severity: "high", arg_positions: [0] },
12504
- // Template output sinks
12505
- { method: "output", type: "xss", cwe: "CWE-79", severity: "high", arg_positions: [0] },
12504
+ // Template output sinks. `output` is classless (Java template engines /
12505
+ // Velocity), but Rust `std::process::Command::…output()` is process
12506
+ // execution, not HTML — it already fires the CWE-78 command_injection sink,
12507
+ // so exclude Rust here to drop the spurious xss (cognium-dev#146).
12508
+ { method: "output", type: "xss", cwe: "CWE-79", severity: "high", arg_positions: [0], exclude_languages: ["rust"] },
12506
12509
  { method: "setOutput", type: "xss", cwe: "CWE-79", severity: "high", arg_positions: [0] },
12507
12510
  { method: "writeAttribute", type: "xss", cwe: "CWE-79", severity: "high", arg_positions: [0, 1] },
12508
12511
  // AntiSamy specific (SAX filters)
@@ -18581,6 +18584,26 @@ function analyzeInterprocedural(graphOrTypes, callsOrSources, dfgOrSinks, source
18581
18584
  "Command",
18582
18585
  "CommandContext"
18583
18586
  ]);
18587
+ const ormQueryBuilderMethods = /* @__PURE__ */ new Set([
18588
+ "findMany",
18589
+ "findFirst",
18590
+ "findUnique",
18591
+ "findUniqueOrThrow",
18592
+ "findFirstOrThrow",
18593
+ "findOne",
18594
+ "findAll",
18595
+ "findByPk",
18596
+ "findAndCountAll",
18597
+ "findBy",
18598
+ "findOneBy",
18599
+ "where",
18600
+ "andWhere",
18601
+ "orWhere",
18602
+ "whereIn",
18603
+ "whereNot",
18604
+ "first",
18605
+ "bind"
18606
+ ]);
18584
18607
  const sanitizerMethods = /* @__PURE__ */ new Set();
18585
18608
  for (const san of sanitizers) {
18586
18609
  sanitizerMethods.add(san.method);
@@ -18605,7 +18628,7 @@ function analyzeInterprocedural(graphOrTypes, callsOrSources, dfgOrSinks, source
18605
18628
  }
18606
18629
  const targetMethod = getMethodNode(methodNodes, call.method_name);
18607
18630
  if (!targetMethod) {
18608
- if (taintedArgPositions.length > 0 && !collectionMethods.has(call.method_name) && !sanitizerMethods.has(call.method_name) && !safeUtilityMethods.has(call.method_name)) {
18631
+ if (taintedArgPositions.length > 0 && !collectionMethods.has(call.method_name) && !sanitizerMethods.has(call.method_name) && !safeUtilityMethods.has(call.method_name) && !ormQueryBuilderMethods.has(call.method_name)) {
18609
18632
  const isBash = graph.ir.meta.language === "bash";
18610
18633
  const bashSafeBuiltins = /* @__PURE__ */ new Set([
18611
18634
  "echo",
@@ -26394,6 +26417,7 @@ var LanguageSourcesPass = class {
26394
26417
  additionalSources.push(...findSetterChainSources(types, code, language));
26395
26418
  additionalSources.push(...findJavaScriptAssignmentSources(code, language));
26396
26419
  additionalSources.push(...findCSharpRequestSources(code, language));
26420
+ additionalSources.push(...findGoArgvSources(code, language));
26397
26421
  const jsDOMSinks = findJavaScriptDOMSinks(code, language);
26398
26422
  for (const s of jsDOMSinks) {
26399
26423
  const alreadyExists = additionalSinks.some((x) => x.line === s.line && x.cwe === s.cwe);
@@ -27048,6 +27072,31 @@ function findSetterChainSources(types, sourceCode, language) {
27048
27072
  }
27049
27073
  return sources;
27050
27074
  }
27075
+ function findGoArgvSources(sourceCode, language) {
27076
+ if (language !== "go") return [];
27077
+ const sources = [];
27078
+ const lines = sourceCode.split("\n");
27079
+ const rangeRe = /\bfor\b[^;{]*?,\s*([A-Za-z_]\w*)\s*:?=\s*range\s+os\.Args\b/;
27080
+ const assignRe = /\b([A-Za-z_]\w*)\s*:?=\s*os\.Args\b/;
27081
+ for (let i2 = 0; i2 < lines.length; i2++) {
27082
+ const line = lines[i2];
27083
+ const rm = rangeRe.exec(line);
27084
+ const m = rm ?? assignRe.exec(line);
27085
+ if (!m) continue;
27086
+ const varName = m[1];
27087
+ const lineNumber = i2 + 1;
27088
+ if (sources.some((s) => s.line === lineNumber && s.variable === varName)) continue;
27089
+ sources.push({
27090
+ type: "io_input",
27091
+ location: `${varName} = os.Args`,
27092
+ severity: "high",
27093
+ line: lineNumber,
27094
+ confidence: 1,
27095
+ variable: varName
27096
+ });
27097
+ }
27098
+ return sources;
27099
+ }
27051
27100
  function findCSharpRequestSources(sourceCode, language) {
27052
27101
  if (language !== "csharp") return [];
27053
27102
  const sources = [];
@@ -27892,7 +27941,7 @@ function findBashTaintSources(sourceCode, dfg) {
27892
27941
  });
27893
27942
  }
27894
27943
  }
27895
- const envRe = /\$([A-Z][A-Z0-9_]{2,})|\$\{([A-Z][A-Z0-9_]{2,})\}/g;
27944
+ const envRe = /\$([A-Z][A-Z0-9_]{2,})|\$\{([A-Z][A-Z0-9_]{2,})(?:[:#%/^,@!*+?=-][^}]*)?\}/g;
27896
27945
  let em;
27897
27946
  while ((em = envRe.exec(line)) !== null) {
27898
27947
  const envVar = em[1] ?? em[2];
@@ -38125,6 +38174,7 @@ var SKIP_NAMES3 = /* @__PURE__ */ new Set([
38125
38174
  "unknown",
38126
38175
  "bigint"
38127
38176
  ]);
38177
+ var EMPTY_LINES = [];
38128
38178
  var UnusedVariablePass = class {
38129
38179
  name = "unused-variable";
38130
38180
  category = "reliability";
@@ -38137,6 +38187,29 @@ var UnusedVariablePass = class {
38137
38187
  const codeLines = code.split("\n");
38138
38188
  const unusedVars = [];
38139
38189
  const reported = /* @__PURE__ */ new Set();
38190
+ const defsByVar = /* @__PURE__ */ new Map();
38191
+ for (const d of graph.ir.dfg.defs) {
38192
+ const arr = defsByVar.get(d.variable);
38193
+ if (arr) arr.push(d);
38194
+ else defsByVar.set(d.variable, [d]);
38195
+ }
38196
+ const nameLines = /* @__PURE__ */ new Map();
38197
+ const idRe = /[A-Za-z_][A-Za-z0-9_]*/g;
38198
+ for (let i2 = 0; i2 < codeLines.length; i2++) {
38199
+ const line = codeLines[i2];
38200
+ idRe.lastIndex = 0;
38201
+ let seen = null;
38202
+ let m;
38203
+ while ((m = idRe.exec(line)) !== null) {
38204
+ const w = m[0];
38205
+ if (seen === null) seen = /* @__PURE__ */ new Set();
38206
+ if (seen.has(w)) continue;
38207
+ seen.add(w);
38208
+ const arr = nameLines.get(w);
38209
+ if (arr) arr.push(i2 + 1);
38210
+ else nameLines.set(w, [i2 + 1]);
38211
+ }
38212
+ }
38140
38213
  for (const def of graph.ir.dfg.defs) {
38141
38214
  if (def.kind !== "local") continue;
38142
38215
  const variable = def.variable;
@@ -38147,22 +38220,19 @@ var UnusedVariablePass = class {
38147
38220
  if (/\bexport\b/.test(lineText)) continue;
38148
38221
  const uses = graph.usesOfDef(def.id);
38149
38222
  if (uses.length > 0) continue;
38150
- const otherDefs = graph.ir.dfg.defs.filter(
38151
- (d) => d.variable === variable && d.id !== def.id
38152
- );
38223
+ const otherDefs = (defsByVar.get(variable) ?? []).filter((d) => d.id !== def.id);
38153
38224
  const otherDefLines = new Set(otherDefs.map((d) => d.line));
38154
- const escapedName = variable.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
38155
- const namePattern = new RegExp(`\\b${escapedName}\\b`);
38225
+ const plainName = /^[A-Za-z_][A-Za-z0-9_]*$/.test(variable);
38226
+ const idxLines = plainName ? nameLines.get(variable) ?? EMPTY_LINES : null;
38227
+ const namePattern = plainName ? null : new RegExp(`\\b${variable.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}\\b`);
38156
38228
  if (otherDefLines.size === 0) {
38157
- const usedElsewhere = codeLines.some(
38158
- (line, idx) => idx !== def.line - 1 && namePattern.test(line)
38159
- );
38229
+ const usedElsewhere = idxLines !== null ? idxLines.some((ln) => ln !== def.line) : codeLines.some((line, idx) => idx !== def.line - 1 && namePattern.test(line));
38160
38230
  if (usedElsewhere) continue;
38161
38231
  } else {
38162
38232
  const lineText2 = codeLines[def.line - 1] ?? "";
38163
38233
  const isTrueDeclaration = /\b(?:let|const|var)\s+[\w{[]/.test(lineText2) || /\b(?:int|long|float|double|boolean|byte|char|short|var|final)\b/.test(lineText2) || /\b[A-Z]\w*(?:<[^>]*>)?\s+\w/.test(lineText2) || /\blet\s+(?:mut\s+)?\w/.test(lineText2);
38164
38234
  if (isTrueDeclaration) {
38165
- const usedBeforeNextDef = codeLines.some((line, idx) => {
38235
+ const usedBeforeNextDef = idxLines !== null ? idxLines.some((ln) => ln !== def.line && !otherDefLines.has(ln) && !otherDefs.some((d) => d.line > def.line && d.line < ln)) : codeLines.some((line, idx) => {
38166
38236
  const lineNum = idx + 1;
38167
38237
  if (lineNum === def.line || otherDefLines.has(lineNum)) return false;
38168
38238
  if (!namePattern.test(line)) return false;
@@ -38170,7 +38240,7 @@ var UnusedVariablePass = class {
38170
38240
  });
38171
38241
  if (usedBeforeNextDef) continue;
38172
38242
  } else {
38173
- const usedOnNonDefLine = codeLines.some((line, idx) => {
38243
+ const usedOnNonDefLine = idxLines !== null ? idxLines.some((ln) => ln !== def.line && !otherDefLines.has(ln)) : codeLines.some((line, idx) => {
38174
38244
  const lineNum = idx + 1;
38175
38245
  return lineNum !== def.line && !otherDefLines.has(lineNum) && namePattern.test(line);
38176
38246
  });
@@ -42940,8 +43010,7 @@ var InfoDisclosureStacktracePass = class {
42940
43010
  // src/analysis/passes/unrestricted-file-upload-pass.ts
42941
43011
  var UPLOAD_NAME_RE = /(?:getOriginalFilename|getSubmittedFileName|originalname|originalName|\.filename|\.Filename|FileHeader\.Filename|UploadFile)/;
42942
43012
  var FILE_SAFE_CALL_RE = /(?:secure_filename|FilenameUtils\.getExtension|\.lastIndexOf\(['"]\.['"]\)|ALLOWED_EXT|ALLOWED_EXTENSIONS|allowedExtensions|\bfileFilter\b|filepath\.Ext|path\.extname)/;
42943
- function lineWindow(code, startLine, endLine) {
42944
- const lines = code.split("\n");
43013
+ function lineWindow(lines, startLine, endLine) {
42945
43014
  const s = Math.max(0, startLine - 1);
42946
43015
  const e = Math.min(lines.length, endLine);
42947
43016
  return lines.slice(s, e).join("\n");
@@ -42961,10 +43030,11 @@ var UnrestrictedFileUploadPass = class {
42961
43030
  const { graph, language, code } = ctx;
42962
43031
  const file = graph.ir.meta.file;
42963
43032
  const findings = [];
43033
+ const codeLines = code.split("\n");
42964
43034
  const safeFunctionRanges = [];
42965
43035
  for (const t of graph.ir.types) {
42966
43036
  for (const m of t.methods) {
42967
- const body2 = lineWindow(code, m.start_line, m.end_line);
43037
+ const body2 = lineWindow(codeLines, m.start_line, m.end_line);
42968
43038
  if (FILE_SAFE_CALL_RE.test(body2)) {
42969
43039
  safeFunctionRanges.push({ start: m.start_line, end: m.end_line });
42970
43040
  }
@@ -42974,7 +43044,7 @@ var UnrestrictedFileUploadPass = class {
42974
43044
  for (const r of safeFunctionRanges) {
42975
43045
  if (line >= r.start && line <= r.end) return true;
42976
43046
  }
42977
- const win = lineWindow(code, Math.max(1, line - 20), line + 5);
43047
+ const win = lineWindow(codeLines, Math.max(1, line - 20), line + 5);
42978
43048
  return FILE_SAFE_CALL_RE.test(win);
42979
43049
  };
42980
43050
  if (language === "java") {
@@ -9964,15 +9964,15 @@ function computeChains(defs, uses) {
9964
9964
  existing.push(use);
9965
9965
  usesByLine.set(use.line, existing);
9966
9966
  }
9967
+ const seenChains = /* @__PURE__ */ new Set();
9967
9968
  for (const def of defs) {
9968
9969
  if (def.kind === "local") {
9969
9970
  const usesOnLine = usesByLine.get(def.line) ?? [];
9970
9971
  for (const use of usesOnLine) {
9971
9972
  if (use.def_id !== null && use.def_id !== def.id) {
9972
- const exists = chains.some(
9973
- (c) => c.from_def === use.def_id && c.to_def === def.id && c.via === use.variable
9974
- );
9975
- if (!exists) {
9973
+ const key = `${use.def_id}\0${def.id}\0${use.variable}`;
9974
+ if (!seenChains.has(key)) {
9975
+ seenChains.add(key);
9976
9976
  chains.push({
9977
9977
  from_def: use.def_id,
9978
9978
  to_def: def.id,
@@ -11896,8 +11896,11 @@ var DEFAULT_SINKS = [
11896
11896
  // SAX handler sinks (can lead to XSS in parsed content)
11897
11897
  { method: "startElement", class: "ContentHandler", type: "xss", cwe: "CWE-79", severity: "high", arg_positions: [0, 1, 2] },
11898
11898
  { method: "characters", class: "ContentHandler", type: "xss", cwe: "CWE-79", severity: "high", arg_positions: [0] },
11899
- // Template output sinks
11900
- { method: "output", type: "xss", cwe: "CWE-79", severity: "high", arg_positions: [0] },
11899
+ // Template output sinks. `output` is classless (Java template engines /
11900
+ // Velocity), but Rust `std::process::Command::…output()` is process
11901
+ // execution, not HTML — it already fires the CWE-78 command_injection sink,
11902
+ // so exclude Rust here to drop the spurious xss (cognium-dev#146).
11903
+ { method: "output", type: "xss", cwe: "CWE-79", severity: "high", arg_positions: [0], exclude_languages: ["rust"] },
11901
11904
  { method: "setOutput", type: "xss", cwe: "CWE-79", severity: "high", arg_positions: [0] },
11902
11905
  { method: "writeAttribute", type: "xss", cwe: "CWE-79", severity: "high", arg_positions: [0, 1] },
11903
11906
  // AntiSamy specific (SAX filters)
@@ -9898,15 +9898,15 @@ function computeChains(defs, uses) {
9898
9898
  existing.push(use);
9899
9899
  usesByLine.set(use.line, existing);
9900
9900
  }
9901
+ const seenChains = /* @__PURE__ */ new Set();
9901
9902
  for (const def of defs) {
9902
9903
  if (def.kind === "local") {
9903
9904
  const usesOnLine = usesByLine.get(def.line) ?? [];
9904
9905
  for (const use of usesOnLine) {
9905
9906
  if (use.def_id !== null && use.def_id !== def.id) {
9906
- const exists = chains.some(
9907
- (c) => c.from_def === use.def_id && c.to_def === def.id && c.via === use.variable
9908
- );
9909
- if (!exists) {
9907
+ const key = `${use.def_id}\0${def.id}\0${use.variable}`;
9908
+ if (!seenChains.has(key)) {
9909
+ seenChains.add(key);
9910
9910
  chains.push({
9911
9911
  from_def: use.def_id,
9912
9912
  to_def: def.id,
@@ -11830,8 +11830,11 @@ var DEFAULT_SINKS = [
11830
11830
  // SAX handler sinks (can lead to XSS in parsed content)
11831
11831
  { method: "startElement", class: "ContentHandler", type: "xss", cwe: "CWE-79", severity: "high", arg_positions: [0, 1, 2] },
11832
11832
  { method: "characters", class: "ContentHandler", type: "xss", cwe: "CWE-79", severity: "high", arg_positions: [0] },
11833
- // Template output sinks
11834
- { method: "output", type: "xss", cwe: "CWE-79", severity: "high", arg_positions: [0] },
11833
+ // Template output sinks. `output` is classless (Java template engines /
11834
+ // Velocity), but Rust `std::process::Command::…output()` is process
11835
+ // execution, not HTML — it already fires the CWE-78 command_injection sink,
11836
+ // so exclude Rust here to drop the spurious xss (cognium-dev#146).
11837
+ { method: "output", type: "xss", cwe: "CWE-79", severity: "high", arg_positions: [0], exclude_languages: ["rust"] },
11835
11838
  { method: "setOutput", type: "xss", cwe: "CWE-79", severity: "high", arg_positions: [0] },
11836
11839
  { method: "writeAttribute", type: "xss", cwe: "CWE-79", severity: "high", arg_positions: [0, 1] },
11837
11840
  // AntiSamy specific (SAX filters)
@@ -1014,15 +1014,18 @@ function computeChains(defs, uses) {
1014
1014
  }
1015
1015
  // For each definition, find uses on the same line that might be in its initializer
1016
1016
  // This is a heuristic - more precise would require tracking def-use relationships in AST
1017
+ // Dedup via a Set keyed on (from_def, to_def, via) — an `Array.some` scan per
1018
+ // insertion was O(chains²) on large files (cognium-ai#305).
1019
+ const seenChains = new Set();
1017
1020
  for (const def of defs) {
1018
1021
  if (def.kind === 'local') {
1019
1022
  const usesOnLine = usesByLine.get(def.line) ?? [];
1020
1023
  for (const use of usesOnLine) {
1021
1024
  // If this use has a reaching def, create a chain
1022
1025
  if (use.def_id !== null && use.def_id !== def.id) {
1023
- // Avoid duplicate chains
1024
- const exists = chains.some(c => c.from_def === use.def_id && c.to_def === def.id && c.via === use.variable);
1025
- if (!exists) {
1026
+ const key = `${use.def_id}${def.id}${use.variable}`;
1027
+ if (!seenChains.has(key)) {
1028
+ seenChains.add(key);
1026
1029
  chains.push({
1027
1030
  from_def: use.def_id,
1028
1031
  to_def: def.id,