@cyclonedx/cdxgen 9.9.6 → 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 +2 -1
- package/binary.js +52 -2
- package/evinser.js +3 -1
- package/index.js +40 -6
- package/package.json +13 -12
- package/utils.js +206 -35
- 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 | |
|
|
@@ -51,6 +51,7 @@ Most SBOM tools are like barcode scanners. They can scan a few package manifest
|
|
|
51
51
|
| Docker compose | docker-compose\*.yml. Images would also be scanned. | N/A | |
|
|
52
52
|
| Dockerfile | `*Dockerfile*` Images would also be scanned. | N/A | |
|
|
53
53
|
| Containerfile | `*Containerfile*`. Images would also be scanned. | N/A | |
|
|
54
|
+
| Bitbucket Pipelines | `bitbucket-pipelines.yml` images and pipes would also be scanned. | N/A | |
|
|
54
55
|
| Google CloudBuild configuration | cloudbuild.yaml | N/A | |
|
|
55
56
|
| OpenAPI | openapi\*.json, openapi\*.yaml | N/A | |
|
|
56
57
|
|
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
|
@@ -106,7 +106,9 @@ import {
|
|
|
106
106
|
getNugetMetadata,
|
|
107
107
|
frameworksList,
|
|
108
108
|
parseContainerFile,
|
|
109
|
-
parseBitbucketPipelinesFile
|
|
109
|
+
parseBitbucketPipelinesFile,
|
|
110
|
+
getPyMetadata,
|
|
111
|
+
addEvidenceForDotnet
|
|
110
112
|
} from "./utils.js";
|
|
111
113
|
import { spawnSync } from "node:child_process";
|
|
112
114
|
import { fileURLToPath } from "node:url";
|
|
@@ -130,7 +132,8 @@ import {
|
|
|
130
132
|
getGoBuildInfo,
|
|
131
133
|
getCargoAuditableInfo,
|
|
132
134
|
executeOsQuery,
|
|
133
|
-
getOSPackages
|
|
135
|
+
getOSPackages,
|
|
136
|
+
getDotnetSlices
|
|
134
137
|
} from "./binary.js";
|
|
135
138
|
|
|
136
139
|
const isWin = _platform() === "win32";
|
|
@@ -2575,6 +2578,9 @@ export const createPythonBom = async (path, options) => {
|
|
|
2575
2578
|
if (tempDir && tempDir.startsWith(tmpdir()) && rmSync) {
|
|
2576
2579
|
rmSync(tempDir, { recursive: true, force: true });
|
|
2577
2580
|
}
|
|
2581
|
+
if (FETCH_LICENSE) {
|
|
2582
|
+
pkgList = await getPyMetadata(pkgList, false);
|
|
2583
|
+
}
|
|
2578
2584
|
return buildBomNSData(options, pkgList, "pypi", {
|
|
2579
2585
|
allImports,
|
|
2580
2586
|
src: path,
|
|
@@ -4198,11 +4204,17 @@ export const createCsharpBom = async (
|
|
|
4198
4204
|
let manifestFiles = [];
|
|
4199
4205
|
let pkgData = undefined;
|
|
4200
4206
|
let dependencies = [];
|
|
4201
|
-
|
|
4207
|
+
let csProjFiles = getAllFiles(
|
|
4202
4208
|
path,
|
|
4203
4209
|
(options.multiProject ? "**/" : "") + "*.csproj",
|
|
4204
4210
|
options
|
|
4205
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
|
+
);
|
|
4206
4218
|
const pkgConfigFiles = getAllFiles(
|
|
4207
4219
|
path,
|
|
4208
4220
|
(options.multiProject ? "**/" : "") + "packages.config",
|
|
@@ -4249,7 +4261,7 @@ export const createCsharpBom = async (
|
|
|
4249
4261
|
console.log(`Parsing ${af}`);
|
|
4250
4262
|
}
|
|
4251
4263
|
pkgData = readFileSync(af, { encoding: "utf-8" });
|
|
4252
|
-
let results = await parseCsProjAssetsData(pkgData);
|
|
4264
|
+
let results = await parseCsProjAssetsData(pkgData, af);
|
|
4253
4265
|
let deps = results["dependenciesList"];
|
|
4254
4266
|
let dlist = results["pkgList"];
|
|
4255
4267
|
if (dlist && dlist.length) {
|
|
@@ -4301,7 +4313,7 @@ export const createCsharpBom = async (
|
|
|
4301
4313
|
if (csProjData.charCodeAt(0) === 0xfeff) {
|
|
4302
4314
|
csProjData = csProjData.slice(1);
|
|
4303
4315
|
}
|
|
4304
|
-
const dlist = await parseCsProjData(csProjData);
|
|
4316
|
+
const dlist = await parseCsProjData(csProjData, f);
|
|
4305
4317
|
if (dlist && dlist.length) {
|
|
4306
4318
|
pkgList = pkgList.concat(dlist);
|
|
4307
4319
|
}
|
|
@@ -4332,6 +4344,22 @@ export const createCsharpBom = async (
|
|
|
4332
4344
|
if (pkgList.length) {
|
|
4333
4345
|
dependencies = mergeDependencies(dependencies, [], parentComponent);
|
|
4334
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
|
+
}
|
|
4335
4363
|
}
|
|
4336
4364
|
if (FETCH_LICENSE) {
|
|
4337
4365
|
const retMap = await getNugetMetadata(pkgList, dependencies);
|
|
@@ -5113,11 +5141,17 @@ export const createXBom = async (path, options) => {
|
|
|
5113
5141
|
}
|
|
5114
5142
|
|
|
5115
5143
|
// .Net
|
|
5116
|
-
|
|
5144
|
+
let csProjFiles = getAllFiles(
|
|
5117
5145
|
path,
|
|
5118
5146
|
(options.multiProject ? "**/" : "") + "*.csproj",
|
|
5119
5147
|
options
|
|
5120
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
|
+
);
|
|
5121
5155
|
if (csProjFiles.length) {
|
|
5122
5156
|
return await createCsharpBom(path, options);
|
|
5123
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
|
@@ -19,8 +19,7 @@ import {
|
|
|
19
19
|
readFileSync,
|
|
20
20
|
rmSync,
|
|
21
21
|
unlinkSync,
|
|
22
|
-
writeFileSync
|
|
23
|
-
readdirSync
|
|
22
|
+
writeFileSync
|
|
24
23
|
} from "node:fs";
|
|
25
24
|
import got from "got";
|
|
26
25
|
import Arborist from "@npmcli/arborist";
|
|
@@ -5190,7 +5189,7 @@ export const parseCsPkgData = async function (pkgData) {
|
|
|
5190
5189
|
return pkgList;
|
|
5191
5190
|
};
|
|
5192
5191
|
|
|
5193
|
-
export const parseCsProjData = async function (csProjData) {
|
|
5192
|
+
export const parseCsProjData = async function (csProjData, projFile) {
|
|
5194
5193
|
const pkgList = [];
|
|
5195
5194
|
if (!csProjData) {
|
|
5196
5195
|
return pkgList;
|
|
@@ -5219,6 +5218,27 @@ export const parseCsProjData = async function (csProjData) {
|
|
|
5219
5218
|
}
|
|
5220
5219
|
pkg.name = pref.Include;
|
|
5221
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
|
+
}
|
|
5222
5242
|
pkgList.push(pkg);
|
|
5223
5243
|
}
|
|
5224
5244
|
// .net framework use Reference
|
|
@@ -5233,6 +5253,27 @@ export const parseCsProjData = async function (csProjData) {
|
|
|
5233
5253
|
if (incParts.length > 1 && incParts[1].includes("Version")) {
|
|
5234
5254
|
pkg.version = incParts[1].replace("Version=", "").trim();
|
|
5235
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
|
+
}
|
|
5236
5277
|
pkgList.push(pkg);
|
|
5237
5278
|
}
|
|
5238
5279
|
}
|
|
@@ -5240,7 +5281,10 @@ export const parseCsProjData = async function (csProjData) {
|
|
|
5240
5281
|
return pkgList;
|
|
5241
5282
|
};
|
|
5242
5283
|
|
|
5243
|
-
export const parseCsProjAssetsData = async function (
|
|
5284
|
+
export const parseCsProjAssetsData = async function (
|
|
5285
|
+
csProjData,
|
|
5286
|
+
assetsJsonFile
|
|
5287
|
+
) {
|
|
5244
5288
|
// extract name, operator, version from .NET package representation
|
|
5245
5289
|
// like "NLog >= 4.5.0"
|
|
5246
5290
|
function extractNameOperatorVersion(inputStr) {
|
|
@@ -5357,6 +5401,43 @@ export const parseCsProjAssetsData = async function (csProjData) {
|
|
|
5357
5401
|
} else if (lib[rootDep].sha256) {
|
|
5358
5402
|
pkg["_integrity"] = "sha256-" + lib[rootDep].sha256;
|
|
5359
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
|
+
};
|
|
5360
5441
|
}
|
|
5361
5442
|
pkgList.push(pkg);
|
|
5362
5443
|
pkgNameVersionMap[name + framework] = version;
|
|
@@ -6683,30 +6764,13 @@ export const encodeForPurl = (s) => {
|
|
|
6683
6764
|
export const getPomPropertiesFromMavenDir = function (mavenDir) {
|
|
6684
6765
|
let pomProperties = {};
|
|
6685
6766
|
if (existsSync(mavenDir) && lstatSync(mavenDir).isDirectory()) {
|
|
6686
|
-
|
|
6687
|
-
|
|
6688
|
-
|
|
6689
|
-
|
|
6690
|
-
|
|
6691
|
-
|
|
6692
|
-
|
|
6693
|
-
groupDirEntries.forEach((groupDirEntry) => {
|
|
6694
|
-
if (groupDirEntry.isDirectory()) {
|
|
6695
|
-
let pomPropertiesFile = join(
|
|
6696
|
-
groupDirEntry.path,
|
|
6697
|
-
groupDirEntry.name,
|
|
6698
|
-
"pom.properties"
|
|
6699
|
-
);
|
|
6700
|
-
if (existsSync(pomPropertiesFile)) {
|
|
6701
|
-
const pomPropertiesString = readFileSync(pomPropertiesFile, {
|
|
6702
|
-
encoding: "utf-8"
|
|
6703
|
-
});
|
|
6704
|
-
pomProperties = parsePomProperties(pomPropertiesString);
|
|
6705
|
-
}
|
|
6706
|
-
}
|
|
6707
|
-
});
|
|
6708
|
-
}
|
|
6709
|
-
});
|
|
6767
|
+
const pomPropertiesFiles = getAllFiles(mavenDir, "**/pom.properties");
|
|
6768
|
+
if (pomPropertiesFiles && pomPropertiesFiles.length) {
|
|
6769
|
+
const pomPropertiesString = readFileSync(pomPropertiesFiles[0], {
|
|
6770
|
+
encoding: "utf-8"
|
|
6771
|
+
});
|
|
6772
|
+
pomProperties = parsePomProperties(pomPropertiesString);
|
|
6773
|
+
}
|
|
6710
6774
|
}
|
|
6711
6775
|
return pomProperties;
|
|
6712
6776
|
};
|
|
@@ -6845,17 +6909,17 @@ export const extractJarArchive = function (
|
|
|
6845
6909
|
if (!name || !version || name === "" || version === "") {
|
|
6846
6910
|
confidence = 0.5;
|
|
6847
6911
|
technique = "filename";
|
|
6912
|
+
name = jarname.replace(".jar", "");
|
|
6848
6913
|
const tmpA = jarname.split("-");
|
|
6849
6914
|
if (tmpA && tmpA.length > 1) {
|
|
6850
6915
|
const lastPart = tmpA[tmpA.length - 1];
|
|
6851
|
-
if
|
|
6852
|
-
|
|
6853
|
-
|
|
6854
|
-
|
|
6916
|
+
// Bug #768. Check if we have any number before simplifying the name.
|
|
6917
|
+
if (/\d/.test(lastPart)) {
|
|
6918
|
+
if (!version || version === "") {
|
|
6919
|
+
version = lastPart.replace(".jar", "");
|
|
6920
|
+
}
|
|
6855
6921
|
name = jarname.replace("-" + lastPart, "") || "";
|
|
6856
6922
|
}
|
|
6857
|
-
} else {
|
|
6858
|
-
name = jarname.replace(".jar", "");
|
|
6859
6923
|
}
|
|
6860
6924
|
}
|
|
6861
6925
|
if (
|
|
@@ -7226,6 +7290,7 @@ export const executeAtom = (src, args) => {
|
|
|
7226
7290
|
let cwd =
|
|
7227
7291
|
existsSync(src) && lstatSync(src).isDirectory() ? src : dirname(src);
|
|
7228
7292
|
let ATOM_BIN = getAtomCommand();
|
|
7293
|
+
let isSupported = true;
|
|
7229
7294
|
if (ATOM_BIN.includes(" ")) {
|
|
7230
7295
|
const tmpA = ATOM_BIN.split(" ");
|
|
7231
7296
|
if (tmpA && tmpA.length > 1) {
|
|
@@ -7278,6 +7343,12 @@ export const executeAtom = (src, args) => {
|
|
|
7278
7343
|
);
|
|
7279
7344
|
}
|
|
7280
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
|
+
}
|
|
7281
7352
|
if (DEBUG_MODE) {
|
|
7282
7353
|
if (result.stdout) {
|
|
7283
7354
|
console.log(result.stdout);
|
|
@@ -7286,7 +7357,7 @@ export const executeAtom = (src, args) => {
|
|
|
7286
7357
|
console.log(result.stderr);
|
|
7287
7358
|
}
|
|
7288
7359
|
}
|
|
7289
|
-
return !result.error;
|
|
7360
|
+
return isSupported && !result.error;
|
|
7290
7361
|
};
|
|
7291
7362
|
|
|
7292
7363
|
/**
|
|
@@ -8754,3 +8825,103 @@ export const getNugetMetadata = async function (
|
|
|
8754
8825
|
dependencies: newDependencies
|
|
8755
8826
|
};
|
|
8756
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 () => {
|