@cyclonedx/cdxgen 10.9.6 → 10.9.7

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 CHANGED
@@ -55,7 +55,7 @@ Sections include:
55
55
  ## Installing
56
56
 
57
57
  ```shell
58
- npm install -g @cyclonedx/cdxgen
58
+ npm install -g @cyclonedx/cdxgen@10.9.6
59
59
  ```
60
60
 
61
61
  If you are a [Homebrew][homebrew-homepage] user, you can also install [cdxgen][homebrew-cdxgen] via:
@@ -72,28 +72,28 @@ deno install --allow-read --allow-env --allow-run --allow-sys=uid,systemMemoryIn
72
72
 
73
73
  You can also use the cdxgen container image with node, deno, or bun runtime versions.
74
74
 
75
- The default version uses Node.js 20
75
+ The default version uses Node.js 22
76
76
 
77
77
  ```bash
78
- docker run --rm -v /tmp:/tmp -v $(pwd):/app:rw -t ghcr.io/cyclonedx/cdxgen -r /app -o /app/bom.json
78
+ docker run --rm -v /tmp:/tmp -v $(pwd):/app:rw -t ghcr.io/cyclonedx/cdxgen:master -r /app -o /app/bom.json
79
79
  ```
80
80
 
81
81
  To use the deno version, use `ghcr.io/cyclonedx/cdxgen-deno` as the image name.
82
82
 
83
83
  ```bash
84
- docker run --rm -v /tmp:/tmp -v $(pwd):/app:rw -t ghcr.io/cyclonedx/cdxgen-deno -r /app -o /app/bom.json
84
+ docker run --rm -v /tmp:/tmp -v $(pwd):/app:rw -t ghcr.io/cyclonedx/cdxgen-deno:master -r /app -o /app/bom.json
85
85
  ```
86
86
 
87
87
  For the bun version, use `ghcr.io/cyclonedx/cdxgen-bun` as the image name.
88
88
 
89
89
  ```bash
90
- docker run --rm -v /tmp:/tmp -v $(pwd):/app:rw -t ghcr.io/cyclonedx/cdxgen-bun -r /app -o /app/bom.json
90
+ docker run --rm -v /tmp:/tmp -v $(pwd):/app:rw -t ghcr.io/cyclonedx/cdxgen-bun:master -r /app -o /app/bom.json
91
91
  ```
92
92
 
93
93
  In deno applications, cdxgen could be directly imported without any conversion. Please see the section on [integration as a library](#integration-as-library)
94
94
 
95
95
  ```ts
96
- import { createBom, submitBom } from "npm:@cyclonedx/cdxgen@^9.0.1";
96
+ import { createBom, submitBom } from "npm:@cyclonedx/cdxgen@^10.9.6";
97
97
  ```
98
98
 
99
99
  ## Getting Help
@@ -403,7 +403,7 @@ To generate test public/private key pairs, you can run cdxgen by passing the arg
403
403
  Use the bundled `cdx-verify` command, which supports verifying a single signature added at the bom level.
404
404
 
405
405
  ```shell
406
- npm install -g @cyclonedx/cdxgen
406
+ npm install -g @cyclonedx/cdxgen@10.9.6
407
407
  cdx-verify -i bom.json --public-key public.key
408
408
  ```
409
409
 
package/index.js CHANGED
@@ -1233,6 +1233,7 @@ export async function createJavaBom(path, options) {
1233
1233
  // For java, this would correctly include the cyclonedx maven plugin.
1234
1234
  let tools = undefined;
1235
1235
  let possible_misses = false;
1236
+ let mavenDepsTreeInfoShown = false;
1236
1237
  // war/ear mode
1237
1238
  if (path.endsWith(".war") || path.endsWith(".jar")) {
1238
1239
  // Check if the file exists
@@ -1324,13 +1325,14 @@ export async function createJavaBom(path, options) {
1324
1325
  }
1325
1326
  // Use the cyclonedx maven plugin if there is no preference for maven deps tree
1326
1327
  if (!PREFER_MAVEN_DEPS_TREE) {
1327
- if (DEBUG_MODE) {
1328
+ if (!mavenDepsTreeInfoShown && DEBUG_MODE) {
1328
1329
  console.log(
1329
1330
  "cdxgen now supports generating SBOM with only the maven cli without the need for the cyclonedx-maven plugin. This mode works better in enterprise environments and in multi-module projects.",
1330
1331
  );
1331
1332
  console.log(
1332
1333
  "Set the environment variable PREFER_MAVEN_DEPS_TREE to true to enable this.",
1333
1334
  );
1335
+ mavenDepsTreeInfoShown = true;
1334
1336
  }
1335
1337
  console.log(
1336
1338
  `Executing '${mavenCmd} ${mvnArgs.join(" ")}' in`,
@@ -2716,7 +2718,7 @@ export async function createNodejsBom(path, options) {
2716
2718
  * @param {String} path
2717
2719
  * @param {Object} options
2718
2720
  */
2719
- export async function createPixiBom(path, options) {
2721
+ export function createPixiBom(path, options) {
2720
2722
  const allImports = {};
2721
2723
  let metadataFilename = "";
2722
2724
  let dependencies = [];
@@ -3398,7 +3400,11 @@ export async function createGoBom(path, options) {
3398
3400
  for (const f of gomodFiles) {
3399
3401
  const basePath = dirname(f);
3400
3402
  // Ignore vendor packages
3401
- if (basePath.includes("/vendor/") || basePath.includes("/build/")) {
3403
+ if (
3404
+ basePath.includes("/vendor/") ||
3405
+ basePath.includes("/build/") ||
3406
+ basePath.includes("/test-fixtures/")
3407
+ ) {
3402
3408
  continue;
3403
3409
  }
3404
3410
  // First we execute the go list -deps command which gives the correct list of dependencies
@@ -3424,7 +3430,7 @@ export async function createGoBom(path, options) {
3424
3430
  if (result.status !== 0 || result.error) {
3425
3431
  // go list -deps command may not work when private packages are involved
3426
3432
  // So we support a fallback to only operate with go mod graph command output in such instances
3427
- console.log("go list -deps command has failed.");
3433
+ console.log("go list -deps command has failed for", basePath);
3428
3434
  shouldManuallyParse = true;
3429
3435
  if (DEBUG_MODE && result.stdout) {
3430
3436
  console.log(result.stdout);
@@ -3495,6 +3501,11 @@ export async function createGoBom(path, options) {
3495
3501
  parentComponent,
3496
3502
  );
3497
3503
  }
3504
+ // Retain the parent component hierarchy
3505
+ if (Object.keys(retMap.parentComponent).length) {
3506
+ parentComponent.components = parentComponent.components || [];
3507
+ parentComponent.components.push(retMap.parentComponent);
3508
+ }
3498
3509
  }
3499
3510
  } else {
3500
3511
  if (DEBUG_MODE) {
@@ -3528,6 +3539,15 @@ export async function createGoBom(path, options) {
3528
3539
  parentComponent,
3529
3540
  );
3530
3541
  }
3542
+ // Retain the parent component hierarchy
3543
+ if (Object.keys(retMap.parentComponent).length) {
3544
+ if (gomodFiles.length === 1) {
3545
+ parentComponent = retMap.parentComponent;
3546
+ } else {
3547
+ parentComponent.components = parentComponent.components || [];
3548
+ parentComponent.components.push(retMap.parentComponent);
3549
+ }
3550
+ }
3531
3551
  } else {
3532
3552
  shouldManuallyParse = true;
3533
3553
  console.log(
@@ -3566,9 +3586,31 @@ export async function createGoBom(path, options) {
3566
3586
  console.log(`Parsing ${f}`);
3567
3587
  }
3568
3588
  const gomodData = readFileSync(f, { encoding: "utf-8" });
3569
- const dlist = await parseGoModData(gomodData, gosumMap);
3570
- if (dlist?.length) {
3571
- pkgList = pkgList.concat(dlist);
3589
+ const retMap = await parseGoModData(gomodData, gosumMap);
3590
+ if (retMap?.pkgList?.length) {
3591
+ pkgList = pkgList.concat(retMap.pkgList);
3592
+ }
3593
+ // Retain the parent component hierarchy
3594
+ if (Object.keys(retMap.parentComponent).length) {
3595
+ if (gomodFiles.length === 1) {
3596
+ parentComponent = retMap.parentComponent;
3597
+ } else {
3598
+ parentComponent.components = parentComponent.components || [];
3599
+ parentComponent.components.push(retMap.parentComponent);
3600
+ }
3601
+ if (retMap?.rootList?.length) {
3602
+ const thisParentDependsOn = [
3603
+ {
3604
+ ref: retMap.parentComponent["bom-ref"],
3605
+ dependsOn: retMap.rootList.map((c) => c["bom-ref"]),
3606
+ },
3607
+ ];
3608
+ dependencies = mergeDependencies(
3609
+ dependencies,
3610
+ thisParentDependsOn,
3611
+ parentComponent,
3612
+ );
3613
+ }
3572
3614
  }
3573
3615
  }
3574
3616
  return buildBomNSData(options, pkgList, "golang", {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cyclonedx/cdxgen",
3
- "version": "10.9.6",
3
+ "version": "10.9.7",
4
4
  "description": "Creates CycloneDX Software Bill of Materials (SBOM) from source or container image",
5
5
  "homepage": "http://github.com/cyclonedx/cdxgen",
6
6
  "author": "Prabhu Subramanian <prabhu@appthreat.com>",
@@ -61,12 +61,12 @@
61
61
  "*": "biome check --fix --no-errors-on-unmatched"
62
62
  },
63
63
  "dependencies": {
64
- "@babel/parser": "^7.24.8",
65
- "@babel/traverse": "^7.24.8",
64
+ "@babel/parser": "^7.25.6",
65
+ "@babel/traverse": "^7.25.6",
66
66
  "@npmcli/arborist": "7.5.4",
67
- "ajv": "^8.16.0",
67
+ "ajv": "^8.17.1",
68
68
  "ajv-formats": "^3.0.1",
69
- "cheerio": "^1.0.0-rc.12",
69
+ "cheerio": "^1.0.0",
70
70
  "edn-data": "1.1.2",
71
71
  "find-up": "7.0.0",
72
72
  "glob": "^11.0.0",
@@ -90,7 +90,7 @@
90
90
  "yargs": "^17.7.2"
91
91
  },
92
92
  "optionalDependencies": {
93
- "@appthreat/atom": "2.0.17",
93
+ "@appthreat/atom": "2.0.18",
94
94
  "@appthreat/cdx-proto": "1.0.1",
95
95
  "@cyclonedx/cdxgen-plugins-bin": "1.6.3",
96
96
  "@cyclonedx/cdxgen-plugins-bin-arm64": "1.6.3",
package/types/index.d.ts CHANGED
@@ -64,7 +64,7 @@ export function createNodejsBom(path: string, options: any): Promise<any>;
64
64
  * @param {String} path
65
65
  * @param {Object} options
66
66
  */
67
- export function createPixiBom(path: string, options: any): Promise<any>;
67
+ export function createPixiBom(path: string, options: any): any;
68
68
  /**
69
69
  * Function to create bom string for Python projects
70
70
  *
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../index.js"],"names":[],"mappings":"AA6vBA;;;;;;;;GAQG;AACH,gFAFW,MAAM,SAchB;AAyUD;;;;;;;GAOG;AACH,mCALW,MAAM,qBAiEhB;AAED;;;;;GAKG;AACH,uCAHW,MAAM;;;;EAKhB;AAED;;;;;GAKG;AACH,sCAHW,MAAM;;;;EAkBhB;AAED;;;;;GAKG;AACH,oCAHW,MAAM,8BA4/BhB;AAED;;;;;GAKG;AACH,sCAHW,MAAM,8BA2chB;AAED;;;;;;;;;;GAUG;AACH,wEAyEC;AAED;;;;;GAKG;AACH,sCAHW,MAAM,8BA2bhB;AAED;;;;;GAKG;AACH,kCAHW,MAAM,8BAqWhB;AAED;;;;;GAKG;AACH,oCAHW,MAAM,8BAqIhB;AAED;;;;;GAKG;AACH,oCAHW,MAAM,8BAiDhB;AAED;;;;;GAKG;AACH,mCAHW,MAAM,qBA+KhB;AAED;;;;;GAKG;AACH,uCAHW,MAAM,qBAsHhB;AAED;;;;;GAKG;AACH,uCAHW,MAAM,qBA2BhB;AAED;;;;;GAKG;AACH,sCAHW,MAAM,qBA2BhB;AAED;;;;;GAKG;AACH,sCAHW,MAAM,qBA2BhB;AAED;;;;;GAKG;AACH,0CAHW,MAAM,qBAuBhB;AAED;;;;;GAKG;AACH,kCAHW,MAAM,8BAqDhB;AAED;;;;;GAKG;AACH,uCAHW,MAAM,8BA4ChB;AAED;;;;;GAKG;AACH,oCAHW,MAAM,qBA2BhB;AAED;;;;;GAKG;AACH,qCAHW,MAAM,8BAwFhB;AAED;;;;;GAKG;AACH,iDAHW,MAAM,qBAiUhB;AAED;;;;;GAKG;AACH,mCAHW,MAAM,qBAwJhB;AAED;;;;;GAKG;AACH,oCAHW,MAAM,8BAmFhB;AAED;;;;;GAKG;AACH,sCAHW,MAAM,8BA6XhB;AAED;;;;;GAKG;AACH,2CAHW,MAAM;;;;;;;;;;;;;;;;;;;;GAoChB;AAED;;;;;;;;KA+DC;AAED;;;;;;GAMG;AACH,yDA2CC;AAED;;;;;;;;;GASG;AACH,2GA6BC;AAED;;;;;GAKG;AACH,0CAHW,MAAM,EAAE,8BAmclB;AAED;;;;;GAKG;AACH,iCAHW,MAAM,8BAiUhB;AAED;;;;;GAKG;AACH,gCAHW,MAAM,qBAsOhB;AAED;;;;;;GAMG;AACH,wDAFY,OAAO,CAAC;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,MAAM,EAAE,MAAM,EAAE,CAAA;CAAE,GAAG,SAAS,CAAC,CAwHxE"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../index.js"],"names":[],"mappings":"AA6vBA;;;;;;;;GAQG;AACH,gFAFW,MAAM,SAchB;AAyUD;;;;;;;GAOG;AACH,mCALW,MAAM,qBAiEhB;AAED;;;;;GAKG;AACH,uCAHW,MAAM;;;;EAKhB;AAED;;;;;GAKG;AACH,sCAHW,MAAM;;;;EAkBhB;AAED;;;;;GAKG;AACH,oCAHW,MAAM,8BA8/BhB;AAED;;;;;GAKG;AACH,sCAHW,MAAM,8BA2chB;AAED;;;;;;;;;;GAUG;AACH,+DAyEC;AAED;;;;;GAKG;AACH,sCAHW,MAAM,8BA2bhB;AAED;;;;;GAKG;AACH,kCAHW,MAAM,8BA6YhB;AAED;;;;;GAKG;AACH,oCAHW,MAAM,8BAqIhB;AAED;;;;;GAKG;AACH,oCAHW,MAAM,8BAiDhB;AAED;;;;;GAKG;AACH,mCAHW,MAAM,qBA+KhB;AAED;;;;;GAKG;AACH,uCAHW,MAAM,qBAsHhB;AAED;;;;;GAKG;AACH,uCAHW,MAAM,qBA2BhB;AAED;;;;;GAKG;AACH,sCAHW,MAAM,qBA2BhB;AAED;;;;;GAKG;AACH,sCAHW,MAAM,qBA2BhB;AAED;;;;;GAKG;AACH,0CAHW,MAAM,qBAuBhB;AAED;;;;;GAKG;AACH,kCAHW,MAAM,8BAqDhB;AAED;;;;;GAKG;AACH,uCAHW,MAAM,8BA4ChB;AAED;;;;;GAKG;AACH,oCAHW,MAAM,qBA2BhB;AAED;;;;;GAKG;AACH,qCAHW,MAAM,8BAwFhB;AAED;;;;;GAKG;AACH,iDAHW,MAAM,qBAiUhB;AAED;;;;;GAKG;AACH,mCAHW,MAAM,qBAwJhB;AAED;;;;;GAKG;AACH,oCAHW,MAAM,8BAmFhB;AAED;;;;;GAKG;AACH,sCAHW,MAAM,8BA6XhB;AAED;;;;;GAKG;AACH,2CAHW,MAAM;;;;;;;;;;;;;;;;;;;;GAoChB;AAED;;;;;;;;KA+DC;AAED;;;;;;GAMG;AACH,yDA2CC;AAED;;;;;;;;;GASG;AACH,2GA6BC;AAED;;;;;GAKG;AACH,0CAHW,MAAM,EAAE,8BAmclB;AAED;;;;;GAKG;AACH,iCAHW,MAAM,8BAiUhB;AAED;;;;;GAKG;AACH,gCAHW,MAAM,qBAsOhB;AAED;;;;;;GAMG;AACH,wDAFY,OAAO,CAAC;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,MAAM,EAAE,MAAM,EAAE,CAAA;CAAE,GAAG,SAAS,CAAC,CAwHxE"}
package/types/utils.d.ts CHANGED
@@ -522,7 +522,15 @@ export function getRepoLicense(repoUrl: string, repoMetadata: any): Promise<stri
522
522
  */
523
523
  export function getGoPkgLicense(repoMetadata: any): Promise<any>;
524
524
  export function getGoPkgComponent(group: any, name: any, version: any, hash: any): Promise<{}>;
525
- export function parseGoModData(goModData: any, gosumMap: any): Promise<any[]>;
525
+ /**
526
+ * Method to parse go.mod files
527
+ *
528
+ * @param {String} goModData Contents of go.mod file
529
+ * @param {Object} gosumMap Data from go.sum files
530
+ *
531
+ * @returns {Object} Object containing parent component, rootList and packages list
532
+ */
533
+ export function parseGoModData(goModData: string, gosumMap: any): any;
526
534
  /**
527
535
  * Parse go list output
528
536
  *
@@ -540,15 +548,18 @@ export function parseGoListDep(rawOutput: string, gosumMap: any): Promise<{
540
548
  * @param {string} goModFile go.mod file
541
549
  * @param {Object} goSumMap Hashes from gosum for lookups
542
550
  * @param {Array} epkgList Existing package list
551
+ * @param {Object} parentComponent Current parent component
543
552
  *
544
553
  * @returns Object containing List of packages and dependencies
545
554
  */
546
- export function parseGoModGraph(rawOutput: string, goModFile: string, gosumMap: any, epkgList?: any[], parentComponent?: {}): Promise<{
555
+ export function parseGoModGraph(rawOutput: string, goModFile: string, gosumMap: any, epkgList?: any[], parentComponent?: any): Promise<{
547
556
  pkgList: any[];
548
557
  dependenciesList: {
549
558
  ref: string;
550
559
  dependsOn: any[];
551
560
  }[];
561
+ parentComponent: any;
562
+ rootList: any;
552
563
  }>;
553
564
  /**
554
565
  * Parse go mod why output
@@ -1 +1 @@
1
- {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../utils.js"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../utils.js"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"validator.d.ts","sourceRoot":"","sources":["../validator.js"],"names":[],"mappings":"AAmBO,qCAFI,MAAM,WA6ChB;AAOM,0CAFI,MAAM,WAiDhB;AAOM,uCAFI,MAAM,WAgEhB;AA6BM,sCAFI,MAAM,WA8ChB"}
1
+ {"version":3,"file":"validator.d.ts","sourceRoot":"","sources":["../validator.js"],"names":[],"mappings":"AAmBO,qCAFI,MAAM,WA6ChB;AAOM,0CAFI,MAAM,WAqDhB;AAOM,uCAFI,MAAM,WAgEhB;AA6BM,sCAFI,MAAM,WA8ChB"}
package/utils.js CHANGED
@@ -4707,19 +4707,40 @@ export async function getGoPkgComponent(group, name, version, hash) {
4707
4707
  return pkg;
4708
4708
  }
4709
4709
 
4710
+ /**
4711
+ * Method to parse go.mod files
4712
+ *
4713
+ * @param {String} goModData Contents of go.mod file
4714
+ * @param {Object} gosumMap Data from go.sum files
4715
+ *
4716
+ * @returns {Object} Object containing parent component, rootList and packages list
4717
+ */
4710
4718
  export async function parseGoModData(goModData, gosumMap) {
4711
4719
  const pkgComponentsList = [];
4720
+ const parentComponent = {};
4721
+ const rootList = [];
4712
4722
  let isModReplacement = false;
4713
4723
 
4714
4724
  if (!goModData) {
4715
- return pkgComponentsList;
4725
+ return {};
4716
4726
  }
4717
4727
 
4718
4728
  const pkgs = goModData.split("\n");
4719
4729
  for (let l of pkgs) {
4730
+ // Windows of course
4731
+ l = l.replace("\r", "");
4732
+ // Capture the parent component name from the module
4733
+ if (l.startsWith("module ")) {
4734
+ parentComponent.name = l.split(" ").pop().trim();
4735
+ parentComponent.type = "application";
4736
+ parentComponent["purl"] = PackageURL.fromString(
4737
+ `pkg:golang/${parentComponent.name}`,
4738
+ ).toString();
4739
+ parentComponent["bom-ref"] = decodeURIComponent(parentComponent["purl"]);
4740
+ continue;
4741
+ }
4720
4742
  // Skip go.mod file headers, whitespace, and/or comments
4721
4743
  if (
4722
- l.startsWith("module ") ||
4723
4744
  l.startsWith("go ") ||
4724
4745
  l.includes(")") ||
4725
4746
  l.trim() === "" ||
@@ -4743,33 +4764,32 @@ export async function parseGoModData(goModData, gosumMap) {
4743
4764
  l = l.replace("replace", "");
4744
4765
  isModReplacement = true;
4745
4766
  }
4746
-
4767
+ // require google.golang.org/genproto v0.0.0-20231106174013-bbf56f31fb17
4768
+ if (l.startsWith("require ")) {
4769
+ l = l.replace("require ", "");
4770
+ isModReplacement = false;
4771
+ }
4747
4772
  const tmpA = l.trim().split(" ");
4748
-
4749
4773
  if (!isModReplacement) {
4750
4774
  // Add group, name and version component properties for required modules
4751
4775
  const version = tmpA[1];
4752
4776
  const gosumHash = gosumMap[`${tmpA[0]}@${version}`];
4753
- // The hash for this version was not found in go.sum, so skip as it is most likely being replaced.
4754
- if (gosumHash === undefined) {
4755
- continue;
4756
- }
4757
4777
  const component = await getGoPkgComponent(
4758
4778
  "",
4759
4779
  tmpA[0],
4760
4780
  version,
4761
4781
  gosumHash,
4762
4782
  );
4783
+ if (l.endsWith("// indirect")) {
4784
+ component.scope = "optional";
4785
+ } else {
4786
+ rootList.push(component);
4787
+ }
4763
4788
  pkgComponentsList.push(component);
4764
4789
  } else {
4765
4790
  // Add group, name and version component properties for replacement modules
4766
4791
  const version = tmpA[3];
4767
-
4768
4792
  const gosumHash = gosumMap[`${tmpA[2]}@${version}`];
4769
- // The hash for this version was not found in go.sum, so skip.
4770
- if (gosumHash === undefined) {
4771
- continue;
4772
- }
4773
4793
  const component = await getGoPkgComponent(
4774
4794
  "",
4775
4795
  tmpA[2],
@@ -4777,11 +4797,16 @@ export async function parseGoModData(goModData, gosumMap) {
4777
4797
  gosumHash,
4778
4798
  );
4779
4799
  pkgComponentsList.push(component);
4800
+ rootList.push(component);
4780
4801
  }
4781
4802
  }
4782
4803
  // Clear the cache
4783
4804
  metadata_cache = {};
4784
- return pkgComponentsList;
4805
+ return {
4806
+ parentComponent,
4807
+ pkgList: pkgComponentsList.sort((a, b) => a.purl.localeCompare(b.purl)),
4808
+ rootList,
4809
+ };
4785
4810
  }
4786
4811
 
4787
4812
  /**
@@ -4843,31 +4868,33 @@ export async function parseGoListDep(rawOutput, gosumMap) {
4843
4868
  }
4844
4869
  return {
4845
4870
  parentComponent,
4846
- pkgList: deps,
4871
+ pkgList: deps.sort((a, b) => a.purl.localeCompare(b.purl)),
4847
4872
  };
4848
4873
  }
4849
4874
 
4850
- function _addGoComponentEvidence(component, goModFile) {
4851
- component.evidence = {
4852
- identity: {
4853
- field: "purl",
4854
- confidence: 1,
4855
- methods: [
4856
- {
4857
- technique: "manifest-analysis",
4858
- confidence: 1,
4859
- value: goModFile,
4860
- },
4861
- ],
4862
- },
4863
- };
4864
- if (!component.properties) {
4865
- component.properties = [];
4875
+ function _addGoComponentEvidence(component, goModFile, confidence = 0.8) {
4876
+ if (goModFile) {
4877
+ component.evidence = {
4878
+ identity: {
4879
+ field: "purl",
4880
+ confidence,
4881
+ methods: [
4882
+ {
4883
+ technique: "manifest-analysis",
4884
+ confidence,
4885
+ value: goModFile,
4886
+ },
4887
+ ],
4888
+ },
4889
+ };
4890
+ if (!component.properties) {
4891
+ component.properties = [];
4892
+ }
4893
+ component.properties.push({
4894
+ name: "SrcFile",
4895
+ value: goModFile,
4896
+ });
4866
4897
  }
4867
- component.properties.push({
4868
- name: "SrcFile",
4869
- value: goModFile,
4870
- });
4871
4898
  return component;
4872
4899
  }
4873
4900
 
@@ -4878,6 +4905,7 @@ function _addGoComponentEvidence(component, goModFile) {
4878
4905
  * @param {string} goModFile go.mod file
4879
4906
  * @param {Object} goSumMap Hashes from gosum for lookups
4880
4907
  * @param {Array} epkgList Existing package list
4908
+ * @param {Object} parentComponent Current parent component
4881
4909
  *
4882
4910
  * @returns Object containing List of packages and dependencies
4883
4911
  */
@@ -4892,7 +4920,33 @@ export async function parseGoModGraph(
4892
4920
  const dependenciesList = [];
4893
4921
  const addedPkgs = {};
4894
4922
  const depsMap = {};
4923
+ // Useful for filtering out invalid components
4895
4924
  const existingPkgMap = {};
4925
+ // Package map by manually parsing the go.mod data
4926
+ let goModPkgMap = {};
4927
+ // Direct dependencies by manually parsing the go.mod data
4928
+ const goModDirectDepsMap = {};
4929
+ // Indirect dependencies by manually parsing the go.mod data
4930
+ const goModOptionalDepsMap = {};
4931
+ const excludedRefs = [];
4932
+ if (goModFile) {
4933
+ goModPkgMap = await parseGoModData(
4934
+ readFileSync(goModFile, { encoding: "utf-8" }),
4935
+ gosumMap,
4936
+ );
4937
+ if (goModPkgMap?.rootList) {
4938
+ for (const epkg of goModPkgMap.rootList) {
4939
+ goModDirectDepsMap[epkg["bom-ref"]] = true;
4940
+ }
4941
+ }
4942
+ if (goModPkgMap?.pkgList) {
4943
+ for (const epkg of goModPkgMap.pkgList) {
4944
+ if (epkg?.scope === "optional") {
4945
+ goModOptionalDepsMap[epkg["bom-ref"]] = true;
4946
+ }
4947
+ }
4948
+ }
4949
+ }
4896
4950
  for (const epkg of epkgList) {
4897
4951
  existingPkgMap[epkg["bom-ref"]] = true;
4898
4952
  }
@@ -4924,7 +4978,7 @@ export async function parseGoModGraph(
4924
4978
  continue;
4925
4979
  }
4926
4980
  // Add the source and depends to the pkgList
4927
- if (!addedPkgs[tmpA[0]]) {
4981
+ if (!addedPkgs[tmpA[0]] && !excludedRefs.includes(sourceRefString)) {
4928
4982
  const component = await getGoPkgComponent(
4929
4983
  "",
4930
4984
  `${sourcePurl.namespace ? `${sourcePurl.namespace}/` : ""}${
@@ -4933,7 +4987,28 @@ export async function parseGoModGraph(
4933
4987
  sourcePurl.version,
4934
4988
  gosumMap[tmpA[0]],
4935
4989
  );
4936
- pkgList.push(_addGoComponentEvidence(component, goModFile));
4990
+ let confidence = 0.7;
4991
+ if (goModOptionalDepsMap[component["bom-ref"]]) {
4992
+ component.scope = "optional";
4993
+ confidence = 0.5;
4994
+ } else if (goModDirectDepsMap[component["bom-ref"]]) {
4995
+ component.scope = "required";
4996
+ }
4997
+ // These are likely false positives
4998
+ if (
4999
+ goModFile &&
5000
+ !Object.keys(existingPkgMap).length &&
5001
+ goModPkgMap?.parentComponent?.["bom-ref"] !== sourceRefString &&
5002
+ !component.scope
5003
+ ) {
5004
+ continue;
5005
+ }
5006
+ // Don't add the parent component to the package list
5007
+ if (goModPkgMap?.parentComponent?.["bom-ref"] !== sourceRefString) {
5008
+ pkgList.push(
5009
+ _addGoComponentEvidence(component, goModFile, confidence),
5010
+ );
5011
+ }
4937
5012
  addedPkgs[tmpA[0]] = true;
4938
5013
  }
4939
5014
  if (!addedPkgs[tmpA[1]]) {
@@ -4945,7 +5020,46 @@ export async function parseGoModGraph(
4945
5020
  dependsPurl.version,
4946
5021
  gosumMap[tmpA[1]],
4947
5022
  );
4948
- pkgList.push(component);
5023
+ let confidence = 0.7;
5024
+ if (goModDirectDepsMap[component["bom-ref"]]) {
5025
+ component.scope = "required";
5026
+ }
5027
+ if (goModOptionalDepsMap[component["bom-ref"]]) {
5028
+ component.scope = "optional";
5029
+ confidence = 0.5;
5030
+ }
5031
+ if (
5032
+ goModPkgMap?.parentComponent?.["bom-ref"] !== sourceRefString &&
5033
+ goModDirectDepsMap[sourceRefString] &&
5034
+ component?.scope !== "required"
5035
+ ) {
5036
+ // If the parent is required, then ensure the child doesn't accidentally become optional or excluded
5037
+ component.scope = undefined;
5038
+ }
5039
+ // Mark the go toolchain components as excluded
5040
+ if (
5041
+ dependsRefString.startsWith("pkg:golang/toolchain@") ||
5042
+ dependsRefString.startsWith("pkg:golang/go@")
5043
+ ) {
5044
+ excludedRefs.push(dependsRefString);
5045
+ continue;
5046
+ }
5047
+ // These are likely false positives
5048
+ if (
5049
+ goModFile &&
5050
+ goModPkgMap?.parentComponent?.["bom-ref"] !== sourceRefString &&
5051
+ !Object.keys(existingPkgMap).length &&
5052
+ !component.scope
5053
+ ) {
5054
+ excludedRefs.push(dependsRefString);
5055
+ continue;
5056
+ }
5057
+ // The confidence for the indirect dependencies is lower
5058
+ // This is because go mod graph emits module requirements graph, which could be different to module compile graph
5059
+ // See https://go.dev/ref/mod#glos-module-graph
5060
+ pkgList.push(
5061
+ _addGoComponentEvidence(component, goModFile, confidence),
5062
+ );
4949
5063
  addedPkgs[tmpA[1]] = true;
4950
5064
  }
4951
5065
  if (!depsMap[sourceRefString]) {
@@ -4954,7 +5068,16 @@ export async function parseGoModGraph(
4954
5068
  if (!depsMap[dependsRefString]) {
4955
5069
  depsMap[dependsRefString] = new Set();
4956
5070
  }
4957
- depsMap[sourceRefString].add(dependsRefString);
5071
+ // Check if the root is really dependent on this component
5072
+ if (
5073
+ goModPkgMap?.parentComponent?.["bom-ref"] === sourceRefString &&
5074
+ Object.keys(goModDirectDepsMap).length &&
5075
+ !goModDirectDepsMap[dependsRefString]
5076
+ ) {
5077
+ // ignore
5078
+ } else if (!excludedRefs.includes(dependsRefString)) {
5079
+ depsMap[sourceRefString].add(dependsRefString);
5080
+ }
4958
5081
  } catch (_e) {
4959
5082
  // pass
4960
5083
  }
@@ -4967,7 +5090,12 @@ export async function parseGoModGraph(
4967
5090
  dependsOn: Array.from(depsMap[adep]).sort(),
4968
5091
  });
4969
5092
  }
4970
- return { pkgList, dependenciesList };
5093
+ return {
5094
+ pkgList: pkgList.sort((a, b) => a.purl.localeCompare(b.purl)),
5095
+ dependenciesList,
5096
+ parentComponent: goModPkgMap?.parentComponent,
5097
+ rootList: goModPkgMap?.rootList,
5098
+ };
4971
5099
  }
4972
5100
 
4973
5101
  /**
@@ -6397,10 +6525,6 @@ function substituteBuildArgs(statement, buildArgs) {
6397
6525
  statement.slice(0, argIndex) +
6398
6526
  buildArgs.get(argName) +
6399
6527
  statement.slice(argIndex + fullArgName.length);
6400
- } else {
6401
- console.warn(
6402
- `Unable to substitute build argument '${fullArgName}' in '${statement}'.`,
6403
- );
6404
6528
  }
6405
6529
  }
6406
6530
  return statement;
@@ -6452,9 +6576,11 @@ export function parseContainerFile(fileContents) {
6452
6576
  if (imageStatement.includes("$")) {
6453
6577
  imageStatement = substituteBuildArgs(imageStatement, buildArgs);
6454
6578
  if (imageStatement.includes("$")) {
6455
- console.warn(
6456
- `Unable to substitute build arguments in '${line}' statement.`,
6457
- );
6579
+ if (DEBUG_MODE) {
6580
+ console.log(
6581
+ `Unable to substitute build arguments in '${line}' statement.`,
6582
+ );
6583
+ }
6458
6584
  continue;
6459
6585
  }
6460
6586
  }
package/utils.test.js CHANGED
@@ -808,67 +808,104 @@ test("get py metadata", async () => {
808
808
  }, 240000);
809
809
 
810
810
  test("parseGoModData", async () => {
811
- let dep_list = await parseGoModData(null);
812
- expect(dep_list).toEqual([]);
811
+ let retMap = await parseGoModData(null);
812
+ expect(retMap).toEqual({});
813
813
  const gosumMap = {
814
814
  "google.golang.org/grpc@v1.21.0":
815
815
  "sha256-oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=",
816
816
  "github.com/aws/aws-sdk-go@v1.38.47": "sha256-fake-sha-for-aws-go-sdk=",
817
817
  "github.com/spf13/cobra@v1.0.0":
818
818
  "sha256-/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE=",
819
- "github.com/spf13/viper@v1.0.2":
819
+ "github.com/spf13/viper@v1.3.0":
820
820
  "sha256-A8kyI5cUJhb8N+3pkfONlcEcZbueH6nhAm0Fq7SrnBM=",
821
821
  "github.com/stretchr/testify@v1.6.1":
822
822
  "sha256-6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=",
823
823
  };
824
- dep_list = await parseGoModData(
824
+ retMap = await parseGoModData(
825
825
  readFileSync("./test/gomod/go.mod", { encoding: "utf-8" }),
826
826
  gosumMap,
827
827
  );
828
- expect(dep_list.length).toEqual(4);
829
- expect(dep_list[0]).toEqual({
830
- group: "",
831
- name: "github.com/aws/aws-sdk-go",
832
- license: undefined,
833
- version: "v1.38.47",
834
- _integrity: "sha256-fake-sha-for-aws-go-sdk=",
835
- "bom-ref": "pkg:golang/github.com/aws/aws-sdk-go@v1.38.47",
836
- purl: "pkg:golang/github.com/aws/aws-sdk-go@v1.38.47",
837
- });
838
- expect(dep_list[1]).toEqual({
839
- group: "",
840
- name: "github.com/spf13/cobra",
841
- "bom-ref": "pkg:golang/github.com/spf13/cobra@v1.0.0",
842
- purl: "pkg:golang/github.com/spf13/cobra@v1.0.0",
843
- license: undefined,
844
- version: "v1.0.0",
845
- _integrity: "sha256-/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE=",
846
- });
847
- expect(dep_list[2]).toEqual({
848
- group: "",
849
- name: "google.golang.org/grpc",
850
- "bom-ref": "pkg:golang/google.golang.org/grpc@v1.21.0",
851
- purl: "pkg:golang/google.golang.org/grpc@v1.21.0",
852
- license: undefined,
853
- version: "v1.21.0",
854
- _integrity: "sha256-oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=",
828
+ expect(retMap.pkgList.length).toEqual(6);
829
+ expect(retMap.pkgList).toEqual([
830
+ {
831
+ group: "",
832
+ name: "github.com/aws/aws-sdk-go",
833
+ version: "v1.38.47",
834
+ _integrity: "sha256-fake-sha-for-aws-go-sdk=",
835
+ purl: "pkg:golang/github.com/aws/aws-sdk-go@v1.38.47",
836
+ "bom-ref": "pkg:golang/github.com/aws/aws-sdk-go@v1.38.47",
837
+ },
838
+ {
839
+ group: "",
840
+ name: "github.com/spf13/cobra",
841
+ version: "v1.0.0",
842
+ _integrity: "sha256-/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE=",
843
+ purl: "pkg:golang/github.com/spf13/cobra@v1.0.0",
844
+ "bom-ref": "pkg:golang/github.com/spf13/cobra@v1.0.0",
845
+ },
846
+ {
847
+ group: "",
848
+ name: "github.com/spf13/viper",
849
+ version: "v1.0.2",
850
+ purl: "pkg:golang/github.com/spf13/viper@v1.0.2",
851
+ "bom-ref": "pkg:golang/github.com/spf13/viper@v1.0.2",
852
+ },
853
+ {
854
+ group: "",
855
+ name: "github.com/spf13/viper",
856
+ version: "v1.3.0",
857
+ _integrity: "sha256-A8kyI5cUJhb8N+3pkfONlcEcZbueH6nhAm0Fq7SrnBM=",
858
+ purl: "pkg:golang/github.com/spf13/viper@v1.3.0",
859
+ "bom-ref": "pkg:golang/github.com/spf13/viper@v1.3.0",
860
+ },
861
+ {
862
+ group: "",
863
+ name: "google.golang.org/grpc",
864
+ version: "v1.21.0",
865
+ _integrity: "sha256-oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=",
866
+ purl: "pkg:golang/google.golang.org/grpc@v1.21.0",
867
+ "bom-ref": "pkg:golang/google.golang.org/grpc@v1.21.0",
868
+ },
869
+ {
870
+ group: "",
871
+ name: "google.golang.org/grpc",
872
+ version: "v1.32.0",
873
+ purl: "pkg:golang/google.golang.org/grpc@v1.32.0",
874
+ "bom-ref": "pkg:golang/google.golang.org/grpc@v1.32.0",
875
+ },
876
+ ]);
877
+
878
+ retMap.pkgList.forEach((d) => {
879
+ expect(d.license);
855
880
  });
856
- expect(dep_list[3]).toEqual({
857
- group: "",
858
- name: "github.com/spf13/viper",
859
- "bom-ref": "pkg:golang/github.com/spf13/viper@v1.0.2",
860
- purl: "pkg:golang/github.com/spf13/viper@v1.0.2",
861
- license: undefined,
862
- version: "v1.0.2",
863
- _integrity: "sha256-A8kyI5cUJhb8N+3pkfONlcEcZbueH6nhAm0Fq7SrnBM=",
881
+ retMap = await parseGoModData(
882
+ readFileSync("./test/data/go-dvwa.mod", { encoding: "utf-8" }),
883
+ {},
884
+ );
885
+ expect(retMap.parentComponent).toEqual({
886
+ "bom-ref": "pkg:golang/github.com/sqreen/go-dvwa",
887
+ name: "github.com/sqreen/go-dvwa",
888
+ purl: "pkg:golang/github.com/sqreen/go-dvwa",
889
+ type: "application",
864
890
  });
865
- dep_list.forEach((d) => {
866
- expect(d.license);
891
+ expect(retMap.pkgList.length).toEqual(19);
892
+ expect(retMap.rootList.length).toEqual(4);
893
+ retMap = await parseGoModData(
894
+ readFileSync("./test/data/go-syft.mod", { encoding: "utf-8" }),
895
+ {},
896
+ );
897
+ expect(retMap.parentComponent).toEqual({
898
+ "bom-ref": "pkg:golang/github.com/anchore/syft",
899
+ name: "github.com/anchore/syft",
900
+ purl: "pkg:golang/github.com/anchore/syft",
901
+ type: "application",
867
902
  });
903
+ expect(retMap.pkgList.length).toEqual(239);
904
+ expect(retMap.rootList.length).toEqual(84);
868
905
  }, 120000);
869
906
 
870
907
  test("parseGoSumData", async () => {
871
- let dep_list = await parseGoModData(null);
908
+ let dep_list = await parseGosumData(null);
872
909
  expect(dep_list).toEqual([]);
873
910
  dep_list = await parseGosumData(
874
911
  readFileSync("./test/gomod/go.sum", { encoding: "utf-8" }),
@@ -938,35 +975,53 @@ test("parse go list dependencies", async () => {
938
975
  });
939
976
 
940
977
  test("parse go mod graph", async () => {
941
- const retMap = await parseGoModGraph(
978
+ let retMap = await parseGoModGraph(
942
979
  readFileSync("./test/data/gomod-graph.txt", { encoding: "utf-8" }),
943
- "./test/data/gomod-graph.txt",
980
+ undefined,
944
981
  {},
945
982
  [],
946
983
  {},
947
984
  );
948
- expect(retMap.pkgList.length).toEqual(537);
985
+ expect(retMap.pkgList.length).toEqual(536);
949
986
  expect(retMap.pkgList[0]).toEqual({
987
+ _integrity: undefined,
988
+ "bom-ref": "pkg:golang/cloud.google.com/go@v0.26.0",
950
989
  group: "",
990
+ license: undefined,
991
+ name: "cloud.google.com/go",
992
+ purl: "pkg:golang/cloud.google.com/go@v0.26.0",
993
+ version: "v0.26.0",
994
+ });
995
+ retMap = await parseGoModGraph(
996
+ readFileSync("./test/data/gomod-dvwa-graph.txt", { encoding: "utf-8" }),
997
+ "./test/data/go-dvwa.mod",
998
+ {},
999
+ [],
1000
+ {},
1001
+ );
1002
+ expect(retMap.parentComponent).toEqual({
1003
+ "bom-ref": "pkg:golang/github.com/sqreen/go-dvwa",
951
1004
  name: "github.com/sqreen/go-dvwa",
952
- version: null,
953
1005
  purl: "pkg:golang/github.com/sqreen/go-dvwa",
954
- "bom-ref": "pkg:golang/github.com/sqreen/go-dvwa",
955
- evidence: {
956
- identity: {
957
- field: "purl",
958
- confidence: 1,
959
- methods: [
960
- {
961
- technique: "manifest-analysis",
962
- confidence: 1,
963
- value: "./test/data/gomod-graph.txt",
964
- },
965
- ],
966
- },
967
- },
968
- properties: [{ name: "SrcFile", value: "./test/data/gomod-graph.txt" }],
1006
+ type: "application",
1007
+ });
1008
+ expect(retMap.pkgList.length).toEqual(19);
1009
+ expect(retMap.rootList.length).toEqual(4);
1010
+ retMap = await parseGoModGraph(
1011
+ readFileSync("./test/data/gomod-syft-graph.txt", { encoding: "utf-8" }),
1012
+ "./test/data/go-syft.mod",
1013
+ {},
1014
+ [],
1015
+ {},
1016
+ );
1017
+ expect(retMap.parentComponent).toEqual({
1018
+ "bom-ref": "pkg:golang/github.com/anchore/syft",
1019
+ name: "github.com/anchore/syft",
1020
+ purl: "pkg:golang/github.com/anchore/syft",
1021
+ type: "application",
969
1022
  });
1023
+ expect(retMap.pkgList.length).toEqual(235);
1024
+ expect(retMap.rootList.length).toEqual(84);
970
1025
  });
971
1026
 
972
1027
  test("parse go mod why dependencies", () => {
@@ -3033,8 +3088,8 @@ test("parsePnpmLock", async () => {
3033
3088
  expect(parsedList.dependenciesList).toHaveLength(462);
3034
3089
  expect(parsedList.pkgList.filter((pkg) => !pkg.scope)).toHaveLength(3);
3035
3090
  parsedList = await parsePnpmLock("./pnpm-lock.yaml");
3036
- expect(parsedList.pkgList.length).toEqual(653);
3037
- expect(parsedList.dependenciesList.length).toEqual(653);
3091
+ expect(parsedList.pkgList.length).toEqual(655);
3092
+ expect(parsedList.dependenciesList.length).toEqual(655);
3038
3093
  expect(parsedList.pkgList[0]).toEqual({
3039
3094
  group: "@ampproject",
3040
3095
  name: "remapping",
package/validator.js CHANGED
@@ -75,7 +75,9 @@ export const validateMetadata = (bomJson) => {
75
75
  !bomJson.metadata.component ||
76
76
  !Object.keys(bomJson.metadata.component).length
77
77
  ) {
78
- warningsList.push("metadata.component is missing.");
78
+ warningsList.push(
79
+ "metadata.component is missing. Run cdxgen with both --project-name and --project-version argument.",
80
+ );
79
81
  }
80
82
  if (bomJson.metadata.component) {
81
83
  // Do we have a purl and bom-ref for metadata.component
@@ -87,7 +89,9 @@ export const validateMetadata = (bomJson) => {
87
89
  }
88
90
  // Do we have a version for metadata.component
89
91
  if (!bomJson.metadata.component.version) {
90
- warningsList.push("Version is missing for metadata.component");
92
+ warningsList.push(
93
+ "Version is missing for metadata.component. Pass the version using --project-version argument.",
94
+ );
91
95
  }
92
96
  // Is the same component getting repeated inside the components block
93
97
  if (bomJson.metadata.component.components?.length) {