@cyclonedx/cdxgen 9.11.5 → 10.0.0
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 +6 -5
- package/analyzer.js +1 -0
- package/bin/cdxgen.js +140 -142
- package/bin/repl.js +5 -5
- package/bin/verify.js +1 -1
- package/binary.js +19 -13
- package/cbomutils.js +39 -0
- package/cbomutils.test.js +8 -0
- package/data/README.md +1 -0
- package/data/cbomosdb-queries.json +68 -0
- package/data/cosdb-queries.json +1 -1
- package/display.js +2 -2
- package/docker.js +15 -3
- package/envcontext.js +302 -0
- package/envcontext.test.js +31 -0
- package/evinser.js +9 -8
- package/index.js +229 -486
- package/package.json +7 -8
- package/protobom.test.js +1 -1
- package/server.js +2 -1
- package/utils.js +225 -162
- package/utils.test.js +37 -32
- package/validator.js +5 -4
package/utils.js
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { globSync } from "glob";
|
|
2
2
|
import { homedir, platform, tmpdir } from "node:os";
|
|
3
|
+
import process from "node:process";
|
|
4
|
+
import { Buffer } from "node:buffer";
|
|
3
5
|
import {
|
|
4
6
|
basename,
|
|
5
7
|
delimiter as _delimiter,
|
|
@@ -27,7 +29,7 @@ import got from "got";
|
|
|
27
29
|
import Arborist from "@npmcli/arborist";
|
|
28
30
|
import path from "node:path";
|
|
29
31
|
import { xml2js } from "xml-js";
|
|
30
|
-
import { fileURLToPath } from "node:url";
|
|
32
|
+
import { fileURLToPath, URL } from "node:url";
|
|
31
33
|
import { load } from "cheerio";
|
|
32
34
|
import { load as _load } from "js-yaml";
|
|
33
35
|
import { spawnSync } from "node:child_process";
|
|
@@ -51,9 +53,9 @@ let url = import.meta.url;
|
|
|
51
53
|
if (!url.startsWith("file://")) {
|
|
52
54
|
url = new URL(`file://${import.meta.url}`).toString();
|
|
53
55
|
}
|
|
54
|
-
const dirNameStr = import.meta ? dirname(fileURLToPath(url)) : __dirname;
|
|
55
|
-
const isWin = platform() === "win32";
|
|
56
|
-
const isMac = platform() === "darwin";
|
|
56
|
+
export const dirNameStr = import.meta ? dirname(fileURLToPath(url)) : __dirname;
|
|
57
|
+
export const isWin = platform() === "win32";
|
|
58
|
+
export const isMac = platform() === "darwin";
|
|
57
59
|
export let ATOM_DB = join(homedir(), ".local", "share", ".atomdb");
|
|
58
60
|
if (isWin) {
|
|
59
61
|
ATOM_DB = join(homedir(), "AppData", "Local", ".atomdb");
|
|
@@ -62,34 +64,36 @@ if (isWin) {
|
|
|
62
64
|
}
|
|
63
65
|
|
|
64
66
|
const licenseMapping = JSON.parse(
|
|
65
|
-
readFileSync(join(dirNameStr, "data", "lic-mapping.json"))
|
|
67
|
+
readFileSync(join(dirNameStr, "data", "lic-mapping.json"), "utf-8")
|
|
66
68
|
);
|
|
67
69
|
const vendorAliases = JSON.parse(
|
|
68
|
-
readFileSync(join(dirNameStr, "data", "vendor-alias.json"))
|
|
70
|
+
readFileSync(join(dirNameStr, "data", "vendor-alias.json"), "utf-8")
|
|
69
71
|
);
|
|
70
72
|
const spdxLicenses = JSON.parse(
|
|
71
|
-
readFileSync(join(dirNameStr, "data", "spdx-licenses.json"))
|
|
73
|
+
readFileSync(join(dirNameStr, "data", "spdx-licenses.json"), "utf-8")
|
|
72
74
|
);
|
|
73
75
|
const knownLicenses = JSON.parse(
|
|
74
|
-
readFileSync(join(dirNameStr, "data", "known-licenses.json"))
|
|
76
|
+
readFileSync(join(dirNameStr, "data", "known-licenses.json"), "utf-8")
|
|
75
77
|
);
|
|
76
78
|
const mesonWrapDB = JSON.parse(
|
|
77
|
-
readFileSync(join(dirNameStr, "data", "wrapdb-releases.json"))
|
|
79
|
+
readFileSync(join(dirNameStr, "data", "wrapdb-releases.json"), "utf-8")
|
|
78
80
|
);
|
|
79
81
|
export const frameworksList = JSON.parse(
|
|
80
|
-
readFileSync(join(dirNameStr, "data", "frameworks-list.json"))
|
|
82
|
+
readFileSync(join(dirNameStr, "data", "frameworks-list.json"), "utf-8")
|
|
83
|
+
);
|
|
84
|
+
const selfPJson = JSON.parse(
|
|
85
|
+
readFileSync(join(dirNameStr, "package.json"), "utf-8")
|
|
81
86
|
);
|
|
82
|
-
const selfPJson = JSON.parse(readFileSync(join(dirNameStr, "package.json")));
|
|
83
87
|
const _version = selfPJson.version;
|
|
84
88
|
|
|
85
89
|
// Refer to contrib/py-modules.py for a script to generate this list
|
|
86
90
|
// The script needs to be used once every few months to update this list
|
|
87
91
|
const PYTHON_STD_MODULES = JSON.parse(
|
|
88
|
-
readFileSync(join(dirNameStr, "data", "python-stdlib.json"))
|
|
92
|
+
readFileSync(join(dirNameStr, "data", "python-stdlib.json"), "utf-8")
|
|
89
93
|
);
|
|
90
94
|
// Mapping between modules and package names
|
|
91
95
|
const PYPI_MODULE_PACKAGE_MAPPING = JSON.parse(
|
|
92
|
-
readFileSync(join(dirNameStr, "data", "pypi-pkg-aliases.json"))
|
|
96
|
+
readFileSync(join(dirNameStr, "data", "pypi-pkg-aliases.json"), "utf-8")
|
|
93
97
|
);
|
|
94
98
|
|
|
95
99
|
// Debug mode flag
|
|
@@ -122,14 +126,14 @@ export const FETCH_LICENSE =
|
|
|
122
126
|
process.env.FETCH_LICENSE &&
|
|
123
127
|
["true", "1"].includes(process.env.FETCH_LICENSE);
|
|
124
128
|
|
|
125
|
-
//
|
|
129
|
+
// Whether search.maven.org will be used to identify jars without maven metadata; default, if unset shall be 'true'
|
|
126
130
|
export const SEARCH_MAVEN_ORG =
|
|
127
131
|
!process.env.SEARCH_MAVEN_ORG ||
|
|
128
132
|
["true", "1"].includes(process.env.SEARCH_MAVEN_ORG);
|
|
129
133
|
|
|
130
134
|
// circuit breaker for search maven.org
|
|
131
135
|
let search_maven_org_errors = 0;
|
|
132
|
-
const MAX_SEARCH_MAVEN_ORG_ERRORS =
|
|
136
|
+
const MAX_SEARCH_MAVEN_ORG_ERRORS = 1;
|
|
133
137
|
|
|
134
138
|
// circuit breaker for get repo license
|
|
135
139
|
let get_repo_license_errors = 0;
|
|
@@ -137,12 +141,70 @@ const MAX_GET_REPO_LICENSE_ERRORS = 5;
|
|
|
137
141
|
|
|
138
142
|
const MAX_LICENSE_ID_LENGTH = 100;
|
|
139
143
|
|
|
140
|
-
let
|
|
144
|
+
export let JAVA_CMD = "java";
|
|
145
|
+
if (process.env.JAVA_CMD) {
|
|
146
|
+
JAVA_CMD = process.env.JAVA_CMD;
|
|
147
|
+
} else if (
|
|
148
|
+
process.env.JAVA_HOME &&
|
|
149
|
+
existsSync(process.env.JAVA_HOME) &&
|
|
150
|
+
existsSync(join(process.env.JAVA_HOME, "bin", "java"))
|
|
151
|
+
) {
|
|
152
|
+
JAVA_CMD = join(process.env.JAVA_HOME, "bin", "java");
|
|
153
|
+
}
|
|
154
|
+
export let PYTHON_CMD = "python";
|
|
141
155
|
if (process.env.PYTHON_CMD) {
|
|
142
156
|
PYTHON_CMD = process.env.PYTHON_CMD;
|
|
143
157
|
} else if (process.env.CONDA_PYTHON_EXE) {
|
|
144
158
|
PYTHON_CMD = process.env.CONDA_PYTHON_EXE;
|
|
145
159
|
}
|
|
160
|
+
export let DOTNET_CMD = "dotnet";
|
|
161
|
+
if (process.env.DOTNET_CMD) {
|
|
162
|
+
DOTNET_CMD = process.env.DOTNET_CMD;
|
|
163
|
+
}
|
|
164
|
+
export let NODE_CMD = "node";
|
|
165
|
+
if (process.env.NODE_CMD) {
|
|
166
|
+
NODE_CMD = process.env.NODE_CMD;
|
|
167
|
+
}
|
|
168
|
+
export let NPM_CMD = "npm";
|
|
169
|
+
if (process.env.NPM_CMD) {
|
|
170
|
+
NPM_CMD = process.env.NPM_CMD;
|
|
171
|
+
}
|
|
172
|
+
export let YARN_CMD = "yarn";
|
|
173
|
+
if (process.env.YARN_CMD) {
|
|
174
|
+
YARN_CMD = process.env.YARN_CMD;
|
|
175
|
+
}
|
|
176
|
+
export let GCC_CMD = "gcc";
|
|
177
|
+
if (process.env.GCC_CMD) {
|
|
178
|
+
GCC_CMD = process.env.GCC_CMD;
|
|
179
|
+
}
|
|
180
|
+
export let RUSTC_CMD = "rustc";
|
|
181
|
+
if (process.env.RUSTC_CMD) {
|
|
182
|
+
RUSTC_CMD = process.env.RUSTC_CMD;
|
|
183
|
+
}
|
|
184
|
+
export let GO_CMD = "go";
|
|
185
|
+
if (process.env.GO_CMD) {
|
|
186
|
+
GO_CMD = process.env.GO_CMD;
|
|
187
|
+
}
|
|
188
|
+
export let CARGO_CMD = "cargo";
|
|
189
|
+
if (process.env.CARGO_CMD) {
|
|
190
|
+
CARGO_CMD = process.env.CARGO_CMD;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
// Clojure CLI
|
|
194
|
+
export let CLJ_CMD = "clj";
|
|
195
|
+
if (process.env.CLJ_CMD) {
|
|
196
|
+
CLJ_CMD = process.env.CLJ_CMD;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
export let LEIN_CMD = "lein";
|
|
200
|
+
if (process.env.LEIN_CMD) {
|
|
201
|
+
LEIN_CMD = process.env.LEIN_CMD;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
export let SWIFT_CMD = "swift";
|
|
205
|
+
if (process.env.SWIFT_CMD) {
|
|
206
|
+
SWIFT_CMD = process.env.SWIFT_CMD;
|
|
207
|
+
}
|
|
146
208
|
|
|
147
209
|
// Custom user-agent for cdxgen
|
|
148
210
|
export const cdxgenAgent = got.extend({
|
|
@@ -181,7 +243,7 @@ export const getAllFiles = function (dirPath, pattern, options = {}) {
|
|
|
181
243
|
*
|
|
182
244
|
* @param {string} dirPath Root directory for search
|
|
183
245
|
* @param {string} pattern Glob pattern (eg: *.gradle)
|
|
184
|
-
* @param {
|
|
246
|
+
* @param {Array} ignoreList Directory patterns to ignore
|
|
185
247
|
*/
|
|
186
248
|
export const getAllFilesWithIgnore = function (dirPath, pattern, ignoreList) {
|
|
187
249
|
try {
|
|
@@ -190,7 +252,6 @@ export const getAllFilesWithIgnore = function (dirPath, pattern, ignoreList) {
|
|
|
190
252
|
absolute: true,
|
|
191
253
|
nocase: true,
|
|
192
254
|
nodir: true,
|
|
193
|
-
strict: true,
|
|
194
255
|
dot: pattern.startsWith(".") ? true : false,
|
|
195
256
|
follow: false,
|
|
196
257
|
ignore: ignoreList
|
|
@@ -213,7 +274,7 @@ const toBase64 = (hexString) => {
|
|
|
213
274
|
* and url of the license object, otherwise, set the 'name' of the license
|
|
214
275
|
* object.
|
|
215
276
|
*/
|
|
216
|
-
export function getLicenses(pkg
|
|
277
|
+
export function getLicenses(pkg) {
|
|
217
278
|
let license = pkg.license && (pkg.license.type || pkg.license);
|
|
218
279
|
if (license) {
|
|
219
280
|
if (!Array.isArray(license)) {
|
|
@@ -231,7 +292,7 @@ export function getLicenses(pkg, format = "xml") {
|
|
|
231
292
|
licenseContent.id = l;
|
|
232
293
|
licenseContent.url = "https://opensource.org/licenses/" + l;
|
|
233
294
|
} else if (l.startsWith("http")) {
|
|
234
|
-
|
|
295
|
+
const knownLicense = getKnownLicense(l, pkg);
|
|
235
296
|
if (knownLicense) {
|
|
236
297
|
licenseContent.id = knownLicense.id;
|
|
237
298
|
licenseContent.name = knownLicense.name;
|
|
@@ -251,13 +312,13 @@ export function getLicenses(pkg, format = "xml") {
|
|
|
251
312
|
return undefined;
|
|
252
313
|
}
|
|
253
314
|
if (!licenseContent.id) {
|
|
254
|
-
addLicenseText(pkg, l, licenseContent
|
|
315
|
+
addLicenseText(pkg, l, licenseContent);
|
|
255
316
|
}
|
|
256
317
|
return licenseContent;
|
|
257
318
|
})
|
|
258
319
|
.map((l) => ({ license: l }));
|
|
259
320
|
} else {
|
|
260
|
-
|
|
321
|
+
const knownLicense = getKnownLicense(undefined, pkg);
|
|
261
322
|
if (knownLicense) {
|
|
262
323
|
return [{ license: knownLicense }];
|
|
263
324
|
}
|
|
@@ -268,9 +329,9 @@ export function getLicenses(pkg, format = "xml") {
|
|
|
268
329
|
/**
|
|
269
330
|
* Method to retrieve known license by known-licenses.json
|
|
270
331
|
*
|
|
271
|
-
* @param {String}
|
|
332
|
+
* @param {String} licenseUrl Repository url
|
|
272
333
|
* @param {String} pkg Bom ref
|
|
273
|
-
* @return {Object
|
|
334
|
+
* @return {Object} Objetct with SPDX license id or license name
|
|
274
335
|
*/
|
|
275
336
|
export const getKnownLicense = function (licenseUrl, pkg) {
|
|
276
337
|
if (licenseUrl && licenseUrl.includes("opensource.org")) {
|
|
@@ -337,7 +398,7 @@ export const getKnownLicense = function (licenseUrl, pkg) {
|
|
|
337
398
|
* used naming and content types. If a candidate file is found, add
|
|
338
399
|
* the text to the license text object and stop.
|
|
339
400
|
*/
|
|
340
|
-
export function addLicenseText(pkg, l, licenseContent
|
|
401
|
+
export function addLicenseText(pkg, l, licenseContent) {
|
|
341
402
|
const licenseFilenames = [
|
|
342
403
|
"LICENSE",
|
|
343
404
|
"License",
|
|
@@ -366,8 +427,7 @@ export function addLicenseText(pkg, l, licenseContent, format = "xml") {
|
|
|
366
427
|
if (existsSync(licenseFilepath)) {
|
|
367
428
|
licenseContent.text = readLicenseText(
|
|
368
429
|
licenseFilepath,
|
|
369
|
-
licenseContentType
|
|
370
|
-
format
|
|
430
|
+
licenseContentType
|
|
371
431
|
);
|
|
372
432
|
return;
|
|
373
433
|
}
|
|
@@ -380,26 +440,14 @@ export function addLicenseText(pkg, l, licenseContent, format = "xml") {
|
|
|
380
440
|
* Read the file from the given path to the license text object and includes
|
|
381
441
|
* content-type attribute, if not default. Returns the license text object.
|
|
382
442
|
*/
|
|
383
|
-
export function readLicenseText(
|
|
384
|
-
licenseFilepath,
|
|
385
|
-
licenseContentType,
|
|
386
|
-
format = "xml"
|
|
387
|
-
) {
|
|
443
|
+
export function readLicenseText(licenseFilepath, licenseContentType) {
|
|
388
444
|
const licenseText = readFileSync(licenseFilepath, "utf8");
|
|
389
445
|
if (licenseText) {
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
licenseContentText["@content-type"] = licenseContentType;
|
|
394
|
-
}
|
|
395
|
-
return licenseContentText;
|
|
396
|
-
} else {
|
|
397
|
-
const licenseContentText = { content: licenseText };
|
|
398
|
-
if (licenseContentType !== "text/plain") {
|
|
399
|
-
licenseContentText["contentType"] = licenseContentType;
|
|
400
|
-
}
|
|
401
|
-
return licenseContentText;
|
|
446
|
+
const licenseContentText = { content: licenseText };
|
|
447
|
+
if (licenseContentType !== "text/plain") {
|
|
448
|
+
licenseContentText["contentType"] = licenseContentType;
|
|
402
449
|
}
|
|
450
|
+
return licenseContentText;
|
|
403
451
|
}
|
|
404
452
|
return null;
|
|
405
453
|
}
|
|
@@ -681,9 +729,9 @@ export const parsePkgLock = async (pkgLockFile, options = {}) => {
|
|
|
681
729
|
pkgList.push(pkg);
|
|
682
730
|
|
|
683
731
|
// retrieve workspace node pkglists
|
|
684
|
-
|
|
732
|
+
const workspaceDependsOn = [];
|
|
685
733
|
if (node.fsChildren && node.fsChildren.size > 0) {
|
|
686
|
-
for (
|
|
734
|
+
for (const workspaceNode of node.fsChildren) {
|
|
687
735
|
const {
|
|
688
736
|
pkgList: childPkgList,
|
|
689
737
|
dependenciesList: childDependenciesList
|
|
@@ -708,10 +756,10 @@ export const parsePkgLock = async (pkgLockFile, options = {}) => {
|
|
|
708
756
|
|
|
709
757
|
// this handles the case when a node has ["dependencies"] key in a package-lock.json
|
|
710
758
|
// for a node. We exclude the root node because it's already been handled
|
|
711
|
-
|
|
759
|
+
const childrenDependsOn = [];
|
|
712
760
|
if (node != rootNode) {
|
|
713
761
|
for (const child of node.children) {
|
|
714
|
-
|
|
762
|
+
const childNode = child[1];
|
|
715
763
|
const {
|
|
716
764
|
pkgList: childPkgList,
|
|
717
765
|
dependenciesList: childDependenciesList
|
|
@@ -749,7 +797,7 @@ export const parsePkgLock = async (pkgLockFile, options = {}) => {
|
|
|
749
797
|
// which isn't installed
|
|
750
798
|
// Bug #795. At times, npm loses the integrity node completely and such packages are getting missed out
|
|
751
799
|
// To keep things safe, we include these packages.
|
|
752
|
-
|
|
800
|
+
const edgeToIntegrity = edge.to ? edge.to.integrity : undefined;
|
|
753
801
|
if (!edgeToIntegrity) {
|
|
754
802
|
// This hack is required to fix the package name
|
|
755
803
|
targetName = node.name.replace(/-cjs$/, "");
|
|
@@ -1562,7 +1610,7 @@ export const parseMinJs = async (minJsFile) => {
|
|
|
1562
1610
|
*/
|
|
1563
1611
|
export const parsePom = function (pomFile) {
|
|
1564
1612
|
const deps = [];
|
|
1565
|
-
const xmlData = readFileSync(pomFile);
|
|
1613
|
+
const xmlData = readFileSync(pomFile, "utf-8");
|
|
1566
1614
|
const project = xml2js(xmlData, {
|
|
1567
1615
|
compact: true,
|
|
1568
1616
|
spaces: 4,
|
|
@@ -2428,7 +2476,7 @@ export const getMvnMetadata = async function (pkgList, jarNSMapping = {}) {
|
|
|
2428
2476
|
});
|
|
2429
2477
|
}
|
|
2430
2478
|
}
|
|
2431
|
-
|
|
2479
|
+
const group = p.group || "";
|
|
2432
2480
|
// If the package already has key metadata skip querying maven
|
|
2433
2481
|
if (group && p.name && p.version && !FETCH_LICENSE) {
|
|
2434
2482
|
cdepList.push(p);
|
|
@@ -2565,7 +2613,7 @@ export const fetchPomXml = async function ({
|
|
|
2565
2613
|
name,
|
|
2566
2614
|
version
|
|
2567
2615
|
}) {
|
|
2568
|
-
|
|
2616
|
+
const fullUrl = composePomXmlUrl({ urlPrefix, group, name, version });
|
|
2569
2617
|
const res = await cdxgenAgent.get(fullUrl);
|
|
2570
2618
|
return res.body;
|
|
2571
2619
|
};
|
|
@@ -2654,7 +2702,7 @@ export const guessPypiMatchingVersion = (versionsList, versionSpecifiers) => {
|
|
|
2654
2702
|
return -c;
|
|
2655
2703
|
};
|
|
2656
2704
|
// Iterate in the "reverse" order
|
|
2657
|
-
for (
|
|
2705
|
+
for (const rv of versionsList.sort(comparator)) {
|
|
2658
2706
|
if (satisfies(coerce(rv), versionSpecifiers, true)) {
|
|
2659
2707
|
return rv;
|
|
2660
2708
|
}
|
|
@@ -2720,8 +2768,8 @@ export const getPyMetadata = async function (pkgList, fetchDepsInfo) {
|
|
|
2720
2768
|
if (body.info.classifiers) {
|
|
2721
2769
|
for (const c of body.info.classifiers) {
|
|
2722
2770
|
if (c.startsWith("License :: ")) {
|
|
2723
|
-
|
|
2724
|
-
|
|
2771
|
+
const licenseName = c.split("::").slice(-1)[0].trim();
|
|
2772
|
+
const licenseId = findLicenseId(licenseName);
|
|
2725
2773
|
if (licenseId && !p.license.includes(licenseId)) {
|
|
2726
2774
|
p.license.push(licenseId);
|
|
2727
2775
|
}
|
|
@@ -2729,7 +2777,7 @@ export const getPyMetadata = async function (pkgList, fetchDepsInfo) {
|
|
|
2729
2777
|
}
|
|
2730
2778
|
}
|
|
2731
2779
|
if (body.info.license) {
|
|
2732
|
-
|
|
2780
|
+
const licenseId = findLicenseId(body.info.license);
|
|
2733
2781
|
if (licenseId && !p.license.includes(licenseId)) {
|
|
2734
2782
|
p.license.push(licenseId);
|
|
2735
2783
|
}
|
|
@@ -2939,7 +2987,7 @@ export const parsePiplockData = async function (lockData) {
|
|
|
2939
2987
|
export const parsePyProjectToml = (tomlFile) => {
|
|
2940
2988
|
// Do we need a toml npm package at some point?
|
|
2941
2989
|
const tomlData = readFileSync(tomlFile, { encoding: "utf-8" });
|
|
2942
|
-
|
|
2990
|
+
const pkg = {};
|
|
2943
2991
|
if (!tomlData) {
|
|
2944
2992
|
return pkg;
|
|
2945
2993
|
}
|
|
@@ -2947,7 +2995,7 @@ export const parsePyProjectToml = (tomlFile) => {
|
|
|
2947
2995
|
l = l.replace("\r", "");
|
|
2948
2996
|
if (l.indexOf("=") > -1) {
|
|
2949
2997
|
const tmpA = l.split("=");
|
|
2950
|
-
|
|
2998
|
+
const key = tmpA[0].trim();
|
|
2951
2999
|
let value = tmpA[1].trim().replace(/["']/g, "");
|
|
2952
3000
|
switch (key) {
|
|
2953
3001
|
case "description":
|
|
@@ -3080,7 +3128,7 @@ export const parsePoetrylockData = async function (lockData, lockFile) {
|
|
|
3080
3128
|
});
|
|
3081
3129
|
pkgList = await getPyMetadata(pkgList, false);
|
|
3082
3130
|
for (const key of Object.keys(depsMap)) {
|
|
3083
|
-
|
|
3131
|
+
const dependsOnList = [];
|
|
3084
3132
|
for (const adep of Array.from(depsMap[key])) {
|
|
3085
3133
|
if (adep.startsWith("pkg:")) {
|
|
3086
3134
|
dependsOnList.push(adep);
|
|
@@ -3426,10 +3474,10 @@ export const toGitHubApiUrl = function (repoUrl, repoMetadata) {
|
|
|
3426
3474
|
* @return {Promise<String>} SPDX license id
|
|
3427
3475
|
*/
|
|
3428
3476
|
export const getRepoLicense = async function (repoUrl, repoMetadata) {
|
|
3429
|
-
|
|
3477
|
+
const apiUrl = toGitHubApiUrl(repoUrl, repoMetadata);
|
|
3430
3478
|
// Perform github lookups
|
|
3431
3479
|
if (apiUrl && get_repo_license_errors < MAX_GET_REPO_LICENSE_ERRORS) {
|
|
3432
|
-
|
|
3480
|
+
const licenseUrl = apiUrl + "/license";
|
|
3433
3481
|
const headers = {};
|
|
3434
3482
|
if (process.env.GITHUB_TOKEN) {
|
|
3435
3483
|
headers["Authorization"] = "Bearer " + process.env.GITHUB_TOKEN;
|
|
@@ -3849,7 +3897,7 @@ export const parseGosumData = async function (gosumData) {
|
|
|
3849
3897
|
}
|
|
3850
3898
|
const pkgs = gosumData.split("\n");
|
|
3851
3899
|
for (const l of pkgs) {
|
|
3852
|
-
|
|
3900
|
+
const m = l.replace("\r", "");
|
|
3853
3901
|
// look for lines containing go.mod
|
|
3854
3902
|
if (m.indexOf("go.mod") > -1) {
|
|
3855
3903
|
const tmpA = m.split(" ");
|
|
@@ -4534,7 +4582,7 @@ export const recurseImageNameLookup = (keyValueObj, pkgList, imgList) => {
|
|
|
4534
4582
|
export const parseContainerFile = function (fileContents) {
|
|
4535
4583
|
const imgList = [];
|
|
4536
4584
|
|
|
4537
|
-
|
|
4585
|
+
const buildStageNames = [];
|
|
4538
4586
|
for (let line of fileContents.split("\n")) {
|
|
4539
4587
|
line = line.trim();
|
|
4540
4588
|
|
|
@@ -5190,7 +5238,7 @@ export const parseNupkg = async function (nupkgFile) {
|
|
|
5190
5238
|
return await parseNuspecData(nupkgFile, nuspecData);
|
|
5191
5239
|
};
|
|
5192
5240
|
|
|
5193
|
-
export const parseNuspecData =
|
|
5241
|
+
export const parseNuspecData = function (nupkgFile, nuspecData) {
|
|
5194
5242
|
const pkgList = [];
|
|
5195
5243
|
const pkg = { group: "" };
|
|
5196
5244
|
let npkg = undefined;
|
|
@@ -5243,7 +5291,7 @@ export const parseNuspecData = async function (nupkgFile, nuspecData) {
|
|
|
5243
5291
|
return pkgList;
|
|
5244
5292
|
};
|
|
5245
5293
|
|
|
5246
|
-
export const parseCsPkgData =
|
|
5294
|
+
export const parseCsPkgData = function (pkgData) {
|
|
5247
5295
|
const pkgList = [];
|
|
5248
5296
|
if (!pkgData) {
|
|
5249
5297
|
return pkgList;
|
|
@@ -5270,7 +5318,7 @@ export const parseCsPkgData = async function (pkgData) {
|
|
|
5270
5318
|
return pkgList;
|
|
5271
5319
|
};
|
|
5272
5320
|
|
|
5273
|
-
export const parseCsProjData =
|
|
5321
|
+
export const parseCsProjData = function (csProjData, projFile) {
|
|
5274
5322
|
const pkgList = [];
|
|
5275
5323
|
if (!csProjData) {
|
|
5276
5324
|
return pkgList;
|
|
@@ -5362,10 +5410,7 @@ export const parseCsProjData = async function (csProjData, projFile) {
|
|
|
5362
5410
|
return pkgList;
|
|
5363
5411
|
};
|
|
5364
5412
|
|
|
5365
|
-
export const parseCsProjAssetsData =
|
|
5366
|
-
csProjData,
|
|
5367
|
-
assetsJsonFile
|
|
5368
|
-
) {
|
|
5413
|
+
export const parseCsProjAssetsData = function (csProjData, assetsJsonFile) {
|
|
5369
5414
|
// extract name, operator, version from .NET package representation
|
|
5370
5415
|
// like "NLog >= 4.5.0"
|
|
5371
5416
|
function extractNameOperatorVersion(inputStr) {
|
|
@@ -5384,7 +5429,7 @@ export const parseCsProjAssetsData = async function (
|
|
|
5384
5429
|
}
|
|
5385
5430
|
|
|
5386
5431
|
const pkgList = [];
|
|
5387
|
-
|
|
5432
|
+
const dependenciesList = [];
|
|
5388
5433
|
let rootPkg = {};
|
|
5389
5434
|
// This tracks the resolved version
|
|
5390
5435
|
const pkgNameVersionMap = {};
|
|
@@ -5411,7 +5456,7 @@ export const parseCsProjAssetsData = async function (
|
|
|
5411
5456
|
"bom-ref": decodeURIComponent(purlString)
|
|
5412
5457
|
};
|
|
5413
5458
|
pkgList.push(rootPkg);
|
|
5414
|
-
|
|
5459
|
+
const rootPkgDeps = new Set();
|
|
5415
5460
|
|
|
5416
5461
|
// create root pkg deps
|
|
5417
5462
|
if (csProjData.targets && csProjData.projectFileDependencyGroups) {
|
|
@@ -5467,7 +5512,7 @@ export const parseCsProjAssetsData = async function (
|
|
|
5467
5512
|
null,
|
|
5468
5513
|
null
|
|
5469
5514
|
).toString();
|
|
5470
|
-
|
|
5515
|
+
const pkg = {
|
|
5471
5516
|
group: "",
|
|
5472
5517
|
name: name,
|
|
5473
5518
|
version: version,
|
|
@@ -5541,7 +5586,7 @@ export const parseCsProjAssetsData = async function (
|
|
|
5541
5586
|
if (!pkgNameVersionMap[p + framework]) {
|
|
5542
5587
|
continue;
|
|
5543
5588
|
}
|
|
5544
|
-
|
|
5589
|
+
const dversion = pkgNameVersionMap[p + framework];
|
|
5545
5590
|
const ipurl = new PackageURL(
|
|
5546
5591
|
"nuget",
|
|
5547
5592
|
"",
|
|
@@ -5577,7 +5622,7 @@ export const parseCsProjAssetsData = async function (
|
|
|
5577
5622
|
};
|
|
5578
5623
|
};
|
|
5579
5624
|
|
|
5580
|
-
export const parseCsPkgLockData =
|
|
5625
|
+
export const parseCsPkgLockData = function (csLockData, pkgLockFile) {
|
|
5581
5626
|
const pkgList = [];
|
|
5582
5627
|
const dependenciesList = [];
|
|
5583
5628
|
const rootList = [];
|
|
@@ -5668,7 +5713,7 @@ export const parseCsPkgLockData = async function (csLockData, pkgLockFile) {
|
|
|
5668
5713
|
};
|
|
5669
5714
|
};
|
|
5670
5715
|
|
|
5671
|
-
export const parsePaketLockData =
|
|
5716
|
+
export const parsePaketLockData = function (paketLockData, pkgLockFile) {
|
|
5672
5717
|
const pkgList = [];
|
|
5673
5718
|
const dependenciesList = [];
|
|
5674
5719
|
const dependenciesMap = {};
|
|
@@ -6528,12 +6573,12 @@ export const parseSwiftResolved = (resolvedFile) => {
|
|
|
6528
6573
|
* @param {boolean} cleanup Remove temporary directories
|
|
6529
6574
|
* @param {boolean} includeCacheDir Include maven and gradle cache directories
|
|
6530
6575
|
*/
|
|
6531
|
-
export const collectMvnDependencies =
|
|
6576
|
+
export const collectMvnDependencies = async (
|
|
6532
6577
|
mavenCmd,
|
|
6533
6578
|
basePath,
|
|
6534
6579
|
cleanup = true,
|
|
6535
6580
|
includeCacheDir = false
|
|
6536
|
-
) {
|
|
6581
|
+
) => {
|
|
6537
6582
|
let jarNSMapping = {};
|
|
6538
6583
|
const MAVEN_CACHE_DIR =
|
|
6539
6584
|
process.env.MAVEN_CACHE_DIR || join(homedir(), ".m2", "repository");
|
|
@@ -6574,12 +6619,12 @@ export const collectMvnDependencies = function (
|
|
|
6574
6619
|
"3. Ensure the temporary directory is available and has sufficient disk space to copy all the artifacts."
|
|
6575
6620
|
);
|
|
6576
6621
|
} else {
|
|
6577
|
-
jarNSMapping = collectJarNS(tempDir);
|
|
6622
|
+
jarNSMapping = await collectJarNS(tempDir);
|
|
6578
6623
|
}
|
|
6579
6624
|
}
|
|
6580
6625
|
if (includeCacheDir || basePath === MAVEN_CACHE_DIR) {
|
|
6581
6626
|
// slow operation
|
|
6582
|
-
jarNSMapping = collectJarNS(MAVEN_CACHE_DIR);
|
|
6627
|
+
jarNSMapping = await collectJarNS(MAVEN_CACHE_DIR);
|
|
6583
6628
|
}
|
|
6584
6629
|
|
|
6585
6630
|
// Clean up
|
|
@@ -6589,7 +6634,7 @@ export const collectMvnDependencies = function (
|
|
|
6589
6634
|
return jarNSMapping;
|
|
6590
6635
|
};
|
|
6591
6636
|
|
|
6592
|
-
export const collectGradleDependencies = (
|
|
6637
|
+
export const collectGradleDependencies = async (
|
|
6593
6638
|
gradleCmd,
|
|
6594
6639
|
basePath,
|
|
6595
6640
|
cleanup = true, // eslint-disable-line no-unused-vars
|
|
@@ -6619,7 +6664,7 @@ export const collectGradleDependencies = (
|
|
|
6619
6664
|
for (const apom of pomFiles) {
|
|
6620
6665
|
pomPathMap[basename(apom)] = apom;
|
|
6621
6666
|
}
|
|
6622
|
-
const jarNSMapping = collectJarNS(GRADLE_CACHE_DIR, pomPathMap);
|
|
6667
|
+
const jarNSMapping = await collectJarNS(GRADLE_CACHE_DIR, pomPathMap);
|
|
6623
6668
|
return jarNSMapping;
|
|
6624
6669
|
};
|
|
6625
6670
|
|
|
@@ -6631,7 +6676,7 @@ export const collectGradleDependencies = (
|
|
|
6631
6676
|
*
|
|
6632
6677
|
* @return object containing jar name and class list
|
|
6633
6678
|
*/
|
|
6634
|
-
export const collectJarNS =
|
|
6679
|
+
export const collectJarNS = async (jarPath, pomPathMap = {}) => {
|
|
6635
6680
|
const jarNSMapping = {};
|
|
6636
6681
|
console.log(
|
|
6637
6682
|
`About to identify class names for all jars in the path ${jarPath}`
|
|
@@ -6646,14 +6691,10 @@ export const collectJarNS = function (jarPath, pomPathMap = {}) {
|
|
|
6646
6691
|
"bin"
|
|
6647
6692
|
)}`;
|
|
6648
6693
|
}
|
|
6649
|
-
|
|
6650
|
-
// Execute jar tvf to get class names
|
|
6694
|
+
// Parse jar files to get class names
|
|
6651
6695
|
const jarFiles = getAllFiles(jarPath, "**/*.jar");
|
|
6652
6696
|
if (jarFiles && jarFiles.length) {
|
|
6653
6697
|
for (const jf of jarFiles) {
|
|
6654
|
-
if (!jarCommandAvailable) {
|
|
6655
|
-
break;
|
|
6656
|
-
}
|
|
6657
6698
|
const jarname = jf;
|
|
6658
6699
|
let pomname =
|
|
6659
6700
|
pomPathMap[basename(jf).replace(".jar", ".pom")] ||
|
|
@@ -6685,10 +6726,10 @@ export const collectJarNS = function (jarPath, pomPathMap = {}) {
|
|
|
6685
6726
|
// .m2/repository/org/apache/logging/log4j/log4j-web/3.0.0-SNAPSHOT/log4j-web-3.0.0-SNAPSHOT.jar
|
|
6686
6727
|
const tmpA = jf.split(join(".m2", "repository", ""));
|
|
6687
6728
|
if (tmpA && tmpA.length) {
|
|
6688
|
-
|
|
6729
|
+
const tmpJarPath = tmpA[tmpA.length - 1];
|
|
6689
6730
|
// This would yield log4j-web-3.0.0-SNAPSHOT.jar
|
|
6690
6731
|
const jarFileName = basename(tmpJarPath).replace(".jar", "");
|
|
6691
|
-
|
|
6732
|
+
const tmpDirParts = dirname(tmpJarPath).split(_sep);
|
|
6692
6733
|
// Retrieve the version
|
|
6693
6734
|
let jarVersion = tmpDirParts.pop();
|
|
6694
6735
|
if (jarVersion === "plugins") {
|
|
@@ -6731,10 +6772,10 @@ export const collectJarNS = function (jarPath, pomPathMap = {}) {
|
|
|
6731
6772
|
// .gradle/caches/modules-2/files-2.1/org.xmlresolver/xmlresolver/4.2.0/f4dbdaa83d636dcac91c9003ffa7fb173173fe8d/xmlresolver-4.2.0-data.jar
|
|
6732
6773
|
const tmpA = jf.split(join("files-2.1", ""));
|
|
6733
6774
|
if (tmpA && tmpA.length) {
|
|
6734
|
-
|
|
6775
|
+
const tmpJarPath = tmpA[tmpA.length - 1];
|
|
6735
6776
|
// This would yield xmlresolver-4.2.0-data.jar
|
|
6736
6777
|
const jarFileName = basename(tmpJarPath).replace(".jar", "");
|
|
6737
|
-
|
|
6778
|
+
const tmpDirParts = dirname(tmpJarPath).split(_sep);
|
|
6738
6779
|
// This would remove the hash from the end of the directory name
|
|
6739
6780
|
tmpDirParts.pop();
|
|
6740
6781
|
// Retrieve the version
|
|
@@ -6757,44 +6798,9 @@ export const collectJarNS = function (jarPath, pomPathMap = {}) {
|
|
|
6757
6798
|
jarNSMapping[purl] = jarNSMapping_cache[purl];
|
|
6758
6799
|
} else {
|
|
6759
6800
|
if (DEBUG_MODE) {
|
|
6760
|
-
console.log(`
|
|
6761
|
-
}
|
|
6762
|
-
const jarResult = spawnSync("jar", ["-tf", jf], {
|
|
6763
|
-
encoding: "utf-8",
|
|
6764
|
-
shell: isWin,
|
|
6765
|
-
maxBuffer: 50 * 1024 * 1024,
|
|
6766
|
-
env
|
|
6767
|
-
});
|
|
6768
|
-
if (
|
|
6769
|
-
jarResult &&
|
|
6770
|
-
jarResult.stderr &&
|
|
6771
|
-
jarResult.stderr.includes(
|
|
6772
|
-
"is not recognized as an internal or external command"
|
|
6773
|
-
)
|
|
6774
|
-
) {
|
|
6775
|
-
jarCommandAvailable = false;
|
|
6776
|
-
console.log(
|
|
6777
|
-
"jar command is not available in PATH. Ensure JDK >= 21 is installed and set the environment variables JAVA_HOME and PATH to the bin directory inside JAVA_HOME."
|
|
6778
|
-
);
|
|
6801
|
+
console.log(`Parsing ${jf}`);
|
|
6779
6802
|
}
|
|
6780
|
-
const
|
|
6781
|
-
const nsList = consolelines
|
|
6782
|
-
.filter((l) => {
|
|
6783
|
-
return (
|
|
6784
|
-
(l.includes(".class") ||
|
|
6785
|
-
l.includes(".java") ||
|
|
6786
|
-
l.includes(".kt")) &&
|
|
6787
|
-
!l.includes("-INF") &&
|
|
6788
|
-
!l.includes("module-info")
|
|
6789
|
-
);
|
|
6790
|
-
})
|
|
6791
|
-
.map((e) => {
|
|
6792
|
-
return e
|
|
6793
|
-
.replace("\r", "")
|
|
6794
|
-
.replace(/.(class|java|kt)/, "")
|
|
6795
|
-
.replace(/\/$/, "")
|
|
6796
|
-
.replace(/\//g, ".");
|
|
6797
|
-
});
|
|
6803
|
+
const nsList = await getJarClasses(jf);
|
|
6798
6804
|
jarNSMapping[purl || jf] = {
|
|
6799
6805
|
jarFile: jf,
|
|
6800
6806
|
pom: pomData,
|
|
@@ -6816,7 +6822,7 @@ export const collectJarNS = function (jarPath, pomPathMap = {}) {
|
|
|
6816
6822
|
};
|
|
6817
6823
|
|
|
6818
6824
|
export const convertJarNSToPackages = (jarNSMapping) => {
|
|
6819
|
-
|
|
6825
|
+
const pkgList = [];
|
|
6820
6826
|
for (const purl of Object.keys(jarNSMapping)) {
|
|
6821
6827
|
let { jarFile, pom, namespaces } = jarNSMapping[purl];
|
|
6822
6828
|
if (!pom) {
|
|
@@ -6977,7 +6983,7 @@ export const getPomPropertiesFromMavenDir = function (mavenDir) {
|
|
|
6977
6983
|
* @param {string} path path to file
|
|
6978
6984
|
* @returns {Promise<String>} hex value of hash
|
|
6979
6985
|
*/
|
|
6980
|
-
|
|
6986
|
+
function checksumFile(hashName, path) {
|
|
6981
6987
|
return new Promise((resolve, reject) => {
|
|
6982
6988
|
const hash = createHash(hashName);
|
|
6983
6989
|
const stream = createReadStream(path);
|
|
@@ -7006,7 +7012,7 @@ export const extractJarArchive = async function (
|
|
|
7006
7012
|
const fname = basename(jarFile);
|
|
7007
7013
|
let pomname = undefined;
|
|
7008
7014
|
// If there is a pom file in the same directory, try to use it
|
|
7009
|
-
|
|
7015
|
+
const manifestname = join(dirname(jarFile), "META-INF", "MANIFEST.MF");
|
|
7010
7016
|
// Issue 439: Current implementation checks for existance of a .pom file, but .pom file is not used.
|
|
7011
7017
|
// Instead code expects to find META-INF/MANIFEST.MF in the same folder as a .jar file.
|
|
7012
7018
|
// For now check for presence of both .pom and MANIFEST.MF files.
|
|
@@ -7106,7 +7112,15 @@ export const extractJarArchive = async function (
|
|
|
7106
7112
|
sha +
|
|
7107
7113
|
"%22&rows=20&wt=json";
|
|
7108
7114
|
const res = await cdxgenAgent.get(searchurl, {
|
|
7109
|
-
responseType: "json"
|
|
7115
|
+
responseType: "json",
|
|
7116
|
+
timeout: {
|
|
7117
|
+
lookup: 200,
|
|
7118
|
+
connect: 5000,
|
|
7119
|
+
secureConnect: 5000,
|
|
7120
|
+
socket: 1000,
|
|
7121
|
+
send: 10000,
|
|
7122
|
+
response: 1000
|
|
7123
|
+
}
|
|
7110
7124
|
});
|
|
7111
7125
|
const data = res && res.body ? res.body["response"] : undefined;
|
|
7112
7126
|
if (data && data["numFound"] == 1) {
|
|
@@ -7118,7 +7132,9 @@ export const extractJarArchive = async function (
|
|
|
7118
7132
|
}
|
|
7119
7133
|
} catch (err) {
|
|
7120
7134
|
if (err && err.message && !err.message.includes("404")) {
|
|
7121
|
-
|
|
7135
|
+
if (DEBUG_MODE) {
|
|
7136
|
+
console.log(err);
|
|
7137
|
+
}
|
|
7122
7138
|
search_maven_org_errors++;
|
|
7123
7139
|
}
|
|
7124
7140
|
}
|
|
@@ -7202,7 +7218,7 @@ export const extractJarArchive = async function (
|
|
|
7202
7218
|
group = group === "." ? name : group || name;
|
|
7203
7219
|
}
|
|
7204
7220
|
if (name && version) {
|
|
7205
|
-
|
|
7221
|
+
const apkg = {
|
|
7206
7222
|
group: group ? encodeForPurl(group) : "",
|
|
7207
7223
|
name: name ? encodeForPurl(name) : "",
|
|
7208
7224
|
version,
|
|
@@ -7391,6 +7407,53 @@ export const readZipEntry = async function (
|
|
|
7391
7407
|
return retData;
|
|
7392
7408
|
};
|
|
7393
7409
|
|
|
7410
|
+
/**
|
|
7411
|
+
* Method to get the classes and relevant sources in a jar file
|
|
7412
|
+
*
|
|
7413
|
+
* @param {string} jarFile Jar file to read
|
|
7414
|
+
*
|
|
7415
|
+
* @returns List of classes and sources matching certain known patterns
|
|
7416
|
+
*/
|
|
7417
|
+
export const getJarClasses = async function (jarFile) {
|
|
7418
|
+
const retList = [];
|
|
7419
|
+
try {
|
|
7420
|
+
const zip = new StreamZip.async({ file: jarFile });
|
|
7421
|
+
const entriesCount = await zip.entriesCount;
|
|
7422
|
+
if (!entriesCount) {
|
|
7423
|
+
return [];
|
|
7424
|
+
}
|
|
7425
|
+
const entries = await zip.entries();
|
|
7426
|
+
for (const entry of Object.values(entries)) {
|
|
7427
|
+
if (entry.isDirectory) {
|
|
7428
|
+
continue;
|
|
7429
|
+
}
|
|
7430
|
+
if (
|
|
7431
|
+
(entry.name.includes(".class") ||
|
|
7432
|
+
entry.name.includes(".java") ||
|
|
7433
|
+
entry.name.includes(".scala") ||
|
|
7434
|
+
entry.name.includes(".groovy") ||
|
|
7435
|
+
entry.name.includes(".kt")) &&
|
|
7436
|
+
!entry.name.includes("-INF") &&
|
|
7437
|
+
!entry.name.includes("module-info")
|
|
7438
|
+
) {
|
|
7439
|
+
retList.push(
|
|
7440
|
+
entry.name
|
|
7441
|
+
.replace("\r", "")
|
|
7442
|
+
.replace(/.(class|java|kt|scala|groovy)/g, "")
|
|
7443
|
+
.replace(/\/$/, "")
|
|
7444
|
+
.replace(/\//g, ".")
|
|
7445
|
+
);
|
|
7446
|
+
}
|
|
7447
|
+
}
|
|
7448
|
+
zip.close();
|
|
7449
|
+
} catch (e) {
|
|
7450
|
+
if (DEBUG_MODE) {
|
|
7451
|
+
console.log(`Unable to parse ${jarFile}. Skipping.`);
|
|
7452
|
+
}
|
|
7453
|
+
}
|
|
7454
|
+
return retList;
|
|
7455
|
+
};
|
|
7456
|
+
|
|
7394
7457
|
/**
|
|
7395
7458
|
* Method to return the gradle command to use.
|
|
7396
7459
|
*
|
|
@@ -7531,7 +7594,7 @@ export const getAtomCommand = () => {
|
|
|
7531
7594
|
};
|
|
7532
7595
|
|
|
7533
7596
|
export const executeAtom = (src, args) => {
|
|
7534
|
-
|
|
7597
|
+
const cwd =
|
|
7535
7598
|
existsSync(src) && lstatSync(src).isDirectory() ? src : dirname(src);
|
|
7536
7599
|
let ATOM_BIN = getAtomCommand();
|
|
7537
7600
|
let isSupported = true;
|
|
@@ -7579,7 +7642,7 @@ export const executeAtom = (src, args) => {
|
|
|
7579
7642
|
result.stderr.includes("Error: Could not create the Java Virtual Machine")
|
|
7580
7643
|
) {
|
|
7581
7644
|
console.log(
|
|
7582
|
-
"Atom requires Java
|
|
7645
|
+
"Atom requires Java 21 or above. To improve the SBOM accuracy, please install a suitable version, set the JAVA_HOME environment variable, and re-run cdxgen.\nAlternatively, use the cdxgen container image."
|
|
7583
7646
|
);
|
|
7584
7647
|
console.log(`Current JAVA_HOME: ${env["JAVA_HOME"] || ""}`);
|
|
7585
7648
|
} else if (result.stderr.includes("astgen")) {
|
|
@@ -7638,7 +7701,7 @@ export const findAppModules = function (
|
|
|
7638
7701
|
];
|
|
7639
7702
|
executeAtom(src, args);
|
|
7640
7703
|
if (existsSync(slicesFile)) {
|
|
7641
|
-
const slicesData = JSON.parse(readFileSync(slicesFile), {
|
|
7704
|
+
const slicesData = JSON.parse(readFileSync(slicesFile, "utf-8"), {
|
|
7642
7705
|
encoding: "utf-8"
|
|
7643
7706
|
});
|
|
7644
7707
|
if (slicesData && Object.keys(slicesData) && slicesData.modules) {
|
|
@@ -7787,7 +7850,7 @@ export const getPipFrozenTree = (basePath, reqOrSetupFile, tempVenvDir) => {
|
|
|
7787
7850
|
if (reqOrSetupFile) {
|
|
7788
7851
|
// We have a poetry.lock file
|
|
7789
7852
|
if (reqOrSetupFile.endsWith("poetry.lock")) {
|
|
7790
|
-
|
|
7853
|
+
const poetryConfigArgs = [
|
|
7791
7854
|
"-m",
|
|
7792
7855
|
"poetry",
|
|
7793
7856
|
"config",
|
|
@@ -7849,7 +7912,7 @@ export const getPipFrozenTree = (basePath, reqOrSetupFile, tempVenvDir) => {
|
|
|
7849
7912
|
}
|
|
7850
7913
|
}
|
|
7851
7914
|
} else {
|
|
7852
|
-
|
|
7915
|
+
const poetryEnvArgs = ["env info", "--path"];
|
|
7853
7916
|
result = spawnSync("poetry", poetryEnvArgs, {
|
|
7854
7917
|
cwd: basePath,
|
|
7855
7918
|
encoding: "utf-8",
|
|
@@ -7963,7 +8026,7 @@ export const getPipFrozenTree = (basePath, reqOrSetupFile, tempVenvDir) => {
|
|
|
7963
8026
|
}
|
|
7964
8027
|
const name = t.name.replace(/_/g, "-").toLowerCase();
|
|
7965
8028
|
const version = t.version;
|
|
7966
|
-
|
|
8029
|
+
const exclude = ["pip", "setuptools", "wheel"];
|
|
7967
8030
|
if (!exclude.includes(name)) {
|
|
7968
8031
|
const purlString = new PackageURL(
|
|
7969
8032
|
"pypi",
|
|
@@ -8050,7 +8113,7 @@ export const addEvidenceForImports = (pkgList, allImports) => {
|
|
|
8050
8113
|
if (group === "@types") {
|
|
8051
8114
|
continue;
|
|
8052
8115
|
}
|
|
8053
|
-
|
|
8116
|
+
const aliases =
|
|
8054
8117
|
group && group.length
|
|
8055
8118
|
? [name, `${group}/${name}`, `@${group}/${name}`]
|
|
8056
8119
|
: [name];
|
|
@@ -8124,8 +8187,8 @@ export const parseCmakeDotFile = (dotFile, pkgType, options = {}) => {
|
|
|
8124
8187
|
return;
|
|
8125
8188
|
}
|
|
8126
8189
|
let name = "";
|
|
8127
|
-
|
|
8128
|
-
|
|
8190
|
+
const group = "";
|
|
8191
|
+
const version = "";
|
|
8129
8192
|
let path = undefined;
|
|
8130
8193
|
if (l.startsWith("digraph")) {
|
|
8131
8194
|
const tmpA = l.split(" ");
|
|
@@ -8151,7 +8214,7 @@ export const parseCmakeDotFile = (dotFile, pkgType, options = {}) => {
|
|
|
8151
8214
|
if (tmpA && tmpA.length) {
|
|
8152
8215
|
const relationship = tmpA[1];
|
|
8153
8216
|
if (relationship.includes("->")) {
|
|
8154
|
-
|
|
8217
|
+
const tmpB = relationship.split(" -> ");
|
|
8155
8218
|
if (tmpB && tmpB.length === 2) {
|
|
8156
8219
|
if (tmpB[0].includes(_sep)) {
|
|
8157
8220
|
tmpB[0] = basename(tmpB[0]);
|
|
@@ -8240,9 +8303,9 @@ export const parseCmakeLikeFile = (cmakeListFile, pkgType, options = {}) => {
|
|
|
8240
8303
|
if (l === "\n" || l.startsWith("#")) {
|
|
8241
8304
|
return;
|
|
8242
8305
|
}
|
|
8243
|
-
|
|
8244
|
-
|
|
8245
|
-
|
|
8306
|
+
const group = "";
|
|
8307
|
+
const path = undefined;
|
|
8308
|
+
const name_list = [];
|
|
8246
8309
|
if (l.startsWith("set")) {
|
|
8247
8310
|
const tmpA = l.replace("set(", "").replace(")", "").trim().split(" ");
|
|
8248
8311
|
if (tmpA && tmpA.length === 2) {
|
|
@@ -8398,7 +8461,7 @@ export const parseCmakeLikeFile = (cmakeListFile, pkgType, options = {}) => {
|
|
|
8398
8461
|
}
|
|
8399
8462
|
}
|
|
8400
8463
|
for (let n of name_list) {
|
|
8401
|
-
|
|
8464
|
+
const props = [];
|
|
8402
8465
|
let confidence = 0;
|
|
8403
8466
|
if (
|
|
8404
8467
|
n &&
|
|
@@ -8517,7 +8580,7 @@ export const getOSPackageForFile = (afile, osPkgsList) => {
|
|
|
8517
8580
|
*/
|
|
8518
8581
|
export const getCppModules = (src, options, osPkgsList, epkgList) => {
|
|
8519
8582
|
// Generic is the type to use where the package registry could not be located
|
|
8520
|
-
|
|
8583
|
+
const pkgType = "generic";
|
|
8521
8584
|
const pkgList = [];
|
|
8522
8585
|
const pkgAddedMap = {};
|
|
8523
8586
|
let sliceData = {};
|
|
@@ -8655,11 +8718,11 @@ export const getCppModules = (src, options, osPkgsList, epkgList) => {
|
|
|
8655
8718
|
for (let afile of Object.keys(usageData)) {
|
|
8656
8719
|
// Normalize windows separator
|
|
8657
8720
|
afile = afile.replace("..\\", "").replace(/\\/g, "/");
|
|
8658
|
-
|
|
8721
|
+
const fileName = basename(afile);
|
|
8659
8722
|
if (!fileName || !fileName.length) {
|
|
8660
8723
|
continue;
|
|
8661
8724
|
}
|
|
8662
|
-
|
|
8725
|
+
const extn = extname(fileName);
|
|
8663
8726
|
let group = dirname(afile);
|
|
8664
8727
|
if (
|
|
8665
8728
|
group.startsWith(".") ||
|
|
@@ -8669,9 +8732,9 @@ export const getCppModules = (src, options, osPkgsList, epkgList) => {
|
|
|
8669
8732
|
) {
|
|
8670
8733
|
group = "";
|
|
8671
8734
|
}
|
|
8672
|
-
|
|
8735
|
+
const version = "";
|
|
8673
8736
|
// We need to resolve the name to an os package here
|
|
8674
|
-
|
|
8737
|
+
const name = fileName.replace(extn, "");
|
|
8675
8738
|
let apkg = getOSPackageForFile(afile, osPkgsList) ||
|
|
8676
8739
|
epkgMap[group + "/" + name] || {
|
|
8677
8740
|
name,
|
|
@@ -8844,7 +8907,7 @@ async function queryNuget(p, NUGET_URL) {
|
|
|
8844
8907
|
function setLatestVersion(upper) {
|
|
8845
8908
|
// Handle special case for versions with more than 3 parts
|
|
8846
8909
|
if (upper.split(".").length > 3) {
|
|
8847
|
-
|
|
8910
|
+
const tmpVersionArray = upper.split("-")[0].split(".");
|
|
8848
8911
|
// Compromise for versions such as 1.2.3.0-alpha
|
|
8849
8912
|
// How to find latest proper release version?
|
|
8850
8913
|
if (
|
|
@@ -8889,19 +8952,19 @@ async function queryNuget(p, NUGET_URL) {
|
|
|
8889
8952
|
NUGET_URL + np.name.toLowerCase() + "/index.json",
|
|
8890
8953
|
{ responseType: "json" }
|
|
8891
8954
|
);
|
|
8892
|
-
|
|
8955
|
+
const items = res.body.items;
|
|
8893
8956
|
if (!items || !items[0]) {
|
|
8894
8957
|
return [np, newBody, body];
|
|
8895
8958
|
}
|
|
8896
8959
|
if (items[0] && !items[0].items) {
|
|
8897
8960
|
if (!p.version || p.version === "0.0.0" || p.version === "latest") {
|
|
8898
|
-
|
|
8961
|
+
const upper = items[items.length - 1].upper;
|
|
8899
8962
|
np.version = setLatestVersion(upper);
|
|
8900
8963
|
}
|
|
8901
8964
|
for (const item of items) {
|
|
8902
8965
|
if (np.version) {
|
|
8903
|
-
|
|
8904
|
-
|
|
8966
|
+
const lower = compare(coerce(item.lower), coerce(np.version));
|
|
8967
|
+
const upper = compare(coerce(item.upper), coerce(np.version));
|
|
8905
8968
|
if (lower !== 1 && upper !== -1) {
|
|
8906
8969
|
res = await cdxgenAgent.get(item["@id"], { responseType: "json" });
|
|
8907
8970
|
for (const i of res.body.items.reverse()) {
|
|
@@ -8918,13 +8981,13 @@ async function queryNuget(p, NUGET_URL) {
|
|
|
8918
8981
|
}
|
|
8919
8982
|
} else {
|
|
8920
8983
|
if (!p.version || p.version === "0.0.0" || p.version === "latest") {
|
|
8921
|
-
|
|
8984
|
+
const upper = items[items.length - 1].upper;
|
|
8922
8985
|
np.version = setLatestVersion(upper);
|
|
8923
8986
|
}
|
|
8924
8987
|
if (np.version) {
|
|
8925
8988
|
for (const item of items) {
|
|
8926
|
-
|
|
8927
|
-
|
|
8989
|
+
const lower = compare(coerce(item.lower), coerce(np.version));
|
|
8990
|
+
const upper = compare(coerce(item.upper), coerce(np.version));
|
|
8928
8991
|
if (lower !== 1 && upper !== -1) {
|
|
8929
8992
|
for (const i of item.items.reverse()) {
|
|
8930
8993
|
if (
|