@cyclonedx/cdxgen 10.4.0 → 10.4.2
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/analyzer.js +10 -13
- package/bin/cdxgen.js +2 -1
- package/bin/repl.js +4 -4
- package/bin/verify.js +3 -4
- package/binary.js +19 -19
- package/cbomutils.js +2 -2
- package/display.js +6 -7
- package/docker.js +57 -64
- package/envcontext.js +6 -7
- package/evinser.js +33 -33
- package/index.js +924 -1011
- package/package.json +4 -4
- package/postgen.js +3 -6
- package/protobom.test.js +1 -1
- package/types/analyzer.d.ts.map +1 -1
- package/types/binary.d.ts.map +1 -1
- package/types/db.d.ts +2 -1
- package/types/db.d.ts.map +1 -1
- package/types/display.d.ts.map +1 -1
- package/types/docker.d.ts +1 -1
- package/types/docker.d.ts.map +1 -1
- package/types/evinser.d.ts +12 -12
- package/types/evinser.d.ts.map +1 -1
- package/types/index.d.ts.map +1 -1
- package/types/postgen.d.ts.map +1 -1
- package/types/utils.d.ts +25 -1
- package/types/utils.d.ts.map +1 -1
- package/types/validator.d.ts.map +1 -1
- package/utils.js +260 -323
- package/utils.test.js +11 -8
- package/validator.js +11 -14
package/utils.js
CHANGED
|
@@ -232,7 +232,7 @@ export function getAllFiles(dirPath, pattern, options = {}) {
|
|
|
232
232
|
if (!pattern.includes("package.json")) {
|
|
233
233
|
ignoreList.push("**/node_modules/**");
|
|
234
234
|
}
|
|
235
|
-
if (options
|
|
235
|
+
if (options?.exclude && Array.isArray(options.exclude)) {
|
|
236
236
|
ignoreList = ignoreList.concat(options.exclude);
|
|
237
237
|
}
|
|
238
238
|
return getAllFilesWithIgnore(dirPath, pattern, ignoreList);
|
|
@@ -280,7 +280,7 @@ function toBase64(hexString) {
|
|
|
280
280
|
* @returns {string} ISO formatted timestamp, without milliseconds.
|
|
281
281
|
*/
|
|
282
282
|
export function getTimestamp() {
|
|
283
|
-
return new Date().toISOString().split(".")[0]
|
|
283
|
+
return `${new Date().toISOString().split(".")[0]}Z`;
|
|
284
284
|
}
|
|
285
285
|
|
|
286
286
|
/**
|
|
@@ -328,15 +328,13 @@ export function adjustLicenseInformation(licenses) {
|
|
|
328
328
|
console.warn("multiple license expressions found", expressions);
|
|
329
329
|
}
|
|
330
330
|
return [{ expression: expressions[0].expression }];
|
|
331
|
-
} else {
|
|
332
|
-
return licenses.map((l) => {
|
|
333
|
-
if (typeof l.license === "object") {
|
|
334
|
-
return l;
|
|
335
|
-
} else {
|
|
336
|
-
return { license: l };
|
|
337
|
-
}
|
|
338
|
-
});
|
|
339
331
|
}
|
|
332
|
+
return licenses.map((l) => {
|
|
333
|
+
if (typeof l.license === "object") {
|
|
334
|
+
return l;
|
|
335
|
+
}
|
|
336
|
+
return { license: l };
|
|
337
|
+
});
|
|
340
338
|
}
|
|
341
339
|
|
|
342
340
|
/**
|
|
@@ -361,7 +359,7 @@ export function getLicenses(pkg) {
|
|
|
361
359
|
})
|
|
362
360
|
) {
|
|
363
361
|
licenseContent.id = l;
|
|
364
|
-
licenseContent.url =
|
|
362
|
+
licenseContent.url = `https://opensource.org/licenses/${l}`;
|
|
365
363
|
} else if (l.startsWith("http")) {
|
|
366
364
|
const knownLicense = getKnownLicense(l, pkg);
|
|
367
365
|
if (knownLicense) {
|
|
@@ -390,11 +388,10 @@ export function getLicenses(pkg) {
|
|
|
390
388
|
return licenseContent;
|
|
391
389
|
}),
|
|
392
390
|
);
|
|
393
|
-
}
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
}
|
|
391
|
+
}
|
|
392
|
+
const knownLicense = getKnownLicense(undefined, pkg);
|
|
393
|
+
if (knownLicense) {
|
|
394
|
+
return [{ license: knownLicense }];
|
|
398
395
|
}
|
|
399
396
|
return undefined;
|
|
400
397
|
}
|
|
@@ -407,7 +404,7 @@ export function getLicenses(pkg) {
|
|
|
407
404
|
* @return {Object} Objetct with SPDX license id or license name
|
|
408
405
|
*/
|
|
409
406
|
export function getKnownLicense(licenseUrl, pkg) {
|
|
410
|
-
if (licenseUrl
|
|
407
|
+
if (licenseUrl?.includes("opensource.org")) {
|
|
411
408
|
const possibleId = licenseUrl
|
|
412
409
|
.toLowerCase()
|
|
413
410
|
.replace("https://", "http://")
|
|
@@ -417,7 +414,7 @@ export function getKnownLicense(licenseUrl, pkg) {
|
|
|
417
414
|
return { id: spdxLicense };
|
|
418
415
|
}
|
|
419
416
|
}
|
|
420
|
-
} else if (licenseUrl
|
|
417
|
+
} else if (licenseUrl?.includes("apache.org")) {
|
|
421
418
|
const possibleId = licenseUrl
|
|
422
419
|
.toLowerCase()
|
|
423
420
|
.replace("https://", "http://")
|
|
@@ -432,15 +429,15 @@ export function getKnownLicense(licenseUrl, pkg) {
|
|
|
432
429
|
for (const akLicGroup of knownLicenses) {
|
|
433
430
|
if (
|
|
434
431
|
akLicGroup.packageNamespace === "*" ||
|
|
435
|
-
|
|
432
|
+
pkg.purl?.startsWith(akLicGroup.packageNamespace)
|
|
436
433
|
) {
|
|
437
434
|
for (const akLic of akLicGroup.knownLicenses) {
|
|
438
435
|
if (akLic.group && akLic.name) {
|
|
439
436
|
if (akLic.group === "." && akLic.name === pkg.name) {
|
|
440
437
|
return { id: akLic.license, name: akLic.licenseName };
|
|
441
|
-
}
|
|
442
|
-
|
|
443
|
-
pkg.group
|
|
438
|
+
}
|
|
439
|
+
if (
|
|
440
|
+
pkg.group?.includes(akLic.group) &&
|
|
444
441
|
(akLic.name === pkg.name || akLic.name === "*")
|
|
445
442
|
) {
|
|
446
443
|
return { id: akLic.license, name: akLic.licenseName };
|
|
@@ -528,7 +525,7 @@ export function readLicenseText(licenseFilepath, licenseContentType) {
|
|
|
528
525
|
export async function getSwiftPackageMetadata(pkgList) {
|
|
529
526
|
const cdepList = [];
|
|
530
527
|
for (const p of pkgList) {
|
|
531
|
-
if (p.repository
|
|
528
|
+
if (p.repository?.url) {
|
|
532
529
|
if (p.repository.url.includes("://github.com/")) {
|
|
533
530
|
try {
|
|
534
531
|
p.license = await getRepoLicense(p.repository.url, undefined);
|
|
@@ -567,9 +564,9 @@ export async function getNpmMetadata(pkgList) {
|
|
|
567
564
|
if (p.group && p.group !== "") {
|
|
568
565
|
let group = p.group;
|
|
569
566
|
if (!group.startsWith("@")) {
|
|
570
|
-
group =
|
|
567
|
+
group = `@${group}`;
|
|
571
568
|
}
|
|
572
|
-
key = group
|
|
569
|
+
key = `${group}/${p.name}`;
|
|
573
570
|
}
|
|
574
571
|
let body = {};
|
|
575
572
|
if (metadata_cache[key]) {
|
|
@@ -587,7 +584,7 @@ export async function getNpmMetadata(pkgList) {
|
|
|
587
584
|
body.versions?.[p.version]?.license ||
|
|
588
585
|
body.license ||
|
|
589
586
|
(await getRepoLicense(body.repository?.url, undefined));
|
|
590
|
-
if (body.repository
|
|
587
|
+
if (body.repository?.url) {
|
|
591
588
|
p.repository = { url: body.repository.url };
|
|
592
589
|
}
|
|
593
590
|
if (body.homepage) {
|
|
@@ -652,7 +649,7 @@ export async function parsePkgJson(pkgJsonFile, simple = false) {
|
|
|
652
649
|
if (pkgData.homepage) {
|
|
653
650
|
apkg.homepage = { url: pkgData.homepage };
|
|
654
651
|
}
|
|
655
|
-
if (pkgData.repository
|
|
652
|
+
if (pkgData.repository?.url) {
|
|
656
653
|
apkg.repository = { url: pkgData.repository.url };
|
|
657
654
|
}
|
|
658
655
|
if (!simple) {
|
|
@@ -742,7 +739,7 @@ export async function parsePkgLock(pkgLockFile, options = {}) {
|
|
|
742
739
|
author.url ? ` (${author.url})` : ""
|
|
743
740
|
}`
|
|
744
741
|
: author;
|
|
745
|
-
if (node
|
|
742
|
+
if (node === rootNode) {
|
|
746
743
|
purlString = new PackageURL(
|
|
747
744
|
"npm",
|
|
748
745
|
options.projectGroup || "",
|
|
@@ -858,7 +855,7 @@ export async function parsePkgLock(pkgLockFile, options = {}) {
|
|
|
858
855
|
// this handles the case when a node has ["dependencies"] key in a package-lock.json
|
|
859
856
|
// for a node. We exclude the root node because it's already been handled
|
|
860
857
|
const childrenDependsOn = [];
|
|
861
|
-
if (node
|
|
858
|
+
if (node !== rootNode) {
|
|
862
859
|
for (const child of node.children) {
|
|
863
860
|
const childNode = child[1];
|
|
864
861
|
const {
|
|
@@ -936,8 +933,8 @@ export async function parsePkgLock(pkgLockFile, options = {}) {
|
|
|
936
933
|
for (const child of rootNode.children) {
|
|
937
934
|
if (
|
|
938
935
|
edgeToIntegrityOrLocation &&
|
|
939
|
-
(child[1].integrity
|
|
940
|
-
child[1].location
|
|
936
|
+
(child[1].integrity === edgeToIntegrityOrLocation ||
|
|
937
|
+
child[1].location === edgeToIntegrityOrLocation)
|
|
941
938
|
) {
|
|
942
939
|
targetName = child[0].replace(/node_modules\//g, "");
|
|
943
940
|
targetVersion = child[1].version;
|
|
@@ -1057,7 +1054,7 @@ export function yarnLockToIdentMap(lockData) {
|
|
|
1057
1054
|
// "@actions/core@^1.2.6", "@actions/core@^1.6.0":
|
|
1058
1055
|
if (!l.startsWith(" ") && l.trim().length > 0) {
|
|
1059
1056
|
const tmpA = l.replace(/["']/g, "").split(", ");
|
|
1060
|
-
if (tmpA
|
|
1057
|
+
if (tmpA?.length) {
|
|
1061
1058
|
for (let s of tmpA) {
|
|
1062
1059
|
if (!s.startsWith("__")) {
|
|
1063
1060
|
if (s.endsWith(":")) {
|
|
@@ -1079,7 +1076,7 @@ export function yarnLockToIdentMap(lockData) {
|
|
|
1079
1076
|
// - npm:@types/ioredis@^4.28.10
|
|
1080
1077
|
// - npm:strip-ansi@^6.0.1
|
|
1081
1078
|
// See test cases with yarn3.lock and yarn6.lock
|
|
1082
|
-
if (range
|
|
1079
|
+
if (range?.startsWith("npm:")) {
|
|
1083
1080
|
if (range.includes("@")) {
|
|
1084
1081
|
range = range.split("@").slice(-1)[0];
|
|
1085
1082
|
} else {
|
|
@@ -1236,7 +1233,7 @@ export async function parseYarnLock(yarnLockFile) {
|
|
|
1236
1233
|
name = parsedline.name;
|
|
1237
1234
|
} else {
|
|
1238
1235
|
let fullName = parsedline.name;
|
|
1239
|
-
if (parsedline.group
|
|
1236
|
+
if (parsedline.group?.length) {
|
|
1240
1237
|
fullName = `${parsedline.group}/${parsedline.name}`;
|
|
1241
1238
|
}
|
|
1242
1239
|
if (
|
|
@@ -1295,14 +1292,15 @@ export async function parseYarnLock(yarnLockFile) {
|
|
|
1295
1292
|
// in some cases yarn 4 will add a prefix to the checksum, containing the cachekey and compression level
|
|
1296
1293
|
// example: 10c0/53c2b231a61a46792b39a0d43bc4f4f77...
|
|
1297
1294
|
const checksum = parts[1].split("/").pop();
|
|
1298
|
-
integrity =
|
|
1299
|
-
"
|
|
1295
|
+
integrity = `sha512-${Buffer.from(checksum, "hex").toString(
|
|
1296
|
+
"base64",
|
|
1297
|
+
)}`;
|
|
1300
1298
|
}
|
|
1301
1299
|
if (l.startsWith("resolved")) {
|
|
1302
1300
|
const tmpB = parts[1].split("#");
|
|
1303
1301
|
if (tmpB.length > 1) {
|
|
1304
1302
|
const digest = tmpB[1].replace(/"/g, "");
|
|
1305
|
-
integrity =
|
|
1303
|
+
integrity = `sha256-${digest}`;
|
|
1306
1304
|
}
|
|
1307
1305
|
}
|
|
1308
1306
|
}
|
|
@@ -1340,7 +1338,7 @@ export async function parseNodeShrinkwrap(swFile) {
|
|
|
1340
1338
|
const fullName = pkgKeys[k];
|
|
1341
1339
|
const integrity = lockData[fullName];
|
|
1342
1340
|
const parts = fullName.split("@");
|
|
1343
|
-
if (parts
|
|
1341
|
+
if (parts?.length) {
|
|
1344
1342
|
let name = "";
|
|
1345
1343
|
let version = "";
|
|
1346
1344
|
let group = "";
|
|
@@ -1406,7 +1404,7 @@ export async function parsePnpmLock(pnpmLock, parentComponent = null) {
|
|
|
1406
1404
|
let pkgList = [];
|
|
1407
1405
|
const dependenciesList = [];
|
|
1408
1406
|
let ppurl = "";
|
|
1409
|
-
if (parentComponent
|
|
1407
|
+
if (parentComponent?.name) {
|
|
1410
1408
|
ppurl =
|
|
1411
1409
|
parentComponent.purl ||
|
|
1412
1410
|
new PackageURL(
|
|
@@ -1471,7 +1469,7 @@ export async function parsePnpmLock(pnpmLock, parentComponent = null) {
|
|
|
1471
1469
|
const integrity = packages[pkgKeys[k]].resolution.integrity;
|
|
1472
1470
|
const deps = packages[pkgKeys[k]].dependencies || [];
|
|
1473
1471
|
const scope = packages[pkgKeys[k]].dev === true ? "optional" : undefined;
|
|
1474
|
-
if (parts
|
|
1472
|
+
if (parts?.length) {
|
|
1475
1473
|
let name = "";
|
|
1476
1474
|
let version = "";
|
|
1477
1475
|
let group = "";
|
|
@@ -1669,7 +1667,7 @@ export async function parseMinJs(minJsFile) {
|
|
|
1669
1667
|
return;
|
|
1670
1668
|
}
|
|
1671
1669
|
const pkgIdentifier = parsePackageJsonName(name);
|
|
1672
|
-
if (pkgIdentifier.fullName
|
|
1670
|
+
if (pkgIdentifier.fullName !== "") {
|
|
1673
1671
|
pkgList.push({
|
|
1674
1672
|
name: pkgIdentifier.fullName,
|
|
1675
1673
|
group: pkgIdentifier.scope || "",
|
|
@@ -1728,7 +1726,7 @@ export function parsePom(pomFile) {
|
|
|
1728
1726
|
attributesKey: "$",
|
|
1729
1727
|
commentKey: "value",
|
|
1730
1728
|
}).project;
|
|
1731
|
-
if (project
|
|
1729
|
+
if (project?.dependencies) {
|
|
1732
1730
|
let dependencies = project.dependencies.dependency;
|
|
1733
1731
|
// Convert to an array
|
|
1734
1732
|
if (!dependencies) {
|
|
@@ -1739,7 +1737,7 @@ export function parsePom(pomFile) {
|
|
|
1739
1737
|
for (const adep of dependencies) {
|
|
1740
1738
|
const version = adep.version;
|
|
1741
1739
|
let versionStr = undefined;
|
|
1742
|
-
if (version
|
|
1740
|
+
if (version?._ && version._.indexOf("$") === -1) {
|
|
1743
1741
|
versionStr = version._;
|
|
1744
1742
|
if (includeMavenTestScope || !adep.scope || adep.scope !== "test")
|
|
1745
1743
|
deps.push({
|
|
@@ -1796,7 +1794,7 @@ export function parseMavenTree(rawOutput) {
|
|
|
1796
1794
|
}
|
|
1797
1795
|
let level = 0;
|
|
1798
1796
|
const tmpline = l.split(" ");
|
|
1799
|
-
if (tmpline
|
|
1797
|
+
if (tmpline?.length) {
|
|
1800
1798
|
if (l.includes(" ")) {
|
|
1801
1799
|
level = l.replace(tmpline[tmpline.length - 1], "").length / 3;
|
|
1802
1800
|
}
|
|
@@ -1804,10 +1802,10 @@ export function parseMavenTree(rawOutput) {
|
|
|
1804
1802
|
const pkgArr = l.split(":");
|
|
1805
1803
|
if (pkgArr && pkgArr.length > 2) {
|
|
1806
1804
|
let versionStr = pkgArr[pkgArr.length - 2];
|
|
1807
|
-
if (pkgArr.length
|
|
1805
|
+
if (pkgArr.length === 4) {
|
|
1808
1806
|
versionStr = pkgArr[pkgArr.length - 1];
|
|
1809
1807
|
}
|
|
1810
|
-
const key = pkgArr[0]
|
|
1808
|
+
const key = `${pkgArr[0]}-${pkgArr[1]}-${versionStr}`;
|
|
1811
1809
|
if (!keys_cache[key]) {
|
|
1812
1810
|
keys_cache[key] = key;
|
|
1813
1811
|
let purlString = new PackageURL(
|
|
@@ -1828,7 +1826,7 @@ export function parseMavenTree(rawOutput) {
|
|
|
1828
1826
|
if (!level_trees[purlString]) {
|
|
1829
1827
|
level_trees[purlString] = [];
|
|
1830
1828
|
}
|
|
1831
|
-
if (level
|
|
1829
|
+
if (level === 0 || last_purl === "") {
|
|
1832
1830
|
stack.push(purlString);
|
|
1833
1831
|
} else if (level > last_level) {
|
|
1834
1832
|
const cnodes = level_trees[last_purl] || [];
|
|
@@ -1921,7 +1919,7 @@ export function parseGradleDep(
|
|
|
1921
1919
|
level_trees[last_purl] = [];
|
|
1922
1920
|
let scope = undefined;
|
|
1923
1921
|
let profileName = undefined;
|
|
1924
|
-
if (retMap
|
|
1922
|
+
if (retMap?.projects) {
|
|
1925
1923
|
const subDependsOn = [];
|
|
1926
1924
|
for (const sd of retMap.projects) {
|
|
1927
1925
|
subDependsOn.push(
|
|
@@ -2008,7 +2006,7 @@ export function parseGradleDep(
|
|
|
2008
2006
|
null,
|
|
2009
2007
|
).toString();
|
|
2010
2008
|
purlString = decodeURIComponent(purlString);
|
|
2011
|
-
keys_cache[purlString
|
|
2009
|
+
keys_cache[`${purlString}_${last_purl}`] = true;
|
|
2012
2010
|
// Filter duplicates
|
|
2013
2011
|
if (!deps_keys_cache[purlString]) {
|
|
2014
2012
|
deps_keys_cache[purlString] = true;
|
|
@@ -2036,7 +2034,7 @@ export function parseGradleDep(
|
|
|
2036
2034
|
if (!level_trees[purlString]) {
|
|
2037
2035
|
level_trees[purlString] = [];
|
|
2038
2036
|
}
|
|
2039
|
-
if (level
|
|
2037
|
+
if (level === 0) {
|
|
2040
2038
|
stack = [first_purl];
|
|
2041
2039
|
stack.push(purlString);
|
|
2042
2040
|
} else if (last_purl === "") {
|
|
@@ -2098,14 +2096,14 @@ export function parseCljDep(rawOutput) {
|
|
|
2098
2096
|
l = l.replace(". ", "");
|
|
2099
2097
|
}
|
|
2100
2098
|
const tmpArr = l.split(" ");
|
|
2101
|
-
if (tmpArr.length
|
|
2099
|
+
if (tmpArr.length === 2) {
|
|
2102
2100
|
let group = dirname(tmpArr[0]);
|
|
2103
2101
|
if (group === ".") {
|
|
2104
2102
|
group = "";
|
|
2105
2103
|
}
|
|
2106
2104
|
const name = basename(tmpArr[0]);
|
|
2107
2105
|
const version = tmpArr[1];
|
|
2108
|
-
const cacheKey = group
|
|
2106
|
+
const cacheKey = `${group}-${name}-${version}`;
|
|
2109
2107
|
if (!keys_cache[cacheKey]) {
|
|
2110
2108
|
keys_cache[cacheKey] = true;
|
|
2111
2109
|
deps.push({
|
|
@@ -2131,7 +2129,7 @@ export function parseLeinDep(rawOutput) {
|
|
|
2131
2129
|
const deps = [];
|
|
2132
2130
|
const keys_cache = {};
|
|
2133
2131
|
if (rawOutput.includes("{[") && !rawOutput.startsWith("{[")) {
|
|
2134
|
-
rawOutput =
|
|
2132
|
+
rawOutput = `{[${rawOutput.split("{[")[1]}`;
|
|
2135
2133
|
}
|
|
2136
2134
|
const ednData = parseEDNString(rawOutput);
|
|
2137
2135
|
return parseLeinMap(ednData, keys_cache, deps);
|
|
@@ -2151,7 +2149,7 @@ export function parseLeinMap(node, keys_cache, deps) {
|
|
|
2151
2149
|
group = "";
|
|
2152
2150
|
}
|
|
2153
2151
|
const name = basename(psym);
|
|
2154
|
-
const cacheKey = group
|
|
2152
|
+
const cacheKey = `${group}-${name}-${version}`;
|
|
2155
2153
|
if (!keys_cache[cacheKey]) {
|
|
2156
2154
|
keys_cache[cacheKey] = true;
|
|
2157
2155
|
deps.push({ group, name, version });
|
|
@@ -2312,15 +2310,17 @@ export function executeGradleProperties(dir, rootPath, subProject) {
|
|
|
2312
2310
|
if (result.stderr) {
|
|
2313
2311
|
if (result.stderr.includes("does not exist")) {
|
|
2314
2312
|
return defaultProps;
|
|
2315
|
-
} else {
|
|
2316
|
-
console.error(result.stdout, result.stderr);
|
|
2317
|
-
console.log(
|
|
2318
|
-
"1. Check if the correct version of java and gradle are installed and available in PATH. For example, some project might require Java 11 with gradle 7.\n cdxgen container image bundles Java 21 with gradle 8 which might be incompatible.",
|
|
2319
|
-
);
|
|
2320
2313
|
}
|
|
2314
|
+
console.error(result.stdout, result.stderr);
|
|
2315
|
+
console.log(
|
|
2316
|
+
"1. Check if the correct version of java and gradle are installed and available in PATH. For example, some project might require Java 11 with gradle 7.\n cdxgen container image bundles Java 21 with gradle 8 which might be incompatible.",
|
|
2317
|
+
);
|
|
2318
|
+
console.log(
|
|
2319
|
+
"2. Try running cdxgen with the unofficial JDK11-based image `ghcr.io/appthreat/cdxgen-java:v10`.",
|
|
2320
|
+
);
|
|
2321
2321
|
if (result.stderr.includes("not get unknown property")) {
|
|
2322
2322
|
console.log(
|
|
2323
|
-
"
|
|
2323
|
+
"3. Check if the SBOM is generated for the correct root project for your application.",
|
|
2324
2324
|
);
|
|
2325
2325
|
}
|
|
2326
2326
|
}
|
|
@@ -2357,7 +2357,7 @@ export function parseBazelActionGraph(rawOutput) {
|
|
|
2357
2357
|
) {
|
|
2358
2358
|
const matches = Array.from(l.matchAll(mavenPrefixRegex));
|
|
2359
2359
|
|
|
2360
|
-
if (matches[0]
|
|
2360
|
+
if (matches[0]?.[1]) {
|
|
2361
2361
|
const group = matches[0][1].split("/").join(".");
|
|
2362
2362
|
const name = matches[0][2];
|
|
2363
2363
|
const version = matches[0][3];
|
|
@@ -2399,7 +2399,7 @@ export function parseBazelSkyframe(rawOutput) {
|
|
|
2399
2399
|
l = l.split(",")[0];
|
|
2400
2400
|
}
|
|
2401
2401
|
const mparts = l.split("external/maven/v1/");
|
|
2402
|
-
if (mparts
|
|
2402
|
+
if (mparts?.[mparts.length - 1].endsWith(".jar")) {
|
|
2403
2403
|
// Example
|
|
2404
2404
|
// https/jcenter.bintray.com/com/google/guava/failureaccess/1.0.1/failureaccess-1.0.1.jar
|
|
2405
2405
|
// https/repo1.maven.org/maven2/org/simpleflatmapper/sfm-util/8.2.2/header_sfmutil-8.2.2.jar
|
|
@@ -2615,12 +2615,11 @@ export async function getMvnMetadata(pkgList, jarNSMapping = {}) {
|
|
|
2615
2615
|
);
|
|
2616
2616
|
}
|
|
2617
2617
|
const bodyJson = await fetchPomXmlAsJson(pomMetadata);
|
|
2618
|
-
p.publisher =
|
|
2619
|
-
|
|
2620
|
-
|
|
2621
|
-
: "";
|
|
2618
|
+
p.publisher = bodyJson.organization?.name
|
|
2619
|
+
? bodyJson.organization.name._
|
|
2620
|
+
: "";
|
|
2622
2621
|
p.description = bodyJson.description ? bodyJson.description._ : "";
|
|
2623
|
-
if (bodyJson.scm
|
|
2622
|
+
if (bodyJson.scm?.url) {
|
|
2624
2623
|
p.repository = { url: bodyJson.scm.url._ };
|
|
2625
2624
|
}
|
|
2626
2625
|
p.license =
|
|
@@ -2653,18 +2652,9 @@ export async function getMvnMetadata(pkgList, jarNSMapping = {}) {
|
|
|
2653
2652
|
*/
|
|
2654
2653
|
export function composePomXmlUrl({ urlPrefix, group, name, version }) {
|
|
2655
2654
|
const groupPart = group.replace(/\./g, "/");
|
|
2656
|
-
const fullUrl =
|
|
2657
|
-
urlPrefix +
|
|
2658
|
-
|
|
2659
|
-
"/" +
|
|
2660
|
-
name +
|
|
2661
|
-
"/" +
|
|
2662
|
-
version +
|
|
2663
|
-
"/" +
|
|
2664
|
-
name +
|
|
2665
|
-
"-" +
|
|
2666
|
-
version +
|
|
2667
|
-
".pom";
|
|
2655
|
+
const fullUrl = `${
|
|
2656
|
+
urlPrefix + groupPart
|
|
2657
|
+
}/${name}/${version}/${name}-${version}.pom`;
|
|
2668
2658
|
return fullUrl;
|
|
2669
2659
|
}
|
|
2670
2660
|
|
|
@@ -2729,7 +2719,8 @@ export function parseLicenseEntryOrArrayFromPomXml(license) {
|
|
|
2729
2719
|
return license.map((l) => {
|
|
2730
2720
|
return findLicenseId(l.name._);
|
|
2731
2721
|
});
|
|
2732
|
-
}
|
|
2722
|
+
}
|
|
2723
|
+
if (Object.keys(license).length) {
|
|
2733
2724
|
return [findLicenseId(license.name._)];
|
|
2734
2725
|
}
|
|
2735
2726
|
}
|
|
@@ -2753,7 +2744,7 @@ export async function extractLicenseCommentFromPomXml({
|
|
|
2753
2744
|
const pom_xml = await fetchPomXml({ urlPrefix, group, name, version });
|
|
2754
2745
|
const licenseRegex = /<!--([\s\S]*?)-->[\s\n]*<project/m;
|
|
2755
2746
|
const match = licenseRegex.exec(pom_xml);
|
|
2756
|
-
if (match
|
|
2747
|
+
if (match?.[1]) {
|
|
2757
2748
|
return findLicenseId(match[1].trim());
|
|
2758
2749
|
}
|
|
2759
2750
|
}
|
|
@@ -2772,7 +2763,8 @@ export function parsePyRequiresDist(dist_string) {
|
|
|
2772
2763
|
let version = "";
|
|
2773
2764
|
if (!tmpA) {
|
|
2774
2765
|
return undefined;
|
|
2775
|
-
}
|
|
2766
|
+
}
|
|
2767
|
+
if (tmpA.length === 1) {
|
|
2776
2768
|
name = tmpA[0];
|
|
2777
2769
|
} else if (tmpA.length > 1) {
|
|
2778
2770
|
name = tmpA[0];
|
|
@@ -2840,15 +2832,15 @@ export async function getPyMetadata(pkgList, fetchDepsInfo) {
|
|
|
2840
2832
|
}
|
|
2841
2833
|
let res = undefined;
|
|
2842
2834
|
try {
|
|
2843
|
-
res = await cdxgenAgent.get(PYPI_URL + p.name
|
|
2835
|
+
res = await cdxgenAgent.get(`${PYPI_URL + p.name}/json`, {
|
|
2844
2836
|
responseType: "json",
|
|
2845
2837
|
});
|
|
2846
2838
|
} catch (err) {
|
|
2847
2839
|
// retry by prefixing django- to the package name
|
|
2848
|
-
res = await cdxgenAgent.get(PYPI_URL
|
|
2840
|
+
res = await cdxgenAgent.get(`${PYPI_URL}django-${p.name}/json`, {
|
|
2849
2841
|
responseType: "json",
|
|
2850
2842
|
});
|
|
2851
|
-
p.name =
|
|
2843
|
+
p.name = `django-${p.name}`;
|
|
2852
2844
|
}
|
|
2853
2845
|
const body = res.body;
|
|
2854
2846
|
if (body.info.author && body.info.author.trim() !== "") {
|
|
@@ -2892,7 +2884,7 @@ export async function getPyMetadata(pkgList, fetchDepsInfo) {
|
|
|
2892
2884
|
// Use the latest version if none specified
|
|
2893
2885
|
if (!p.version || !p.version.trim().length) {
|
|
2894
2886
|
let versionSpecifiers = undefined;
|
|
2895
|
-
if (p.properties
|
|
2887
|
+
if (p.properties?.length) {
|
|
2896
2888
|
for (const pprop of p.properties) {
|
|
2897
2889
|
if (pprop.name === "cdx:pypi:versionSpecifiers") {
|
|
2898
2890
|
versionSpecifiers = pprop.value;
|
|
@@ -2960,16 +2952,12 @@ export async function getPyMetadata(pkgList, fetchDepsInfo) {
|
|
|
2960
2952
|
value: origName,
|
|
2961
2953
|
});
|
|
2962
2954
|
}
|
|
2963
|
-
if (
|
|
2964
|
-
body.releases &&
|
|
2965
|
-
body.releases[p.version] &&
|
|
2966
|
-
body.releases[p.version].length
|
|
2967
|
-
) {
|
|
2955
|
+
if (body.releases?.[p.version] && body.releases[p.version].length) {
|
|
2968
2956
|
const digest = body.releases[p.version][0].digests;
|
|
2969
2957
|
if (digest["sha256"]) {
|
|
2970
|
-
p._integrity =
|
|
2958
|
+
p._integrity = `sha256-${digest["sha256"]}`;
|
|
2971
2959
|
} else if (digest["md5"]) {
|
|
2972
|
-
p._integrity =
|
|
2960
|
+
p._integrity = `md5-${digest["md5"]}`;
|
|
2973
2961
|
}
|
|
2974
2962
|
}
|
|
2975
2963
|
const purlString = new PackageURL(
|
|
@@ -3163,7 +3151,7 @@ export async function parsePoetrylockData(lockData, lockFile) {
|
|
|
3163
3151
|
) {
|
|
3164
3152
|
// Package dependencies starts with this marker
|
|
3165
3153
|
depsMode = l.includes("[package.dependencies]");
|
|
3166
|
-
if (pkg
|
|
3154
|
+
if (pkg?.name && pkg.version) {
|
|
3167
3155
|
const purlString = new PackageURL(
|
|
3168
3156
|
"pypi",
|
|
3169
3157
|
"",
|
|
@@ -3222,7 +3210,7 @@ export async function parsePoetrylockData(lockData, lockFile) {
|
|
|
3222
3210
|
pkg.version = value;
|
|
3223
3211
|
break;
|
|
3224
3212
|
case "optional":
|
|
3225
|
-
pkg.scope = value
|
|
3213
|
+
pkg.scope = value === "true" ? "optional" : undefined;
|
|
3226
3214
|
break;
|
|
3227
3215
|
}
|
|
3228
3216
|
}
|
|
@@ -3236,8 +3224,8 @@ export async function parsePoetrylockData(lockData, lockFile) {
|
|
|
3236
3224
|
dependsOnList.push(adep);
|
|
3237
3225
|
} else if (existingPkgMap[adep]) {
|
|
3238
3226
|
dependsOnList.push(existingPkgMap[adep]);
|
|
3239
|
-
} else if (existingPkgMap[
|
|
3240
|
-
dependsOnList.push(existingPkgMap[
|
|
3227
|
+
} else if (existingPkgMap[`py${adep}`]) {
|
|
3228
|
+
dependsOnList.push(existingPkgMap[`py${adep}`]);
|
|
3241
3229
|
} else if (existingPkgMap[adep.replace(/-/g, "_")]) {
|
|
3242
3230
|
dependsOnList.push(existingPkgMap[adep.replace(/-/g, "_")]);
|
|
3243
3231
|
}
|
|
@@ -3443,7 +3431,7 @@ export async function getPyModules(src, epkgList, options) {
|
|
|
3443
3431
|
PYPI_MODULE_PACKAGE_MAPPING[p.name.toLowerCase()] ||
|
|
3444
3432
|
PYPI_MODULE_PACKAGE_MAPPING[p.name.replace(/_/g, "-").toLowerCase()] ||
|
|
3445
3433
|
p.name.replace(/_/g, "-").toLowerCase(),
|
|
3446
|
-
version: p.version
|
|
3434
|
+
version: p.version?.trim().length ? p.version : undefined,
|
|
3447
3435
|
scope: "required",
|
|
3448
3436
|
properties: [
|
|
3449
3437
|
{
|
|
@@ -3463,13 +3451,13 @@ export async function getPyModules(src, epkgList, options) {
|
|
|
3463
3451
|
pkgList = pkgList.filter(
|
|
3464
3452
|
(obj, index) => pkgList.findIndex((i) => i.name === obj.name) === index,
|
|
3465
3453
|
);
|
|
3466
|
-
if (epkgList
|
|
3454
|
+
if (epkgList?.length) {
|
|
3467
3455
|
const pkgMaps = epkgList.map((p) => p.name);
|
|
3468
3456
|
pkgList = pkgList.filter((p) => !pkgMaps.includes(p.name));
|
|
3469
3457
|
}
|
|
3470
3458
|
pkgList = await getPyMetadata(pkgList, true);
|
|
3471
3459
|
// Populate the imports list after dealiasing
|
|
3472
|
-
if (pkgList
|
|
3460
|
+
if (pkgList?.length) {
|
|
3473
3461
|
pkgList.forEach((p) => {
|
|
3474
3462
|
allImports[p.name] = true;
|
|
3475
3463
|
});
|
|
@@ -3523,14 +3511,13 @@ export function repoMetadataToGitHubApiUrl(repoMetadata) {
|
|
|
3523
3511
|
const group = repoMetadata.group;
|
|
3524
3512
|
const name = repoMetadata.name;
|
|
3525
3513
|
let ghUrl = "https://api.github.com/repos";
|
|
3526
|
-
if (group && group !== "." && group
|
|
3527
|
-
ghUrl = ghUrl
|
|
3514
|
+
if (group && group !== "." && group !== "") {
|
|
3515
|
+
ghUrl = `${ghUrl}/${group.replace("github.com/", "")}`;
|
|
3528
3516
|
}
|
|
3529
|
-
ghUrl = ghUrl
|
|
3517
|
+
ghUrl = `${ghUrl}/${name}`;
|
|
3530
3518
|
return ghUrl;
|
|
3531
|
-
} else {
|
|
3532
|
-
return undefined;
|
|
3533
3519
|
}
|
|
3520
|
+
return undefined;
|
|
3534
3521
|
}
|
|
3535
3522
|
|
|
3536
3523
|
/**
|
|
@@ -3560,12 +3547,11 @@ export function toGitHubApiUrl(repoUrl, repoMetadata) {
|
|
|
3560
3547
|
const parts = getGithubUrlParts(repoUrl);
|
|
3561
3548
|
if (parts.length < 5 || parts[2] !== "github.com") {
|
|
3562
3549
|
return undefined; // Not a valid GitHub repo URL
|
|
3563
|
-
} else {
|
|
3564
|
-
return repoMetadataToGitHubApiUrl({
|
|
3565
|
-
group: parts[3],
|
|
3566
|
-
name: parts[4],
|
|
3567
|
-
});
|
|
3568
3550
|
}
|
|
3551
|
+
return repoMetadataToGitHubApiUrl({
|
|
3552
|
+
group: parts[3],
|
|
3553
|
+
name: parts[4],
|
|
3554
|
+
});
|
|
3569
3555
|
}
|
|
3570
3556
|
|
|
3571
3557
|
/**
|
|
@@ -3579,17 +3565,17 @@ export async function getRepoLicense(repoUrl, repoMetadata) {
|
|
|
3579
3565
|
const apiUrl = toGitHubApiUrl(repoUrl, repoMetadata);
|
|
3580
3566
|
// Perform github lookups
|
|
3581
3567
|
if (apiUrl && get_repo_license_errors < MAX_GET_REPO_LICENSE_ERRORS) {
|
|
3582
|
-
const licenseUrl = apiUrl
|
|
3568
|
+
const licenseUrl = `${apiUrl}/license`;
|
|
3583
3569
|
const headers = {};
|
|
3584
3570
|
if (process.env.GITHUB_TOKEN) {
|
|
3585
|
-
headers["Authorization"] =
|
|
3571
|
+
headers["Authorization"] = `Bearer ${process.env.GITHUB_TOKEN}`;
|
|
3586
3572
|
}
|
|
3587
3573
|
try {
|
|
3588
3574
|
const res = await cdxgenAgent.get(licenseUrl, {
|
|
3589
3575
|
responseType: "json",
|
|
3590
3576
|
headers: headers,
|
|
3591
3577
|
});
|
|
3592
|
-
if (res
|
|
3578
|
+
if (res?.body) {
|
|
3593
3579
|
const license = res.body.license;
|
|
3594
3580
|
let licenseId = license.spdx_id;
|
|
3595
3581
|
const licObj = {
|
|
@@ -3614,7 +3600,7 @@ export async function getRepoLicense(repoUrl, repoMetadata) {
|
|
|
3614
3600
|
}
|
|
3615
3601
|
}
|
|
3616
3602
|
} catch (err) {
|
|
3617
|
-
if (err
|
|
3603
|
+
if (err?.message) {
|
|
3618
3604
|
if (
|
|
3619
3605
|
err.message.includes("rate limit exceeded") &&
|
|
3620
3606
|
!process.env.GITHUB_TOKEN
|
|
@@ -3645,16 +3631,16 @@ export async function getGoPkgLicense(repoMetadata) {
|
|
|
3645
3631
|
const name = repoMetadata.name;
|
|
3646
3632
|
let pkgUrlPrefix = "https://pkg.go.dev/";
|
|
3647
3633
|
if (group && group !== "." && group !== name) {
|
|
3648
|
-
pkgUrlPrefix = pkgUrlPrefix + group
|
|
3634
|
+
pkgUrlPrefix = `${pkgUrlPrefix + group}/`;
|
|
3649
3635
|
}
|
|
3650
|
-
pkgUrlPrefix = pkgUrlPrefix + name
|
|
3636
|
+
pkgUrlPrefix = `${pkgUrlPrefix + name}?tab=licenses`;
|
|
3651
3637
|
// Check the metadata cache first
|
|
3652
3638
|
if (metadata_cache[pkgUrlPrefix]) {
|
|
3653
3639
|
return metadata_cache[pkgUrlPrefix];
|
|
3654
3640
|
}
|
|
3655
3641
|
try {
|
|
3656
3642
|
const res = await cdxgenAgent.get(pkgUrlPrefix);
|
|
3657
|
-
if (res
|
|
3643
|
+
if (res?.body) {
|
|
3658
3644
|
const $ = load(res.body);
|
|
3659
3645
|
let licenses = $("#LICENSE > h2").text().trim();
|
|
3660
3646
|
if (licenses === "") {
|
|
@@ -3745,10 +3731,12 @@ export async function parseGoModData(goModData, gosumMap) {
|
|
|
3745
3731
|
if (l.includes("require (")) {
|
|
3746
3732
|
isModReplacement = false;
|
|
3747
3733
|
continue;
|
|
3748
|
-
}
|
|
3734
|
+
}
|
|
3735
|
+
if (l.includes("replace (")) {
|
|
3749
3736
|
isModReplacement = true;
|
|
3750
3737
|
continue;
|
|
3751
|
-
}
|
|
3738
|
+
}
|
|
3739
|
+
if (l.includes("replace ")) {
|
|
3752
3740
|
// If this is an inline replacement, drop the word replace
|
|
3753
3741
|
// (eg; "replace google.golang.org/grpc => google.golang.org/grpc v1.21.0" becomes " google.golang.org/grpc => google.golang.org/grpc v1.21.0")
|
|
3754
3742
|
l = l.replace("replace", "");
|
|
@@ -3811,7 +3799,7 @@ export async function parseGoListDep(rawOutput, gosumMap) {
|
|
|
3811
3799
|
const verArr = l.trim().replace(/[\"']/g, "").split(" ");
|
|
3812
3800
|
|
|
3813
3801
|
if (verArr && verArr.length >= 5) {
|
|
3814
|
-
const key = verArr[0]
|
|
3802
|
+
const key = `${verArr[0]}-${verArr[1]}`;
|
|
3815
3803
|
// Filter duplicates
|
|
3816
3804
|
if (!keys_cache[key]) {
|
|
3817
3805
|
keys_cache[key] = key;
|
|
@@ -3915,8 +3903,8 @@ export async function parseGoModGraph(
|
|
|
3915
3903
|
const tmpA = l.replace("\r", "").split(" ");
|
|
3916
3904
|
if (tmpA && tmpA.length === 2) {
|
|
3917
3905
|
try {
|
|
3918
|
-
const sourcePurl = PackageURL.fromString(
|
|
3919
|
-
const dependsPurl = PackageURL.fromString(
|
|
3906
|
+
const sourcePurl = PackageURL.fromString(`pkg:golang/${tmpA[0]}`);
|
|
3907
|
+
const dependsPurl = PackageURL.fromString(`pkg:golang/${tmpA[1]}`);
|
|
3920
3908
|
const sourceRefString = decodeURIComponent(sourcePurl.toString());
|
|
3921
3909
|
const dependsRefString = decodeURIComponent(dependsPurl.toString());
|
|
3922
3910
|
// Since go mod graph over-reports direct dependencies we use the existing list
|
|
@@ -3933,7 +3921,7 @@ export async function parseGoModGraph(
|
|
|
3933
3921
|
if (!addedPkgs[tmpA[0]]) {
|
|
3934
3922
|
const component = await getGoPkgComponent(
|
|
3935
3923
|
"",
|
|
3936
|
-
`${sourcePurl.namespace ? sourcePurl.namespace
|
|
3924
|
+
`${sourcePurl.namespace ? `${sourcePurl.namespace}/` : ""}${
|
|
3937
3925
|
sourcePurl.name
|
|
3938
3926
|
}`,
|
|
3939
3927
|
sourcePurl.version,
|
|
@@ -3945,7 +3933,7 @@ export async function parseGoModGraph(
|
|
|
3945
3933
|
if (!addedPkgs[tmpA[1]]) {
|
|
3946
3934
|
const component = await getGoPkgComponent(
|
|
3947
3935
|
"",
|
|
3948
|
-
`${dependsPurl.namespace ? dependsPurl.namespace
|
|
3936
|
+
`${dependsPurl.namespace ? `${dependsPurl.namespace}/` : ""}${
|
|
3949
3937
|
dependsPurl.name
|
|
3950
3938
|
}`,
|
|
3951
3939
|
dependsPurl.version,
|
|
@@ -4062,7 +4050,7 @@ export async function parseGopkgData(gopkgData) {
|
|
|
4062
4050
|
switch (key) {
|
|
4063
4051
|
case "digest":
|
|
4064
4052
|
digestStr = value.replace("1:", "");
|
|
4065
|
-
pkg._integrity =
|
|
4053
|
+
pkg._integrity = `sha256-${toBase64(digestStr)}`;
|
|
4066
4054
|
break;
|
|
4067
4055
|
case "name":
|
|
4068
4056
|
pkg.group = "";
|
|
@@ -4104,7 +4092,7 @@ export async function parseGoVersionData(buildInfoData) {
|
|
|
4104
4092
|
}
|
|
4105
4093
|
const name = tmpA[1].trim();
|
|
4106
4094
|
let hash = "";
|
|
4107
|
-
if (tmpA.length
|
|
4095
|
+
if (tmpA.length === 4) {
|
|
4108
4096
|
hash = tmpA[tmpA.length - 1].replace("h1:", "sha256-");
|
|
4109
4097
|
}
|
|
4110
4098
|
const component = await getGoPkgComponent("", name, tmpA[2].trim(), hash);
|
|
@@ -4171,7 +4159,7 @@ export async function getRubyGemsMetadata(pkgList) {
|
|
|
4171
4159
|
: `${RUBYGEMS_V1_URL}${p.name}.json`;
|
|
4172
4160
|
const res = await cdxgenAgent.get(fullUrl, apiOptions);
|
|
4173
4161
|
let body = res.body;
|
|
4174
|
-
if (body
|
|
4162
|
+
if (body?.length) {
|
|
4175
4163
|
body = body[0];
|
|
4176
4164
|
}
|
|
4177
4165
|
p.description = body.description || body.summary || "";
|
|
@@ -4193,7 +4181,7 @@ export async function getRubyGemsMetadata(pkgList) {
|
|
|
4193
4181
|
}
|
|
4194
4182
|
}
|
|
4195
4183
|
if (body.sha) {
|
|
4196
|
-
p._integrity =
|
|
4184
|
+
p._integrity = `sha256-${body.sha}`;
|
|
4197
4185
|
}
|
|
4198
4186
|
if (body.authors) {
|
|
4199
4187
|
p.author = body.authors;
|
|
@@ -4222,13 +4210,13 @@ export async function getRubyGemsMetadata(pkgList) {
|
|
|
4222
4210
|
if (body.yanked) {
|
|
4223
4211
|
p.properties.push({
|
|
4224
4212
|
name: "cdx:gem:yanked",
|
|
4225
|
-
value:
|
|
4213
|
+
value: `${body.yanked}`,
|
|
4226
4214
|
});
|
|
4227
4215
|
}
|
|
4228
4216
|
if (body.prerelease) {
|
|
4229
4217
|
p.properties.push({
|
|
4230
4218
|
name: "cdx:gem:prerelease",
|
|
4231
|
-
value:
|
|
4219
|
+
value: `${body.prerelease}`,
|
|
4232
4220
|
});
|
|
4233
4221
|
}
|
|
4234
4222
|
// Use the latest version if none specified
|
|
@@ -4279,9 +4267,8 @@ export async function parseGemspecData(gemspecData) {
|
|
|
4279
4267
|
pkgList = [pkg];
|
|
4280
4268
|
if (FETCH_LICENSE) {
|
|
4281
4269
|
return await getRubyGemsMetadata(pkgList);
|
|
4282
|
-
} else {
|
|
4283
|
-
return pkgList;
|
|
4284
4270
|
}
|
|
4271
|
+
return pkgList;
|
|
4285
4272
|
}
|
|
4286
4273
|
|
|
4287
4274
|
/**
|
|
@@ -4309,7 +4296,7 @@ export async function parseGemfileLockData(gemLockData, lockFile) {
|
|
|
4309
4296
|
l = l.replace("\r", "");
|
|
4310
4297
|
if (specsFound) {
|
|
4311
4298
|
const tmpA = l.split(" ");
|
|
4312
|
-
if (tmpA && tmpA.length
|
|
4299
|
+
if (tmpA && tmpA.length === 2) {
|
|
4313
4300
|
const name = tmpA[0];
|
|
4314
4301
|
if (name === "remote:") {
|
|
4315
4302
|
return;
|
|
@@ -4375,7 +4362,7 @@ export async function parseGemfileLockData(gemLockData, lockFile) {
|
|
|
4375
4362
|
if (l.trim().startsWith("tag:")) {
|
|
4376
4363
|
lastTag = l.trim().split(" ")[1];
|
|
4377
4364
|
}
|
|
4378
|
-
if (l.trim()
|
|
4365
|
+
if (l.trim() === l.trim().toUpperCase()) {
|
|
4379
4366
|
specsFound = false;
|
|
4380
4367
|
lastRemote = undefined;
|
|
4381
4368
|
lastRevision = undefined;
|
|
@@ -4586,7 +4573,7 @@ export async function getDartMetadata(pkgList) {
|
|
|
4586
4573
|
const RESPONSE_TYPE = "json";
|
|
4587
4574
|
const HEADER_ACCEPT = "application/vnd.pub.v2+json";
|
|
4588
4575
|
const PUB_DEV_URL = process.env.PUB_DEV_URL || "https://pub.dev";
|
|
4589
|
-
const PUB_PACKAGES_URL = PUB_DEV_URL
|
|
4576
|
+
const PUB_PACKAGES_URL = `${PUB_DEV_URL}/api/packages/`;
|
|
4590
4577
|
const PUB_LICENSE_REGEX = /^license:/i;
|
|
4591
4578
|
const cdepList = [];
|
|
4592
4579
|
|
|
@@ -4601,7 +4588,7 @@ export async function getDartMetadata(pkgList) {
|
|
|
4601
4588
|
Accept: HEADER_ACCEPT,
|
|
4602
4589
|
},
|
|
4603
4590
|
});
|
|
4604
|
-
if (res
|
|
4591
|
+
if (res?.body) {
|
|
4605
4592
|
const version = res.body.versions.find((v) => p.version === v.version);
|
|
4606
4593
|
if (version) {
|
|
4607
4594
|
const pubspec = version.pubspec;
|
|
@@ -4613,7 +4600,7 @@ export async function getDartMetadata(pkgList) {
|
|
|
4613
4600
|
p.homepage = { url: pubspec.homepage };
|
|
4614
4601
|
}
|
|
4615
4602
|
const res2 = await cdxgenAgent.get(
|
|
4616
|
-
PUB_PACKAGES_URL + p.name
|
|
4603
|
+
`${PUB_PACKAGES_URL + p.name}/score`,
|
|
4617
4604
|
{
|
|
4618
4605
|
responseType: RESPONSE_TYPE,
|
|
4619
4606
|
headers: {
|
|
@@ -4621,7 +4608,7 @@ export async function getDartMetadata(pkgList) {
|
|
|
4621
4608
|
},
|
|
4622
4609
|
},
|
|
4623
4610
|
);
|
|
4624
|
-
if (res2
|
|
4611
|
+
if (res2?.body) {
|
|
4625
4612
|
const tags = res2.body.tags;
|
|
4626
4613
|
const license = tags.find((tag) => PUB_LICENSE_REGEX.test(tag));
|
|
4627
4614
|
if (license) {
|
|
@@ -4760,7 +4747,7 @@ export async function parseCargoTomlData(cargoTomlFile, simple = false) {
|
|
|
4760
4747
|
value = tmpA[1].trim().replace(/"/g, "");
|
|
4761
4748
|
switch (key) {
|
|
4762
4749
|
case "checksum":
|
|
4763
|
-
pkg._integrity =
|
|
4750
|
+
pkg._integrity = `sha384-${value}`;
|
|
4764
4751
|
break;
|
|
4765
4752
|
case "name":
|
|
4766
4753
|
value = value.split(" ")[0];
|
|
@@ -4803,9 +4790,9 @@ export async function parseCargoTomlData(cargoTomlFile, simple = false) {
|
|
|
4803
4790
|
} else if (l.includes("git =")) {
|
|
4804
4791
|
tmpB = l.split(" { git = ");
|
|
4805
4792
|
if (tmpB && tmpB.length > 1) {
|
|
4806
|
-
version =
|
|
4793
|
+
version = `git+${tmpB[1].split(" }")[0]}`;
|
|
4807
4794
|
}
|
|
4808
|
-
} else if (l.indexOf("path =")
|
|
4795
|
+
} else if (l.indexOf("path =") === -1 && tmpA.length > 1) {
|
|
4809
4796
|
version = tmpA[1];
|
|
4810
4797
|
}
|
|
4811
4798
|
if (name && version) {
|
|
@@ -4821,9 +4808,8 @@ export async function parseCargoTomlData(cargoTomlFile, simple = false) {
|
|
|
4821
4808
|
}
|
|
4822
4809
|
if (!simple && FETCH_LICENSE) {
|
|
4823
4810
|
return await getCratesMetadata(pkgList);
|
|
4824
|
-
} else {
|
|
4825
|
-
return pkgList;
|
|
4826
4811
|
}
|
|
4812
|
+
return pkgList;
|
|
4827
4813
|
}
|
|
4828
4814
|
|
|
4829
4815
|
/**
|
|
@@ -4952,9 +4938,8 @@ export async function parseCargoData(cargoLockFile, simple = false) {
|
|
|
4952
4938
|
}
|
|
4953
4939
|
if (FETCH_LICENSE && !simple) {
|
|
4954
4940
|
return await getCratesMetadata(pkgList);
|
|
4955
|
-
} else {
|
|
4956
|
-
return pkgList;
|
|
4957
4941
|
}
|
|
4942
|
+
return pkgList;
|
|
4958
4943
|
}
|
|
4959
4944
|
|
|
4960
4945
|
export function parseCargoDependencyData(cargoLockData) {
|
|
@@ -5119,9 +5104,8 @@ export async function parseCargoAuditableData(cargoData) {
|
|
|
5119
5104
|
});
|
|
5120
5105
|
if (FETCH_LICENSE) {
|
|
5121
5106
|
return await getCratesMetadata(pkgList);
|
|
5122
|
-
} else {
|
|
5123
|
-
return pkgList;
|
|
5124
5107
|
}
|
|
5108
|
+
return pkgList;
|
|
5125
5109
|
}
|
|
5126
5110
|
|
|
5127
5111
|
export async function parsePubLockData(pubLockData) {
|
|
@@ -5159,9 +5143,8 @@ export async function parsePubLockData(pubLockData) {
|
|
|
5159
5143
|
});
|
|
5160
5144
|
if (FETCH_LICENSE) {
|
|
5161
5145
|
return await getDartMetadata(pkgList);
|
|
5162
|
-
} else {
|
|
5163
|
-
return pkgList;
|
|
5164
5146
|
}
|
|
5147
|
+
return pkgList;
|
|
5165
5148
|
}
|
|
5166
5149
|
|
|
5167
5150
|
export function parsePubYamlData(pubYamlData) {
|
|
@@ -5238,7 +5221,7 @@ export function parseHelmYamlData(helmData) {
|
|
|
5238
5221
|
pkg["homepage"] = { url: hd.home };
|
|
5239
5222
|
}
|
|
5240
5223
|
if (hd.digest) {
|
|
5241
|
-
pkg._integrity =
|
|
5224
|
+
pkg._integrity = `sha256-${hd.digest}`;
|
|
5242
5225
|
}
|
|
5243
5226
|
|
|
5244
5227
|
pkgList.push(pkg);
|
|
@@ -5269,7 +5252,12 @@ export function recurseImageNameLookup(keyValueObj, pkgList, imgList) {
|
|
|
5269
5252
|
keyValueObj.packImage ||
|
|
5270
5253
|
keyValueObj.koImage ||
|
|
5271
5254
|
keyValueObj.kanikoImage;
|
|
5272
|
-
if (
|
|
5255
|
+
if (
|
|
5256
|
+
!imageLike &&
|
|
5257
|
+
keyValueObj.name &&
|
|
5258
|
+
typeof keyValueObj.name === "string" &&
|
|
5259
|
+
keyValueObj.name.includes("/")
|
|
5260
|
+
) {
|
|
5273
5261
|
imageLike = keyValueObj.name;
|
|
5274
5262
|
}
|
|
5275
5263
|
if (
|
|
@@ -5384,16 +5372,15 @@ export function parseBitbucketPipelinesFile(fileContents) {
|
|
|
5384
5372
|
if (imageName === "") {
|
|
5385
5373
|
privateImageBlockFound = true;
|
|
5386
5374
|
continue;
|
|
5387
|
-
} else {
|
|
5388
|
-
/**
|
|
5389
|
-
* Assume this is a public build image
|
|
5390
|
-
* See: https://support.atlassian.com/bitbucket-cloud/docs/use-docker-images-as-build-environments/#Using-public-build-images
|
|
5391
|
-
*/
|
|
5392
|
-
|
|
5393
|
-
imgList.push({
|
|
5394
|
-
image: imageName,
|
|
5395
|
-
});
|
|
5396
5375
|
}
|
|
5376
|
+
/**
|
|
5377
|
+
* Assume this is a public build image
|
|
5378
|
+
* See: https://support.atlassian.com/bitbucket-cloud/docs/use-docker-images-as-build-environments/#Using-public-build-images
|
|
5379
|
+
*/
|
|
5380
|
+
|
|
5381
|
+
imgList.push({
|
|
5382
|
+
image: imageName,
|
|
5383
|
+
});
|
|
5397
5384
|
}
|
|
5398
5385
|
|
|
5399
5386
|
// Pipe usage
|
|
@@ -5544,13 +5531,13 @@ export function parsePrivadoFile(f) {
|
|
|
5544
5531
|
});
|
|
5545
5532
|
}
|
|
5546
5533
|
// Capture processing
|
|
5547
|
-
if (jsonData.processing
|
|
5534
|
+
if (jsonData.processing?.length) {
|
|
5548
5535
|
aservice.data = aservice.data.concat(
|
|
5549
5536
|
convertProcessing(jsonData.processing),
|
|
5550
5537
|
);
|
|
5551
5538
|
}
|
|
5552
5539
|
// Capture sink processing
|
|
5553
|
-
if (jsonData.sinkProcessing
|
|
5540
|
+
if (jsonData.sinkProcessing?.length) {
|
|
5554
5541
|
aservice.data = aservice.data.concat(
|
|
5555
5542
|
convertProcessing(jsonData.sinkProcessing),
|
|
5556
5543
|
);
|
|
@@ -5579,11 +5566,7 @@ export function parsePrivadoFile(f) {
|
|
|
5579
5566
|
}
|
|
5580
5567
|
}
|
|
5581
5568
|
// If there are third party libraries detected, then there are cross boundary calls happening
|
|
5582
|
-
if (
|
|
5583
|
-
jsonData.dataFlow &&
|
|
5584
|
-
jsonData.dataFlow.third_parties &&
|
|
5585
|
-
jsonData.dataFlow.third_parties.length
|
|
5586
|
-
) {
|
|
5569
|
+
if (jsonData.dataFlow?.third_parties?.length) {
|
|
5587
5570
|
aservice["x-trust-boundary"] = true;
|
|
5588
5571
|
}
|
|
5589
5572
|
servlist.push(aservice);
|
|
@@ -5606,12 +5589,10 @@ export function parseOpenapiSpecData(oaData) {
|
|
|
5606
5589
|
return servlist;
|
|
5607
5590
|
}
|
|
5608
5591
|
|
|
5609
|
-
const name =
|
|
5610
|
-
|
|
5611
|
-
|
|
5612
|
-
|
|
5613
|
-
const version =
|
|
5614
|
-
oaData.info && oaData.info.version ? oaData.info.version : "latest";
|
|
5592
|
+
const name = oaData.info?.title
|
|
5593
|
+
? oaData.info.title.replace(/ /g, "-")
|
|
5594
|
+
: "default-name";
|
|
5595
|
+
const version = oaData.info?.version ? oaData.info.version : "latest";
|
|
5615
5596
|
const aservice = {
|
|
5616
5597
|
"bom-ref": `urn:service:${name}:${version}`,
|
|
5617
5598
|
name,
|
|
@@ -5619,10 +5600,10 @@ export function parseOpenapiSpecData(oaData) {
|
|
|
5619
5600
|
version,
|
|
5620
5601
|
};
|
|
5621
5602
|
let serverName = [];
|
|
5622
|
-
if (oaData.servers
|
|
5603
|
+
if (oaData.servers?.length && oaData.servers[0].url) {
|
|
5623
5604
|
serverName = oaData.servers[0].url;
|
|
5624
5605
|
if (!serverName.startsWith("http") || !serverName.includes("//")) {
|
|
5625
|
-
serverName =
|
|
5606
|
+
serverName = `http://${serverName}`;
|
|
5626
5607
|
}
|
|
5627
5608
|
}
|
|
5628
5609
|
if (oaData.paths) {
|
|
@@ -5637,7 +5618,7 @@ export function parseOpenapiSpecData(oaData) {
|
|
|
5637
5618
|
aservice.endpoints = endpoints;
|
|
5638
5619
|
}
|
|
5639
5620
|
let authenticated = false;
|
|
5640
|
-
if (oaData.components
|
|
5621
|
+
if (oaData.components?.securitySchemes) {
|
|
5641
5622
|
authenticated = true;
|
|
5642
5623
|
}
|
|
5643
5624
|
aservice.authenticated = authenticated;
|
|
@@ -5721,11 +5702,11 @@ export function parseGitHubWorkflowData(ghwData) {
|
|
|
5721
5702
|
let group = "";
|
|
5722
5703
|
const version = tmpA[1];
|
|
5723
5704
|
const tmpB = groupName.split("/");
|
|
5724
|
-
if (tmpB.length
|
|
5705
|
+
if (tmpB.length === 2) {
|
|
5725
5706
|
name = tmpB[1];
|
|
5726
5707
|
group = tmpB[0];
|
|
5727
5708
|
}
|
|
5728
|
-
const key = group
|
|
5709
|
+
const key = `${group}-${name}-${version}`;
|
|
5729
5710
|
if (!keys_cache[key] && name && version) {
|
|
5730
5711
|
keys_cache[key] = key;
|
|
5731
5712
|
pkgList.push({
|
|
@@ -5763,7 +5744,7 @@ export function parseCloudBuildData(cbwData) {
|
|
|
5763
5744
|
group = "";
|
|
5764
5745
|
}
|
|
5765
5746
|
const version = tmpA[1];
|
|
5766
|
-
const key = group
|
|
5747
|
+
const key = `${group}-${name}-${version}`;
|
|
5767
5748
|
if (!keys_cache[key] && name && version) {
|
|
5768
5749
|
keys_cache[key] = key;
|
|
5769
5750
|
pkgList.push({
|
|
@@ -5881,7 +5862,7 @@ export function parseLeiningenData(leinData) {
|
|
|
5881
5862
|
}
|
|
5882
5863
|
const tmpArr = leinData.split("(defproject");
|
|
5883
5864
|
if (tmpArr.length > 1) {
|
|
5884
|
-
leinData =
|
|
5865
|
+
leinData = `(defproject${tmpArr[1]}`;
|
|
5885
5866
|
}
|
|
5886
5867
|
const ednData = parseEDNString(leinData);
|
|
5887
5868
|
for (const k of Object.keys(ednData)) {
|
|
@@ -5939,7 +5920,7 @@ export function parseEdnData(rawEdnData) {
|
|
|
5939
5920
|
group = "";
|
|
5940
5921
|
}
|
|
5941
5922
|
const name = basename(psym);
|
|
5942
|
-
const cacheKey = group
|
|
5923
|
+
const cacheKey = `${group}-${name}-${version}`;
|
|
5943
5924
|
if (!pkgCache[cacheKey]) {
|
|
5944
5925
|
pkgList.push({ group, name, version });
|
|
5945
5926
|
pkgCache[cacheKey] = true;
|
|
@@ -6037,7 +6018,7 @@ export function parseCsPkgData(pkgData) {
|
|
|
6037
6018
|
attributesKey: "$",
|
|
6038
6019
|
commentKey: "value",
|
|
6039
6020
|
}).packages;
|
|
6040
|
-
if (!packages || packages.length
|
|
6021
|
+
if (!packages || packages.length === 0) {
|
|
6041
6022
|
return pkgList;
|
|
6042
6023
|
}
|
|
6043
6024
|
packages = packages[0].package;
|
|
@@ -6064,11 +6045,11 @@ export function parseCsProjData(csProjData, projFile) {
|
|
|
6064
6045
|
attributesKey: "$",
|
|
6065
6046
|
commentKey: "value",
|
|
6066
6047
|
}).Project;
|
|
6067
|
-
if (!projects || projects.length
|
|
6048
|
+
if (!projects || projects.length === 0) {
|
|
6068
6049
|
return pkgList;
|
|
6069
6050
|
}
|
|
6070
6051
|
const project = projects[0];
|
|
6071
|
-
if (project.ItemGroup
|
|
6052
|
+
if (project.ItemGroup?.length) {
|
|
6072
6053
|
for (const i in project.ItemGroup) {
|
|
6073
6054
|
const item = project.ItemGroup[i];
|
|
6074
6055
|
// .net core use PackageReference
|
|
@@ -6156,9 +6137,8 @@ export function parseCsProjAssetsData(csProjData, assetsJsonFile) {
|
|
|
6156
6137
|
operator: match[2],
|
|
6157
6138
|
version: match[3],
|
|
6158
6139
|
};
|
|
6159
|
-
} else {
|
|
6160
|
-
return null;
|
|
6161
6140
|
}
|
|
6141
|
+
return null;
|
|
6162
6142
|
}
|
|
6163
6143
|
|
|
6164
6144
|
const pkgList = [];
|
|
@@ -6256,9 +6236,9 @@ export function parseCsProjAssetsData(csProjData, assetsJsonFile) {
|
|
|
6256
6236
|
};
|
|
6257
6237
|
if (lib[rootDep]) {
|
|
6258
6238
|
if (lib[rootDep].sha512) {
|
|
6259
|
-
pkg["_integrity"] =
|
|
6239
|
+
pkg["_integrity"] = `sha512-${lib[rootDep].sha512}`;
|
|
6260
6240
|
} else if (lib[rootDep].sha256) {
|
|
6261
|
-
pkg["_integrity"] =
|
|
6241
|
+
pkg["_integrity"] = `sha256-${lib[rootDep].sha256}`;
|
|
6262
6242
|
}
|
|
6263
6243
|
if (lib[rootDep].files && Array.isArray(lib[rootDep].files)) {
|
|
6264
6244
|
const dllFiles = new Set();
|
|
@@ -6393,7 +6373,7 @@ export function parseCsPkgLockData(csLockData, pkgLockFile) {
|
|
|
6393
6373
|
purl,
|
|
6394
6374
|
"bom-ref": decodeURIComponent(purl),
|
|
6395
6375
|
_integrity: libData.contentHash
|
|
6396
|
-
?
|
|
6376
|
+
? `sha512-${libData.contentHash}`
|
|
6397
6377
|
: undefined,
|
|
6398
6378
|
properties: [
|
|
6399
6379
|
{
|
|
@@ -6425,11 +6405,7 @@ export function parseCsPkgLockData(csLockData, pkgLockFile) {
|
|
|
6425
6405
|
let adepResolvedVersion = libData.dependencies[adep];
|
|
6426
6406
|
const aversionNoRuntime = aversion.split("/")[0];
|
|
6427
6407
|
// Try to get the resolved version of the dependency. See #930 and #937
|
|
6428
|
-
if (
|
|
6429
|
-
assetData.dependencies[aversion] &&
|
|
6430
|
-
assetData.dependencies[aversion][adep] &&
|
|
6431
|
-
assetData.dependencies[aversion][adep].resolved
|
|
6432
|
-
) {
|
|
6408
|
+
if (assetData.dependencies[aversion]?.[adep]?.resolved) {
|
|
6433
6409
|
adepResolvedVersion =
|
|
6434
6410
|
assetData.dependencies[aversion][adep].resolved;
|
|
6435
6411
|
} else if (
|
|
@@ -6441,12 +6417,10 @@ export function parseCsPkgLockData(csLockData, pkgLockFile) {
|
|
|
6441
6417
|
adepResolvedVersion =
|
|
6442
6418
|
assetData.dependencies[aversionNoRuntime][adep].resolved;
|
|
6443
6419
|
} else if (
|
|
6444
|
-
(assetData.dependencies[aversion] &&
|
|
6445
|
-
assetData.dependencies[aversion][adep.toLowerCase()] &&
|
|
6420
|
+
(assetData.dependencies[aversion]?.[adep.toLowerCase()] &&
|
|
6446
6421
|
assetData.dependencies[aversion][adep.toLowerCase()].type ===
|
|
6447
6422
|
"Project") ||
|
|
6448
|
-
(assetData.dependencies[aversionNoRuntime] &&
|
|
6449
|
-
assetData.dependencies[aversionNoRuntime][adep.toLowerCase()] &&
|
|
6423
|
+
(assetData.dependencies[aversionNoRuntime]?.[adep.toLowerCase()] &&
|
|
6450
6424
|
assetData.dependencies[aversionNoRuntime][adep.toLowerCase()]
|
|
6451
6425
|
.type === "Project")
|
|
6452
6426
|
) {
|
|
@@ -6827,7 +6801,7 @@ export function parseSbtTree(sbtTreeFile) {
|
|
|
6827
6801
|
if (!level_trees[purlString]) {
|
|
6828
6802
|
level_trees[purlString] = [];
|
|
6829
6803
|
}
|
|
6830
|
-
if (level
|
|
6804
|
+
if (level === 0) {
|
|
6831
6805
|
first_purl = purlString;
|
|
6832
6806
|
stack = [first_purl];
|
|
6833
6807
|
stack.push(purlString);
|
|
@@ -6878,11 +6852,11 @@ export function parseSbtLock(pkgLockFile) {
|
|
|
6878
6852
|
const lockData = JSON.parse(
|
|
6879
6853
|
readFileSync(pkgLockFile, { encoding: "utf-8" }),
|
|
6880
6854
|
);
|
|
6881
|
-
if (lockData
|
|
6855
|
+
if (lockData?.dependencies) {
|
|
6882
6856
|
for (const pkg of lockData.dependencies) {
|
|
6883
6857
|
const artifacts = pkg.artifacts || undefined;
|
|
6884
6858
|
let integrity = "";
|
|
6885
|
-
if (artifacts
|
|
6859
|
+
if (artifacts?.length) {
|
|
6886
6860
|
integrity = artifacts[0].hash.replace("sha1:", "sha1-");
|
|
6887
6861
|
}
|
|
6888
6862
|
let compScope = undefined;
|
|
@@ -7028,7 +7002,7 @@ export function convertOSQueryResults(
|
|
|
7028
7002
|
enhance = false,
|
|
7029
7003
|
) {
|
|
7030
7004
|
const pkgList = [];
|
|
7031
|
-
if (results
|
|
7005
|
+
if (results?.length) {
|
|
7032
7006
|
for (const res of results) {
|
|
7033
7007
|
const version =
|
|
7034
7008
|
res.version ||
|
|
@@ -7083,7 +7057,7 @@ export function convertOSQueryResults(
|
|
|
7083
7057
|
name = queryObj.name;
|
|
7084
7058
|
}
|
|
7085
7059
|
let qualifiers = undefined;
|
|
7086
|
-
if (res.identifying_number
|
|
7060
|
+
if (res.identifying_number?.length) {
|
|
7087
7061
|
qualifiers = {
|
|
7088
7062
|
tag_id: res.identifying_number.replace("{", "").replace("}", ""),
|
|
7089
7063
|
};
|
|
@@ -7163,24 +7137,24 @@ export function convertOSQueryResults(
|
|
|
7163
7137
|
}
|
|
7164
7138
|
|
|
7165
7139
|
function purlFromUrlString(type, repoUrl, version) {
|
|
7166
|
-
let namespace = ""
|
|
7167
|
-
|
|
7168
|
-
if (repoUrl
|
|
7140
|
+
let namespace = "";
|
|
7141
|
+
let name;
|
|
7142
|
+
if (repoUrl?.startsWith("http")) {
|
|
7169
7143
|
const url = new URL(repoUrl);
|
|
7170
7144
|
const pathnameParts = url.pathname.split("/");
|
|
7171
7145
|
const pathnameLastElement = pathnameParts.pop(); // pop() returns last element and removes it from pathnameParts
|
|
7172
7146
|
name = pathnameLastElement.replace(".git", "");
|
|
7173
7147
|
const urlpath = pathnameParts.join("/");
|
|
7174
7148
|
namespace = url.hostname + urlpath;
|
|
7175
|
-
} else if (repoUrl
|
|
7149
|
+
} else if (repoUrl?.startsWith("git@")) {
|
|
7176
7150
|
const parts = repoUrl.split(":");
|
|
7177
7151
|
const hostname = parts[0].split("@")[1];
|
|
7178
7152
|
const pathnameParts = parts[1].split("/");
|
|
7179
7153
|
const pathnameLastElement = pathnameParts.pop();
|
|
7180
7154
|
name = pathnameLastElement.replace(".git", "");
|
|
7181
7155
|
const urlpath = pathnameParts.join("/");
|
|
7182
|
-
namespace = hostname
|
|
7183
|
-
} else if (repoUrl
|
|
7156
|
+
namespace = `${hostname}/${urlpath}`;
|
|
7157
|
+
} else if (repoUrl?.startsWith("ssh://git@bitbucket")) {
|
|
7184
7158
|
repoUrl = repoUrl.replace("ssh://git@", "");
|
|
7185
7159
|
const parts = repoUrl.split(":");
|
|
7186
7160
|
const hostname = parts[0];
|
|
@@ -7188,8 +7162,8 @@ function purlFromUrlString(type, repoUrl, version) {
|
|
|
7188
7162
|
const pathnameLastElement = pathnameParts.pop();
|
|
7189
7163
|
name = pathnameLastElement.replace(".git", "");
|
|
7190
7164
|
const urlpath = pathnameParts.join("/");
|
|
7191
|
-
namespace = hostname
|
|
7192
|
-
} else if (repoUrl
|
|
7165
|
+
namespace = `${hostname}/${urlpath}`;
|
|
7166
|
+
} else if (repoUrl?.startsWith("/")) {
|
|
7193
7167
|
const parts = repoUrl.split("/");
|
|
7194
7168
|
name = parts[parts.length - 1];
|
|
7195
7169
|
} else {
|
|
@@ -7303,7 +7277,7 @@ export function parseSwiftResolved(resolvedFile) {
|
|
|
7303
7277
|
let resolvedList = [];
|
|
7304
7278
|
if (pkgData.pins) {
|
|
7305
7279
|
resolvedList = pkgData.pins;
|
|
7306
|
-
} else if (pkgData.object
|
|
7280
|
+
} else if (pkgData.object?.pins) {
|
|
7307
7281
|
resolvedList = pkgData.object.pins;
|
|
7308
7282
|
}
|
|
7309
7283
|
for (const adep of resolvedList) {
|
|
@@ -7374,8 +7348,8 @@ export async function collectMvnDependencies(
|
|
|
7374
7348
|
"-Dmdep.copyPom=true",
|
|
7375
7349
|
"-Dmdep.useRepositoryLayout=true",
|
|
7376
7350
|
"-Dmdep.includeScope=compile",
|
|
7377
|
-
|
|
7378
|
-
|
|
7351
|
+
`-Dmdep.prependGroupId=${process.env.MAVEN_PREPEND_GROUP || "false"}`,
|
|
7352
|
+
`-Dmdep.stripVersion=${process.env.MAVEN_STRIP_VERSION || "false"}`,
|
|
7379
7353
|
];
|
|
7380
7354
|
if (process.env.MVN_ARGS) {
|
|
7381
7355
|
const addArgs = process.env.MVN_ARGS.split(" ");
|
|
@@ -7477,7 +7451,7 @@ export async function collectJarNS(jarPath, pomPathMap = {}) {
|
|
|
7477
7451
|
}
|
|
7478
7452
|
// Parse jar files to get class names
|
|
7479
7453
|
const jarFiles = getAllFiles(jarPath, "**/*.jar");
|
|
7480
|
-
if (jarFiles
|
|
7454
|
+
if (jarFiles?.length) {
|
|
7481
7455
|
for (const jf of jarFiles) {
|
|
7482
7456
|
const jarname = jf;
|
|
7483
7457
|
let pomname =
|
|
@@ -7515,7 +7489,7 @@ export async function collectJarNS(jarPath, pomPathMap = {}) {
|
|
|
7515
7489
|
// Let's try our best to construct a purl for .m2 cache entries of the form
|
|
7516
7490
|
// .m2/repository/org/apache/logging/log4j/log4j-web/3.0.0-SNAPSHOT/log4j-web-3.0.0-SNAPSHOT.jar
|
|
7517
7491
|
const tmpA = jf.split(join(".m2", "repository", ""));
|
|
7518
|
-
if (tmpA
|
|
7492
|
+
if (tmpA?.length) {
|
|
7519
7493
|
const tmpJarPath = tmpA[tmpA.length - 1];
|
|
7520
7494
|
// This would yield log4j-web-3.0.0-SNAPSHOT.jar
|
|
7521
7495
|
const jarFileName = basename(tmpJarPath).replace(".jar", "");
|
|
@@ -7561,7 +7535,7 @@ export async function collectJarNS(jarPath, pomPathMap = {}) {
|
|
|
7561
7535
|
// Let's try our best to construct a purl for gradle cache entries of the form
|
|
7562
7536
|
// .gradle/caches/modules-2/files-2.1/org.xmlresolver/xmlresolver/4.2.0/f4dbdaa83d636dcac91c9003ffa7fb173173fe8d/xmlresolver-4.2.0-data.jar
|
|
7563
7537
|
const tmpA = jf.split(join("files-2.1", ""));
|
|
7564
|
-
if (tmpA
|
|
7538
|
+
if (tmpA?.length) {
|
|
7565
7539
|
const tmpJarPath = tmpA[tmpA.length - 1];
|
|
7566
7540
|
// This would yield xmlresolver-4.2.0-data.jar
|
|
7567
7541
|
const jarFileName = basename(tmpJarPath).replace(".jar", "");
|
|
@@ -7574,7 +7548,7 @@ export async function collectJarNS(jarPath, pomPathMap = {}) {
|
|
|
7574
7548
|
// The result would form the group name
|
|
7575
7549
|
let jarGroupName = tmpDirParts.join(".").replace(/^\./, "");
|
|
7576
7550
|
if (jarGroupName.includes(pkgName)) {
|
|
7577
|
-
jarGroupName = jarGroupName.replace(
|
|
7551
|
+
jarGroupName = jarGroupName.replace(`.${pkgName}`, "");
|
|
7578
7552
|
}
|
|
7579
7553
|
const purlObj = new PackageURL(
|
|
7580
7554
|
"maven",
|
|
@@ -7704,7 +7678,7 @@ export function parsePomXml(pomXmlData) {
|
|
|
7704
7678
|
version,
|
|
7705
7679
|
description: project.description ? project.description._ : "",
|
|
7706
7680
|
url: project.url ? project.url._ : "",
|
|
7707
|
-
scm: project.scm
|
|
7681
|
+
scm: project.scm?.url ? project.scm.url._ : "",
|
|
7708
7682
|
};
|
|
7709
7683
|
}
|
|
7710
7684
|
return undefined;
|
|
@@ -7761,7 +7735,7 @@ export function getPomPropertiesFromMavenDir(mavenDir) {
|
|
|
7761
7735
|
let pomProperties = {};
|
|
7762
7736
|
if (existsSync(mavenDir) && lstatSync(mavenDir).isDirectory()) {
|
|
7763
7737
|
const pomPropertiesFiles = getAllFiles(mavenDir, "**/pom.properties");
|
|
7764
|
-
if (pomPropertiesFiles
|
|
7738
|
+
if (pomPropertiesFiles?.length) {
|
|
7765
7739
|
const pomPropertiesString = readFileSync(pomPropertiesFiles[0], {
|
|
7766
7740
|
encoding: "utf-8",
|
|
7767
7741
|
});
|
|
@@ -7866,7 +7840,7 @@ export async function extractJarArchive(jarFile, tempDir, jarNSMapping = {}) {
|
|
|
7866
7840
|
if (DEBUG_MODE) {
|
|
7867
7841
|
console.log(`List of jars: ${jarFiles}`);
|
|
7868
7842
|
}
|
|
7869
|
-
if (jarFiles
|
|
7843
|
+
if (jarFiles?.length) {
|
|
7870
7844
|
for (const jf of jarFiles) {
|
|
7871
7845
|
// If the jar file doesn't exist at the point of use, skip it
|
|
7872
7846
|
if (!existsSync(jf)) {
|
|
@@ -7914,11 +7888,11 @@ export async function extractJarArchive(jarFile, tempDir, jarNSMapping = {}) {
|
|
|
7914
7888
|
// META-INF/maven/${groupId}/${artifactId}/pom.properties
|
|
7915
7889
|
// see https://maven.apache.org/shared/maven-archiver/index.html
|
|
7916
7890
|
const pomProperties = getPomPropertiesFromMavenDir(mavenDir);
|
|
7917
|
-
let group = pomProperties["groupId"]
|
|
7918
|
-
|
|
7919
|
-
|
|
7920
|
-
|
|
7921
|
-
|
|
7891
|
+
let group = pomProperties["groupId"];
|
|
7892
|
+
let name = pomProperties["artifactId"];
|
|
7893
|
+
let version = pomProperties["version"];
|
|
7894
|
+
let confidence = 1;
|
|
7895
|
+
let technique = "manifest-analysis";
|
|
7922
7896
|
if (
|
|
7923
7897
|
(!group || !name || !version) &&
|
|
7924
7898
|
SEARCH_MAVEN_ORG &&
|
|
@@ -7926,10 +7900,7 @@ export async function extractJarArchive(jarFile, tempDir, jarNSMapping = {}) {
|
|
|
7926
7900
|
) {
|
|
7927
7901
|
try {
|
|
7928
7902
|
const sha = await checksumFile("sha1", jf);
|
|
7929
|
-
const searchurl =
|
|
7930
|
-
"https://search.maven.org/solrsearch/select?q=1:%22" +
|
|
7931
|
-
sha +
|
|
7932
|
-
"%22&rows=20&wt=json";
|
|
7903
|
+
const searchurl = `https://search.maven.org/solrsearch/select?q=1:%22${sha}%22&rows=20&wt=json`;
|
|
7933
7904
|
const res = await cdxgenAgent.get(searchurl, {
|
|
7934
7905
|
responseType: "json",
|
|
7935
7906
|
timeout: {
|
|
@@ -7941,8 +7912,8 @@ export async function extractJarArchive(jarFile, tempDir, jarNSMapping = {}) {
|
|
|
7941
7912
|
response: 1000,
|
|
7942
7913
|
},
|
|
7943
7914
|
});
|
|
7944
|
-
const data = res
|
|
7945
|
-
if (data && data["numFound"]
|
|
7915
|
+
const data = res?.body ? res.body["response"] : undefined;
|
|
7916
|
+
if (data && data["numFound"] === 1) {
|
|
7946
7917
|
const jarInfo = data["docs"][0];
|
|
7947
7918
|
group = jarInfo["g"];
|
|
7948
7919
|
name = jarInfo["a"];
|
|
@@ -7950,7 +7921,7 @@ export async function extractJarArchive(jarFile, tempDir, jarNSMapping = {}) {
|
|
|
7950
7921
|
technique = "hash-comparison";
|
|
7951
7922
|
}
|
|
7952
7923
|
} catch (err) {
|
|
7953
|
-
if (err
|
|
7924
|
+
if (err?.message && !err.message.includes("404")) {
|
|
7954
7925
|
if (err.message.includes("Timeout")) {
|
|
7955
7926
|
console.log(
|
|
7956
7927
|
"Maven search appears to be unavailable. Search will be skipped for all remaining packages.",
|
|
@@ -7982,7 +7953,7 @@ export async function extractJarArchive(jarFile, tempDir, jarNSMapping = {}) {
|
|
|
7982
7953
|
jarMetadata["Bundle-Version"] ||
|
|
7983
7954
|
jarMetadata["Implementation-Version"] ||
|
|
7984
7955
|
jarMetadata["Specification-Version"];
|
|
7985
|
-
if (version
|
|
7956
|
+
if (version?.includes(" ")) {
|
|
7986
7957
|
version = version.split(" ")[0];
|
|
7987
7958
|
}
|
|
7988
7959
|
// Prefer jar filename to construct name and version
|
|
@@ -7998,7 +7969,7 @@ export async function extractJarArchive(jarFile, tempDir, jarNSMapping = {}) {
|
|
|
7998
7969
|
if (!version || version === "") {
|
|
7999
7970
|
version = lastPart.replace(".jar", "");
|
|
8000
7971
|
}
|
|
8001
|
-
name = jarname.replace(
|
|
7972
|
+
name = jarname.replace(`-${lastPart}`, "") || "";
|
|
8002
7973
|
}
|
|
8003
7974
|
}
|
|
8004
7975
|
}
|
|
@@ -8018,21 +7989,18 @@ export async function extractJarArchive(jarFile, tempDir, jarNSMapping = {}) {
|
|
|
8018
7989
|
// Sometimes the group might already contain the name
|
|
8019
7990
|
// Eg: group: org.checkerframework.checker.qual name: checker-qual
|
|
8020
7991
|
if (name && group && !group.startsWith("javax")) {
|
|
8021
|
-
if (group.includes(
|
|
7992
|
+
if (group.includes(`.${name.toLowerCase().replace(/-/g, ".")}`)) {
|
|
8022
7993
|
group = group.replace(
|
|
8023
|
-
new RegExp(
|
|
8024
|
-
"",
|
|
8025
|
-
);
|
|
8026
|
-
} else if (group.includes("." + name.toLowerCase())) {
|
|
8027
|
-
group = group.replace(
|
|
8028
|
-
new RegExp("." + name.toLowerCase() + "$"),
|
|
7994
|
+
new RegExp(`.${name.toLowerCase().replace(/-/g, ".")}$`),
|
|
8029
7995
|
"",
|
|
8030
7996
|
);
|
|
7997
|
+
} else if (group.includes(`.${name.toLowerCase()}`)) {
|
|
7998
|
+
group = group.replace(new RegExp(`.${name.toLowerCase()}$`), "");
|
|
8031
7999
|
}
|
|
8032
8000
|
}
|
|
8033
8001
|
// Patch the group string
|
|
8034
8002
|
for (const aprefix in vendorAliases) {
|
|
8035
|
-
if (name
|
|
8003
|
+
if (name?.startsWith(aprefix)) {
|
|
8036
8004
|
group = vendorAliases[aprefix];
|
|
8037
8005
|
break;
|
|
8038
8006
|
}
|
|
@@ -8073,11 +8041,7 @@ export async function extractJarArchive(jarFile, tempDir, jarNSMapping = {}) {
|
|
|
8073
8041
|
},
|
|
8074
8042
|
],
|
|
8075
8043
|
};
|
|
8076
|
-
if (
|
|
8077
|
-
jarNSMapping &&
|
|
8078
|
-
jarNSMapping[apkg.purl] &&
|
|
8079
|
-
jarNSMapping[apkg.purl].namespaces
|
|
8080
|
-
) {
|
|
8044
|
+
if (jarNSMapping?.[apkg.purl] && jarNSMapping[apkg.purl].namespaces) {
|
|
8081
8045
|
apkg.properties.push({
|
|
8082
8046
|
name: "Namespaces",
|
|
8083
8047
|
value: jarNSMapping[apkg.purl].namespaces.join("\n"),
|
|
@@ -8148,7 +8112,7 @@ export function addPlugin(projectPath, plugin) {
|
|
|
8148
8112
|
const pluginsFile = sbtPluginsPath(projectPath);
|
|
8149
8113
|
let originalPluginsFile = null;
|
|
8150
8114
|
if (existsSync(pluginsFile)) {
|
|
8151
|
-
originalPluginsFile = pluginsFile
|
|
8115
|
+
originalPluginsFile = `${pluginsFile}.cdxgen`;
|
|
8152
8116
|
copyFileSync(pluginsFile, originalPluginsFile, constants.COPYFILE_FICLONE);
|
|
8153
8117
|
}
|
|
8154
8118
|
|
|
@@ -8170,19 +8134,13 @@ export function cleanupPlugin(projectPath, originalPluginsFile) {
|
|
|
8170
8134
|
// just remove the file, it was never there
|
|
8171
8135
|
unlinkSync(pluginsFile);
|
|
8172
8136
|
return !existsSync(pluginsFile);
|
|
8173
|
-
} else {
|
|
8174
|
-
// Bring back the original file
|
|
8175
|
-
copyFileSync(
|
|
8176
|
-
originalPluginsFile,
|
|
8177
|
-
pluginsFile,
|
|
8178
|
-
constants.COPYFILE_FICLONE,
|
|
8179
|
-
);
|
|
8180
|
-
unlinkSync(originalPluginsFile);
|
|
8181
|
-
return true;
|
|
8182
8137
|
}
|
|
8183
|
-
|
|
8184
|
-
|
|
8138
|
+
// Bring back the original file
|
|
8139
|
+
copyFileSync(originalPluginsFile, pluginsFile, constants.COPYFILE_FICLONE);
|
|
8140
|
+
unlinkSync(originalPluginsFile);
|
|
8141
|
+
return true;
|
|
8185
8142
|
}
|
|
8143
|
+
return false;
|
|
8186
8144
|
}
|
|
8187
8145
|
|
|
8188
8146
|
/**
|
|
@@ -8290,7 +8248,7 @@ export function getGradleCommand(srcPath, rootPath) {
|
|
|
8290
8248
|
let gradleCmd = "gradle";
|
|
8291
8249
|
|
|
8292
8250
|
let findGradleFile = "gradlew";
|
|
8293
|
-
if (platform()
|
|
8251
|
+
if (platform() === "win32") {
|
|
8294
8252
|
findGradleFile = "gradlew.bat";
|
|
8295
8253
|
}
|
|
8296
8254
|
|
|
@@ -8332,7 +8290,7 @@ export function getMavenCommand(srcPath, rootPath) {
|
|
|
8332
8290
|
let isWrapperFound = false;
|
|
8333
8291
|
let findMavenFile = "mvnw";
|
|
8334
8292
|
let mavenWrapperCmd = null;
|
|
8335
|
-
if (platform()
|
|
8293
|
+
if (platform() === "win32") {
|
|
8336
8294
|
findMavenFile = "mvnw.bat";
|
|
8337
8295
|
if (
|
|
8338
8296
|
!existsSync(join(srcPath, findMavenFile)) &&
|
|
@@ -8544,7 +8502,7 @@ export function findAppModules(
|
|
|
8544
8502
|
);
|
|
8545
8503
|
}
|
|
8546
8504
|
// Clean up
|
|
8547
|
-
if (tempDir
|
|
8505
|
+
if (tempDir?.startsWith(tmpdir()) && rmSync) {
|
|
8548
8506
|
rmSync(tempDir, { recursive: true, force: true });
|
|
8549
8507
|
}
|
|
8550
8508
|
return retList;
|
|
@@ -8642,10 +8600,7 @@ export function getPipFrozenTree(basePath, reqOrSetupFile, tempVenvDir) {
|
|
|
8642
8600
|
frozen = false;
|
|
8643
8601
|
if (DEBUG_MODE) {
|
|
8644
8602
|
console.log("Virtual env creation has failed");
|
|
8645
|
-
if (
|
|
8646
|
-
result.stderr &&
|
|
8647
|
-
result.stderr.includes("spawnSync python ENOENT")
|
|
8648
|
-
) {
|
|
8603
|
+
if (result.stderr?.includes("spawnSync python ENOENT")) {
|
|
8649
8604
|
console.log(
|
|
8650
8605
|
"Install suitable version of python or set the environment variable PYTHON_CMD.",
|
|
8651
8606
|
);
|
|
@@ -8701,7 +8656,7 @@ export function getPipFrozenTree(basePath, reqOrSetupFile, tempVenvDir) {
|
|
|
8701
8656
|
shell: isWin,
|
|
8702
8657
|
});
|
|
8703
8658
|
if (result.status !== 0 || result.error) {
|
|
8704
|
-
if (result.stderr
|
|
8659
|
+
if (result.stderr?.includes("No module named poetry")) {
|
|
8705
8660
|
poetryInstallArgs = ["install", "-n", "--no-root"];
|
|
8706
8661
|
// Attempt to perform poetry install
|
|
8707
8662
|
result = spawnSync("poetry", poetryInstallArgs, {
|
|
@@ -8751,7 +8706,7 @@ export function getPipFrozenTree(basePath, reqOrSetupFile, tempVenvDir) {
|
|
|
8751
8706
|
env,
|
|
8752
8707
|
});
|
|
8753
8708
|
tempVenvDir = result.stdout.replaceAll(/[\r\n]+/g, "");
|
|
8754
|
-
if (tempVenvDir
|
|
8709
|
+
if (tempVenvDir?.length) {
|
|
8755
8710
|
env.VIRTUAL_ENV = tempVenvDir;
|
|
8756
8711
|
env.PATH = `${join(
|
|
8757
8712
|
tempVenvDir,
|
|
@@ -8837,10 +8792,7 @@ export function getPipFrozenTree(basePath, reqOrSetupFile, tempVenvDir) {
|
|
|
8837
8792
|
}
|
|
8838
8793
|
}
|
|
8839
8794
|
// Bug #375. Attempt pip freeze on existing and new virtual environments
|
|
8840
|
-
if (
|
|
8841
|
-
(env.VIRTUAL_ENV && env.VIRTUAL_ENV.length) ||
|
|
8842
|
-
(env.CONDA_PREFIX && env.CONDA_PREFIX.length)
|
|
8843
|
-
) {
|
|
8795
|
+
if (env.VIRTUAL_ENV?.length || env.CONDA_PREFIX?.length) {
|
|
8844
8796
|
/**
|
|
8845
8797
|
* At this point, the previous attempt to do a pip install might have failed and we might have an unclean virtual environment with an incomplete list
|
|
8846
8798
|
* The position taken by cdxgen is "Some SBOM is better than no SBOM", so we proceed to collecting the dependencies that got installed with pip freeze
|
|
@@ -8930,7 +8882,7 @@ export function parsePackageJsonName(name) {
|
|
|
8930
8882
|
);
|
|
8931
8883
|
if (match) {
|
|
8932
8884
|
returnObject.scope =
|
|
8933
|
-
(match[1] && name.includes("@") ?
|
|
8885
|
+
(match[1] && name.includes("@") ? `@${match[1]}` : match[1]) || null;
|
|
8934
8886
|
returnObject.fullName = match[2] || match[0];
|
|
8935
8887
|
returnObject.projectName = match[3] === match[2] ? null : match[3];
|
|
8936
8888
|
returnObject.moduleName = match[4] || match[2] || null;
|
|
@@ -8954,7 +8906,7 @@ export async function addEvidenceForImports(
|
|
|
8954
8906
|
const impPkgs = Object.keys(allImports);
|
|
8955
8907
|
const exportedPkgs = Object.keys(allExports);
|
|
8956
8908
|
for (const pkg of pkgList) {
|
|
8957
|
-
if (impPkgs
|
|
8909
|
+
if (impPkgs?.length) {
|
|
8958
8910
|
// Assume that all packages are optional until we see an evidence
|
|
8959
8911
|
pkg.scope = "optional";
|
|
8960
8912
|
}
|
|
@@ -8963,10 +8915,9 @@ export async function addEvidenceForImports(
|
|
|
8963
8915
|
if (group === "@types") {
|
|
8964
8916
|
continue;
|
|
8965
8917
|
}
|
|
8966
|
-
const aliases =
|
|
8967
|
-
|
|
8968
|
-
|
|
8969
|
-
: [name];
|
|
8918
|
+
const aliases = group?.length
|
|
8919
|
+
? [name, `${group}/${name}`, `@${group}/${name}`]
|
|
8920
|
+
: [name];
|
|
8970
8921
|
for (const alias of aliases) {
|
|
8971
8922
|
const all_includes = impPkgs.filter(
|
|
8972
8923
|
(find_pkg) =>
|
|
@@ -8976,7 +8927,7 @@ export async function addEvidenceForImports(
|
|
|
8976
8927
|
const all_exports = exportedPkgs.filter((find_pkg) =>
|
|
8977
8928
|
find_pkg.startsWith(alias),
|
|
8978
8929
|
);
|
|
8979
|
-
if (all_exports
|
|
8930
|
+
if (all_exports?.length) {
|
|
8980
8931
|
let exportedModules = new Set(all_exports);
|
|
8981
8932
|
pkg.properties = pkg.properties || [];
|
|
8982
8933
|
for (const subevidence of all_exports) {
|
|
@@ -9025,7 +8976,7 @@ export async function addEvidenceForImports(
|
|
|
9025
8976
|
pkg.evidence.occurrences = pkg.evidence.occurrences || [];
|
|
9026
8977
|
pkg.evidence.occurrences.push({
|
|
9027
8978
|
location: `${evidence.fileName}${
|
|
9028
|
-
evidence.lineNumber ?
|
|
8979
|
+
evidence.lineNumber ? `#${evidence.lineNumber}` : ""
|
|
9029
8980
|
}`,
|
|
9030
8981
|
});
|
|
9031
8982
|
importedModules.add(evidence.importedAs);
|
|
@@ -9131,7 +9082,7 @@ export function parseCmakeDotFile(dotFile, pkgType, options = {}) {
|
|
|
9131
9082
|
} else if (l.includes("// ")) {
|
|
9132
9083
|
// Indirect dependencies are represented with comments
|
|
9133
9084
|
const tmpA = l.split("// ");
|
|
9134
|
-
if (tmpA
|
|
9085
|
+
if (tmpA?.length) {
|
|
9135
9086
|
const relationship = tmpA[1];
|
|
9136
9087
|
if (relationship.includes("->")) {
|
|
9137
9088
|
const tmpB = relationship.split(" -> ");
|
|
@@ -9237,7 +9188,7 @@ export function parseCmakeLikeFile(cmakeListFile, pkgType, options = {}) {
|
|
|
9237
9188
|
) {
|
|
9238
9189
|
if (l.includes("${")) {
|
|
9239
9190
|
for (const tmplKey of Object.keys(templateValues)) {
|
|
9240
|
-
l = l.replace(
|
|
9191
|
+
l = l.replace(`\${${tmplKey}}`, templateValues[tmplKey] || "");
|
|
9241
9192
|
}
|
|
9242
9193
|
}
|
|
9243
9194
|
const tmpA = l.replace("project (", "project(").split("project(");
|
|
@@ -9257,7 +9208,7 @@ export function parseCmakeLikeFile(cmakeListFile, pkgType, options = {}) {
|
|
|
9257
9208
|
if (versionIndex > -1 && tmpB.length > versionIndex) {
|
|
9258
9209
|
parentVersion = tmpB[versionIndex + 1];
|
|
9259
9210
|
}
|
|
9260
|
-
if (parentName
|
|
9211
|
+
if (parentName?.length && !parentName.includes("$")) {
|
|
9261
9212
|
parentComponent = {
|
|
9262
9213
|
group: options.projectGroup || "",
|
|
9263
9214
|
name: parentName,
|
|
@@ -9353,7 +9304,7 @@ export function parseCmakeLikeFile(cmakeListFile, pkgType, options = {}) {
|
|
|
9353
9304
|
}
|
|
9354
9305
|
} else if (l.includes("dependency(")) {
|
|
9355
9306
|
let tmpA = l.split("dependency(");
|
|
9356
|
-
if (tmpA
|
|
9307
|
+
if (tmpA?.length) {
|
|
9357
9308
|
if (!l.includes("_dependency") && !l.includes(".dependency")) {
|
|
9358
9309
|
tmpA = tmpA[tmpA.length - 1]
|
|
9359
9310
|
.split(", ")
|
|
@@ -9508,7 +9459,7 @@ export function getCppModules(src, options, osPkgsList, epkgList) {
|
|
|
9508
9459
|
let parentComponent = undefined;
|
|
9509
9460
|
const dependsOn = [];
|
|
9510
9461
|
(epkgList || []).forEach((p) => {
|
|
9511
|
-
epkgMap[p.group
|
|
9462
|
+
epkgMap[`${p.group}/${p.name}`] = p;
|
|
9512
9463
|
});
|
|
9513
9464
|
// Let's look for any vcpkg.json file to tell us about the directory we're scanning
|
|
9514
9465
|
// users can use this file to give us a clue even if they do not use vcpkg library manager
|
|
@@ -9553,9 +9504,9 @@ export function getCppModules(src, options, osPkgsList, epkgList) {
|
|
|
9553
9504
|
// Is this a dependency we haven't seen before including the all lower and upper case version?
|
|
9554
9505
|
if (
|
|
9555
9506
|
avcpkgName &&
|
|
9556
|
-
!epkgMap[
|
|
9557
|
-
!epkgMap[
|
|
9558
|
-
!epkgMap[
|
|
9507
|
+
!epkgMap[`/${avcpkgName}`] &&
|
|
9508
|
+
!epkgMap[`/${avcpkgName.toLowerCase()}`] &&
|
|
9509
|
+
!epkgMap[`/${avcpkgName.toUpperCase()}`]
|
|
9559
9510
|
) {
|
|
9560
9511
|
const pkgPurl = new PackageURL(
|
|
9561
9512
|
pkgType,
|
|
@@ -9605,7 +9556,7 @@ export function getCppModules(src, options, osPkgsList, epkgList) {
|
|
|
9605
9556
|
parentComponent = {
|
|
9606
9557
|
group: options.projectGroup || "",
|
|
9607
9558
|
name: options.projectName || "",
|
|
9608
|
-
version:
|
|
9559
|
+
version: `${options.projectVersion}` || "latest",
|
|
9609
9560
|
type: "application",
|
|
9610
9561
|
};
|
|
9611
9562
|
const parentPurl = new PackageURL(
|
|
@@ -9656,7 +9607,7 @@ export function getCppModules(src, options, osPkgsList, epkgList) {
|
|
|
9656
9607
|
// We need to resolve the name to an os package here
|
|
9657
9608
|
const name = fileName.replace(extn, "");
|
|
9658
9609
|
let apkg = getOSPackageForFile(afile, osPkgsList) ||
|
|
9659
|
-
epkgMap[group
|
|
9610
|
+
epkgMap[`${group}/${name}`] || {
|
|
9660
9611
|
name,
|
|
9661
9612
|
group,
|
|
9662
9613
|
version: "",
|
|
@@ -9782,7 +9733,7 @@ export function parseCUsageSlice(sliceData) {
|
|
|
9782
9733
|
const slFileName = slice.fileName;
|
|
9783
9734
|
const allLines = usageData[slFileName] || new Set();
|
|
9784
9735
|
if (slice.fullName && slice.fullName.length > 3) {
|
|
9785
|
-
if (slice.code
|
|
9736
|
+
if (slice.code?.startsWith("#include")) {
|
|
9786
9737
|
usageData[slice.fullName] = new Set();
|
|
9787
9738
|
} else {
|
|
9788
9739
|
allLines.add(slice.fullName);
|
|
@@ -9833,28 +9784,24 @@ async function queryNuget(p, NUGET_URL) {
|
|
|
9833
9784
|
Number(tmpVersionArray.slice(-1)) === 0
|
|
9834
9785
|
) {
|
|
9835
9786
|
return upper;
|
|
9836
|
-
}
|
|
9787
|
+
}
|
|
9788
|
+
if (upper.split("-").length > 1) {
|
|
9837
9789
|
tmpVersionArray[tmpVersionArray.length - 1] = (
|
|
9838
9790
|
Number(tmpVersionArray.slice(-1)) - 1
|
|
9839
9791
|
).toString();
|
|
9840
9792
|
}
|
|
9841
9793
|
return tmpVersionArray.join(".");
|
|
9842
|
-
}
|
|
9843
|
-
|
|
9844
|
-
|
|
9845
|
-
|
|
9846
|
-
if (
|
|
9847
|
-
|
|
9848
|
-
|
|
9849
|
-
|
|
9850
|
-
"." +
|
|
9851
|
-
tmpVersion.minor +
|
|
9852
|
-
"." +
|
|
9853
|
-
(tmpVersion.patch - 1).toString();
|
|
9854
|
-
}
|
|
9794
|
+
}
|
|
9795
|
+
const tmpVersion = parse(upper);
|
|
9796
|
+
let version = `${tmpVersion.major}.${tmpVersion.minor}.${tmpVersion.patch}`;
|
|
9797
|
+
if (compare(version, upper) === 1) {
|
|
9798
|
+
if (tmpVersion.patch > 0) {
|
|
9799
|
+
version = `${tmpVersion.major}.${tmpVersion.minor}.${(
|
|
9800
|
+
tmpVersion.patch - 1
|
|
9801
|
+
).toString()}`;
|
|
9855
9802
|
}
|
|
9856
|
-
return version;
|
|
9857
9803
|
}
|
|
9804
|
+
return version;
|
|
9858
9805
|
}
|
|
9859
9806
|
// Coerce only when missing patch/minor version
|
|
9860
9807
|
function coerceUp(version) {
|
|
@@ -9867,7 +9814,7 @@ async function queryNuget(p, NUGET_URL) {
|
|
|
9867
9814
|
const body = [];
|
|
9868
9815
|
const newBody = [];
|
|
9869
9816
|
let res = await cdxgenAgent.get(
|
|
9870
|
-
NUGET_URL + np.name.toLowerCase()
|
|
9817
|
+
`${NUGET_URL + np.name.toLowerCase()}/index.json`,
|
|
9871
9818
|
{ responseType: "json" },
|
|
9872
9819
|
);
|
|
9873
9820
|
const items = res.body.items;
|
|
@@ -9940,7 +9887,7 @@ export async function getNugetMetadata(pkgList, dependencies = undefined) {
|
|
|
9940
9887
|
cacheKey = `${p.name}|${p.version}`;
|
|
9941
9888
|
let body = metadata_cache[cacheKey];
|
|
9942
9889
|
|
|
9943
|
-
if (body
|
|
9890
|
+
if (body?.error) {
|
|
9944
9891
|
cdepList.push(p);
|
|
9945
9892
|
continue;
|
|
9946
9893
|
}
|
|
@@ -9994,12 +9941,7 @@ export async function getNugetMetadata(pkgList, dependencies = undefined) {
|
|
|
9994
9941
|
if (body.catalogEntry.projectUrl) {
|
|
9995
9942
|
p.repository = { url: body.catalogEntry.projectUrl };
|
|
9996
9943
|
p.homepage = {
|
|
9997
|
-
url:
|
|
9998
|
-
"https://www.nuget.org/packages/" +
|
|
9999
|
-
p.name +
|
|
10000
|
-
"/" +
|
|
10001
|
-
p.version +
|
|
10002
|
-
"/",
|
|
9944
|
+
url: `https://www.nuget.org/packages/${p.name}/${p.version}/`,
|
|
10003
9945
|
};
|
|
10004
9946
|
if (
|
|
10005
9947
|
(!p.license || typeof p.license === "string") &&
|
|
@@ -10067,7 +10009,7 @@ export function addEvidenceForDotnet(pkgList, slicesFile) {
|
|
|
10067
10009
|
.forEach((aprop) => {
|
|
10068
10010
|
if (aprop.value) {
|
|
10069
10011
|
const tmpA = aprop.value.split(", ");
|
|
10070
|
-
if (tmpA
|
|
10012
|
+
if (tmpA?.length) {
|
|
10071
10013
|
tmpA.forEach((dllFile) => {
|
|
10072
10014
|
pkgFilePurlMap[dllFile] = apkg.purl;
|
|
10073
10015
|
});
|
|
@@ -10080,11 +10022,7 @@ export function addEvidenceForDotnet(pkgList, slicesFile) {
|
|
|
10080
10022
|
if (slicesData && Object.keys(slicesData)) {
|
|
10081
10023
|
if (slicesData.Dependencies) {
|
|
10082
10024
|
for (const adep of slicesData.Dependencies) {
|
|
10083
|
-
if (
|
|
10084
|
-
adep.Module &&
|
|
10085
|
-
adep.Module.endsWith(".dll") &&
|
|
10086
|
-
pkgFilePurlMap[adep.Module]
|
|
10087
|
-
) {
|
|
10025
|
+
if (adep.Module?.endsWith(".dll") && pkgFilePurlMap[adep.Module]) {
|
|
10088
10026
|
const modPurl = pkgFilePurlMap[adep.Module];
|
|
10089
10027
|
if (!purlLocationMap[modPurl]) {
|
|
10090
10028
|
purlLocationMap[modPurl] = new Set();
|
|
@@ -10096,8 +10034,7 @@ export function addEvidenceForDotnet(pkgList, slicesFile) {
|
|
|
10096
10034
|
if (slicesData.MethodCalls) {
|
|
10097
10035
|
for (const amethodCall of slicesData.MethodCalls) {
|
|
10098
10036
|
if (
|
|
10099
|
-
amethodCall.Module &&
|
|
10100
|
-
amethodCall.Module.endsWith(".dll") &&
|
|
10037
|
+
amethodCall.Module?.endsWith(".dll") &&
|
|
10101
10038
|
pkgFilePurlMap[amethodCall.Module]
|
|
10102
10039
|
) {
|
|
10103
10040
|
const modPurl = pkgFilePurlMap[amethodCall.Module];
|