@cyclonedx/cdxgen 9.9.7 → 9.9.8
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/README.md +1 -1
- package/binary.js +52 -2
- package/evinser.js +3 -1
- package/index.js +36 -6
- package/package.json +13 -12
- package/utils.js +192 -3
- package/utils.test.js +25 -4
package/README.md
CHANGED
|
@@ -27,7 +27,7 @@ Most SBOM tools are like barcode scanners. They can scan a few package manifest
|
|
|
27
27
|
| Go | binary, go.mod, go.sum, Gopkg.lock | Yes except binary | Yes |
|
|
28
28
|
| Ruby | Gemfile.lock, gemspec | Only for Gemfile.lock | |
|
|
29
29
|
| Rust | binary, Cargo.toml, Cargo.lock | Only for Cargo.lock | |
|
|
30
|
-
| .Net | .csproj, packages.config, project.assets.json [3], packages.lock.json, .nupkg, paket.lock
|
|
30
|
+
| .Net | .csproj, .vbproj, .fsproj, packages.config, project.assets.json [3], packages.lock.json, .nupkg, paket.lock | Only for project.assets.json, packages.lock.json, paket.lock | |
|
|
31
31
|
| Dart | pubspec.lock, pubspec.yaml | Only for pubspec.lock | |
|
|
32
32
|
| Haskell | cabal.project.freeze | Yes | |
|
|
33
33
|
| Elixir | mix.lock | Yes | |
|
package/binary.js
CHANGED
|
@@ -9,7 +9,7 @@ import {
|
|
|
9
9
|
import { join, dirname, basename } from "node:path";
|
|
10
10
|
import { spawnSync } from "node:child_process";
|
|
11
11
|
import { PackageURL } from "packageurl-js";
|
|
12
|
-
import { DEBUG_MODE, findLicenseId } from "./utils.js";
|
|
12
|
+
import { DEBUG_MODE, TIMEOUT_MS, findLicenseId } from "./utils.js";
|
|
13
13
|
|
|
14
14
|
import { fileURLToPath } from "node:url";
|
|
15
15
|
|
|
@@ -24,7 +24,7 @@ const isWin = _platform() === "win32";
|
|
|
24
24
|
let platform = _platform();
|
|
25
25
|
let extn = "";
|
|
26
26
|
let pluginsBinSuffix = "";
|
|
27
|
-
if (platform
|
|
27
|
+
if (platform === "win32") {
|
|
28
28
|
platform = "windows";
|
|
29
29
|
extn = ".exe";
|
|
30
30
|
}
|
|
@@ -36,6 +36,9 @@ switch (arch) {
|
|
|
36
36
|
break;
|
|
37
37
|
case "x64":
|
|
38
38
|
arch = "amd64";
|
|
39
|
+
if (platform === "windows") {
|
|
40
|
+
pluginsBinSuffix = "-windows-amd64";
|
|
41
|
+
}
|
|
39
42
|
break;
|
|
40
43
|
case "arm64":
|
|
41
44
|
pluginsBinSuffix = "-arm64";
|
|
@@ -165,7 +168,21 @@ if (existsSync(join(CDXGEN_PLUGINS_DIR, "osquery"))) {
|
|
|
165
168
|
} else if (process.env.OSQUERY_CMD) {
|
|
166
169
|
OSQUERY_BIN = process.env.OSQUERY_CMD;
|
|
167
170
|
}
|
|
171
|
+
let DOSAI_BIN = null;
|
|
172
|
+
if (existsSync(join(CDXGEN_PLUGINS_DIR, "dosai"))) {
|
|
173
|
+
if (platform === "darwin") {
|
|
174
|
+
platform = "osx";
|
|
175
|
+
}
|
|
176
|
+
DOSAI_BIN = join(
|
|
177
|
+
CDXGEN_PLUGINS_DIR,
|
|
178
|
+
"dosai",
|
|
179
|
+
"dosai-" + platform + "-" + arch + extn
|
|
180
|
+
);
|
|
181
|
+
} else if (process.env.DOSAI_CMD) {
|
|
182
|
+
DOSAI_BIN = process.env.DOSAI_CMD;
|
|
183
|
+
}
|
|
168
184
|
|
|
185
|
+
// Keep this list updated every year
|
|
169
186
|
const OS_DISTRO_ALIAS = {
|
|
170
187
|
"ubuntu-4.10": "warty",
|
|
171
188
|
"ubuntu-5.04": "hoary",
|
|
@@ -692,3 +709,36 @@ export const executeOsQuery = (query) => {
|
|
|
692
709
|
}
|
|
693
710
|
return undefined;
|
|
694
711
|
};
|
|
712
|
+
|
|
713
|
+
/**
|
|
714
|
+
* Method to execute dosai to create slices for dotnet
|
|
715
|
+
*
|
|
716
|
+
* @param {string} src
|
|
717
|
+
* @param {string} slicesFile
|
|
718
|
+
* @returns boolean
|
|
719
|
+
*/
|
|
720
|
+
export const getDotnetSlices = (src, slicesFile) => {
|
|
721
|
+
if (!DOSAI_BIN) {
|
|
722
|
+
return false;
|
|
723
|
+
}
|
|
724
|
+
const args = ["methods", "--path", src, "--o", slicesFile];
|
|
725
|
+
if (DEBUG_MODE) {
|
|
726
|
+
console.log("Executing", DOSAI_BIN, args.join(" "));
|
|
727
|
+
}
|
|
728
|
+
const result = spawnSync(DOSAI_BIN, args, {
|
|
729
|
+
encoding: "utf-8",
|
|
730
|
+
timeout: TIMEOUT_MS,
|
|
731
|
+
cwd: src
|
|
732
|
+
});
|
|
733
|
+
if (result.status !== 0 || result.error) {
|
|
734
|
+
if (DEBUG_MODE && result.error) {
|
|
735
|
+
if (result.stderr) {
|
|
736
|
+
console.error(result.stdout, result.stderr);
|
|
737
|
+
} else {
|
|
738
|
+
console.log("Check if dosai plugin was installed successfully.");
|
|
739
|
+
}
|
|
740
|
+
}
|
|
741
|
+
return false;
|
|
742
|
+
}
|
|
743
|
+
return true;
|
|
744
|
+
};
|
package/evinser.js
CHANGED
|
@@ -244,7 +244,9 @@ export const createSlice = (
|
|
|
244
244
|
args.push(path.resolve(filePath));
|
|
245
245
|
const result = executeAtom(filePath, args);
|
|
246
246
|
if (!result || !fs.existsSync(slicesFile)) {
|
|
247
|
-
console.warn(
|
|
247
|
+
console.warn(
|
|
248
|
+
`Unable to generate ${sliceType} slice using atom. Check if this is a supported language.`
|
|
249
|
+
);
|
|
248
250
|
console.log(
|
|
249
251
|
"Set the environment variable CDXGEN_DEBUG_MODE=debug to troubleshoot."
|
|
250
252
|
);
|
package/index.js
CHANGED
|
@@ -107,7 +107,8 @@ import {
|
|
|
107
107
|
frameworksList,
|
|
108
108
|
parseContainerFile,
|
|
109
109
|
parseBitbucketPipelinesFile,
|
|
110
|
-
getPyMetadata
|
|
110
|
+
getPyMetadata,
|
|
111
|
+
addEvidenceForDotnet
|
|
111
112
|
} from "./utils.js";
|
|
112
113
|
import { spawnSync } from "node:child_process";
|
|
113
114
|
import { fileURLToPath } from "node:url";
|
|
@@ -131,7 +132,8 @@ import {
|
|
|
131
132
|
getGoBuildInfo,
|
|
132
133
|
getCargoAuditableInfo,
|
|
133
134
|
executeOsQuery,
|
|
134
|
-
getOSPackages
|
|
135
|
+
getOSPackages,
|
|
136
|
+
getDotnetSlices
|
|
135
137
|
} from "./binary.js";
|
|
136
138
|
|
|
137
139
|
const isWin = _platform() === "win32";
|
|
@@ -4202,11 +4204,17 @@ export const createCsharpBom = async (
|
|
|
4202
4204
|
let manifestFiles = [];
|
|
4203
4205
|
let pkgData = undefined;
|
|
4204
4206
|
let dependencies = [];
|
|
4205
|
-
|
|
4207
|
+
let csProjFiles = getAllFiles(
|
|
4206
4208
|
path,
|
|
4207
4209
|
(options.multiProject ? "**/" : "") + "*.csproj",
|
|
4208
4210
|
options
|
|
4209
4211
|
);
|
|
4212
|
+
csProjFiles = csProjFiles.concat(
|
|
4213
|
+
getAllFiles(path, (options.multiProject ? "**/" : "") + "*.vbproj", options)
|
|
4214
|
+
);
|
|
4215
|
+
csProjFiles = csProjFiles.concat(
|
|
4216
|
+
getAllFiles(path, (options.multiProject ? "**/" : "") + "*.fsproj", options)
|
|
4217
|
+
);
|
|
4210
4218
|
const pkgConfigFiles = getAllFiles(
|
|
4211
4219
|
path,
|
|
4212
4220
|
(options.multiProject ? "**/" : "") + "packages.config",
|
|
@@ -4253,7 +4261,7 @@ export const createCsharpBom = async (
|
|
|
4253
4261
|
console.log(`Parsing ${af}`);
|
|
4254
4262
|
}
|
|
4255
4263
|
pkgData = readFileSync(af, { encoding: "utf-8" });
|
|
4256
|
-
let results = await parseCsProjAssetsData(pkgData);
|
|
4264
|
+
let results = await parseCsProjAssetsData(pkgData, af);
|
|
4257
4265
|
let deps = results["dependenciesList"];
|
|
4258
4266
|
let dlist = results["pkgList"];
|
|
4259
4267
|
if (dlist && dlist.length) {
|
|
@@ -4305,7 +4313,7 @@ export const createCsharpBom = async (
|
|
|
4305
4313
|
if (csProjData.charCodeAt(0) === 0xfeff) {
|
|
4306
4314
|
csProjData = csProjData.slice(1);
|
|
4307
4315
|
}
|
|
4308
|
-
const dlist = await parseCsProjData(csProjData);
|
|
4316
|
+
const dlist = await parseCsProjData(csProjData, f);
|
|
4309
4317
|
if (dlist && dlist.length) {
|
|
4310
4318
|
pkgList = pkgList.concat(dlist);
|
|
4311
4319
|
}
|
|
@@ -4336,6 +4344,22 @@ export const createCsharpBom = async (
|
|
|
4336
4344
|
if (pkgList.length) {
|
|
4337
4345
|
dependencies = mergeDependencies(dependencies, [], parentComponent);
|
|
4338
4346
|
pkgList = trimComponents(pkgList, "json");
|
|
4347
|
+
// Perform deep analysis using dosai
|
|
4348
|
+
if (options.deep) {
|
|
4349
|
+
const slicesFile = resolve(
|
|
4350
|
+
options.depsSlicesFile || join(tmpdir(), "dosai.json")
|
|
4351
|
+
);
|
|
4352
|
+
// Create the slices file if it doesn't exist
|
|
4353
|
+
if (!existsSync(slicesFile)) {
|
|
4354
|
+
const sliceResult = getDotnetSlices(resolve(path), resolve(slicesFile));
|
|
4355
|
+
if (!sliceResult && DEBUG_MODE) {
|
|
4356
|
+
console.log(
|
|
4357
|
+
"Slicing with dosai was unsuccessful. Check the errors reported in the logs above."
|
|
4358
|
+
);
|
|
4359
|
+
}
|
|
4360
|
+
}
|
|
4361
|
+
pkgList = addEvidenceForDotnet(pkgList, slicesFile, options);
|
|
4362
|
+
}
|
|
4339
4363
|
}
|
|
4340
4364
|
if (FETCH_LICENSE) {
|
|
4341
4365
|
const retMap = await getNugetMetadata(pkgList, dependencies);
|
|
@@ -5117,11 +5141,17 @@ export const createXBom = async (path, options) => {
|
|
|
5117
5141
|
}
|
|
5118
5142
|
|
|
5119
5143
|
// .Net
|
|
5120
|
-
|
|
5144
|
+
let csProjFiles = getAllFiles(
|
|
5121
5145
|
path,
|
|
5122
5146
|
(options.multiProject ? "**/" : "") + "*.csproj",
|
|
5123
5147
|
options
|
|
5124
5148
|
);
|
|
5149
|
+
csProjFiles = csProjFiles.concat(
|
|
5150
|
+
getAllFiles(path, (options.multiProject ? "**/" : "") + "*.vbproj", options)
|
|
5151
|
+
);
|
|
5152
|
+
csProjFiles = csProjFiles.concat(
|
|
5153
|
+
getAllFiles(path, (options.multiProject ? "**/" : "") + "*.fsproj", options)
|
|
5154
|
+
);
|
|
5125
5155
|
if (csProjFiles.length) {
|
|
5126
5156
|
return await createCsharpBom(path, options);
|
|
5127
5157
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cyclonedx/cdxgen",
|
|
3
|
-
"version": "9.9.
|
|
3
|
+
"version": "9.9.8",
|
|
4
4
|
"description": "Creates CycloneDX Software Bill of Materials (SBOM) from source or container image",
|
|
5
5
|
"homepage": "http://github.com/cyclonedx/cdxgen",
|
|
6
6
|
"author": "Prabhu Subramanian <prabhu@appthreat.com>",
|
|
@@ -55,17 +55,17 @@
|
|
|
55
55
|
"url": "https://github.com/cyclonedx/cdxgen/issues"
|
|
56
56
|
},
|
|
57
57
|
"dependencies": {
|
|
58
|
-
"@babel/parser": "^7.23.
|
|
59
|
-
"@babel/traverse": "^7.23.
|
|
58
|
+
"@babel/parser": "^7.23.6",
|
|
59
|
+
"@babel/traverse": "^7.23.6",
|
|
60
60
|
"@npmcli/arborist": "7.2.0",
|
|
61
61
|
"ajv": "^8.12.0",
|
|
62
62
|
"ajv-formats": "^2.1.1",
|
|
63
63
|
"cheerio": "^1.0.0-rc.12",
|
|
64
64
|
"edn-data": "1.1.1",
|
|
65
|
-
"find-up": "
|
|
65
|
+
"find-up": "6.3.0",
|
|
66
66
|
"glob": "^10.3.10",
|
|
67
67
|
"global-agent": "^3.0.0",
|
|
68
|
-
"got": "
|
|
68
|
+
"got": "13.0.0",
|
|
69
69
|
"iconv-lite": "^0.6.3",
|
|
70
70
|
"js-yaml": "^4.1.0",
|
|
71
71
|
"jws": "^4.0.0",
|
|
@@ -84,14 +84,15 @@
|
|
|
84
84
|
},
|
|
85
85
|
"optionalDependencies": {
|
|
86
86
|
"@appthreat/atom": "1.7.2",
|
|
87
|
-
"@cyclonedx/cdxgen-plugins-bin": "^1.4
|
|
88
|
-
"@cyclonedx/cdxgen-plugins-bin-
|
|
89
|
-
"@cyclonedx/cdxgen-plugins-bin-
|
|
87
|
+
"@cyclonedx/cdxgen-plugins-bin": "^1.5.4",
|
|
88
|
+
"@cyclonedx/cdxgen-plugins-bin-windows-amd64": "^1.5.4",
|
|
89
|
+
"@cyclonedx/cdxgen-plugins-bin-arm64": "^1.5.4",
|
|
90
|
+
"@cyclonedx/cdxgen-plugins-bin-ppc64": "^1.5.4",
|
|
90
91
|
"body-parser": "^1.20.2",
|
|
91
92
|
"compression": "^1.7.4",
|
|
92
93
|
"connect": "^3.7.0",
|
|
93
94
|
"jsonata": "^2.0.3",
|
|
94
|
-
"sequelize": "^6.35.
|
|
95
|
+
"sequelize": "^6.35.2",
|
|
95
96
|
"sqlite3": "^5.1.6"
|
|
96
97
|
},
|
|
97
98
|
"files": [
|
|
@@ -102,10 +103,10 @@
|
|
|
102
103
|
"devDependencies": {
|
|
103
104
|
"caxa": "^3.0.1",
|
|
104
105
|
"docsify-cli": "^4.4.4",
|
|
105
|
-
"eslint": "^8.
|
|
106
|
-
"eslint-config-prettier": "^9.
|
|
106
|
+
"eslint": "^8.55.0",
|
|
107
|
+
"eslint-config-prettier": "^9.1.0",
|
|
107
108
|
"eslint-plugin-prettier": "^5.0.1",
|
|
108
109
|
"jest": "^29.7.0",
|
|
109
|
-
"prettier": "3.1.
|
|
110
|
+
"prettier": "3.1.1"
|
|
110
111
|
}
|
|
111
112
|
}
|
package/utils.js
CHANGED
|
@@ -5189,7 +5189,7 @@ export const parseCsPkgData = async function (pkgData) {
|
|
|
5189
5189
|
return pkgList;
|
|
5190
5190
|
};
|
|
5191
5191
|
|
|
5192
|
-
export const parseCsProjData = async function (csProjData) {
|
|
5192
|
+
export const parseCsProjData = async function (csProjData, projFile) {
|
|
5193
5193
|
const pkgList = [];
|
|
5194
5194
|
if (!csProjData) {
|
|
5195
5195
|
return pkgList;
|
|
@@ -5218,6 +5218,27 @@ export const parseCsProjData = async function (csProjData) {
|
|
|
5218
5218
|
}
|
|
5219
5219
|
pkg.name = pref.Include;
|
|
5220
5220
|
pkg.version = pref.Version;
|
|
5221
|
+
if (projFile) {
|
|
5222
|
+
pkg.properties = [
|
|
5223
|
+
{
|
|
5224
|
+
name: "SrcFile",
|
|
5225
|
+
value: projFile
|
|
5226
|
+
}
|
|
5227
|
+
];
|
|
5228
|
+
pkg.evidence = {
|
|
5229
|
+
identity: {
|
|
5230
|
+
field: "purl",
|
|
5231
|
+
confidence: 0.7,
|
|
5232
|
+
methods: [
|
|
5233
|
+
{
|
|
5234
|
+
technique: "manifest-analysis",
|
|
5235
|
+
confidence: 0.7,
|
|
5236
|
+
value: projFile
|
|
5237
|
+
}
|
|
5238
|
+
]
|
|
5239
|
+
}
|
|
5240
|
+
};
|
|
5241
|
+
}
|
|
5221
5242
|
pkgList.push(pkg);
|
|
5222
5243
|
}
|
|
5223
5244
|
// .net framework use Reference
|
|
@@ -5232,6 +5253,27 @@ export const parseCsProjData = async function (csProjData) {
|
|
|
5232
5253
|
if (incParts.length > 1 && incParts[1].includes("Version")) {
|
|
5233
5254
|
pkg.version = incParts[1].replace("Version=", "").trim();
|
|
5234
5255
|
}
|
|
5256
|
+
if (projFile) {
|
|
5257
|
+
pkg.properties = [
|
|
5258
|
+
{
|
|
5259
|
+
name: "SrcFile",
|
|
5260
|
+
value: projFile
|
|
5261
|
+
}
|
|
5262
|
+
];
|
|
5263
|
+
pkg.evidence = {
|
|
5264
|
+
identity: {
|
|
5265
|
+
field: "purl",
|
|
5266
|
+
confidence: 0.7,
|
|
5267
|
+
methods: [
|
|
5268
|
+
{
|
|
5269
|
+
technique: "manifest-analysis",
|
|
5270
|
+
confidence: 0.7,
|
|
5271
|
+
value: projFile
|
|
5272
|
+
}
|
|
5273
|
+
]
|
|
5274
|
+
}
|
|
5275
|
+
};
|
|
5276
|
+
}
|
|
5235
5277
|
pkgList.push(pkg);
|
|
5236
5278
|
}
|
|
5237
5279
|
}
|
|
@@ -5239,7 +5281,10 @@ export const parseCsProjData = async function (csProjData) {
|
|
|
5239
5281
|
return pkgList;
|
|
5240
5282
|
};
|
|
5241
5283
|
|
|
5242
|
-
export const parseCsProjAssetsData = async function (
|
|
5284
|
+
export const parseCsProjAssetsData = async function (
|
|
5285
|
+
csProjData,
|
|
5286
|
+
assetsJsonFile
|
|
5287
|
+
) {
|
|
5243
5288
|
// extract name, operator, version from .NET package representation
|
|
5244
5289
|
// like "NLog >= 4.5.0"
|
|
5245
5290
|
function extractNameOperatorVersion(inputStr) {
|
|
@@ -5356,6 +5401,43 @@ export const parseCsProjAssetsData = async function (csProjData) {
|
|
|
5356
5401
|
} else if (lib[rootDep].sha256) {
|
|
5357
5402
|
pkg["_integrity"] = "sha256-" + lib[rootDep].sha256;
|
|
5358
5403
|
}
|
|
5404
|
+
if (lib[rootDep].files && Array.isArray(lib[rootDep].files)) {
|
|
5405
|
+
const dllFiles = new Set();
|
|
5406
|
+
lib[rootDep].files.forEach((f) => {
|
|
5407
|
+
if (
|
|
5408
|
+
f.endsWith(".dll") ||
|
|
5409
|
+
f.endsWith(".exe") ||
|
|
5410
|
+
f.endsWith(".so")
|
|
5411
|
+
) {
|
|
5412
|
+
dllFiles.add(basename(f));
|
|
5413
|
+
}
|
|
5414
|
+
});
|
|
5415
|
+
pkg.properties = [
|
|
5416
|
+
{
|
|
5417
|
+
name: "SrcFile",
|
|
5418
|
+
value: assetsJsonFile
|
|
5419
|
+
},
|
|
5420
|
+
{
|
|
5421
|
+
name: "PackageFiles",
|
|
5422
|
+
value: Array.from(dllFiles).join(", ")
|
|
5423
|
+
}
|
|
5424
|
+
];
|
|
5425
|
+
}
|
|
5426
|
+
}
|
|
5427
|
+
if (assetsJsonFile) {
|
|
5428
|
+
pkg.evidence = {
|
|
5429
|
+
identity: {
|
|
5430
|
+
field: "purl",
|
|
5431
|
+
confidence: 1,
|
|
5432
|
+
methods: [
|
|
5433
|
+
{
|
|
5434
|
+
technique: "manifest-analysis",
|
|
5435
|
+
confidence: 1,
|
|
5436
|
+
value: assetsJsonFile
|
|
5437
|
+
}
|
|
5438
|
+
]
|
|
5439
|
+
}
|
|
5440
|
+
};
|
|
5359
5441
|
}
|
|
5360
5442
|
pkgList.push(pkg);
|
|
5361
5443
|
pkgNameVersionMap[name + framework] = version;
|
|
@@ -7208,6 +7290,7 @@ export const executeAtom = (src, args) => {
|
|
|
7208
7290
|
let cwd =
|
|
7209
7291
|
existsSync(src) && lstatSync(src).isDirectory() ? src : dirname(src);
|
|
7210
7292
|
let ATOM_BIN = getAtomCommand();
|
|
7293
|
+
let isSupported = true;
|
|
7211
7294
|
if (ATOM_BIN.includes(" ")) {
|
|
7212
7295
|
const tmpA = ATOM_BIN.split(" ");
|
|
7213
7296
|
if (tmpA && tmpA.length > 1) {
|
|
@@ -7260,6 +7343,12 @@ export const executeAtom = (src, args) => {
|
|
|
7260
7343
|
);
|
|
7261
7344
|
}
|
|
7262
7345
|
}
|
|
7346
|
+
if (result.stdout) {
|
|
7347
|
+
if (result.stdout.includes("No language frontend supported for language")) {
|
|
7348
|
+
console.log("This language is not yet supported by atom.");
|
|
7349
|
+
isSupported = false;
|
|
7350
|
+
}
|
|
7351
|
+
}
|
|
7263
7352
|
if (DEBUG_MODE) {
|
|
7264
7353
|
if (result.stdout) {
|
|
7265
7354
|
console.log(result.stdout);
|
|
@@ -7268,7 +7357,7 @@ export const executeAtom = (src, args) => {
|
|
|
7268
7357
|
console.log(result.stderr);
|
|
7269
7358
|
}
|
|
7270
7359
|
}
|
|
7271
|
-
return !result.error;
|
|
7360
|
+
return isSupported && !result.error;
|
|
7272
7361
|
};
|
|
7273
7362
|
|
|
7274
7363
|
/**
|
|
@@ -8736,3 +8825,103 @@ export const getNugetMetadata = async function (
|
|
|
8736
8825
|
dependencies: newDependencies
|
|
8737
8826
|
};
|
|
8738
8827
|
};
|
|
8828
|
+
|
|
8829
|
+
export const addEvidenceForDotnet = (pkgList, slicesFile) => {
|
|
8830
|
+
// We need two datastructures.
|
|
8831
|
+
// dll to purl mapping from the pkgList
|
|
8832
|
+
// purl to occurrences list using the slicesFile
|
|
8833
|
+
if (!slicesFile || !existsSync(slicesFile)) {
|
|
8834
|
+
return pkgList;
|
|
8835
|
+
}
|
|
8836
|
+
const pkgFilePurlMap = {};
|
|
8837
|
+
const purlLocationMap = {};
|
|
8838
|
+
const purlModulesMap = {};
|
|
8839
|
+
const purlMethodsMap = {};
|
|
8840
|
+
for (const apkg of pkgList) {
|
|
8841
|
+
if (apkg.properties && Array.isArray(apkg.properties)) {
|
|
8842
|
+
apkg.properties
|
|
8843
|
+
.filter((p) => p.name === "PackageFiles")
|
|
8844
|
+
.forEach((aprop) => {
|
|
8845
|
+
if (aprop.value) {
|
|
8846
|
+
const tmpA = aprop.value.split(", ");
|
|
8847
|
+
if (tmpA && tmpA.length) {
|
|
8848
|
+
tmpA.forEach((dllFile) => {
|
|
8849
|
+
pkgFilePurlMap[dllFile] = apkg.purl;
|
|
8850
|
+
});
|
|
8851
|
+
}
|
|
8852
|
+
}
|
|
8853
|
+
});
|
|
8854
|
+
}
|
|
8855
|
+
}
|
|
8856
|
+
const slicesData = JSON.parse(readFileSync(slicesFile, "utf-8"));
|
|
8857
|
+
if (slicesData && Object.keys(slicesData)) {
|
|
8858
|
+
if (slicesData.Dependencies) {
|
|
8859
|
+
for (const adep of slicesData.Dependencies) {
|
|
8860
|
+
if (
|
|
8861
|
+
adep.Module &&
|
|
8862
|
+
adep.Module.endsWith(".dll") &&
|
|
8863
|
+
pkgFilePurlMap[adep.Module]
|
|
8864
|
+
) {
|
|
8865
|
+
const modPurl = pkgFilePurlMap[adep.Module];
|
|
8866
|
+
if (!purlLocationMap[modPurl]) {
|
|
8867
|
+
purlLocationMap[modPurl] = new Set();
|
|
8868
|
+
}
|
|
8869
|
+
purlLocationMap[modPurl].add(`${adep.Path}#${adep.LineNumber}`);
|
|
8870
|
+
}
|
|
8871
|
+
}
|
|
8872
|
+
}
|
|
8873
|
+
if (slicesData.MethodCalls) {
|
|
8874
|
+
for (const amethodCall of slicesData.MethodCalls) {
|
|
8875
|
+
if (
|
|
8876
|
+
amethodCall.Module &&
|
|
8877
|
+
amethodCall.Module.endsWith(".dll") &&
|
|
8878
|
+
pkgFilePurlMap[amethodCall.Module]
|
|
8879
|
+
) {
|
|
8880
|
+
const modPurl = pkgFilePurlMap[amethodCall.Module];
|
|
8881
|
+
if (!purlLocationMap[modPurl]) {
|
|
8882
|
+
purlLocationMap[modPurl] = new Set();
|
|
8883
|
+
}
|
|
8884
|
+
if (!purlModulesMap[modPurl]) {
|
|
8885
|
+
purlModulesMap[modPurl] = new Set();
|
|
8886
|
+
}
|
|
8887
|
+
if (!purlMethodsMap[modPurl]) {
|
|
8888
|
+
purlMethodsMap[modPurl] = new Set();
|
|
8889
|
+
}
|
|
8890
|
+
purlLocationMap[modPurl].add(
|
|
8891
|
+
`${amethodCall.Path}#${amethodCall.LineNumber}`
|
|
8892
|
+
);
|
|
8893
|
+
purlModulesMap[modPurl].add(amethodCall.ClassName);
|
|
8894
|
+
purlMethodsMap[modPurl].add(amethodCall.CalledMethod);
|
|
8895
|
+
}
|
|
8896
|
+
}
|
|
8897
|
+
}
|
|
8898
|
+
}
|
|
8899
|
+
if (Object.keys(purlLocationMap).length) {
|
|
8900
|
+
for (const apkg of pkgList) {
|
|
8901
|
+
if (purlLocationMap[apkg.purl]) {
|
|
8902
|
+
const locationOccurrences = Array.from(
|
|
8903
|
+
purlLocationMap[apkg.purl]
|
|
8904
|
+
).sort();
|
|
8905
|
+
// Add the occurrences evidence
|
|
8906
|
+
apkg.evidence.occurrences = locationOccurrences.map((l) => ({
|
|
8907
|
+
location: l
|
|
8908
|
+
}));
|
|
8909
|
+
}
|
|
8910
|
+
// Add the imported modules to properties
|
|
8911
|
+
if (purlModulesMap[apkg.purl]) {
|
|
8912
|
+
apkg.properties.push({
|
|
8913
|
+
name: "ImportedModules",
|
|
8914
|
+
value: Array.from(purlModulesMap[apkg.purl]).sort().join(", ")
|
|
8915
|
+
});
|
|
8916
|
+
}
|
|
8917
|
+
// Add the called methods to properties
|
|
8918
|
+
if (purlMethodsMap[apkg.purl]) {
|
|
8919
|
+
apkg.properties.push({
|
|
8920
|
+
name: "CalledMethods",
|
|
8921
|
+
value: Array.from(purlMethodsMap[apkg.purl]).sort().join(", ")
|
|
8922
|
+
});
|
|
8923
|
+
}
|
|
8924
|
+
}
|
|
8925
|
+
}
|
|
8926
|
+
return pkgList;
|
|
8927
|
+
};
|
package/utils.test.js
CHANGED
|
@@ -1272,8 +1272,9 @@ test("parse project.assets.json", async () => {
|
|
|
1272
1272
|
dependenciesList: [],
|
|
1273
1273
|
pkgList: []
|
|
1274
1274
|
});
|
|
1275
|
-
|
|
1276
|
-
readFileSync("./test/data/project.assets.json", { encoding: "utf-8" })
|
|
1275
|
+
let dep_list = await parseCsProjAssetsData(
|
|
1276
|
+
readFileSync("./test/data/project.assets.json", { encoding: "utf-8" }),
|
|
1277
|
+
"./test/data/project.assets.json"
|
|
1277
1278
|
);
|
|
1278
1279
|
expect(dep_list["pkgList"].length).toEqual(302);
|
|
1279
1280
|
expect(dep_list["pkgList"][0]).toEqual({
|
|
@@ -1309,6 +1310,26 @@ test("parse project.assets.json", async () => {
|
|
|
1309
1310
|
],
|
|
1310
1311
|
ref: "pkg:nuget/Castle.Core.Tests@0.0.0"
|
|
1311
1312
|
});
|
|
1313
|
+
dep_list = await parseCsProjAssetsData(
|
|
1314
|
+
readFileSync("./test/data/project.assets1.json", { encoding: "utf-8" }),
|
|
1315
|
+
"./test/data/project.assets1.json"
|
|
1316
|
+
);
|
|
1317
|
+
expect(dep_list["pkgList"].length).toEqual(43);
|
|
1318
|
+
expect(dep_list["pkgList"][0]).toEqual({
|
|
1319
|
+
"bom-ref": "pkg:nuget/Podcast.Server@1.0.0",
|
|
1320
|
+
purl: "pkg:nuget/Podcast.Server@1.0.0",
|
|
1321
|
+
group: "",
|
|
1322
|
+
name: "Podcast.Server",
|
|
1323
|
+
type: "application",
|
|
1324
|
+
version: "1.0.0"
|
|
1325
|
+
});
|
|
1326
|
+
/*
|
|
1327
|
+
const pkgList = addEvidenceForDotnet(
|
|
1328
|
+
dep_list.pkgList,
|
|
1329
|
+
"./test/data/dosai-methods.json"
|
|
1330
|
+
);
|
|
1331
|
+
expect(pkgList.length).toEqual(43);
|
|
1332
|
+
*/
|
|
1312
1333
|
});
|
|
1313
1334
|
|
|
1314
1335
|
test("parse packages.lock.json", async () => {
|
|
@@ -1725,8 +1746,8 @@ test("parsePkgLock v3", async () => {
|
|
|
1725
1746
|
projectName: "cdxgen"
|
|
1726
1747
|
});
|
|
1727
1748
|
deps = parsedList.pkgList;
|
|
1728
|
-
expect(deps.length).toEqual(
|
|
1729
|
-
expect(parsedList.dependenciesList.length).toEqual(
|
|
1749
|
+
expect(deps.length).toEqual(1205);
|
|
1750
|
+
expect(parsedList.dependenciesList.length).toEqual(1205);
|
|
1730
1751
|
});
|
|
1731
1752
|
|
|
1732
1753
|
test("parseBowerJson", async () => {
|