cognium-dev 4.9.11 → 4.9.13

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.js +252 -45
  2. package/package.json +2 -2
package/dist/cli.js CHANGED
@@ -5,7 +5,7 @@ var __require = /* @__PURE__ */ createRequire(import.meta.url);
5
5
  // src/cli.ts
6
6
  import { readFileSync, existsSync, writeFileSync } from "fs";
7
7
  import { stat as stat2, readdir as readdir2 } from "fs/promises";
8
- import { join as join2, dirname as dirname2, extname, resolve, relative as relative3, basename } from "path";
8
+ import { join as join2, dirname as dirname3, extname, resolve as resolve2, relative as relative4, basename } from "path";
9
9
  import { createRequire as createRequire2 } from "module";
10
10
 
11
11
  // ../../node_modules/web-tree-sitter/web-tree-sitter.js
@@ -13192,6 +13192,22 @@ var PYTHON_TAINTED_PATTERNS = [
13192
13192
  { pattern: /\brequest\.path_params\b/, sourceType: "http_param" },
13193
13193
  { pattern: /\binput\s*\(/, sourceType: "io_input" }
13194
13194
  ];
13195
+ function dropCSharpObjectCarriedWaypoints(sinks, calls) {
13196
+ const zeroArgCtors = new Set;
13197
+ for (const call of calls) {
13198
+ if (call.is_constructor && call.arguments.length === 0) {
13199
+ zeroArgCtors.add(`${call.location.line}:${call.method_name}`);
13200
+ }
13201
+ }
13202
+ return sinks.filter((sink) => {
13203
+ if (sink.type !== "sql_injection")
13204
+ return true;
13205
+ if (sink.method && zeroArgCtors.has(`${sink.line}:${sink.method}`)) {
13206
+ return false;
13207
+ }
13208
+ return true;
13209
+ });
13210
+ }
13195
13211
  function analyzeTaint(calls, types, config = getDefaultConfig(), typeHierarchy, language, code) {
13196
13212
  const sourceLines = code !== undefined ? code.split(`
13197
13213
  `) : undefined;
@@ -13199,8 +13215,9 @@ function analyzeTaint(calls, types, config = getDefaultConfig(), typeHierarchy,
13199
13215
  let sinkPatterns = expandPromisifyAliases(config.sinks, sourceLines, language);
13200
13216
  sinkPatterns = expandIndirectEvalAliases(sinkPatterns, sourceLines, language);
13201
13217
  const sinks = findSinks(calls, sinkPatterns, typeHierarchy, language, sourceLines, types);
13218
+ const gatedSinks = language === "csharp" ? dropCSharpObjectCarriedWaypoints(sinks, calls) : sinks;
13202
13219
  const sanitizers = findSanitizers(calls, types, config.sanitizers, sourceLines);
13203
- return { sources, sinks, sanitizers };
13220
+ return { sources, sinks: gatedSinks, sanitizers };
13204
13221
  }
13205
13222
  function sinkPatternAppliesTo(pattern, language) {
13206
13223
  if (language === undefined)
@@ -13485,7 +13502,7 @@ function findSources(calls, types, patterns, sourceLines, language) {
13485
13502
  }
13486
13503
  const sourceMap = new Map;
13487
13504
  for (const source of sources) {
13488
- const key = `${source.line}:${source.type}`;
13505
+ const key = source.type === "interprocedural_param" && source.variable ? `${source.line}:${source.type}:${source.variable}` : `${source.line}:${source.type}`;
13489
13506
  const existing = sourceMap.get(key);
13490
13507
  if (!existing || source.confidence > existing.confidence) {
13491
13508
  sourceMap.set(key, source);
@@ -14163,6 +14180,19 @@ var CWE_78_RECEIVER_ALLOWLIST = new Set([
14163
14180
  "ProcessExecutor",
14164
14181
  "RuntimeUtil"
14165
14182
  ]);
14183
+ function isRegexReceiver(receiver, sourceLines) {
14184
+ const r = (receiver ?? "").trim();
14185
+ if (r.length === 0)
14186
+ return false;
14187
+ if (r.startsWith("/") && /\/[a-z]*$/.test(r))
14188
+ return true;
14189
+ if (/^(?:new\s+)?RegExp\s*\(/.test(r))
14190
+ return true;
14191
+ if (!/^[A-Za-z_$][\w$]*$/.test(r) || !sourceLines)
14192
+ return false;
14193
+ const decl = new RegExp(`(?:const|let|var)\\s+${escapeRe(r)}\\s*=\\s*(?:/|(?:new\\s+)?RegExp\\s*\\()`);
14194
+ return sourceLines.some((l) => decl.test(l));
14195
+ }
14166
14196
  function isFunctionCallbackArgument(arg) {
14167
14197
  if (arg.literal !== null && arg.literal !== undefined)
14168
14198
  return false;
@@ -14370,6 +14400,12 @@ function findSinks(calls, patterns, typeHierarchy, language, sourceLines, types)
14370
14400
  continue;
14371
14401
  }
14372
14402
  }
14403
+ if (pattern.type === "command_injection" && call.method_name === "exec" && (language === "javascript" || language === "typescript") && isRegexReceiver(call.receiver, sourceLines)) {
14404
+ continue;
14405
+ }
14406
+ if (pattern.type === "code_injection" && language === "python" && call.method_name === "compile" && call.receiver && call.receiver !== "builtins") {
14407
+ continue;
14408
+ }
14373
14409
  if (isSafeGoJsonUnmarshalCall(call, pattern, language, sourceLines)) {
14374
14410
  continue;
14375
14411
  }
@@ -17887,6 +17923,9 @@ function findInitialTaint(sources, callsByLine, defsByLine) {
17887
17923
  for (const source of sources) {
17888
17924
  const defsOnLine = defsByLine.get(source.line) ?? [];
17889
17925
  for (const def of defsOnLine) {
17926
+ if (source.type === "interprocedural_param" && source.variable && def.kind === "param" && def.variable !== source.variable) {
17927
+ continue;
17928
+ }
17890
17929
  tainted.push({
17891
17930
  variable: def.variable,
17892
17931
  defId: def.id,
@@ -35817,7 +35856,7 @@ class TaintPropagationPass {
35817
35856
  for (const f of paramFlows) {
35818
35857
  pushIfNew(f);
35819
35858
  }
35820
- const exprScanFlows = detectExpressionScanFlows(calls, sources, sinks, sanitizers, constProp.unreachableLines, constProp.tainted, ctx.code, ctx.language) ?? [];
35859
+ const exprScanFlows = detectExpressionScanFlows(calls, sources, sinks, sanitizers, constProp.unreachableLines, constProp.tainted, ctx.code, ctx.language, types) ?? [];
35821
35860
  for (const f of exprScanFlows) {
35822
35861
  if (flowKeys.has(flowKey(f)))
35823
35862
  continue;
@@ -35981,6 +36020,35 @@ class TaintPropagationPass {
35981
36020
  return bestByKey.get(key) === f;
35982
36021
  });
35983
36022
  }
36023
+ if (ctx.language === "csharp" && finalFlows.length > 1) {
36024
+ const CSHARP_ADO_EXECUTE = /^Execute(?:Reader|NonQuery|Scalar)(?:Async)?$/;
36025
+ const commandTextReceiverByLine = new Map;
36026
+ const execLinesByReceiver = new Map;
36027
+ for (const call of calls) {
36028
+ const receiver = (call.receiver ?? "").trim();
36029
+ if (!receiver)
36030
+ continue;
36031
+ if (call.method_name === "CommandText") {
36032
+ commandTextReceiverByLine.set(call.location.line, receiver);
36033
+ } else if (CSHARP_ADO_EXECUTE.test(call.method_name)) {
36034
+ const lines = execLinesByReceiver.get(receiver) ?? [];
36035
+ lines.push(call.location.line);
36036
+ execLinesByReceiver.set(receiver, lines);
36037
+ }
36038
+ }
36039
+ if (commandTextReceiverByLine.size > 0) {
36040
+ const reportedSqlSinkLines = new Set(finalFlows.filter((f) => f.sink_type === "sql_injection").map((f) => f.sink_line));
36041
+ finalFlows = finalFlows.filter((f) => {
36042
+ if (f.sink_type !== "sql_injection")
36043
+ return true;
36044
+ const receiver = commandTextReceiverByLine.get(f.sink_line);
36045
+ if (receiver === undefined)
36046
+ return true;
36047
+ const execLines = execLinesByReceiver.get(receiver) ?? [];
36048
+ return !execLines.some((line) => line > f.sink_line && reportedSqlSinkLines.has(line));
36049
+ });
36050
+ }
36051
+ }
35984
36052
  return { flows: finalFlows };
35985
36053
  }
35986
36054
  }
@@ -36447,7 +36515,7 @@ function isReassignedToLiteralBetween(code, variable, srcLine, sinkLine) {
36447
36515
  }
36448
36516
  return false;
36449
36517
  }
36450
- function detectExpressionScanFlows(calls, sources, sinks, sanitizers, unreachableLines, tainted, code, language) {
36518
+ function detectExpressionScanFlows(calls, sources, sinks, sanitizers, unreachableLines, tainted, code, language, types) {
36451
36519
  const flows = [];
36452
36520
  const sourcesWithVar = sources.filter((s) => typeof s.variable === "string" && s.variable.length > 0);
36453
36521
  const aliasSanitizedFor = new Map;
@@ -36730,13 +36798,37 @@ function detectExpressionScanFlows(calls, sources, sinks, sanitizers, unreachabl
36730
36798
  if (s.line < anchor.line)
36731
36799
  anchor = s;
36732
36800
  }
36801
+ const methodAt = (line) => {
36802
+ for (const t of types ?? []) {
36803
+ for (const m of t.methods) {
36804
+ if (line >= m.start_line && line <= m.end_line)
36805
+ return m.name;
36806
+ }
36807
+ }
36808
+ return null;
36809
+ };
36733
36810
  const existingVars = new Set(sourcesWithVar.map((s) => s.variable));
36734
- for (const [varName] of derived) {
36811
+ for (const [varName, derivedLine] of derived) {
36735
36812
  if (!varName || existingVars.has(varName))
36736
36813
  continue;
36814
+ const owner = methodAt(derivedLine);
36815
+ let scopedAnchor = anchor;
36816
+ if (owner) {
36817
+ let best;
36818
+ for (const s of sourcesWithVar) {
36819
+ const sOwner = s.in_method ?? methodAt(s.line);
36820
+ if (sOwner !== owner)
36821
+ continue;
36822
+ if (!best || s.line < best.line)
36823
+ best = s;
36824
+ }
36825
+ if (best)
36826
+ scopedAnchor = best;
36827
+ }
36737
36828
  sourcesWithVar.push({
36738
- ...anchor,
36739
- variable: varName
36829
+ ...scopedAnchor,
36830
+ variable: varName,
36831
+ ...owner ? { in_method: owner } : {}
36740
36832
  });
36741
36833
  existingVars.add(varName);
36742
36834
  }
@@ -48298,14 +48390,14 @@ function toSpdx(deps, meta = {}) {
48298
48390
  relationships
48299
48391
  };
48300
48392
  }
48301
- // node_modules/@cognium/project-profile-detect/dist/index.js
48302
- import { relative as relative2 } from "path";
48393
+ // ../project-profile-detect/dist/index.js
48394
+ import { relative as relative3 } from "path";
48303
48395
 
48304
- // node_modules/@cognium/project-profile-detect/dist/walk.js
48396
+ // ../project-profile-detect/dist/walk.js
48305
48397
  import { readdir, readFile, stat } from "fs/promises";
48306
- import { join, relative } from "path";
48398
+ import { join, relative as relative2 } from "path";
48307
48399
 
48308
- // node_modules/@cognium/project-profile-detect/dist/maven-parse.js
48400
+ // ../project-profile-detect/dist/maven-parse.js
48309
48401
  var TAG = (name2) => new RegExp(`<${name2}\\b[^>]*>([\\s\\S]*?)<\\/${name2}>`, "i");
48310
48402
  var ALL_TAGS = (name2) => new RegExp(`<${name2}\\b[^>]*>([\\s\\S]*?)<\\/${name2}>`, "gi");
48311
48403
  function firstTag(xml, name2) {
@@ -48329,7 +48421,12 @@ var MAVEN_PLUGIN_MAP = {
48329
48421
  "exec-maven-plugin": "application",
48330
48422
  "maven-assembly-plugin": "application"
48331
48423
  };
48424
+ var MAVEN_PUBLISH_PLUGIN_URLS = {
48425
+ "central-publishing-maven-plugin": "https://central.sonatype.com/",
48426
+ "nexus-staging-maven-plugin": "https://oss.sonatype.org/"
48427
+ };
48332
48428
  function parseMavenPom(xml, moduleRoot, buildFile, directorySignals) {
48429
+ const parentRef = extractParentRef(xml);
48333
48430
  const stripped = xml.replace(/<parent\b[\s\S]*?<\/parent>/i, "");
48334
48431
  const groupId = firstTag(stripped, "groupId");
48335
48432
  const artifactId = firstTag(stripped, "artifactId");
@@ -48338,10 +48435,15 @@ function parseMavenPom(xml, moduleRoot, buildFile, directorySignals) {
48338
48435
  const buildBlock = firstTag(xml, "build") ?? "";
48339
48436
  const pluginBlocks = allTags(buildBlock, "plugin");
48340
48437
  const plugins = new Set;
48438
+ const publishUrls = new Set;
48341
48439
  for (const p of pluginBlocks) {
48342
48440
  const aid = firstTag(p, "artifactId");
48343
- if (aid && MAVEN_PLUGIN_MAP[aid])
48441
+ if (!aid)
48442
+ continue;
48443
+ if (MAVEN_PLUGIN_MAP[aid])
48344
48444
  plugins.add(MAVEN_PLUGIN_MAP[aid]);
48445
+ if (MAVEN_PUBLISH_PLUGIN_URLS[aid])
48446
+ publishUrls.add(MAVEN_PUBLISH_PLUGIN_URLS[aid]);
48345
48447
  }
48346
48448
  if (/<parent\b[\s\S]*?<artifactId>\s*spring-boot-starter-parent\s*<\/artifactId>/i.test(xml)) {
48347
48449
  plugins.add("spring-boot");
@@ -48354,7 +48456,8 @@ function parseMavenPom(xml, moduleRoot, buildFile, directorySignals) {
48354
48456
  plugins.add("maven-plugin");
48355
48457
  const distBlock = firstTag(xml, "distributionManagement") ?? "";
48356
48458
  const urls = [
48357
- ...allTags(distBlock, "url")
48459
+ ...allTags(distBlock, "url"),
48460
+ ...publishUrls
48358
48461
  ].map((u) => u.trim()).filter(Boolean);
48359
48462
  const signals = {
48360
48463
  ...directorySignals,
@@ -48369,11 +48472,36 @@ function parseMavenPom(xml, moduleRoot, buildFile, directorySignals) {
48369
48472
  groupId,
48370
48473
  artifactId,
48371
48474
  version,
48372
- signals
48475
+ signals,
48476
+ parentRef
48373
48477
  };
48374
48478
  }
48479
+ function extractParentRef(xml) {
48480
+ const block = TAG("parent").exec(xml);
48481
+ if (!block)
48482
+ return;
48483
+ const inner = block[1];
48484
+ const groupId = firstTag(inner, "groupId");
48485
+ const artifactId = firstTag(inner, "artifactId");
48486
+ const version = firstTag(inner, "version");
48487
+ let relativePath;
48488
+ let emptyRelativePath = false;
48489
+ const selfClosing = /<relativePath\b[^>]*\/\s*>/i.test(inner);
48490
+ if (selfClosing) {
48491
+ emptyRelativePath = true;
48492
+ } else {
48493
+ const rp = firstTag(inner, "relativePath");
48494
+ if (rp !== undefined) {
48495
+ if (rp.length === 0)
48496
+ emptyRelativePath = true;
48497
+ else
48498
+ relativePath = rp;
48499
+ }
48500
+ }
48501
+ return { groupId, artifactId, version, relativePath, emptyRelativePath };
48502
+ }
48375
48503
 
48376
- // node_modules/@cognium/project-profile-detect/dist/gradle-parse.js
48504
+ // ../project-profile-detect/dist/gradle-parse.js
48377
48505
  var GRADLE_PLUGIN_MAP = {
48378
48506
  "org.springframework.boot": "spring-boot",
48379
48507
  "io.spring.dependency-management": "spring-boot",
@@ -48438,7 +48566,81 @@ function parseGradleBuild(text, moduleRoot, buildFile, buildSystem, directorySig
48438
48566
  };
48439
48567
  }
48440
48568
 
48441
- // node_modules/@cognium/project-profile-detect/dist/walk.js
48569
+ // ../project-profile-detect/dist/maven-inherit.js
48570
+ import { dirname as dirname2, isAbsolute, normalize, relative, resolve } from "path";
48571
+ var MAX_DEPTH = 6;
48572
+ var DEFAULT_RELATIVE_PATH = "../pom.xml";
48573
+ function mergeMavenInheritance(modules, scanRoot) {
48574
+ const normalizedScanRoot = normalize(scanRoot);
48575
+ const byBuildFile = new Map;
48576
+ for (const m of modules) {
48577
+ if (m.buildSystem === "maven") {
48578
+ byBuildFile.set(normalize(m.buildFile), m);
48579
+ }
48580
+ }
48581
+ const ownSignals = new Map;
48582
+ for (const [buildFile, m] of byBuildFile) {
48583
+ ownSignals.set(buildFile, {
48584
+ urls: [...m.signals.distributionUrls],
48585
+ plugins: [...m.signals.plugins]
48586
+ });
48587
+ }
48588
+ for (const child of modules) {
48589
+ if (child.buildSystem !== "maven")
48590
+ continue;
48591
+ if (!child.parentRef)
48592
+ continue;
48593
+ const inheritedUrls = new Set;
48594
+ const inheritedPlugins = new Set;
48595
+ walkParents(child, byBuildFile, ownSignals, normalizedScanRoot, inheritedUrls, inheritedPlugins);
48596
+ if (inheritedUrls.size === 0 && inheritedPlugins.size === 0)
48597
+ continue;
48598
+ const existingUrls = new Set(child.signals.distributionUrls);
48599
+ for (const u of inheritedUrls) {
48600
+ if (!existingUrls.has(u))
48601
+ child.signals.distributionUrls.push(u);
48602
+ }
48603
+ const existingPlugins = new Set(child.signals.plugins);
48604
+ for (const p of inheritedPlugins) {
48605
+ if (!existingPlugins.has(p))
48606
+ child.signals.plugins.push(p);
48607
+ }
48608
+ }
48609
+ }
48610
+ function walkParents(start2, byBuildFile, ownSignals, scanRoot, outUrls, outPlugins) {
48611
+ const visited = new Set([normalize(start2.buildFile)]);
48612
+ let current = start2;
48613
+ for (let depth = 0;depth < MAX_DEPTH; depth++) {
48614
+ const ref = current.parentRef;
48615
+ if (!ref)
48616
+ return;
48617
+ if (ref.emptyRelativePath)
48618
+ return;
48619
+ const childDir = dirname2(current.buildFile);
48620
+ const rel = ref.relativePath ?? DEFAULT_RELATIVE_PATH;
48621
+ const candidateAbs = normalize(isAbsolute(rel) ? rel : resolve(childDir, rel));
48622
+ const parentBuildFile = candidateAbs.endsWith("pom.xml") ? candidateAbs : normalize(resolve(candidateAbs, "pom.xml"));
48623
+ const relToRoot = relative(scanRoot, parentBuildFile);
48624
+ if (relToRoot.startsWith("..") || isAbsolute(relToRoot))
48625
+ return;
48626
+ if (visited.has(parentBuildFile))
48627
+ return;
48628
+ visited.add(parentBuildFile);
48629
+ const parent = byBuildFile.get(parentBuildFile);
48630
+ if (!parent)
48631
+ return;
48632
+ const parentOwn = ownSignals.get(parentBuildFile);
48633
+ if (parentOwn) {
48634
+ for (const u of parentOwn.urls)
48635
+ outUrls.add(u);
48636
+ for (const p of parentOwn.plugins)
48637
+ outPlugins.add(p);
48638
+ }
48639
+ current = parent;
48640
+ }
48641
+ }
48642
+
48643
+ // ../project-profile-detect/dist/walk.js
48442
48644
  var BUILD_FILES = ["pom.xml", "build.gradle", "build.gradle.kts"];
48443
48645
  var SKIP_DIRS = new Set([
48444
48646
  "node_modules",
@@ -48458,6 +48660,7 @@ var SKIP_DIRS = new Set([
48458
48660
  async function discoverBuildModules(scanRoot) {
48459
48661
  const modules = [];
48460
48662
  await walk(scanRoot, modules);
48663
+ mergeMavenInheritance(modules, scanRoot);
48461
48664
  return modules;
48462
48665
  }
48463
48666
  async function walk(dir, out2) {
@@ -48599,7 +48802,7 @@ function ownerOf(file, modules) {
48599
48802
  return best;
48600
48803
  }
48601
48804
 
48602
- // node_modules/@cognium/project-profile-detect/dist/publication-detect.js
48805
+ // ../project-profile-detect/dist/publication-detect.js
48603
48806
  var PUBLIC_REGISTRY_HOSTS = new Set([
48604
48807
  "repo.maven.apache.org",
48605
48808
  "repo1.maven.org",
@@ -48624,7 +48827,7 @@ function isPubliclyPublished(urls) {
48624
48827
  return false;
48625
48828
  }
48626
48829
 
48627
- // node_modules/@cognium/project-profile-detect/dist/shape-resolve.js
48830
+ // ../project-profile-detect/dist/shape-resolve.js
48628
48831
  function resolveShape(mod) {
48629
48832
  const sig = mod.signals;
48630
48833
  const has = (tag) => sig.plugins.includes(tag);
@@ -48665,11 +48868,15 @@ function resolveShape(mod) {
48665
48868
  reasons.push(...libSignals, "no public-registry distribution (internal helper)");
48666
48869
  return { shape: "application", reasons };
48667
48870
  }
48871
+ if (isPubliclyPublished(sig.distributionUrls)) {
48872
+ reasons.push("public-registry distribution", "no application/server/plugin signals → implicit library");
48873
+ return { shape: "library", reasons };
48874
+ }
48668
48875
  reasons.push("no shape signals");
48669
48876
  return { shape: "unknown", reasons };
48670
48877
  }
48671
48878
 
48672
- // node_modules/@cognium/project-profile-detect/dist/env-resolve.js
48879
+ // ../project-profile-detect/dist/env-resolve.js
48673
48880
  var TEST_RE = /(?:^|\/)tests?\//;
48674
48881
  var SAMPLE_RE = /(?:^|\/)(?:samples?|examples?|demos?|fixtures?)\//;
48675
48882
  var BENCHMARK_RE = /(?:^|\/)benchmarks?\//;
@@ -48687,7 +48894,7 @@ function resolveEnv(absoluteFile) {
48687
48894
  return "dev";
48688
48895
  }
48689
48896
 
48690
- // node_modules/@cognium/project-profile-detect/dist/overrides.js
48897
+ // ../project-profile-detect/dist/overrides.js
48691
48898
  function compileGlob(glob) {
48692
48899
  let re = "";
48693
48900
  let i2 = 0;
@@ -48734,7 +48941,7 @@ function applyOverrides(relativePath, compiled) {
48734
48941
  return;
48735
48942
  }
48736
48943
 
48737
- // node_modules/@cognium/project-profile-detect/dist/index.js
48944
+ // ../project-profile-detect/dist/index.js
48738
48945
  async function detectProjectProfiles(scanRoot, options = {}) {
48739
48946
  const modules = await discoverBuildModules(scanRoot);
48740
48947
  const files = await enumerateScanFiles(scanRoot);
@@ -48752,7 +48959,7 @@ async function detectProjectProfiles(scanRoot, options = {}) {
48752
48959
  const profileByFile = new Map;
48753
48960
  const unknownFiles = [];
48754
48961
  for (const file of files) {
48755
- const rel = relative2(scanRoot, file);
48962
+ const rel = relative3(scanRoot, file);
48756
48963
  const ov = applyOverrides(rel, compiledOverrides);
48757
48964
  if (ov) {
48758
48965
  profileByFile.set(file, ov.profile);
@@ -48804,7 +49011,7 @@ var colors = {
48804
49011
  };
48805
49012
 
48806
49013
  // src/version.ts
48807
- var version = "4.9.11";
49014
+ var version = "4.9.13";
48808
49015
 
48809
49016
  // src/formatters.ts
48810
49017
  var LIBRARY_API_SURFACE_TAG2 = "library-api-surface:caller-responsibility";
@@ -49357,8 +49564,8 @@ function generateSarifResults(results, crossFileData) {
49357
49564
 
49358
49565
  // src/build-info.ts
49359
49566
  var buildInfo = {
49360
- gitSha: "6c811aa",
49361
- builtAt: "2026-09-10T06:22:49.258Z"
49567
+ gitSha: "c7e3f20",
49568
+ builtAt: "2026-09-11T05:41:41.484Z"
49362
49569
  };
49363
49570
 
49364
49571
  // src/utils/args.ts
@@ -49646,7 +49853,7 @@ function applySuppressionsToResults(results, suppressions, basePath) {
49646
49853
  if (suppressions.length === 0)
49647
49854
  return results;
49648
49855
  return results.map((result) => {
49649
- const relativeFile = relative3(basePath, result.file) || result.file;
49856
+ const relativeFile = relative4(basePath, result.file) || result.file;
49650
49857
  const filteredVulns = result.vulnerabilities.filter((vuln) => {
49651
49858
  for (const supp of suppressions) {
49652
49859
  if (supp.pass !== vuln.type)
@@ -49752,7 +49959,7 @@ async function collectFiles(targetPath, options = {}) {
49752
49959
  return files;
49753
49960
  }
49754
49961
  if (fileMatchesLanguage(targetPath, language)) {
49755
- const relativePath = basePath ? relative3(basePath, targetPath) : targetPath;
49962
+ const relativePath = basePath ? relative4(basePath, targetPath) : targetPath;
49756
49963
  if (includePatterns && includePatterns.length > 0) {
49757
49964
  if (!matchesAnyPattern(relativePath, includePatterns)) {
49758
49965
  return files;
@@ -49771,7 +49978,7 @@ async function collectFiles(targetPath, options = {}) {
49771
49978
  if (excludeTests && /^(test|tests|__tests__|spec|__mocks__)$/i.test(entry.name))
49772
49979
  continue;
49773
49980
  const fullPath = join2(targetPath, entry.name);
49774
- const relativePath = basePath ? relative3(basePath, fullPath) : fullPath;
49981
+ const relativePath = basePath ? relative4(basePath, fullPath) : fullPath;
49775
49982
  if (excludePatterns && entry.isDirectory()) {
49776
49983
  const dirPattern = relativePath + "/";
49777
49984
  if (excludePatterns.some((p) => matchesGlob(dirPattern, p) || matchesGlob(relativePath, p))) {
@@ -49869,14 +50076,14 @@ async function scanProject(files, language, analyzeOpts, crossFileBudgetMs) {
49869
50076
  async function initWasm(spin) {
49870
50077
  const isStandalone = import.meta.url.includes("/$bunfs/");
49871
50078
  if (isStandalone) {
49872
- const { dirname: dirname3, join: join3 } = await import("path");
49873
- const binaryDir = dirname3(process.execPath);
50079
+ const { dirname: dirname4, join: join3 } = await import("path");
50080
+ const binaryDir = dirname4(process.execPath);
49874
50081
  const cwd = process.cwd();
49875
50082
  let scriptDir = null;
49876
50083
  if (!import.meta.url.includes("/$bunfs/")) {
49877
50084
  try {
49878
50085
  const { fileURLToPath } = await import("url");
49879
- scriptDir = dirname3(fileURLToPath(import.meta.url));
50086
+ scriptDir = dirname4(fileURLToPath(import.meta.url));
49880
50087
  } catch {}
49881
50088
  }
49882
50089
  const wasmLocations = [
@@ -49931,7 +50138,7 @@ Please ensure the wasm/ directory is located next to the binary or in your curre
49931
50138
  } else {
49932
50139
  const require2 = createRequire2(import.meta.url);
49933
50140
  const circleIrPkg = require2.resolve("circle-ir/package.json");
49934
- const wasmBasePath = join2(dirname2(circleIrPkg), "dist", "wasm") + "/";
50141
+ const wasmBasePath = join2(dirname3(circleIrPkg), "dist", "wasm") + "/";
49935
50142
  await initAnalyzer({
49936
50143
  wasmPath: wasmBasePath + "web-tree-sitter.wasm",
49937
50144
  languagePaths: {
@@ -49962,7 +50169,7 @@ function buildProfileSummary(scanRoot, modules, resolvedProfiles) {
49962
50169
  return {
49963
50170
  scanRoot,
49964
50171
  modules: modules.map((m) => ({
49965
- root: relative3(scanRoot, m.module.root) || ".",
50172
+ root: relative4(scanRoot, m.module.root) || ".",
49966
50173
  profile: m.profile,
49967
50174
  reasons: m.reasons,
49968
50175
  buildSystem: m.module.buildSystem
@@ -49991,9 +50198,9 @@ function printProfileExplain(scanRoot, detection) {
49991
50198
  out2.push(" (no pom.xml, build.gradle, or build.gradle.kts found)");
49992
50199
  } else {
49993
50200
  for (const r of detection.modules) {
49994
- const rel = relative3(scanRoot, r.module.root) || ".";
50201
+ const rel = relative4(scanRoot, r.module.root) || ".";
49995
50202
  out2.push(` ${colors.cyan(rel || ".")} → ${colors.bold(r.profile)}`);
49996
- out2.push(` build: ${r.module.buildSystem} (${relative3(scanRoot, r.module.buildFile)})`);
50203
+ out2.push(` build: ${r.module.buildSystem} (${relative4(scanRoot, r.module.buildFile)})`);
49997
50204
  if (r.module.artifactId) {
49998
50205
  out2.push(` coords: ${r.module.groupId ?? "?"}:${r.module.artifactId}:${r.module.version ?? "?"}`);
49999
50206
  }
@@ -50038,7 +50245,7 @@ async function runScan(targetPath, options) {
50038
50245
  await initWasm(spin);
50039
50246
  if (spin)
50040
50247
  spin.text = "Collecting files...";
50041
- const absPath = resolve(targetPath);
50248
+ const absPath = resolve2(targetPath);
50042
50249
  if (!existsSync(absPath)) {
50043
50250
  if (spin)
50044
50251
  spin.fail(`Path not found: ${absPath}`);
@@ -50102,7 +50309,7 @@ async function runScan(targetPath, options) {
50102
50309
  results = [];
50103
50310
  let processed = 0;
50104
50311
  const formatCurrentFile = (file) => {
50105
- const rel = relative3(absPath, file) || file;
50312
+ const rel = relative4(absPath, file) || file;
50106
50313
  return rel.length > 80 ? `...${rel.slice(-77)}` : rel;
50107
50314
  };
50108
50315
  const concurrency = options.threads;
@@ -50278,7 +50485,7 @@ async function runMetrics(targetPath, options) {
50278
50485
  await initWasm(spin);
50279
50486
  if (spin)
50280
50487
  spin.text = "Collecting files...";
50281
- const absPath = resolve(targetPath);
50488
+ const absPath = resolve2(targetPath);
50282
50489
  if (!existsSync(absPath)) {
50283
50490
  if (spin)
50284
50491
  spin.fail(`Path not found: ${absPath}`);
@@ -50306,7 +50513,7 @@ async function runMetrics(targetPath, options) {
50306
50513
  continue;
50307
50514
  }
50308
50515
  if (spin) {
50309
- const rel = relative3(absPath, file) || file;
50516
+ const rel = relative4(absPath, file) || file;
50310
50517
  const maxLen = 80;
50311
50518
  const label = rel.length > maxLen ? `...${rel.slice(-(maxLen - 3))}` : rel;
50312
50519
  spin.text = `Analyzing ${label}... (${processed}/${totalFiles})`;
@@ -50351,7 +50558,7 @@ async function runMetrics(targetPath, options) {
50351
50558
  } else {
50352
50559
  const lines = [];
50353
50560
  for (const fm of filtered) {
50354
- const rel = relative3(absPath, fm.file) || fm.file;
50561
+ const rel = relative4(absPath, fm.file) || fm.file;
50355
50562
  lines.push(rel);
50356
50563
  const byCategory = new Map;
50357
50564
  for (const m of fm.metrics) {
@@ -50579,7 +50786,7 @@ async function collectManifestFiles(targetPath) {
50579
50786
  return found;
50580
50787
  }
50581
50788
  async function runSbom(targetPath, options) {
50582
- const absPath = resolve(targetPath);
50789
+ const absPath = resolve2(targetPath);
50583
50790
  if (!existsSync(absPath)) {
50584
50791
  console.error(colors.red(`Error: path not found: ${targetPath}`));
50585
50792
  process.exit(2);
@@ -50593,9 +50800,9 @@ async function runSbom(targetPath, options) {
50593
50800
  for (const m of manifests) {
50594
50801
  const superseded = SBOM_SUPERSEDES[basename(m)];
50595
50802
  if (superseded)
50596
- supersededInDir.add(`${dirname2(m)}\x00${superseded}`);
50803
+ supersededInDir.add(`${dirname3(m)}\x00${superseded}`);
50597
50804
  }
50598
- const effective = manifests.filter((m) => !supersededInDir.has(`${dirname2(m)}\x00${basename(m)}`));
50805
+ const effective = manifests.filter((m) => !supersededInDir.has(`${dirname3(m)}\x00${basename(m)}`));
50599
50806
  let projectName = options.name;
50600
50807
  let projectLicense;
50601
50808
  {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cognium-dev",
3
- "version": "4.9.11",
3
+ "version": "4.9.13",
4
4
  "description": "Static Application Security Testing CLI for detecting security vulnerabilities via taint tracking",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -66,7 +66,7 @@
66
66
  },
67
67
  "dependencies": {
68
68
  "@cognium/project-profile-detect": "1.1.1",
69
- "circle-ir": "4.9.11"
69
+ "circle-ir": "4.9.13"
70
70
  },
71
71
  "devDependencies": {
72
72
  "@types/node": "^25.5.0",