@cyclonedx/cdxgen 8.4.3 → 8.4.7
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 +1 -0
- package/docker.js +1 -0
- package/index.js +53 -4
- package/package.json +8 -8
- package/utils.js +67 -19
- package/utils.test.js +29 -0
package/README.md
CHANGED
|
@@ -248,7 +248,7 @@ cdxgen can retain the dependency tree under the `dependencies` attribute for a s
|
|
|
248
248
|
|
|
249
249
|
| Variable | Description |
|
|
250
250
|
| ---------------------------- | --------------------------------------------------------------------------------------------------------------------------- |
|
|
251
|
-
|
|
|
251
|
+
| CDXGEN_DEBUG_MODE | Set to `debug` to enable debug messages |
|
|
252
252
|
| GITHUB_TOKEN | Specify GitHub token to prevent traffic shaping while querying license and repo information |
|
|
253
253
|
| MVN_CMD | Set to override maven command |
|
|
254
254
|
| MVN_ARGS | Set to pass additional arguments such as profile or settings to maven |
|
package/binary.js
CHANGED
|
@@ -7,6 +7,7 @@ const isWin = require("os").platform() === "win32";
|
|
|
7
7
|
|
|
8
8
|
// Debug mode flag
|
|
9
9
|
const DEBUG_MODE =
|
|
10
|
+
process.env.CDXGEN_DEBUG_MODE === "debug" ||
|
|
10
11
|
process.env.SCAN_DEBUG_MODE === "debug" ||
|
|
11
12
|
process.env.SHIFTLEFT_LOGGING_LEVEL === "debug" ||
|
|
12
13
|
process.env.NODE_ENV === "development";
|
package/docker.js
CHANGED
package/index.js
CHANGED
|
@@ -55,6 +55,7 @@ let SBT_CACHE_DIR =
|
|
|
55
55
|
|
|
56
56
|
// Debug mode flag
|
|
57
57
|
const DEBUG_MODE =
|
|
58
|
+
process.env.CDXGEN_DEBUG_MODE === "debug" ||
|
|
58
59
|
process.env.SCAN_DEBUG_MODE === "debug" ||
|
|
59
60
|
process.env.SHIFTLEFT_LOGGING_LEVEL === "debug" ||
|
|
60
61
|
process.env.NODE_ENV === "development";
|
|
@@ -1189,6 +1190,15 @@ const createJavaBom = async (path, options) => {
|
|
|
1189
1190
|
const retMap = utils.parseGradleProjects(cmdOutput);
|
|
1190
1191
|
const allProjects = retMap.projects || [];
|
|
1191
1192
|
let rootProject = retMap.rootProject;
|
|
1193
|
+
if (rootProject) {
|
|
1194
|
+
parentComponent = {
|
|
1195
|
+
group: "",
|
|
1196
|
+
name: rootProject,
|
|
1197
|
+
version: "latest",
|
|
1198
|
+
type: "maven",
|
|
1199
|
+
qualifiers: { type: "jar" }
|
|
1200
|
+
};
|
|
1201
|
+
}
|
|
1192
1202
|
if (!allProjects) {
|
|
1193
1203
|
console.log(
|
|
1194
1204
|
"No projects found. Is this a gradle multi-project application?"
|
|
@@ -1200,6 +1210,37 @@ const createJavaBom = async (path, options) => {
|
|
|
1200
1210
|
allProjects.length,
|
|
1201
1211
|
"gradle sub-projects. This might take a while ..."
|
|
1202
1212
|
);
|
|
1213
|
+
// We need the first dependency between the root project and child projects
|
|
1214
|
+
// See: #249 and #315
|
|
1215
|
+
const rootDependsOn = [];
|
|
1216
|
+
for (let sp of allProjects) {
|
|
1217
|
+
sp = sp.replace(":", "");
|
|
1218
|
+
rootDependsOn.push(
|
|
1219
|
+
decodeURIComponent(
|
|
1220
|
+
new PackageURL(
|
|
1221
|
+
"maven",
|
|
1222
|
+
"",
|
|
1223
|
+
sp,
|
|
1224
|
+
parentComponent.version,
|
|
1225
|
+
parentComponent.qualifiers,
|
|
1226
|
+
null
|
|
1227
|
+
).toString()
|
|
1228
|
+
)
|
|
1229
|
+
);
|
|
1230
|
+
}
|
|
1231
|
+
dependencies.push({
|
|
1232
|
+
ref: decodeURIComponent(
|
|
1233
|
+
new PackageURL(
|
|
1234
|
+
"maven",
|
|
1235
|
+
parentComponent.group,
|
|
1236
|
+
parentComponent.name,
|
|
1237
|
+
parentComponent.version,
|
|
1238
|
+
parentComponent.qualifiers,
|
|
1239
|
+
null
|
|
1240
|
+
).toString()
|
|
1241
|
+
),
|
|
1242
|
+
dependsOn: rootDependsOn
|
|
1243
|
+
});
|
|
1203
1244
|
for (let sp of allProjects) {
|
|
1204
1245
|
let gradleDepArgs = [
|
|
1205
1246
|
sp + ":dependencies",
|
|
@@ -1232,15 +1273,20 @@ const createJavaBom = async (path, options) => {
|
|
|
1232
1273
|
}
|
|
1233
1274
|
const sstdout = sresult.stdout;
|
|
1234
1275
|
if (sstdout) {
|
|
1276
|
+
sp = sp.replace(":", "");
|
|
1235
1277
|
const cmdOutput = Buffer.from(sstdout).toString();
|
|
1236
|
-
const parsedList = utils.parseGradleDep(cmdOutput,
|
|
1278
|
+
const parsedList = utils.parseGradleDep(cmdOutput, sp);
|
|
1237
1279
|
const dlist = parsedList.pkgList;
|
|
1238
|
-
parentComponent
|
|
1280
|
+
// Do not overwrite the parentComponent in multi-project mode
|
|
1281
|
+
if (!parentComponent) {
|
|
1282
|
+
parentComponent = dlist.splice(0, 1)[0];
|
|
1283
|
+
}
|
|
1239
1284
|
if (
|
|
1240
1285
|
parsedList.dependenciesList &&
|
|
1241
1286
|
parsedList.dependenciesList
|
|
1242
1287
|
) {
|
|
1243
|
-
dependencies =
|
|
1288
|
+
dependencies = mergeDependencies(
|
|
1289
|
+
dependencies,
|
|
1244
1290
|
parsedList.dependenciesList
|
|
1245
1291
|
);
|
|
1246
1292
|
}
|
|
@@ -1347,7 +1393,10 @@ const createJavaBom = async (path, options) => {
|
|
|
1347
1393
|
const dlist = parsedList.pkgList;
|
|
1348
1394
|
parentComponent = dlist.splice(0, 1)[0];
|
|
1349
1395
|
if (parsedList.dependenciesList && parsedList.dependenciesList) {
|
|
1350
|
-
dependencies =
|
|
1396
|
+
dependencies = mergeDependencies(
|
|
1397
|
+
dependencies,
|
|
1398
|
+
parsedList.dependenciesList
|
|
1399
|
+
);
|
|
1351
1400
|
}
|
|
1352
1401
|
if (dlist && dlist.length) {
|
|
1353
1402
|
pkgList = pkgList.concat(dlist);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cyclonedx/cdxgen",
|
|
3
|
-
"version": "8.4.
|
|
3
|
+
"version": "8.4.7",
|
|
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>",
|
|
@@ -43,14 +43,14 @@
|
|
|
43
43
|
},
|
|
44
44
|
"repository": {
|
|
45
45
|
"type": "git",
|
|
46
|
-
"url": "git+https://github.com/
|
|
46
|
+
"url": "git+https://github.com/CycloneDX/cdxgen"
|
|
47
47
|
},
|
|
48
48
|
"bugs": {
|
|
49
49
|
"url": "https://github.com/cyclonedx/cdxgen/issues"
|
|
50
50
|
},
|
|
51
51
|
"dependencies": {
|
|
52
|
-
"@babel/parser": "^7.21.
|
|
53
|
-
"@babel/traverse": "^7.21.
|
|
52
|
+
"@babel/parser": "^7.21.8",
|
|
53
|
+
"@babel/traverse": "^7.21.5",
|
|
54
54
|
"cheerio": "^1.0.0-rc.12",
|
|
55
55
|
"edn-data": "^1.0.0",
|
|
56
56
|
"glob": "^8.1.0",
|
|
@@ -66,11 +66,11 @@
|
|
|
66
66
|
"semver": "^7.5.0",
|
|
67
67
|
"ssri": "^8.0.1",
|
|
68
68
|
"table": "^6.8.1",
|
|
69
|
-
"tar": "^6.1.
|
|
69
|
+
"tar": "^6.1.14",
|
|
70
70
|
"uuid": "^9.0.0",
|
|
71
71
|
"xml-js": "^1.6.11",
|
|
72
72
|
"xmlbuilder": "^15.1.1",
|
|
73
|
-
"yargs": "^17.7.
|
|
73
|
+
"yargs": "^17.7.2"
|
|
74
74
|
},
|
|
75
75
|
"optionalDependencies": {
|
|
76
76
|
"@cyclonedx/cdxgen-plugins-bin": "^1.1.0",
|
|
@@ -88,7 +88,7 @@
|
|
|
88
88
|
"queries.json"
|
|
89
89
|
],
|
|
90
90
|
"devDependencies": {
|
|
91
|
-
"eslint": "^8.
|
|
92
|
-
"jest": "^
|
|
91
|
+
"eslint": "^8.40.0",
|
|
92
|
+
"jest": "^29.5.0"
|
|
93
93
|
}
|
|
94
94
|
}
|
package/utils.js
CHANGED
|
@@ -20,6 +20,7 @@ const { PackageURL } = require("packageurl-js");
|
|
|
20
20
|
|
|
21
21
|
// Debug mode flag
|
|
22
22
|
const DEBUG_MODE =
|
|
23
|
+
process.env.CDXGEN_DEBUG_MODE === "debug" ||
|
|
23
24
|
process.env.SCAN_DEBUG_MODE === "debug" ||
|
|
24
25
|
process.env.SHIFTLEFT_LOGGING_LEVEL === "debug";
|
|
25
26
|
|
|
@@ -256,18 +257,33 @@ const _getDepPkgList = async function (
|
|
|
256
257
|
depKeys,
|
|
257
258
|
pkg
|
|
258
259
|
) {
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
260
|
+
let pkgDependencies =
|
|
261
|
+
pkg.lockfileVersion && pkg.lockfileVersion >= 3
|
|
262
|
+
? pkg.packages
|
|
263
|
+
: pkg.dependencies;
|
|
264
|
+
if (pkg && pkgDependencies) {
|
|
265
|
+
const pkgKeys = Object.keys(pkgDependencies);
|
|
266
|
+
for (const k of pkgKeys) {
|
|
267
|
+
// Skip the root package in lockFileVersion 3 and above
|
|
268
|
+
if (k === "") {
|
|
269
|
+
continue;
|
|
270
|
+
}
|
|
271
|
+
let name = k;
|
|
272
|
+
const version = pkgDependencies[name].version;
|
|
273
|
+
const purl = new PackageURL(
|
|
274
|
+
"npm",
|
|
275
|
+
"",
|
|
276
|
+
name.replace("node_modules/", ""),
|
|
277
|
+
version,
|
|
278
|
+
null,
|
|
279
|
+
null
|
|
280
|
+
);
|
|
265
281
|
const purlString = decodeURIComponent(purl.toString());
|
|
266
|
-
let scope =
|
|
282
|
+
let scope = pkgDependencies[name].dev === true ? "optional" : undefined;
|
|
267
283
|
const apkg = {
|
|
268
|
-
name,
|
|
284
|
+
name: name.replace("node_modules/", ""),
|
|
269
285
|
version,
|
|
270
|
-
_integrity:
|
|
286
|
+
_integrity: pkgDependencies[name].integrity,
|
|
271
287
|
scope,
|
|
272
288
|
properties: [
|
|
273
289
|
{
|
|
@@ -277,9 +293,9 @@ const _getDepPkgList = async function (
|
|
|
277
293
|
]
|
|
278
294
|
};
|
|
279
295
|
pkgList.push(apkg);
|
|
280
|
-
if (
|
|
296
|
+
if (pkgDependencies[name].dependencies) {
|
|
281
297
|
// Include child dependencies
|
|
282
|
-
const dependencies =
|
|
298
|
+
const dependencies = pkgDependencies[name].dependencies;
|
|
283
299
|
const pkgDepKeys = Object.keys(dependencies);
|
|
284
300
|
const deplist = [];
|
|
285
301
|
for (const j in pkgDepKeys) {
|
|
@@ -288,7 +304,7 @@ const _getDepPkgList = async function (
|
|
|
288
304
|
const deppurl = new PackageURL(
|
|
289
305
|
"npm",
|
|
290
306
|
"",
|
|
291
|
-
depName,
|
|
307
|
+
depName.replace("node_modules/", ""),
|
|
292
308
|
depVersion,
|
|
293
309
|
null,
|
|
294
310
|
null
|
|
@@ -303,13 +319,17 @@ const _getDepPkgList = async function (
|
|
|
303
319
|
});
|
|
304
320
|
depKeys[purlString] = true;
|
|
305
321
|
}
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
322
|
+
if (pkg.lockfileVersion && pkg.lockfileVersion >= 3) {
|
|
323
|
+
// Do not recurse for lock file v3 and above
|
|
324
|
+
} else {
|
|
325
|
+
await _getDepPkgList(
|
|
326
|
+
pkgLockFile,
|
|
327
|
+
pkgList,
|
|
328
|
+
dependenciesList,
|
|
329
|
+
depKeys,
|
|
330
|
+
pkgDependencies[name]
|
|
331
|
+
);
|
|
332
|
+
}
|
|
313
333
|
} else {
|
|
314
334
|
if (!depKeys[purlString]) {
|
|
315
335
|
dependenciesList.push({
|
|
@@ -1184,8 +1204,28 @@ const parseGradleDep = function (
|
|
|
1184
1204
|
const keys_cache = {};
|
|
1185
1205
|
let last_level = 0;
|
|
1186
1206
|
let last_purl = `pkg:maven/${rootProjectName}@${rootProjectVersion}?type=jar`;
|
|
1207
|
+
// Bug: 249. Get any sub-projects refered here
|
|
1208
|
+
const retMap = parseGradleProjects(rawOutput);
|
|
1187
1209
|
const level_trees = {};
|
|
1188
1210
|
level_trees[last_purl] = [];
|
|
1211
|
+
if (retMap && retMap.projects) {
|
|
1212
|
+
const subDependsOn = [];
|
|
1213
|
+
for (const sd of retMap.projects) {
|
|
1214
|
+
subDependsOn.push(
|
|
1215
|
+
decodeURIComponent(
|
|
1216
|
+
new PackageURL(
|
|
1217
|
+
"maven",
|
|
1218
|
+
"",
|
|
1219
|
+
sd.replace(":", ""),
|
|
1220
|
+
rootProject.version,
|
|
1221
|
+
rootProject.qualifiers,
|
|
1222
|
+
null
|
|
1223
|
+
).toString()
|
|
1224
|
+
)
|
|
1225
|
+
);
|
|
1226
|
+
}
|
|
1227
|
+
level_trees[last_purl] = subDependsOn;
|
|
1228
|
+
}
|
|
1189
1229
|
let stack = [last_purl];
|
|
1190
1230
|
const depRegex =
|
|
1191
1231
|
/^.*?--- +(?<group>[^\s:]+):(?<name>[^\s:]+)(?::(?:{strictly [[]?)?(?<versionspecified>[^,\s:}]+))?(?:})?(?:[^->]* +-> +(?<versionoverride>[^\s:]+))?/gm;
|
|
@@ -1368,6 +1408,14 @@ const parseGradleProjects = function (rawOutput) {
|
|
|
1368
1408
|
projects.add(projName);
|
|
1369
1409
|
}
|
|
1370
1410
|
}
|
|
1411
|
+
} else if (l.includes("--- project ")) {
|
|
1412
|
+
const tmpB = l.split("--- project ");
|
|
1413
|
+
if (tmpB && tmpB.length > 1) {
|
|
1414
|
+
let projName = tmpB[1];
|
|
1415
|
+
if (projName.startsWith(":")) {
|
|
1416
|
+
projects.add(projName);
|
|
1417
|
+
}
|
|
1418
|
+
}
|
|
1371
1419
|
}
|
|
1372
1420
|
});
|
|
1373
1421
|
return {
|
package/utils.test.js
CHANGED
|
@@ -206,6 +206,11 @@ test("parse gradle dependencies", () => {
|
|
|
206
206
|
);
|
|
207
207
|
expect(parsedList.pkgList.length).toEqual(68);
|
|
208
208
|
expect(parsedList.dependenciesList.length).toEqual(69);
|
|
209
|
+
parsedList = utils.parseGradleDep(
|
|
210
|
+
fs.readFileSync("./test/data/gradle-out-249.dep", { encoding: "utf-8" })
|
|
211
|
+
);
|
|
212
|
+
expect(parsedList.pkgList.length).toEqual(21);
|
|
213
|
+
expect(parsedList.dependenciesList.length).toEqual(21);
|
|
209
214
|
});
|
|
210
215
|
|
|
211
216
|
test("parse gradle projects", () => {
|
|
@@ -1097,6 +1102,30 @@ test("parsePkgLock", async () => {
|
|
|
1097
1102
|
"bom-ref": "pkg:application/MyProject",
|
|
1098
1103
|
name: "MyProject"
|
|
1099
1104
|
});
|
|
1105
|
+
parsedList = await utils.parsePkgLock("./test/data/package-lock-v2.json");
|
|
1106
|
+
deps = parsedList.pkgList;
|
|
1107
|
+
expect(deps.length).toEqual(1467);
|
|
1108
|
+
expect(parsedList.dependenciesList.length).toEqual(1280);
|
|
1109
|
+
expect(deps[0]).toEqual({
|
|
1110
|
+
"bom-ref": "pkg:application/flink-dashboard@2.0.0",
|
|
1111
|
+
group: "",
|
|
1112
|
+
name: "flink-dashboard",
|
|
1113
|
+
type: "application",
|
|
1114
|
+
version: "2.0.0"
|
|
1115
|
+
});
|
|
1116
|
+
expect(deps[deps.length - 1].name).toEqual("zone.js");
|
|
1117
|
+
parsedList = await utils.parsePkgLock("./test/data/package-lock-v3.json");
|
|
1118
|
+
deps = parsedList.pkgList;
|
|
1119
|
+
expect(deps.length).toEqual(879);
|
|
1120
|
+
expect(parsedList.dependenciesList.length).toEqual(879);
|
|
1121
|
+
expect(deps[0]).toEqual({
|
|
1122
|
+
"bom-ref": "pkg:application/@cyclonedx/cdxgen@8.4.3",
|
|
1123
|
+
group: "",
|
|
1124
|
+
name: "@cyclonedx/cdxgen",
|
|
1125
|
+
type: "application",
|
|
1126
|
+
version: "8.4.3"
|
|
1127
|
+
});
|
|
1128
|
+
expect(deps[deps.length - 1].name).toEqual("yocto-queue");
|
|
1100
1129
|
});
|
|
1101
1130
|
|
|
1102
1131
|
test("parseBowerJson", async () => {
|