snyk-docker-plugin
Version:
Snyk CLI docker plugin
133 lines • 4.96 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.dotnetFilesToScannedProjects = void 0;
const dep_graph_1 = require("@snyk/dep-graph");
const Debug = require("debug");
const event_loop_spinner_1 = require("event-loop-spinner");
const path = require("path");
const error_utils_1 = require("../../error-utils");
const debug = Debug("snyk");
function parsePackageKey(key) {
const slashIndex = key.indexOf("/");
if (slashIndex === -1) {
return null;
}
return {
name: key.substring(0, slashIndex),
version: key.substring(slashIndex + 1),
};
}
// Self-contained .NET publishes prefix the bundled runtime packages with
// "runtimepack." in deps.json (e.g. runtimepack.Microsoft.NETCore.App.Runtime.linux-x64).
// The canonical NuGet id (which the vuln DB matches against) has no prefix, so
// strip it to keep names matchable. See https://github.com/dotnet/sdk/issues/3010
const RUNTIME_PACK_PREFIX = "runtimepack.";
function normalizePackageName(name) {
return name.startsWith(RUNTIME_PACK_PREFIX)
? name.slice(RUNTIME_PACK_PREFIX.length)
: name;
}
async function addDependency(parentNodeId, depName, packageIndex, visited, builder) {
if (event_loop_spinner_1.eventLoopSpinner.isStarving()) {
await event_loop_spinner_1.eventLoopSpinner.spin();
}
const pkg = packageIndex.get(normalizePackageName(depName).toLowerCase());
if (!pkg) {
return;
}
const nodeId = `${pkg.name}@${pkg.version}`;
if (!visited.has(nodeId)) {
visited.add(nodeId);
builder.addPkgNode({ name: pkg.name, version: pkg.version }, nodeId);
for (const childName of Object.keys(pkg.dependencies)) {
await addDependency(nodeId, childName, packageIndex, visited, builder);
}
}
builder.connectDep(parentNodeId, nodeId);
}
async function dotnetFilesToScannedProjects(filePathToContent) {
const scanResults = [];
for (const [filePath, content] of Object.entries(filePathToContent)) {
try {
const depGraph = await buildDepGraphFromDepsJson(content, filePath);
if (!depGraph) {
continue;
}
const depGraphFact = {
type: "depGraph",
data: depGraph,
};
const testedFilesFact = {
type: "testedFiles",
data: [path.basename(filePath)],
};
scanResults.push({
facts: [depGraphFact, testedFilesFact],
identity: {
type: "nuget",
targetFile: filePath,
},
});
}
catch (err) {
debug(`Failed to parse .NET deps.json at ${filePath}: ${(0, error_utils_1.getErrorMessage)(err)}`);
}
}
return scanResults;
}
exports.dotnetFilesToScannedProjects = dotnetFilesToScannedProjects;
async function buildDepGraphFromDepsJson(content, filePath) {
var _a, _b, _c;
const depsJson = JSON.parse(content);
const targets = depsJson.targets;
if (!targets) {
debug(`No targets in deps.json: ${filePath}`);
return null;
}
const target = ((_a = depsJson.runtimeTarget) === null || _a === void 0 ? void 0 : _a.name)
? targets[depsJson.runtimeTarget.name]
: undefined;
if (!target) {
return null;
}
const libraries = depsJson.libraries;
if (!libraries) {
return null;
}
const allPackages = Object.keys(target);
const rootEntry = allPackages.find((key) => {
const lib = libraries[key];
return (lib === null || lib === void 0 ? void 0 : lib.type) === "project";
});
if (!rootEntry) {
return null;
}
const parsed = parsePackageKey(rootEntry);
const rootName = parsed ? parsed.name : rootEntry;
const rootVersion = parsed ? parsed.version : "0.0.0";
const rootDependencies = (_b = target[rootEntry]) === null || _b === void 0 ? void 0 : _b.dependencies;
if (!rootDependencies) {
return null;
}
const builder = new dep_graph_1.DepGraphBuilder({ name: "nuget" }, { name: rootName, version: rootVersion });
const packageIndex = new Map();
for (const key of allPackages) {
const parsed = parsePackageKey(key);
if (!parsed) {
continue;
}
const name = normalizePackageName(parsed.name);
packageIndex.set(name.toLowerCase(), {
name,
version: parsed.version,
dependencies: ((_c = target[key]) === null || _c === void 0 ? void 0 : _c.dependencies) || {},
});
}
const visited = new Set();
const directDeps = Object.keys(rootDependencies);
for (const depName of directDeps) {
await addDependency(builder.rootNodeId, depName, packageIndex, visited, builder);
}
return builder.build();
}
//# sourceMappingURL=dotnet.js.map