@cyclonedx/cdxgen 9.9.4 → 9.9.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/README.md +4 -4
- package/analyzer.js +1 -1
- package/data/frameworks-list.json +20 -1
- package/data/known-licenses.json +78 -27
- package/docker.js +271 -30
- package/docker.test.js +38 -6
- package/evinser.js +35 -31
- package/index.js +78 -28
- package/package.json +7 -7
- package/server.js +3 -2
- package/utils.js +459 -145
- package/utils.test.js +36 -1
package/utils.js
CHANGED
|
@@ -19,7 +19,8 @@ import {
|
|
|
19
19
|
readFileSync,
|
|
20
20
|
rmSync,
|
|
21
21
|
unlinkSync,
|
|
22
|
-
writeFileSync
|
|
22
|
+
writeFileSync,
|
|
23
|
+
readdirSync
|
|
23
24
|
} from "node:fs";
|
|
24
25
|
import got from "got";
|
|
25
26
|
import Arborist from "@npmcli/arborist";
|
|
@@ -216,20 +217,10 @@ export function getLicenses(pkg, format = "xml") {
|
|
|
216
217
|
licenseContent.id = l;
|
|
217
218
|
licenseContent.url = "https://opensource.org/licenses/" + l;
|
|
218
219
|
} else if (l.startsWith("http")) {
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
.replace("http://www.opensource.org/licenses/", "")
|
|
224
|
-
.toUpperCase();
|
|
225
|
-
spdxLicenses.forEach((v) => {
|
|
226
|
-
if (v.toUpperCase() === possibleId) {
|
|
227
|
-
licenseContent.id = v;
|
|
228
|
-
}
|
|
229
|
-
});
|
|
230
|
-
}
|
|
231
|
-
if (l.includes("mit-license")) {
|
|
232
|
-
licenseContent.id = "MIT";
|
|
220
|
+
let knownLicense = getKnownLicense(l, pkg);
|
|
221
|
+
if (knownLicense) {
|
|
222
|
+
licenseContent.id = knownLicense.id;
|
|
223
|
+
licenseContent.name = knownLicense.name;
|
|
233
224
|
}
|
|
234
225
|
// We always need a name to avoid validation errors
|
|
235
226
|
// Issue: #469
|
|
@@ -251,10 +242,82 @@ export function getLicenses(pkg, format = "xml") {
|
|
|
251
242
|
return licenseContent;
|
|
252
243
|
})
|
|
253
244
|
.map((l) => ({ license: l }));
|
|
245
|
+
} else {
|
|
246
|
+
let knownLicense = getKnownLicense(undefined, pkg);
|
|
247
|
+
if (knownLicense) {
|
|
248
|
+
return [{ license: knownLicense }];
|
|
249
|
+
}
|
|
254
250
|
}
|
|
255
251
|
return undefined;
|
|
256
252
|
}
|
|
257
253
|
|
|
254
|
+
/**
|
|
255
|
+
* Method to retrieve known license by known-licenses.json
|
|
256
|
+
*
|
|
257
|
+
* @param {String} repoUrl Repository url
|
|
258
|
+
* @param {String} pkg Bom ref
|
|
259
|
+
* @return {Object>} Objetct with SPDX license id or license name
|
|
260
|
+
*/
|
|
261
|
+
export const getKnownLicense = function (licenseUrl, pkg) {
|
|
262
|
+
if (licenseUrl && licenseUrl.includes("opensource.org")) {
|
|
263
|
+
const possibleId = licenseUrl
|
|
264
|
+
.toLowerCase()
|
|
265
|
+
.replace("https://", "http://")
|
|
266
|
+
.replace("http://www.opensource.org/licenses/", "");
|
|
267
|
+
for (const spdxLicense of spdxLicenses) {
|
|
268
|
+
if (spdxLicense.toLowerCase() === possibleId) {
|
|
269
|
+
return { id: spdxLicense };
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
} else if (licenseUrl && licenseUrl.includes("apache.org")) {
|
|
273
|
+
const possibleId = licenseUrl
|
|
274
|
+
.toLowerCase()
|
|
275
|
+
.replace("https://", "http://")
|
|
276
|
+
.replace("http://www.apache.org/licenses/license-", "apache-")
|
|
277
|
+
.replace(".txt", "");
|
|
278
|
+
for (const spdxLicense of spdxLicenses) {
|
|
279
|
+
if (spdxLicense.toLowerCase() === possibleId) {
|
|
280
|
+
return { id: spdxLicense };
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
for (const akLicGroup of knownLicenses) {
|
|
285
|
+
if (
|
|
286
|
+
akLicGroup.packageNamespace === "*" ||
|
|
287
|
+
(pkg.purl && pkg.purl.startsWith(akLicGroup.packageNamespace))
|
|
288
|
+
) {
|
|
289
|
+
for (const akLic of akLicGroup.knownLicenses) {
|
|
290
|
+
if (akLic.group && akLic.name) {
|
|
291
|
+
if (akLic.group === "." && akLic.name === pkg.name) {
|
|
292
|
+
return { id: akLic.license, name: akLic.licenseName };
|
|
293
|
+
} else if (
|
|
294
|
+
pkg.group &&
|
|
295
|
+
pkg.group.includes(akLic.group) &&
|
|
296
|
+
(akLic.name === pkg.name || akLic.name === "*")
|
|
297
|
+
) {
|
|
298
|
+
return { id: akLic.license, name: akLic.licenseName };
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
if (
|
|
302
|
+
akLic.urlIncludes &&
|
|
303
|
+
licenseUrl &&
|
|
304
|
+
licenseUrl.includes(akLic.urlIncludes)
|
|
305
|
+
) {
|
|
306
|
+
return { id: akLic.license, name: akLic.licenseName };
|
|
307
|
+
}
|
|
308
|
+
if (
|
|
309
|
+
akLic.urlEndswith &&
|
|
310
|
+
licenseUrl &&
|
|
311
|
+
licenseUrl.endsWith(akLic.urlEndswith)
|
|
312
|
+
) {
|
|
313
|
+
return { id: akLic.license, name: akLic.licenseName };
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
return undefined;
|
|
319
|
+
};
|
|
320
|
+
|
|
258
321
|
/**
|
|
259
322
|
* Tries to find a file containing the license text based on commonly
|
|
260
323
|
* used naming and content types. If a candidate file is found, add
|
|
@@ -2429,7 +2492,7 @@ export const fetchPomXmlAsJson = async function ({
|
|
|
2429
2492
|
* @param {String} name
|
|
2430
2493
|
* @param {String} version
|
|
2431
2494
|
*
|
|
2432
|
-
* @return {String}
|
|
2495
|
+
* @return {Promise<String>}
|
|
2433
2496
|
*/
|
|
2434
2497
|
export const fetchPomXml = async function ({
|
|
2435
2498
|
urlPrefix,
|
|
@@ -2466,7 +2529,7 @@ export const parseLicenseEntryOrArrayFromPomXml = function (license) {
|
|
|
2466
2529
|
* @param {String} name
|
|
2467
2530
|
* @param {String} version
|
|
2468
2531
|
*
|
|
2469
|
-
* @return {String} License ID
|
|
2532
|
+
* @return {Promise<String>} License ID
|
|
2470
2533
|
*/
|
|
2471
2534
|
export const extractLicenseCommentFromPomXml = async function ({
|
|
2472
2535
|
urlPrefix,
|
|
@@ -3286,7 +3349,7 @@ export const toGitHubApiUrl = function (repoUrl, repoMetadata) {
|
|
|
3286
3349
|
*
|
|
3287
3350
|
* @param {String} repoUrl Repository url
|
|
3288
3351
|
* @param {Object} repoMetadata Object containing group and package name strings
|
|
3289
|
-
* @return {String} SPDX license id
|
|
3352
|
+
* @return {Promise<String>} SPDX license id
|
|
3290
3353
|
*/
|
|
3291
3354
|
export const getRepoLicense = async function (repoUrl, repoMetadata) {
|
|
3292
3355
|
let apiUrl = toGitHubApiUrl(repoUrl, repoMetadata);
|
|
@@ -3322,23 +3385,23 @@ export const getRepoLicense = async function (repoUrl, repoMetadata) {
|
|
|
3322
3385
|
}
|
|
3323
3386
|
}
|
|
3324
3387
|
licObj["id"] = licenseId;
|
|
3325
|
-
|
|
3388
|
+
if (licObj["id"] || licObj["name"]) {
|
|
3389
|
+
return licObj;
|
|
3390
|
+
}
|
|
3326
3391
|
}
|
|
3327
3392
|
} catch (err) {
|
|
3328
|
-
|
|
3329
|
-
|
|
3330
|
-
|
|
3331
|
-
|
|
3332
|
-
const name = repoMetadata.name;
|
|
3333
|
-
if (group && name) {
|
|
3334
|
-
for (const akLic of knownLicenses) {
|
|
3335
|
-
if (akLic.group === "." && akLic.name === name) {
|
|
3336
|
-
return akLic.license;
|
|
3337
|
-
} else if (
|
|
3338
|
-
group.includes(akLic.group) &&
|
|
3339
|
-
(akLic.name === name || akLic.name === "*")
|
|
3393
|
+
if (err && err.message) {
|
|
3394
|
+
if (
|
|
3395
|
+
err.message.includes("rate limit exceeded") &&
|
|
3396
|
+
!process.env.GITHUB_TOKEN
|
|
3340
3397
|
) {
|
|
3341
|
-
|
|
3398
|
+
console.log(
|
|
3399
|
+
"Rate limit exceeded for REST API of github.com. " +
|
|
3400
|
+
"Please ensure GITHUB_TOKEN is set as environment variable. " +
|
|
3401
|
+
"See: https://docs.github.com/en/rest/overview/rate-limits-for-the-rest-api"
|
|
3402
|
+
);
|
|
3403
|
+
} else if (!err.message.includes("404")) {
|
|
3404
|
+
console.log(err);
|
|
3342
3405
|
}
|
|
3343
3406
|
}
|
|
3344
3407
|
}
|
|
@@ -4392,12 +4455,14 @@ export const parseContainerFile = function (fileContents) {
|
|
|
4392
4455
|
const imgList = [];
|
|
4393
4456
|
|
|
4394
4457
|
let buildStageNames = [];
|
|
4395
|
-
for (
|
|
4396
|
-
|
|
4458
|
+
for (let line of fileContents.split("\n")) {
|
|
4459
|
+
line = line.trim();
|
|
4460
|
+
|
|
4461
|
+
if (line.startsWith("#")) {
|
|
4397
4462
|
continue; // skip commented out lines
|
|
4398
4463
|
}
|
|
4399
4464
|
|
|
4400
|
-
if (line.
|
|
4465
|
+
if (line.startsWith("FROM")) {
|
|
4401
4466
|
const fromStatement = line.split("FROM")[1].split("AS");
|
|
4402
4467
|
|
|
4403
4468
|
const imageStatement = fromStatement[0].trim();
|
|
@@ -4425,6 +4490,68 @@ export const parseContainerFile = function (fileContents) {
|
|
|
4425
4490
|
return imgList;
|
|
4426
4491
|
};
|
|
4427
4492
|
|
|
4493
|
+
export const parseBitbucketPipelinesFile = function (fileContents) {
|
|
4494
|
+
const imgList = [];
|
|
4495
|
+
|
|
4496
|
+
let privateImageBlockFound = false;
|
|
4497
|
+
|
|
4498
|
+
for (let line of fileContents.split("\n")) {
|
|
4499
|
+
line = line.trim();
|
|
4500
|
+
if (line.startsWith("#")) {
|
|
4501
|
+
continue; // skip commented out lines
|
|
4502
|
+
}
|
|
4503
|
+
|
|
4504
|
+
// Assume this is a private build image object
|
|
4505
|
+
if (line.startsWith("name:") && privateImageBlockFound) {
|
|
4506
|
+
const imageName = line.split("name:").pop().trim();
|
|
4507
|
+
|
|
4508
|
+
imgList.push({
|
|
4509
|
+
image: imageName
|
|
4510
|
+
});
|
|
4511
|
+
|
|
4512
|
+
privateImageBlockFound = false;
|
|
4513
|
+
}
|
|
4514
|
+
|
|
4515
|
+
// Docker image usage
|
|
4516
|
+
if (line.startsWith("image:")) {
|
|
4517
|
+
const imageName = line.split("image:").pop().trim();
|
|
4518
|
+
|
|
4519
|
+
/**
|
|
4520
|
+
* Assume this is a private build image object
|
|
4521
|
+
* See: https://support.atlassian.com/bitbucket-cloud/docs/use-docker-images-as-build-environments/#Using-private-build-images
|
|
4522
|
+
*/
|
|
4523
|
+
if (imageName === "") {
|
|
4524
|
+
privateImageBlockFound = true;
|
|
4525
|
+
continue;
|
|
4526
|
+
} else {
|
|
4527
|
+
/**
|
|
4528
|
+
* Assume this is a public build image
|
|
4529
|
+
* See: https://support.atlassian.com/bitbucket-cloud/docs/use-docker-images-as-build-environments/#Using-public-build-images
|
|
4530
|
+
*/
|
|
4531
|
+
|
|
4532
|
+
imgList.push({
|
|
4533
|
+
image: imageName
|
|
4534
|
+
});
|
|
4535
|
+
}
|
|
4536
|
+
}
|
|
4537
|
+
|
|
4538
|
+
// Pipe usage
|
|
4539
|
+
if (line.startsWith("- pipe:")) {
|
|
4540
|
+
let pipeName = line.split("- pipe:").pop().trim();
|
|
4541
|
+
|
|
4542
|
+
if (pipeName.startsWith("docker://")) {
|
|
4543
|
+
pipeName = pipeName.replace("docker://", "");
|
|
4544
|
+
}
|
|
4545
|
+
|
|
4546
|
+
imgList.push({
|
|
4547
|
+
image: pipeName
|
|
4548
|
+
});
|
|
4549
|
+
}
|
|
4550
|
+
}
|
|
4551
|
+
|
|
4552
|
+
return imgList;
|
|
4553
|
+
};
|
|
4554
|
+
|
|
4428
4555
|
export const parseContainerSpecData = function (dcData) {
|
|
4429
4556
|
const pkgList = [];
|
|
4430
4557
|
const imgList = [];
|
|
@@ -4617,8 +4744,13 @@ export const parseOpenapiSpecData = function (oaData) {
|
|
|
4617
4744
|
} catch (e) {
|
|
4618
4745
|
return servlist;
|
|
4619
4746
|
}
|
|
4620
|
-
|
|
4621
|
-
const
|
|
4747
|
+
|
|
4748
|
+
const name =
|
|
4749
|
+
oaData.info && oaData.info.title
|
|
4750
|
+
? oaData.info.title.replace(/ /g, "-")
|
|
4751
|
+
: "default-name";
|
|
4752
|
+
const version =
|
|
4753
|
+
oaData.info && oaData.info.version ? oaData.info.version : "latest";
|
|
4622
4754
|
const aservice = {
|
|
4623
4755
|
"bom-ref": `urn:service:${name}:${version}`,
|
|
4624
4756
|
name,
|
|
@@ -5404,7 +5536,7 @@ export const parseComposerLock = function (pkgLockFile) {
|
|
|
5404
5536
|
if (existsSync(pkgLockFile)) {
|
|
5405
5537
|
let lockData = {};
|
|
5406
5538
|
try {
|
|
5407
|
-
lockData = JSON.parse(readFileSync(pkgLockFile, "
|
|
5539
|
+
lockData = JSON.parse(readFileSync(pkgLockFile, { encoding: "utf-8" }));
|
|
5408
5540
|
} catch (e) {
|
|
5409
5541
|
console.error("Invalid composer.lock file:", pkgLockFile);
|
|
5410
5542
|
return [];
|
|
@@ -5473,7 +5605,7 @@ export const parseSbtTree = (sbtTreeFile) => {
|
|
|
5473
5605
|
const dependenciesList = [];
|
|
5474
5606
|
const keys_cache = {};
|
|
5475
5607
|
const level_trees = {};
|
|
5476
|
-
const tmpA = readFileSync(sbtTreeFile, "utf-8").split("\n");
|
|
5608
|
+
const tmpA = readFileSync(sbtTreeFile, { encoding: "utf-8" }).split("\n");
|
|
5477
5609
|
let last_level = 0;
|
|
5478
5610
|
let last_purl = "";
|
|
5479
5611
|
let stack = [];
|
|
@@ -5605,7 +5737,9 @@ export const parseSbtTree = (sbtTreeFile) => {
|
|
|
5605
5737
|
export const parseSbtLock = function (pkgLockFile) {
|
|
5606
5738
|
const pkgList = [];
|
|
5607
5739
|
if (existsSync(pkgLockFile)) {
|
|
5608
|
-
const lockData = JSON.parse(
|
|
5740
|
+
const lockData = JSON.parse(
|
|
5741
|
+
readFileSync(pkgLockFile, { encoding: "utf-8" })
|
|
5742
|
+
);
|
|
5609
5743
|
if (lockData && lockData.dependencies) {
|
|
5610
5744
|
for (const pkg of lockData.dependencies) {
|
|
5611
5745
|
const artifacts = pkg.artifacts || undefined;
|
|
@@ -6062,7 +6196,9 @@ export const parseSwiftResolved = (resolvedFile) => {
|
|
|
6062
6196
|
const pkgList = [];
|
|
6063
6197
|
if (existsSync(resolvedFile)) {
|
|
6064
6198
|
try {
|
|
6065
|
-
const pkgData = JSON.parse(
|
|
6199
|
+
const pkgData = JSON.parse(
|
|
6200
|
+
readFileSync(resolvedFile, { encoding: "utf-8" })
|
|
6201
|
+
);
|
|
6066
6202
|
let resolvedList = [];
|
|
6067
6203
|
if (pkgData.pins) {
|
|
6068
6204
|
resolvedList = pkgData.pins;
|
|
@@ -6255,7 +6391,7 @@ export const collectJarNS = function (jarPath, pomPathMap = {}) {
|
|
|
6255
6391
|
}
|
|
6256
6392
|
}
|
|
6257
6393
|
if (existsSync(pomname)) {
|
|
6258
|
-
pomData = parsePomXml(readFileSync(pomname, "utf-8"));
|
|
6394
|
+
pomData = parsePomXml(readFileSync(pomname, { encoding: "utf-8" }));
|
|
6259
6395
|
if (pomData) {
|
|
6260
6396
|
const purlObj = new PackageURL(
|
|
6261
6397
|
"maven",
|
|
@@ -6514,12 +6650,67 @@ export const parseJarManifest = function (jarMetadata) {
|
|
|
6514
6650
|
return metadata;
|
|
6515
6651
|
};
|
|
6516
6652
|
|
|
6653
|
+
export const parsePomProperties = function (pomProperties) {
|
|
6654
|
+
const properties = {};
|
|
6655
|
+
if (!pomProperties) {
|
|
6656
|
+
return properties;
|
|
6657
|
+
}
|
|
6658
|
+
pomProperties.split("\n").forEach((l) => {
|
|
6659
|
+
l = l.replace("\r", "");
|
|
6660
|
+
if (l.includes("=")) {
|
|
6661
|
+
const tmpA = l.split("=");
|
|
6662
|
+
if (tmpA && tmpA.length === 2) {
|
|
6663
|
+
properties[tmpA[0]] = tmpA[1].replace("\r", "");
|
|
6664
|
+
}
|
|
6665
|
+
}
|
|
6666
|
+
});
|
|
6667
|
+
return properties;
|
|
6668
|
+
};
|
|
6669
|
+
|
|
6517
6670
|
export const encodeForPurl = (s) => {
|
|
6518
6671
|
return s && !s.includes("%40")
|
|
6519
6672
|
? encodeURIComponent(s).replace(/%3A/g, ":").replace(/%2F/g, "/")
|
|
6520
6673
|
: s;
|
|
6521
6674
|
};
|
|
6522
6675
|
|
|
6676
|
+
/**
|
|
6677
|
+
* Method to get pom properties from maven directory
|
|
6678
|
+
*
|
|
6679
|
+
* @param {string} mavenDir Path to maven directory
|
|
6680
|
+
*
|
|
6681
|
+
* @return array with pom properties
|
|
6682
|
+
*/
|
|
6683
|
+
export const getPomPropertiesFromMavenDir = function (mavenDir) {
|
|
6684
|
+
let pomProperties = {};
|
|
6685
|
+
if (existsSync(mavenDir) && lstatSync(mavenDir).isDirectory()) {
|
|
6686
|
+
let mavenDirEntries = readdirSync(mavenDir, { withFileTypes: true });
|
|
6687
|
+
mavenDirEntries.forEach((mavenDirEntry) => {
|
|
6688
|
+
if (mavenDirEntry.isDirectory()) {
|
|
6689
|
+
let groupDirEntries = readdirSync(
|
|
6690
|
+
join(mavenDirEntry.path, mavenDirEntry.name),
|
|
6691
|
+
{ withFileTypes: true }
|
|
6692
|
+
);
|
|
6693
|
+
groupDirEntries.forEach((groupDirEntry) => {
|
|
6694
|
+
if (groupDirEntry.isDirectory()) {
|
|
6695
|
+
let pomPropertiesFile = join(
|
|
6696
|
+
groupDirEntry.path,
|
|
6697
|
+
groupDirEntry.name,
|
|
6698
|
+
"pom.properties"
|
|
6699
|
+
);
|
|
6700
|
+
if (existsSync(pomPropertiesFile)) {
|
|
6701
|
+
const pomPropertiesString = readFileSync(pomPropertiesFile, {
|
|
6702
|
+
encoding: "utf-8"
|
|
6703
|
+
});
|
|
6704
|
+
pomProperties = parsePomProperties(pomPropertiesString);
|
|
6705
|
+
}
|
|
6706
|
+
}
|
|
6707
|
+
});
|
|
6708
|
+
}
|
|
6709
|
+
});
|
|
6710
|
+
}
|
|
6711
|
+
return pomProperties;
|
|
6712
|
+
};
|
|
6713
|
+
|
|
6523
6714
|
/**
|
|
6524
6715
|
* Method to extract a war or ear file
|
|
6525
6716
|
*
|
|
@@ -6601,13 +6792,14 @@ export const extractJarArchive = function (
|
|
|
6601
6792
|
}
|
|
6602
6793
|
const manifestDir = join(tempDir, "META-INF");
|
|
6603
6794
|
const manifestFile = join(manifestDir, "MANIFEST.MF");
|
|
6795
|
+
const mavenDir = join(manifestDir, "maven");
|
|
6604
6796
|
let jarResult = {
|
|
6605
6797
|
status: 1
|
|
6606
6798
|
};
|
|
6607
6799
|
if (existsSync(pomname)) {
|
|
6608
6800
|
jarResult = { status: 0 };
|
|
6609
6801
|
} else {
|
|
6610
|
-
jarResult = spawnSync("jar", ["-xf", jf], {
|
|
6802
|
+
jarResult = spawnSync("jar", ["-xf", jf, "META-INF"], {
|
|
6611
6803
|
encoding: "utf-8",
|
|
6612
6804
|
cwd: tempDir,
|
|
6613
6805
|
shell: isWin,
|
|
@@ -6617,29 +6809,42 @@ export const extractJarArchive = function (
|
|
|
6617
6809
|
if (jarResult.status !== 0) {
|
|
6618
6810
|
console.error(jarResult.stdout, jarResult.stderr);
|
|
6619
6811
|
} else {
|
|
6620
|
-
|
|
6812
|
+
// When maven descriptor is available take group, name and version from pom.properties
|
|
6813
|
+
// META-INF/maven/${groupId}/${artifactId}/pom.properties
|
|
6814
|
+
// see https://maven.apache.org/shared/maven-archiver/index.html
|
|
6815
|
+
const pomProperties = getPomPropertiesFromMavenDir(mavenDir);
|
|
6816
|
+
let group = pomProperties["groupId"],
|
|
6817
|
+
name = pomProperties["artifactId"],
|
|
6818
|
+
version = pomProperties["version"],
|
|
6819
|
+
confidence = 1,
|
|
6820
|
+
technique = "manifest-analysis";
|
|
6821
|
+
if ((!group || !name || !version) && existsSync(manifestFile)) {
|
|
6822
|
+
confidence = 0.8;
|
|
6621
6823
|
const jarMetadata = parseJarManifest(
|
|
6622
6824
|
readFileSync(manifestFile, {
|
|
6623
6825
|
encoding: "utf-8"
|
|
6624
6826
|
})
|
|
6625
6827
|
);
|
|
6626
|
-
|
|
6828
|
+
group =
|
|
6829
|
+
group ||
|
|
6627
6830
|
jarMetadata["Extension-Name"] ||
|
|
6628
6831
|
jarMetadata["Implementation-Vendor-Id"] ||
|
|
6629
6832
|
jarMetadata["Bundle-SymbolicName"] ||
|
|
6630
6833
|
jarMetadata["Bundle-Vendor"] ||
|
|
6631
6834
|
jarMetadata["Automatic-Module-Name"] ||
|
|
6632
6835
|
"";
|
|
6633
|
-
|
|
6836
|
+
version =
|
|
6837
|
+
version ||
|
|
6634
6838
|
jarMetadata["Bundle-Version"] ||
|
|
6635
6839
|
jarMetadata["Implementation-Version"] ||
|
|
6636
6840
|
jarMetadata["Specification-Version"];
|
|
6637
6841
|
if (version && version.includes(" ")) {
|
|
6638
6842
|
version = version.split(" ")[0];
|
|
6639
6843
|
}
|
|
6640
|
-
let name = "";
|
|
6641
6844
|
// Prefer jar filename to construct name and version
|
|
6642
6845
|
if (!name || !version || name === "" || version === "") {
|
|
6846
|
+
confidence = 0.5;
|
|
6847
|
+
technique = "filename";
|
|
6643
6848
|
const tmpA = jarname.split("-");
|
|
6644
6849
|
if (tmpA && tmpA.length > 1) {
|
|
6645
6850
|
const lastPart = tmpA[tmpA.length - 1];
|
|
@@ -6688,56 +6893,56 @@ export const extractJarArchive = function (
|
|
|
6688
6893
|
break;
|
|
6689
6894
|
}
|
|
6690
6895
|
}
|
|
6691
|
-
if
|
|
6692
|
-
|
|
6693
|
-
|
|
6694
|
-
|
|
6896
|
+
// if group is empty use name as group
|
|
6897
|
+
group = group === "." ? name : group || name;
|
|
6898
|
+
}
|
|
6899
|
+
if (name && version) {
|
|
6900
|
+
let apkg = {
|
|
6901
|
+
group: group ? encodeForPurl(group) : "",
|
|
6902
|
+
name: name ? encodeForPurl(name) : "",
|
|
6903
|
+
version,
|
|
6904
|
+
purl: new PackageURL(
|
|
6905
|
+
"maven",
|
|
6695
6906
|
group,
|
|
6696
|
-
name
|
|
6907
|
+
name,
|
|
6697
6908
|
version,
|
|
6698
|
-
|
|
6699
|
-
|
|
6700
|
-
|
|
6701
|
-
|
|
6702
|
-
|
|
6703
|
-
|
|
6704
|
-
|
|
6705
|
-
|
|
6706
|
-
|
|
6707
|
-
|
|
6708
|
-
|
|
6709
|
-
|
|
6710
|
-
|
|
6711
|
-
|
|
6712
|
-
|
|
6713
|
-
|
|
6714
|
-
|
|
6715
|
-
|
|
6716
|
-
|
|
6717
|
-
|
|
6718
|
-
}
|
|
6719
|
-
|
|
6720
|
-
|
|
6721
|
-
|
|
6722
|
-
|
|
6723
|
-
|
|
6724
|
-
|
|
6725
|
-
|
|
6726
|
-
|
|
6727
|
-
|
|
6728
|
-
jarNSMapping[apkg.purl]
|
|
6729
|
-
|
|
6730
|
-
|
|
6731
|
-
|
|
6732
|
-
|
|
6733
|
-
|
|
6734
|
-
|
|
6735
|
-
}
|
|
6736
|
-
pkgList.push(apkg);
|
|
6737
|
-
} else {
|
|
6738
|
-
if (DEBUG_MODE) {
|
|
6739
|
-
console.log(`Ignored jar ${jarname}`, jarMetadata, name, version);
|
|
6740
|
-
}
|
|
6909
|
+
{ type: "jar" },
|
|
6910
|
+
null
|
|
6911
|
+
).toString(),
|
|
6912
|
+
evidence: {
|
|
6913
|
+
identity: {
|
|
6914
|
+
field: "purl",
|
|
6915
|
+
confidence: confidence,
|
|
6916
|
+
methods: [
|
|
6917
|
+
{
|
|
6918
|
+
technique: technique,
|
|
6919
|
+
confidence: confidence,
|
|
6920
|
+
value: jarname
|
|
6921
|
+
}
|
|
6922
|
+
]
|
|
6923
|
+
}
|
|
6924
|
+
},
|
|
6925
|
+
properties: [
|
|
6926
|
+
{
|
|
6927
|
+
name: "SrcFile",
|
|
6928
|
+
value: jarname
|
|
6929
|
+
}
|
|
6930
|
+
]
|
|
6931
|
+
};
|
|
6932
|
+
if (
|
|
6933
|
+
jarNSMapping &&
|
|
6934
|
+
jarNSMapping[apkg.purl] &&
|
|
6935
|
+
jarNSMapping[apkg.purl].namespaces
|
|
6936
|
+
) {
|
|
6937
|
+
apkg.properties.push({
|
|
6938
|
+
name: "Namespaces",
|
|
6939
|
+
value: jarNSMapping[apkg.purl].namespaces.join("\n")
|
|
6940
|
+
});
|
|
6941
|
+
}
|
|
6942
|
+
pkgList.push(apkg);
|
|
6943
|
+
} else {
|
|
6944
|
+
if (DEBUG_MODE) {
|
|
6945
|
+
console.log(`Ignored jar ${jarname}`, name, version);
|
|
6741
6946
|
}
|
|
6742
6947
|
}
|
|
6743
6948
|
try {
|
|
@@ -6929,6 +7134,7 @@ export const getMavenCommand = (srcPath, rootPath) => {
|
|
|
6929
7134
|
let isWrapperReady = false;
|
|
6930
7135
|
let isWrapperFound = false;
|
|
6931
7136
|
let findMavenFile = "mvnw";
|
|
7137
|
+
let mavenWrapperCmd = null;
|
|
6932
7138
|
if (platform() == "win32") {
|
|
6933
7139
|
findMavenFile = "mvnw.bat";
|
|
6934
7140
|
if (
|
|
@@ -6947,7 +7153,7 @@ export const getMavenCommand = (srcPath, rootPath) => {
|
|
|
6947
7153
|
} catch (e) {
|
|
6948
7154
|
// continue regardless of error
|
|
6949
7155
|
}
|
|
6950
|
-
|
|
7156
|
+
mavenWrapperCmd = resolve(join(srcPath, findMavenFile));
|
|
6951
7157
|
isWrapperFound = true;
|
|
6952
7158
|
} else if (rootPath && existsSync(join(rootPath, findMavenFile))) {
|
|
6953
7159
|
// Check if the root directory has a wrapper script
|
|
@@ -6956,7 +7162,7 @@ export const getMavenCommand = (srcPath, rootPath) => {
|
|
|
6956
7162
|
} catch (e) {
|
|
6957
7163
|
// continue regardless of error
|
|
6958
7164
|
}
|
|
6959
|
-
|
|
7165
|
+
mavenWrapperCmd = resolve(join(rootPath, findMavenFile));
|
|
6960
7166
|
isWrapperFound = true;
|
|
6961
7167
|
}
|
|
6962
7168
|
if (isWrapperFound) {
|
|
@@ -6965,14 +7171,15 @@ export const getMavenCommand = (srcPath, rootPath) => {
|
|
|
6965
7171
|
"Testing the wrapper script by invoking wrapper:wrapper task"
|
|
6966
7172
|
);
|
|
6967
7173
|
}
|
|
6968
|
-
const result = spawnSync(
|
|
7174
|
+
const result = spawnSync(mavenWrapperCmd, ["wrapper:wrapper"], {
|
|
6969
7175
|
encoding: "utf-8",
|
|
6970
7176
|
cwd: rootPath,
|
|
6971
7177
|
timeout: TIMEOUT_MS,
|
|
6972
7178
|
shell: isWin
|
|
6973
7179
|
});
|
|
6974
|
-
if (!result.error) {
|
|
7180
|
+
if (!result.error && !result.status) {
|
|
6975
7181
|
isWrapperReady = true;
|
|
7182
|
+
mavenCmd = mavenWrapperCmd;
|
|
6976
7183
|
} else {
|
|
6977
7184
|
if (DEBUG_MODE) {
|
|
6978
7185
|
console.log(
|
|
@@ -7115,7 +7322,9 @@ export const findAppModules = function (
|
|
|
7115
7322
|
];
|
|
7116
7323
|
executeAtom(src, args);
|
|
7117
7324
|
if (existsSync(slicesFile)) {
|
|
7118
|
-
const slicesData = JSON.parse(readFileSync(slicesFile),
|
|
7325
|
+
const slicesData = JSON.parse(readFileSync(slicesFile), {
|
|
7326
|
+
encoding: "utf-8"
|
|
7327
|
+
});
|
|
7119
7328
|
if (slicesData && Object.keys(slicesData) && slicesData.modules) {
|
|
7120
7329
|
retList = slicesData.modules;
|
|
7121
7330
|
} else {
|
|
@@ -7588,7 +7797,7 @@ export const componentSorter = (a, b) => {
|
|
|
7588
7797
|
};
|
|
7589
7798
|
|
|
7590
7799
|
export const parseCmakeDotFile = (dotFile, pkgType, options = {}) => {
|
|
7591
|
-
const dotGraphData = readFileSync(dotFile, "utf-8");
|
|
7800
|
+
const dotGraphData = readFileSync(dotFile, { encoding: "utf-8" });
|
|
7592
7801
|
const pkgList = [];
|
|
7593
7802
|
const dependenciesMap = {};
|
|
7594
7803
|
const pkgBomRefMap = {};
|
|
@@ -7697,12 +7906,13 @@ export const parseCmakeDotFile = (dotFile, pkgType, options = {}) => {
|
|
|
7697
7906
|
};
|
|
7698
7907
|
|
|
7699
7908
|
export const parseCmakeLikeFile = (cmakeListFile, pkgType, options = {}) => {
|
|
7700
|
-
let cmakeListData = readFileSync(cmakeListFile, "utf-8");
|
|
7909
|
+
let cmakeListData = readFileSync(cmakeListFile, { encoding: "utf-8" });
|
|
7701
7910
|
const pkgList = [];
|
|
7702
7911
|
const pkgAddedMap = {};
|
|
7703
7912
|
const versionSpecifiersMap = {};
|
|
7704
7913
|
const versionsMap = {};
|
|
7705
7914
|
let parentComponent = {};
|
|
7915
|
+
const templateValues = {};
|
|
7706
7916
|
cmakeListData = cmakeListData
|
|
7707
7917
|
.replace(/^ {2}/g, "")
|
|
7708
7918
|
.replace(/\(\r\n/g, "(")
|
|
@@ -7717,7 +7927,20 @@ export const parseCmakeLikeFile = (cmakeListFile, pkgType, options = {}) => {
|
|
|
7717
7927
|
let group = "";
|
|
7718
7928
|
let path = undefined;
|
|
7719
7929
|
let name_list = [];
|
|
7720
|
-
if (l.startsWith("
|
|
7930
|
+
if (l.startsWith("set")) {
|
|
7931
|
+
const tmpA = l.replace("set(", "").replace(")", "").trim().split(" ");
|
|
7932
|
+
if (tmpA && tmpA.length === 2) {
|
|
7933
|
+
templateValues[tmpA[0]] = tmpA[1];
|
|
7934
|
+
}
|
|
7935
|
+
} else if (
|
|
7936
|
+
l.startsWith("project") &&
|
|
7937
|
+
!Object.keys(parentComponent).length
|
|
7938
|
+
) {
|
|
7939
|
+
if (l.includes("${")) {
|
|
7940
|
+
for (const tmplKey of Object.keys(templateValues)) {
|
|
7941
|
+
l = l.replace("${" + tmplKey + "}", templateValues[tmplKey] || "");
|
|
7942
|
+
}
|
|
7943
|
+
}
|
|
7721
7944
|
const tmpA = l.replace("project (", "project(").split("project(");
|
|
7722
7945
|
if (tmpA && tmpA.length > 1) {
|
|
7723
7946
|
const tmpB = (tmpA[1] || "")
|
|
@@ -7735,7 +7958,7 @@ export const parseCmakeLikeFile = (cmakeListFile, pkgType, options = {}) => {
|
|
|
7735
7958
|
if (versionIndex > -1 && tmpB.length > versionIndex) {
|
|
7736
7959
|
parentVersion = tmpB[versionIndex + 1];
|
|
7737
7960
|
}
|
|
7738
|
-
if (parentName && parentName.length) {
|
|
7961
|
+
if (parentName && parentName.length && !parentName.includes("$")) {
|
|
7739
7962
|
parentComponent = {
|
|
7740
7963
|
group: options.projectGroup || "",
|
|
7741
7964
|
name: parentName,
|
|
@@ -7917,7 +8140,7 @@ export const parseCmakeLikeFile = (cmakeListFile, pkgType, options = {}) => {
|
|
|
7917
8140
|
methods: [
|
|
7918
8141
|
{
|
|
7919
8142
|
technique: "source-code-analysis",
|
|
7920
|
-
confidence: 0,
|
|
8143
|
+
confidence: 0.5,
|
|
7921
8144
|
value: `Filename ${cmakeListFile}`
|
|
7922
8145
|
}
|
|
7923
8146
|
]
|
|
@@ -7951,7 +8174,7 @@ export const getOSPackageForFile = (afile, osPkgsList) => {
|
|
|
7951
8174
|
ospkg.evidence = {
|
|
7952
8175
|
identity: {
|
|
7953
8176
|
field: "purl",
|
|
7954
|
-
confidence: 0,
|
|
8177
|
+
confidence: 0.8,
|
|
7955
8178
|
methods: [
|
|
7956
8179
|
{
|
|
7957
8180
|
technique: "filename",
|
|
@@ -7985,47 +8208,122 @@ export const getCppModules = (src, options, osPkgsList, epkgList) => {
|
|
|
7985
8208
|
const epkgMap = {};
|
|
7986
8209
|
let parentComponent = undefined;
|
|
7987
8210
|
const dependsOn = [];
|
|
8211
|
+
(epkgList || []).forEach((p) => {
|
|
8212
|
+
epkgMap[p.group + "/" + p.name] = p;
|
|
8213
|
+
});
|
|
7988
8214
|
// Let's look for any vcpkg.json file to tell us about the directory we're scanning
|
|
7989
8215
|
// users can use this file to give us a clue even if they do not use vcpkg library manager
|
|
7990
8216
|
if (existsSync(join(src, "vcpkg.json"))) {
|
|
7991
|
-
const vcPkgData = JSON.parse(
|
|
7992
|
-
|
|
7993
|
-
|
|
7994
|
-
|
|
7995
|
-
vcPkgData.name &&
|
|
7996
|
-
vcPkgData.version
|
|
7997
|
-
) {
|
|
8217
|
+
const vcPkgData = JSON.parse(
|
|
8218
|
+
readFileSync(join(src, "vcpkg.json"), { encoding: "utf-8" })
|
|
8219
|
+
);
|
|
8220
|
+
if (vcPkgData && Object.keys(vcPkgData).length && vcPkgData.name) {
|
|
7998
8221
|
const parentPurl = new PackageURL(
|
|
7999
8222
|
pkgType,
|
|
8000
8223
|
"",
|
|
8001
8224
|
vcPkgData.name,
|
|
8002
|
-
vcPkgData.version,
|
|
8225
|
+
vcPkgData.version || "",
|
|
8003
8226
|
null,
|
|
8004
8227
|
null
|
|
8005
8228
|
).toString();
|
|
8006
8229
|
parentComponent = {
|
|
8007
8230
|
name: vcPkgData.name,
|
|
8008
|
-
version: vcPkgData.version,
|
|
8231
|
+
version: vcPkgData.version || "",
|
|
8009
8232
|
description: vcPkgData.description,
|
|
8010
8233
|
license: vcPkgData.license,
|
|
8011
8234
|
purl: parentPurl,
|
|
8235
|
+
type: "application",
|
|
8012
8236
|
"bom-ref": decodeURIComponent(parentPurl)
|
|
8013
8237
|
};
|
|
8014
8238
|
if (vcPkgData.homepage) {
|
|
8015
8239
|
parentComponent.homepage = { url: vcPkgData.homepage };
|
|
8016
8240
|
}
|
|
8017
|
-
|
|
8241
|
+
// Are there any dependencies declared in vcpkg.json
|
|
8242
|
+
if (vcPkgData.dependencies && Array.isArray(vcPkgData.dependencies)) {
|
|
8243
|
+
for (const avcdep of vcPkgData.dependencies) {
|
|
8244
|
+
let avcpkgName = undefined;
|
|
8245
|
+
let scope = undefined;
|
|
8246
|
+
if (typeof avcdep === "string" || avcdep instanceof String) {
|
|
8247
|
+
avcpkgName = avcdep;
|
|
8248
|
+
} else if (Object.keys(avcdep).length && avcdep.name) {
|
|
8249
|
+
avcpkgName = avcdep.name;
|
|
8250
|
+
if (avcdep.host) {
|
|
8251
|
+
scope = "optional";
|
|
8252
|
+
}
|
|
8253
|
+
}
|
|
8254
|
+
// Is this a dependency we haven't seen before including the all lower and upper case version?
|
|
8255
|
+
if (
|
|
8256
|
+
avcpkgName &&
|
|
8257
|
+
!epkgMap["/" + avcpkgName] &&
|
|
8258
|
+
!epkgMap["/" + avcpkgName.toLowerCase()] &&
|
|
8259
|
+
!epkgMap["/" + avcpkgName.toUpperCase()]
|
|
8260
|
+
) {
|
|
8261
|
+
const pkgPurl = new PackageURL(
|
|
8262
|
+
pkgType,
|
|
8263
|
+
"",
|
|
8264
|
+
avcpkgName,
|
|
8265
|
+
"",
|
|
8266
|
+
null,
|
|
8267
|
+
null
|
|
8268
|
+
).toString();
|
|
8269
|
+
const apkg = {
|
|
8270
|
+
group: "",
|
|
8271
|
+
name: avcpkgName,
|
|
8272
|
+
type: pkgType,
|
|
8273
|
+
version: "",
|
|
8274
|
+
purl: pkgPurl,
|
|
8275
|
+
scope,
|
|
8276
|
+
"bom-ref": decodeURIComponent(pkgPurl),
|
|
8277
|
+
evidence: {
|
|
8278
|
+
identity: {
|
|
8279
|
+
field: "purl",
|
|
8280
|
+
confidence: 0.5,
|
|
8281
|
+
methods: [
|
|
8282
|
+
{
|
|
8283
|
+
technique: "source-code-analysis",
|
|
8284
|
+
confidence: 0.5,
|
|
8285
|
+
value: `Filename ${join(src, "vcpkg.json")}`
|
|
8286
|
+
}
|
|
8287
|
+
]
|
|
8288
|
+
}
|
|
8289
|
+
}
|
|
8290
|
+
};
|
|
8291
|
+
if (!pkgAddedMap[avcpkgName]) {
|
|
8292
|
+
pkgList.push(apkg);
|
|
8293
|
+
dependsOn.push(apkg["bom-ref"]);
|
|
8294
|
+
pkgAddedMap[avcpkgName] = true;
|
|
8295
|
+
}
|
|
8296
|
+
}
|
|
8297
|
+
}
|
|
8298
|
+
}
|
|
8299
|
+
} // if
|
|
8018
8300
|
} else if (existsSync(join(src, "CMakeLists.txt"))) {
|
|
8019
8301
|
const retMap = parseCmakeLikeFile(join(src, "CMakeLists.txt"), pkgType);
|
|
8020
8302
|
if (retMap.parentComponent && Object.keys(retMap.parentComponent).length) {
|
|
8021
8303
|
parentComponent = retMap.parentComponent;
|
|
8022
8304
|
}
|
|
8305
|
+
} else if (options.projectName && options.projectVersion) {
|
|
8306
|
+
parentComponent = {
|
|
8307
|
+
group: options.projectGroup || "",
|
|
8308
|
+
name: options.projectName || "",
|
|
8309
|
+
version: "" + options.projectVersion || "latest",
|
|
8310
|
+
type: "application"
|
|
8311
|
+
};
|
|
8312
|
+
const parentPurl = new PackageURL(
|
|
8313
|
+
pkgType,
|
|
8314
|
+
parentComponent.group,
|
|
8315
|
+
parentComponent.name,
|
|
8316
|
+
parentComponent.version,
|
|
8317
|
+
null,
|
|
8318
|
+
null
|
|
8319
|
+
).toString();
|
|
8320
|
+
parentComponent.purl = parentPurl;
|
|
8321
|
+
parentComponent["bom-ref"] = decodeURIComponent(parentPurl);
|
|
8023
8322
|
}
|
|
8024
|
-
(epkgList || []).forEach((p) => {
|
|
8025
|
-
epkgMap[p.name] = p;
|
|
8026
|
-
});
|
|
8027
8323
|
if (options.usagesSlicesFile && existsSync(options.usagesSlicesFile)) {
|
|
8028
|
-
sliceData = JSON.parse(
|
|
8324
|
+
sliceData = JSON.parse(
|
|
8325
|
+
readFileSync(options.usagesSlicesFile, { encoding: "utf-8" })
|
|
8326
|
+
);
|
|
8029
8327
|
if (DEBUG_MODE) {
|
|
8030
8328
|
console.log("Re-using existing slices file", options.usagesSlicesFile);
|
|
8031
8329
|
}
|
|
@@ -8038,7 +8336,9 @@ export const getCppModules = (src, options, osPkgsList, epkgList) => {
|
|
|
8038
8336
|
);
|
|
8039
8337
|
}
|
|
8040
8338
|
const usageData = parseCUsageSlice(sliceData);
|
|
8041
|
-
for (
|
|
8339
|
+
for (let afile of Object.keys(usageData)) {
|
|
8340
|
+
// Normalize windows separator
|
|
8341
|
+
afile = afile.replace("..\\", "").replace(/\\/g, "/");
|
|
8042
8342
|
let fileName = basename(afile);
|
|
8043
8343
|
if (!fileName || !fileName.length) {
|
|
8044
8344
|
continue;
|
|
@@ -8057,14 +8357,14 @@ export const getCppModules = (src, options, osPkgsList, epkgList) => {
|
|
|
8057
8357
|
// We need to resolve the name to an os package here
|
|
8058
8358
|
let name = fileName.replace(extn, "");
|
|
8059
8359
|
let apkg = getOSPackageForFile(afile, osPkgsList) ||
|
|
8060
|
-
epkgMap[name] || {
|
|
8360
|
+
epkgMap[group + "/" + name] || {
|
|
8061
8361
|
name,
|
|
8062
8362
|
group,
|
|
8063
8363
|
version: "",
|
|
8064
8364
|
type: pkgType
|
|
8065
8365
|
};
|
|
8066
8366
|
// If this is a relative file, there is a good chance we can reuse the project group
|
|
8067
|
-
if (!afile.startsWith(_sep)) {
|
|
8367
|
+
if (!afile.startsWith(_sep) && !group.length) {
|
|
8068
8368
|
group = options.projectGroup || "";
|
|
8069
8369
|
}
|
|
8070
8370
|
if (!apkg.purl) {
|
|
@@ -8092,9 +8392,16 @@ export const getCppModules = (src, options, osPkgsList, epkgList) => {
|
|
|
8092
8392
|
apkg["bom-ref"] = decodeURIComponent(apkg["purl"]);
|
|
8093
8393
|
}
|
|
8094
8394
|
if (usageData[afile]) {
|
|
8095
|
-
const usymbols = Array.from(usageData[afile])
|
|
8096
|
-
|
|
8097
|
-
|
|
8395
|
+
const usymbols = Array.from(usageData[afile])
|
|
8396
|
+
.filter(
|
|
8397
|
+
(v) =>
|
|
8398
|
+
!v.startsWith("<") &&
|
|
8399
|
+
!v.startsWith("__") &&
|
|
8400
|
+
v !== "main" &&
|
|
8401
|
+
!v.includes("anonymous_") &&
|
|
8402
|
+
!v.includes(afile)
|
|
8403
|
+
)
|
|
8404
|
+
.sort();
|
|
8098
8405
|
if (!apkg["properties"] && usymbols.length) {
|
|
8099
8406
|
apkg["properties"] = [
|
|
8100
8407
|
{ name: "ImportedSymbols", value: usymbols.join(", ") }
|
|
@@ -8141,7 +8448,9 @@ export const getCppModules = (src, options, osPkgsList, epkgList) => {
|
|
|
8141
8448
|
: [];
|
|
8142
8449
|
return {
|
|
8143
8450
|
parentComponent,
|
|
8144
|
-
pkgList,
|
|
8451
|
+
pkgList: pkgList.sort(function (a, b) {
|
|
8452
|
+
return a.purl.localeCompare(b.purl);
|
|
8453
|
+
}),
|
|
8145
8454
|
dependenciesList
|
|
8146
8455
|
};
|
|
8147
8456
|
};
|
|
@@ -8174,34 +8483,21 @@ export const parseCUsageSlice = (sliceData) => {
|
|
|
8174
8483
|
continue;
|
|
8175
8484
|
}
|
|
8176
8485
|
const slFileName = slice.fileName;
|
|
8177
|
-
const slLineNumber = slice.lineNumber || 0;
|
|
8178
8486
|
const allLines = usageData[slFileName] || new Set();
|
|
8179
8487
|
if (slice.fullName && slice.fullName.length > 3) {
|
|
8180
|
-
allLines.add(slice.fullName + "|" + slLineNumber);
|
|
8181
8488
|
if (slice.code && slice.code.startsWith("#include")) {
|
|
8182
8489
|
usageData[slice.fullName] = new Set();
|
|
8490
|
+
} else {
|
|
8491
|
+
allLines.add(slice.fullName);
|
|
8183
8492
|
}
|
|
8184
8493
|
}
|
|
8185
8494
|
for (const ausage of slice.usages) {
|
|
8186
|
-
if (ausage.targetObj.resolvedMethod) {
|
|
8187
|
-
allLines.add(ausage.targetObj.resolvedMethod + "|" + slLineNumber);
|
|
8188
|
-
} else {
|
|
8189
|
-
const targetObjName = ausage.targetObj.name.replace(/\n/g, " ");
|
|
8190
|
-
// We need to still filter out <global>, <clinit> style targets
|
|
8191
|
-
if (
|
|
8192
|
-
ausage.targetObj.lineNumber === slLineNumber ||
|
|
8193
|
-
targetObjName.startsWith("<") ||
|
|
8194
|
-
(slice.fullName.length > 3 &&
|
|
8195
|
-
targetObjName.includes(slice.fullName))
|
|
8196
|
-
) {
|
|
8197
|
-
continue;
|
|
8198
|
-
}
|
|
8199
|
-
allLines.add(targetObjName + "|" + slLineNumber);
|
|
8200
|
-
}
|
|
8201
8495
|
let calls = ausage?.invokedCalls || [];
|
|
8202
8496
|
calls = calls.concat(ausage?.argToCalls || []);
|
|
8203
8497
|
for (const acall of calls) {
|
|
8204
|
-
|
|
8498
|
+
if (!acall.resolvedMethod.includes("->")) {
|
|
8499
|
+
allLines.add(acall.resolvedMethod);
|
|
8500
|
+
}
|
|
8205
8501
|
}
|
|
8206
8502
|
}
|
|
8207
8503
|
if (Array.from(allLines).length) {
|
|
@@ -8393,6 +8689,13 @@ export const getNugetMetadata = async function (
|
|
|
8393
8689
|
p.license = findLicenseId(body.catalogEntry.licenseExpression);
|
|
8394
8690
|
} else if (body.catalogEntry.licenseUrl) {
|
|
8395
8691
|
p.license = findLicenseId(body.catalogEntry.licenseUrl);
|
|
8692
|
+
if (
|
|
8693
|
+
typeof p.license === "string" &&
|
|
8694
|
+
p.license.includes("://github.com/")
|
|
8695
|
+
) {
|
|
8696
|
+
p.license =
|
|
8697
|
+
(await getRepoLicense(p.license, undefined)) || p.license;
|
|
8698
|
+
}
|
|
8396
8699
|
}
|
|
8397
8700
|
if (body.catalogEntry.projectUrl) {
|
|
8398
8701
|
p.repository = { url: body.catalogEntry.projectUrl };
|
|
@@ -8404,6 +8707,17 @@ export const getNugetMetadata = async function (
|
|
|
8404
8707
|
p.version +
|
|
8405
8708
|
"/"
|
|
8406
8709
|
};
|
|
8710
|
+
if (
|
|
8711
|
+
(!p.license || typeof p.license === "string") &&
|
|
8712
|
+
typeof p.repository.url === "string" &&
|
|
8713
|
+
p.repository.url.includes("://github.com/")
|
|
8714
|
+
) {
|
|
8715
|
+
// license couldn't be properly identified and is still a url,
|
|
8716
|
+
// therefore trying to resolve license via repository
|
|
8717
|
+
p.license =
|
|
8718
|
+
(await getRepoLicense(p.repository.url, undefined)) ||
|
|
8719
|
+
p.license;
|
|
8720
|
+
}
|
|
8407
8721
|
}
|
|
8408
8722
|
cdepList.push(p);
|
|
8409
8723
|
}
|