@cyclonedx/cdxgen 8.4.11 → 8.4.13
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/index.js +53 -17
- package/package.json +1 -1
- package/utils.js +58 -18
- package/utils.test.js +32 -15
package/index.js
CHANGED
|
@@ -1057,7 +1057,7 @@ const createJavaBom = async (path, options) => {
|
|
|
1057
1057
|
"Resolve the above maven error. This could be due to the following:\n"
|
|
1058
1058
|
);
|
|
1059
1059
|
console.log(
|
|
1060
|
-
"1. Java version requirement: cdxgen container image bundles Java 17 with
|
|
1060
|
+
"1. Java version requirement: cdxgen container image bundles Java 17 with maven 3.8 which might be incompatible."
|
|
1061
1061
|
);
|
|
1062
1062
|
console.log(
|
|
1063
1063
|
"2. Private dependencies cannot be downloaded: Check if any additional arguments must be passed to maven and set them via MVN_ARGS environment variable."
|
|
@@ -1580,6 +1580,7 @@ const createJavaBom = async (path, options) => {
|
|
|
1580
1580
|
sbtVersion != null &&
|
|
1581
1581
|
semver.gte(sbtVersion, "1.3.4") &&
|
|
1582
1582
|
semver.lte(sbtVersion, "1.4.0");
|
|
1583
|
+
const useSlashSyntax = semver.gte(sbtVersion, "1.5.0");
|
|
1583
1584
|
const isDependencyTreeBuiltIn =
|
|
1584
1585
|
sbtVersion != null && semver.gte(sbtVersion, "1.4.0");
|
|
1585
1586
|
let tempDir = fs.mkdtempSync(pathLib.join(os.tmpdir(), "cdxsbt-"));
|
|
@@ -1619,7 +1620,11 @@ const createJavaBom = async (path, options) => {
|
|
|
1619
1620
|
];
|
|
1620
1621
|
} else {
|
|
1621
1622
|
// write to the existing plugins file
|
|
1622
|
-
|
|
1623
|
+
if (useSlashSyntax) {
|
|
1624
|
+
sbtArgs = [`"dependencyList / toFile ${dlFile} --force"`];
|
|
1625
|
+
} else {
|
|
1626
|
+
sbtArgs = [`"dependencyList::toFile ${dlFile} --force"`];
|
|
1627
|
+
}
|
|
1623
1628
|
pluginFile = utils.addPlugin(basePath, sbtPluginDefinition);
|
|
1624
1629
|
}
|
|
1625
1630
|
// Note that the command has to be invoked with `shell: true` to properly execut sbt
|
|
@@ -1641,17 +1646,12 @@ const createJavaBom = async (path, options) => {
|
|
|
1641
1646
|
"3. Consider creating a lockfile using sbt-dependency-lock plugin. See https://github.com/stringbean/sbt-dependency-lock"
|
|
1642
1647
|
);
|
|
1643
1648
|
options.failOnError && process.exit(1);
|
|
1644
|
-
} else if (DEBUG_MODE) {
|
|
1645
|
-
console.log(result.stdout);
|
|
1646
1649
|
}
|
|
1647
1650
|
if (!standalonePluginFile) {
|
|
1648
1651
|
utils.cleanupPlugin(basePath, pluginFile);
|
|
1649
1652
|
}
|
|
1650
1653
|
if (fs.existsSync(dlFile)) {
|
|
1651
1654
|
const cmdOutput = fs.readFileSync(dlFile, { encoding: "utf-8" });
|
|
1652
|
-
if (DEBUG_MODE) {
|
|
1653
|
-
console.log(cmdOutput);
|
|
1654
|
-
}
|
|
1655
1655
|
const dlist = utils.parseKVDep(cmdOutput);
|
|
1656
1656
|
if (dlist && dlist.length) {
|
|
1657
1657
|
pkgList = pkgList.concat(dlist);
|
|
@@ -4569,7 +4569,7 @@ exports.createBom = createBom;
|
|
|
4569
4569
|
* @param bomContents BOM Xml
|
|
4570
4570
|
*/
|
|
4571
4571
|
exports.submitBom = async (args, bomContents) => {
|
|
4572
|
-
let serverUrl = args.serverUrl + "/api/v1/bom";
|
|
4572
|
+
let serverUrl = args.serverUrl.replace(/\/$/, "") + "/api/v1/bom";
|
|
4573
4573
|
let encodedBomContents = Buffer.from(bomContents).toString("base64");
|
|
4574
4574
|
if (encodedBomContents.startsWith("77u/")) {
|
|
4575
4575
|
encodedBomContents = encodedBomContents.substring(4);
|
|
@@ -4594,13 +4594,49 @@ exports.submitBom = async (args, bomContents) => {
|
|
|
4594
4594
|
projectVersion
|
|
4595
4595
|
);
|
|
4596
4596
|
}
|
|
4597
|
-
|
|
4598
|
-
|
|
4599
|
-
|
|
4600
|
-
|
|
4601
|
-
|
|
4602
|
-
|
|
4603
|
-
|
|
4604
|
-
|
|
4605
|
-
|
|
4597
|
+
try {
|
|
4598
|
+
return await got(serverUrl, {
|
|
4599
|
+
method: "PUT",
|
|
4600
|
+
headers: {
|
|
4601
|
+
"X-Api-Key": args.apiKey,
|
|
4602
|
+
"Content-Type": "application/json"
|
|
4603
|
+
},
|
|
4604
|
+
json: bomPayload,
|
|
4605
|
+
responseType: "json"
|
|
4606
|
+
}).json();
|
|
4607
|
+
} catch (error) {
|
|
4608
|
+
if (error.response && error.response.statusCode === 401) {
|
|
4609
|
+
// Unauthorized
|
|
4610
|
+
console.log(
|
|
4611
|
+
"Received Unauthorized error. Check the API key used is valid and has necessary permissions to create projects and upload bom."
|
|
4612
|
+
);
|
|
4613
|
+
} else if (error.response && error.response.statusCode === 405) {
|
|
4614
|
+
// Method not allowed errors
|
|
4615
|
+
try {
|
|
4616
|
+
return await got(serverUrl, {
|
|
4617
|
+
method: "POST",
|
|
4618
|
+
headers: {
|
|
4619
|
+
"X-Api-Key": args.apiKey,
|
|
4620
|
+
"Content-Type": "application/json"
|
|
4621
|
+
},
|
|
4622
|
+
json: {
|
|
4623
|
+
project: args.projectId,
|
|
4624
|
+
projectName: args.projectName,
|
|
4625
|
+
projectVersion: projectVersion,
|
|
4626
|
+
autoCreate: "true",
|
|
4627
|
+
bom: Buffer.from(bomContents).toString()
|
|
4628
|
+
},
|
|
4629
|
+
responseType: "json"
|
|
4630
|
+
}).json();
|
|
4631
|
+
} catch (error) {
|
|
4632
|
+
console.log(
|
|
4633
|
+
"Unable to submit the SBoM to the Dependency-Track server using POST method"
|
|
4634
|
+
);
|
|
4635
|
+
console.log(error);
|
|
4636
|
+
}
|
|
4637
|
+
} else {
|
|
4638
|
+
console.log("Unable to submit the SBoM to the Dependency-Track server");
|
|
4639
|
+
console.log(error);
|
|
4640
|
+
}
|
|
4641
|
+
}
|
|
4606
4642
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cyclonedx/cdxgen",
|
|
3
|
-
"version": "8.4.
|
|
3
|
+
"version": "8.4.13",
|
|
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>",
|
package/utils.js
CHANGED
|
@@ -1103,7 +1103,7 @@ const parseMavenTree = function (rawOutput) {
|
|
|
1103
1103
|
let last_purl = "";
|
|
1104
1104
|
let stack = [];
|
|
1105
1105
|
tmpA.forEach((l) => {
|
|
1106
|
-
if (!includeMavenTestScope && l.endsWith(":test")) {
|
|
1106
|
+
if (!includeMavenTestScope && l.trim().endsWith(":test")) {
|
|
1107
1107
|
return;
|
|
1108
1108
|
}
|
|
1109
1109
|
let level = 0;
|
|
@@ -1218,8 +1218,11 @@ const parseGradleDep = function (
|
|
|
1218
1218
|
let last_level = 0;
|
|
1219
1219
|
let last_purl = `pkg:maven/${rootProjectName}@${rootProjectVersion}?type=jar`;
|
|
1220
1220
|
const first_purl = last_purl;
|
|
1221
|
+
let last_project_purl = first_purl;
|
|
1221
1222
|
const level_trees = {};
|
|
1222
1223
|
level_trees[last_purl] = [];
|
|
1224
|
+
let scope = undefined;
|
|
1225
|
+
let profileName = undefined;
|
|
1223
1226
|
if (retMap && retMap.projects) {
|
|
1224
1227
|
const subDependsOn = [];
|
|
1225
1228
|
for (const sd of retMap.projects) {
|
|
@@ -1242,16 +1245,34 @@ const parseGradleDep = function (
|
|
|
1242
1245
|
const depRegex =
|
|
1243
1246
|
/^.*?--- +(?<group>[^\s:]+):(?<name>[^\s:]+)(?::(?:{strictly [[]?)?(?<versionspecified>[^,\s:}]+))?(?:})?(?:[^->]* +-> +(?<versionoverride>[^\s:]+))?/gm;
|
|
1244
1247
|
for (const rline of rawOutput.split("\n")) {
|
|
1245
|
-
if (
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
)
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1248
|
+
if (!rline) {
|
|
1249
|
+
continue;
|
|
1250
|
+
}
|
|
1251
|
+
if (
|
|
1252
|
+
rline.trim() === "" ||
|
|
1253
|
+
rline.startsWith("+--- ") ||
|
|
1254
|
+
rline.startsWith("\\--- ")
|
|
1255
|
+
) {
|
|
1256
|
+
last_level = 1;
|
|
1257
|
+
if (rline.startsWith("+--- project :")) {
|
|
1258
|
+
let tmpProj = rline.split("+--- project :");
|
|
1259
|
+
last_project_purl = `pkg:maven/${tmpProj[1].trim()}@${rootProjectVersion}?type=jar`;
|
|
1260
|
+
stack = [last_project_purl];
|
|
1261
|
+
last_purl = last_project_purl;
|
|
1262
|
+
} else {
|
|
1263
|
+
last_project_purl = first_purl;
|
|
1264
|
+
last_purl = last_project_purl;
|
|
1265
|
+
stack = [first_purl];
|
|
1266
|
+
}
|
|
1267
|
+
}
|
|
1268
|
+
if (rline.includes(" - ")) {
|
|
1269
|
+
profileName = rline.split(" - ")[0];
|
|
1270
|
+
if (profileName.toLowerCase().includes("test")) {
|
|
1271
|
+
scope = "optional";
|
|
1272
|
+
} else if (profileName.toLowerCase().includes("runtime")) {
|
|
1273
|
+
scope = "required";
|
|
1274
|
+
} else {
|
|
1275
|
+
scope = undefined;
|
|
1255
1276
|
}
|
|
1256
1277
|
}
|
|
1257
1278
|
while ((match = depRegex.exec(rline))) {
|
|
@@ -1273,21 +1294,38 @@ const parseGradleDep = function (
|
|
|
1273
1294
|
// Filter duplicates
|
|
1274
1295
|
if (!deps_keys_cache[purlString]) {
|
|
1275
1296
|
deps_keys_cache[purlString] = true;
|
|
1276
|
-
|
|
1297
|
+
const adep = {
|
|
1277
1298
|
group,
|
|
1278
1299
|
name: name,
|
|
1279
1300
|
version: version,
|
|
1280
1301
|
qualifiers: { type: "jar" }
|
|
1281
|
-
}
|
|
1302
|
+
};
|
|
1303
|
+
if (scope) {
|
|
1304
|
+
adep["scope"] = scope;
|
|
1305
|
+
}
|
|
1306
|
+
if (profileName) {
|
|
1307
|
+
adep.properties = [
|
|
1308
|
+
{
|
|
1309
|
+
name: "GradleProfileName",
|
|
1310
|
+
value: profileName
|
|
1311
|
+
}
|
|
1312
|
+
];
|
|
1313
|
+
}
|
|
1314
|
+
deps.push(adep);
|
|
1282
1315
|
}
|
|
1283
1316
|
if (!level_trees[purlString]) {
|
|
1284
1317
|
level_trees[purlString] = [];
|
|
1285
1318
|
}
|
|
1286
|
-
if (level == 0
|
|
1319
|
+
if (level == 0) {
|
|
1320
|
+
stack = [first_purl];
|
|
1321
|
+
stack.push(purlString);
|
|
1322
|
+
} else if (last_purl === "") {
|
|
1287
1323
|
stack.push(purlString);
|
|
1288
1324
|
} else if (level > last_level) {
|
|
1289
1325
|
const cnodes = level_trees[last_purl] || [];
|
|
1290
|
-
cnodes.
|
|
1326
|
+
if (!cnodes.includes(purlString)) {
|
|
1327
|
+
cnodes.push(purlString);
|
|
1328
|
+
}
|
|
1291
1329
|
level_trees[last_purl] = cnodes;
|
|
1292
1330
|
if (stack[stack.length - 1] !== purlString) {
|
|
1293
1331
|
stack.push(purlString);
|
|
@@ -1297,9 +1335,11 @@ const parseGradleDep = function (
|
|
|
1297
1335
|
stack.pop();
|
|
1298
1336
|
}
|
|
1299
1337
|
const last_stack =
|
|
1300
|
-
stack.length > 0 ? stack[stack.length - 1] :
|
|
1338
|
+
stack.length > 0 ? stack[stack.length - 1] : last_project_purl;
|
|
1301
1339
|
const cnodes = level_trees[last_stack] || [];
|
|
1302
|
-
cnodes.
|
|
1340
|
+
if (!cnodes.includes(purlString)) {
|
|
1341
|
+
cnodes.push(purlString);
|
|
1342
|
+
}
|
|
1303
1343
|
level_trees[last_stack] = cnodes;
|
|
1304
1344
|
stack.push(purlString);
|
|
1305
1345
|
}
|
|
@@ -1614,7 +1654,7 @@ const getMvnMetadata = async function (pkgList) {
|
|
|
1614
1654
|
if (!pkgList || !pkgList.length) {
|
|
1615
1655
|
return pkgList;
|
|
1616
1656
|
}
|
|
1617
|
-
if (DEBUG_MODE) {
|
|
1657
|
+
if (DEBUG_MODE && fetchLicenses) {
|
|
1618
1658
|
console.log(`About to query maven for ${pkgList.length} packages`);
|
|
1619
1659
|
}
|
|
1620
1660
|
for (const p of pkgList) {
|
package/utils.test.js
CHANGED
|
@@ -98,7 +98,14 @@ test("parse gradle dependencies", () => {
|
|
|
98
98
|
qualifiers: {
|
|
99
99
|
type: "jar"
|
|
100
100
|
},
|
|
101
|
-
|
|
101
|
+
scope: "optional",
|
|
102
|
+
version: "1.0.2",
|
|
103
|
+
properties: [
|
|
104
|
+
{
|
|
105
|
+
name: "GradleProfileName",
|
|
106
|
+
value: "androidTestImplementation"
|
|
107
|
+
}
|
|
108
|
+
]
|
|
102
109
|
});
|
|
103
110
|
expect(parsedList.pkgList[104]).toEqual({
|
|
104
111
|
group: "androidx.print",
|
|
@@ -106,15 +113,14 @@ test("parse gradle dependencies", () => {
|
|
|
106
113
|
qualifiers: {
|
|
107
114
|
type: "jar"
|
|
108
115
|
},
|
|
109
|
-
version: "1.0.0"
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
version: "1.7.0"
|
|
116
|
+
version: "1.0.0",
|
|
117
|
+
scope: "optional",
|
|
118
|
+
properties: [
|
|
119
|
+
{
|
|
120
|
+
name: "GradleProfileName",
|
|
121
|
+
value: "releaseUnitTestRuntimeClasspath"
|
|
122
|
+
}
|
|
123
|
+
]
|
|
118
124
|
});
|
|
119
125
|
parsedList = utils.parseGradleDep(
|
|
120
126
|
fs.readFileSync("./test/data/gradle-out1.dep", { encoding: "utf-8" })
|
|
@@ -125,7 +131,13 @@ test("parse gradle dependencies", () => {
|
|
|
125
131
|
group: "org.springframework.boot",
|
|
126
132
|
name: "spring-boot-starter-web",
|
|
127
133
|
version: "2.2.0.RELEASE",
|
|
128
|
-
qualifiers: { type: "jar" }
|
|
134
|
+
qualifiers: { type: "jar" },
|
|
135
|
+
properties: [
|
|
136
|
+
{
|
|
137
|
+
name: "GradleProfileName",
|
|
138
|
+
value: "compileClasspath"
|
|
139
|
+
}
|
|
140
|
+
]
|
|
129
141
|
});
|
|
130
142
|
|
|
131
143
|
parsedList = utils.parseGradleDep(
|
|
@@ -210,17 +222,17 @@ test("parse gradle dependencies", () => {
|
|
|
210
222
|
fs.readFileSync("./test/data/gradle-out-249.dep", { encoding: "utf-8" })
|
|
211
223
|
);
|
|
212
224
|
expect(parsedList.pkgList.length).toEqual(21);
|
|
213
|
-
expect(parsedList.dependenciesList.length).toEqual(
|
|
225
|
+
expect(parsedList.dependenciesList.length).toEqual(22);
|
|
214
226
|
parsedList = utils.parseGradleDep(
|
|
215
227
|
fs.readFileSync("./test/data/gradle-service.out", { encoding: "utf-8" })
|
|
216
228
|
);
|
|
217
229
|
expect(parsedList.pkgList.length).toEqual(35);
|
|
218
|
-
expect(parsedList.dependenciesList.length).toEqual(
|
|
230
|
+
expect(parsedList.dependenciesList.length).toEqual(36);
|
|
219
231
|
parsedList = utils.parseGradleDep(
|
|
220
232
|
fs.readFileSync("./test/data/gradle-s.out", { encoding: "utf-8" })
|
|
221
233
|
);
|
|
222
234
|
expect(parsedList.pkgList.length).toEqual(28);
|
|
223
|
-
expect(parsedList.dependenciesList.length).toEqual(
|
|
235
|
+
expect(parsedList.dependenciesList.length).toEqual(29);
|
|
224
236
|
parsedList = utils.parseGradleDep(
|
|
225
237
|
fs.readFileSync("./test/data/gradle-core.out", { encoding: "utf-8" })
|
|
226
238
|
);
|
|
@@ -1022,8 +1034,8 @@ test("get repo license", async () => {
|
|
|
1022
1034
|
url: "https://github.com/ugorji/go/blob/master/LICENSE"
|
|
1023
1035
|
});
|
|
1024
1036
|
});
|
|
1025
|
-
*/
|
|
1026
1037
|
test("get go pkg license", async () => {
|
|
1038
|
+
jest.setTimeout(120000);
|
|
1027
1039
|
let license = await utils.getGoPkgLicense({
|
|
1028
1040
|
group: "github.com/Azure/azure-amqp-common-go",
|
|
1029
1041
|
name: "v2"
|
|
@@ -1057,6 +1069,7 @@ test("get go pkg license", async () => {
|
|
|
1057
1069
|
}
|
|
1058
1070
|
]);
|
|
1059
1071
|
});
|
|
1072
|
+
*/
|
|
1060
1073
|
|
|
1061
1074
|
test("get licenses", () => {
|
|
1062
1075
|
let licenses = utils.getLicenses({ license: "MIT" });
|
|
@@ -1639,6 +1652,10 @@ test("parse scala sbt list", async () => {
|
|
|
1639
1652
|
fs.readFileSync("./test/data/sbt-dl.list", { encoding: "utf-8" })
|
|
1640
1653
|
);
|
|
1641
1654
|
expect(deps.length).toEqual(57);
|
|
1655
|
+
deps = utils.parseKVDep(
|
|
1656
|
+
fs.readFileSync("./test/data/atom-sbt-list.txt", { encoding: "utf-8" })
|
|
1657
|
+
);
|
|
1658
|
+
expect(deps.length).toEqual(117);
|
|
1642
1659
|
});
|
|
1643
1660
|
|
|
1644
1661
|
test("parse scala sbt lock", async () => {
|