@cdxgen/cdxgen 13.3.0 → 13.5.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 +12 -9
- package/bin/cdxgen-secure.js +15 -0
- package/bin/cdxgen.js +115 -31
- package/bin/evinse.js +23 -1
- package/bin/hbom.js +15 -7
- package/bin/repl.js +115 -0
- package/bin/sign.js +45 -15
- package/bin/tracebom.js +5 -1
- package/bin/validate.js +84 -18
- package/bin/verify.js +155 -86
- package/data/cbomosdb-queries.json +13 -1
- package/data/component-tags.json +8 -0
- package/data/helpers/init.gradle +46 -21
- package/data/queries-darwin.json +25 -1
- package/data/queries-win.json +19 -1
- package/data/queries.json +41 -0
- package/data/remediations.json +344 -1
- package/data/rules/cbom-security.yaml +235 -4
- package/data/rules/dependency-sources.yaml +67 -0
- package/data/rules/go-binaries.yaml +46 -0
- package/data/rules/golem-go.yaml +80 -0
- package/data/rules/hbom-compliance.yaml +40 -22
- package/data/rules/hbom-performance.yaml +7 -1
- package/data/rules/host-topology.yaml +1 -1
- package/data/rules/obom-runtime.yaml +31 -2
- package/data/rules/php-runtime.yaml +143 -0
- package/data/rules/scala-evidence.yaml +115 -0
- package/lib/audit/index.js +52 -6
- package/lib/cli/bomAssembly.js +28 -3
- package/lib/cli/cliOptions.js +110 -3
- package/lib/cli/index.js +186 -58
- package/lib/cli/jsBom.js +50 -29
- package/lib/cli/jvmBom.js +779 -146
- package/lib/cli/managedBom.js +1021 -261
- package/lib/cli/nativeBom.js +364 -58
- package/lib/core/activity.js +12 -0
- package/lib/core/env.js +47 -17
- package/lib/core/fs.js +31 -21
- package/lib/core/httpClient.js +233 -69
- package/lib/core/pluginRun.js +184 -0
- package/lib/core/processTree.js +100 -0
- package/lib/core/projectConfig.js +1 -0
- package/lib/core/projectTooling.js +97 -0
- package/lib/core/propertySanitizer.js +72 -0
- package/lib/core/runState.js +39 -0
- package/lib/core/toml.js +72 -0
- package/lib/ecosystems/asarutils.js +4 -2
- package/lib/ecosystems/bunutils.js +5 -7
- package/lib/ecosystems/cargoCache.js +231 -8
- package/lib/ecosystems/cmakeResolver.js +10 -21
- package/lib/ecosystems/cppBuildContext.js +631 -0
- package/lib/ecosystems/cppEvidence.js +337 -22
- package/lib/ecosystems/cppIncludeResolver.js +294 -0
- package/lib/ecosystems/denoutils.js +93 -66
- package/lib/ecosystems/ecosystems.js +1967 -788
- package/lib/ecosystems/golem.js +578 -18
- package/lib/ecosystems/gradleutils.js +340 -46
- package/lib/ecosystems/jsEvidence.js +85 -24
- package/lib/ecosystems/kosi.js +21 -4
- package/lib/ecosystems/npmutils.js +64 -0
- package/lib/ecosystems/parsers-dotnet.js +668 -153
- package/lib/ecosystems/parsers-elm.js +46 -28
- package/lib/ecosystems/parsers-gleam.js +3 -4
- package/lib/ecosystems/parsers-go.js +1283 -297
- package/lib/ecosystems/parsers-js.js +92 -26
- package/lib/ecosystems/parsers-julia.js +2 -3
- package/lib/ecosystems/parsers-jvm.js +463 -29
- package/lib/ecosystems/parsers-misc.js +405 -93
- package/lib/ecosystems/parsers-python.js +152 -20
- package/lib/ecosystems/parsers-rust.js +4 -4
- package/lib/ecosystems/parsers-terraform.js +1573 -19
- package/lib/ecosystems/pythonutils.js +102 -6
- package/lib/ecosystems/remote/huggingface.js +3 -0
- package/lib/ecosystems/rubyutils.js +73 -20
- package/lib/ecosystems/rusi.js +32 -9
- package/lib/ecosystems/sbtutils.js +243 -187
- package/lib/ecosystems/scalacliutils.js +343 -0
- package/lib/ecosystems/scalasem.js +2620 -0
- package/lib/ecosystems/terraformRegistry.js +288 -0
- package/lib/ecosystems/utils.js +2 -0
- package/lib/ecosystems/vendoredCode.js +156 -0
- package/lib/evinser/evinser.js +695 -78
- package/lib/evinser/swiftsem.js +68 -5
- package/lib/helpers/agenticToolutils.js +2 -2
- package/lib/helpers/bomSigner.js +576 -128
- package/lib/inventory/agentSkillSpec.js +17 -0
- package/lib/inventory/aiCollector.js +4 -1
- package/lib/inventory/analyzer.js +110 -127
- package/lib/inventory/apkInstalledDb.js +243 -0
- package/lib/inventory/atomUtils.js +204 -48
- package/lib/inventory/auditCategories.js +10 -3
- package/lib/inventory/buildToolRateLimit.js +144 -0
- package/lib/inventory/cacheCommands.js +2 -1
- package/lib/inventory/cacheDir.js +52 -9
- package/lib/inventory/certificates.js +2371 -0
- package/lib/inventory/cmakeBuildDirs.js +254 -0
- package/lib/inventory/communityAiConfigParser.js +4 -9
- package/lib/inventory/deps.js +507 -128
- package/lib/inventory/display.js +200 -3
- package/lib/inventory/dosai.js +747 -101
- package/lib/inventory/dosaiParsers.js +310 -15
- package/lib/inventory/dynamic.js +96 -8
- package/lib/inventory/envcontext.js +168 -5
- package/lib/inventory/evidenceUtils.js +590 -132
- package/lib/inventory/fetchBatch.js +574 -38
- package/lib/inventory/fetchDiskCache.js +597 -0
- package/lib/inventory/forgeEnricher.js +14 -5
- package/lib/inventory/formulationParsers.js +3 -2
- package/lib/inventory/goBuildInfo.js +140 -0
- package/lib/inventory/hbom.js +67 -7
- package/lib/inventory/hbomAnalysis.js +16 -0
- package/lib/inventory/hostTopology.js +21 -0
- package/lib/inventory/jvmLocalRepos.js +917 -0
- package/lib/inventory/mcpConfigParser.js +2 -3
- package/lib/inventory/osPackagePurl.js +244 -0
- package/lib/inventory/osPackageResolver.js +89 -87
- package/lib/inventory/osinfo.js +79 -31
- package/lib/inventory/osqueryTransform.js +114 -5
- package/lib/inventory/parentSelection.js +146 -0
- package/lib/inventory/phpBuildInfo.js +487 -0
- package/lib/inventory/phpHostProbe.js +641 -0
- package/lib/inventory/rootfsCerts.js +426 -0
- package/lib/inventory/rustFormulationParser.js +3 -4
- package/lib/inventory/scalaCoords.js +153 -0
- package/lib/inventory/source.js +215 -11
- package/lib/inventory/spdx.js +245 -0
- package/lib/inventory/traceRunner.js +93 -8
- package/lib/inventory/tracedCrypto.js +423 -0
- package/lib/managers/binary.js +529 -183
- package/lib/managers/docker.js +199 -44
- package/lib/managers/oci.js +24 -2
- package/lib/parsers/cmakeCache.js +69 -0
- package/lib/parsers/cmakeLists.js +16 -2
- package/lib/parsers/cmakePresets.js +400 -0
- package/lib/parsers/compileCommands.js +557 -0
- package/lib/parsers/email.js +277 -0
- package/lib/parsers/largeJson.js +34 -2
- package/lib/parsers/strictJson.js +322 -0
- package/lib/parsers/terraformConfig.js +1073 -0
- package/lib/parsers/terraformSource.js +652 -0
- package/lib/server/server.js +209 -1
- package/lib/stages/postgen/annotator.js +17 -1
- package/lib/stages/postgen/introspection/markers.js +1 -1
- package/lib/stages/postgen/introspection/reflect.js +4 -1
- package/lib/stages/postgen/postgen.js +20 -6
- package/lib/stages/postgen/ruleEngine.js +58 -1
- package/lib/stages/postgen/specVersionCompat.js +62 -0
- package/lib/stages/pregen/pregen.js +117 -5
- package/lib/validator/bomValidator.js +26 -5
- package/lib/validator/generated/runtime.mjs +13 -0
- package/lib/validator/generated/validate-1.6.mjs +26 -7
- package/lib/validator/generated/validate-1.7.mjs +31 -12
- package/lib/validator/generated/validate-2.0.mjs +30 -11
- package/lib/validator/index.js +25 -10
- package/lib/validator/reporters/json.js +1 -0
- package/package.json +23 -23
- package/types/bin/cdxgen-secure.d.ts +3 -0
- package/types/bin/cdxgen-secure.d.ts.map +1 -0
- package/types/bin/repl.d.ts.map +1 -1
- package/types/lib/audit/index.d.ts.map +1 -1
- package/types/lib/cli/bomAssembly.d.ts +9 -2
- package/types/lib/cli/bomAssembly.d.ts.map +1 -1
- package/types/lib/cli/cliOptions.d.ts +43 -0
- package/types/lib/cli/cliOptions.d.ts.map +1 -1
- package/types/lib/cli/index.d.ts.map +1 -1
- package/types/lib/cli/jsBom.d.ts.map +1 -1
- package/types/lib/cli/jvmBom.d.ts +44 -1
- package/types/lib/cli/jvmBom.d.ts.map +1 -1
- package/types/lib/cli/managedBom.d.ts +7 -4
- package/types/lib/cli/managedBom.d.ts.map +1 -1
- package/types/lib/cli/nativeBom.d.ts +3 -1
- 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 +27 -2
- package/types/lib/core/env.d.ts.map +1 -1
- package/types/lib/core/fs.d.ts.map +1 -1
- package/types/lib/core/httpClient.d.ts +13 -8
- package/types/lib/core/httpClient.d.ts.map +1 -1
- package/types/lib/core/pluginRun.d.ts +97 -0
- package/types/lib/core/pluginRun.d.ts.map +1 -0
- package/types/lib/core/processTree.d.ts +36 -0
- package/types/lib/core/processTree.d.ts.map +1 -0
- package/types/lib/core/projectConfig.d.ts.map +1 -1
- package/types/lib/core/projectTooling.d.ts +41 -0
- package/types/lib/core/projectTooling.d.ts.map +1 -0
- package/types/lib/core/propertySanitizer.d.ts +26 -0
- package/types/lib/core/propertySanitizer.d.ts.map +1 -1
- package/types/lib/core/runState.d.ts +29 -0
- package/types/lib/core/runState.d.ts.map +1 -0
- package/types/lib/core/toml.d.ts +20 -0
- package/types/lib/core/toml.d.ts.map +1 -0
- package/types/lib/ecosystems/asarutils.d.ts.map +1 -1
- package/types/lib/ecosystems/bunutils.d.ts.map +1 -1
- package/types/lib/ecosystems/cargoCache.d.ts +12 -0
- package/types/lib/ecosystems/cargoCache.d.ts.map +1 -1
- package/types/lib/ecosystems/cmakeResolver.d.ts +5 -3
- package/types/lib/ecosystems/cmakeResolver.d.ts.map +1 -1
- package/types/lib/ecosystems/cppBuildContext.d.ts +55 -0
- package/types/lib/ecosystems/cppBuildContext.d.ts.map +1 -0
- package/types/lib/ecosystems/cppEvidence.d.ts +19 -3
- package/types/lib/ecosystems/cppEvidence.d.ts.map +1 -1
- package/types/lib/ecosystems/cppIncludeResolver.d.ts +92 -0
- package/types/lib/ecosystems/cppIncludeResolver.d.ts.map +1 -0
- package/types/lib/ecosystems/denoutils.d.ts +9 -3
- package/types/lib/ecosystems/denoutils.d.ts.map +1 -1
- package/types/lib/ecosystems/ecosystems.d.ts +62 -13
- package/types/lib/ecosystems/ecosystems.d.ts.map +1 -1
- package/types/lib/ecosystems/golem.d.ts +81 -1
- package/types/lib/ecosystems/golem.d.ts.map +1 -1
- package/types/lib/ecosystems/gradleutils.d.ts +59 -7
- package/types/lib/ecosystems/gradleutils.d.ts.map +1 -1
- package/types/lib/ecosystems/jsEvidence.d.ts.map +1 -1
- package/types/lib/ecosystems/kosi.d.ts.map +1 -1
- package/types/lib/ecosystems/npmutils.d.ts +15 -0
- package/types/lib/ecosystems/npmutils.d.ts.map +1 -1
- package/types/lib/ecosystems/parsers-dotnet.d.ts +155 -5
- package/types/lib/ecosystems/parsers-dotnet.d.ts.map +1 -1
- package/types/lib/ecosystems/parsers-elm.d.ts.map +1 -1
- package/types/lib/ecosystems/parsers-gleam.d.ts.map +1 -1
- package/types/lib/ecosystems/parsers-go.d.ts +119 -5
- package/types/lib/ecosystems/parsers-go.d.ts.map +1 -1
- package/types/lib/ecosystems/parsers-js.d.ts +6 -1
- package/types/lib/ecosystems/parsers-js.d.ts.map +1 -1
- package/types/lib/ecosystems/parsers-julia.d.ts.map +1 -1
- package/types/lib/ecosystems/parsers-jvm.d.ts +74 -3
- package/types/lib/ecosystems/parsers-jvm.d.ts.map +1 -1
- package/types/lib/ecosystems/parsers-misc.d.ts +21 -59
- package/types/lib/ecosystems/parsers-misc.d.ts.map +1 -1
- package/types/lib/ecosystems/parsers-python.d.ts +57 -6
- package/types/lib/ecosystems/parsers-python.d.ts.map +1 -1
- package/types/lib/ecosystems/parsers-terraform.d.ts +38 -21
- package/types/lib/ecosystems/parsers-terraform.d.ts.map +1 -1
- package/types/lib/ecosystems/pythonutils.d.ts +26 -1
- package/types/lib/ecosystems/pythonutils.d.ts.map +1 -1
- package/types/lib/ecosystems/remote/huggingface.d.ts.map +1 -1
- package/types/lib/ecosystems/rubyutils.d.ts +21 -1
- package/types/lib/ecosystems/rubyutils.d.ts.map +1 -1
- package/types/lib/ecosystems/rusi.d.ts.map +1 -1
- package/types/lib/ecosystems/sbtutils.d.ts +88 -2
- package/types/lib/ecosystems/sbtutils.d.ts.map +1 -1
- package/types/lib/ecosystems/scalacliutils.d.ts +56 -0
- package/types/lib/ecosystems/scalacliutils.d.ts.map +1 -0
- package/types/lib/ecosystems/scalasem.d.ts +311 -0
- package/types/lib/ecosystems/scalasem.d.ts.map +1 -0
- package/types/lib/ecosystems/terraformRegistry.d.ts +9 -0
- package/types/lib/ecosystems/terraformRegistry.d.ts.map +1 -0
- package/types/lib/ecosystems/utils.d.ts +2 -2
- package/types/lib/ecosystems/utils.d.ts.map +1 -1
- package/types/lib/ecosystems/vendoredCode.d.ts +32 -0
- package/types/lib/ecosystems/vendoredCode.d.ts.map +1 -0
- package/types/lib/evinser/evinser.d.ts +100 -8
- package/types/lib/evinser/evinser.d.ts.map +1 -1
- package/types/lib/evinser/swiftsem.d.ts +10 -0
- package/types/lib/evinser/swiftsem.d.ts.map +1 -1
- package/types/lib/helpers/bomSigner.d.ts +80 -4
- package/types/lib/helpers/bomSigner.d.ts.map +1 -1
- package/types/lib/inventory/agentSkillSpec.d.ts +13 -0
- package/types/lib/inventory/agentSkillSpec.d.ts.map +1 -0
- package/types/lib/inventory/aiCollector.d.ts.map +1 -1
- package/types/lib/inventory/analyzer.d.ts.map +1 -1
- package/types/lib/inventory/apkInstalledDb.d.ts +42 -0
- package/types/lib/inventory/apkInstalledDb.d.ts.map +1 -0
- package/types/lib/inventory/atomUtils.d.ts +96 -10
- package/types/lib/inventory/atomUtils.d.ts.map +1 -1
- package/types/lib/inventory/auditCategories.d.ts +3 -0
- package/types/lib/inventory/auditCategories.d.ts.map +1 -1
- package/types/lib/inventory/buildToolRateLimit.d.ts +38 -0
- package/types/lib/inventory/buildToolRateLimit.d.ts.map +1 -0
- package/types/lib/inventory/cacheCommands.d.ts +2 -1
- package/types/lib/inventory/cacheCommands.d.ts.map +1 -1
- package/types/lib/inventory/cacheDir.d.ts +12 -4
- package/types/lib/inventory/cacheDir.d.ts.map +1 -1
- package/types/lib/inventory/certificates.d.ts +205 -0
- package/types/lib/inventory/certificates.d.ts.map +1 -0
- package/types/lib/inventory/cmakeBuildDirs.d.ts +58 -0
- package/types/lib/inventory/cmakeBuildDirs.d.ts.map +1 -0
- package/types/lib/inventory/communityAiConfigParser.d.ts.map +1 -1
- package/types/lib/inventory/deps.d.ts +61 -2
- package/types/lib/inventory/deps.d.ts.map +1 -1
- package/types/lib/inventory/display.d.ts +18 -0
- package/types/lib/inventory/display.d.ts.map +1 -1
- package/types/lib/inventory/dosai.d.ts +202 -14
- package/types/lib/inventory/dosai.d.ts.map +1 -1
- package/types/lib/inventory/dosaiParsers.d.ts +53 -7
- package/types/lib/inventory/dosaiParsers.d.ts.map +1 -1
- package/types/lib/inventory/dynamic.d.ts +16 -1
- package/types/lib/inventory/dynamic.d.ts.map +1 -1
- package/types/lib/inventory/envcontext.d.ts +40 -2
- package/types/lib/inventory/envcontext.d.ts.map +1 -1
- package/types/lib/inventory/evidenceUtils.d.ts +48 -14
- package/types/lib/inventory/evidenceUtils.d.ts.map +1 -1
- package/types/lib/inventory/fetchBatch.d.ts +83 -14
- package/types/lib/inventory/fetchBatch.d.ts.map +1 -1
- package/types/lib/inventory/fetchDiskCache.d.ts +169 -0
- package/types/lib/inventory/fetchDiskCache.d.ts.map +1 -0
- package/types/lib/inventory/forgeEnricher.d.ts.map +1 -1
- package/types/lib/inventory/formulationParsers.d.ts.map +1 -1
- package/types/lib/inventory/goBuildInfo.d.ts +10 -0
- package/types/lib/inventory/goBuildInfo.d.ts.map +1 -0
- package/types/lib/inventory/hbom.d.ts.map +1 -1
- package/types/lib/inventory/hbomAnalysis.d.ts +10 -0
- package/types/lib/inventory/hbomAnalysis.d.ts.map +1 -1
- package/types/lib/inventory/hostTopology.d.ts.map +1 -1
- package/types/lib/inventory/jvmLocalRepos.d.ts +178 -0
- package/types/lib/inventory/jvmLocalRepos.d.ts.map +1 -0
- package/types/lib/inventory/mcpConfigParser.d.ts.map +1 -1
- package/types/lib/inventory/osPackagePurl.d.ts +99 -0
- package/types/lib/inventory/osPackagePurl.d.ts.map +1 -0
- package/types/lib/inventory/osPackageResolver.d.ts +6 -2
- package/types/lib/inventory/osPackageResolver.d.ts.map +1 -1
- package/types/lib/inventory/osinfo.d.ts +31 -6
- package/types/lib/inventory/osinfo.d.ts.map +1 -1
- package/types/lib/inventory/osqueryTransform.d.ts +51 -0
- package/types/lib/inventory/osqueryTransform.d.ts.map +1 -1
- package/types/lib/inventory/parentSelection.d.ts +34 -0
- package/types/lib/inventory/parentSelection.d.ts.map +1 -0
- package/types/lib/inventory/phpBuildInfo.d.ts +142 -0
- package/types/lib/inventory/phpBuildInfo.d.ts.map +1 -0
- package/types/lib/inventory/phpHostProbe.d.ts +35 -0
- package/types/lib/inventory/phpHostProbe.d.ts.map +1 -0
- package/types/lib/inventory/rootfsCerts.d.ts +27 -0
- package/types/lib/inventory/rootfsCerts.d.ts.map +1 -0
- package/types/lib/inventory/rustFormulationParser.d.ts.map +1 -1
- package/types/lib/inventory/scalaCoords.d.ts +80 -0
- package/types/lib/inventory/scalaCoords.d.ts.map +1 -0
- package/types/lib/inventory/source.d.ts +28 -0
- package/types/lib/inventory/source.d.ts.map +1 -1
- package/types/lib/inventory/spdx.d.ts +24 -0
- package/types/lib/inventory/spdx.d.ts.map +1 -1
- package/types/lib/inventory/traceRunner.d.ts +16 -1
- package/types/lib/inventory/traceRunner.d.ts.map +1 -1
- package/types/lib/inventory/tracedCrypto.d.ts +64 -0
- package/types/lib/inventory/tracedCrypto.d.ts.map +1 -0
- package/types/lib/managers/binary.d.ts +10 -0
- package/types/lib/managers/binary.d.ts.map +1 -1
- package/types/lib/managers/docker.d.ts +12 -0
- package/types/lib/managers/docker.d.ts.map +1 -1
- package/types/lib/managers/oci.d.ts +3 -1
- package/types/lib/managers/oci.d.ts.map +1 -1
- package/types/lib/parsers/cmakeCache.d.ts +16 -0
- package/types/lib/parsers/cmakeCache.d.ts.map +1 -1
- package/types/lib/parsers/cmakeLists.d.ts +2 -1
- package/types/lib/parsers/cmakeLists.d.ts.map +1 -1
- package/types/lib/parsers/cmakePresets.d.ts +78 -0
- package/types/lib/parsers/cmakePresets.d.ts.map +1 -0
- package/types/lib/parsers/compileCommands.d.ts +115 -0
- package/types/lib/parsers/compileCommands.d.ts.map +1 -0
- package/types/lib/parsers/email.d.ts +19 -0
- package/types/lib/parsers/email.d.ts.map +1 -0
- package/types/lib/parsers/largeJson.d.ts +13 -0
- package/types/lib/parsers/largeJson.d.ts.map +1 -1
- package/types/lib/parsers/strictJson.d.ts +46 -0
- package/types/lib/parsers/strictJson.d.ts.map +1 -0
- package/types/lib/parsers/terraformConfig.d.ts +70 -0
- package/types/lib/parsers/terraformConfig.d.ts.map +1 -0
- package/types/lib/parsers/terraformSource.d.ts +66 -0
- package/types/lib/parsers/terraformSource.d.ts.map +1 -0
- package/types/lib/server/server.d.ts +8 -0
- package/types/lib/server/server.d.ts.map +1 -1
- package/types/lib/stages/postgen/annotator.d.ts.map +1 -1
- package/types/lib/stages/postgen/introspection/reflect.d.ts.map +1 -1
- package/types/lib/stages/postgen/postgen.d.ts.map +1 -1
- package/types/lib/stages/postgen/ruleEngine.d.ts +7 -4
- package/types/lib/stages/postgen/ruleEngine.d.ts.map +1 -1
- package/types/lib/stages/postgen/specVersionCompat.d.ts.map +1 -1
- package/types/lib/stages/pregen/pregen.d.ts +14 -1
- package/types/lib/stages/pregen/pregen.d.ts.map +1 -1
- package/types/lib/validator/bomValidator.d.ts.map +1 -1
- package/types/lib/validator/index.d.ts +8 -0
- package/types/lib/validator/index.d.ts.map +1 -1
- package/types/lib/validator/reporters/json.d.ts.map +1 -1
- package/lib/third-party/arborist/snapshots/calc-dep-flags.test.cjs +0 -462
package/lib/cli/nativeBom.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Buffer } from "node:buffer";
|
|
2
2
|
import { readFileSync, statSync } from "node:fs";
|
|
3
3
|
import { homedir } from "node:os";
|
|
4
|
-
import { basename, dirname, join, relative, resolve } from "node:path";
|
|
4
|
+
import { basename, dirname, join, relative, resolve, sep } from "node:path";
|
|
5
5
|
import process from "node:process";
|
|
6
6
|
|
|
7
7
|
import { build } from "@cdxgen/cdx-purl";
|
|
@@ -23,11 +23,17 @@ import {
|
|
|
23
23
|
import {
|
|
24
24
|
checksumFile,
|
|
25
25
|
getAllFiles,
|
|
26
|
+
getTmpDir,
|
|
26
27
|
safeExistsSync,
|
|
27
28
|
safeSpawnSync,
|
|
28
29
|
} from "../core/fs.js";
|
|
29
30
|
import { thoughtLog } from "../core/logger.js";
|
|
30
31
|
import { dirNameStr, isMac } from "../core/paths.js";
|
|
32
|
+
import {
|
|
33
|
+
isProjectToolingAllowed,
|
|
34
|
+
reportProjectToolingSkipped,
|
|
35
|
+
} from "../core/projectTooling.js";
|
|
36
|
+
import { readCrateArchiveValues } from "../ecosystems/cargoCache.js";
|
|
31
37
|
import {
|
|
32
38
|
buildDependentPurl,
|
|
33
39
|
collapseCmakeVersions,
|
|
@@ -35,7 +41,11 @@ import {
|
|
|
35
41
|
resolveCmakeContext,
|
|
36
42
|
withoutScrapedFetchDependency,
|
|
37
43
|
} from "../ecosystems/cmakeResolver.js";
|
|
38
|
-
import {
|
|
44
|
+
import {
|
|
45
|
+
emptyCppBuildContext,
|
|
46
|
+
resolveCppBuildContext,
|
|
47
|
+
} from "../ecosystems/cppBuildContext.js";
|
|
48
|
+
import { getCppModules, hasCppSources } from "../ecosystems/cppEvidence.js";
|
|
39
49
|
import {
|
|
40
50
|
getCratesMetadata,
|
|
41
51
|
getSwiftPackageMetadata,
|
|
@@ -50,6 +60,7 @@ import {
|
|
|
50
60
|
} from "../ecosystems/parsers-elm.js";
|
|
51
61
|
import { parseGleamProject } from "../ecosystems/parsers-gleam.js";
|
|
52
62
|
import {
|
|
63
|
+
compareGoVersions,
|
|
53
64
|
isGoModWhyNotNeeded,
|
|
54
65
|
parseGoListDep,
|
|
55
66
|
parseGoModData,
|
|
@@ -58,6 +69,7 @@ import {
|
|
|
58
69
|
parseGoModWhy,
|
|
59
70
|
parseGopkgData,
|
|
60
71
|
parseGosumData,
|
|
72
|
+
parseGosumHashes,
|
|
61
73
|
} from "../ecosystems/parsers-go.js";
|
|
62
74
|
import { parseJuliaProject } from "../ecosystems/parsers-julia.js";
|
|
63
75
|
import {
|
|
@@ -115,7 +127,9 @@ import {
|
|
|
115
127
|
} from "../ecosystems/parsers-rust.js";
|
|
116
128
|
import { parseSpackLock } from "../ecosystems/parsers-spack.js";
|
|
117
129
|
import { parseStackProject } from "../ecosystems/parsers-stack.js";
|
|
130
|
+
import { findVendoredCode } from "../ecosystems/vendoredCode.js";
|
|
118
131
|
import { resolveZigGraph } from "../ecosystems/zigResolver.js";
|
|
132
|
+
import { cmakeBuildDirCandidates } from "../inventory/cmakeBuildDirs.js";
|
|
119
133
|
import { mergeDependencies, trimComponents } from "../inventory/depsUtils.js";
|
|
120
134
|
import { convertOSQueryResults } from "../inventory/evidenceUtils.js";
|
|
121
135
|
import { applyPurl, nixBomRef, tryBuildPurl } from "../inventory/purl.js";
|
|
@@ -190,6 +204,30 @@ export function getCargoCacheDir() {
|
|
|
190
204
|
);
|
|
191
205
|
}
|
|
192
206
|
|
|
207
|
+
/**
|
|
208
|
+
* Add a Go module of the project, a nested go.mod or a go.work member, under
|
|
209
|
+
* the parent component. A module that is already the parent, one of its
|
|
210
|
+
* subcomponents, or a component (a directory replacement inside the project)
|
|
211
|
+
* is not added again, so no bom-ref appears twice.
|
|
212
|
+
*
|
|
213
|
+
* @param {Object} parentComponent The project's parent component
|
|
214
|
+
* @param {Object} moduleComponent The module to add
|
|
215
|
+
* @param {Object[]} pkgList Components found so far
|
|
216
|
+
*/
|
|
217
|
+
function addGoSubComponent(parentComponent, moduleComponent, pkgList) {
|
|
218
|
+
const ref = moduleComponent?.["bom-ref"];
|
|
219
|
+
if (
|
|
220
|
+
!ref ||
|
|
221
|
+
ref === parentComponent["bom-ref"] ||
|
|
222
|
+
parentComponent.components?.some((c) => c["bom-ref"] === ref) ||
|
|
223
|
+
pkgList.some((c) => c["bom-ref"] === ref)
|
|
224
|
+
) {
|
|
225
|
+
return;
|
|
226
|
+
}
|
|
227
|
+
parentComponent.components = parentComponent.components || [];
|
|
228
|
+
parentComponent.components.push(moduleComponent);
|
|
229
|
+
}
|
|
230
|
+
|
|
193
231
|
/**
|
|
194
232
|
* Function to create bom string for Go projects
|
|
195
233
|
*
|
|
@@ -305,6 +343,20 @@ export async function createGoBom(path, options) {
|
|
|
305
343
|
}
|
|
306
344
|
}
|
|
307
345
|
}
|
|
346
|
+
// go mod why answers for a module path, but go.sum also names versions
|
|
347
|
+
// that only took part in version selection. Only a version whose content
|
|
348
|
+
// go.sum holds a checksum for was ever downloaded, and of those, MVS
|
|
349
|
+
// builds the highest.
|
|
350
|
+
const builtVersions = {};
|
|
351
|
+
for (const apkg of pkgList) {
|
|
352
|
+
const built = builtVersions[apkg.name];
|
|
353
|
+
if (
|
|
354
|
+
apkg._integrity &&
|
|
355
|
+
(!built || compareGoVersions(apkg.version, built) > 0)
|
|
356
|
+
) {
|
|
357
|
+
builtVersions[apkg.name] = apkg.version;
|
|
358
|
+
}
|
|
359
|
+
}
|
|
308
360
|
// A module go reports as unneeded is optional, but only when every module
|
|
309
361
|
// was checked: once go mod why fails, the answers are incomplete, and a
|
|
310
362
|
// tool failure is not evidence that a module is unused.
|
|
@@ -313,7 +365,9 @@ export async function createGoBom(path, options) {
|
|
|
313
365
|
continue;
|
|
314
366
|
}
|
|
315
367
|
if (requiredModules.has(apkg.name)) {
|
|
316
|
-
apkg.
|
|
368
|
+
if (builtVersions[apkg.name] === apkg.version) {
|
|
369
|
+
apkg.scope = "required";
|
|
370
|
+
}
|
|
317
371
|
} else if (!circuitBreak && unneededModules.has(apkg.name)) {
|
|
318
372
|
apkg.scope = "optional";
|
|
319
373
|
}
|
|
@@ -339,12 +393,9 @@ export async function createGoBom(path, options) {
|
|
|
339
393
|
console.log(`Parsing ${f}`);
|
|
340
394
|
}
|
|
341
395
|
const gosumData = readFileSync(f, { encoding: "utf-8" });
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
gosumMap[`${pkg.name}@${pkg.version}`] = pkg._integrity;
|
|
346
|
-
});
|
|
347
|
-
}
|
|
396
|
+
// Only the hashes are needed here; reading them costs no registry
|
|
397
|
+
// round trip. The components come from go.mod and the go list output.
|
|
398
|
+
Object.assign(gosumMap, parseGosumHashes(gosumData));
|
|
348
399
|
}
|
|
349
400
|
}
|
|
350
401
|
|
|
@@ -379,6 +430,9 @@ export async function createGoBom(path, options) {
|
|
|
379
430
|
});
|
|
380
431
|
|
|
381
432
|
let rootParentComponent = null;
|
|
433
|
+
// Whether the go toolchain resolved a module graph. A module without
|
|
434
|
+
// dependencies resolves to no components, and that is a complete answer.
|
|
435
|
+
let resolvedByToolchain = false;
|
|
382
436
|
// Use the go list -deps and go mod why commands to generate a good quality BOM for non-docker invocations
|
|
383
437
|
if (
|
|
384
438
|
!hasAnyProjectType(["docker", "oci", "container", "os"], options, false)
|
|
@@ -398,13 +452,15 @@ export async function createGoBom(path, options) {
|
|
|
398
452
|
console.log("Executing go list -deps in", basePath);
|
|
399
453
|
}
|
|
400
454
|
// TODO: Replacing this with -json gives us more interesting data points such as GoFiles, Imports, and Deps
|
|
455
|
+
// The fields after Dir name the module content checksum and, for a
|
|
456
|
+
// module a replace directive swapped out, the replacement Go builds.
|
|
401
457
|
let result = safeSpawnSync(
|
|
402
458
|
"go",
|
|
403
459
|
[
|
|
404
460
|
"list",
|
|
405
461
|
"-deps",
|
|
406
462
|
"-f",
|
|
407
|
-
"'{{with .Module}}{{.Path}}|{{.Version}}|{{.Indirect}}|{{.GoMod}}|{{.GoVersion}}|{{.Main}}|{{.Time}}|{{.Deprecated}}|{{.GoModSum}}|{{.Dir}}{{end}}'",
|
|
463
|
+
"'{{with .Module}}{{.Path}}|{{.Version}}|{{.Indirect}}|{{.GoMod}}|{{.GoVersion}}|{{.Main}}|{{.Time}}|{{.Deprecated}}|{{.GoModSum}}|{{.Dir}}|{{.Sum}}|{{with .Replace}}{{.Path}}{{end}}|{{with .Replace}}{{.Version}}{{end}}|{{with .Replace}}{{.Sum}}{{end}}{{end}}'",
|
|
408
464
|
"./...",
|
|
409
465
|
],
|
|
410
466
|
{
|
|
@@ -448,7 +504,9 @@ export async function createGoBom(path, options) {
|
|
|
448
504
|
const stdout = result.stdout;
|
|
449
505
|
if (stdout) {
|
|
450
506
|
let cmdOutput = Buffer.from(stdout).toString();
|
|
451
|
-
const retMap = await parseGoListDep(cmdOutput, gosumMap
|
|
507
|
+
const retMap = await parseGoListDep(cmdOutput, gosumMap, {
|
|
508
|
+
mainModuleDir: basePath,
|
|
509
|
+
});
|
|
452
510
|
if (retMap.pkgList?.length) {
|
|
453
511
|
pkgList = pkgList.concat(retMap.pkgList);
|
|
454
512
|
}
|
|
@@ -457,6 +515,7 @@ export async function createGoBom(path, options) {
|
|
|
457
515
|
retMap.parentComponent &&
|
|
458
516
|
Object.keys(retMap.parentComponent).length
|
|
459
517
|
) {
|
|
518
|
+
resolvedByToolchain = true;
|
|
460
519
|
if (!rootParentComponent) {
|
|
461
520
|
// First (shallowest) module becomes the root
|
|
462
521
|
rootParentComponent = retMap.parentComponent;
|
|
@@ -464,12 +523,18 @@ export async function createGoBom(path, options) {
|
|
|
464
523
|
parentComponent = rootParentComponent;
|
|
465
524
|
} else {
|
|
466
525
|
// Subsequent modules become subcomponents
|
|
467
|
-
|
|
468
|
-
parentComponent
|
|
469
|
-
|
|
470
|
-
|
|
526
|
+
addGoSubComponent(
|
|
527
|
+
parentComponent,
|
|
528
|
+
retMap.parentComponent,
|
|
529
|
+
pkgList,
|
|
530
|
+
);
|
|
471
531
|
}
|
|
472
532
|
}
|
|
533
|
+
// The other members of a go.work workspace are modules of the same
|
|
534
|
+
// project, which no registry holds.
|
|
535
|
+
for (const workspaceModule of retMap.workspaceModules || []) {
|
|
536
|
+
addGoSubComponent(parentComponent, workspaceModule, pkgList);
|
|
537
|
+
}
|
|
473
538
|
if (DEBUG_MODE) {
|
|
474
539
|
console.log("Executing go mod graph in", basePath);
|
|
475
540
|
}
|
|
@@ -519,8 +584,11 @@ export async function createGoBom(path, options) {
|
|
|
519
584
|
}
|
|
520
585
|
// Retain the parent component hierarchy
|
|
521
586
|
if (Object.keys(retMap.parentComponent).length) {
|
|
522
|
-
|
|
523
|
-
|
|
587
|
+
addGoSubComponent(
|
|
588
|
+
parentComponent,
|
|
589
|
+
retMap.parentComponent,
|
|
590
|
+
pkgList,
|
|
591
|
+
);
|
|
524
592
|
}
|
|
525
593
|
}
|
|
526
594
|
} else {
|
|
@@ -533,6 +601,7 @@ export async function createGoBom(path, options) {
|
|
|
533
601
|
shell: isWin,
|
|
534
602
|
});
|
|
535
603
|
if (result.stdout) {
|
|
604
|
+
resolvedByToolchain = true;
|
|
536
605
|
const cmdOutput = Buffer.from(result.stdout).toString();
|
|
537
606
|
// The arguments to parseGoModGraph are slightly different to force inclusion of all packages
|
|
538
607
|
const retMap = await parseGoModGraph(
|
|
@@ -561,8 +630,11 @@ export async function createGoBom(path, options) {
|
|
|
561
630
|
parentComponent = rootParentComponent;
|
|
562
631
|
} else {
|
|
563
632
|
// Subsequent modules become subcomponents
|
|
564
|
-
|
|
565
|
-
|
|
633
|
+
addGoSubComponent(
|
|
634
|
+
parentComponent,
|
|
635
|
+
retMap.parentComponent,
|
|
636
|
+
pkgList,
|
|
637
|
+
);
|
|
566
638
|
}
|
|
567
639
|
}
|
|
568
640
|
} else {
|
|
@@ -584,7 +656,7 @@ export async function createGoBom(path, options) {
|
|
|
584
656
|
}
|
|
585
657
|
}
|
|
586
658
|
}
|
|
587
|
-
if (pkgList.length && !shouldManuallyParse) {
|
|
659
|
+
if ((pkgList.length || resolvedByToolchain) && !shouldManuallyParse) {
|
|
588
660
|
return buildBomNSData(options, pkgList, "golang", {
|
|
589
661
|
dependencies,
|
|
590
662
|
parentComponent,
|
|
@@ -727,11 +799,19 @@ function cargoAnswersVersion(cwd) {
|
|
|
727
799
|
* @param {string} [filterPlatform] Target triple to resolve the graph for
|
|
728
800
|
* @returns {object|undefined} Parsed `cargo metadata` output
|
|
729
801
|
*/
|
|
730
|
-
function runCargoMetadata(cargoTomlFile, filterPlatform) {
|
|
731
|
-
|
|
802
|
+
function runCargoMetadata(cargoTomlFile, filterPlatform, options = {}) {
|
|
803
|
+
// cargo reads `.cargo/config.toml` (rustc, rustc-wrapper, [env]) and rustup
|
|
804
|
+
// reads `rust-toolchain.toml` from the working directory, and `cargo
|
|
805
|
+
// metadata` runs rustc to learn the target. Without permission to run the
|
|
806
|
+
// project's tooling, cargo starts outside the project and stays offline.
|
|
807
|
+
const toolingAllowed = isProjectToolingAllowed(options);
|
|
808
|
+
const basePath = toolingAllowed ? dirname(cargoTomlFile) : getTmpDir();
|
|
732
809
|
const platformArgs = filterPlatform
|
|
733
810
|
? ["--filter-platform", filterPlatform]
|
|
734
811
|
: [];
|
|
812
|
+
if (!toolingAllowed) {
|
|
813
|
+
platformArgs.push("--offline");
|
|
814
|
+
}
|
|
735
815
|
// `--locked` keeps the user's lock file untouched; a workspace that is out of
|
|
736
816
|
// date with its lock file needs the retry without it.
|
|
737
817
|
for (const lockArgs of [["--locked"], []]) {
|
|
@@ -805,7 +885,7 @@ function annotateCargoDependencyKinds(
|
|
|
805
885
|
let anyMetadata = false;
|
|
806
886
|
let everyMetadata = true;
|
|
807
887
|
for (const cargoTomlFile of cargoFiles) {
|
|
808
|
-
const metadata = runCargoMetadata(cargoTomlFile);
|
|
888
|
+
const metadata = runCargoMetadata(cargoTomlFile, undefined, options);
|
|
809
889
|
if (!metadata) {
|
|
810
890
|
everyMetadata = false;
|
|
811
891
|
continue;
|
|
@@ -819,7 +899,11 @@ function annotateCargoDependencyKinds(
|
|
|
819
899
|
visitedWorkspaceRoots.add(workspaceRoot);
|
|
820
900
|
anyMetadata = true;
|
|
821
901
|
if (CARGO_TARGET) {
|
|
822
|
-
const targetMetadata = runCargoMetadata(
|
|
902
|
+
const targetMetadata = runCargoMetadata(
|
|
903
|
+
cargoTomlFile,
|
|
904
|
+
CARGO_TARGET,
|
|
905
|
+
options,
|
|
906
|
+
);
|
|
823
907
|
if (targetMetadata) {
|
|
824
908
|
for (const key of parseCargoMetadataResolve(targetMetadata)
|
|
825
909
|
.resolvedKeys) {
|
|
@@ -957,13 +1041,31 @@ export async function createRustBom(path, options) {
|
|
|
957
1041
|
`${options.multiProject ? "**/" : ""}Cargo.toml`,
|
|
958
1042
|
options,
|
|
959
1043
|
);
|
|
1044
|
+
// `cargo check` compiles the project, running its build scripts and
|
|
1045
|
+
// procedural macros, so --deep runs it only when the project's own tooling
|
|
1046
|
+
// may run.
|
|
1047
|
+
const cargoToolingAllowed = isProjectToolingAllowed(options);
|
|
1048
|
+
if (
|
|
1049
|
+
options.deep &&
|
|
1050
|
+
cargoFiles.length &&
|
|
1051
|
+
!cargoToolingAllowed &&
|
|
1052
|
+
!hasAnyProjectType(["oci"], options, false)
|
|
1053
|
+
) {
|
|
1054
|
+
reportProjectToolingSkipped(
|
|
1055
|
+
options,
|
|
1056
|
+
null,
|
|
1057
|
+
"Skipping 'cargo check' since dependency installation is disabled. Build scripts and procedural macros are not run, so the files each crate uses are not recorded.",
|
|
1058
|
+
);
|
|
1059
|
+
}
|
|
960
1060
|
// Attempt to build or generate lock files automatically
|
|
961
1061
|
for (const f of cargoFiles) {
|
|
962
1062
|
// If there are no cargo.lock files, we can attempt a cargo install when
|
|
963
1063
|
// options.deep is true or options.lifecycle == build or post-build with installDeps
|
|
964
1064
|
// Why the need for installDeps? It currently defaults to true, so let's obey if someone wants no installs
|
|
965
1065
|
if (
|
|
966
|
-
(options.deep &&
|
|
1066
|
+
(options.deep &&
|
|
1067
|
+
cargoToolingAllowed &&
|
|
1068
|
+
!hasAnyProjectType(["oci"], options, false)) ||
|
|
967
1069
|
(options.installDeps &&
|
|
968
1070
|
!safeExistsSync(f.replace(".toml", ".lock")) &&
|
|
969
1071
|
["build", "post-build"].includes(options.lifecycle))
|
|
@@ -1163,7 +1265,9 @@ export function buildCargoCacheComponent(crateFile) {
|
|
|
1163
1265
|
|
|
1164
1266
|
/**
|
|
1165
1267
|
* Enriches a cargo cache component with a SHA-256 hash and filename-based
|
|
1166
|
-
* identity evidence (confidence 0.5)
|
|
1268
|
+
* identity evidence (confidence 0.5), and with what the archive's own manifest
|
|
1269
|
+
* says: its licence, description and repository, read from the archive without
|
|
1270
|
+
* extracting it anywhere. Hash computation failures are ignored.
|
|
1167
1271
|
*
|
|
1168
1272
|
* @param {string} crateFile Absolute path to the `.crate` archive
|
|
1169
1273
|
* @param {object} [component] Component produced by `buildCargoCacheComponent`
|
|
@@ -1183,6 +1287,33 @@ export async function enrichCargoCacheComponent(crateFile, component) {
|
|
|
1183
1287
|
} catch {
|
|
1184
1288
|
// continue without hashes
|
|
1185
1289
|
}
|
|
1290
|
+
const archive = await readCrateArchiveValues(
|
|
1291
|
+
crateFile,
|
|
1292
|
+
component.name,
|
|
1293
|
+
component.version,
|
|
1294
|
+
);
|
|
1295
|
+
if (archive) {
|
|
1296
|
+
if (archive.values.license && !component.license) {
|
|
1297
|
+
component.license = archive.values.license;
|
|
1298
|
+
}
|
|
1299
|
+
if (archive.values.licenses && !component.licenses) {
|
|
1300
|
+
component.licenses = archive.values.licenses;
|
|
1301
|
+
}
|
|
1302
|
+
if (archive.values.description && !component.description) {
|
|
1303
|
+
component.description = archive.values.description;
|
|
1304
|
+
}
|
|
1305
|
+
if (archive.values.repository && !component.repository) {
|
|
1306
|
+
component.repository = { url: archive.values.repository };
|
|
1307
|
+
}
|
|
1308
|
+
if (archive.values.homepage && !component.homepage) {
|
|
1309
|
+
component.homepage = { url: archive.values.homepage };
|
|
1310
|
+
}
|
|
1311
|
+
component.properties = component.properties || [];
|
|
1312
|
+
component.properties.push({
|
|
1313
|
+
name: "cdx:cargo:metadataSource",
|
|
1314
|
+
value: "local-registry",
|
|
1315
|
+
});
|
|
1316
|
+
}
|
|
1186
1317
|
component.evidence = {
|
|
1187
1318
|
identity: {
|
|
1188
1319
|
field: "purl",
|
|
@@ -1365,6 +1496,7 @@ export function createCppBom(path, options) {
|
|
|
1365
1496
|
}
|
|
1366
1497
|
let pkgList = [];
|
|
1367
1498
|
let parentComponentDependencies = [];
|
|
1499
|
+
const subProjects = [];
|
|
1368
1500
|
if (conanLockFiles.length) {
|
|
1369
1501
|
for (const f of conanLockFiles) {
|
|
1370
1502
|
if (DEBUG_MODE) {
|
|
@@ -1477,8 +1609,17 @@ export function createCppBom(path, options) {
|
|
|
1477
1609
|
Object.keys(retMap.parentComponent).length &&
|
|
1478
1610
|
!addedParentComponentsMap[retMap.parentComponent.name]
|
|
1479
1611
|
) {
|
|
1612
|
+
// a project() below the scan root is a part of this project, not a
|
|
1613
|
+
// dependency of it
|
|
1480
1614
|
retMap.parentComponent.type = "library";
|
|
1481
|
-
|
|
1615
|
+
const subprojectDir = relative(scanRoot, resolve(dirname(f)))
|
|
1616
|
+
.split(sep)
|
|
1617
|
+
.join("/");
|
|
1618
|
+
retMap.parentComponent.properties = [
|
|
1619
|
+
...(retMap.parentComponent.properties || []),
|
|
1620
|
+
{ name: "cdx:cmake:subprojectDir", value: subprojectDir || "." },
|
|
1621
|
+
];
|
|
1622
|
+
subProjects.push(retMap.parentComponent);
|
|
1482
1623
|
addedParentComponentsMap[retMap.parentComponent.name] = true;
|
|
1483
1624
|
}
|
|
1484
1625
|
// Retain the dependency tree from cmake
|
|
@@ -1522,6 +1663,29 @@ export function createCppBom(path, options) {
|
|
|
1522
1663
|
boundaries: new Map(),
|
|
1523
1664
|
}
|
|
1524
1665
|
: resolveCmakeContext(path, options);
|
|
1666
|
+
// How the project is built: its presets and compilers (formulation), its
|
|
1667
|
+
// hardening options (project properties) and its own include directories.
|
|
1668
|
+
const isImageScan = hasAnyProjectType(
|
|
1669
|
+
["docker", "oci", "container", "os"],
|
|
1670
|
+
options,
|
|
1671
|
+
false,
|
|
1672
|
+
);
|
|
1673
|
+
// Code carried in the tree under a license of its own, outside the sources
|
|
1674
|
+
// of the dependencies CMake already knows and the build trees
|
|
1675
|
+
const vendored = isImageScan
|
|
1676
|
+
? { components: [], dirs: [] }
|
|
1677
|
+
: findVendoredCode(path, options, [
|
|
1678
|
+
...[...(cmakeContext.boundaries || new Map())]
|
|
1679
|
+
.filter(([, e]) => e?.kind === "fetch" || e?.kind === "submodule")
|
|
1680
|
+
.map(([dir]) => resolve(path, dir)),
|
|
1681
|
+
...cmakeBuildDirCandidates(path, options),
|
|
1682
|
+
]);
|
|
1683
|
+
if (vendored.components.length) {
|
|
1684
|
+
pkgList = pkgList.concat(vendored.components);
|
|
1685
|
+
}
|
|
1686
|
+
const buildContext = isImageScan
|
|
1687
|
+
? emptyCppBuildContext()
|
|
1688
|
+
: resolveCppBuildContext(path, options, cmakeContext, vendored.dirs);
|
|
1525
1689
|
if (cmakeContext.rootProject?.version && parentComponent) {
|
|
1526
1690
|
const resolvedVersion = cmakeContext.rootProject.version;
|
|
1527
1691
|
const scrapedVersion = parentComponent.version;
|
|
@@ -1651,30 +1815,44 @@ export function createCppBom(path, options) {
|
|
|
1651
1815
|
// We collect OS packages with the word dev in the name using osquery here
|
|
1652
1816
|
// rpm, deb and ebuild are supported
|
|
1653
1817
|
// TODO: For archlinux and alpine users we need a different mechanism to collect this information
|
|
1654
|
-
|
|
1655
|
-
|
|
1656
|
-
|
|
1657
|
-
|
|
1658
|
-
|
|
1659
|
-
|
|
1660
|
-
|
|
1661
|
-
|
|
1662
|
-
|
|
1663
|
-
|
|
1664
|
-
|
|
1665
|
-
|
|
1666
|
-
|
|
1667
|
-
|
|
1668
|
-
|
|
1669
|
-
|
|
1670
|
-
|
|
1671
|
-
|
|
1818
|
+
// The packages only resolve the headers named by the usages slice, so
|
|
1819
|
+
// they are not queried when there is neither a slice to reuse nor a C or
|
|
1820
|
+
// C++ source for atom to read.
|
|
1821
|
+
if (
|
|
1822
|
+
(options.usagesSlicesFile && safeExistsSync(options.usagesSlicesFile)) ||
|
|
1823
|
+
hasCppSources(path, options)
|
|
1824
|
+
) {
|
|
1825
|
+
for (const queryCategory of Object.keys(cosDbQueries)) {
|
|
1826
|
+
const queryObj = cosDbQueries[queryCategory];
|
|
1827
|
+
const results = executeOsQuery(queryObj.query);
|
|
1828
|
+
const dlist = convertOSQueryResults(
|
|
1829
|
+
queryCategory,
|
|
1830
|
+
queryObj,
|
|
1831
|
+
results,
|
|
1832
|
+
true,
|
|
1833
|
+
{
|
|
1834
|
+
deb: executeDpkgList,
|
|
1835
|
+
rpm: executeRpmList,
|
|
1836
|
+
apk: executeApkList,
|
|
1837
|
+
ebuild: executeEqueryList,
|
|
1838
|
+
alpm: executeAlpmList,
|
|
1839
|
+
},
|
|
1840
|
+
);
|
|
1841
|
+
if (dlist?.length) {
|
|
1842
|
+
osPkgsList = osPkgsList.concat(dlist);
|
|
1843
|
+
}
|
|
1672
1844
|
}
|
|
1673
1845
|
}
|
|
1674
1846
|
// Now we check with atom and attempt to detect all external modules via usages
|
|
1675
1847
|
// We pass the current list of packages so that we enhance the current list and replace
|
|
1676
1848
|
// components inadvertently. For example, we might resolved a name, version and url information already via cmake
|
|
1677
|
-
const retMap = getCppModules(
|
|
1849
|
+
const retMap = getCppModules(
|
|
1850
|
+
path,
|
|
1851
|
+
options,
|
|
1852
|
+
osPkgsList,
|
|
1853
|
+
pkgList,
|
|
1854
|
+
buildContext.isFirstPartyHeader,
|
|
1855
|
+
);
|
|
1678
1856
|
if (retMap.pkgList?.length) {
|
|
1679
1857
|
pkgList = pkgList.concat(retMap.pkgList);
|
|
1680
1858
|
}
|
|
@@ -1718,6 +1896,33 @@ export function createCppBom(path, options) {
|
|
|
1718
1896
|
]);
|
|
1719
1897
|
}
|
|
1720
1898
|
|
|
1899
|
+
if (subProjects.length) {
|
|
1900
|
+
if (parentComponent) {
|
|
1901
|
+
parentComponent.components = parentComponent.components || [];
|
|
1902
|
+
for (const sub of subProjects) {
|
|
1903
|
+
if (
|
|
1904
|
+
!parentComponent.components.some(
|
|
1905
|
+
(c) => c["bom-ref"] === sub["bom-ref"],
|
|
1906
|
+
) &&
|
|
1907
|
+
sub["bom-ref"] !== parentComponent["bom-ref"]
|
|
1908
|
+
) {
|
|
1909
|
+
parentComponent.components.push(sub);
|
|
1910
|
+
}
|
|
1911
|
+
}
|
|
1912
|
+
} else {
|
|
1913
|
+
// with no project at the scan root there is nothing to nest them under
|
|
1914
|
+
pkgList = pkgList.concat(subProjects);
|
|
1915
|
+
}
|
|
1916
|
+
}
|
|
1917
|
+
if (parentComponent && buildContext.parentProperties.length) {
|
|
1918
|
+
parentComponent.properties = (parentComponent.properties || []).filter(
|
|
1919
|
+
(p) =>
|
|
1920
|
+
!buildContext.parentProperties.some(
|
|
1921
|
+
(bp) => bp.name === p.name && bp.value === p.value,
|
|
1922
|
+
),
|
|
1923
|
+
);
|
|
1924
|
+
parentComponent.properties.push(...buildContext.parentProperties);
|
|
1925
|
+
}
|
|
1721
1926
|
if (parentComponent) {
|
|
1722
1927
|
sanitizeUnresolvedPurl(parentComponent);
|
|
1723
1928
|
if (parentComponent.components) {
|
|
@@ -1734,6 +1939,7 @@ export function createCppBom(path, options) {
|
|
|
1734
1939
|
src: path,
|
|
1735
1940
|
parentComponent,
|
|
1736
1941
|
dependencies,
|
|
1942
|
+
formulationList: buildContext.formulationComponents,
|
|
1737
1943
|
});
|
|
1738
1944
|
}
|
|
1739
1945
|
|
|
@@ -1761,11 +1967,35 @@ export function createClojureBom(path, options) {
|
|
|
1761
1967
|
if (readEnvironmentVariable("LEIN_ARGS")) {
|
|
1762
1968
|
LEIN_ARGS = readEnvironmentVariable("LEIN_ARGS").split(" ");
|
|
1763
1969
|
}
|
|
1970
|
+
// `lein deps :tree-data` evaluates project.clj, which is a Clojure
|
|
1971
|
+
// program, so it belongs to the dependency-tooling surface disabled by
|
|
1972
|
+
// --no-install-deps and the pre-build lifecycle.
|
|
1973
|
+
const leinToolingAllowed = isProjectToolingAllowed(options);
|
|
1764
1974
|
for (const f of leinFiles) {
|
|
1765
1975
|
if (DEBUG_MODE) {
|
|
1766
1976
|
console.log(`Parsing ${f}`);
|
|
1767
1977
|
}
|
|
1768
1978
|
const basePath = dirname(f);
|
|
1979
|
+
if (!leinToolingAllowed) {
|
|
1980
|
+
reportProjectToolingSkipped(
|
|
1981
|
+
options,
|
|
1982
|
+
"clojure.lein.tooling-disabled",
|
|
1983
|
+
"Skipping 'lein deps :tree-data' since dependency installation is disabled. Only the dependencies declared in project.clj will be used.",
|
|
1984
|
+
{
|
|
1985
|
+
ecosystem: "clojure",
|
|
1986
|
+
tool: "lein",
|
|
1987
|
+
impact: "transitive-deps",
|
|
1988
|
+
detail:
|
|
1989
|
+
"Dependency installation is disabled, so project.clj was not evaluated and only its directly declared dependencies are available.",
|
|
1990
|
+
},
|
|
1991
|
+
);
|
|
1992
|
+
const leinData = readFileSync(f, { encoding: "utf-8" });
|
|
1993
|
+
const dlist = parseLeiningenData(leinData);
|
|
1994
|
+
if (dlist?.length) {
|
|
1995
|
+
pkgList = pkgList.concat(dlist);
|
|
1996
|
+
}
|
|
1997
|
+
continue;
|
|
1998
|
+
}
|
|
1769
1999
|
console.log("Executing", LEIN_CMD, "in", basePath);
|
|
1770
2000
|
const result = safeSpawnSync(LEIN_CMD, LEIN_ARGS, {
|
|
1771
2001
|
cwd: basePath,
|
|
@@ -2126,7 +2356,39 @@ export async function createSwiftBom(path, options) {
|
|
|
2126
2356
|
);
|
|
2127
2357
|
}
|
|
2128
2358
|
if (swiftFiles.length) {
|
|
2359
|
+
// A SwiftPM manifest is a Swift program, so `swift package dump-package`
|
|
2360
|
+
// and `show-dependencies` execute the scanned project's code (and fetch
|
|
2361
|
+
// missing dependencies). They belong to the dependency-tooling surface
|
|
2362
|
+
// disabled by --no-install-deps and the pre-build lifecycle; the BOM then
|
|
2363
|
+
// comes from Package.resolved alone.
|
|
2364
|
+
const swiftToolingAllowed = isProjectToolingAllowed(options);
|
|
2365
|
+
if (!swiftToolingAllowed) {
|
|
2366
|
+
reportProjectToolingSkipped(
|
|
2367
|
+
options,
|
|
2368
|
+
"swift.tooling-disabled",
|
|
2369
|
+
"Skipping 'swift package show-dependencies' since dependency installation is disabled. Only the packages in Package.resolved will be used.",
|
|
2370
|
+
{
|
|
2371
|
+
ecosystem: "swift",
|
|
2372
|
+
tool: "swift",
|
|
2373
|
+
impact: "transitive-deps",
|
|
2374
|
+
detail:
|
|
2375
|
+
"Dependency installation is disabled, so the Package.swift manifest was not evaluated and only the packages from Package.resolved are available.",
|
|
2376
|
+
},
|
|
2377
|
+
);
|
|
2378
|
+
// The manifest is not run, so a project without Package.resolved still
|
|
2379
|
+
// gets a parent component named after its directory.
|
|
2380
|
+
if (!Object.keys(parentComponent).length) {
|
|
2381
|
+
parentComponent = createDefaultParentComponent(
|
|
2382
|
+
swiftFiles[0],
|
|
2383
|
+
"swift",
|
|
2384
|
+
options,
|
|
2385
|
+
);
|
|
2386
|
+
}
|
|
2387
|
+
}
|
|
2129
2388
|
for (const f of swiftFiles) {
|
|
2389
|
+
if (!swiftToolingAllowed) {
|
|
2390
|
+
break;
|
|
2391
|
+
}
|
|
2130
2392
|
const basePath = dirname(f);
|
|
2131
2393
|
if (completedPath.includes(basePath)) {
|
|
2132
2394
|
continue;
|
|
@@ -2328,7 +2590,7 @@ export async function createCocoaBom(path, options) {
|
|
|
2328
2590
|
"application",
|
|
2329
2591
|
);
|
|
2330
2592
|
const podfileLock = loadYaml(readFileSync(lockFile, "utf-8"));
|
|
2331
|
-
const pods = await parsePodfileLock(podfileLock, projectPath);
|
|
2593
|
+
const pods = await parsePodfileLock(podfileLock, projectPath, path);
|
|
2332
2594
|
const allObjects = new Map();
|
|
2333
2595
|
if (options) {
|
|
2334
2596
|
// Every remote podspec the scan below reads is known from the lockfile,
|
|
@@ -2352,10 +2614,33 @@ export async function createCocoaBom(path, options) {
|
|
|
2352
2614
|
allDependencies.set(name, podDependencies);
|
|
2353
2615
|
}
|
|
2354
2616
|
const targetDependencies = new Map();
|
|
2355
|
-
|
|
2356
|
-
|
|
2357
|
-
|
|
2358
|
-
|
|
2617
|
+
// `pod ipc podfile-json` evaluates the Podfile, which is a Ruby program,
|
|
2618
|
+
// so per-target filtering through it belongs to the dependency-tooling
|
|
2619
|
+
// surface disabled by --no-install-deps and the pre-build lifecycle. A
|
|
2620
|
+
// gated scan then keeps every pod the lockfile resolved (the union across
|
|
2621
|
+
// targets) instead of the configured target subset.
|
|
2622
|
+
const cocoaTargetsConfigured =
|
|
2623
|
+
readEnvironmentVariable("COCOA_INCLUDED_TARGETS") ||
|
|
2624
|
+
readEnvironmentVariable("COCOA_EXCLUDED_TARGETS");
|
|
2625
|
+
const cocoaToolingAllowed = isProjectToolingAllowed(options);
|
|
2626
|
+
// True only when target names the Podfile actually resolved are known, so
|
|
2627
|
+
// the include/exclude filters below can be applied to real targets.
|
|
2628
|
+
let targetFilteringActive = false;
|
|
2629
|
+
if (!cocoaTargetsConfigured || !cocoaToolingAllowed) {
|
|
2630
|
+
if (cocoaTargetsConfigured) {
|
|
2631
|
+
reportProjectToolingSkipped(
|
|
2632
|
+
options,
|
|
2633
|
+
"cocoa.podfile-json.tooling-disabled",
|
|
2634
|
+
"Skipping 'pod ipc podfile-json' since dependency installation is disabled. Every pod from Podfile.lock is included without per-target filtering.",
|
|
2635
|
+
{
|
|
2636
|
+
ecosystem: "cocoa",
|
|
2637
|
+
tool: "pod",
|
|
2638
|
+
impact: "components",
|
|
2639
|
+
detail:
|
|
2640
|
+
"Dependency installation is disabled, so the Podfile was not evaluated and target filtering fell back to all pods resolved in Podfile.lock.",
|
|
2641
|
+
},
|
|
2642
|
+
);
|
|
2643
|
+
}
|
|
2359
2644
|
targetDependencies.set("Pods", podfileLock["DEPENDENCIES"]);
|
|
2360
2645
|
} else {
|
|
2361
2646
|
const result = executePodCommand(
|
|
@@ -2363,18 +2648,39 @@ export async function createCocoaBom(path, options) {
|
|
|
2363
2648
|
projectPath,
|
|
2364
2649
|
options,
|
|
2365
2650
|
);
|
|
2366
|
-
|
|
2367
|
-
|
|
2368
|
-
resolvedPodFile
|
|
2369
|
-
|
|
2370
|
-
|
|
2651
|
+
let resolvedPodFile;
|
|
2652
|
+
try {
|
|
2653
|
+
resolvedPodFile = JSON.parse(result.stdout);
|
|
2654
|
+
} catch (_e) {
|
|
2655
|
+
resolvedPodFile = undefined;
|
|
2656
|
+
}
|
|
2657
|
+
if (resolvedPodFile?.target_definitions?.length) {
|
|
2658
|
+
parsePodfileTargets(
|
|
2659
|
+
resolvedPodFile["target_definitions"][0],
|
|
2660
|
+
targetDependencies,
|
|
2661
|
+
);
|
|
2662
|
+
targetFilteringActive = true;
|
|
2663
|
+
} else {
|
|
2664
|
+
// pod failed or printed nothing usable (it refuses to run as root,
|
|
2665
|
+
// for one), and an unparseable Podfile used to abort the whole scan.
|
|
2666
|
+
// Keep every locked pod rather than none.
|
|
2667
|
+
console.log(
|
|
2668
|
+
"The Podfile could not be resolved with CocoaPods, so all pods from Podfile.lock are included without per-target filtering.",
|
|
2669
|
+
);
|
|
2670
|
+
targetDependencies.set("Pods", podfileLock["DEPENDENCIES"]);
|
|
2671
|
+
}
|
|
2371
2672
|
}
|
|
2372
2673
|
const usedTargets = new Set(
|
|
2373
|
-
readEnvironmentVariable("COCOA_INCLUDED_TARGETS")
|
|
2674
|
+
targetFilteringActive && readEnvironmentVariable("COCOA_INCLUDED_TARGETS")
|
|
2374
2675
|
? readEnvironmentVariable("COCOA_INCLUDED_TARGETS").split(",")
|
|
2375
2676
|
: targetDependencies.keys(),
|
|
2376
2677
|
);
|
|
2377
|
-
|
|
2678
|
+
// Without the resolved Podfile there are no target names to exclude, and
|
|
2679
|
+
// excluding the lockfile's stand-in "Pods" target would drop every pod.
|
|
2680
|
+
if (
|
|
2681
|
+
targetFilteringActive &&
|
|
2682
|
+
readEnvironmentVariable("COCOA_EXCLUDED_TARGETS")
|
|
2683
|
+
) {
|
|
2378
2684
|
readEnvironmentVariable("COCOA_EXCLUDED_TARGETS")
|
|
2379
2685
|
.split(",")
|
|
2380
2686
|
.forEach((excludedTarget) => {
|