@cyclonedx/cdxgen 12.1.5 → 12.2.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.
Files changed (181) hide show
  1. package/README.md +47 -39
  2. package/bin/cdxgen.js +175 -96
  3. package/bin/evinse.js +4 -4
  4. package/bin/repl.js +1 -1
  5. package/bin/sign.js +102 -0
  6. package/bin/validate.js +233 -0
  7. package/bin/verify.js +69 -28
  8. package/data/queries.json +1 -1
  9. package/data/rules/ci-permissions.yaml +186 -0
  10. package/data/rules/dependency-sources.yaml +123 -0
  11. package/data/rules/package-integrity.yaml +135 -0
  12. package/data/rules/vscode-extensions.yaml +228 -0
  13. package/lib/cli/index.js +327 -372
  14. package/lib/evinser/db.js +137 -0
  15. package/lib/{helpers → evinser}/db.poku.js +2 -6
  16. package/lib/evinser/evinser.js +2 -14
  17. package/lib/helpers/bomSigner.js +312 -0
  18. package/lib/helpers/bomSigner.poku.js +156 -0
  19. package/lib/helpers/ciParsers/azurePipelines.js +295 -0
  20. package/lib/helpers/ciParsers/azurePipelines.poku.js +253 -0
  21. package/lib/helpers/ciParsers/circleCi.js +286 -0
  22. package/lib/helpers/ciParsers/circleCi.poku.js +230 -0
  23. package/lib/helpers/ciParsers/common.js +24 -0
  24. package/lib/helpers/ciParsers/githubActions.js +636 -0
  25. package/lib/helpers/ciParsers/githubActions.poku.js +802 -0
  26. package/lib/helpers/ciParsers/gitlabCi.js +213 -0
  27. package/lib/helpers/ciParsers/gitlabCi.poku.js +247 -0
  28. package/lib/helpers/ciParsers/jenkins.js +181 -0
  29. package/lib/helpers/ciParsers/jenkins.poku.js +197 -0
  30. package/lib/helpers/depsUtils.js +203 -0
  31. package/lib/helpers/depsUtils.poku.js +150 -0
  32. package/lib/helpers/display.js +423 -4
  33. package/lib/helpers/envcontext.js +18 -3
  34. package/lib/helpers/formulationParsers.js +351 -0
  35. package/lib/helpers/logger.js +14 -0
  36. package/lib/helpers/protobom.js +9 -9
  37. package/lib/helpers/pythonutils.js +9 -0
  38. package/lib/helpers/utils.js +681 -406
  39. package/lib/helpers/utils.poku.js +55 -255
  40. package/lib/helpers/versutils.js +202 -0
  41. package/lib/helpers/versutils.poku.js +315 -0
  42. package/lib/helpers/vsixutils.js +1061 -0
  43. package/lib/helpers/vsixutils.poku.js +2247 -0
  44. package/lib/managers/binary.js +19 -19
  45. package/lib/managers/docker.js +108 -1
  46. package/lib/managers/oci.js +10 -0
  47. package/lib/managers/piptree.js +3 -9
  48. package/lib/parsers/npmrc.js +17 -13
  49. package/lib/parsers/npmrc.poku.js +41 -5
  50. package/lib/server/openapi.yaml +1 -1
  51. package/lib/server/server.js +40 -11
  52. package/lib/server/server.poku.js +123 -144
  53. package/lib/stages/postgen/annotator.js +1 -1
  54. package/lib/stages/postgen/auditBom.js +197 -0
  55. package/lib/stages/postgen/auditBom.poku.js +378 -0
  56. package/lib/stages/postgen/postgen.js +54 -1
  57. package/lib/stages/postgen/postgen.poku.js +90 -1
  58. package/lib/stages/postgen/ruleEngine.js +369 -0
  59. package/lib/stages/pregen/envAudit.js +299 -0
  60. package/lib/stages/pregen/envAudit.poku.js +572 -0
  61. package/lib/stages/pregen/pregen.js +12 -8
  62. package/lib/{helpers/validator.js → validator/bomValidator.js} +107 -47
  63. package/lib/validator/complianceEngine.js +241 -0
  64. package/lib/validator/complianceEngine.poku.js +168 -0
  65. package/lib/validator/complianceRules.js +1610 -0
  66. package/lib/validator/complianceRules.poku.js +328 -0
  67. package/lib/validator/index.js +222 -0
  68. package/lib/validator/index.poku.js +144 -0
  69. package/lib/validator/reporters/annotations.js +121 -0
  70. package/lib/validator/reporters/console.js +149 -0
  71. package/lib/validator/reporters/index.js +41 -0
  72. package/lib/validator/reporters/json.js +37 -0
  73. package/lib/validator/reporters/sarif.js +184 -0
  74. package/lib/validator/reporters.poku.js +150 -0
  75. package/package.json +8 -8
  76. package/types/bin/sign.d.ts +3 -0
  77. package/types/bin/sign.d.ts.map +1 -0
  78. package/types/bin/validate.d.ts +3 -0
  79. package/types/bin/validate.d.ts.map +1 -0
  80. package/types/helpers/utils.d.ts +0 -1
  81. package/types/lib/cli/index.d.ts +49 -52
  82. package/types/lib/cli/index.d.ts.map +1 -1
  83. package/types/lib/evinser/db.d.ts +34 -0
  84. package/types/lib/evinser/db.d.ts.map +1 -0
  85. package/types/lib/evinser/evinser.d.ts +63 -16
  86. package/types/lib/evinser/evinser.d.ts.map +1 -1
  87. package/types/lib/helpers/bomSigner.d.ts +27 -0
  88. package/types/lib/helpers/bomSigner.d.ts.map +1 -0
  89. package/types/lib/helpers/ciParsers/azurePipelines.d.ts +17 -0
  90. package/types/lib/helpers/ciParsers/azurePipelines.d.ts.map +1 -0
  91. package/types/lib/helpers/ciParsers/circleCi.d.ts +17 -0
  92. package/types/lib/helpers/ciParsers/circleCi.d.ts.map +1 -0
  93. package/types/lib/helpers/ciParsers/common.d.ts +11 -0
  94. package/types/lib/helpers/ciParsers/common.d.ts.map +1 -0
  95. package/types/lib/helpers/ciParsers/githubActions.d.ts +34 -0
  96. package/types/lib/helpers/ciParsers/githubActions.d.ts.map +1 -0
  97. package/types/lib/helpers/ciParsers/gitlabCi.d.ts +17 -0
  98. package/types/lib/helpers/ciParsers/gitlabCi.d.ts.map +1 -0
  99. package/types/lib/helpers/ciParsers/jenkins.d.ts +17 -0
  100. package/types/lib/helpers/ciParsers/jenkins.d.ts.map +1 -0
  101. package/types/lib/helpers/depsUtils.d.ts +21 -0
  102. package/types/lib/helpers/depsUtils.d.ts.map +1 -0
  103. package/types/lib/helpers/display.d.ts +111 -11
  104. package/types/lib/helpers/display.d.ts.map +1 -1
  105. package/types/lib/helpers/envcontext.d.ts +19 -7
  106. package/types/lib/helpers/envcontext.d.ts.map +1 -1
  107. package/types/lib/helpers/formulationParsers.d.ts +50 -0
  108. package/types/lib/helpers/formulationParsers.d.ts.map +1 -0
  109. package/types/lib/helpers/logger.d.ts +15 -1
  110. package/types/lib/helpers/logger.d.ts.map +1 -1
  111. package/types/lib/helpers/protobom.d.ts +2 -2
  112. package/types/lib/helpers/pythonutils.d.ts +10 -1
  113. package/types/lib/helpers/pythonutils.d.ts.map +1 -1
  114. package/types/lib/helpers/utils.d.ts +532 -128
  115. package/types/lib/helpers/utils.d.ts.map +1 -1
  116. package/types/lib/helpers/versutils.d.ts +8 -0
  117. package/types/lib/helpers/versutils.d.ts.map +1 -0
  118. package/types/lib/helpers/vsixutils.d.ts +130 -0
  119. package/types/lib/helpers/vsixutils.d.ts.map +1 -0
  120. package/types/lib/managers/docker.d.ts +12 -31
  121. package/types/lib/managers/docker.d.ts.map +1 -1
  122. package/types/lib/managers/oci.d.ts +11 -1
  123. package/types/lib/managers/oci.d.ts.map +1 -1
  124. package/types/lib/managers/piptree.d.ts.map +1 -1
  125. package/types/lib/parsers/npmrc.d.ts +4 -1
  126. package/types/lib/parsers/npmrc.d.ts.map +1 -1
  127. package/types/lib/server/server.d.ts +21 -2
  128. package/types/lib/server/server.d.ts.map +1 -1
  129. package/types/lib/stages/postgen/auditBom.d.ts +20 -0
  130. package/types/lib/stages/postgen/auditBom.d.ts.map +1 -0
  131. package/types/lib/stages/postgen/postgen.d.ts +8 -1
  132. package/types/lib/stages/postgen/postgen.d.ts.map +1 -1
  133. package/types/lib/stages/postgen/ruleEngine.d.ts +18 -0
  134. package/types/lib/stages/postgen/ruleEngine.d.ts.map +1 -0
  135. package/types/lib/stages/pregen/envAudit.d.ts +8 -0
  136. package/types/lib/stages/pregen/envAudit.d.ts.map +1 -0
  137. package/types/lib/stages/pregen/pregen.d.ts.map +1 -1
  138. package/types/lib/{helpers/validator.d.ts → validator/bomValidator.d.ts} +1 -1
  139. package/types/lib/validator/bomValidator.d.ts.map +1 -0
  140. package/types/lib/validator/complianceEngine.d.ts +66 -0
  141. package/types/lib/validator/complianceEngine.d.ts.map +1 -0
  142. package/types/lib/validator/complianceRules.d.ts +70 -0
  143. package/types/lib/validator/complianceRules.d.ts.map +1 -0
  144. package/types/lib/validator/index.d.ts +70 -0
  145. package/types/lib/validator/index.d.ts.map +1 -0
  146. package/types/lib/validator/reporters/annotations.d.ts +31 -0
  147. package/types/lib/validator/reporters/annotations.d.ts.map +1 -0
  148. package/types/lib/validator/reporters/console.d.ts +30 -0
  149. package/types/lib/validator/reporters/console.d.ts.map +1 -0
  150. package/types/lib/validator/reporters/index.d.ts +21 -0
  151. package/types/lib/validator/reporters/index.d.ts.map +1 -0
  152. package/types/lib/validator/reporters/json.d.ts +11 -0
  153. package/types/lib/validator/reporters/json.d.ts.map +1 -0
  154. package/types/lib/validator/reporters/sarif.d.ts +16 -0
  155. package/types/lib/validator/reporters/sarif.d.ts.map +1 -0
  156. package/lib/helpers/db.js +0 -162
  157. package/lib/stages/pregen/env-audit.js +0 -34
  158. package/lib/stages/pregen/env-audit.poku.js +0 -290
  159. package/types/helpers/db.d.ts +0 -35
  160. package/types/helpers/db.d.ts.map +0 -1
  161. package/types/lib/helpers/db.d.ts +0 -35
  162. package/types/lib/helpers/db.d.ts.map +0 -1
  163. package/types/lib/helpers/validator.d.ts.map +0 -1
  164. package/types/lib/stages/pregen/env-audit.d.ts +0 -2
  165. package/types/lib/stages/pregen/env-audit.d.ts.map +0 -1
  166. package/types/managers/binary.d.ts +0 -37
  167. package/types/managers/binary.d.ts.map +0 -1
  168. package/types/managers/docker.d.ts +0 -56
  169. package/types/managers/docker.d.ts.map +0 -1
  170. package/types/managers/oci.d.ts +0 -2
  171. package/types/managers/oci.d.ts.map +0 -1
  172. package/types/managers/piptree.d.ts +0 -2
  173. package/types/managers/piptree.d.ts.map +0 -1
  174. package/types/server/server.d.ts +0 -34
  175. package/types/server/server.d.ts.map +0 -1
  176. package/types/stages/postgen/annotator.d.ts +0 -27
  177. package/types/stages/postgen/annotator.d.ts.map +0 -1
  178. package/types/stages/postgen/postgen.d.ts +0 -51
  179. package/types/stages/postgen/postgen.d.ts.map +0 -1
  180. package/types/stages/pregen/pregen.d.ts +0 -59
  181. package/types/stages/pregen/pregen.d.ts.map +0 -1
@@ -11,53 +11,71 @@ import {
11
11
  validateAndRejectGitSource,
12
12
  } from "./server.js";
13
13
 
14
+ function nullProtoObj(obj) {
15
+ if (obj === null || typeof obj !== "object") {
16
+ return obj;
17
+ }
18
+ if (Array.isArray(obj)) {
19
+ return obj.map(nullProtoObj);
20
+ }
21
+ if (Object.prototype.toString.call(obj) === "[object Object]") {
22
+ const result = Object.create(null);
23
+ for (const [key, value] of Object.entries(obj)) {
24
+ result[key] = nullProtoObj(value);
25
+ }
26
+ return result;
27
+ }
28
+ return obj;
29
+ }
30
+
31
+ function checkEqual(actual, expected, message) {
32
+ assert.deepStrictEqual(nullProtoObj(actual), nullProtoObj(expected), message);
33
+ }
34
+
14
35
  it("parseValue tests", () => {
15
- assert.deepStrictEqual(parseValue("foo"), "foo");
16
- assert.deepStrictEqual(parseValue("foo\n"), "foo");
17
- assert.deepStrictEqual(parseValue("foo\r\n"), "foo");
18
- assert.deepStrictEqual(parseValue(1), 1);
19
- assert.deepStrictEqual(parseValue("true"), true);
20
- assert.deepStrictEqual(parseValue("false"), false);
21
- assert.deepStrictEqual(parseValue(["foo", "bar", 42]), ["foo", "bar", 42]);
36
+ checkEqual(parseValue("foo"), "foo");
37
+ checkEqual(parseValue("foo\n"), "foo");
38
+ checkEqual(parseValue("foo\r\n"), "foo");
39
+ checkEqual(parseValue(1), 1);
40
+ checkEqual(parseValue("true"), true);
41
+ checkEqual(parseValue("false"), false);
42
+ checkEqual(parseValue(["foo", "bar", 42]), ["foo", "bar", 42]);
22
43
  assert.throws(() => parseValue({ foo: "bar" }), TypeError);
23
44
  assert.throws(() => parseValue([42, "foo", { foo: "bar" }]), TypeError);
24
45
  assert.throws(() => parseValue([42, "foo", new Error()]), TypeError);
25
46
  assert.throws(() => parseValue(["foo", "bar", new String(42)]), TypeError);
26
- assert.deepStrictEqual(parseValue(true), true);
27
- assert.deepStrictEqual(parseValue(false), false);
28
- assert.deepStrictEqual(parseValue(null), null);
29
- assert.deepStrictEqual(parseValue(undefined), undefined);
30
- assert.deepStrictEqual(parseValue([null, undefined, null]), [
47
+ checkEqual(parseValue(true), true);
48
+ checkEqual(parseValue(false), false);
49
+ checkEqual(parseValue(null), null);
50
+ checkEqual(parseValue(undefined), undefined);
51
+ checkEqual(parseValue([null, undefined, null]), [null, undefined, null]);
52
+ checkEqual(parseValue(""), "");
53
+ checkEqual(parseValue(" \n"), " ");
54
+ checkEqual(parseValue("42"), "42");
55
+ checkEqual(parseValue("0"), "0");
56
+ checkEqual(parseValue("-1"), "-1");
57
+ checkEqual(parseValue("True"), "True");
58
+ checkEqual(parseValue("False"), "False");
59
+ checkEqual(parseValue(" TRUE "), " TRUE ");
60
+ checkEqual(parseValue(["true", "false", 0, "0", null, undefined]), [
61
+ true,
62
+ false,
63
+ 0,
64
+ "0",
31
65
  null,
32
66
  undefined,
33
- null,
34
67
  ]);
35
- assert.deepStrictEqual(parseValue(""), "");
36
- assert.deepStrictEqual(parseValue(" \n"), " ");
37
- assert.deepStrictEqual(parseValue("42"), "42");
38
- assert.deepStrictEqual(parseValue("0"), "0");
39
- assert.deepStrictEqual(parseValue("-1"), "-1");
40
- assert.deepStrictEqual(parseValue("True"), "True");
41
- assert.deepStrictEqual(parseValue("False"), "False");
42
- assert.deepStrictEqual(parseValue(" TRUE "), " TRUE ");
43
- assert.deepStrictEqual(
44
- parseValue(["true", "false", 0, "0", null, undefined]),
45
- [true, false, 0, "0", null, undefined],
46
- );
47
68
  assert.throws(() => parseValue([["nested"]]), TypeError);
48
69
  assert.throws(() => parseValue(Symbol("test")), TypeError);
49
70
  assert.throws(() => parseValue(BigInt(42)), TypeError);
50
71
  // biome-ignore-start lint/suspicious/noEmptyBlockStatements: test
51
72
  assert.throws(() => parseValue(() => {}), TypeError);
52
73
  // biome-ignore-end lint/suspicious/noEmptyBlockStatements: test
53
- assert.deepStrictEqual(parseValue(Number.NaN), Number.NaN);
54
- assert.deepStrictEqual(
55
- parseValue(Number.POSITIVE_INFINITY),
56
- Number.POSITIVE_INFINITY,
57
- );
74
+ checkEqual(parseValue(Number.NaN), Number.NaN);
75
+ checkEqual(parseValue(Number.POSITIVE_INFINITY), Number.POSITIVE_INFINITY);
58
76
  const obj = { toString: () => "foo" };
59
77
  assert.throws(() => parseValue(obj), TypeError);
60
- assert.deepStrictEqual(parseValue("hello\r\n"), "hello");
78
+ checkEqual(parseValue("hello\r\n"), "hello");
61
79
  });
62
80
 
63
81
  describe("parseQueryString tests", () => {
@@ -70,22 +88,22 @@ describe("parseQueryString tests", () => {
70
88
  };
71
89
  const options = {};
72
90
  const result = parseQueryString(q, body, options);
73
- assert.deepStrictEqual(result.foo, undefined);
74
- assert.deepStrictEqual(result.excludeType, ["2"]);
75
- assert.deepStrictEqual(result.technique, ["manifest-analysis"]);
91
+ checkEqual(result.foo, undefined);
92
+ checkEqual(result.excludeType, ["2"]);
93
+ checkEqual(result.technique, ["manifest-analysis"]);
76
94
  });
77
95
 
78
96
  it("splits type into projectType and removes type", () => {
79
97
  const options = { type: "a,b,c" };
80
98
  const result = parseQueryString({}, {}, options);
81
- assert.deepStrictEqual(result.projectType, ["a", "b", "c"]);
82
- assert.deepStrictEqual(result.type, undefined);
99
+ checkEqual(result.projectType, ["a", "b", "c"]);
100
+ checkEqual(result.type, undefined);
83
101
  });
84
102
 
85
103
  it("sets installDeps to false for pre-build lifecycle", () => {
86
104
  const options = { lifecycle: "pre-build" };
87
105
  const result = parseQueryString({}, {}, options);
88
- assert.deepStrictEqual(result.installDeps, false);
106
+ checkEqual(result.installDeps, false);
89
107
  });
90
108
  });
91
109
 
@@ -102,23 +120,23 @@ describe("isAllowedHost()", () => {
102
120
 
103
121
  it("returns true if CDXGEN_SERVER_ALLOWED_HOSTS is not set", () => {
104
122
  delete process.env.CDXGEN_SERVER_ALLOWED_HOSTS;
105
- assert.deepStrictEqual(isAllowedHost("anything"), true);
123
+ checkEqual(isAllowedHost("anything"), true);
106
124
  });
107
125
 
108
126
  it("returns true for a hostname that is in the list", () => {
109
127
  process.env.CDXGEN_SERVER_ALLOWED_HOSTS = "foo.com,bar.com";
110
- assert.deepStrictEqual(isAllowedHost("foo.com"), true);
111
- assert.deepStrictEqual(isAllowedHost("bar.com"), true);
128
+ checkEqual(isAllowedHost("foo.com"), true);
129
+ checkEqual(isAllowedHost("bar.com"), true);
112
130
  });
113
131
 
114
132
  it("returns false for a hostname not in the list", () => {
115
133
  process.env.CDXGEN_SERVER_ALLOWED_HOSTS = "foo.com,bar.com";
116
- assert.deepStrictEqual(isAllowedHost("baz.com"), false);
134
+ checkEqual(isAllowedHost("baz.com"), false);
117
135
  });
118
136
 
119
137
  it("treats an empty-string env var as unset (returns true)", () => {
120
138
  process.env.CDXGEN_SERVER_ALLOWED_HOSTS = "";
121
- assert.deepStrictEqual(isAllowedHost("whatever"), true);
139
+ checkEqual(isAllowedHost("whatever"), true);
122
140
  });
123
141
  });
124
142
 
@@ -203,15 +221,15 @@ describe("isAllowedPath()", () => {
203
221
  describe("isAllowedWinPath windows tests()", () => {
204
222
  it("returns false for windows device name paths", () => {
205
223
  if (isWin) {
206
- assert.deepStrictEqual(isAllowedWinPath("CON:../foo"), false);
207
- assert.deepStrictEqual(isAllowedWinPath("X:\\foo\\..\\bar"), true);
208
- assert.deepStrictEqual(isAllowedWinPath("C:\\Users"), true);
209
- assert.deepStrictEqual(isAllowedWinPath("C:\\🚀"), true);
210
- assert.deepStrictEqual(isAllowedWinPath("C:"), true);
211
- assert.deepStrictEqual(isAllowedWinPath("c:"), true);
212
- assert.deepStrictEqual(isAllowedWinPath("CON:"), false);
213
- assert.deepStrictEqual(isAllowedWinPath("COM¹:"), false);
214
- assert.deepStrictEqual(isAllowedWinPath("COM¹:../foo"), false);
224
+ checkEqual(isAllowedWinPath("CON:../foo"), false);
225
+ checkEqual(isAllowedWinPath("X:\\foo\\..\\bar"), true);
226
+ checkEqual(isAllowedWinPath("C:\\Users"), true);
227
+ checkEqual(isAllowedWinPath("C:\\🚀"), true);
228
+ checkEqual(isAllowedWinPath("C:"), true);
229
+ checkEqual(isAllowedWinPath("c:"), true);
230
+ checkEqual(isAllowedWinPath("CON:"), false);
231
+ checkEqual(isAllowedWinPath("COM¹:"), false);
232
+ checkEqual(isAllowedWinPath("COM¹:../foo"), false);
215
233
  for (const d of [
216
234
  "PRN:.\\..\\bar",
217
235
  "LpT5:/another/path",
@@ -244,7 +262,7 @@ describe("isAllowedWinPath windows tests()", () => {
244
262
  "🚀:\\",
245
263
  "⚡:\\",
246
264
  ]) {
247
- assert.deepStrictEqual(isAllowedWinPath(d), false);
265
+ checkEqual(isAllowedWinPath(d), false);
248
266
  }
249
267
  }
250
268
  });
@@ -264,7 +282,7 @@ describe("getQueryParams", () => {
264
282
  );
265
283
  const result = getQueryParams(req);
266
284
 
267
- assert.deepStrictEqual(result, {
285
+ checkEqual(result, {
268
286
  url: "https://example.com",
269
287
  multiProject: "true",
270
288
  type: "js",
@@ -277,7 +295,7 @@ describe("getQueryParams", () => {
277
295
  );
278
296
  const result = getQueryParams(req);
279
297
 
280
- assert.deepStrictEqual(result, {
298
+ checkEqual(result, {
281
299
  q: "hello world",
282
300
  filter: "category=tech",
283
301
  });
@@ -288,7 +306,7 @@ describe("getQueryParams", () => {
288
306
  const result = getQueryParams(req);
289
307
 
290
308
  // URLSearchParams.entries() returns the first value when there are duplicates
291
- assert.deepStrictEqual(result, {
309
+ checkEqual(result, {
292
310
  tags: ["javascript", "react", "node"],
293
311
  });
294
312
  });
@@ -297,21 +315,21 @@ describe("getQueryParams", () => {
297
315
  const req = createMockRequest("/sbom");
298
316
  const result = getQueryParams(req);
299
317
 
300
- assert.deepStrictEqual(result, {});
318
+ checkEqual(result, {});
301
319
  });
302
320
 
303
321
  it("should handle query string with only question mark", () => {
304
322
  const req = createMockRequest("/sbom?");
305
323
  const result = getQueryParams(req);
306
324
 
307
- assert.deepStrictEqual(result, {});
325
+ checkEqual(result, {});
308
326
  });
309
327
 
310
328
  it("should handle parameters without values", () => {
311
329
  const req = createMockRequest("/api?flag1&flag2&param=value");
312
330
  const result = getQueryParams(req);
313
331
 
314
- assert.deepStrictEqual(result, {
332
+ checkEqual(result, {
315
333
  flag1: "",
316
334
  flag2: "",
317
335
  param: "value",
@@ -325,7 +343,7 @@ describe("getQueryParams", () => {
325
343
  );
326
344
  const result = getQueryParams(req);
327
345
 
328
- assert.deepStrictEqual(result, {
346
+ checkEqual(result, {
329
347
  param1: "value1",
330
348
  });
331
349
  });
@@ -338,7 +356,7 @@ describe("getQueryParams", () => {
338
356
  );
339
357
  const result = getQueryParams(req);
340
358
 
341
- assert.deepStrictEqual(result, {
359
+ checkEqual(result, {
342
360
  token: "abc123",
343
361
  });
344
362
  });
@@ -349,7 +367,7 @@ describe("getQueryParams", () => {
349
367
  );
350
368
  const result = getQueryParams(req);
351
369
 
352
- assert.deepStrictEqual(result, {
370
+ checkEqual(result, {
353
371
  name: "john",
354
372
  age: "25",
355
373
  active: "true",
@@ -362,7 +380,7 @@ describe("getQueryParams", () => {
362
380
  );
363
381
  const result = getQueryParams(req);
364
382
 
365
- assert.deepStrictEqual(result, {
383
+ checkEqual(result, {
366
384
  q: "hello world!",
367
385
  category: "web development",
368
386
  });
@@ -372,14 +390,14 @@ describe("getQueryParams", () => {
372
390
  const req = createMockRequest(undefined);
373
391
  const result = getQueryParams(req);
374
392
 
375
- assert.deepStrictEqual(result, {});
393
+ checkEqual(result, {});
376
394
  });
377
395
 
378
396
  it("should handle numeric values as strings", () => {
379
397
  const req = createMockRequest("/calculate?x=10&y=20&operation=add");
380
398
  const result = getQueryParams(req);
381
399
 
382
- assert.deepStrictEqual(result, {
400
+ checkEqual(result, {
383
401
  x: "10",
384
402
  y: "20",
385
403
  operation: "add",
@@ -390,7 +408,7 @@ describe("getQueryParams", () => {
390
408
  const req = createMockRequest("/config?debug=true&verbose=false&enabled=1");
391
409
  const result = getQueryParams(req);
392
410
 
393
- assert.deepStrictEqual(result, {
411
+ checkEqual(result, {
394
412
  debug: "true",
395
413
  verbose: "false",
396
414
  enabled: "1",
@@ -402,7 +420,7 @@ describe("getQueryParams", () => {
402
420
  const req = createMockRequest("not-a-valid-url");
403
421
  const result = getQueryParams(req);
404
422
 
405
- assert.deepStrictEqual(result, {});
423
+ checkEqual(result, {});
406
424
  });
407
425
 
408
426
  it("should handle empty host gracefully", () => {
@@ -413,7 +431,7 @@ describe("getQueryParams", () => {
413
431
  };
414
432
  const result = getQueryParams(req);
415
433
 
416
- assert.deepStrictEqual(result, {
434
+ checkEqual(result, {
417
435
  param: "value",
418
436
  });
419
437
  });
@@ -426,7 +444,7 @@ describe("getQueryParams", () => {
426
444
  };
427
445
  const result = getQueryParams(req);
428
446
 
429
- assert.deepStrictEqual(result, {
447
+ checkEqual(result, {
430
448
  param: "value",
431
449
  });
432
450
  });
@@ -450,84 +468,60 @@ describe("validateGitSource() tests", () => {
450
468
  });
451
469
 
452
470
  it("should reject ext:: and fd:: outright", () => {
453
- assert.deepStrictEqual(
471
+ checkEqual(
454
472
  validateAndRejectGitSource("ext::sh -c id").error,
455
473
  "Invalid Protocol",
456
474
  );
457
- assert.deepStrictEqual(
458
- validateAndRejectGitSource("fd::123").error,
459
- "Invalid Protocol",
460
- );
461
- assert.deepStrictEqual(
475
+ checkEqual(validateAndRejectGitSource("fd::123").error, "Invalid Protocol");
476
+ checkEqual(
462
477
  validateAndRejectGitSource("EXT::sh -c id").error,
463
478
  "Invalid Protocol",
464
479
  );
465
480
  });
466
481
 
467
482
  it("should allow standard local paths to bypass validation", () => {
468
- assert.deepStrictEqual(validateAndRejectGitSource("/tmp/local-path"), null);
469
- assert.deepStrictEqual(
470
- validateAndRejectGitSource("C:\\Users\\local"),
471
- null,
472
- );
483
+ checkEqual(validateAndRejectGitSource("/tmp/local-path"), null);
484
+ checkEqual(validateAndRejectGitSource("C:\\Users\\local"), null);
473
485
  });
474
486
 
475
487
  it("should handle ssh git@ format gracefully", () => {
476
- assert.deepStrictEqual(
477
- validateAndRejectGitSource("git@github.com:foo/bar.git"),
478
- null,
479
- );
488
+ checkEqual(validateAndRejectGitSource("git@github.com:foo/bar.git"), null);
480
489
  });
481
490
 
482
491
  it("should reject malformed git URLs", () => {
483
492
  // invalid URL format (can't parse via node's new URL object)
484
- assert.deepStrictEqual(
493
+ checkEqual(
485
494
  validateAndRejectGitSource("http://[:::1]/bad-ipv6").error,
486
495
  "Invalid URL Format",
487
496
  );
488
497
  });
489
498
 
490
499
  it("should enforce GIT_ALLOW_PROTOCOL default schemes", () => {
491
- assert.deepStrictEqual(
492
- validateAndRejectGitSource("https://github.com/repo"),
493
- null,
494
- );
495
- assert.deepStrictEqual(
496
- validateAndRejectGitSource("http://github.com/repo"),
497
- {
498
- status: 400,
499
- error: "Protocol Not Allowed",
500
- details: "The protocol 'http:' is not permitted by GIT_ALLOW_PROTOCOL.",
501
- },
502
- );
503
- assert.deepStrictEqual(
504
- validateAndRejectGitSource("git://github.com/repo"),
505
- null,
506
- );
507
- assert.deepStrictEqual(
508
- validateAndRejectGitSource("ssh://github.com/repo"),
509
- null,
510
- );
511
- assert.deepStrictEqual(
512
- validateAndRejectGitSource("git+ssh://github.com/repo"),
513
- null,
514
- );
500
+ checkEqual(validateAndRejectGitSource("https://github.com/repo"), null);
501
+ checkEqual(validateAndRejectGitSource("http://github.com/repo"), {
502
+ status: 400,
503
+ error: "Protocol Not Allowed",
504
+ details: "The protocol 'http:' is not permitted by GIT_ALLOW_PROTOCOL.",
505
+ });
506
+ checkEqual(validateAndRejectGitSource("git://github.com/repo"), null);
507
+ checkEqual(validateAndRejectGitSource("ssh://github.com/repo"), null);
508
+ checkEqual(validateAndRejectGitSource("git+ssh://github.com/repo"), null);
515
509
 
516
510
  // ftp is not allowed by default
517
511
  const res = validateAndRejectGitSource("ftp://github.com/repo");
518
- assert.deepStrictEqual(res.error, "Protocol Not Allowed");
519
- assert.deepStrictEqual(
512
+ checkEqual(res.error, "Protocol Not Allowed");
513
+ checkEqual(
520
514
  res.details,
521
515
  "The protocol 'ftp:' is not permitted by GIT_ALLOW_PROTOCOL.",
522
516
  );
523
517
  });
524
518
 
525
519
  it("should reject protocol smuggling techniques", () => {
526
- assert.deepStrictEqual(
520
+ checkEqual(
527
521
  validateAndRejectGitSource("git+ext://github.com/repo").error,
528
522
  "Protocol Not Allowed",
529
523
  );
530
- assert.deepStrictEqual(
524
+ checkEqual(
531
525
  validateAndRejectGitSource("http+ext://github.com/repo").error,
532
526
  "Protocol Not Allowed",
533
527
  );
@@ -535,30 +529,24 @@ describe("validateGitSource() tests", () => {
535
529
 
536
530
  it("should respect custom CDXGEN_SERVER_GIT_ALLOW_PROTOCOL configs", () => {
537
531
  process.env.CDXGEN_SERVER_GIT_ALLOW_PROTOCOL = "https:git";
538
- assert.deepStrictEqual(
539
- validateAndRejectGitSource("https://github.com/repo"),
540
- null,
541
- );
542
- assert.deepStrictEqual(
543
- validateAndRejectGitSource("git://github.com/repo"),
544
- null,
545
- );
532
+ checkEqual(validateAndRejectGitSource("https://github.com/repo"), null);
533
+ checkEqual(validateAndRejectGitSource("git://github.com/repo"), null);
546
534
 
547
535
  // http is no longer allowed
548
536
  const res = validateAndRejectGitSource("http://github.com/repo");
549
- assert.deepStrictEqual(res.error, "Protocol Not Allowed");
550
- assert.deepStrictEqual(
537
+ checkEqual(res.error, "Protocol Not Allowed");
538
+ checkEqual(
551
539
  res.details,
552
540
  "The protocol 'http:' is not permitted by GIT_ALLOW_PROTOCOL.",
553
541
  );
554
542
  });
555
543
 
556
544
  it("should reject remote helper syntax (::) inside valid schemes", () => {
557
- assert.deepStrictEqual(
545
+ checkEqual(
558
546
  validateAndRejectGitSource("https://github.com/ext::sh -c id").error,
559
547
  "Invalid URL Syntax",
560
548
  );
561
- assert.deepStrictEqual(
549
+ checkEqual(
562
550
  validateAndRejectGitSource("git://foo::bar/repo").error,
563
551
  "Invalid URL Format",
564
552
  );
@@ -566,44 +554,35 @@ describe("validateGitSource() tests", () => {
566
554
 
567
555
  it("should validate allowed hosts", () => {
568
556
  process.env.CDXGEN_SERVER_ALLOWED_HOSTS = "github.com,gitlab.com";
569
- assert.deepStrictEqual(
570
- validateAndRejectGitSource("https://github.com/repo"),
571
- null,
572
- );
557
+ checkEqual(validateAndRejectGitSource("https://github.com/repo"), null);
573
558
 
574
559
  const res = validateAndRejectGitSource("https://evil.com/repo");
575
- assert.deepStrictEqual(res.error, "Host Not Allowed");
576
- assert.deepStrictEqual(res.status, 403);
560
+ checkEqual(res.error, "Host Not Allowed");
561
+ checkEqual(res.status, 403);
577
562
  });
578
563
  });
579
564
  it("should correctly normalize and validate various git@ (SCP-like) formats", () => {
580
- assert.deepStrictEqual(
565
+ checkEqual(
581
566
  validateAndRejectGitSource("git@gitlab.com:group/project.git"),
582
567
  null,
583
568
  );
584
- assert.deepStrictEqual(
569
+ checkEqual(
585
570
  validateAndRejectGitSource("git@bitbucket.org:workspace/repo:name.git"),
586
571
  null,
587
572
  );
588
- assert.deepStrictEqual(
589
- validateAndRejectGitSource("git@github.com/user/repo.git"),
590
- null,
591
- );
592
- assert.deepStrictEqual(
573
+ checkEqual(validateAndRejectGitSource("git@github.com/user/repo.git"), null);
574
+ checkEqual(
593
575
  validateAndRejectGitSource("ssh://git@github.com/user/repo.git"),
594
576
  null,
595
577
  );
596
578
  process.env.CDXGEN_SERVER_ALLOWED_HOSTS = "github.com,bitbucket.org";
597
- assert.deepStrictEqual(
598
- validateAndRejectGitSource("git@github.com:user/repo.git"),
599
- null,
600
- );
601
- assert.deepStrictEqual(
579
+ checkEqual(validateAndRejectGitSource("git@github.com:user/repo.git"), null);
580
+ checkEqual(
602
581
  validateAndRejectGitSource("git@bitbucket.org:workspace/repo.git"),
603
582
  null,
604
583
  );
605
584
  const deniedRes = validateAndRejectGitSource("git@evil.com:foo/bar.git");
606
- assert.deepStrictEqual(deniedRes.status, 403);
607
- assert.deepStrictEqual(deniedRes.error, "Host Not Allowed");
585
+ checkEqual(deniedRes.status, 403);
586
+ checkEqual(deniedRes.error, "Host Not Allowed");
608
587
  delete process.env.CDXGEN_SERVER_ALLOWED_HOSTS;
609
588
  });
@@ -289,7 +289,7 @@ export function textualMetadata(bomJson) {
289
289
  (c) => c.type === "cryptographic-asset",
290
290
  ).length;
291
291
  const vsixCount = bomJson?.components?.filter((c) =>
292
- c?.purl?.startsWith("pkg:vsix"),
292
+ c?.purl?.startsWith("pkg:vscode-extension"),
293
293
  ).length;
294
294
  const swidCount = bomJson?.components?.filter((c) =>
295
295
  c?.purl?.startsWith("pkg:swid"),