@cyclonedx/cdxgen 10.2.4 → 10.2.6
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 +13 -4
- package/package.json +1 -1
- package/utils.js +88 -12
- package/utils.test.js +48 -25
package/index.js
CHANGED
|
@@ -4312,6 +4312,13 @@ export async function createCsharpBom(path, options) {
|
|
|
4312
4312
|
csProjFiles = csProjFiles.concat(
|
|
4313
4313
|
getAllFiles(path, (options.multiProject ? "**/" : "") + "*.vbproj", options)
|
|
4314
4314
|
);
|
|
4315
|
+
csProjFiles = csProjFiles.concat(
|
|
4316
|
+
getAllFiles(
|
|
4317
|
+
path,
|
|
4318
|
+
(options.multiProject ? "**/" : "") + "*.vcxproj",
|
|
4319
|
+
options
|
|
4320
|
+
)
|
|
4321
|
+
);
|
|
4315
4322
|
csProjFiles = csProjFiles.concat(
|
|
4316
4323
|
getAllFiles(path, (options.multiProject ? "**/" : "") + "*.fsproj", options)
|
|
4317
4324
|
);
|
|
@@ -4412,7 +4419,7 @@ export async function createCsharpBom(path, options) {
|
|
|
4412
4419
|
}
|
|
4413
4420
|
} else if (pkgLockFiles.length) {
|
|
4414
4421
|
manifestFiles = manifestFiles.concat(pkgLockFiles);
|
|
4415
|
-
|
|
4422
|
+
const parentDependsOn = new Set();
|
|
4416
4423
|
// packages.lock.json from nuget
|
|
4417
4424
|
for (const af of pkgLockFiles) {
|
|
4418
4425
|
if (DEBUG_MODE) {
|
|
@@ -4432,13 +4439,15 @@ export async function createCsharpBom(path, options) {
|
|
|
4432
4439
|
// Keep track of the direct dependencies so that we can construct one complete
|
|
4433
4440
|
// list after processing all lock files
|
|
4434
4441
|
if (rootList && rootList.length) {
|
|
4435
|
-
|
|
4442
|
+
for (const p of rootList) {
|
|
4443
|
+
parentDependsOn.add(p["bom-ref"]);
|
|
4444
|
+
}
|
|
4436
4445
|
}
|
|
4437
4446
|
}
|
|
4438
|
-
if (parentDependsOn.
|
|
4447
|
+
if (parentDependsOn.size) {
|
|
4439
4448
|
dependencies.splice(0, 0, {
|
|
4440
4449
|
ref: parentComponent["bom-ref"],
|
|
4441
|
-
dependsOn:
|
|
4450
|
+
dependsOn: Array.from(parentDependsOn)
|
|
4442
4451
|
});
|
|
4443
4452
|
}
|
|
4444
4453
|
} else if (pkgConfigFiles.length) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cyclonedx/cdxgen",
|
|
3
|
-
"version": "10.2.
|
|
3
|
+
"version": "10.2.6",
|
|
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
|
@@ -825,19 +825,25 @@ export async function parsePkgLock(pkgLockFile, options = {}) {
|
|
|
825
825
|
// which isn't installed
|
|
826
826
|
// Bug #795. At times, npm loses the integrity node completely and such packages are getting missed out
|
|
827
827
|
// To keep things safe, we include these packages.
|
|
828
|
-
|
|
829
|
-
|
|
828
|
+
let edgeToIntegrityOrLocation = edge.to ? edge.to.integrity : undefined;
|
|
829
|
+
// Fallback to location based lookups when integrity is missing
|
|
830
|
+
if (!edgeToIntegrityOrLocation && edge.to && edge.to.location) {
|
|
831
|
+
edgeToIntegrityOrLocation = edge.to.location;
|
|
832
|
+
}
|
|
833
|
+
if (!edgeToIntegrityOrLocation) {
|
|
830
834
|
// This hack is required to fix the package name
|
|
831
|
-
targetName =
|
|
832
|
-
|
|
833
|
-
foundMatch = true;
|
|
835
|
+
targetName = edge.name.replace(/-cjs$/, "");
|
|
836
|
+
foundMatch = false;
|
|
834
837
|
} else {
|
|
835
838
|
// the edges don't actually contain a version, so we need to search the root node
|
|
836
839
|
// children to find the correct version. we check the node children first, then
|
|
837
840
|
// we check the root node children
|
|
838
841
|
for (const child of node.children) {
|
|
839
|
-
if (
|
|
840
|
-
if (
|
|
842
|
+
if (edgeToIntegrityOrLocation) {
|
|
843
|
+
if (
|
|
844
|
+
child[1].integrity === edgeToIntegrityOrLocation ||
|
|
845
|
+
child[1].location === edgeToIntegrityOrLocation
|
|
846
|
+
) {
|
|
841
847
|
targetName = child[0].replace(/node_modules\//g, "");
|
|
842
848
|
// The package name could be different from the targetName retrieved
|
|
843
849
|
// Eg: "string-width-cjs": "npm:string-width@^4.2.0",
|
|
@@ -853,7 +859,11 @@ export async function parsePkgLock(pkgLockFile, options = {}) {
|
|
|
853
859
|
}
|
|
854
860
|
if (!foundMatch) {
|
|
855
861
|
for (const child of rootNode.children) {
|
|
856
|
-
if (
|
|
862
|
+
if (
|
|
863
|
+
edgeToIntegrityOrLocation &&
|
|
864
|
+
(child[1].integrity == edgeToIntegrityOrLocation ||
|
|
865
|
+
child[1].location == edgeToIntegrityOrLocation)
|
|
866
|
+
) {
|
|
857
867
|
targetName = child[0].replace(/node_modules\//g, "");
|
|
858
868
|
targetVersion = child[1].version;
|
|
859
869
|
// The package name could be different from the targetName retrieved
|
|
@@ -897,7 +907,6 @@ export async function parsePkgLock(pkgLockFile, options = {}) {
|
|
|
897
907
|
pkgList = pkgList.concat(childPkgList);
|
|
898
908
|
dependenciesList = dependenciesList.concat(childDependenciesList);
|
|
899
909
|
}
|
|
900
|
-
|
|
901
910
|
dependenciesList.push({
|
|
902
911
|
ref: decodeURIComponent(purlString),
|
|
903
912
|
dependsOn: workspaceDependsOn
|
|
@@ -6018,17 +6027,84 @@ export function parseCsPkgLockData(csLockData, pkgLockFile) {
|
|
|
6018
6027
|
}
|
|
6019
6028
|
};
|
|
6020
6029
|
pkgList.push(pkg);
|
|
6021
|
-
if (libData.type
|
|
6030
|
+
if (["Direct", "Project"].includes(libData.type)) {
|
|
6022
6031
|
rootList.push(pkg);
|
|
6023
6032
|
}
|
|
6024
6033
|
const dependsOn = [];
|
|
6025
6034
|
if (libData.dependencies) {
|
|
6026
|
-
for (
|
|
6035
|
+
for (let adep of Object.keys(libData.dependencies)) {
|
|
6036
|
+
let adepResolvedVersion = libData.dependencies[adep];
|
|
6037
|
+
const aversionNoRuntime = aversion.split("/")[0];
|
|
6038
|
+
let isProjectType = false;
|
|
6039
|
+
// Try to get the resolved version of the dependency. See #930 and #937
|
|
6040
|
+
if (
|
|
6041
|
+
assetData.dependencies[aversion] &&
|
|
6042
|
+
assetData.dependencies[aversion][adep] &&
|
|
6043
|
+
assetData.dependencies[aversion][adep].resolved
|
|
6044
|
+
) {
|
|
6045
|
+
adepResolvedVersion =
|
|
6046
|
+
assetData.dependencies[aversion][adep].resolved;
|
|
6047
|
+
} else if (
|
|
6048
|
+
aversion.includes("/") &&
|
|
6049
|
+
assetData.dependencies[aversionNoRuntime] &&
|
|
6050
|
+
assetData.dependencies[aversionNoRuntime][adep] &&
|
|
6051
|
+
assetData.dependencies[aversionNoRuntime][adep].resolved
|
|
6052
|
+
) {
|
|
6053
|
+
adepResolvedVersion =
|
|
6054
|
+
assetData.dependencies[aversionNoRuntime][adep].resolved;
|
|
6055
|
+
} else if (DEBUG_MODE) {
|
|
6056
|
+
// Only Microsoft can call a lock file that uses version ranges as a "lock file" for "reproducible" builds.
|
|
6057
|
+
if (adepResolvedVersion.startsWith("[")) {
|
|
6058
|
+
const versionToUse = adepResolvedVersion.replace(/[[, )]/g, "");
|
|
6059
|
+
if (
|
|
6060
|
+
(assetData.dependencies[aversion] &&
|
|
6061
|
+
assetData.dependencies[aversion][adep] &&
|
|
6062
|
+
assetData.dependencies[aversion][adep].type === "Project") ||
|
|
6063
|
+
(assetData.dependencies[aversionNoRuntime] &&
|
|
6064
|
+
assetData.dependencies[aversionNoRuntime][adep] &&
|
|
6065
|
+
assetData.dependencies[aversionNoRuntime][adep].type ===
|
|
6066
|
+
"Project")
|
|
6067
|
+
) {
|
|
6068
|
+
isProjectType = true;
|
|
6069
|
+
}
|
|
6070
|
+
// To make matters worse, the name of the project could be all lowercased
|
|
6071
|
+
// Eg: In react-native-windows repo, folly and Folly are used for the project name
|
|
6072
|
+
else if (
|
|
6073
|
+
(assetData.dependencies[aversion] &&
|
|
6074
|
+
assetData.dependencies[aversion][adep.toLowerCase()] &&
|
|
6075
|
+
assetData.dependencies[aversion][adep.toLowerCase()].type ===
|
|
6076
|
+
"Project") ||
|
|
6077
|
+
(assetData.dependencies[aversionNoRuntime] &&
|
|
6078
|
+
assetData.dependencies[aversionNoRuntime][
|
|
6079
|
+
adep.toLowerCase()
|
|
6080
|
+
] &&
|
|
6081
|
+
assetData.dependencies[aversionNoRuntime][adep.toLowerCase()]
|
|
6082
|
+
.type === "Project")
|
|
6083
|
+
) {
|
|
6084
|
+
isProjectType = true;
|
|
6085
|
+
adep = adep.toLowerCase();
|
|
6086
|
+
}
|
|
6087
|
+
// If this component is a project type, the version information would be often missing.
|
|
6088
|
+
// So we remove the version to match based on name alone
|
|
6089
|
+
if (isProjectType) {
|
|
6090
|
+
adepResolvedVersion = undefined;
|
|
6091
|
+
} else {
|
|
6092
|
+
console.warn(
|
|
6093
|
+
`The version used for ${adep} is a range - ${adepResolvedVersion}. Using the min version ${versionToUse} which may be incorrect.`
|
|
6094
|
+
);
|
|
6095
|
+
adepResolvedVersion = versionToUse;
|
|
6096
|
+
}
|
|
6097
|
+
} else {
|
|
6098
|
+
console.warn(
|
|
6099
|
+
`Unable to find the resolved version for ${adep} ${aversion}. Using ${adepResolvedVersion} which may be incorrect.`
|
|
6100
|
+
);
|
|
6101
|
+
}
|
|
6102
|
+
}
|
|
6027
6103
|
const adpurl = new PackageURL(
|
|
6028
6104
|
"nuget",
|
|
6029
6105
|
"",
|
|
6030
6106
|
adep,
|
|
6031
|
-
|
|
6107
|
+
adepResolvedVersion,
|
|
6032
6108
|
null,
|
|
6033
6109
|
null
|
|
6034
6110
|
).toString();
|
package/utils.test.js
CHANGED
|
@@ -1230,9 +1230,9 @@ test("parse github actions workflow data", () => {
|
|
|
1230
1230
|
expect(dep_list.length).toEqual(3);
|
|
1231
1231
|
});
|
|
1232
1232
|
|
|
1233
|
-
test("parse cs pkg data",
|
|
1234
|
-
expect(
|
|
1235
|
-
const dep_list =
|
|
1233
|
+
test("parse cs pkg data", () => {
|
|
1234
|
+
expect(parseCsPkgData(null)).toEqual([]);
|
|
1235
|
+
const dep_list = parseCsPkgData(
|
|
1236
1236
|
readFileSync("./test/data/packages.config", { encoding: "utf-8" })
|
|
1237
1237
|
);
|
|
1238
1238
|
expect(dep_list.length).toEqual(21);
|
|
@@ -1243,9 +1243,9 @@ test("parse cs pkg data", async () => {
|
|
|
1243
1243
|
});
|
|
1244
1244
|
});
|
|
1245
1245
|
|
|
1246
|
-
test("parse cs pkg data 2",
|
|
1247
|
-
expect(
|
|
1248
|
-
const dep_list =
|
|
1246
|
+
test("parse cs pkg data 2", () => {
|
|
1247
|
+
expect(parseCsPkgData(null)).toEqual([]);
|
|
1248
|
+
const dep_list = parseCsPkgData(
|
|
1249
1249
|
readFileSync("./test/data/packages2.config", { encoding: "utf-8" })
|
|
1250
1250
|
);
|
|
1251
1251
|
expect(dep_list.length).toEqual(1);
|
|
@@ -1256,9 +1256,9 @@ test("parse cs pkg data 2", async () => {
|
|
|
1256
1256
|
});
|
|
1257
1257
|
});
|
|
1258
1258
|
|
|
1259
|
-
test("parse cs proj",
|
|
1260
|
-
expect(
|
|
1261
|
-
const dep_list =
|
|
1259
|
+
test("parse cs proj", () => {
|
|
1260
|
+
expect(parseCsProjData(null)).toEqual([]);
|
|
1261
|
+
const dep_list = parseCsProjData(
|
|
1262
1262
|
readFileSync("./test/sample.csproj", { encoding: "utf-8" })
|
|
1263
1263
|
);
|
|
1264
1264
|
expect(dep_list.length).toEqual(5);
|
|
@@ -1269,12 +1269,12 @@ test("parse cs proj", async () => {
|
|
|
1269
1269
|
});
|
|
1270
1270
|
});
|
|
1271
1271
|
|
|
1272
|
-
test("parse project.assets.json",
|
|
1273
|
-
expect(
|
|
1272
|
+
test("parse project.assets.json", () => {
|
|
1273
|
+
expect(parseCsProjAssetsData(null)).toEqual({
|
|
1274
1274
|
dependenciesList: [],
|
|
1275
1275
|
pkgList: []
|
|
1276
1276
|
});
|
|
1277
|
-
let dep_list =
|
|
1277
|
+
let dep_list = parseCsProjAssetsData(
|
|
1278
1278
|
readFileSync("./test/data/project.assets.json", { encoding: "utf-8" }),
|
|
1279
1279
|
"./test/data/project.assets.json"
|
|
1280
1280
|
);
|
|
@@ -1312,7 +1312,7 @@ test("parse project.assets.json", async () => {
|
|
|
1312
1312
|
],
|
|
1313
1313
|
ref: "pkg:nuget/Castle.Core.Tests@0.0.0"
|
|
1314
1314
|
});
|
|
1315
|
-
dep_list =
|
|
1315
|
+
dep_list = parseCsProjAssetsData(
|
|
1316
1316
|
readFileSync("./test/data/project.assets1.json", { encoding: "utf-8" }),
|
|
1317
1317
|
"./test/data/project.assets1.json"
|
|
1318
1318
|
);
|
|
@@ -1334,13 +1334,13 @@ test("parse project.assets.json", async () => {
|
|
|
1334
1334
|
*/
|
|
1335
1335
|
});
|
|
1336
1336
|
|
|
1337
|
-
test("parse packages.lock.json",
|
|
1338
|
-
expect(
|
|
1337
|
+
test("parse packages.lock.json", () => {
|
|
1338
|
+
expect(parseCsPkgLockData(null)).toEqual({
|
|
1339
1339
|
dependenciesList: [],
|
|
1340
1340
|
pkgList: [],
|
|
1341
1341
|
rootList: []
|
|
1342
1342
|
});
|
|
1343
|
-
let dep_list =
|
|
1343
|
+
let dep_list = parseCsPkgLockData(
|
|
1344
1344
|
readFileSync("./test/data/packages.lock.json", { encoding: "utf-8" }),
|
|
1345
1345
|
"./test/data/packages.lock.json"
|
|
1346
1346
|
);
|
|
@@ -1368,7 +1368,7 @@ test("parse packages.lock.json", async () => {
|
|
|
1368
1368
|
}
|
|
1369
1369
|
}
|
|
1370
1370
|
});
|
|
1371
|
-
dep_list =
|
|
1371
|
+
dep_list = parseCsPkgLockData(
|
|
1372
1372
|
readFileSync("./test/data/packages2.lock.json", { encoding: "utf-8" }),
|
|
1373
1373
|
"./test/data/packages2.lock.json"
|
|
1374
1374
|
);
|
|
@@ -1405,20 +1405,43 @@ test("parse packages.lock.json", async () => {
|
|
|
1405
1405
|
"pkg:nuget/Microsoft.Extensions.Logging.Abstractions@6.0.0"
|
|
1406
1406
|
]
|
|
1407
1407
|
});
|
|
1408
|
-
dep_list =
|
|
1408
|
+
dep_list = parseCsPkgLockData(
|
|
1409
1409
|
readFileSync("./test/data/packages3.lock.json", { encoding: "utf-8" }),
|
|
1410
1410
|
"./test/data/packages3.lock.json"
|
|
1411
1411
|
);
|
|
1412
1412
|
expect(dep_list["pkgList"].length).toEqual(15);
|
|
1413
|
+
expect(dep_list["pkgList"][1]).toEqual({
|
|
1414
|
+
group: "",
|
|
1415
|
+
name: "FSharp.Core",
|
|
1416
|
+
version: "4.5.2",
|
|
1417
|
+
purl: "pkg:nuget/FSharp.Core@4.5.2",
|
|
1418
|
+
"bom-ref": "pkg:nuget/FSharp.Core@4.5.2",
|
|
1419
|
+
_integrity:
|
|
1420
|
+
"sha512-apbdQOjzsjQ637kTWQuW29jqwY18jsHMyNC5A+TPJZKFEIE2cIfQWf3V7+mXrxlbX69BueYkv293/g70wuXuRw==",
|
|
1421
|
+
properties: [{ name: "SrcFile", value: "./test/data/packages3.lock.json" }],
|
|
1422
|
+
evidence: {
|
|
1423
|
+
identity: {
|
|
1424
|
+
field: "purl",
|
|
1425
|
+
confidence: 1,
|
|
1426
|
+
methods: [
|
|
1427
|
+
{
|
|
1428
|
+
technique: "manifest-analysis",
|
|
1429
|
+
confidence: 1,
|
|
1430
|
+
value: "./test/data/packages3.lock.json"
|
|
1431
|
+
}
|
|
1432
|
+
]
|
|
1433
|
+
}
|
|
1434
|
+
}
|
|
1435
|
+
});
|
|
1413
1436
|
expect(dep_list["dependenciesList"].length).toEqual(15);
|
|
1414
1437
|
});
|
|
1415
1438
|
|
|
1416
|
-
test("parse paket.lock",
|
|
1417
|
-
expect(
|
|
1439
|
+
test("parse paket.lock", () => {
|
|
1440
|
+
expect(parsePaketLockData(null)).toEqual({
|
|
1418
1441
|
pkgList: [],
|
|
1419
1442
|
dependenciesList: []
|
|
1420
1443
|
});
|
|
1421
|
-
const dep_list =
|
|
1444
|
+
const dep_list = parsePaketLockData(
|
|
1422
1445
|
readFileSync("./test/data/paket.lock", { encoding: "utf-8" }),
|
|
1423
1446
|
"./test/data/paket.lock"
|
|
1424
1447
|
);
|
|
@@ -1454,9 +1477,9 @@ test("parse paket.lock", async () => {
|
|
|
1454
1477
|
});
|
|
1455
1478
|
});
|
|
1456
1479
|
|
|
1457
|
-
test("parse .net cs proj",
|
|
1458
|
-
expect(
|
|
1459
|
-
const dep_list =
|
|
1480
|
+
test("parse .net cs proj", () => {
|
|
1481
|
+
expect(parseCsProjData(null)).toEqual([]);
|
|
1482
|
+
const dep_list = parseCsProjData(
|
|
1460
1483
|
readFileSync("./test/data/sample-dotnet.csproj", { encoding: "utf-8" })
|
|
1461
1484
|
);
|
|
1462
1485
|
expect(dep_list.length).toEqual(19);
|
|
@@ -2835,7 +2858,7 @@ test("parse nupkg file", async () => {
|
|
|
2835
2858
|
);
|
|
2836
2859
|
expect(deps.length).toEqual(1);
|
|
2837
2860
|
expect(deps[0].name).toEqual("Microsoft.Web.Infrastructure");
|
|
2838
|
-
deps =
|
|
2861
|
+
deps = parseNuspecData(
|
|
2839
2862
|
"./test/data/Microsoft.Web.Infrastructure.1.0.0.0.nuspec",
|
|
2840
2863
|
readFileSync(
|
|
2841
2864
|
"./test/data/Microsoft.Web.Infrastructure.1.0.0.0.nuspec",
|