@coana-tech/cli 14.12.143 → 14.12.144
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 +359 -130
- package/package.json +1 -1
- package/reachability-analyzers-cli.mjs +342 -123
- package/repos/coana-tech/goana/bin/goana-darwin-amd64.gz +0 -0
- package/repos/coana-tech/goana/bin/goana-darwin-arm64.gz +0 -0
- package/repos/coana-tech/goana/bin/goana-linux-amd64.gz +0 -0
- package/repos/coana-tech/goana/bin/goana-linux-arm64.gz +0 -0
- package/repos/coana-tech/javap-service/javap-service.jar +0 -0
|
@@ -35534,8 +35534,8 @@ var require_follow_redirects = __commonJS({
|
|
|
35534
35534
|
}
|
|
35535
35535
|
return parsed;
|
|
35536
35536
|
}
|
|
35537
|
-
function resolveUrl(
|
|
35538
|
-
return useNativeURL ? new URL3(
|
|
35537
|
+
function resolveUrl(relative11, base) {
|
|
35538
|
+
return useNativeURL ? new URL3(relative11, base) : parseUrl(url2.resolve(base, relative11));
|
|
35539
35539
|
}
|
|
35540
35540
|
function validateUrl(input) {
|
|
35541
35541
|
if (/^\[/.test(input.hostname) && !/^\[[:0-9a-f]+\]$/i.test(input.hostname)) {
|
|
@@ -46796,7 +46796,7 @@ var require_mock_interceptor = __commonJS({
|
|
|
46796
46796
|
var require_mock_client = __commonJS({
|
|
46797
46797
|
"../../node_modules/.pnpm/undici@5.28.5/node_modules/undici/lib/mock/mock-client.js"(exports, module) {
|
|
46798
46798
|
"use strict";
|
|
46799
|
-
var { promisify } = __require("util");
|
|
46799
|
+
var { promisify: promisify2 } = __require("util");
|
|
46800
46800
|
var Client = require_client();
|
|
46801
46801
|
var { buildMockDispatch } = require_mock_utils();
|
|
46802
46802
|
var {
|
|
@@ -46836,7 +46836,7 @@ var require_mock_client = __commonJS({
|
|
|
46836
46836
|
return new MockInterceptor(opts, this[kDispatches]);
|
|
46837
46837
|
}
|
|
46838
46838
|
async [kClose]() {
|
|
46839
|
-
await
|
|
46839
|
+
await promisify2(this[kOriginalClose])();
|
|
46840
46840
|
this[kConnected] = 0;
|
|
46841
46841
|
this[kMockAgent][Symbols.kClients].delete(this[kOrigin]);
|
|
46842
46842
|
}
|
|
@@ -46849,7 +46849,7 @@ var require_mock_client = __commonJS({
|
|
|
46849
46849
|
var require_mock_pool = __commonJS({
|
|
46850
46850
|
"../../node_modules/.pnpm/undici@5.28.5/node_modules/undici/lib/mock/mock-pool.js"(exports, module) {
|
|
46851
46851
|
"use strict";
|
|
46852
|
-
var { promisify } = __require("util");
|
|
46852
|
+
var { promisify: promisify2 } = __require("util");
|
|
46853
46853
|
var Pool = require_pool();
|
|
46854
46854
|
var { buildMockDispatch } = require_mock_utils();
|
|
46855
46855
|
var {
|
|
@@ -46889,7 +46889,7 @@ var require_mock_pool = __commonJS({
|
|
|
46889
46889
|
return new MockInterceptor(opts, this[kDispatches]);
|
|
46890
46890
|
}
|
|
46891
46891
|
async [kClose]() {
|
|
46892
|
-
await
|
|
46892
|
+
await promisify2(this[kOriginalClose])();
|
|
46893
46893
|
this[kConnected] = 0;
|
|
46894
46894
|
this[kMockAgent][Symbols.kClients].delete(this[kOrigin]);
|
|
46895
46895
|
}
|
|
@@ -57757,13 +57757,13 @@ var require_tmp = __commonJS({
|
|
|
57757
57757
|
var require_tmp_promise = __commonJS({
|
|
57758
57758
|
"../../node_modules/.pnpm/tmp-promise@3.0.3/node_modules/tmp-promise/index.js"(exports, module) {
|
|
57759
57759
|
"use strict";
|
|
57760
|
-
var { promisify } = __require("util");
|
|
57760
|
+
var { promisify: promisify2 } = __require("util");
|
|
57761
57761
|
var tmp = require_tmp();
|
|
57762
57762
|
module.exports.fileSync = tmp.fileSync;
|
|
57763
|
-
var fileWithOptions =
|
|
57763
|
+
var fileWithOptions = promisify2(
|
|
57764
57764
|
(options, cb) => tmp.file(
|
|
57765
57765
|
options,
|
|
57766
|
-
(err, path10, fd, cleanup) => err ? cb(err) : cb(void 0, { path: path10, fd, cleanup:
|
|
57766
|
+
(err, path10, fd, cleanup) => err ? cb(err) : cb(void 0, { path: path10, fd, cleanup: promisify2(cleanup) })
|
|
57767
57767
|
)
|
|
57768
57768
|
);
|
|
57769
57769
|
module.exports.file = async (options) => fileWithOptions(options);
|
|
@@ -57776,10 +57776,10 @@ var require_tmp_promise = __commonJS({
|
|
|
57776
57776
|
}
|
|
57777
57777
|
};
|
|
57778
57778
|
module.exports.dirSync = tmp.dirSync;
|
|
57779
|
-
var dirWithOptions =
|
|
57779
|
+
var dirWithOptions = promisify2(
|
|
57780
57780
|
(options, cb) => tmp.dir(
|
|
57781
57781
|
options,
|
|
57782
|
-
(err, path10, cleanup) => err ? cb(err) : cb(void 0, { path: path10, cleanup:
|
|
57782
|
+
(err, path10, cleanup) => err ? cb(err) : cb(void 0, { path: path10, cleanup: promisify2(cleanup) })
|
|
57783
57783
|
)
|
|
57784
57784
|
);
|
|
57785
57785
|
module.exports.dir = async (options) => dirWithOptions(options);
|
|
@@ -57792,7 +57792,7 @@ var require_tmp_promise = __commonJS({
|
|
|
57792
57792
|
}
|
|
57793
57793
|
};
|
|
57794
57794
|
module.exports.tmpNameSync = tmp.tmpNameSync;
|
|
57795
|
-
module.exports.tmpName =
|
|
57795
|
+
module.exports.tmpName = promisify2(tmp.tmpName);
|
|
57796
57796
|
module.exports.tmpdir = tmp.tmpdir;
|
|
57797
57797
|
module.exports.setGracefulCleanup = tmp.setGracefulCleanup;
|
|
57798
57798
|
}
|
|
@@ -59955,8 +59955,8 @@ var require_utils4 = __commonJS({
|
|
|
59955
59955
|
exports.toPosixSlashes = (str) => str.replace(REGEX_BACKSLASH, "/");
|
|
59956
59956
|
exports.isWindows = () => {
|
|
59957
59957
|
if (typeof navigator !== "undefined" && navigator.platform) {
|
|
59958
|
-
const
|
|
59959
|
-
return
|
|
59958
|
+
const platform7 = navigator.platform.toLowerCase();
|
|
59959
|
+
return platform7 === "win32" || platform7 === "windows";
|
|
59960
59960
|
}
|
|
59961
59961
|
if (typeof process !== "undefined" && process.platform) {
|
|
59962
59962
|
return process.platform === "win32";
|
|
@@ -79999,7 +79999,7 @@ function deserializeRustDependencyChainNode(s2) {
|
|
|
79999
79999
|
|
|
80000
80000
|
// dist/main.js
|
|
80001
80001
|
var import_lodash22 = __toESM(require_lodash(), 1);
|
|
80002
|
-
import { relative as
|
|
80002
|
+
import { relative as relative10, resolve as resolve22 } from "path";
|
|
80003
80003
|
|
|
80004
80004
|
// ../utils/src/dashboard-api/coana-api.ts
|
|
80005
80005
|
import { writeFile } from "fs/promises";
|
|
@@ -80226,15 +80226,6 @@ var import_form_data2 = __toESM(require_form_data(), 1);
|
|
|
80226
80226
|
import { readFile as readFile2 } from "node:fs/promises";
|
|
80227
80227
|
import { join } from "node:path";
|
|
80228
80228
|
|
|
80229
|
-
// ../web-compat-utils/src/ghsa.ts
|
|
80230
|
-
function extractGHSAIdFromUrl(url2) {
|
|
80231
|
-
const match2 = url2.match(/(GHSA-[a-z0-9-]+)/);
|
|
80232
|
-
if (match2) {
|
|
80233
|
-
return match2[1];
|
|
80234
|
-
}
|
|
80235
|
-
return void 0;
|
|
80236
|
-
}
|
|
80237
|
-
|
|
80238
80229
|
// ../../node_modules/.pnpm/remeda@2.21.2/node_modules/remeda/dist/chunk-ANXBDSUI.js
|
|
80239
80230
|
var s = { done: false, hasNext: false };
|
|
80240
80231
|
|
|
@@ -80536,30 +80527,7 @@ async function registerCLIProgressSocket(isStartEvent, cliProgressEvent, tier1Sc
|
|
|
80536
80527
|
handleError(error, "Error registering CLI progress", false);
|
|
80537
80528
|
}
|
|
80538
80529
|
}
|
|
80539
|
-
async function registerAnalysisMetadataSocket(
|
|
80540
|
-
if (!tier1ScanId) {
|
|
80541
|
-
return;
|
|
80542
|
-
}
|
|
80543
|
-
const abnormalExit = analysisMetadata.analysisDiagnostics.aborted ? "ABORTED" : analysisMetadata.analysisDiagnostics.timeout ? "TIMEOUT" : "NONE";
|
|
80544
|
-
try {
|
|
80545
|
-
const url2 = getSocketApiUrl("tier1-reachability-scan/analysis-metadata");
|
|
80546
|
-
const data2 = {
|
|
80547
|
-
tier1_reachability_scan_id: tier1ScanId,
|
|
80548
|
-
subproject_path: subprojectPath,
|
|
80549
|
-
workspace_path: workspacePath,
|
|
80550
|
-
ghsa_ids: analysisMetadata.vulnUrls.map((vUrl) => extractGHSAIdFromUrl(vUrl)).filter((ghsaId) => ghsaId !== void 0),
|
|
80551
|
-
analysis_diagnostics: analysisMetadata.analysisDiagnostics,
|
|
80552
|
-
heuristic_name: analysisMetadata.heuristicName,
|
|
80553
|
-
is_final_result: analysisMetadata.finalResult,
|
|
80554
|
-
purl_type: getPurlType(ecosystem),
|
|
80555
|
-
error_message: analysisMetadata.errorMessage,
|
|
80556
|
-
experiment_name: analysisMetadata.experiment,
|
|
80557
|
-
abnormal_exit: abnormalExit
|
|
80558
|
-
};
|
|
80559
|
-
await axios2.put(url2, data2, { headers: getAuthHeaders() });
|
|
80560
|
-
} catch (error) {
|
|
80561
|
-
handleError(error, "Error registering analysis metadata", false);
|
|
80562
|
-
}
|
|
80530
|
+
async function registerAnalysisMetadataSocket(_subprojectPath, _workspacePath, _ecosystem, _analysisMetadata, _tier1ScanId) {
|
|
80563
80531
|
}
|
|
80564
80532
|
async function getLatestBucketsSocket(subprojectPath, workspacePath) {
|
|
80565
80533
|
try {
|
|
@@ -80667,6 +80635,54 @@ async function sendLogChunkSocket(reportId, logs) {
|
|
|
80667
80635
|
console.warn("Failed to send log chunk to Socket:", error.message);
|
|
80668
80636
|
}
|
|
80669
80637
|
}
|
|
80638
|
+
async function createAnalysisMetadataSocket(tier1ScanId, subprojectPath, workspacePath, ecosystem, ghsaIds, heuristicName, experimentName) {
|
|
80639
|
+
if (!tier1ScanId) return void 0;
|
|
80640
|
+
try {
|
|
80641
|
+
const url2 = getSocketApiUrl("tier1-reachability-scan/create-analysis-metadata");
|
|
80642
|
+
const data2 = {
|
|
80643
|
+
tier1_reachability_scan_id: tier1ScanId,
|
|
80644
|
+
subproject_path: subprojectPath,
|
|
80645
|
+
workspace_path: workspacePath,
|
|
80646
|
+
purl_type: getPurlType(ecosystem),
|
|
80647
|
+
ghsa_ids: ghsaIds,
|
|
80648
|
+
heuristic_name: heuristicName,
|
|
80649
|
+
experiment_name: experimentName
|
|
80650
|
+
};
|
|
80651
|
+
const response = await axios2.post(url2, data2, { headers: getAuthHeaders() });
|
|
80652
|
+
return response.data.analysis_metadata_id;
|
|
80653
|
+
} catch (error) {
|
|
80654
|
+
handleError(error, "Error creating analysis metadata", false);
|
|
80655
|
+
return void 0;
|
|
80656
|
+
}
|
|
80657
|
+
}
|
|
80658
|
+
async function sendTelemetrySocket(analysisMetadataId, telemetry) {
|
|
80659
|
+
try {
|
|
80660
|
+
const url2 = getSocketApiUrl("tier1-reachability-scan/add-telemetry");
|
|
80661
|
+
const data2 = {
|
|
80662
|
+
analysis_metadata_id: analysisMetadataId,
|
|
80663
|
+
telemetry
|
|
80664
|
+
};
|
|
80665
|
+
await axios2.post(url2, data2, { headers: getAuthHeaders() });
|
|
80666
|
+
} catch (error) {
|
|
80667
|
+
console.warn("Failed to send telemetry to Socket:", error.message);
|
|
80668
|
+
}
|
|
80669
|
+
}
|
|
80670
|
+
async function registerDiagnosticsToAnalysisMetadataSocket(analysisMetadataId, diagnosticsData) {
|
|
80671
|
+
const abnormalExit = diagnosticsData.analysisDiagnostics.aborted ? "ABORTED" : diagnosticsData.analysisDiagnostics.timeout ? "TIMEOUT" : "NONE";
|
|
80672
|
+
try {
|
|
80673
|
+
const url2 = getSocketApiUrl("tier1-reachability-scan/register-diagnostics-to-analysis-metadata");
|
|
80674
|
+
const data2 = {
|
|
80675
|
+
analysis_metadata_id: analysisMetadataId,
|
|
80676
|
+
analysis_diagnostics: diagnosticsData.analysisDiagnostics,
|
|
80677
|
+
is_final_result: diagnosticsData.finalResult,
|
|
80678
|
+
error_message: diagnosticsData.errorMessage,
|
|
80679
|
+
abnormal_exit: abnormalExit
|
|
80680
|
+
};
|
|
80681
|
+
await axios2.post(url2, data2, { headers: getAuthHeaders() });
|
|
80682
|
+
} catch (error) {
|
|
80683
|
+
handleError(error, "Error registering diagnostics to analysis metadata", false);
|
|
80684
|
+
}
|
|
80685
|
+
}
|
|
80670
80686
|
function getSocketAPI() {
|
|
80671
80687
|
return {
|
|
80672
80688
|
createSocketTier1Scan,
|
|
@@ -80679,7 +80695,10 @@ function getSocketAPI() {
|
|
|
80679
80695
|
finalizeAutofixRun,
|
|
80680
80696
|
registerUpgradePurlRun,
|
|
80681
80697
|
finalizeUpgradePurlRun,
|
|
80682
|
-
sendLogChunkSocket
|
|
80698
|
+
sendLogChunkSocket,
|
|
80699
|
+
createAnalysisMetadataSocket,
|
|
80700
|
+
sendTelemetrySocket,
|
|
80701
|
+
registerDiagnosticsToAnalysisMetadataSocket
|
|
80683
80702
|
};
|
|
80684
80703
|
}
|
|
80685
80704
|
|
|
@@ -80796,6 +80815,39 @@ var DashboardAPI = class {
|
|
|
80796
80815
|
await this.socketAPI.sendLogChunkSocket(reportId, logs);
|
|
80797
80816
|
}
|
|
80798
80817
|
}
|
|
80818
|
+
async createAnalysisMetadata(tier1ScanId, subprojectPath, workspacePath, ecosystem, ghsaIds, heuristicName, experimentName) {
|
|
80819
|
+
if (this.disableAnalyticsSharing) {
|
|
80820
|
+
return void 0;
|
|
80821
|
+
}
|
|
80822
|
+
if (this.socketMode) {
|
|
80823
|
+
return await this.socketAPI.createAnalysisMetadataSocket(
|
|
80824
|
+
tier1ScanId,
|
|
80825
|
+
subprojectPath,
|
|
80826
|
+
workspacePath,
|
|
80827
|
+
ecosystem,
|
|
80828
|
+
ghsaIds,
|
|
80829
|
+
heuristicName,
|
|
80830
|
+
experimentName
|
|
80831
|
+
);
|
|
80832
|
+
}
|
|
80833
|
+
return void 0;
|
|
80834
|
+
}
|
|
80835
|
+
async sendTelemetry(analysisMetadataId, telemetry) {
|
|
80836
|
+
if (this.disableAnalyticsSharing) {
|
|
80837
|
+
return;
|
|
80838
|
+
}
|
|
80839
|
+
if (this.socketMode) {
|
|
80840
|
+
await this.socketAPI.sendTelemetrySocket(analysisMetadataId, telemetry);
|
|
80841
|
+
}
|
|
80842
|
+
}
|
|
80843
|
+
async registerDiagnosticsToAnalysisMetadata(analysisMetadataId, diagnosticsData) {
|
|
80844
|
+
if (this.disableAnalyticsSharing || !analysisMetadataId) {
|
|
80845
|
+
return;
|
|
80846
|
+
}
|
|
80847
|
+
if (this.socketMode) {
|
|
80848
|
+
this.socketAPI.registerDiagnosticsToAnalysisMetadataSocket(analysisMetadataId, diagnosticsData).catch((err) => logger.debug("Failed to register diagnostics to analysis metadata:", err));
|
|
80849
|
+
}
|
|
80850
|
+
}
|
|
80799
80851
|
};
|
|
80800
80852
|
|
|
80801
80853
|
// dist/analyzers/go-analyzer.js
|
|
@@ -80823,7 +80875,68 @@ import { join as join3 } from "path";
|
|
|
80823
80875
|
|
|
80824
80876
|
// ../utils/src/command-utils.ts
|
|
80825
80877
|
import assert from "assert";
|
|
80878
|
+
import { execFile as execFile2 } from "child_process";
|
|
80879
|
+
|
|
80880
|
+
// ../utils/src/telemetry/telemetry-collector.ts
|
|
80826
80881
|
import { execFile } from "child_process";
|
|
80882
|
+
import { platform } from "os";
|
|
80883
|
+
import { promisify } from "util";
|
|
80884
|
+
var execFileAsync = promisify(execFile);
|
|
80885
|
+
var TelemetryCollector = class {
|
|
80886
|
+
/**
|
|
80887
|
+
* Collect memory metrics for a child process by PID.
|
|
80888
|
+
* Uses OS-specific commands to query memory usage.
|
|
80889
|
+
*
|
|
80890
|
+
* @param pid - The process ID to query
|
|
80891
|
+
* @returns TelemetryMetrics or undefined if the process doesn't exist or query fails
|
|
80892
|
+
*/
|
|
80893
|
+
async collectChildProcessMetrics(pid) {
|
|
80894
|
+
if (!Number.isInteger(pid) || pid <= 0) {
|
|
80895
|
+
return void 0;
|
|
80896
|
+
}
|
|
80897
|
+
try {
|
|
80898
|
+
const currentPlatform = platform();
|
|
80899
|
+
if (currentPlatform === "darwin" || currentPlatform === "linux") {
|
|
80900
|
+
return await this.collectUnixProcessMetrics(pid);
|
|
80901
|
+
}
|
|
80902
|
+
return void 0;
|
|
80903
|
+
} catch {
|
|
80904
|
+
return void 0;
|
|
80905
|
+
}
|
|
80906
|
+
}
|
|
80907
|
+
/**
|
|
80908
|
+
* Collect metrics for a Unix-like system (macOS, Linux) using ps command.
|
|
80909
|
+
*/
|
|
80910
|
+
async collectUnixProcessMetrics(pid) {
|
|
80911
|
+
try {
|
|
80912
|
+
const { stdout } = await execFileAsync("ps", ["-o", "rss=,pcpu=", "-p", String(pid)], {
|
|
80913
|
+
timeout: 5e3
|
|
80914
|
+
});
|
|
80915
|
+
const trimmed = stdout.trim();
|
|
80916
|
+
if (!trimmed) {
|
|
80917
|
+
return void 0;
|
|
80918
|
+
}
|
|
80919
|
+
const parts = trimmed.split(/\s+/);
|
|
80920
|
+
if (parts.length < 2) {
|
|
80921
|
+
return void 0;
|
|
80922
|
+
}
|
|
80923
|
+
const rssKb = parseInt(parts[0], 10);
|
|
80924
|
+
const cpuPercent = parseFloat(parts[1]);
|
|
80925
|
+
if (isNaN(rssKb) || isNaN(cpuPercent)) {
|
|
80926
|
+
return void 0;
|
|
80927
|
+
}
|
|
80928
|
+
const rssBytes = rssKb * 1024;
|
|
80929
|
+
return {
|
|
80930
|
+
rss: rssBytes,
|
|
80931
|
+
cpuPercent
|
|
80932
|
+
};
|
|
80933
|
+
} catch {
|
|
80934
|
+
return void 0;
|
|
80935
|
+
}
|
|
80936
|
+
}
|
|
80937
|
+
};
|
|
80938
|
+
|
|
80939
|
+
// ../utils/src/command-utils.ts
|
|
80827
80940
|
var DEFAULT_TIMEOUT_MS = 30 * 60 * 1e3;
|
|
80828
80941
|
async function execAndLogOnFailure(cmd, dir, options, logLevel = "info") {
|
|
80829
80942
|
const result = await execNeverFail(cmd, dir, options);
|
|
@@ -80852,14 +80965,35 @@ function startHeartbeat(options) {
|
|
|
80852
80965
|
timer.unref?.();
|
|
80853
80966
|
return () => clearInterval(timer);
|
|
80854
80967
|
}
|
|
80968
|
+
var DEFAULT_TELEMETRY_INTERVAL_MS = 5e3;
|
|
80969
|
+
function startTelemetry(pid, handler) {
|
|
80970
|
+
const collector = new TelemetryCollector();
|
|
80971
|
+
const intervalMs = handler.intervalMs ?? DEFAULT_TELEMETRY_INTERVAL_MS;
|
|
80972
|
+
const collectAndReport = async () => {
|
|
80973
|
+
const metrics = await collector.collectChildProcessMetrics(pid);
|
|
80974
|
+
if (metrics) {
|
|
80975
|
+
handler.onTelemetry(metrics);
|
|
80976
|
+
}
|
|
80977
|
+
};
|
|
80978
|
+
collectAndReport().catch((err) => {
|
|
80979
|
+
logger.debug("Initial telemetry collection failed:", err);
|
|
80980
|
+
});
|
|
80981
|
+
const timer = setInterval(() => {
|
|
80982
|
+
collectAndReport().catch(() => {
|
|
80983
|
+
});
|
|
80984
|
+
}, intervalMs);
|
|
80985
|
+
timer.unref?.();
|
|
80986
|
+
return () => clearInterval(timer);
|
|
80987
|
+
}
|
|
80855
80988
|
async function execNeverFail(cmd, dir, options) {
|
|
80856
80989
|
const stopHeartbeat = options?.heartbeat ? startHeartbeat(options.heartbeat) : void 0;
|
|
80990
|
+
let stopTelemetry;
|
|
80857
80991
|
try {
|
|
80858
80992
|
return await new Promise((resolve23) => {
|
|
80859
80993
|
let args;
|
|
80860
80994
|
if (typeof cmd !== "string") [cmd, ...args] = cmd;
|
|
80861
80995
|
const timeout = options?.timeout ?? DEFAULT_TIMEOUT_MS;
|
|
80862
|
-
const childProcess =
|
|
80996
|
+
const childProcess = execFile2(
|
|
80863
80997
|
cmd,
|
|
80864
80998
|
args,
|
|
80865
80999
|
{ ...options, cwd: dir, maxBuffer: 1024 * 1024 * 1024, shell: args === void 0, timeout },
|
|
@@ -80867,6 +81001,9 @@ async function execNeverFail(cmd, dir, options) {
|
|
|
80867
81001
|
resolve23({ error, stdout, stderr });
|
|
80868
81002
|
}
|
|
80869
81003
|
);
|
|
81004
|
+
if (options?.telemetryHandler && childProcess.pid) {
|
|
81005
|
+
stopTelemetry = startTelemetry(childProcess.pid, options.telemetryHandler);
|
|
81006
|
+
}
|
|
80870
81007
|
if (options?.pipe) {
|
|
80871
81008
|
childProcess.stdout?.on("data", (data2) => {
|
|
80872
81009
|
Spinner.instance().suspend(() => {
|
|
@@ -80884,6 +81021,7 @@ async function execNeverFail(cmd, dir, options) {
|
|
|
80884
81021
|
});
|
|
80885
81022
|
} finally {
|
|
80886
81023
|
stopHeartbeat?.();
|
|
81024
|
+
stopTelemetry?.();
|
|
80887
81025
|
}
|
|
80888
81026
|
}
|
|
80889
81027
|
async function exec(cmd, dir, options) {
|
|
@@ -86442,7 +86580,7 @@ var Pattern = class _Pattern {
|
|
|
86442
86580
|
#isUNC;
|
|
86443
86581
|
#isAbsolute;
|
|
86444
86582
|
#followGlobstar = true;
|
|
86445
|
-
constructor(patternList, globList, index2,
|
|
86583
|
+
constructor(patternList, globList, index2, platform7) {
|
|
86446
86584
|
if (!isPatternList(patternList)) {
|
|
86447
86585
|
throw new TypeError("empty pattern list");
|
|
86448
86586
|
}
|
|
@@ -86459,7 +86597,7 @@ var Pattern = class _Pattern {
|
|
|
86459
86597
|
this.#patternList = patternList;
|
|
86460
86598
|
this.#globList = globList;
|
|
86461
86599
|
this.#index = index2;
|
|
86462
|
-
this.#platform =
|
|
86600
|
+
this.#platform = platform7;
|
|
86463
86601
|
if (this.#index === 0) {
|
|
86464
86602
|
if (this.isUNC()) {
|
|
86465
86603
|
const [p0, p1, p2, p3, ...prest] = this.#patternList;
|
|
@@ -86601,12 +86739,12 @@ var Ignore = class {
|
|
|
86601
86739
|
absoluteChildren;
|
|
86602
86740
|
platform;
|
|
86603
86741
|
mmopts;
|
|
86604
|
-
constructor(ignored, { nobrace, nocase, noext, noglobstar, platform:
|
|
86742
|
+
constructor(ignored, { nobrace, nocase, noext, noglobstar, platform: platform7 = defaultPlatform2 }) {
|
|
86605
86743
|
this.relative = [];
|
|
86606
86744
|
this.absolute = [];
|
|
86607
86745
|
this.relativeChildren = [];
|
|
86608
86746
|
this.absoluteChildren = [];
|
|
86609
|
-
this.platform =
|
|
86747
|
+
this.platform = platform7;
|
|
86610
86748
|
this.mmopts = {
|
|
86611
86749
|
dot: true,
|
|
86612
86750
|
nobrace,
|
|
@@ -86614,7 +86752,7 @@ var Ignore = class {
|
|
|
86614
86752
|
noext,
|
|
86615
86753
|
noglobstar,
|
|
86616
86754
|
optimizationLevel: 2,
|
|
86617
|
-
platform:
|
|
86755
|
+
platform: platform7,
|
|
86618
86756
|
nocomment: true,
|
|
86619
86757
|
nonegate: true
|
|
86620
86758
|
};
|
|
@@ -86652,10 +86790,10 @@ var Ignore = class {
|
|
|
86652
86790
|
ignored(p) {
|
|
86653
86791
|
const fullpath = p.fullpath();
|
|
86654
86792
|
const fullpaths = `${fullpath}/`;
|
|
86655
|
-
const
|
|
86656
|
-
const relatives = `${
|
|
86793
|
+
const relative11 = p.relative() || ".";
|
|
86794
|
+
const relatives = `${relative11}/`;
|
|
86657
86795
|
for (const m of this.relative) {
|
|
86658
|
-
if (m.match(
|
|
86796
|
+
if (m.match(relative11) || m.match(relatives))
|
|
86659
86797
|
return true;
|
|
86660
86798
|
}
|
|
86661
86799
|
for (const m of this.absolute) {
|
|
@@ -86666,9 +86804,9 @@ var Ignore = class {
|
|
|
86666
86804
|
}
|
|
86667
86805
|
childrenIgnored(p) {
|
|
86668
86806
|
const fullpath = p.fullpath() + "/";
|
|
86669
|
-
const
|
|
86807
|
+
const relative11 = (p.relative() || ".") + "/";
|
|
86670
86808
|
for (const m of this.relativeChildren) {
|
|
86671
|
-
if (m.match(
|
|
86809
|
+
if (m.match(relative11))
|
|
86672
86810
|
return true;
|
|
86673
86811
|
}
|
|
86674
86812
|
for (const m of this.absoluteChildren) {
|
|
@@ -87493,6 +87631,24 @@ var import_semver4 = __toESM(require_semver2(), 1);
|
|
|
87493
87631
|
import assert8 from "assert";
|
|
87494
87632
|
import { relative as relative7 } from "path";
|
|
87495
87633
|
|
|
87634
|
+
// ../utils/src/telemetry/telemetry-options-factory.ts
|
|
87635
|
+
function createTelemetryHandler(dashboardAPI4, analysisMetadataId) {
|
|
87636
|
+
if (!analysisMetadataId) {
|
|
87637
|
+
return void 0;
|
|
87638
|
+
}
|
|
87639
|
+
return {
|
|
87640
|
+
onTelemetry: (metrics) => {
|
|
87641
|
+
dashboardAPI4.sendTelemetry(analysisMetadataId, [
|
|
87642
|
+
{
|
|
87643
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
87644
|
+
metrics
|
|
87645
|
+
}
|
|
87646
|
+
]).catch((err) => logger.debug("Failed to send telemetry:", err));
|
|
87647
|
+
},
|
|
87648
|
+
intervalMs: 5e3
|
|
87649
|
+
};
|
|
87650
|
+
}
|
|
87651
|
+
|
|
87496
87652
|
// ../utils/src/promise-queue.ts
|
|
87497
87653
|
var PromiseQueue = class {
|
|
87498
87654
|
/*
|
|
@@ -87569,6 +87725,25 @@ var PromiseQueue = class {
|
|
|
87569
87725
|
// ../web-compat-utils/src/analysis-error-keys.ts
|
|
87570
87726
|
var FAILED_TO_INSTALL_PACKAGE_KEY = "[UNABLE_TO_INSTALL_PACKAGE_ERROR]: ";
|
|
87571
87727
|
|
|
87728
|
+
// ../web-compat-utils/src/ghsa.ts
|
|
87729
|
+
function extractGHSAIdFromUrl(url2) {
|
|
87730
|
+
const match2 = url2.match(/(GHSA-[a-z0-9-]+)/);
|
|
87731
|
+
if (match2) {
|
|
87732
|
+
return match2[1];
|
|
87733
|
+
}
|
|
87734
|
+
return void 0;
|
|
87735
|
+
}
|
|
87736
|
+
function extractGhsaIdsFromVulnUrls(vulnUrls) {
|
|
87737
|
+
const ghsaIds = /* @__PURE__ */ new Set();
|
|
87738
|
+
for (const url2 of vulnUrls) {
|
|
87739
|
+
const ghsaId = extractGHSAIdFromUrl(url2);
|
|
87740
|
+
if (ghsaId) {
|
|
87741
|
+
ghsaIds.add(ghsaId);
|
|
87742
|
+
}
|
|
87743
|
+
}
|
|
87744
|
+
return Array.from(ghsaIds);
|
|
87745
|
+
}
|
|
87746
|
+
|
|
87572
87747
|
// ../web-compat-utils/src/detected-occurrence-utils.ts
|
|
87573
87748
|
function hasReachableMatches(detectedOccurrences) {
|
|
87574
87749
|
if (!detectedOccurrences) return false;
|
|
@@ -87919,14 +88094,14 @@ function findBestWheel(packageName, version3, packageData) {
|
|
|
87919
88094
|
logger.debug(`Invalid wheel file name: ${filename}`);
|
|
87920
88095
|
return void 0;
|
|
87921
88096
|
}
|
|
87922
|
-
let [distribution, whVersion, pyver, abi,
|
|
88097
|
+
let [distribution, whVersion, pyver, abi, platform7] = parts;
|
|
87923
88098
|
if (whVersion !== version3) return void 0;
|
|
87924
88099
|
if (normalizePackageName(distribution) !== normalized)
|
|
87925
88100
|
logger.debug(`Distribution name mismatch: ${distribution} != ${normalized}`);
|
|
87926
88101
|
if (pyver === "py2.py3") pyver = "py3";
|
|
87927
88102
|
if (!pyver.startsWith("py") && !pyver.startsWith("cp")) return void 0;
|
|
87928
88103
|
if (pyver[2] === "2") return void 0;
|
|
87929
|
-
return { url: url2, version: pyver.slice(2), abi, platforms:
|
|
88104
|
+
return { url: url2, version: pyver.slice(2), abi, platforms: platform7.split(".") };
|
|
87930
88105
|
}).filter((w) => w !== void 0);
|
|
87931
88106
|
if (wheels.length === 0) {
|
|
87932
88107
|
logger.debug(`No suitable wheel file found for ${packageName}==${version3}`);
|
|
@@ -87939,9 +88114,9 @@ function findBestWheel(packageName, version3, packageData) {
|
|
|
87939
88114
|
});
|
|
87940
88115
|
for (const re of [/^any$/, /linux.*x86_64/, /linux/, /(?:x86_|amd)64/, /./]) {
|
|
87941
88116
|
for (const candidate of wheels) {
|
|
87942
|
-
const
|
|
87943
|
-
if (
|
|
87944
|
-
return { url: candidate.url, pythonVersion: candidate.version, abi: candidate.abi, platform:
|
|
88117
|
+
const platform7 = candidate.platforms.find((p) => re.test(p));
|
|
88118
|
+
if (platform7 !== void 0)
|
|
88119
|
+
return { url: candidate.url, pythonVersion: candidate.version, abi: candidate.abi, platform: platform7 };
|
|
87945
88120
|
}
|
|
87946
88121
|
}
|
|
87947
88122
|
}
|
|
@@ -88268,9 +88443,9 @@ var ToolPathResolver = class {
|
|
|
88268
88443
|
/**
|
|
88269
88444
|
* Get the path to the Goana binary for the current platform and architecture
|
|
88270
88445
|
*/
|
|
88271
|
-
static getGoanaBinaryPath(
|
|
88446
|
+
static getGoanaBinaryPath(platform7, arch) {
|
|
88272
88447
|
const rarch = arch === "arm" ? "arm64" : arch === "x64" ? "amd64" : arch;
|
|
88273
|
-
const binaryName = `goana-${
|
|
88448
|
+
const binaryName = `goana-${platform7}-${rarch}.gz`;
|
|
88274
88449
|
return resolve6(COANA_REPOS_PATH(), "goana", "bin", binaryName);
|
|
88275
88450
|
}
|
|
88276
88451
|
/**
|
|
@@ -90054,8 +90229,8 @@ var parseKVLine = (set, line) => {
|
|
|
90054
90229
|
};
|
|
90055
90230
|
|
|
90056
90231
|
// ../../node_modules/.pnpm/tar@7.4.3/node_modules/tar/dist/esm/normalize-windows-path.js
|
|
90057
|
-
var
|
|
90058
|
-
var normalizeWindowsPath =
|
|
90232
|
+
var platform2 = process.env.TESTING_TAR_FAKE_PLATFORM || process.platform;
|
|
90233
|
+
var normalizeWindowsPath = platform2 !== "win32" ? (p) => p : (p) => p && p.replace(/\\/g, "/");
|
|
90059
90234
|
|
|
90060
90235
|
// ../../node_modules/.pnpm/tar@7.4.3/node_modules/tar/dist/esm/read-entry.js
|
|
90061
90236
|
var ReadEntry = class extends Minipass {
|
|
@@ -91882,8 +92057,8 @@ import path7 from "node:path";
|
|
|
91882
92057
|
|
|
91883
92058
|
// ../../node_modules/.pnpm/tar@7.4.3/node_modules/tar/dist/esm/get-write-flag.js
|
|
91884
92059
|
import fs5 from "fs";
|
|
91885
|
-
var
|
|
91886
|
-
var isWindows =
|
|
92060
|
+
var platform3 = process.env.__FAKE_PLATFORM__ || process.platform;
|
|
92061
|
+
var isWindows = platform3 === "win32";
|
|
91887
92062
|
var { O_CREAT, O_TRUNC, O_WRONLY } = fs5.constants;
|
|
91888
92063
|
var UV_FS_O_FILEMAP = Number(process.env.__FAKE_FS_O_FILENAME__) || fs5.constants.UV_FS_O_FILEMAP || 0;
|
|
91889
92064
|
var fMapEnabled = isWindows && !!UV_FS_O_FILEMAP;
|
|
@@ -92138,7 +92313,7 @@ var mkdirpNative = Object.assign(async (path10, options) => {
|
|
|
92138
92313
|
|
|
92139
92314
|
// ../../node_modules/.pnpm/mkdirp@3.0.1/node_modules/mkdirp/dist/mjs/path-arg.js
|
|
92140
92315
|
import { parse as parse6, resolve as resolve7 } from "path";
|
|
92141
|
-
var
|
|
92316
|
+
var platform4 = process.env.__TESTING_MKDIRP_PLATFORM__ || process.platform;
|
|
92142
92317
|
var pathArg = (path10) => {
|
|
92143
92318
|
if (/\0/.test(path10)) {
|
|
92144
92319
|
throw Object.assign(new TypeError("path must be a string without null bytes"), {
|
|
@@ -92147,7 +92322,7 @@ var pathArg = (path10) => {
|
|
|
92147
92322
|
});
|
|
92148
92323
|
}
|
|
92149
92324
|
path10 = resolve7(path10);
|
|
92150
|
-
if (
|
|
92325
|
+
if (platform4 === "win32") {
|
|
92151
92326
|
const badWinChars = /[*|"<>?:]/;
|
|
92152
92327
|
const { root: root3 } = parse6(path10);
|
|
92153
92328
|
if (badWinChars.test(path10.substring(root3.length))) {
|
|
@@ -92407,8 +92582,8 @@ var normalizeUnicode = (s2) => {
|
|
|
92407
92582
|
|
|
92408
92583
|
// ../../node_modules/.pnpm/tar@7.4.3/node_modules/tar/dist/esm/path-reservations.js
|
|
92409
92584
|
import { join as join9 } from "node:path";
|
|
92410
|
-
var
|
|
92411
|
-
var isWindows2 =
|
|
92585
|
+
var platform5 = process.env.TESTING_TAR_FAKE_PLATFORM || process.platform;
|
|
92586
|
+
var isWindows2 = platform5 === "win32";
|
|
92412
92587
|
var getDirs = (path10) => {
|
|
92413
92588
|
const dirs = path10.split("/").slice(0, -1).reduce((set, path11) => {
|
|
92414
92589
|
const s2 = set[set.length - 1];
|
|
@@ -92564,8 +92739,8 @@ var DOCHOWN = Symbol("doChown");
|
|
|
92564
92739
|
var UID = Symbol("uid");
|
|
92565
92740
|
var GID = Symbol("gid");
|
|
92566
92741
|
var CHECKED_CWD = Symbol("checkedCwd");
|
|
92567
|
-
var
|
|
92568
|
-
var isWindows3 =
|
|
92742
|
+
var platform6 = process.env.TESTING_TAR_FAKE_PLATFORM || process.platform;
|
|
92743
|
+
var isWindows3 = platform6 === "win32";
|
|
92569
92744
|
var DEFAULT_MAX_DEPTH = 1024;
|
|
92570
92745
|
var unlinkFile = (path10, cb) => {
|
|
92571
92746
|
if (!isWindows3) {
|
|
@@ -93511,13 +93686,13 @@ async function getNodeExecutable(overridePath) {
|
|
|
93511
93686
|
logger.debug("Extracting Node.js binary for spawned processes...");
|
|
93512
93687
|
extractedNodePath = (async () => {
|
|
93513
93688
|
const extractedPath = await extractTool("nodejs-binaries", "nodejs-binaries");
|
|
93514
|
-
const { platform:
|
|
93689
|
+
const { platform: platform7, arch } = process;
|
|
93515
93690
|
const nodeArch = arch === "arm" ? "arm64" : arch;
|
|
93516
|
-
const isWindows4 =
|
|
93517
|
-
const binaryName = isWindows4 ? `node-${
|
|
93691
|
+
const isWindows4 = platform7 === "win32";
|
|
93692
|
+
const binaryName = isWindows4 ? `node-${platform7}-${nodeArch}.exe.gz` : `node-${platform7}-${nodeArch}.gz`;
|
|
93518
93693
|
const compressedBinaryPath = join10(extractedPath, binaryName);
|
|
93519
93694
|
if (!await exists(compressedBinaryPath)) {
|
|
93520
|
-
throw new Error(`Node.js binary not found: ${compressedBinaryPath}. Platform: ${
|
|
93695
|
+
throw new Error(`Node.js binary not found: ${compressedBinaryPath}. Platform: ${platform7}-${nodeArch}`);
|
|
93521
93696
|
}
|
|
93522
93697
|
const tmpDir = join10(getExtractionBaseDir(), "node-runtime");
|
|
93523
93698
|
await mkdir4(tmpDir, { recursive: true });
|
|
@@ -95871,7 +96046,7 @@ var DotnetCodeAwareVulnerabilityScanner = class _DotnetCodeAwareVulnerabilitySca
|
|
|
95871
96046
|
return packageIds?.map((packageId) => this.depIdToPurl.get(packageId)).filter((purl) => purl !== void 0).map((purl) => purl.name ?? "");
|
|
95872
96047
|
});
|
|
95873
96048
|
}
|
|
95874
|
-
async runAnalysis(vulnerabilities, heuristic, timeoutInSeconds, _experiment) {
|
|
96049
|
+
async runAnalysis(vulnerabilities, heuristic, timeoutInSeconds, _experiment, telemetryHandler) {
|
|
95875
96050
|
try {
|
|
95876
96051
|
this.statusUpdater?.("Preparing code for analysis...");
|
|
95877
96052
|
const packagesToAnalyze = heuristic.getPackagesToAnalyze(vulnerabilities);
|
|
@@ -95880,12 +96055,12 @@ var DotnetCodeAwareVulnerabilityScanner = class _DotnetCodeAwareVulnerabilitySca
|
|
|
95880
96055
|
const purl = this.depIdToPurl.get(packageId);
|
|
95881
96056
|
return purl?.name && packagesToAnalyzeSet.has(purl.name);
|
|
95882
96057
|
}));
|
|
95883
|
-
return await this.actuallyRunAnalysis(vulnerabilities.flatMap((v) => v.vulnerabilityAccessPaths), timeoutInSeconds, filteredDeps);
|
|
96058
|
+
return await this.actuallyRunAnalysis(vulnerabilities.flatMap((v) => v.vulnerabilityAccessPaths), timeoutInSeconds, filteredDeps, telemetryHandler);
|
|
95884
96059
|
} catch (e) {
|
|
95885
96060
|
return { type: "error", message: e.message };
|
|
95886
96061
|
}
|
|
95887
96062
|
}
|
|
95888
|
-
async actuallyRunAnalysis(vulnerabilityAccessPaths, timeoutInSeconds, filteredDeps) {
|
|
96063
|
+
async actuallyRunAnalysis(vulnerabilityAccessPaths, timeoutInSeconds, filteredDeps, telemetryHandler) {
|
|
95889
96064
|
this.statusUpdater?.("Running analysis...");
|
|
95890
96065
|
return withTmpDirectory("dotnet-run-analysis", async (tmpDir) => {
|
|
95891
96066
|
try {
|
|
@@ -95903,7 +96078,7 @@ var DotnetCodeAwareVulnerabilityScanner = class _DotnetCodeAwareVulnerabilitySca
|
|
|
95903
96078
|
const outputFile = resolve9(tmpDir, "output.json");
|
|
95904
96079
|
await writeFile4(inputFile, JSON.stringify(options));
|
|
95905
96080
|
const timeoutMs = Math.max(timeoutInSeconds * 1.5, timeoutInSeconds + 30) * 1e3;
|
|
95906
|
-
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, killSignal: "SIGKILL", heartbeat: HEARTBEATS.dotnet });
|
|
96081
|
+
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, killSignal: "SIGKILL", heartbeat: HEARTBEATS.dotnet, telemetryHandler });
|
|
95907
96082
|
if (result.error)
|
|
95908
96083
|
return { type: "error", message: result.error.message ?? "unknown error" };
|
|
95909
96084
|
const { success, error, analysisDiagnostics: diagnostics, vulnerablePaths, reachablePackageIds } = JSON.parse(await readFile6(outputFile, "utf-8")).result;
|
|
@@ -97697,10 +97872,10 @@ function compareDocumentPosition(nodeA, nodeB) {
|
|
|
97697
97872
|
function uniqueSort(nodes) {
|
|
97698
97873
|
nodes = nodes.filter((node, i4, arr) => !arr.includes(node, i4 + 1));
|
|
97699
97874
|
nodes.sort((a2, b) => {
|
|
97700
|
-
const
|
|
97701
|
-
if (
|
|
97875
|
+
const relative11 = compareDocumentPosition(a2, b);
|
|
97876
|
+
if (relative11 & DocumentPosition.PRECEDING) {
|
|
97702
97877
|
return -1;
|
|
97703
|
-
} else if (
|
|
97878
|
+
} else if (relative11 & DocumentPosition.FOLLOWING) {
|
|
97704
97879
|
return 1;
|
|
97705
97880
|
}
|
|
97706
97881
|
return 0;
|
|
@@ -109847,7 +110022,7 @@ var JavaCodeAwareVulnerabilityScanner = class _JavaCodeAwareVulnerabilityScanner
|
|
|
109847
110022
|
return packageIds?.map((packageId) => this.depIdToPurl.get(packageId)).filter((purl) => purl !== void 0).map((purl) => `${purl.namespace}:${purl.name}}`);
|
|
109848
110023
|
});
|
|
109849
110024
|
}
|
|
109850
|
-
async runAnalysis(vulnerabilities, heuristic, timeoutInSeconds, _experiment) {
|
|
110025
|
+
async runAnalysis(vulnerabilities, heuristic, timeoutInSeconds, _experiment, telemetryHandler) {
|
|
109851
110026
|
try {
|
|
109852
110027
|
this.statusUpdater?.("Preparing code for analysis...");
|
|
109853
110028
|
const packagesToAnalyze = heuristic.getPackagesToAnalyze(vulnerabilities);
|
|
@@ -109856,12 +110031,12 @@ var JavaCodeAwareVulnerabilityScanner = class _JavaCodeAwareVulnerabilityScanner
|
|
|
109856
110031
|
const purl = this.depIdToPurl.get(packageId);
|
|
109857
110032
|
return purl && packagesToAnalyzeSet.has(`${purl.namespace}:${purl.name}}`);
|
|
109858
110033
|
}));
|
|
109859
|
-
return await this.actuallyRunAnalysis(vulnerabilities.flatMap((v) => v.vulnerabilityAccessPaths), timeoutInSeconds, filteredDeps);
|
|
110034
|
+
return await this.actuallyRunAnalysis(vulnerabilities.flatMap((v) => v.vulnerabilityAccessPaths), timeoutInSeconds, filteredDeps, telemetryHandler);
|
|
109860
110035
|
} catch (e) {
|
|
109861
110036
|
return { type: "error", message: e.message };
|
|
109862
110037
|
}
|
|
109863
110038
|
}
|
|
109864
|
-
async actuallyRunAnalysis(vulnerabilityAccessPaths, timeoutInSeconds, filteredDeps) {
|
|
110039
|
+
async actuallyRunAnalysis(vulnerabilityAccessPaths, timeoutInSeconds, filteredDeps, telemetryHandler) {
|
|
109865
110040
|
this.statusUpdater?.("Running analysis...");
|
|
109866
110041
|
return withTmpDirectory("java-run-analysis", async (tmpDir) => {
|
|
109867
110042
|
try {
|
|
@@ -109879,7 +110054,7 @@ var JavaCodeAwareVulnerabilityScanner = class _JavaCodeAwareVulnerabilityScanner
|
|
|
109879
110054
|
const outputFile = resolve10(tmpDir, "output.json");
|
|
109880
110055
|
await writeFile5(inputFile, JSON.stringify(options));
|
|
109881
110056
|
const timeoutMs = Math.max(timeoutInSeconds * 1.5, timeoutInSeconds + 30) * 1e3;
|
|
109882
|
-
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, killSignal: "SIGKILL", heartbeat: HEARTBEATS.java });
|
|
110057
|
+
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, killSignal: "SIGKILL", heartbeat: HEARTBEATS.java, telemetryHandler });
|
|
109883
110058
|
if (result.error)
|
|
109884
110059
|
return { type: "error", message: result.error.message ?? "unknown error" };
|
|
109885
110060
|
const { success, error, analysisDiagnostics: diagnostics, vulnerablePaths, reachablePackageIds } = JSON.parse(await readFile7(outputFile, "utf-8")).result;
|
|
@@ -110467,7 +110642,7 @@ import { readFile as readFile8, realpath as realpath2, rm as rm2, writeFile as w
|
|
|
110467
110642
|
import { relative as relative6, resolve as resolve13 } from "path";
|
|
110468
110643
|
var { map: map2, uniq: uniq4 } = import_lodash10.default;
|
|
110469
110644
|
var PRINT_JELLY_COMMAND = false;
|
|
110470
|
-
async function runJellyAnalysis(mainProjectRoot, projectRoot, jellyOptions, reachabilityAnalysisOptions, timeoutInSeconds, vulnerabilities, experiment) {
|
|
110645
|
+
async function runJellyAnalysis(mainProjectRoot, projectRoot, jellyOptions, reachabilityAnalysisOptions, timeoutInSeconds, vulnerabilities, experiment, telemetryHandler) {
|
|
110471
110646
|
const tmpFolder = await createTmpDirectory("jelly-analysis");
|
|
110472
110647
|
try {
|
|
110473
110648
|
const filesToAnalyze = reachabilityAnalysisOptions.entryPoints ?? [projectRoot];
|
|
@@ -110511,7 +110686,12 @@ async function runJellyAnalysis(mainProjectRoot, projectRoot, jellyOptions, reac
|
|
|
110511
110686
|
jellyCmd,
|
|
110512
110687
|
void 0,
|
|
110513
110688
|
// Use SIGKILL to ensure termination even if the process is unresponsive 50% above the timeout (e.g., due to GC pressure).
|
|
110514
|
-
{
|
|
110689
|
+
{
|
|
110690
|
+
timeout: timeoutInSeconds * 1e3 * 1.5,
|
|
110691
|
+
killSignal: "SIGKILL",
|
|
110692
|
+
heartbeat: HEARTBEATS.js,
|
|
110693
|
+
telemetryHandler
|
|
110694
|
+
}
|
|
110515
110695
|
);
|
|
110516
110696
|
if (reachabilityAnalysisOptions.printLogFile)
|
|
110517
110697
|
logger.info("JS analysis log file:", await readFile8(logFile, "utf-8"));
|
|
@@ -110544,7 +110724,7 @@ async function runJellyAnalysis(mainProjectRoot, projectRoot, jellyOptions, reac
|
|
|
110544
110724
|
await rm2(tmpFolder, { recursive: true });
|
|
110545
110725
|
}
|
|
110546
110726
|
}
|
|
110547
|
-
async function runJellyPhantomDependencyAnalysis(projectRoot, options) {
|
|
110727
|
+
async function runJellyPhantomDependencyAnalysis(projectRoot, options, telemetryHandler) {
|
|
110548
110728
|
const tmpFolder = await createTmpDirectory("jelly-analysis");
|
|
110549
110729
|
try {
|
|
110550
110730
|
const jellyExecutable = ToolPathResolver.jellyPath;
|
|
@@ -110555,14 +110735,15 @@ async function runJellyPhantomDependencyAnalysis(projectRoot, options) {
|
|
|
110555
110735
|
await runCommandResolveStdOut2(jellyCmd, void 0, {
|
|
110556
110736
|
timeout: options.timeoutSeconds.allVulnRuns * 1e3,
|
|
110557
110737
|
killSignal: "SIGKILL",
|
|
110558
|
-
heartbeat: HEARTBEATS.js
|
|
110738
|
+
heartbeat: HEARTBEATS.js,
|
|
110739
|
+
telemetryHandler
|
|
110559
110740
|
});
|
|
110560
110741
|
return JSON.parse(await readFile8(reachablePackagesFile, "utf-8")).packages;
|
|
110561
110742
|
} finally {
|
|
110562
110743
|
await rm2(tmpFolder, { recursive: true });
|
|
110563
110744
|
}
|
|
110564
110745
|
}
|
|
110565
|
-
async function runJellyImportReachabilityAnalysis(mainProjectRoot, projectRoot, vulnerabilities, options) {
|
|
110746
|
+
async function runJellyImportReachabilityAnalysis(mainProjectRoot, projectRoot, vulnerabilities, options, telemetryHandler) {
|
|
110566
110747
|
const tmpFolder = await createTmpDirectory("jelly-analysis");
|
|
110567
110748
|
try {
|
|
110568
110749
|
const includePackages = computePackagesOnVulnPath(vulnerabilities, { includeLeafPackages: true });
|
|
@@ -110576,7 +110757,8 @@ async function runJellyImportReachabilityAnalysis(mainProjectRoot, projectRoot,
|
|
|
110576
110757
|
await runCommandResolveStdOut2(jellyCmd, void 0, {
|
|
110577
110758
|
timeout: options.timeoutSeconds.allVulnRuns * 1e3,
|
|
110578
110759
|
killSignal: "SIGKILL",
|
|
110579
|
-
heartbeat: HEARTBEATS.js
|
|
110760
|
+
heartbeat: HEARTBEATS.js,
|
|
110761
|
+
telemetryHandler
|
|
110580
110762
|
});
|
|
110581
110763
|
return JSON.parse(await readFile8(reachableModulesFile, "utf-8"));
|
|
110582
110764
|
} finally {
|
|
@@ -110631,11 +110813,11 @@ var JSCodeAwareVulnerabilityScanner = class _JSCodeAwareVulnerabilityScanner {
|
|
|
110631
110813
|
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);
|
|
110632
110814
|
this.packagesExcludedUnrelatedToHeuristic = failedPackages.map((p) => getPackageName(p));
|
|
110633
110815
|
}
|
|
110634
|
-
async runAnalysis(vulnerabilities, heuristic, timeoutInSeconds, experiment) {
|
|
110816
|
+
async runAnalysis(vulnerabilities, heuristic, timeoutInSeconds, experiment, telemetryHandler) {
|
|
110635
110817
|
const analysisOptionsFromHeuristic = heuristic.getOptions(vulnerabilities);
|
|
110636
110818
|
try {
|
|
110637
110819
|
analysisOptionsFromHeuristic.approx = process.env.JELLY_APPROX === "true" || experiment === "JELLY_APPROX";
|
|
110638
|
-
const analysisRes = await runJellyAnalysis(this.mainProjectDir, this.projectDir, analysisOptionsFromHeuristic, this.options, timeoutInSeconds, vulnerabilities, experiment);
|
|
110820
|
+
const analysisRes = await runJellyAnalysis(this.mainProjectDir, this.projectDir, analysisOptionsFromHeuristic, this.options, timeoutInSeconds, vulnerabilities, experiment, telemetryHandler);
|
|
110639
110821
|
const { analysisDiagnostics: diagnostics, matches } = analysisRes;
|
|
110640
110822
|
return {
|
|
110641
110823
|
type: "success",
|
|
@@ -110814,7 +110996,7 @@ var GoCodeAwareVulnerabilityScanner = class {
|
|
|
110814
110996
|
this.projectDir = projectDir;
|
|
110815
110997
|
this.options = options;
|
|
110816
110998
|
}
|
|
110817
|
-
async runAnalysis(vulns, heuristic, timeoutInSeconds) {
|
|
110999
|
+
async runAnalysis(vulns, heuristic, timeoutInSeconds, _experiment, telemetryHandler) {
|
|
110818
111000
|
logger.info("Started instantiating Go code-aware analysis");
|
|
110819
111001
|
if (!existsSync10(join15(this.projectDir, "go.mod")))
|
|
110820
111002
|
throw new Error("go.mod file not found in the project directory");
|
|
@@ -110838,7 +111020,8 @@ var GoCodeAwareVulnerabilityScanner = class {
|
|
|
110838
111020
|
timeout: timeoutInSeconds * 1e3,
|
|
110839
111021
|
killSignal: "SIGKILL",
|
|
110840
111022
|
env: memoryLimitInMB ? { ...process.env, GOMEMLIMIT: `${memoryLimitInMB}MiB` } : void 0,
|
|
110841
|
-
heartbeat: HEARTBEATS.go
|
|
111023
|
+
heartbeat: HEARTBEATS.go,
|
|
111024
|
+
telemetryHandler
|
|
110842
111025
|
});
|
|
110843
111026
|
if (error) {
|
|
110844
111027
|
logger.error("Error running Go code-aware analysis", error);
|
|
@@ -111244,7 +111427,7 @@ var RustCodeAwareVulnerabilityScanner = class _RustCodeAwareVulnerabilityScanner
|
|
|
111244
111427
|
return packageIds?.map((packageId) => this.depIdToPurl.get(packageId)?.name).filter((name2) => name2 !== void 0).map((name2) => name2);
|
|
111245
111428
|
});
|
|
111246
111429
|
}
|
|
111247
|
-
async runAnalysis(vulnerabilities, heuristic, timeoutInSeconds) {
|
|
111430
|
+
async runAnalysis(vulnerabilities, heuristic, timeoutInSeconds, _experiment, telemetryHandler) {
|
|
111248
111431
|
try {
|
|
111249
111432
|
this.statusUpdater?.("Preparing code for analysis...");
|
|
111250
111433
|
const packagesToAnalyze = heuristic.getPackagesToAnalyze(vulnerabilities);
|
|
@@ -111253,12 +111436,12 @@ var RustCodeAwareVulnerabilityScanner = class _RustCodeAwareVulnerabilityScanner
|
|
|
111253
111436
|
const purl = this.depIdToPurl.get(packageId);
|
|
111254
111437
|
return purl?.name && packagesToAnalyzeSet.has(purl.name);
|
|
111255
111438
|
}));
|
|
111256
|
-
return await this.actuallyRunAnalysis(vulnerabilities.flatMap((v) => v.vulnerabilityAccessPaths), timeoutInSeconds, filteredDeps);
|
|
111439
|
+
return await this.actuallyRunAnalysis(vulnerabilities.flatMap((v) => v.vulnerabilityAccessPaths), timeoutInSeconds, filteredDeps, telemetryHandler);
|
|
111257
111440
|
} catch (e) {
|
|
111258
111441
|
return { type: "error", message: e.message };
|
|
111259
111442
|
}
|
|
111260
111443
|
}
|
|
111261
|
-
async actuallyRunAnalysis(vulnerabilityAccessPaths, timeoutInSeconds, filteredDeps) {
|
|
111444
|
+
async actuallyRunAnalysis(vulnerabilityAccessPaths, timeoutInSeconds, filteredDeps, telemetryHandler) {
|
|
111262
111445
|
this.statusUpdater?.("Running analysis...");
|
|
111263
111446
|
return withTmpDirectory("rust-run-analysis", async (tmpDir) => {
|
|
111264
111447
|
const effectiveTimeout = timeoutInSeconds;
|
|
@@ -111273,7 +111456,7 @@ var RustCodeAwareVulnerabilityScanner = class _RustCodeAwareVulnerabilityScanner
|
|
|
111273
111456
|
const outputFile = resolve15(tmpDir, "output.json");
|
|
111274
111457
|
await writeFile8(inputFile, JSON.stringify(options));
|
|
111275
111458
|
const timeoutMs = Math.max(effectiveTimeout * 1.5, effectiveTimeout + 30) * 1e3;
|
|
111276
|
-
const result = await execNeverFail2(cmdt`${await getNodeExecutable(ToolPathResolver.nodeExecutablePath)} ${getClassGraphAnalysisCliPath()} runRustReachabilityAnalysis -i ${inputFile} -o ${outputFile} --tree-sitter-rust ${getTreeSitterRustPath()}`, void 0, { timeout: timeoutMs, killSignal: "SIGKILL", heartbeat: HEARTBEATS.rust });
|
|
111459
|
+
const result = await execNeverFail2(cmdt`${await getNodeExecutable(ToolPathResolver.nodeExecutablePath)} ${getClassGraphAnalysisCliPath()} runRustReachabilityAnalysis -i ${inputFile} -o ${outputFile} --tree-sitter-rust ${getTreeSitterRustPath()}`, void 0, { timeout: timeoutMs, killSignal: "SIGKILL", heartbeat: HEARTBEATS.rust, telemetryHandler });
|
|
111277
111460
|
if (result.error)
|
|
111278
111461
|
return { type: "error", message: result.error.message ?? "unknown error" };
|
|
111279
111462
|
const { success, error, analysisDiagnostics: diagnostics, vulnerablePaths, reachablePackageIds } = JSON.parse(await readFile10(outputFile, "utf-8")).result;
|
|
@@ -111744,7 +111927,7 @@ var PythonCodeAwareVulnerabilityScanner = class {
|
|
|
111744
111927
|
logger.info("Done setting up virtual environment");
|
|
111745
111928
|
}
|
|
111746
111929
|
}
|
|
111747
|
-
async runAnalysis(vulns, heuristic, timeoutInSeconds) {
|
|
111930
|
+
async runAnalysis(vulns, heuristic, timeoutInSeconds, _experiment, telemetryHandler) {
|
|
111748
111931
|
if (!this.virtualEnvInfo)
|
|
111749
111932
|
throw new Error("Virtual environment not set up");
|
|
111750
111933
|
this.mambaladeVenvPath ??= await setupMambalade();
|
|
@@ -111798,7 +111981,8 @@ var PythonCodeAwareVulnerabilityScanner = class {
|
|
|
111798
111981
|
// Use SIGKILL to ensure termination even if the process is unresponsive.
|
|
111799
111982
|
timeout: (timeoutInSeconds * 1.5 + 15) * 1e3,
|
|
111800
111983
|
killSignal: "SIGKILL",
|
|
111801
|
-
heartbeat: HEARTBEATS.python
|
|
111984
|
+
heartbeat: HEARTBEATS.python,
|
|
111985
|
+
telemetryHandler
|
|
111802
111986
|
});
|
|
111803
111987
|
logger.debug("Done running mambalade");
|
|
111804
111988
|
const errors = stderr.split("\n").filter((line) => line.startsWith("ERROR:") && !/^ERROR: Excluded distribution/.test(line));
|
|
@@ -112562,12 +112746,14 @@ async function analyzeWithHeuristics(state, vulns, heuristicsInOrder, doNotRecom
|
|
|
112562
112746
|
};
|
|
112563
112747
|
const vulnDepIdentifierToVulns = groupBy(bucket.vulnerabilities, getVulnDepIdentifier);
|
|
112564
112748
|
const vulnDepIdentifiers = Object.keys(vulnDepIdentifierToVulns);
|
|
112749
|
+
const ghsaIds = extractGhsaIdsFromVulnUrls(vulnsForBucket.map((v) => v.url));
|
|
112750
|
+
const analysisMetadataId = COANA_REPORT_ID ? await dashboardAPI.createAnalysisMetadata(COANA_REPORT_ID, relative7(state.rootWorkingDir, state.subprojectDir) || ".", state.workspacePath, ecosystem, ghsaIds, bucket.heuristic.name, experiment) : void 0;
|
|
112565
112751
|
try {
|
|
112566
112752
|
newAnalysisRunListener();
|
|
112567
112753
|
const initialBucketContainingAllVulns = buckets.length === 1 && buckets[0] === bucket;
|
|
112568
112754
|
const timeoutInSeconds = initialBucketContainingAllVulns ? state.reachabilityAnalysisOptions.timeoutSeconds.allVulnRuns : state.reachabilityAnalysisOptions.timeoutSeconds.bucketedRuns;
|
|
112569
112755
|
logger.info(`Running full reachability analysis for ${vulnsForBucket.length}/${vulnerabilities.length} vulnerabilities.`);
|
|
112570
|
-
const result = await codeAwareScanner.runAnalysis(vulnsForBucket, bucket.heuristic, timeoutInSeconds, experiment);
|
|
112756
|
+
const result = await codeAwareScanner.runAnalysis(vulnsForBucket, bucket.heuristic, timeoutInSeconds, experiment, createTelemetryHandler(dashboardAPI, analysisMetadataId));
|
|
112571
112757
|
const allowSplitInBuckets = !disableBucketing && bucket.heuristic.splitAnalysisInBuckets && !state.otherAnalysisOptions.disableBucketing && vulnDepIdentifiers.length > 1 && (result.type === "error" || result.reachedDependencies);
|
|
112572
112758
|
if (result.type === "success") {
|
|
112573
112759
|
result.diagnostics.timings ??= {};
|
|
@@ -112581,11 +112767,13 @@ async function analyzeWithHeuristics(state, vulns, heuristicsInOrder, doNotRecom
|
|
|
112581
112767
|
const analysisMetadata = { ...partialWithDiagnostics, finalResult: true };
|
|
112582
112768
|
bucketedAnalysisRes.analysisMetadata.push(analysisMetadata);
|
|
112583
112769
|
await analysisMetadataCollector2?.(analysisMetadata);
|
|
112770
|
+
dashboardAPI.registerDiagnosticsToAnalysisMetadata(analysisMetadataId, analysisMetadata).catch((err) => logger.debug("Failed to register diagnostics to analysis metadata:", err));
|
|
112584
112771
|
return;
|
|
112585
112772
|
}
|
|
112586
112773
|
result.diagnostics.timings.totalTime = Date.now() - bucketStartTime;
|
|
112587
112774
|
const finalAnalysisMetadata = { ...partialWithDiagnostics, finalResult: false };
|
|
112588
112775
|
await analysisMetadataCollector2?.(finalAnalysisMetadata);
|
|
112776
|
+
dashboardAPI.registerDiagnosticsToAnalysisMetadata(analysisMetadataId, finalAnalysisMetadata).catch((err) => logger.debug("Failed to register diagnostics to analysis metadata:", err));
|
|
112589
112777
|
} else {
|
|
112590
112778
|
result.type;
|
|
112591
112779
|
await sendErrorAnalysisMetadata(result.message, !allowSplitInBuckets && isLastHeuristic(bucket.heuristic.name), !allowSplitInBuckets);
|
|
@@ -112625,6 +112813,7 @@ async function analyzeWithHeuristics(state, vulns, heuristicsInOrder, doNotRecom
|
|
|
112625
112813
|
if (pushMetadata)
|
|
112626
112814
|
bucketedAnalysisRes.analysisMetadata.push(analysisMetadataToSend);
|
|
112627
112815
|
await analysisMetadataCollector2?.(analysisMetadataToSend);
|
|
112816
|
+
dashboardAPI.registerDiagnosticsToAnalysisMetadata(analysisMetadataId, analysisMetadataToSend).catch((err) => logger.debug("Failed to register diagnostics to analysis metadata:", err));
|
|
112628
112817
|
}
|
|
112629
112818
|
}
|
|
112630
112819
|
}
|
|
@@ -112775,7 +112964,10 @@ function findDuplicateVulnsInBuckets(bucketsFromLastAnalysis) {
|
|
|
112775
112964
|
function transformVulnsToUrlToReachability(oldHeuristicAugmentedVulnerabilities) {
|
|
112776
112965
|
return Object.fromEntries(oldHeuristicAugmentedVulnerabilities.map((v) => [
|
|
112777
112966
|
v.url,
|
|
112778
|
-
{
|
|
112967
|
+
{
|
|
112968
|
+
reachability: getVulnReachability(v.results),
|
|
112969
|
+
terminatedEarly: v.results.type === "success" && v.results.terminatedEarly
|
|
112970
|
+
}
|
|
112779
112971
|
]));
|
|
112780
112972
|
}
|
|
112781
112973
|
|
|
@@ -112927,7 +113119,7 @@ var import_lodash19 = __toESM(require_lodash(), 1);
|
|
|
112927
113119
|
var import_picomatch4 = __toESM(require_picomatch2(), 1);
|
|
112928
113120
|
import { existsSync as existsSync13 } from "fs";
|
|
112929
113121
|
import { rm as rm6 } from "fs/promises";
|
|
112930
|
-
import { resolve as resolve20 } from "path";
|
|
113122
|
+
import { relative as relative8, resolve as resolve20 } from "path";
|
|
112931
113123
|
|
|
112932
113124
|
// ../web-compat-utils/src/pluralize.ts
|
|
112933
113125
|
function pluralize(count, word) {
|
|
@@ -112941,6 +113133,8 @@ function pluralize(count, word) {
|
|
|
112941
113133
|
|
|
112942
113134
|
// dist/analyzers/npm-analyzer.js
|
|
112943
113135
|
var { partition: partition3, memoize: memoize2 } = import_lodash19.default;
|
|
113136
|
+
var SOCKET_MODE2 = process.env.SOCKET_MODE === "true";
|
|
113137
|
+
var dashboardAPI2 = new DashboardAPI(SOCKET_MODE2, process.env.DISABLE_ANALYTICS_SHARING === "true");
|
|
112944
113138
|
var NpmAnalyzer = class {
|
|
112945
113139
|
state;
|
|
112946
113140
|
projectDir;
|
|
@@ -112973,12 +113167,36 @@ var NpmAnalyzer = class {
|
|
|
112973
113167
|
await vulnerabilityScanner.prepareDependencies(this.state, heuristicsInOrder[0]);
|
|
112974
113168
|
logger.info(`Running import reachability analysis for ${vulns.length} ${pluralize(vulns.length, "vulnerability")}`);
|
|
112975
113169
|
let reachable;
|
|
113170
|
+
const ghsaIds = extractGhsaIdsFromVulnUrls(vulns.map((v) => v.url));
|
|
113171
|
+
const importAnalysisMetadataId = COANA_REPORT_ID ? await dashboardAPI2.createAnalysisMetadata(COANA_REPORT_ID, relative8(this.state.rootWorkingDir, this.state.subprojectDir) || ".", this.state.workspacePath, "NPM", ghsaIds, heuristics.IMPORT_REACHABILITY.name) : void 0;
|
|
113172
|
+
if (COANA_REPORT_ID && !importAnalysisMetadataId) {
|
|
113173
|
+
logger.debug("Failed to create analysis metadata for import analysis");
|
|
113174
|
+
}
|
|
113175
|
+
const importAnalysisStartTime = Date.now();
|
|
112976
113176
|
try {
|
|
112977
113177
|
statusUpdater?.("Running import reachability analysis");
|
|
112978
113178
|
logger.debug("Starting jelly import reachability analysis");
|
|
112979
|
-
reachable = await runJellyImportReachabilityAnalysis(this.state.rootWorkingDir, this.projectDir, vulns, this.state.reachabilityAnalysisOptions);
|
|
113179
|
+
reachable = await runJellyImportReachabilityAnalysis(this.state.rootWorkingDir, this.projectDir, vulns, this.state.reachabilityAnalysisOptions, createTelemetryHandler(dashboardAPI2, importAnalysisMetadataId));
|
|
113180
|
+
dashboardAPI2.registerDiagnosticsToAnalysisMetadata(importAnalysisMetadataId, {
|
|
113181
|
+
analysisDiagnostics: {
|
|
113182
|
+
timeout: false,
|
|
113183
|
+
aborted: false,
|
|
113184
|
+
timings: { totalTime: Date.now() - importAnalysisStartTime }
|
|
113185
|
+
},
|
|
113186
|
+
finalResult: true
|
|
113187
|
+
}).catch((err) => logger.debug("Failed to register diagnostics to analysis metadata:", err));
|
|
112980
113188
|
} catch (e) {
|
|
112981
113189
|
logger.debug("Error while running jelly import reachability analysis:", e);
|
|
113190
|
+
dashboardAPI2.registerDiagnosticsToAnalysisMetadata(importAnalysisMetadataId, {
|
|
113191
|
+
analysisDiagnostics: {
|
|
113192
|
+
timeout: false,
|
|
113193
|
+
aborted: true,
|
|
113194
|
+
timings: { totalTime: Date.now() - importAnalysisStartTime }
|
|
113195
|
+
},
|
|
113196
|
+
errorMessage: e instanceof Error ? `${e.message}
|
|
113197
|
+
${e.stack}` : String(e),
|
|
113198
|
+
finalResult: true
|
|
113199
|
+
}).catch((err) => logger.debug("Failed to register diagnostics to analysis metadata:", err));
|
|
112982
113200
|
}
|
|
112983
113201
|
let [unreachableVulns, otherVulns] = [[], vulns];
|
|
112984
113202
|
logger.debug(`Reachable modules from import reachability analysis: ${reachable?.modules.length}`);
|
|
@@ -113148,7 +113366,7 @@ import { resolve as resolve21 } from "path";
|
|
|
113148
113366
|
var import_lodash20 = __toESM(require_lodash(), 1);
|
|
113149
113367
|
import { createWriteStream as createWriteStream4, existsSync as existsSync14 } from "fs";
|
|
113150
113368
|
import { mkdir as mkdir9, readdir as readdir5, readFile as readFile12, rm as rm7 } from "fs/promises";
|
|
113151
|
-
import { join as join17, relative as
|
|
113369
|
+
import { join as join17, relative as relative9 } from "path";
|
|
113152
113370
|
import { pipeline as pipeline3 } from "stream/promises";
|
|
113153
113371
|
var PRINT_ANALYSIS_COMMAND = false;
|
|
113154
113372
|
var { uniqBy: uniqBy2, sortedUniq: sortedUniq2 } = import_lodash20.default;
|
|
@@ -113195,7 +113413,7 @@ var RubyCodeAwareVulnerabilityScanner = class {
|
|
|
113195
113413
|
this.vendorDirWasCreated = true;
|
|
113196
113414
|
logger.info("Done setting up vendor directory");
|
|
113197
113415
|
}
|
|
113198
|
-
async runAnalysis(vulns, heuristic, timeoutInSeconds, _experiment) {
|
|
113416
|
+
async runAnalysis(vulns, heuristic, timeoutInSeconds, _experiment, telemetryHandler) {
|
|
113199
113417
|
return await withTmpDirectory("ruby-analyzer-output", async (tmpDir) => {
|
|
113200
113418
|
if (!this.vendorDir)
|
|
113201
113419
|
throw new Error("Assertion error: The vendor directory is not correctly initialized");
|
|
@@ -113236,10 +113454,11 @@ var RubyCodeAwareVulnerabilityScanner = class {
|
|
|
113236
113454
|
await exec2(cmd, this.projectDir, {
|
|
113237
113455
|
timeout: (timeoutInSeconds * 1.5 + 10) * 1e3,
|
|
113238
113456
|
killSignal: "SIGKILL",
|
|
113239
|
-
heartbeat: HEARTBEATS.ruby
|
|
113457
|
+
heartbeat: HEARTBEATS.ruby,
|
|
113458
|
+
telemetryHandler
|
|
113240
113459
|
});
|
|
113241
113460
|
const result = JSON.parse(await readFile12(vulnsOutputFile, "utf-8"));
|
|
113242
|
-
const relativeLoadPathsToPackageNames = new Map([...loadPathsToPackageNames.entries()].map(([k, v]) => [join17("vendor",
|
|
113461
|
+
const relativeLoadPathsToPackageNames = new Map([...loadPathsToPackageNames.entries()].map(([k, v]) => [join17("vendor", relative9(this.vendorDir, k)), v]));
|
|
113243
113462
|
const { timedOut, ...diagnostics } = JSON.parse(await readFile12(diagnosticsOutputFile, "utf-8"));
|
|
113244
113463
|
const reachedPackages = JSON.parse(await readFile12(reachedPackagesOutputFile, "utf-8"));
|
|
113245
113464
|
logger.debug("Reached packages: %O", reachedPackages);
|
|
@@ -113338,9 +113557,9 @@ async function downloadAndExtractGem(gemName, version3, vendorDir) {
|
|
|
113338
113557
|
return;
|
|
113339
113558
|
}
|
|
113340
113559
|
const tempGemFile = join17(vendorDir, `${gemName}-${version3}.gem`);
|
|
113341
|
-
const downloadAndExtract = async (
|
|
113560
|
+
const downloadAndExtract = async (platform7) => {
|
|
113342
113561
|
logger.debug(`Downloading gem ${gemName}@${version3}`);
|
|
113343
|
-
const response = await fetch(`https://rubygems.org/gems/${gemName}-${version3}${
|
|
113562
|
+
const response = await fetch(`https://rubygems.org/gems/${gemName}-${version3}${platform7 ? `-${platform7}` : ""}.gem`);
|
|
113344
113563
|
if (!response.ok)
|
|
113345
113564
|
throw new Error(`Failed to download gem: ${response.statusText}`);
|
|
113346
113565
|
if (!response.body)
|
|
@@ -113360,10 +113579,10 @@ async function downloadAndExtractGem(gemName, version3, vendorDir) {
|
|
|
113360
113579
|
await downloadAndExtract(void 0);
|
|
113361
113580
|
} catch (e) {
|
|
113362
113581
|
try {
|
|
113363
|
-
const
|
|
113582
|
+
const platform7 = await axios_default.get(`https://gem.coop/api/v1/versions/${gemName}.json`).then((res) => {
|
|
113364
113583
|
return res.data.find((v) => v.number === version3)?.platform;
|
|
113365
113584
|
});
|
|
113366
|
-
await downloadAndExtract(
|
|
113585
|
+
await downloadAndExtract(platform7);
|
|
113367
113586
|
} catch (e2) {
|
|
113368
113587
|
await rm7(gemDir, { recursive: true, force: true });
|
|
113369
113588
|
await rm7(tempGemFile, { force: true });
|
|
@@ -113518,18 +113737,18 @@ var ecosystemAnalyzer = {
|
|
|
113518
113737
|
RUBYGEMS: RubyGemsAnalyzer
|
|
113519
113738
|
};
|
|
113520
113739
|
var apiKey2 = COANA_API_KEY ? { type: "present", value: COANA_API_KEY } : { type: "missing" };
|
|
113521
|
-
var
|
|
113740
|
+
var dashboardAPI3 = new DashboardAPI(process.env.SOCKET_MODE === "true", process.env.DISABLE_ANALYTICS_SHARING === "true");
|
|
113522
113741
|
async function runReachabilityAnalysis(state) {
|
|
113523
113742
|
const projectDir = resolve22(state.subprojectDir, state.workspacePath);
|
|
113524
113743
|
const ecosystem = state.workspaceData.data.type;
|
|
113525
|
-
logger.info(`Preparing to run reachability analysis for project at "${
|
|
113744
|
+
logger.info(`Preparing to run reachability analysis for project at "${relative10(state.rootWorkingDir, projectDir) || "."}" (${ecosystem})`);
|
|
113526
113745
|
const constructor = ecosystemAnalyzer[ecosystem];
|
|
113527
113746
|
if (!constructor)
|
|
113528
113747
|
throw Error(`No analyzer associated with ecosystem ${ecosystem}`);
|
|
113529
113748
|
const analyzer = new constructor(state, projectDir);
|
|
113530
113749
|
const [vulnerabilitiesWithPrecomputedResults, vulnerabilitiesWithoutPrecomputedResults] = partition4(state.vulnerabilities, (v) => "results" in v);
|
|
113531
113750
|
const augmentedVulnerabilities = await runWholeProgramCodeAwareVulnerabilityScanner(analyzer, vulnerabilitiesWithoutPrecomputedResults, async (amd) => {
|
|
113532
|
-
await
|
|
113751
|
+
await dashboardAPI3.registerAnalysisMetadata(relative10(state.rootWorkingDir, state.subprojectDir) || ".", state.workspacePath, state.workspaceData.data.type, amd, COANA_REPORT_ID, apiKey2);
|
|
113533
113752
|
});
|
|
113534
113753
|
const diagnostics = await analyzer.getWorkspaceDiagnostics();
|
|
113535
113754
|
return {
|