@coana-tech/cli 14.12.106 → 14.12.107

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.
package/cli.mjs CHANGED
@@ -250700,10 +250700,11 @@ async function onlineScan(dependencyTree, apiKey, timeout) {
250700
250700
  }
250701
250701
 
250702
250702
  // dist/version.js
250703
- var version3 = "14.12.106";
250703
+ var version3 = "14.12.107";
250704
250704
 
250705
250705
  // dist/cli-core.js
250706
250706
  var { mapValues, omit, partition, pick } = import_lodash15.default;
250707
+ var bucketedAnalysisTimeoutInSeconds = 60;
250707
250708
  var SEVERITY_ORDER = {
250708
250709
  INFO: 0,
250709
250710
  LOW: 1,
@@ -250737,10 +250738,13 @@ var CliCore = class {
250737
250738
  this.options = options;
250738
250739
  this.analysisMemoryLimitInMb = +this.options.memoryLimit;
250739
250740
  if (this.options.analysisTimeout !== void 0) {
250740
- this.analysisTimeoutInSeconds = Number(this.options.analysisTimeout);
250741
- if (isNaN(this.analysisTimeoutInSeconds)) {
250741
+ const parsedTimeout = Number(this.options.analysisTimeout);
250742
+ if (isNaN(parsedTimeout)) {
250742
250743
  throw new Error("Invalid analysis timeout value");
250743
250744
  }
250745
+ this.analysisTimeoutInSeconds = parsedTimeout;
250746
+ } else {
250747
+ this.analysisTimeoutInSeconds = 600;
250744
250748
  }
250745
250749
  this.rootWorkingDirectory = resolve43(rootWorkingDirectory);
250746
250750
  this.spinner = Spinner.instance({
@@ -251354,7 +251358,10 @@ Subproject: ${subproject}`);
251354
251358
  return result;
251355
251359
  this.sendProgress("REACHABILITY_ANALYSIS", true, subprojectPath, workspacePath);
251356
251360
  result.push(...await otherModulesCommunicator.runReachabilityAnalysis(subprojectPath, workspacePath, workspaceData, ecosystem, vulnerabilities, {
251357
- timeoutInSeconds: this.analysisTimeoutInSeconds,
251361
+ timeoutSeconds: {
251362
+ allVulnRuns: this.analysisTimeoutInSeconds,
251363
+ bucketedRuns: bucketedAnalysisTimeoutInSeconds
251364
+ },
251358
251365
  memoryLimitInMB: this.analysisMemoryLimitInMb,
251359
251366
  printLogFile: this.options.printAnalysisLogFile,
251360
251367
  // entryPoints are only supported for root workspace atm.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@coana-tech/cli",
3
- "version": "14.12.106",
3
+ "version": "14.12.107",
4
4
  "description": "Coana CLI",
5
5
  "type": "module",
6
6
  "bin": {
@@ -95651,17 +95651,15 @@ var DotnetCodeAwareVulnerabilityScanner = class _DotnetCodeAwareVulnerabilitySca
95651
95651
  apps;
95652
95652
  deps;
95653
95653
  depIdToPurl;
95654
- timeoutInSeconds;
95655
95654
  statusUpdater;
95656
95655
  name = "COCOA";
95657
- constructor(apps, deps, depIdToPurl, timeoutInSeconds, statusUpdater) {
95656
+ constructor(apps, deps, depIdToPurl, statusUpdater) {
95658
95657
  this.apps = apps;
95659
95658
  this.deps = deps;
95660
95659
  this.depIdToPurl = depIdToPurl;
95661
- this.timeoutInSeconds = timeoutInSeconds;
95662
95660
  this.statusUpdater = statusUpdater;
95663
95661
  }
95664
- static initFromDependencyTree(dependencyTree, timeoutInSeconds, statusUpdater) {
95662
+ static initFromDependencyTree(dependencyTree, statusUpdater) {
95665
95663
  const apps = {
95666
95664
  "<app>": {
95667
95665
  src: dependencyTree.src,
@@ -95677,9 +95675,9 @@ var DotnetCodeAwareVulnerabilityScanner = class _DotnetCodeAwareVulnerabilitySca
95677
95675
  bin: dep.bin
95678
95676
  };
95679
95677
  }
95680
- return new _DotnetCodeAwareVulnerabilityScanner(apps, deps, depIdToPurl, timeoutInSeconds, statusUpdater);
95678
+ return new _DotnetCodeAwareVulnerabilityScanner(apps, deps, depIdToPurl, statusUpdater);
95681
95679
  }
95682
- static async initFromSocketArtifacts(subprojectDir, manifestFiles, artifacts, tmpDir, timeoutInSeconds, statusUpdater) {
95680
+ static async initFromSocketArtifacts(subprojectDir, manifestFiles, artifacts, tmpDir, statusUpdater) {
95683
95681
  const projMatcher = (0, import_picomatch.default)("*.*proj", { basename: true });
95684
95682
  const src = await asyncFlatMap(manifestFiles.filter((f2) => projMatcher(f2)), async (projFile) => {
95685
95683
  const project = await loadNuGetProject(subprojectDir, projFile);
@@ -95691,7 +95689,7 @@ var DotnetCodeAwareVulnerabilityScanner = class _DotnetCodeAwareVulnerabilitySca
95691
95689
  }
95692
95690
  };
95693
95691
  const { deps, depIdToPurl } = await convertSocketArtifacts(artifacts, tmpDir);
95694
- return new _DotnetCodeAwareVulnerabilityScanner(apps, deps, depIdToPurl, timeoutInSeconds, statusUpdater);
95692
+ return new _DotnetCodeAwareVulnerabilityScanner(apps, deps, depIdToPurl, statusUpdater);
95695
95693
  }
95696
95694
  static async runOnAlreadyDownloadedPackages([appPath, ...depPaths], vulnerability, options) {
95697
95695
  const apps = {
@@ -95708,8 +95706,8 @@ var DotnetCodeAwareVulnerabilityScanner = class _DotnetCodeAwareVulnerabilitySca
95708
95706
  bin: await isDirectory(depPath) ? await getFiles(depPath) : [depPath]
95709
95707
  };
95710
95708
  }
95711
- const scanner = new _DotnetCodeAwareVulnerabilityScanner(apps, deps, depIdToPurl, options.timeoutInSeconds);
95712
- const result = await scanner.runAnalysis([vulnerability], CocoaHeuristics.ALL_PACKAGES, false);
95709
+ const scanner = new _DotnetCodeAwareVulnerabilityScanner(apps, deps, depIdToPurl);
95710
+ const result = await scanner.runAnalysis([vulnerability], CocoaHeuristics.ALL_PACKAGES, options.timeoutSeconds.allVulnRuns);
95713
95711
  if (result.type === "error")
95714
95712
  return { error: result.message, terminatedEarly: true };
95715
95713
  return {
@@ -95737,8 +95735,8 @@ var DotnetCodeAwareVulnerabilityScanner = class _DotnetCodeAwareVulnerabilitySca
95737
95735
  bin: dep.bin
95738
95736
  };
95739
95737
  });
95740
- const scanner = new _DotnetCodeAwareVulnerabilityScanner(apps, deps, depIdToPurl, timeoutInSeconds, statusUpdater);
95741
- const result = await scanner.actuallyRunAnalysis(vulnerability.vulnerabilityAccessPaths);
95738
+ const scanner = new _DotnetCodeAwareVulnerabilityScanner(apps, deps, depIdToPurl, statusUpdater);
95739
+ const result = await scanner.actuallyRunAnalysis(vulnerability.vulnerabilityAccessPaths, timeoutInSeconds);
95742
95740
  if (result.type === "error")
95743
95741
  return { error: result.message, terminatedEarly: false };
95744
95742
  return {
@@ -95750,7 +95748,7 @@ var DotnetCodeAwareVulnerabilityScanner = class _DotnetCodeAwareVulnerabilitySca
95750
95748
  }
95751
95749
  });
95752
95750
  }
95753
- async runPhantomDependencyAnalysis() {
95751
+ async runPhantomDependencyAnalysis(timeoutInSeconds) {
95754
95752
  return withTmpDirectory("dotnet-direct-dependency-analysis", async (tmpDir) => {
95755
95753
  try {
95756
95754
  await ensureDotnet6OrAbove();
@@ -95760,12 +95758,12 @@ var DotnetCodeAwareVulnerabilityScanner = class _DotnetCodeAwareVulnerabilitySca
95760
95758
  const options = {
95761
95759
  apps: this.apps,
95762
95760
  deps: this.deps,
95763
- timeoutInSeconds: this.timeoutInSeconds
95761
+ timeoutInSeconds
95764
95762
  };
95765
95763
  const inputFile = resolve10(tmpDir, "input.json");
95766
95764
  const outputFile = resolve10(tmpDir, "output.json");
95767
95765
  await writeFile4(inputFile, JSON.stringify(options));
95768
- const timeoutMs = this.timeoutInSeconds ? Math.max(this.timeoutInSeconds * 1.5, this.timeoutInSeconds + 30) * 1e3 : 750 * 1e3;
95766
+ const timeoutMs = Math.max(timeoutInSeconds * 1.5, timeoutInSeconds + 30) * 1e3;
95769
95767
  const result = await execNeverFail2(cmdt`${await getNodeExecutable(ToolPathResolver.nodeExecutablePath)} ${getClassGraphAnalysisCliPath()} runDotnetDirectDependencyAnalysis -i ${inputFile} -o ${outputFile} --cocoa ${getCocoaPath()} --tree-sitter-c-sharp ${getTreeSitterCSharpPath()}`, void 0, { timeout: timeoutMs });
95770
95768
  if (result.error)
95771
95769
  return void 0;
@@ -95773,7 +95771,7 @@ var DotnetCodeAwareVulnerabilityScanner = class _DotnetCodeAwareVulnerabilitySca
95773
95771
  return packageIds?.map((packageId) => this.depIdToPurl.get(packageId)).filter((purl) => purl !== void 0).map((purl) => purl.name ?? "");
95774
95772
  });
95775
95773
  }
95776
- async runAnalysis(vulnerabilities, heuristic, _analyzesAllVulns, _experiment) {
95774
+ async runAnalysis(vulnerabilities, heuristic, timeoutInSeconds, _experiment) {
95777
95775
  try {
95778
95776
  this.statusUpdater?.("Preparing code for analysis...");
95779
95777
  const packagesToAnalyze = heuristic.getPackagesToAnalyze(vulnerabilities);
@@ -95782,12 +95780,12 @@ var DotnetCodeAwareVulnerabilityScanner = class _DotnetCodeAwareVulnerabilitySca
95782
95780
  const purl = this.depIdToPurl.get(packageId);
95783
95781
  return purl?.name && packagesToAnalyzeSet.has(purl.name);
95784
95782
  }));
95785
- return await this.actuallyRunAnalysis(vulnerabilities.flatMap((v) => v.vulnerabilityAccessPaths), filteredDeps);
95783
+ return await this.actuallyRunAnalysis(vulnerabilities.flatMap((v) => v.vulnerabilityAccessPaths), timeoutInSeconds, filteredDeps);
95786
95784
  } catch (e) {
95787
95785
  return { type: "error", message: e.message };
95788
95786
  }
95789
95787
  }
95790
- async actuallyRunAnalysis(vulnerabilityAccessPaths, filteredDeps) {
95788
+ async actuallyRunAnalysis(vulnerabilityAccessPaths, timeoutInSeconds, filteredDeps) {
95791
95789
  this.statusUpdater?.("Running analysis...");
95792
95790
  return withTmpDirectory("dotnet-run-analysis", async (tmpDir) => {
95793
95791
  try {
@@ -95799,12 +95797,12 @@ var DotnetCodeAwareVulnerabilityScanner = class _DotnetCodeAwareVulnerabilitySca
95799
95797
  apps: this.apps,
95800
95798
  deps: filteredDeps ?? this.deps,
95801
95799
  vulnerableClasses: uniq2(vulnerabilityAccessPaths?.map((vulnFunction) => vulnFunction.slice(1).split(":")[0])),
95802
- timeoutInSeconds: this.timeoutInSeconds
95800
+ timeoutInSeconds
95803
95801
  };
95804
95802
  const inputFile = resolve10(tmpDir, "input.json");
95805
95803
  const outputFile = resolve10(tmpDir, "output.json");
95806
95804
  await writeFile4(inputFile, JSON.stringify(options));
95807
- const timeoutMs = this.timeoutInSeconds ? Math.max(this.timeoutInSeconds * 1.5, this.timeoutInSeconds + 30) * 1e3 : 750 * 1e3;
95805
+ const timeoutMs = Math.max(timeoutInSeconds * 1.5, timeoutInSeconds + 30) * 1e3;
95808
95806
  const result = await execNeverFail2(cmdt`${await getNodeExecutable(ToolPathResolver.nodeExecutablePath)} ${getClassGraphAnalysisCliPath()} runDotnetReachabilityAnalysis -i ${inputFile} -o ${outputFile} --cocoa ${getCocoaPath()} --tree-sitter-c-sharp ${getTreeSitterCSharpPath()}`, void 0, { timeout: timeoutMs });
95809
95807
  if (result.error)
95810
95808
  return { type: "error", message: result.error.message ?? "unknown error" };
@@ -109628,17 +109626,15 @@ var JavaCodeAwareVulnerabilityScanner = class _JavaCodeAwareVulnerabilityScanner
109628
109626
  apps;
109629
109627
  deps;
109630
109628
  depIdToPurl;
109631
- timeoutInSeconds;
109632
109629
  statusUpdater;
109633
109630
  name = "ALUCARD";
109634
- constructor(apps, deps, depIdToPurl, timeoutInSeconds, statusUpdater) {
109631
+ constructor(apps, deps, depIdToPurl, statusUpdater) {
109635
109632
  this.apps = apps;
109636
109633
  this.deps = deps;
109637
109634
  this.depIdToPurl = depIdToPurl;
109638
- this.timeoutInSeconds = timeoutInSeconds;
109639
109635
  this.statusUpdater = statusUpdater;
109640
109636
  }
109641
- static async initFromDependencyTree(dependencyTree, tmpDir, timeoutInSeconds, statusUpdater) {
109637
+ static async initFromDependencyTree(dependencyTree, tmpDir, statusUpdater) {
109642
109638
  const apps = {
109643
109639
  "<app>": {
109644
109640
  src: dependencyTree.src
@@ -109655,9 +109651,9 @@ var JavaCodeAwareVulnerabilityScanner = class _JavaCodeAwareVulnerabilityScanner
109655
109651
  };
109656
109652
  }
109657
109653
  await extractArchivesIfNeeded(tmpDir, apps, deps);
109658
- return new _JavaCodeAwareVulnerabilityScanner(apps, deps, depIdToPurl, timeoutInSeconds, statusUpdater);
109654
+ return new _JavaCodeAwareVulnerabilityScanner(apps, deps, depIdToPurl, statusUpdater);
109659
109655
  }
109660
- static async initFromSocketArtifacts(subprojectDir, artifacts, tmpDir, timeoutInSeconds, statusUpdater) {
109656
+ static async initFromSocketArtifacts(subprojectDir, artifacts, tmpDir, statusUpdater) {
109661
109657
  const apps = {
109662
109658
  "<app>": {
109663
109659
  src: [subprojectDir]
@@ -109665,7 +109661,7 @@ var JavaCodeAwareVulnerabilityScanner = class _JavaCodeAwareVulnerabilityScanner
109665
109661
  };
109666
109662
  const { deps, depIdToPurl } = await convertSocketArtifacts2(subprojectDir, artifacts, tmpDir);
109667
109663
  await extractArchivesIfNeeded(tmpDir, apps, deps);
109668
- return new _JavaCodeAwareVulnerabilityScanner(apps, deps, depIdToPurl, timeoutInSeconds, statusUpdater);
109664
+ return new _JavaCodeAwareVulnerabilityScanner(apps, deps, depIdToPurl, statusUpdater);
109669
109665
  }
109670
109666
  static async runOnAlreadyDownloadedPackages([appPath, ...depPaths], vulnerability, options) {
109671
109667
  return withTmpDirectory("java-run-on-dependency-chain", async (tmpDir) => {
@@ -109683,8 +109679,8 @@ var JavaCodeAwareVulnerabilityScanner = class _JavaCodeAwareVulnerabilityScanner
109683
109679
  };
109684
109680
  }
109685
109681
  await extractArchivesIfNeeded(tmpDir, apps, deps);
109686
- const scanner = new _JavaCodeAwareVulnerabilityScanner(apps, deps, depIdToPurl, options.timeoutInSeconds);
109687
- const result = await scanner.runAnalysis([vulnerability], AlucardHeuristics.ALL_PACKAGES, false);
109682
+ const scanner = new _JavaCodeAwareVulnerabilityScanner(apps, deps, depIdToPurl);
109683
+ const result = await scanner.runAnalysis([vulnerability], AlucardHeuristics.ALL_PACKAGES, options.timeoutSeconds.allVulnRuns);
109688
109684
  if (result.type === "error")
109689
109685
  return { error: result.message, terminatedEarly: true };
109690
109686
  return {
@@ -109715,8 +109711,8 @@ var JavaCodeAwareVulnerabilityScanner = class _JavaCodeAwareVulnerabilityScanner
109715
109711
  };
109716
109712
  });
109717
109713
  await extractArchivesIfNeeded(tmpDir, apps, deps);
109718
- const scanner = new _JavaCodeAwareVulnerabilityScanner(apps, deps, depIdToPurl, timeoutInSeconds, statusUpdater);
109719
- const result = await scanner.actuallyRunAnalysis(vulnerability.vulnerabilityAccessPaths);
109714
+ const scanner = new _JavaCodeAwareVulnerabilityScanner(apps, deps, depIdToPurl, statusUpdater);
109715
+ const result = await scanner.actuallyRunAnalysis(vulnerability.vulnerabilityAccessPaths, timeoutInSeconds);
109720
109716
  if (result.type === "error")
109721
109717
  return { error: result.message, terminatedEarly: false };
109722
109718
  return {
@@ -109728,7 +109724,7 @@ var JavaCodeAwareVulnerabilityScanner = class _JavaCodeAwareVulnerabilityScanner
109728
109724
  }
109729
109725
  });
109730
109726
  }
109731
- async runPhantomDependencyAnalysis() {
109727
+ async runPhantomDependencyAnalysis(timeoutInSeconds) {
109732
109728
  return withTmpDirectory("java-direct-dependency-analysis", async (tmpDir) => {
109733
109729
  try {
109734
109730
  await ensureJdk8OrAbove();
@@ -109738,12 +109734,12 @@ var JavaCodeAwareVulnerabilityScanner = class _JavaCodeAwareVulnerabilityScanner
109738
109734
  const options = {
109739
109735
  apps: this.apps,
109740
109736
  deps: this.deps,
109741
- timeoutInSeconds: this.timeoutInSeconds
109737
+ timeoutInSeconds
109742
109738
  };
109743
109739
  const inputFile = resolve11(tmpDir, "input.json");
109744
109740
  const outputFile = resolve11(tmpDir, "output.json");
109745
109741
  await writeFile5(inputFile, JSON.stringify(options));
109746
- const timeoutMs = this.timeoutInSeconds ? Math.max(this.timeoutInSeconds * 1.5, this.timeoutInSeconds + 30) * 1e3 : 750 * 1e3;
109742
+ const timeoutMs = Math.max(timeoutInSeconds * 1.5, timeoutInSeconds + 30) * 1e3;
109747
109743
  const result = await execNeverFail2(cmdt`${await getNodeExecutable(ToolPathResolver.nodeExecutablePath)} ${getClassGraphAnalysisCliPath()} runJvmDirectDependencyAnalysis -i ${inputFile} -o ${outputFile} --javap-service ${getJavapServicePath()} --tree-sitter-java ${getTreeSitterJavaPath()} --tree-sitter-kotlin ${getTreeSitterKotlinPath()} --tree-sitter-scala ${getTreeSitterScalaPath()}`, void 0, { timeout: timeoutMs });
109748
109744
  if (result.error)
109749
109745
  return void 0;
@@ -109751,7 +109747,7 @@ var JavaCodeAwareVulnerabilityScanner = class _JavaCodeAwareVulnerabilityScanner
109751
109747
  return packageIds?.map((packageId) => this.depIdToPurl.get(packageId)).filter((purl) => purl !== void 0).map((purl) => `${purl.namespace}:${purl.name}}`);
109752
109748
  });
109753
109749
  }
109754
- async runAnalysis(vulnerabilities, heuristic, _analyzesAllVulns, _experiment) {
109750
+ async runAnalysis(vulnerabilities, heuristic, timeoutInSeconds, _experiment) {
109755
109751
  try {
109756
109752
  this.statusUpdater?.("Preparing code for analysis...");
109757
109753
  const packagesToAnalyze = heuristic.getPackagesToAnalyze(vulnerabilities);
@@ -109760,12 +109756,12 @@ var JavaCodeAwareVulnerabilityScanner = class _JavaCodeAwareVulnerabilityScanner
109760
109756
  const purl = this.depIdToPurl.get(packageId);
109761
109757
  return purl && packagesToAnalyzeSet.has(`${purl.namespace}:${purl.name}}`);
109762
109758
  }));
109763
- return await this.actuallyRunAnalysis(vulnerabilities.flatMap((v) => v.vulnerabilityAccessPaths), filteredDeps);
109759
+ return await this.actuallyRunAnalysis(vulnerabilities.flatMap((v) => v.vulnerabilityAccessPaths), timeoutInSeconds, filteredDeps);
109764
109760
  } catch (e) {
109765
109761
  return { type: "error", message: e.message };
109766
109762
  }
109767
109763
  }
109768
- async actuallyRunAnalysis(vulnerabilityAccessPaths, filteredDeps) {
109764
+ async actuallyRunAnalysis(vulnerabilityAccessPaths, timeoutInSeconds, filteredDeps) {
109769
109765
  this.statusUpdater?.("Running analysis...");
109770
109766
  return withTmpDirectory("java-run-analysis", async (tmpDir) => {
109771
109767
  try {
@@ -109777,12 +109773,12 @@ var JavaCodeAwareVulnerabilityScanner = class _JavaCodeAwareVulnerabilityScanner
109777
109773
  apps: this.apps,
109778
109774
  deps: filteredDeps ?? this.deps,
109779
109775
  vulnerableClasses: uniq3(vulnerabilityAccessPaths?.map((vulnFunction) => vulnFunction.slice(1).split(":")[0])),
109780
- timeoutInSeconds: this.timeoutInSeconds
109776
+ timeoutInSeconds
109781
109777
  };
109782
109778
  const inputFile = resolve11(tmpDir, "input.json");
109783
109779
  const outputFile = resolve11(tmpDir, "output.json");
109784
109780
  await writeFile5(inputFile, JSON.stringify(options));
109785
- const timeoutMs = this.timeoutInSeconds ? Math.max(this.timeoutInSeconds * 1.5, this.timeoutInSeconds + 30) * 1e3 : 750 * 1e3;
109781
+ const timeoutMs = Math.max(timeoutInSeconds * 1.5, timeoutInSeconds + 30) * 1e3;
109786
109782
  const result = await execNeverFail2(cmdt`${await getNodeExecutable(ToolPathResolver.nodeExecutablePath)} ${getClassGraphAnalysisCliPath()} runJvmReachabilityAnalysis -i ${inputFile} -o ${outputFile} --javap-service ${getJavapServicePath()} --tree-sitter-java ${getTreeSitterJavaPath()} --tree-sitter-kotlin ${getTreeSitterKotlinPath()} --tree-sitter-scala ${getTreeSitterScalaPath()}`, void 0, { timeout: timeoutMs });
109787
109783
  if (result.error)
109788
109784
  return { type: "error", message: result.error.message ?? "unknown error" };
@@ -110442,7 +110438,7 @@ import { readFile as readFile8, rm as rm2, writeFile as writeFile6 } from "fs/pr
110442
110438
  import { relative as relative6, resolve as resolve14 } from "path";
110443
110439
  var { map: map2, uniq: uniq4 } = import_lodash10.default;
110444
110440
  var PRINT_JELLY_COMMAND = false;
110445
- async function runJellyAnalysis(mainProjectRoot, projectRoot, jellyOptions, reachabilityAnalysisOptions, vulnerabilities, experiment) {
110441
+ async function runJellyAnalysis(mainProjectRoot, projectRoot, jellyOptions, reachabilityAnalysisOptions, timeoutInSeconds, vulnerabilities, experiment) {
110446
110442
  const tmpFolder = await createTmpDirectory("jelly-analysis");
110447
110443
  try {
110448
110444
  const filesToAnalyze = reachabilityAnalysisOptions.entryPoints ? reachabilityAnalysisOptions.entryPoints : [projectRoot];
@@ -110468,7 +110464,7 @@ async function runJellyAnalysis(mainProjectRoot, projectRoot, jellyOptions, reac
110468
110464
  ${await getNodeExecutable(ToolPathResolver.nodeExecutablePath)} --max-old-space-size=${reachabilityAnalysisOptions.memoryLimitInMB ?? 8192}
110469
110465
  ${jellyExecutable}
110470
110466
  --basedir ${mainProjectRoot}
110471
- --timeout ${reachabilityAnalysisOptions.timeoutInSeconds ?? 60}
110467
+ --timeout ${timeoutInSeconds}
110472
110468
  --vulnerabilities ${vulnerabilitiesFile}
110473
110469
  --reachable-json ${affectedPackagesFile}
110474
110470
  ${excludeEntries && ["--exclude-entries", ...excludeEntries]}
@@ -110487,7 +110483,7 @@ async function runJellyAnalysis(mainProjectRoot, projectRoot, jellyOptions, reac
110487
110483
  void 0,
110488
110484
  // If it is an experimental run, make sure to crash the process if Jelly takes more than 50% longer than the timeout.
110489
110485
  // This is done to mitigate the scenario where the Jelly process gets close to the memory limit and thus ends up spending most of its time on garbage collection, which can increase the time between timeout checks dramatically.
110490
- experiment && reachabilityAnalysisOptions.timeoutInSeconds ? { timeout: reachabilityAnalysisOptions.timeoutInSeconds * 1e3 * 1.5 } : void 0
110486
+ experiment ? { timeout: timeoutInSeconds * 1e3 * 1.5 } : void 0
110491
110487
  );
110492
110488
  if (reachabilityAnalysisOptions.printLogFile)
110493
110489
  logger.info("JS analysis log file:", await readFile8(logFile, "utf-8"));
@@ -110526,7 +110522,7 @@ async function runJellyPhantomDependencyAnalysis(projectRoot, options) {
110526
110522
  const jellyCmd = cmdt`${await getNodeExecutable(ToolPathResolver.nodeExecutablePath)} --max-old-space-size=${options.memoryLimitInMB}
110527
110523
  ${jellyExecutable} --basedir ${projectRoot} --modules-only --ignore-dependencies
110528
110524
  --reachable-json ${reachablePackagesFile} ${projectRoot}`;
110529
- await runCommandResolveStdOut2(jellyCmd);
110525
+ await runCommandResolveStdOut2(jellyCmd, void 0, { timeout: options.timeoutSeconds.allVulnRuns * 1e3 });
110530
110526
  return JSON.parse(await readFile8(reachablePackagesFile, "utf-8")).packages;
110531
110527
  } finally {
110532
110528
  await rm2(tmpFolder, { recursive: true });
@@ -110540,7 +110536,7 @@ async function runJellyImportReachabilityAnalysis(baseDir, projectDir, options)
110540
110536
  const jellyCmd = cmdt`${await getNodeExecutable(ToolPathResolver.nodeExecutablePath)} --max-old-space-size=${options.memoryLimitInMB}
110541
110537
  ${jellyExecutable} --basedir ${baseDir} --modules-only
110542
110538
  --reachable-json ${reachableModulesFile} ${projectDir}`;
110543
- await runCommandResolveStdOut2(jellyCmd);
110539
+ await runCommandResolveStdOut2(jellyCmd, void 0, { timeout: options.timeoutSeconds.allVulnRuns * 1e3 });
110544
110540
  return JSON.parse(await readFile8(reachableModulesFile, "utf-8"));
110545
110541
  } finally {
110546
110542
  await rm2(tmpFolder, { recursive: true });
@@ -110571,7 +110567,7 @@ var JSCodeAwareVulnerabilityScanner = class _JSCodeAwareVulnerabilityScanner {
110571
110567
  numberAnalysesRun = 0;
110572
110568
  packagesExcludedUnrelatedToHeuristic = [];
110573
110569
  socketMode = false;
110574
- constructor(mainProjectDir, projectDir, options = {}) {
110570
+ constructor(mainProjectDir, projectDir, options) {
110575
110571
  this.mainProjectDir = mainProjectDir;
110576
110572
  this.projectDir = projectDir;
110577
110573
  this.options = options;
@@ -110587,15 +110583,11 @@ var JSCodeAwareVulnerabilityScanner = class _JSCodeAwareVulnerabilityScanner {
110587
110583
  const { failedPackages } = await prepareNpmDependencies(state.rootWorkingDir, this.projectDir, state.workspaceData.type === "coana" ? state.workspaceData.data.dependencyTree.transitiveDependencies : Object.fromEntries(state.workspaceData.data.artifacts.map((d) => [d.id, d])), state.workspaceData.type === "coana" ? state.workspaceData.data.dependencyTree.dependencies ?? [] : state.workspaceData.data.artifacts.filter((a2) => a2.direct).map((a2) => a2.id), packagesToInstall);
110588
110584
  this.packagesExcludedUnrelatedToHeuristic = failedPackages.map((p) => getPackageName(p));
110589
110585
  }
110590
- async runAnalysis(vulnerabilities, heuristic, analyzesAllVulns, experiment) {
110586
+ async runAnalysis(vulnerabilities, heuristic, timeoutInSeconds, experiment) {
110591
110587
  const analysisOptionsFromHeuristic = heuristic.getOptions(vulnerabilities);
110592
- const timeoutInSeconds = analyzesAllVulns ? this.options.timeoutInSeconds ?? 600 : 60;
110593
110588
  try {
110594
110589
  analysisOptionsFromHeuristic.approx = process.env.JELLY_APPROX === "true" || experiment === "JELLY_APPROX";
110595
- const analysisRes = await runJellyAnalysis(this.mainProjectDir, this.projectDir, analysisOptionsFromHeuristic, {
110596
- ...this.options,
110597
- timeoutInSeconds
110598
- }, vulnerabilities, experiment);
110590
+ const analysisRes = await runJellyAnalysis(this.mainProjectDir, this.projectDir, analysisOptionsFromHeuristic, this.options, timeoutInSeconds, vulnerabilities, experiment);
110599
110591
  const { analysisDiagnostics: diagnostics, matches } = analysisRes;
110600
110592
  return {
110601
110593
  type: "success",
@@ -110659,7 +110651,7 @@ var JSCodeAwareVulnerabilityScanner = class _JSCodeAwareVulnerabilityScanner {
110659
110651
  const projectDir = join14(tmpDir, "node_modules", firstPackageName);
110660
110652
  const scanner = new _JSCodeAwareVulnerabilityScanner(projectDir, projectDir, reachabilityAnalysisOptions);
110661
110653
  logger.info(`Started analysis of ${projectDir}`);
110662
- const result = await scanner.runAnalysis([vulnerability], heuristics.createIncludePackagesHeuristic(otherPackageNames, baseHeuristic.getOptions([vulnerability])), true);
110654
+ const result = await scanner.runAnalysis([vulnerability], heuristics.createIncludePackagesHeuristic(otherPackageNames, baseHeuristic.getOptions([vulnerability])), reachabilityAnalysisOptions.timeoutSeconds.allVulnRuns);
110663
110655
  if (result.type === "error") {
110664
110656
  return {
110665
110657
  error: result.message,
@@ -110683,7 +110675,7 @@ var JSCodeAwareVulnerabilityScanner = class _JSCodeAwareVulnerabilityScanner {
110683
110675
  const restWithoutLast = rest.slice(0, -1);
110684
110676
  const projectDir = join14(tmpDir, "node_modules", first2.packageName);
110685
110677
  const scanner = new _JSCodeAwareVulnerabilityScanner(tmpDir, projectDir, reachabilityAnalysisOptions);
110686
- const result = await scanner.runAnalysis([vulnerability], heuristics.createIncludePackagesHeuristic(restWithoutLast.map((p) => p.packageName), baseHeuristic.getOptions([vulnerability])), true);
110678
+ const result = await scanner.runAnalysis([vulnerability], heuristics.createIncludePackagesHeuristic(restWithoutLast.map((p) => p.packageName), baseHeuristic.getOptions([vulnerability])), reachabilityAnalysisOptions.timeoutSeconds.allVulnRuns);
110687
110679
  await rm3(tmpDir, { recursive: true, force: true });
110688
110680
  if (result.type === "error") {
110689
110681
  return {
@@ -110774,11 +110766,11 @@ var GoCodeAwareVulnerabilityScanner = class {
110774
110766
  this.projectDir = projectDir;
110775
110767
  this.options = options;
110776
110768
  }
110777
- async runAnalysis(vulns, heuristic, analyzesAllVulns) {
110769
+ async runAnalysis(vulns, heuristic, timeoutInSeconds) {
110778
110770
  logger.info("Started instantiating Go code-aware analysis");
110779
110771
  if (!existsSync10(join15(this.projectDir, "go.mod")))
110780
110772
  throw new Error("go.mod file not found in the project directory");
110781
- const { timeoutInSeconds, memoryLimitInMB } = this.options;
110773
+ const { memoryLimitInMB } = this.options;
110782
110774
  const tmpDir = await createTmpDirectory("goana-output");
110783
110775
  const vulnsOutputFile = join15(tmpDir, "vulns.json");
110784
110776
  const diagnosticsOutputFile = join15(tmpDir, "diagnostics.json");
@@ -110795,7 +110787,7 @@ var GoCodeAwareVulnerabilityScanner = class {
110795
110787
  -output-reached-modules ${reachedModulesOutputFile}
110796
110788
  -topk=4 ${heuristic.includeTests && "-tests"}
110797
110789
  ${this.projectDir} ${vulnAccPaths}`, void 0, {
110798
- timeout: timeoutInSeconds ? timeoutInSeconds * 1e3 : analyzesAllVulns ? 600 * 1e3 : 60 * 1e3,
110790
+ timeout: timeoutInSeconds * 1e3,
110799
110791
  env: memoryLimitInMB ? { ...process.env, GOMEMLIMIT: `${memoryLimitInMB}MiB` } : void 0
110800
110792
  });
110801
110793
  if (error) {
@@ -110840,7 +110832,7 @@ ${stderr}`);
110840
110832
  await rm4(tmpDir, { recursive: true, force: true });
110841
110833
  }
110842
110834
  }
110843
- static async runOnDependencyChain([first2, ...rest], vuln, options = {}) {
110835
+ static async runOnDependencyChain([first2, ...rest], vuln, options) {
110844
110836
  assert4(first2.version);
110845
110837
  const { Dir, GoMod } = JSON.parse(await runCommandResolveStdOut2(cmdt`go mod download -json ${first2.packageName}@v${first2.version}`));
110846
110838
  const projectDir = await createTmpDirectory("go-run-on-dependency-chain-");
@@ -110857,7 +110849,7 @@ ${stderr}`);
110857
110849
  await runGoModTidy(projectDir);
110858
110850
  }
110859
110851
  const heuristic = GoanaHeuristics.NO_TESTS;
110860
- const result = await new this(projectDir, options).runAnalysis([vuln], heuristic, true);
110852
+ const result = await new this(projectDir, options).runAnalysis([vuln], heuristic, options.timeoutSeconds.allVulnRuns);
110861
110853
  if (result.type === "error")
110862
110854
  return {
110863
110855
  error: result.message,
@@ -110873,7 +110865,7 @@ ${stderr}`);
110873
110865
  await rm4(projectDir, { recursive: true, force: true });
110874
110866
  }
110875
110867
  }
110876
- static async runOnAlreadyDownloadedPackages(packages, vuln, options = {}) {
110868
+ static async runOnAlreadyDownloadedPackages(packages, vuln, options) {
110877
110869
  for (const pkg of packages)
110878
110870
  assert4(existsSync10(join15(pkg, "go.mod")), `${pkg} does not contain a go.mod file`);
110879
110871
  const [app, ...dependencies] = packages;
@@ -110890,7 +110882,7 @@ ${stderr}`);
110890
110882
  await runGoModTidy(projectDir);
110891
110883
  }
110892
110884
  const heuristic = GoanaHeuristics.NO_TESTS;
110893
- const result = await new this(projectDir, options).runAnalysis([vuln], heuristic, true);
110885
+ const result = await new this(projectDir, options).runAnalysis([vuln], heuristic, options.timeoutSeconds.allVulnRuns);
110894
110886
  if (result.type === "error")
110895
110887
  return {
110896
110888
  error: result.message,
@@ -110948,17 +110940,15 @@ var RustCodeAwareVulnerabilityScanner = class _RustCodeAwareVulnerabilityScanner
110948
110940
  apps;
110949
110941
  deps;
110950
110942
  depIdToPurl;
110951
- timeoutInSeconds;
110952
110943
  statusUpdater;
110953
110944
  name = "RUSTICA";
110954
- constructor(apps, deps, depIdToPurl, timeoutInSeconds, statusUpdater) {
110945
+ constructor(apps, deps, depIdToPurl, statusUpdater) {
110955
110946
  this.apps = apps;
110956
110947
  this.deps = deps;
110957
110948
  this.depIdToPurl = depIdToPurl;
110958
- this.timeoutInSeconds = timeoutInSeconds;
110959
110949
  this.statusUpdater = statusUpdater;
110960
110950
  }
110961
- static initFromDependencyTree(dependencyTree, timeoutInSeconds, statusUpdater) {
110951
+ static initFromDependencyTree(dependencyTree, statusUpdater) {
110962
110952
  const appDependencies = {};
110963
110953
  if (dependencyTree.dependenciesWithAliases) {
110964
110954
  for (const [depId, names] of Object.entries(dependencyTree.dependenciesWithAliases)) {
@@ -110992,9 +110982,9 @@ var RustCodeAwareVulnerabilityScanner = class _RustCodeAwareVulnerabilityScanner
110992
110982
  }
110993
110983
  };
110994
110984
  }
110995
- return new _RustCodeAwareVulnerabilityScanner(apps, deps, depIdToPurl, timeoutInSeconds, statusUpdater);
110985
+ return new _RustCodeAwareVulnerabilityScanner(apps, deps, depIdToPurl, statusUpdater);
110996
110986
  }
110997
- static async initFromSocketArtifacts(subprojectDir, workspacePath, artifacts, tmpDir, timeoutInSeconds, statusUpdater) {
110987
+ static async initFromSocketArtifacts(subprojectDir, workspacePath, artifacts, tmpDir, statusUpdater) {
110998
110988
  const cargoTomlToArtifacts = /* @__PURE__ */ new Map();
110999
110989
  for (const artifact of artifacts) {
111000
110990
  for (const mf of artifact.manifestFiles ?? []) {
@@ -111048,7 +111038,7 @@ var RustCodeAwareVulnerabilityScanner = class _RustCodeAwareVulnerabilityScanner
111048
111038
  }
111049
111039
  };
111050
111040
  const { deps, depIdToPurl } = await convertSocketArtifacts3(artifacts, tmpDir, artifactNameToId);
111051
- return new _RustCodeAwareVulnerabilityScanner(apps, deps, depIdToPurl, timeoutInSeconds, statusUpdater);
111041
+ return new _RustCodeAwareVulnerabilityScanner(apps, deps, depIdToPurl, statusUpdater);
111052
111042
  }
111053
111043
  /** @deprecated */
111054
111044
  static async runOnAlreadyDownloadedPackages([appPath, ...depPaths], vulnerability, options) {
@@ -111106,8 +111096,8 @@ var RustCodeAwareVulnerabilityScanner = class _RustCodeAwareVulnerabilityScanner
111106
111096
  deps[packageId] = packageInfo;
111107
111097
  }
111108
111098
  }
111109
- const scanner = new _RustCodeAwareVulnerabilityScanner(apps, deps, depIdToPurl, options.timeoutInSeconds);
111110
- const result = await scanner.runAnalysis([vulnerability], RusticaHeuristics.ALL_PACKAGES, false);
111099
+ const scanner = new _RustCodeAwareVulnerabilityScanner(apps, deps, depIdToPurl);
111100
+ const result = await scanner.runAnalysis([vulnerability], RusticaHeuristics.ALL_PACKAGES, options.timeoutSeconds.allVulnRuns);
111111
111101
  if (result.type === "error")
111112
111102
  return { error: result.message, terminatedEarly: true };
111113
111103
  return {
@@ -111173,8 +111163,8 @@ var RustCodeAwareVulnerabilityScanner = class _RustCodeAwareVulnerabilityScanner
111173
111163
  }
111174
111164
  };
111175
111165
  }
111176
- const scanner = new _RustCodeAwareVulnerabilityScanner(apps, deps, depIdToPurl, timeoutInSeconds, statusUpdater);
111177
- const result = await scanner.actuallyRunAnalysis(vulnerability.vulnerabilityAccessPaths);
111166
+ const scanner = new _RustCodeAwareVulnerabilityScanner(apps, deps, depIdToPurl, statusUpdater);
111167
+ const result = await scanner.actuallyRunAnalysis(vulnerability.vulnerabilityAccessPaths, timeoutInSeconds);
111178
111168
  if (result.type === "error")
111179
111169
  return { error: result.message, terminatedEarly: false };
111180
111170
  return {
@@ -111186,17 +111176,17 @@ var RustCodeAwareVulnerabilityScanner = class _RustCodeAwareVulnerabilityScanner
111186
111176
  }
111187
111177
  });
111188
111178
  }
111189
- async runPhantomDependencyAnalysis() {
111179
+ async runPhantomDependencyAnalysis(timeoutInSeconds) {
111190
111180
  return withTmpDirectory("rust-direct-dependency-analysis", async (tmpDir) => {
111191
111181
  const options = {
111192
111182
  apps: this.apps,
111193
111183
  deps: this.deps,
111194
- timeoutInSeconds: this.timeoutInSeconds
111184
+ timeoutInSeconds
111195
111185
  };
111196
111186
  const inputFile = resolve16(tmpDir, "input.json");
111197
111187
  const outputFile = resolve16(tmpDir, "output.json");
111198
111188
  await writeFile8(inputFile, JSON.stringify(options));
111199
- const timeoutMs = this.timeoutInSeconds ? Math.max(this.timeoutInSeconds * 1.5, this.timeoutInSeconds + 30) * 1e3 : 750 * 1e3;
111189
+ const timeoutMs = Math.max(timeoutInSeconds * 1.5, timeoutInSeconds + 30) * 1e3;
111200
111190
  const result = await execNeverFail2(cmdt`${await getNodeExecutable(ToolPathResolver.nodeExecutablePath)} ${getClassGraphAnalysisCliPath()} runRustDirectDependencyAnalysis -i ${inputFile} -o ${outputFile} --tree-sitter-rust ${getTreeSitterRustPath()}`, void 0, { timeout: timeoutMs });
111201
111191
  if (result.error)
111202
111192
  return void 0;
@@ -111204,7 +111194,7 @@ var RustCodeAwareVulnerabilityScanner = class _RustCodeAwareVulnerabilityScanner
111204
111194
  return packageIds?.map((packageId) => this.depIdToPurl.get(packageId)?.name).filter((name2) => name2 !== void 0).map((name2) => name2);
111205
111195
  });
111206
111196
  }
111207
- async runAnalysis(vulnerabilities, heuristic, _analyzesAllVulns) {
111197
+ async runAnalysis(vulnerabilities, heuristic, timeoutInSeconds) {
111208
111198
  try {
111209
111199
  this.statusUpdater?.("Preparing code for analysis...");
111210
111200
  const packagesToAnalyze = heuristic.getPackagesToAnalyze(vulnerabilities);
@@ -111213,25 +111203,26 @@ var RustCodeAwareVulnerabilityScanner = class _RustCodeAwareVulnerabilityScanner
111213
111203
  const purl = this.depIdToPurl.get(packageId);
111214
111204
  return purl?.name && packagesToAnalyzeSet.has(purl.name);
111215
111205
  }));
111216
- return await this.actuallyRunAnalysis(vulnerabilities.flatMap((v) => v.vulnerabilityAccessPaths), filteredDeps);
111206
+ return await this.actuallyRunAnalysis(vulnerabilities.flatMap((v) => v.vulnerabilityAccessPaths), timeoutInSeconds, filteredDeps);
111217
111207
  } catch (e) {
111218
111208
  return { type: "error", message: e.message };
111219
111209
  }
111220
111210
  }
111221
- async actuallyRunAnalysis(vulnerabilityAccessPaths, filteredDeps) {
111211
+ async actuallyRunAnalysis(vulnerabilityAccessPaths, timeoutInSeconds, filteredDeps) {
111222
111212
  this.statusUpdater?.("Running analysis...");
111223
111213
  return withTmpDirectory("rust-run-analysis", async (tmpDir) => {
111214
+ const effectiveTimeout = timeoutInSeconds;
111224
111215
  const options = {
111225
111216
  apps: this.apps,
111226
111217
  deps: filteredDeps ?? this.deps,
111227
111218
  // Note, rust uses '::' as path separator, so we need to split on ': ' and not only ':'
111228
111219
  vulnerableClasses: uniq6(vulnerabilityAccessPaths?.map((vulnFunction) => vulnFunction.slice(1).split(": ")[0])),
111229
- timeoutInSeconds: this.timeoutInSeconds
111220
+ timeoutInSeconds: effectiveTimeout
111230
111221
  };
111231
111222
  const inputFile = resolve16(tmpDir, "input.json");
111232
111223
  const outputFile = resolve16(tmpDir, "output.json");
111233
111224
  await writeFile8(inputFile, JSON.stringify(options));
111234
- const timeoutMs = this.timeoutInSeconds ? Math.max(this.timeoutInSeconds * 1.5, this.timeoutInSeconds + 30) * 1e3 : 750 * 1e3;
111225
+ const timeoutMs = Math.max(effectiveTimeout * 1.5, effectiveTimeout + 30) * 1e3;
111235
111226
  const result = await execNeverFail2(cmdt`${await getNodeExecutable(ToolPathResolver.nodeExecutablePath)} ${getClassGraphAnalysisCliPath()} runRustReachabilityAnalysis -i ${inputFile} -o ${outputFile} --tree-sitter-rust ${getTreeSitterRustPath()}`, void 0, { timeout: timeoutMs });
111236
111227
  if (result.error)
111237
111228
  return { type: "error", message: result.error.message ?? "unknown error" };
@@ -111549,36 +111540,27 @@ async function analyzePackages(ecosystem, packages, vulnerability, options) {
111549
111540
  switch (ecosystem) {
111550
111541
  case "NPM":
111551
111542
  analysisName = "Jelly";
111552
- result = await runWithJSHeuristics(async (h) => await JSCodeAwareVulnerabilityScanner.runOnDependencyChain(packages, vulnerability, {
111553
- timeoutInSeconds: options?.timeoutInSeconds ?? 60,
111554
- memoryLimitInMB: options?.memoryLimitInMB ?? 16384
111555
- }, h));
111543
+ result = await runWithJSHeuristics(async (h) => await JSCodeAwareVulnerabilityScanner.runOnDependencyChain(packages, vulnerability, options, h));
111556
111544
  break;
111557
111545
  case "MAVEN":
111558
111546
  analysisName = "Alucard";
111559
- result = await JavaCodeAwareVulnerabilityScanner.runOnDependencyChain(packages, vulnerability, options?.timeoutInSeconds ?? 60);
111547
+ result = await JavaCodeAwareVulnerabilityScanner.runOnDependencyChain(packages, vulnerability, options.timeoutSeconds.allVulnRuns);
111560
111548
  break;
111561
111549
  case "NUGET":
111562
111550
  analysisName = "Cocoa";
111563
- result = await DotnetCodeAwareVulnerabilityScanner.runOnDependencyChain(packages, vulnerability, options?.timeoutInSeconds ?? 60);
111551
+ result = await DotnetCodeAwareVulnerabilityScanner.runOnDependencyChain(packages, vulnerability, options.timeoutSeconds.allVulnRuns);
111564
111552
  break;
111565
111553
  case "PIP":
111566
111554
  analysisName = "Mambalade";
111567
- result = await PythonCodeAwareVulnerabilityScanner.runOnDependencyChain(packages, vulnerability, {
111568
- timeoutInSeconds: options?.timeoutInSeconds ?? 60,
111569
- memoryLimitInMB: options?.memoryLimitInMB ?? 16384
111570
- });
111555
+ result = await PythonCodeAwareVulnerabilityScanner.runOnDependencyChain(packages, vulnerability, options);
111571
111556
  break;
111572
111557
  case "GO":
111573
111558
  analysisName = "Goana";
111574
- result = await GoCodeAwareVulnerabilityScanner.runOnDependencyChain(packages, vulnerability, {
111575
- timeoutInSeconds: options?.timeoutInSeconds ?? 60,
111576
- memoryLimitInMB: options?.memoryLimitInMB ?? 16384
111577
- });
111559
+ result = await GoCodeAwareVulnerabilityScanner.runOnDependencyChain(packages, vulnerability, options);
111578
111560
  break;
111579
111561
  case "RUST":
111580
111562
  analysisName = "Rustica";
111581
- result = await RustCodeAwareVulnerabilityScanner.runOnDependencyChain(packages, vulnerability, options?.timeoutInSeconds ?? 60);
111563
+ result = await RustCodeAwareVulnerabilityScanner.runOnDependencyChain(packages, vulnerability, options.timeoutSeconds.allVulnRuns);
111582
111564
  break;
111583
111565
  default:
111584
111566
  throw new Error(`Analyze dependency chain not implemented for ${ecosystem}.`);
@@ -111591,45 +111573,27 @@ async function analyzeAlreadyInstalledPackages(ecosystem, packages, vulnerabilit
111591
111573
  switch (ecosystem) {
111592
111574
  case "NPM":
111593
111575
  analysisName = "Jelly";
111594
- result = await runWithJSHeuristics(async (h) => await JSCodeAwareVulnerabilityScanner.runOnAlreadyDownloadedPackages(packages, vulnerability, {
111595
- timeoutInSeconds: options?.timeoutInSeconds ?? 60,
111596
- memoryLimitInMB: options?.memoryLimitInMB ?? 16384
111597
- }, h));
111576
+ result = await runWithJSHeuristics(async (h) => await JSCodeAwareVulnerabilityScanner.runOnAlreadyDownloadedPackages(packages, vulnerability, options, h));
111598
111577
  break;
111599
111578
  case "MAVEN":
111600
111579
  analysisName = "Alucard";
111601
- result = await JavaCodeAwareVulnerabilityScanner.runOnAlreadyDownloadedPackages(packages, vulnerability, {
111602
- timeoutInSeconds: options?.timeoutInSeconds ?? 60,
111603
- memoryLimitInMB: options?.memoryLimitInMB ?? 16384
111604
- });
111580
+ result = await JavaCodeAwareVulnerabilityScanner.runOnAlreadyDownloadedPackages(packages, vulnerability, options);
111605
111581
  break;
111606
111582
  case "NUGET":
111607
111583
  analysisName = "Cocoa";
111608
- result = await DotnetCodeAwareVulnerabilityScanner.runOnAlreadyDownloadedPackages(packages, vulnerability, {
111609
- timeoutInSeconds: options?.timeoutInSeconds ?? 60,
111610
- memoryLimitInMB: options?.memoryLimitInMB ?? 16384
111611
- });
111584
+ result = await DotnetCodeAwareVulnerabilityScanner.runOnAlreadyDownloadedPackages(packages, vulnerability, options);
111612
111585
  break;
111613
111586
  case "PIP":
111614
111587
  analysisName = "Mambalade";
111615
- result = await PythonCodeAwareVulnerabilityScanner.runOnAlreadyDownloadedPackages(packages, vulnerability, {
111616
- timeoutInSeconds: options?.timeoutInSeconds ?? 60,
111617
- memoryLimitInMB: options?.memoryLimitInMB ?? 16384
111618
- });
111588
+ result = await PythonCodeAwareVulnerabilityScanner.runOnAlreadyDownloadedPackages(packages, vulnerability, options);
111619
111589
  break;
111620
111590
  case "GO":
111621
111591
  analysisName = "Goana";
111622
- result = await GoCodeAwareVulnerabilityScanner.runOnAlreadyDownloadedPackages(packages, vulnerability, {
111623
- timeoutInSeconds: options?.timeoutInSeconds ?? 60,
111624
- memoryLimitInMB: options?.memoryLimitInMB ?? 16384
111625
- });
111592
+ result = await GoCodeAwareVulnerabilityScanner.runOnAlreadyDownloadedPackages(packages, vulnerability, options);
111626
111593
  break;
111627
111594
  case "RUST":
111628
111595
  analysisName = "Rustica";
111629
- result = await RustCodeAwareVulnerabilityScanner.runOnAlreadyDownloadedPackages(packages, vulnerability, {
111630
- timeoutInSeconds: options?.timeoutInSeconds ?? 60,
111631
- memoryLimitInMB: options?.memoryLimitInMB ?? 16384
111632
- });
111596
+ result = await RustCodeAwareVulnerabilityScanner.runOnAlreadyDownloadedPackages(packages, vulnerability, options);
111633
111597
  break;
111634
111598
  default:
111635
111599
  throw new Error(`analyzePackageRegistryPackage is not implemented for ${ecosystem}.`);
@@ -111723,7 +111687,7 @@ var PythonCodeAwareVulnerabilityScanner = class {
111723
111687
  logger.info("Done setting up virtual environment");
111724
111688
  }
111725
111689
  }
111726
- async runAnalysis(vulns, heuristic, analyzesAllVulns) {
111690
+ async runAnalysis(vulns, heuristic, timeoutInSeconds) {
111727
111691
  if (!this.virtualEnvInfo)
111728
111692
  throw new Error("Virtual environment not set up");
111729
111693
  this.mambaladeVenvPath ??= await setupMambalade();
@@ -111753,8 +111717,6 @@ var PythonCodeAwareVulnerabilityScanner = class {
111753
111717
  const vulnsOutputFile = join16(tmpDir, "vulns.json");
111754
111718
  const diagnosticsOutputFile = join16(tmpDir, "diagnostics.json");
111755
111719
  const reachedPackagesOutputFile = join16(tmpDir, "reached-packages.json");
111756
- const timeout = reachabilityAnalysisOptions.timeoutInSeconds ?? // 10 minutes for the first analysis, 1 minute for subsequent analyses
111757
- (analyzesAllVulns ? 60 * 10 : 60);
111758
111720
  const pythonExecutable = join16(this.mambaladeVenvPath, "bin", "python");
111759
111721
  const mambaladeArgs = cmdt`\
111760
111722
  ${pythonExecutable} - ${reachabilityAnalysisOptions.memoryLimitInMB ?? 0}
@@ -111764,7 +111726,7 @@ var PythonCodeAwareVulnerabilityScanner = class {
111764
111726
  --output-vulnerabilities ${vulnsOutputFile}
111765
111727
  --output-diagnostics ${diagnosticsOutputFile}
111766
111728
  --output-reached-distributions ${reachedPackagesOutputFile}
111767
- --timeout=${timeout}
111729
+ --timeout=${timeoutInSeconds}
111768
111730
  ${packagesToExclude?.size ? ["--exclude-distributions", ...packagesToExclude] : []}
111769
111731
  --
111770
111732
  ${filesToAnalyze}`;
@@ -111782,7 +111744,7 @@ ${vulnAccPaths.join("\n")}`);
111782
111744
  PYPY_GC_MAX: `${reachabilityAnalysisOptions.memoryLimitInMB ?? 0}MB`
111783
111745
  },
111784
111746
  // Forcefully kill the process if the internal timeout mechanism fails
111785
- timeout: (timeout * 1.5 + 15) * 1e3
111747
+ timeout: (timeoutInSeconds * 1.5 + 15) * 1e3
111786
111748
  });
111787
111749
  logger.debug("Done running mambalade");
111788
111750
  const errors = stderr.split("\n").filter((line) => line.startsWith("ERROR:") && !/^ERROR: Excluded distribution/.test(line));
@@ -111876,7 +111838,7 @@ ${msg}`;
111876
111838
  await cp6(dep, dependencyDir, { recursive: true });
111877
111839
  fileMappings.set(dependencyDir, dep);
111878
111840
  }
111879
- const result = await scanner.runAnalysis([vuln], MambaladeHeuristics.ALL_PACKAGES, false);
111841
+ const result = await scanner.runAnalysis([vuln], MambaladeHeuristics.ALL_PACKAGES, options.timeoutSeconds.allVulnRuns);
111880
111842
  if (result.type === "error")
111881
111843
  return { error: result.message, terminatedEarly: true };
111882
111844
  return {
@@ -111916,7 +111878,7 @@ ${msg}`;
111916
111878
  ]);
111917
111879
  if (scanner.virtualEnvInfo.packageInstallationStats.failedToInstall.length)
111918
111880
  throw new Error("Failed to install some packages");
111919
- const result = await scanner.runAnalysis([vuln], MambaladeHeuristics.ALL_PACKAGES, false);
111881
+ const result = await scanner.runAnalysis([vuln], MambaladeHeuristics.ALL_PACKAGES, options.timeoutSeconds.allVulnRuns);
111920
111882
  if (result.type === "error")
111921
111883
  return { error: result.message, terminatedEarly: true };
111922
111884
  return {
@@ -112510,8 +112472,9 @@ async function analyzeWithHeuristics(state, vulns, heuristicsInOrder, doNotRecom
112510
112472
  try {
112511
112473
  newAnalysisRunListener();
112512
112474
  const initialBucketContainingAllVulns = buckets.length === 1 && buckets[0] === bucket;
112475
+ const timeoutInSeconds = initialBucketContainingAllVulns ? state.reachabilityAnalysisOptions.timeoutSeconds.allVulnRuns : state.reachabilityAnalysisOptions.timeoutSeconds.bucketedRuns;
112513
112476
  logger.info(`Running full reachability analysis for ${vulnsForBucket.length}/${vulnerabilities.length} vulnerabilities.`);
112514
- const result = await codeAwareScanner.runAnalysis(vulnsForBucket, bucket.heuristic, initialBucketContainingAllVulns, experiment);
112477
+ const result = await codeAwareScanner.runAnalysis(vulnsForBucket, bucket.heuristic, timeoutInSeconds, experiment);
112515
112478
  const allowSplitInBuckets = !disableBucketing && bucket.heuristic.splitAnalysisInBuckets && !state.otherAnalysisOptions.disableBucketing && vulnDepIdentifiers.length > 1 && (result.type === "error" || result.reachedDependencies);
112516
112479
  if (result.type === "success") {
112517
112480
  result.diagnostics.timings ??= {};
@@ -112532,13 +112495,7 @@ async function analyzeWithHeuristics(state, vulns, heuristicsInOrder, doNotRecom
112532
112495
  await analysisMetadataCollector2?.(finalAnalysisMetadata);
112533
112496
  } else {
112534
112497
  result.type;
112535
- const enqueueWithoutSplitting = !allowSplitInBuckets && initialBucketContainingAllVulns && !state.reachabilityAnalysisOptions.timeoutInSeconds;
112536
- await sendErrorAnalysisMetadata(result.message, !allowSplitInBuckets && isLastHeuristic(bucket.heuristic.name) && !enqueueWithoutSplitting, !allowSplitInBuckets);
112537
- if (enqueueWithoutSplitting) {
112538
- logger.info("Analysis failed, retrying different configuration.");
112539
- enqueueBucket(vulnDepIdentifiers);
112540
- return;
112541
- }
112498
+ await sendErrorAnalysisMetadata(result.message, !allowSplitInBuckets && isLastHeuristic(bucket.heuristic.name), !allowSplitInBuckets);
112542
112499
  if (!allowSplitInBuckets) {
112543
112500
  augmentVulnsWithErrorMessage(vulnsForBucket, result.message);
112544
112501
  return;
@@ -112794,12 +112751,12 @@ var MavenAnalyzer = class {
112794
112751
  async runPhantomDependencyAnalysis() {
112795
112752
  return withTmpDirectory("maven-phantom-dependency-analysis", async (tmpDir) => {
112796
112753
  const scanner = this.state.workspaceData.type === "coana" ? await JavaCodeAwareVulnerabilityScanner.initFromDependencyTree(this.state.workspaceData.data.dependencyTree, tmpDir) : await JavaCodeAwareVulnerabilityScanner.initFromSocketArtifacts(this.state.subprojectDir, this.state.workspaceData.data.artifacts, tmpDir);
112797
- return scanner.runPhantomDependencyAnalysis();
112754
+ return scanner.runPhantomDependencyAnalysis(this.state.reachabilityAnalysisOptions.timeoutSeconds.allVulnRuns);
112798
112755
  });
112799
112756
  }
112800
112757
  async runReachabilityAnalysis(vulns, analysisMetadataCollector, statusUpdater) {
112801
112758
  return withTmpDirectory("maven-reachability-analysis", async (tmpDir) => {
112802
- const scanner = this.state.workspaceData.type === "coana" ? await JavaCodeAwareVulnerabilityScanner.initFromDependencyTree(this.state.workspaceData.data.dependencyTree, tmpDir, this.state.reachabilityAnalysisOptions.timeoutInSeconds, statusUpdater) : await JavaCodeAwareVulnerabilityScanner.initFromSocketArtifacts(this.state.subprojectDir, this.state.workspaceData.data.artifacts, tmpDir, this.state.reachabilityAnalysisOptions.timeoutInSeconds, statusUpdater);
112759
+ const scanner = this.state.workspaceData.type === "coana" ? await JavaCodeAwareVulnerabilityScanner.initFromDependencyTree(this.state.workspaceData.data.dependencyTree, tmpDir, statusUpdater) : await JavaCodeAwareVulnerabilityScanner.initFromSocketArtifacts(this.state.subprojectDir, this.state.workspaceData.data.artifacts, tmpDir, statusUpdater);
112803
112760
  const heuristicsInOrder = [AlucardHeuristics.ALL_PACKAGES];
112804
112761
  return await analyzeWithHeuristics(this.state, vulns, heuristicsInOrder, false, scanner, analysisMetadataCollector, statusUpdater);
112805
112762
  });
@@ -112932,12 +112889,12 @@ var NugetAnalyzer = class {
112932
112889
  async runPhantomDependencyAnalysis() {
112933
112890
  return withTmpDirectory("nuget-phantom-dependency-analysis", async (tmpDir) => {
112934
112891
  const scanner = this.state.workspaceData.type === "coana" ? DotnetCodeAwareVulnerabilityScanner.initFromDependencyTree(this.state.workspaceData.data.dependencyTree) : await DotnetCodeAwareVulnerabilityScanner.initFromSocketArtifacts(this.state.subprojectDir, this.state.workspaceData.data.manifestFiles, this.state.workspaceData.data.artifacts, tmpDir);
112935
- return scanner.runPhantomDependencyAnalysis();
112892
+ return scanner.runPhantomDependencyAnalysis(this.state.reachabilityAnalysisOptions.timeoutSeconds.allVulnRuns);
112936
112893
  });
112937
112894
  }
112938
112895
  async runReachabilityAnalysis(vulns, analysisMetadataCollector, statusUpdater) {
112939
112896
  return withTmpDirectory("nuget-reachability-analysis", async (tmpDir) => {
112940
- const scanner = this.state.workspaceData.type === "coana" ? DotnetCodeAwareVulnerabilityScanner.initFromDependencyTree(this.state.workspaceData.data.dependencyTree, this.state.reachabilityAnalysisOptions.timeoutInSeconds, statusUpdater) : await DotnetCodeAwareVulnerabilityScanner.initFromSocketArtifacts(this.state.subprojectDir, this.state.workspaceData.data.manifestFiles, this.state.workspaceData.data.artifacts, tmpDir, this.state.reachabilityAnalysisOptions.timeoutInSeconds, statusUpdater);
112897
+ const scanner = this.state.workspaceData.type === "coana" ? DotnetCodeAwareVulnerabilityScanner.initFromDependencyTree(this.state.workspaceData.data.dependencyTree, statusUpdater) : await DotnetCodeAwareVulnerabilityScanner.initFromSocketArtifacts(this.state.subprojectDir, this.state.workspaceData.data.manifestFiles, this.state.workspaceData.data.artifacts, tmpDir, statusUpdater);
112941
112898
  const heuristicsInOrder = [CocoaHeuristics.ALL_PACKAGES];
112942
112899
  return await analyzeWithHeuristics(this.state, vulns, heuristicsInOrder, false, scanner, analysisMetadataCollector, statusUpdater);
112943
112900
  });
@@ -116307,7 +116264,7 @@ var RubyCodeAwareVulnerabilityScanner = class {
116307
116264
  this.vendorDirWasCreated = true;
116308
116265
  logger.info("Done setting up vendor directory");
116309
116266
  }
116310
- async runAnalysis(vulns, heuristic, analyzesAllVulns, _experiment) {
116267
+ async runAnalysis(vulns, heuristic, timeoutInSeconds, _experiment) {
116311
116268
  return await withTmpDirectory("ruby-analyzer-output", async (tmpDir) => {
116312
116269
  if (!this.vendorDir)
116313
116270
  throw new Error("Assertion error: The vendor directory is not correctly initialized");
@@ -116334,7 +116291,7 @@ var RubyCodeAwareVulnerabilityScanner = class {
116334
116291
  const cmd = cmdt`
116335
116292
  ${await getNodeExecutable(ToolPathResolver.nodeExecutablePath)} --max-old-space-size=${this.options.memoryLimitInMB}
116336
116293
  ${analyzerPath}
116337
- --timeout ${analyzesAllVulns ? this.options.timeoutInSeconds ?? 600 : 60}
116294
+ --timeout ${timeoutInSeconds}
116338
116295
  --load-path ${loadPaths}
116339
116296
  --vulnerabilities ${vulnAccPaths}
116340
116297
  --output-diagnostics ${diagnosticsOutputFile}
@@ -116533,12 +116490,12 @@ var RustAnalyzer = class {
116533
116490
  async runPhantomDependencyAnalysis() {
116534
116491
  return withTmpDirectory("cargo-phantom-dependency-analysis", async (tmpDir) => {
116535
116492
  const scanner = this.state.workspaceData.type === "coana" ? RustCodeAwareVulnerabilityScanner.initFromDependencyTree(this.state.workspaceData.data.dependencyTree) : await RustCodeAwareVulnerabilityScanner.initFromSocketArtifacts(this.state.subprojectDir, this.state.workspacePath, this.state.workspaceData.data.artifacts, tmpDir);
116536
- return scanner.runPhantomDependencyAnalysis();
116493
+ return scanner.runPhantomDependencyAnalysis(this.state.reachabilityAnalysisOptions.timeoutSeconds.allVulnRuns);
116537
116494
  });
116538
116495
  }
116539
116496
  async runReachabilityAnalysis(vulns, analysisMetadataCollector, statusUpdater) {
116540
116497
  return withTmpDirectory("cargo-reachability-analysis", async (tmpDir) => {
116541
- const scanner = this.state.workspaceData.type === "coana" ? RustCodeAwareVulnerabilityScanner.initFromDependencyTree(this.state.workspaceData.data.dependencyTree, this.state.reachabilityAnalysisOptions.timeoutInSeconds, statusUpdater) : await RustCodeAwareVulnerabilityScanner.initFromSocketArtifacts(this.state.subprojectDir, this.state.workspacePath, this.state.workspaceData.data.artifacts, tmpDir, this.state.reachabilityAnalysisOptions.timeoutInSeconds, statusUpdater);
116498
+ const scanner = this.state.workspaceData.type === "coana" ? RustCodeAwareVulnerabilityScanner.initFromDependencyTree(this.state.workspaceData.data.dependencyTree, statusUpdater) : await RustCodeAwareVulnerabilityScanner.initFromSocketArtifacts(this.state.subprojectDir, this.state.workspacePath, this.state.workspaceData.data.artifacts, tmpDir, statusUpdater);
116542
116499
  const heuristicsInOrder = [RusticaHeuristics.ALL_PACKAGES];
116543
116500
  return await analyzeWithHeuristics(this.state, vulns, heuristicsInOrder, false, scanner, analysisMetadataCollector, statusUpdater);
116544
116501
  });
@@ -116597,7 +116554,11 @@ var runReachabilityAnalysisCmd = new Command().name("runReachabilityAnalysis").a
116597
116554
  }, "reachability-analyzer"));
116598
116555
  var runOnDependencyChainCmd = new Command().name("runOnDependencyChain").option("-d, --debug", "Enable debug logging", false).option("-s, --silent", "Silence all debug/warning output", false).option("--coana-socket-path <socketPath>", "Coana socket path").option("--silent-spinner", "Silence spinner", "CI" in process.env || !process.stdin.isTTY).requiredOption("-i, --input-file <inputFile>", "Input file for data and vulnerabilities").requiredOption("-o, --output-file <outputFile>", "Output file for the results").configureHelp({ sortSubcommands: true, sortOptions: true }).action(async (options) => withLoggerAndSpinner("Coana Reachability Analyzers", options, async () => {
116599
116556
  const { ecosystem, dependencyChain, vulnerability } = JSON.parse(await readFile14(options.inputFile, "utf-8"));
116600
- const result = await analyzePackages(ecosystem, deserializeDependencyChain(ecosystem, dependencyChain), vulnerability);
116557
+ const defaultOptions2 = {
116558
+ timeoutSeconds: { allVulnRuns: 60, bucketedRuns: 60 },
116559
+ memoryLimitInMB: 16384
116560
+ };
116561
+ const result = await analyzePackages(ecosystem, deserializeDependencyChain(ecosystem, dependencyChain), vulnerability, defaultOptions2);
116601
116562
  if (options.outputFile) {
116602
116563
  logger.debug("Writing result to file", options.outputFile);
116603
116564
  await writeFile9(options.outputFile, JSON.stringify({ result }));
@@ -116625,7 +116586,12 @@ var runOnPackageRegistryPackageCmd = new Command().name("runOnPackageRegistryPac
116625
116586
  else if (typeof vulnerability.vulnerabilityAccessPaths === "string")
116626
116587
  throw new Error(`Vulnerability ${options.vulnerability} has undeterminable reachability, so running the reachability analysis is not possible.`);
116627
116588
  const isFile4 = mainPackage.startsWith("file://");
116628
- const result = isFile4 ? await analyzeAlreadyInstalledPackages(options.ecosystem, [mainPackage, ...options.dependencies].map((p) => p.replace("file://", "")), vulnerability, { timeoutInSeconds: +options.analysisTimeout, memoryLimitInMB: +options.memoryLimit }) : await analyzePackages(options.ecosystem, deserializeDependencyChain(options.ecosystem, `${mainPackage}${options.dependencies.length > 0 ? ` > ${options.dependencies.join(" > ")}` : ""}`), vulnerability, { timeoutInSeconds: +options.analysisTimeout, memoryLimitInMB: +options.memoryLimit });
116589
+ const analysisTimeout = +options.analysisTimeout;
116590
+ const reachabilityOptions = {
116591
+ timeoutSeconds: { allVulnRuns: analysisTimeout, bucketedRuns: analysisTimeout },
116592
+ memoryLimitInMB: +options.memoryLimit
116593
+ };
116594
+ const result = isFile4 ? await analyzeAlreadyInstalledPackages(options.ecosystem, [mainPackage, ...options.dependencies].map((p) => p.replace("file://", "")), vulnerability, reachabilityOptions) : await analyzePackages(options.ecosystem, deserializeDependencyChain(options.ecosystem, `${mainPackage}${options.dependencies.length > 0 ? ` > ${options.dependencies.join(" > ")}` : ""}`), vulnerability, reachabilityOptions);
116629
116595
  if (options.outputFile) {
116630
116596
  logger.info("Writing result to file", options.outputFile);
116631
116597
  await writeFile9(options.outputFile, JSON.stringify(result, null, 2));