circle-ir 3.175.0 → 3.176.0

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.
@@ -12602,6 +12602,64 @@ function getDefaultConfig() {
12602
12602
  };
12603
12603
  }
12604
12604
 
12605
+ // src/analysis/arg-type-resolver.ts
12606
+ function findEnclosingType(callInMethod, types) {
12607
+ if (!callInMethod) return null;
12608
+ for (const t of types) {
12609
+ for (const m of t.methods) {
12610
+ if (m.name === callInMethod) return t;
12611
+ }
12612
+ }
12613
+ return null;
12614
+ }
12615
+ function resolveIdentifierType(name2, callInMethod, types) {
12616
+ if (!name2) return null;
12617
+ const enclosing = findEnclosingType(callInMethod, types);
12618
+ if (enclosing) {
12619
+ for (const m of enclosing.methods) {
12620
+ if (m.name !== callInMethod) continue;
12621
+ for (const p of m.parameters) {
12622
+ if (p.name === name2 && p.type) return p.type;
12623
+ }
12624
+ }
12625
+ for (const f of enclosing.fields) {
12626
+ if (f.name === name2 && f.type) return f.type;
12627
+ }
12628
+ return null;
12629
+ }
12630
+ for (const t of types) {
12631
+ for (const m of t.methods) {
12632
+ for (const p of m.parameters) {
12633
+ if (p.name === name2 && p.type) return p.type;
12634
+ }
12635
+ }
12636
+ for (const f of t.fields) {
12637
+ if (f.name === name2 && f.type) return f.type;
12638
+ }
12639
+ }
12640
+ return null;
12641
+ }
12642
+ function resolveCallReturnType(calleeName, callInMethod, types) {
12643
+ if (!calleeName) return null;
12644
+ const enclosing = findEnclosingType(callInMethod, types);
12645
+ if (enclosing) {
12646
+ for (const m of enclosing.methods) {
12647
+ if (m.name === calleeName && m.return_type) return m.return_type;
12648
+ }
12649
+ }
12650
+ for (const t of types) {
12651
+ for (const m of t.methods) {
12652
+ if (m.name === calleeName && m.return_type) return m.return_type;
12653
+ }
12654
+ }
12655
+ return null;
12656
+ }
12657
+ function isBoundedClassType(rawType) {
12658
+ if (!rawType) return false;
12659
+ const stripped = rawType.trim().replace(/^(?:java\.lang\.)+/, "");
12660
+ return /^Class(?:\s*<[\s\S]*>)?$/.test(stripped);
12661
+ }
12662
+
12605
12663
  // src/analysis/taint-matcher.ts
12606
12664
  var PYTHON_TAINTED_PATTERNS = [
12607
12665
  { pattern: /\brequest\.args\b/, sourceType: "http_param" },
@@ -12627,7 +12685,7 @@ function analyzeTaint(calls, types, config = getDefaultConfig(), typeHierarchy,
12627
12685
  const sources = findSources(calls, types, config.sources, sourceLines, language);
12628
12686
  let sinkPatterns = expandPromisifyAliases(config.sinks, sourceLines, language);
12629
12687
  sinkPatterns = expandIndirectEvalAliases(sinkPatterns, sourceLines, language);
12630
- const sinks = findSinks(calls, sinkPatterns, typeHierarchy, language, sourceLines);
12688
+ const sinks = findSinks(calls, sinkPatterns, typeHierarchy, language, sourceLines, types);
12631
12689
  const sanitizers = findSanitizers(calls, types, config.sanitizers, sourceLines);
12632
12690
  return { sources, sinks, sanitizers };
12633
12691
  }
@@ -13205,13 +13263,30 @@ function isSafeRustCommandCall(call, pattern, language) {
13205
13263
  return false;
13206
13264
  }
13207
13265
  var CLASS_LITERAL_RE = /^(?:[A-Za-z_][\w]*\.)*[A-Z][\w]*(?:\[\])*\.class$/;
13208
- function argIsClassLiteral(call, position) {
13266
+ function argIsClassLiteral(call, position, types) {
13209
13267
  const arg = call.arguments.find((a) => a.position === position);
13210
13268
  if (!arg) return false;
13211
13269
  const expr = (arg.literal ?? arg.expression ?? "").trim();
13212
13270
  if (!expr) return false;
13213
13271
  if (CLASS_LITERAL_RE.test(expr)) return true;
13214
- return TYPE_TOKEN_RE.test(expr);
13272
+ if (TYPE_TOKEN_RE.test(expr)) return true;
13273
+ if (!types || types.length === 0) return false;
13274
+ const argExpr = (arg.expression ?? "").trim();
13275
+ const varName = arg.variable ?? "";
13276
+ const isBareIdentifier = varName !== "" && argExpr === varName && !/[(.]/.test(argExpr);
13277
+ if (isBareIdentifier) {
13278
+ const t = resolveIdentifierType(varName, call.in_method, types);
13279
+ if (isBoundedClassType(t)) return true;
13280
+ }
13281
+ const isCallExpr = varName !== "" && new RegExp(`^${escapeRe(varName)}\\s*\\(`).test(argExpr);
13282
+ if (isCallExpr) {
13283
+ const t = resolveCallReturnType(varName, call.in_method, types);
13284
+ if (isBoundedClassType(t)) return true;
13285
+ }
13286
+ return false;
13287
+ }
13288
+ function escapeRe(s) {
13289
+ return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
13215
13290
  }
13216
13291
  var TYPE_TOKEN_RE = /^new\s+(?:TypeReference|TypeToken)\s*<[\s\S]*>\s*\(\s*\)\s*\{\s*\}$/;
13217
13292
  function argIsStringLiteral(call, position) {
@@ -13372,7 +13447,7 @@ function isSafeJinjaRenderCall(call, pattern, language, sourceLines) {
13372
13447
  }
13373
13448
  return false;
13374
13449
  }
13375
- function findSinks(calls, patterns, typeHierarchy, language, sourceLines) {
13450
+ function findSinks(calls, patterns, typeHierarchy, language, sourceLines, types) {
13376
13451
  const sinkMap = /* @__PURE__ */ new Map();
13377
13452
  for (const call of calls) {
13378
13453
  for (const pattern of patterns) {
@@ -13392,7 +13467,7 @@ function findSinks(calls, patterns, typeHierarchy, language, sourceLines) {
13392
13467
  if (isSafeJSChildProcessCall(call, pattern, language)) {
13393
13468
  continue;
13394
13469
  }
13395
- if (pattern.safe_if_class_literal_at !== void 0 && argIsClassLiteral(call, pattern.safe_if_class_literal_at)) {
13470
+ if (pattern.safe_if_class_literal_at !== void 0 && argIsClassLiteral(call, pattern.safe_if_class_literal_at, types)) {
13396
13471
  continue;
13397
13472
  }
13398
13473
  if (pattern.safe_if_string_literal_at !== void 0 && argIsStringLiteral(call, pattern.safe_if_string_literal_at)) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "circle-ir",
3
- "version": "3.175.0",
3
+ "version": "3.176.0",
4
4
  "description": "High-performance Static Application Security Testing (SAST) library for detecting security vulnerabilities through taint analysis",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.js",