@cdxgen/cdxgen 13.1.0 → 13.3.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 +32 -15
- package/bin/cdxgen.js +243 -122
- package/bin/evinse.js +7 -0
- package/bin/sign.js +88 -14
- package/bin/tracebom.js +64 -4
- package/bin/validate.js +29 -7
- package/bin/verify.js +79 -39
- package/data/crypto-oid.json +88 -12
- package/data/remediations.json +47 -0
- package/data/rules/ai-bom.yaml +78 -0
- package/data/rules/cargo-rust.yaml +132 -0
- package/data/rules/mcp-servers.yaml +122 -0
- package/lib/audit/targets.js +6 -1
- package/lib/cli/bomAssembly.js +117 -15
- package/lib/cli/cliOptions.js +93 -1
- package/lib/cli/index.js +235 -5
- package/lib/cli/jsBom.js +108 -26
- package/lib/cli/jvmBom.js +68 -12
- package/lib/cli/managedBom.js +264 -41
- package/lib/cli/nativeBom.js +923 -15
- package/lib/core/activity.js +120 -2
- package/lib/core/env.js +44 -7
- package/lib/core/fs.js +174 -6
- package/lib/core/metadataProperties.js +97 -0
- package/lib/core/projectConfig.js +31 -4
- package/lib/core/userAgent.js +151 -0
- package/lib/ecosystems/bunutils.js +269 -101
- package/lib/ecosystems/cargoCache.js +364 -0
- package/lib/ecosystems/caxa.js +447 -7
- package/lib/ecosystems/cmakeResolver.js +66 -0
- package/lib/ecosystems/cppEvidence.js +104 -33
- package/lib/ecosystems/ecosystems.js +260 -99
- package/lib/ecosystems/golem.js +11 -1
- package/lib/ecosystems/gradleutils.js +185 -9
- package/lib/ecosystems/jsEvidence.js +19 -20
- package/lib/ecosystems/kosi.js +1263 -0
- package/lib/ecosystems/npmutils.js +110 -9
- package/lib/ecosystems/parsers-crystal.js +179 -0
- package/lib/ecosystems/parsers-dotnet.js +120 -49
- package/lib/ecosystems/parsers-elm.js +816 -0
- package/lib/ecosystems/parsers-gleam.js +1 -1
- package/lib/ecosystems/parsers-go.js +47 -9
- package/lib/ecosystems/parsers-js.js +171 -50
- package/lib/ecosystems/parsers-julia.js +268 -0
- package/lib/ecosystems/parsers-lua.js +218 -0
- package/lib/ecosystems/parsers-misc.js +919 -161
- package/lib/ecosystems/parsers-nim.js +221 -0
- package/lib/ecosystems/parsers-opam.js +180 -0
- package/lib/ecosystems/parsers-perl.js +277 -0
- package/lib/ecosystems/parsers-python.js +27 -15
- package/lib/ecosystems/parsers-r.js +148 -0
- package/lib/ecosystems/parsers-rebar.js +411 -0
- package/lib/ecosystems/parsers-rust.js +954 -33
- package/lib/ecosystems/parsers-spack.js +204 -0
- package/lib/ecosystems/parsers-stack.js +264 -0
- package/lib/ecosystems/parsers-terraform.js +194 -0
- package/lib/ecosystems/rubyutils.js +1426 -166
- package/lib/ecosystems/rusi.js +158 -7
- package/lib/evinser/evinser.js +547 -129
- package/lib/evinser/swiftsem.js +1914 -302
- package/lib/helpers/agenticToolutils.js +925 -0
- package/lib/helpers/bomSigner.js +652 -221
- package/lib/inventory/agentFormulationParser.js +57 -4
- package/lib/inventory/aiCollector.js +504 -10
- package/lib/inventory/aiInventory.js +12 -0
- package/lib/inventory/analyzer.js +488 -30
- package/lib/inventory/astWorker.js +6 -0
- package/lib/inventory/atomUtils.js +568 -31
- package/lib/inventory/auditCategories.js +8 -0
- package/lib/inventory/cbomutils.js +30 -0
- package/lib/inventory/cdxrs.js +110 -14
- package/lib/inventory/communityAiConfigParser.js +215 -2
- package/lib/inventory/depsUtils.js +183 -11
- package/lib/inventory/display.js +4 -5
- package/lib/inventory/dosai.js +627 -13
- package/lib/inventory/dynamic.js +39 -1
- package/lib/inventory/envcontext.js +9 -6
- package/lib/inventory/evidenceUtils.js +26 -5
- package/lib/inventory/fetchBatch.js +190 -19
- package/lib/inventory/fetchRate.js +74 -11
- package/lib/inventory/forgeEnricher.js +3 -2
- package/lib/inventory/jvmToolEnv.js +6 -5
- package/lib/inventory/mcpConfigParser.js +166 -2
- package/lib/inventory/mcpDiscovery.js +11 -0
- package/lib/inventory/mcpServerManifest.js +389 -0
- package/lib/inventory/mcpbBundle.js +419 -0
- package/lib/inventory/plugins.js +3 -0
- package/lib/inventory/protobom.js +62 -89
- package/lib/inventory/protobomLoader.js +4 -0
- package/lib/inventory/purl.js +152 -3
- package/lib/inventory/rustFormulationParser.js +1 -1
- package/lib/inventory/sbomDocument.js +2 -70
- package/lib/inventory/source.js +47 -23
- package/lib/inventory/stylePackageRefs.js +41 -0
- package/lib/inventory/svelteUtils.js +524 -0
- package/lib/inventory/traceRunner.js +210 -21
- package/lib/managers/binary.js +115 -24
- package/lib/managers/docker.js +440 -20
- package/lib/managers/oci.js +39 -1
- package/lib/parsers/cmakeLists.js +452 -0
- package/lib/parsers/huggingfaceUtils.js +15 -7
- package/lib/parsers/largeJson.js +454 -0
- package/lib/parsers/npmrc.js +19 -1
- package/lib/parsers/onnx.js +294 -0
- package/lib/parsers/safetensors.js +114 -0
- package/lib/stages/postgen/introspection/markers.js +29 -6
- package/lib/stages/postgen/postgen.js +237 -16
- package/lib/third-party/arborist/snapshots/calc-dep-flags.test.cjs +462 -0
- package/lib/validator/bomValidator.js +6 -16
- package/lib/validator/index.js +48 -10
- package/lib/validator/reporters/console.js +3 -0
- package/lib/validator/reporters/json.js +1 -0
- package/lib/validator/reporters/sarif.js +7 -0
- package/package.json +27 -27
- package/types/lib/audit/targets.d.ts.map +1 -1
- package/types/lib/cli/bomAssembly.d.ts +2 -1
- package/types/lib/cli/bomAssembly.d.ts.map +1 -1
- package/types/lib/cli/cliOptions.d.ts +33 -1
- package/types/lib/cli/cliOptions.d.ts.map +1 -1
- package/types/lib/cli/index.d.ts +2 -2
- package/types/lib/cli/index.d.ts.map +1 -1
- package/types/lib/cli/jsBom.d.ts +23 -0
- package/types/lib/cli/jsBom.d.ts.map +1 -1
- package/types/lib/cli/jvmBom.d.ts.map +1 -1
- package/types/lib/cli/managedBom.d.ts +33 -0
- package/types/lib/cli/managedBom.d.ts.map +1 -1
- package/types/lib/cli/nativeBom.d.ts +88 -8
- package/types/lib/cli/nativeBom.d.ts.map +1 -1
- package/types/lib/core/activity.d.ts.map +1 -1
- package/types/lib/core/env.d.ts +21 -0
- package/types/lib/core/env.d.ts.map +1 -1
- package/types/lib/core/fs.d.ts +55 -0
- package/types/lib/core/fs.d.ts.map +1 -1
- package/types/lib/core/metadataProperties.d.ts +39 -0
- package/types/lib/core/metadataProperties.d.ts.map +1 -0
- package/types/lib/core/projectConfig.d.ts +6 -2
- package/types/lib/core/projectConfig.d.ts.map +1 -1
- package/types/lib/core/userAgent.d.ts +56 -0
- package/types/lib/core/userAgent.d.ts.map +1 -0
- package/types/lib/ecosystems/bunutils.d.ts +12 -5
- package/types/lib/ecosystems/bunutils.d.ts.map +1 -1
- package/types/lib/ecosystems/cargoCache.d.ts +75 -0
- package/types/lib/ecosystems/cargoCache.d.ts.map +1 -0
- package/types/lib/ecosystems/caxa.d.ts +14 -0
- package/types/lib/ecosystems/caxa.d.ts.map +1 -1
- package/types/lib/ecosystems/cmakeResolver.d.ts +23 -0
- package/types/lib/ecosystems/cmakeResolver.d.ts.map +1 -1
- package/types/lib/ecosystems/cppEvidence.d.ts +2 -2
- package/types/lib/ecosystems/cppEvidence.d.ts.map +1 -1
- package/types/lib/ecosystems/ecosystems.d.ts +15 -1
- package/types/lib/ecosystems/ecosystems.d.ts.map +1 -1
- package/types/lib/ecosystems/golem.d.ts.map +1 -1
- package/types/lib/ecosystems/gradleutils.d.ts +40 -4
- package/types/lib/ecosystems/gradleutils.d.ts.map +1 -1
- package/types/lib/ecosystems/jsEvidence.d.ts +5 -2
- package/types/lib/ecosystems/jsEvidence.d.ts.map +1 -1
- package/types/lib/ecosystems/kosi.d.ts +86 -0
- package/types/lib/ecosystems/kosi.d.ts.map +1 -0
- package/types/lib/ecosystems/npmutils.d.ts +42 -0
- package/types/lib/ecosystems/npmutils.d.ts.map +1 -1
- package/types/lib/ecosystems/parsers-crystal.d.ts +27 -0
- package/types/lib/ecosystems/parsers-crystal.d.ts.map +1 -0
- package/types/lib/ecosystems/parsers-dotnet.d.ts +19 -0
- package/types/lib/ecosystems/parsers-dotnet.d.ts.map +1 -1
- package/types/lib/ecosystems/parsers-elm.d.ts +79 -0
- package/types/lib/ecosystems/parsers-elm.d.ts.map +1 -0
- package/types/lib/ecosystems/parsers-go.d.ts +10 -0
- package/types/lib/ecosystems/parsers-go.d.ts.map +1 -1
- package/types/lib/ecosystems/parsers-js.d.ts +10 -4
- package/types/lib/ecosystems/parsers-js.d.ts.map +1 -1
- package/types/lib/ecosystems/parsers-julia.d.ts +57 -0
- package/types/lib/ecosystems/parsers-julia.d.ts.map +1 -0
- package/types/lib/ecosystems/parsers-lua.d.ts +50 -0
- package/types/lib/ecosystems/parsers-lua.d.ts.map +1 -0
- package/types/lib/ecosystems/parsers-misc.d.ts +90 -3
- package/types/lib/ecosystems/parsers-misc.d.ts.map +1 -1
- package/types/lib/ecosystems/parsers-nim.d.ts +43 -0
- package/types/lib/ecosystems/parsers-nim.d.ts.map +1 -0
- package/types/lib/ecosystems/parsers-opam.d.ts +31 -0
- package/types/lib/ecosystems/parsers-opam.d.ts.map +1 -0
- package/types/lib/ecosystems/parsers-perl.d.ts +36 -0
- package/types/lib/ecosystems/parsers-perl.d.ts.map +1 -0
- package/types/lib/ecosystems/parsers-python.d.ts.map +1 -1
- package/types/lib/ecosystems/parsers-r.d.ts +35 -0
- package/types/lib/ecosystems/parsers-r.d.ts.map +1 -0
- package/types/lib/ecosystems/parsers-rebar.d.ts +42 -0
- package/types/lib/ecosystems/parsers-rebar.d.ts.map +1 -0
- package/types/lib/ecosystems/parsers-rust.d.ts +199 -0
- package/types/lib/ecosystems/parsers-rust.d.ts.map +1 -1
- package/types/lib/ecosystems/parsers-spack.d.ts +33 -0
- package/types/lib/ecosystems/parsers-spack.d.ts.map +1 -0
- package/types/lib/ecosystems/parsers-stack.d.ts +35 -0
- package/types/lib/ecosystems/parsers-stack.d.ts.map +1 -0
- package/types/lib/ecosystems/parsers-terraform.d.ts +34 -0
- package/types/lib/ecosystems/parsers-terraform.d.ts.map +1 -0
- package/types/lib/ecosystems/pythonutils.d.ts +1 -1
- package/types/lib/ecosystems/rubyutils.d.ts +143 -2
- package/types/lib/ecosystems/rubyutils.d.ts.map +1 -1
- package/types/lib/ecosystems/rusi.d.ts +13 -0
- package/types/lib/ecosystems/rusi.d.ts.map +1 -1
- package/types/lib/evinser/evinser.d.ts +81 -2
- package/types/lib/evinser/evinser.d.ts.map +1 -1
- package/types/lib/evinser/swiftsem.d.ts +280 -15
- package/types/lib/evinser/swiftsem.d.ts.map +1 -1
- package/types/lib/helpers/agenticToolutils.d.ts +87 -0
- package/types/lib/helpers/agenticToolutils.d.ts.map +1 -0
- package/types/lib/helpers/bomSigner.d.ts +106 -13
- package/types/lib/helpers/bomSigner.d.ts.map +1 -1
- package/types/lib/inventory/agentFormulationParser.d.ts.map +1 -1
- package/types/lib/inventory/aiCollector.d.ts.map +1 -1
- package/types/lib/inventory/aiInventory.d.ts.map +1 -1
- package/types/lib/inventory/analyzer.d.ts.map +1 -1
- package/types/lib/inventory/atomUtils.d.ts +145 -3
- package/types/lib/inventory/atomUtils.d.ts.map +1 -1
- package/types/lib/inventory/auditCategories.d.ts +4 -0
- package/types/lib/inventory/auditCategories.d.ts.map +1 -1
- package/types/lib/inventory/cbomutils.d.ts.map +1 -1
- package/types/lib/inventory/cdxrs.d.ts +8 -3
- package/types/lib/inventory/cdxrs.d.ts.map +1 -1
- package/types/lib/inventory/communityAiConfigParser.d.ts.map +1 -1
- package/types/lib/inventory/depsUtils.d.ts +15 -0
- package/types/lib/inventory/depsUtils.d.ts.map +1 -1
- package/types/lib/inventory/display.d.ts.map +1 -1
- package/types/lib/inventory/dosai.d.ts +87 -1
- package/types/lib/inventory/dosai.d.ts.map +1 -1
- package/types/lib/inventory/dynamic.d.ts.map +1 -1
- package/types/lib/inventory/envcontext.d.ts.map +1 -1
- package/types/lib/inventory/evidenceUtils.d.ts.map +1 -1
- package/types/lib/inventory/fetchBatch.d.ts +34 -0
- package/types/lib/inventory/fetchBatch.d.ts.map +1 -1
- package/types/lib/inventory/fetchRate.d.ts +9 -6
- package/types/lib/inventory/fetchRate.d.ts.map +1 -1
- package/types/lib/inventory/forgeEnricher.d.ts.map +1 -1
- package/types/lib/inventory/jvmToolEnv.d.ts +5 -4
- package/types/lib/inventory/jvmToolEnv.d.ts.map +1 -1
- package/types/lib/inventory/mcpConfigParser.d.ts.map +1 -1
- package/types/lib/inventory/mcpDiscovery.d.ts.map +1 -1
- package/types/lib/inventory/mcpServerManifest.d.ts +19 -0
- package/types/lib/inventory/mcpServerManifest.d.ts.map +1 -0
- package/types/lib/inventory/mcpbBundle.d.ts +19 -0
- package/types/lib/inventory/mcpbBundle.d.ts.map +1 -0
- package/types/lib/inventory/plugins.d.ts.map +1 -1
- package/types/lib/inventory/protobom.d.ts +18 -13
- package/types/lib/inventory/protobom.d.ts.map +1 -1
- package/types/lib/inventory/protobomLoader.d.ts.map +1 -1
- package/types/lib/inventory/purl.d.ts +71 -2
- package/types/lib/inventory/purl.d.ts.map +1 -1
- package/types/lib/inventory/sbomDocument.d.ts.map +1 -1
- package/types/lib/inventory/source.d.ts.map +1 -1
- package/types/lib/inventory/stylePackageRefs.d.ts +17 -0
- package/types/lib/inventory/stylePackageRefs.d.ts.map +1 -0
- package/types/lib/inventory/svelteUtils.d.ts +124 -0
- package/types/lib/inventory/svelteUtils.d.ts.map +1 -0
- package/types/lib/inventory/traceRunner.d.ts +47 -1
- package/types/lib/inventory/traceRunner.d.ts.map +1 -1
- package/types/lib/managers/binary.d.ts +30 -1
- package/types/lib/managers/binary.d.ts.map +1 -1
- package/types/lib/managers/docker.d.ts +29 -0
- package/types/lib/managers/docker.d.ts.map +1 -1
- package/types/lib/managers/oci.d.ts +14 -0
- package/types/lib/managers/oci.d.ts.map +1 -1
- package/types/lib/parsers/cmakeLists.d.ts +76 -0
- package/types/lib/parsers/cmakeLists.d.ts.map +1 -0
- package/types/lib/parsers/huggingfaceUtils.d.ts +8 -1
- package/types/lib/parsers/huggingfaceUtils.d.ts.map +1 -1
- package/types/lib/parsers/largeJson.d.ts +52 -0
- package/types/lib/parsers/largeJson.d.ts.map +1 -0
- package/types/lib/parsers/npmrc.d.ts +5 -0
- package/types/lib/parsers/npmrc.d.ts.map +1 -1
- package/types/lib/parsers/onnx.d.ts +28 -0
- package/types/lib/parsers/onnx.d.ts.map +1 -0
- package/types/lib/parsers/safetensors.d.ts +22 -0
- package/types/lib/parsers/safetensors.d.ts.map +1 -0
- package/types/lib/stages/postgen/introspection/markers.d.ts +3 -2
- package/types/lib/stages/postgen/introspection/markers.d.ts.map +1 -1
- package/types/lib/stages/postgen/postgen.d.ts +33 -0
- package/types/lib/stages/postgen/postgen.d.ts.map +1 -1
- package/types/lib/validator/bomValidator.d.ts.map +1 -1
- package/types/lib/validator/index.d.ts +10 -1
- package/types/lib/validator/index.d.ts.map +1 -1
- package/types/lib/validator/reporters/console.d.ts.map +1 -1
- package/types/lib/validator/reporters/json.d.ts.map +1 -1
- package/types/lib/validator/reporters/sarif.d.ts.map +1 -1
package/lib/cli/managedBom.js
CHANGED
|
@@ -50,6 +50,7 @@ import {
|
|
|
50
50
|
parseGitHubWorkflowData,
|
|
51
51
|
parseHelmYamlData,
|
|
52
52
|
} from "../ecosystems/parsers-misc.js";
|
|
53
|
+
import { parseCpanSnapshot } from "../ecosystems/parsers-perl.js";
|
|
53
54
|
import {
|
|
54
55
|
generatePixiLockFile,
|
|
55
56
|
parseMojoProject,
|
|
@@ -61,6 +62,8 @@ import {
|
|
|
61
62
|
parseReqFile,
|
|
62
63
|
parseSetupPyFile,
|
|
63
64
|
} from "../ecosystems/parsers-python.js";
|
|
65
|
+
import { parseRenvLock } from "../ecosystems/parsers-r.js";
|
|
66
|
+
import { parseTerraformLockFile } from "../ecosystems/parsers-terraform.js";
|
|
64
67
|
import { collectEmbeddedSboms } from "../ecosystems/pep770.js";
|
|
65
68
|
import { isPyLockFile } from "../ecosystems/pylockutils.js";
|
|
66
69
|
import {
|
|
@@ -70,7 +73,10 @@ import {
|
|
|
70
73
|
getPyModules,
|
|
71
74
|
} from "../ecosystems/pythonutils.js";
|
|
72
75
|
import {
|
|
76
|
+
addRubyGemsDistributionUrls,
|
|
77
|
+
addRubyRuntimeComponent,
|
|
73
78
|
collectGemModuleNames,
|
|
79
|
+
describeProjectGem,
|
|
74
80
|
enrichGemsFromLocalCache,
|
|
75
81
|
parseBundleConfig,
|
|
76
82
|
parseGemfileLockData,
|
|
@@ -101,7 +107,7 @@ import {
|
|
|
101
107
|
createDosaiMethodsSlice,
|
|
102
108
|
isDosaiDotnetLanguage,
|
|
103
109
|
normalizeDosaiServiceMap,
|
|
104
|
-
|
|
110
|
+
readDosaiMethodsReport,
|
|
105
111
|
} from "../inventory/dosai.js";
|
|
106
112
|
import { addEvidenceForDotnet } from "../inventory/evidenceUtils.js";
|
|
107
113
|
import { nugetPurl, pypiBomRef } from "../inventory/purl.js";
|
|
@@ -570,8 +576,17 @@ export async function createPythonBom(path, options) {
|
|
|
570
576
|
}
|
|
571
577
|
if (requirementsMode || pipenvMode) {
|
|
572
578
|
if (pipenvMode) {
|
|
573
|
-
//
|
|
574
|
-
|
|
579
|
+
// `pipenv install` builds and installs the project's own dependencies
|
|
580
|
+
// (including `-e .` self-references that execute setup.py), so unlike
|
|
581
|
+
// the lockfile parsing below it must honor --no-install-deps and the
|
|
582
|
+
// pre-build lifecycle.
|
|
583
|
+
if (options.installDeps !== false) {
|
|
584
|
+
safeSpawnSync("pipenv", ["install"], { cwd: path, shell: isWin });
|
|
585
|
+
} else {
|
|
586
|
+
console.log(
|
|
587
|
+
"Skipping 'pipenv install' since dependency installation is disabled.",
|
|
588
|
+
);
|
|
589
|
+
}
|
|
575
590
|
const piplockFile = join(path, "Pipfile.lock");
|
|
576
591
|
if (safeExistsSync(piplockFile)) {
|
|
577
592
|
let dlist;
|
|
@@ -1349,6 +1364,7 @@ export async function createRubyBom(path, options) {
|
|
|
1349
1364
|
let pkgList = [];
|
|
1350
1365
|
let dependencies = [];
|
|
1351
1366
|
let rootList = [];
|
|
1367
|
+
const projectGemRefs = [];
|
|
1352
1368
|
const parentComponent = createDefaultParentComponent(path, "gem", options);
|
|
1353
1369
|
const gemFileMode = gemFiles.length;
|
|
1354
1370
|
const gemLockMode = gemLockFiles.length;
|
|
@@ -1402,10 +1418,18 @@ export async function createRubyBom(path, options) {
|
|
|
1402
1418
|
if (retMap.rootList?.length) {
|
|
1403
1419
|
rootList = rootList.concat(retMap.rootList);
|
|
1404
1420
|
}
|
|
1421
|
+
// `PATH remote: .` is relative to the lockfile, so only the lockfiles
|
|
1422
|
+
// of the scanned directory can serve the gem the root gemspec builds
|
|
1423
|
+
if (
|
|
1424
|
+
retMap.projectGemRefs?.length &&
|
|
1425
|
+
dirname(resolve(f)) === resolve(path)
|
|
1426
|
+
) {
|
|
1427
|
+
projectGemRefs.push(...retMap.projectGemRefs);
|
|
1428
|
+
}
|
|
1405
1429
|
}
|
|
1406
1430
|
}
|
|
1407
1431
|
// Parsing .gemspec files would help us get more metadata such as description, authors, licenses etc
|
|
1408
|
-
let
|
|
1432
|
+
let projectGem;
|
|
1409
1433
|
if (gemspecFiles.length) {
|
|
1410
1434
|
if (!gemLockFiles.length && !hasAnyProjectType(["oci"], options, false)) {
|
|
1411
1435
|
console.log(
|
|
@@ -1417,38 +1441,51 @@ export async function createRubyBom(path, options) {
|
|
|
1417
1441
|
detail: "only gemspec files were available to parse",
|
|
1418
1442
|
});
|
|
1419
1443
|
}
|
|
1444
|
+
// Bundler evaluated the root gemspec to lock it under `PATH remote: .`,
|
|
1445
|
+
// so the locked release stands in for a version computed at runtime. It
|
|
1446
|
+
// is resolved before the merge, so that the gemspec and lockfile
|
|
1447
|
+
// sightings of the gem reconcile into one component.
|
|
1448
|
+
const lockedVersions = Object.create(null);
|
|
1449
|
+
for (const p of pkgList) {
|
|
1450
|
+
if (p.version && projectGemRefs.includes(p["bom-ref"])) {
|
|
1451
|
+
lockedVersions[p.name] = p.version;
|
|
1452
|
+
}
|
|
1453
|
+
}
|
|
1420
1454
|
for (const f of gemspecFiles) {
|
|
1421
1455
|
const gemspecData = readFileSync(f, { encoding: "utf-8" });
|
|
1422
|
-
const
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
) {
|
|
1431
|
-
rootGemspecComponent = gpkgList[0];
|
|
1432
|
-
}
|
|
1456
|
+
const isRootGemspec = dirname(resolve(f)) === resolve(path);
|
|
1457
|
+
const gpkgList = await parseGemspecData(
|
|
1458
|
+
gemspecData,
|
|
1459
|
+
f,
|
|
1460
|
+
isRootGemspec ? { lockedVersions } : {},
|
|
1461
|
+
);
|
|
1462
|
+
if (!gpkgList.length) {
|
|
1463
|
+
continue;
|
|
1433
1464
|
}
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
) {
|
|
1440
|
-
parentComponent.name = rootGemspecComponent.name;
|
|
1441
|
-
parentComponent.version = rootGemspecComponent.version || "latest";
|
|
1442
|
-
const parentPurl = build({
|
|
1443
|
-
type: "gem",
|
|
1444
|
-
namespace: parentComponent.group || null,
|
|
1445
|
-
name: parentComponent.name,
|
|
1446
|
-
version: parentComponent.version || null,
|
|
1447
|
-
});
|
|
1448
|
-
parentComponent["bom-ref"] = decodeURIComponent(parentPurl);
|
|
1449
|
-
parentComponent["purl"] = parentPurl;
|
|
1465
|
+
// The gemspec in the scanned directory is the gem the project builds
|
|
1466
|
+
if (!projectGem && isRootGemspec && gpkgList[0]?.name) {
|
|
1467
|
+
projectGem = gpkgList[0];
|
|
1468
|
+
}
|
|
1469
|
+
pkgList = trimComponents(pkgList.concat(gpkgList));
|
|
1450
1470
|
}
|
|
1451
1471
|
}
|
|
1472
|
+
// Describe that gem in metadata.component, unless `--project-name` names a
|
|
1473
|
+
// different project or an image is being scanned
|
|
1474
|
+
if (
|
|
1475
|
+
projectGem &&
|
|
1476
|
+
!hasAnyProjectType(["oci"], options, false) &&
|
|
1477
|
+
(!("project-name" in options) || options.projectName === projectGem.name)
|
|
1478
|
+
) {
|
|
1479
|
+
({ pkgList, dependencies, rootList } = describeProjectGem(
|
|
1480
|
+
parentComponent,
|
|
1481
|
+
projectGem,
|
|
1482
|
+
pkgList,
|
|
1483
|
+
dependencies,
|
|
1484
|
+
rootList,
|
|
1485
|
+
projectGemRefs,
|
|
1486
|
+
options,
|
|
1487
|
+
));
|
|
1488
|
+
}
|
|
1452
1489
|
if (rootList.length) {
|
|
1453
1490
|
dependencies = mergeDependencies(
|
|
1454
1491
|
dependencies,
|
|
@@ -1544,6 +1581,21 @@ export async function createRubyBom(path, options) {
|
|
|
1544
1581
|
// lookup, gives us the sha256 of the exact native build, and unlike the
|
|
1545
1582
|
// registry lookups it also works in dry-run mode.
|
|
1546
1583
|
pkgList = await enrichGemsFromLocalCache(pkgList, { gemHome });
|
|
1584
|
+
// The download URL of a gem from the public registry needs no network call
|
|
1585
|
+
pkgList = addRubyGemsDistributionUrls(pkgList);
|
|
1586
|
+
// Gems declare the Ruby they run on; surface it as the runtime they depend
|
|
1587
|
+
// on. The component says the runtime is external, which only CycloneDX 1.7
|
|
1588
|
+
// can express, and a container image ships its own Ruby.
|
|
1589
|
+
if (
|
|
1590
|
+
options.specVersion >= 1.7 &&
|
|
1591
|
+
!hasAnyProjectType(["oci"], options, false)
|
|
1592
|
+
) {
|
|
1593
|
+
({ pkgList, dependencies } = addRubyRuntimeComponent(
|
|
1594
|
+
pkgList,
|
|
1595
|
+
parentComponent,
|
|
1596
|
+
dependencies,
|
|
1597
|
+
));
|
|
1598
|
+
}
|
|
1547
1599
|
return buildBomNSData(options, pkgList, "gem", {
|
|
1548
1600
|
src: path,
|
|
1549
1601
|
dependencies,
|
|
@@ -2003,9 +2055,13 @@ export async function createCsharpBom(path, options) {
|
|
|
2003
2055
|
pkgList = trimComponents(pkgList);
|
|
2004
2056
|
// Perform deep analysis using dosai
|
|
2005
2057
|
if (options.deep) {
|
|
2058
|
+
// resolve (not join) so a fully-qualified --deps-slices-file is used
|
|
2059
|
+
// as-is: join would append it to the scan path, which is never a valid
|
|
2060
|
+
// path on Windows and silently loses the .NET evidence elsewhere
|
|
2061
|
+
// (issue 4394). A relative value still resolves against the scan path.
|
|
2006
2062
|
const slicesFile = resolve(
|
|
2007
2063
|
options.depsSlicesFile
|
|
2008
|
-
?
|
|
2064
|
+
? resolve(path, options.depsSlicesFile)
|
|
2009
2065
|
: join(getTmpDir(), "dosai.json"),
|
|
2010
2066
|
);
|
|
2011
2067
|
// Create the slices file if it doesn't exist
|
|
@@ -2018,14 +2074,24 @@ export async function createCsharpBom(path, options) {
|
|
|
2018
2074
|
resolve(slicesFile),
|
|
2019
2075
|
options,
|
|
2020
2076
|
);
|
|
2021
|
-
if (!sliceResult
|
|
2022
|
-
|
|
2023
|
-
|
|
2077
|
+
if (!sliceResult) {
|
|
2078
|
+
// Visible without --debug: otherwise the components silently lose
|
|
2079
|
+
// the dependency-slice evidence while the scan still exits 0.
|
|
2080
|
+
// --evidence (which implies --deep) runs dosai again during evinse
|
|
2081
|
+
// and can still add occurrences, so this names only what is lost.
|
|
2082
|
+
console.warn(
|
|
2083
|
+
"Slicing with dosai was unsuccessful, so the .NET components get no occurrence, reachability, or services evidence from the dependency slice. Re-run with --debug for the dosai errors.",
|
|
2024
2084
|
);
|
|
2025
2085
|
}
|
|
2086
|
+
} else if (DEBUG_MODE) {
|
|
2087
|
+
console.log(
|
|
2088
|
+
`Reusing the existing dosai methods slice "${slicesFile}" without checking whether it honours the current --exclude patterns. Delete the file to force a fresh run.`,
|
|
2089
|
+
);
|
|
2026
2090
|
}
|
|
2027
2091
|
pkgList = addEvidenceForDotnet(pkgList, slicesFile);
|
|
2028
|
-
const methodsSlice =
|
|
2092
|
+
const methodsSlice = readDosaiMethodsReport(slicesFile, {
|
|
2093
|
+
sections: ["Metadata", "Services", "ApiEndpoints"],
|
|
2094
|
+
});
|
|
2029
2095
|
// Provider-backed Services[] first so bom-refs, trust zones, and data
|
|
2030
2096
|
// classifications survive; ApiEndpoints derivation fills in the rest.
|
|
2031
2097
|
const servicesMap = collectDosaiServiceComponents(methodsSlice, {});
|
|
@@ -2033,12 +2099,20 @@ export async function createCsharpBom(path, options) {
|
|
|
2033
2099
|
services = normalizeDosaiServiceMap(servicesMap);
|
|
2034
2100
|
}
|
|
2035
2101
|
}
|
|
2036
|
-
// Parent dependency tree
|
|
2102
|
+
// Parent dependency tree. A single project file already contributed an
|
|
2103
|
+
// entry for the same parent, so the lock file roots are merged into it
|
|
2104
|
+
// rather than added as a second entry for the same ref.
|
|
2037
2105
|
if (parentDependsOn.size && parentComponent?.["bom-ref"]) {
|
|
2038
|
-
dependencies
|
|
2039
|
-
|
|
2040
|
-
|
|
2041
|
-
|
|
2106
|
+
dependencies = mergeDependencies(
|
|
2107
|
+
[
|
|
2108
|
+
{
|
|
2109
|
+
ref: parentComponent["bom-ref"],
|
|
2110
|
+
dependsOn: Array.from(parentDependsOn).sort(),
|
|
2111
|
+
},
|
|
2112
|
+
],
|
|
2113
|
+
dependencies,
|
|
2114
|
+
parentComponent,
|
|
2115
|
+
);
|
|
2042
2116
|
}
|
|
2043
2117
|
if (shouldFetchLicense()) {
|
|
2044
2118
|
const retMap = await getNugetMetadata(pkgList, dependencies);
|
|
@@ -2150,3 +2224,152 @@ export async function createCryptoCertsBom(path, options) {
|
|
|
2150
2224
|
},
|
|
2151
2225
|
};
|
|
2152
2226
|
}
|
|
2227
|
+
|
|
2228
|
+
/**
|
|
2229
|
+
* Function to create bom string for R projects using renv.
|
|
2230
|
+
*
|
|
2231
|
+
* The `renv.lock` file carries the resolved package set for the project
|
|
2232
|
+
* library, including the R version it was produced under.
|
|
2233
|
+
*
|
|
2234
|
+
* @param {string} path to the project
|
|
2235
|
+
* @param {Object} options Parse options from the cli
|
|
2236
|
+
* @returns {Object} BOM object
|
|
2237
|
+
*/
|
|
2238
|
+
export function createRBom(path, options) {
|
|
2239
|
+
let pkgList = [];
|
|
2240
|
+
let dependencies = [];
|
|
2241
|
+
let rootInputs = [];
|
|
2242
|
+
let rVersion;
|
|
2243
|
+
const renvLockFiles = getAllFiles(
|
|
2244
|
+
path,
|
|
2245
|
+
`${options.multiProject ? "**/" : ""}renv.lock`,
|
|
2246
|
+
options,
|
|
2247
|
+
);
|
|
2248
|
+
for (const renvLockFile of renvLockFiles) {
|
|
2249
|
+
if (DEBUG_MODE) {
|
|
2250
|
+
console.log(`Parsing ${renvLockFile}`);
|
|
2251
|
+
}
|
|
2252
|
+
const result = parseRenvLock(renvLockFile);
|
|
2253
|
+
if (result.pkgList?.length) {
|
|
2254
|
+
pkgList = pkgList.concat(result.pkgList);
|
|
2255
|
+
}
|
|
2256
|
+
if (result.dependencies?.length) {
|
|
2257
|
+
dependencies = dependencies.concat(result.dependencies);
|
|
2258
|
+
}
|
|
2259
|
+
if (result.rootInputs?.length) {
|
|
2260
|
+
rootInputs = rootInputs.concat(result.rootInputs);
|
|
2261
|
+
}
|
|
2262
|
+
if (!rVersion) {
|
|
2263
|
+
rVersion = result.rVersion;
|
|
2264
|
+
}
|
|
2265
|
+
}
|
|
2266
|
+
if (!pkgList.length) {
|
|
2267
|
+
return {};
|
|
2268
|
+
}
|
|
2269
|
+
// renv locks the library, not the project: they carry no project name, so
|
|
2270
|
+
// the directory is the name the project is already known by. The R version
|
|
2271
|
+
// the library was resolved under is a property of that project.
|
|
2272
|
+
const projectName = basename(resolve(path));
|
|
2273
|
+
const parentComponent = {
|
|
2274
|
+
type: "application",
|
|
2275
|
+
name: projectName,
|
|
2276
|
+
"bom-ref": `application:${projectName}:latest`,
|
|
2277
|
+
description: `R project: ${projectName}`,
|
|
2278
|
+
properties: [
|
|
2279
|
+
{ name: "internal:SrcFile", value: renvLockFiles.join(", ") },
|
|
2280
|
+
...(rVersion ? [{ name: "cdx:renv:rVersion", value: rVersion }] : []),
|
|
2281
|
+
],
|
|
2282
|
+
};
|
|
2283
|
+
if (rootInputs.length) {
|
|
2284
|
+
dependencies.push({
|
|
2285
|
+
ref: parentComponent["bom-ref"],
|
|
2286
|
+
dependsOn: [...new Set(rootInputs)].sort(),
|
|
2287
|
+
});
|
|
2288
|
+
}
|
|
2289
|
+
return buildBomNSData(options, pkgList, "cran", {
|
|
2290
|
+
src: path,
|
|
2291
|
+
filename: renvLockFiles.join(", "),
|
|
2292
|
+
dependencies,
|
|
2293
|
+
parentComponent,
|
|
2294
|
+
});
|
|
2295
|
+
}
|
|
2296
|
+
|
|
2297
|
+
/**
|
|
2298
|
+
* Function to create bom string for Perl projects using Carton.
|
|
2299
|
+
*
|
|
2300
|
+
* The `cpanfile.snapshot` carries the resolved install set; the declared
|
|
2301
|
+
* `cpanfile` is consulted to distinguish direct dependencies.
|
|
2302
|
+
*
|
|
2303
|
+
* @param {string} path to the project
|
|
2304
|
+
* @param {Object} options Parse options from the cli
|
|
2305
|
+
* @returns {Object} BOM object
|
|
2306
|
+
*/
|
|
2307
|
+
export function createPerlBom(path, options) {
|
|
2308
|
+
let pkgList = [];
|
|
2309
|
+
let dependencies = [];
|
|
2310
|
+
const snapshotFiles = getAllFiles(
|
|
2311
|
+
path,
|
|
2312
|
+
`${options.multiProject ? "**/" : ""}cpanfile.snapshot`,
|
|
2313
|
+
options,
|
|
2314
|
+
);
|
|
2315
|
+
for (const snapshotFile of snapshotFiles) {
|
|
2316
|
+
if (DEBUG_MODE) {
|
|
2317
|
+
console.log(`Parsing ${snapshotFile}`);
|
|
2318
|
+
}
|
|
2319
|
+
const baseDir = dirname(snapshotFile);
|
|
2320
|
+
const cpanfile = join(baseDir, "cpanfile");
|
|
2321
|
+
const result = parseCpanSnapshot(
|
|
2322
|
+
snapshotFile,
|
|
2323
|
+
safeExistsSync(cpanfile) ? cpanfile : undefined,
|
|
2324
|
+
);
|
|
2325
|
+
if (result.pkgList?.length) {
|
|
2326
|
+
pkgList = pkgList.concat(result.pkgList);
|
|
2327
|
+
}
|
|
2328
|
+
if (result.dependencies?.length) {
|
|
2329
|
+
dependencies = dependencies.concat(result.dependencies);
|
|
2330
|
+
}
|
|
2331
|
+
}
|
|
2332
|
+
if (pkgList.length) {
|
|
2333
|
+
return buildBomNSData(options, pkgList, "cpan", {
|
|
2334
|
+
src: path,
|
|
2335
|
+
filename: snapshotFiles.join(", "),
|
|
2336
|
+
dependencies,
|
|
2337
|
+
});
|
|
2338
|
+
}
|
|
2339
|
+
return {};
|
|
2340
|
+
}
|
|
2341
|
+
|
|
2342
|
+
/**
|
|
2343
|
+
* Function to create bom string for Terraform and OpenTofu projects.
|
|
2344
|
+
*
|
|
2345
|
+
* The `.terraform.lock.hcl` file pins the providers the configuration
|
|
2346
|
+
* resolves to, with content hashes suitable for the CycloneDX hashes array.
|
|
2347
|
+
*
|
|
2348
|
+
* @param {string} path to the project
|
|
2349
|
+
* @param {Object} options Parse options from the cli
|
|
2350
|
+
* @returns {Object} BOM object
|
|
2351
|
+
*/
|
|
2352
|
+
export function createTerraformBom(path, options) {
|
|
2353
|
+
let pkgList = [];
|
|
2354
|
+
const lockFiles = getAllFiles(
|
|
2355
|
+
path,
|
|
2356
|
+
`${options.multiProject ? "**/" : ""}.terraform.lock.hcl`,
|
|
2357
|
+
options,
|
|
2358
|
+
);
|
|
2359
|
+
for (const lockFile of lockFiles) {
|
|
2360
|
+
if (DEBUG_MODE) {
|
|
2361
|
+
console.log(`Parsing ${lockFile}`);
|
|
2362
|
+
}
|
|
2363
|
+
const result = parseTerraformLockFile(lockFile);
|
|
2364
|
+
if (result.pkgList?.length) {
|
|
2365
|
+
pkgList = pkgList.concat(result.pkgList);
|
|
2366
|
+
}
|
|
2367
|
+
}
|
|
2368
|
+
if (pkgList.length) {
|
|
2369
|
+
return buildBomNSData(options, pkgList, "terraform", {
|
|
2370
|
+
src: path,
|
|
2371
|
+
filename: lockFiles.join(", "),
|
|
2372
|
+
});
|
|
2373
|
+
}
|
|
2374
|
+
return {};
|
|
2375
|
+
}
|