@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/managers/docker.js
CHANGED
|
@@ -18,10 +18,11 @@ import process from "node:process";
|
|
|
18
18
|
import stream from "node:stream/promises";
|
|
19
19
|
import { URL } from "node:url";
|
|
20
20
|
|
|
21
|
-
import { x } from "tar";
|
|
21
|
+
import { t as listTar, x } from "tar";
|
|
22
22
|
|
|
23
23
|
import {
|
|
24
24
|
DEBUG_MODE,
|
|
25
|
+
isAllowedHttpHost,
|
|
25
26
|
isDryRun,
|
|
26
27
|
readEnvironmentVariable,
|
|
27
28
|
recordActivity,
|
|
@@ -1081,6 +1082,36 @@ const isSafeImageReference = (fullImageName) =>
|
|
|
1081
1082
|
fullImageName === fullImageName.trim() &&
|
|
1082
1083
|
isImageReference(fullImageName);
|
|
1083
1084
|
|
|
1085
|
+
/**
|
|
1086
|
+
* Whether an image named in a scanned manifest, such as a docker-compose file
|
|
1087
|
+
* or a Kubernetes spec, may be pulled and inventoried. The name comes from the
|
|
1088
|
+
* scanned project, so a local archive path would read files outside the
|
|
1089
|
+
* allowed paths and a registry outside CDXGEN_ALLOWED_HOSTS would bypass the
|
|
1090
|
+
* host allowlist.
|
|
1091
|
+
*
|
|
1092
|
+
* @param {string} fullImageName Image name from the manifest
|
|
1093
|
+
* @param {Object} [imageObj] Result of parseImageName for the same name
|
|
1094
|
+
* @returns {boolean} true when the image may be followed
|
|
1095
|
+
*/
|
|
1096
|
+
export const isFollowableManifestImage = (fullImageName, imageObj) => {
|
|
1097
|
+
if (!isSafeImageReference(fullImageName)) {
|
|
1098
|
+
return false;
|
|
1099
|
+
}
|
|
1100
|
+
const allowedHostsEnv = readEnvironmentVariable("CDXGEN_ALLOWED_HOSTS");
|
|
1101
|
+
if (!allowedHostsEnv) {
|
|
1102
|
+
return true;
|
|
1103
|
+
}
|
|
1104
|
+
const registry =
|
|
1105
|
+
(imageObj || parseImageName(fullImageName)).registry || "docker.io";
|
|
1106
|
+
let registryHost;
|
|
1107
|
+
try {
|
|
1108
|
+
registryHost = new URL(`https://${registry}`).hostname;
|
|
1109
|
+
} catch (_err) {
|
|
1110
|
+
return false;
|
|
1111
|
+
}
|
|
1112
|
+
return isAllowedHttpHost(registryHost, allowedHostsEnv);
|
|
1113
|
+
};
|
|
1114
|
+
|
|
1084
1115
|
/**
|
|
1085
1116
|
* Parse image name
|
|
1086
1117
|
*
|
|
@@ -1336,58 +1367,59 @@ export const getImage = async (fullImageName) => {
|
|
|
1336
1367
|
let dockerCmd;
|
|
1337
1368
|
if (needsCliFallback()) {
|
|
1338
1369
|
dockerCmd = getContainerCliCmd();
|
|
1339
|
-
|
|
1340
|
-
//
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
}
|
|
1354
|
-
}
|
|
1355
|
-
if (needsPull) {
|
|
1356
|
-
result = safeSpawnSync(dockerCmd, ["pull", fullImageName]);
|
|
1357
|
-
if (result.status !== 0 || result.error) {
|
|
1370
|
+
// The local image is checked with the reference itself. `image inspect`
|
|
1371
|
+
// resolves the reference exactly as the pull below would, so a fully
|
|
1372
|
+
// qualified docker.io/library/... name and a digest reference both find
|
|
1373
|
+
// a local image. The `images` listing compared Repository:Tag strings
|
|
1374
|
+
// and missed both. docker, podman, nerdctl and wslc all implement
|
|
1375
|
+
// `image inspect`.
|
|
1376
|
+
let inspectResult = safeSpawnSync(dockerCmd, [
|
|
1377
|
+
"image",
|
|
1378
|
+
"inspect",
|
|
1379
|
+
fullImageName,
|
|
1380
|
+
]);
|
|
1381
|
+
if (inspectResult.status !== 0 || inspectResult.error) {
|
|
1382
|
+
const pullResult = safeSpawnSync(dockerCmd, ["pull", fullImageName]);
|
|
1383
|
+
if (pullResult.status !== 0 || pullResult.error) {
|
|
1358
1384
|
if (isWslcCmd(dockerCmd)) {
|
|
1359
1385
|
// wslc runs Docker Engine inside its own VM, so its errors may
|
|
1360
1386
|
// mention a docker daemon; the Docker Desktop and DOCKER_CMD hints
|
|
1361
1387
|
// below do not apply. Show wslc's own error instead.
|
|
1362
|
-
if (isWslcSessionFailure(
|
|
1388
|
+
if (isWslcSessionFailure(pullResult.stderr)) {
|
|
1363
1389
|
printWslcSessionFailureHint();
|
|
1364
|
-
} else if (
|
|
1365
|
-
console.log(
|
|
1390
|
+
} else if (pullResult.stderr) {
|
|
1391
|
+
console.log(pullResult.stderr);
|
|
1366
1392
|
}
|
|
1367
|
-
} else if (
|
|
1393
|
+
} else if (
|
|
1394
|
+
pullResult.stderr?.includes("docker daemon is not running")
|
|
1395
|
+
) {
|
|
1368
1396
|
console.log(
|
|
1369
1397
|
"Ensure Docker for Desktop is running as an administrator with 'Exposing daemon on TCP without TLS' setting turned on.",
|
|
1370
1398
|
);
|
|
1371
|
-
} else if (
|
|
1399
|
+
} else if (pullResult.stderr?.includes("not found")) {
|
|
1372
1400
|
console.log(
|
|
1373
1401
|
"Set the environment variable DOCKER_CMD to use an alternative command such as nerdctl or podman.",
|
|
1374
1402
|
);
|
|
1375
|
-
} else if (
|
|
1376
|
-
console.log(
|
|
1403
|
+
} else if (pullResult.stderr) {
|
|
1404
|
+
console.log(pullResult.stderr);
|
|
1377
1405
|
}
|
|
1378
1406
|
}
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1407
|
+
inspectResult = safeSpawnSync(dockerCmd, [
|
|
1408
|
+
"image",
|
|
1409
|
+
"inspect",
|
|
1410
|
+
fullImageName,
|
|
1411
|
+
]);
|
|
1412
|
+
}
|
|
1413
|
+
if (inspectResult.status !== 0 || inspectResult.error) {
|
|
1414
|
+
if (inspectResult.stderr) {
|
|
1415
|
+
console.log(inspectResult.stderr);
|
|
1384
1416
|
}
|
|
1385
1417
|
suggestWslcAlternative(dockerCmd);
|
|
1386
1418
|
// Continue with the daemon client when the CLI fallback is unavailable
|
|
1387
1419
|
// or unable to inspect the image.
|
|
1388
1420
|
} else {
|
|
1389
1421
|
try {
|
|
1390
|
-
const stdout =
|
|
1422
|
+
const stdout = inspectResult.stdout;
|
|
1391
1423
|
if (stdout) {
|
|
1392
1424
|
const inspectData = JSON.parse(Buffer.from(stdout).toString());
|
|
1393
1425
|
if (inspectData && Array.isArray(inspectData)) {
|
|
@@ -1585,19 +1617,20 @@ function handleTarWarning(code, message) {
|
|
|
1585
1617
|
}
|
|
1586
1618
|
}
|
|
1587
1619
|
|
|
1588
|
-
// These paths are known to cause extract errors
|
|
1620
|
+
// These paths are known to cause extract errors. CA-store directories
|
|
1621
|
+
// (etc/ssl/certs, etc/pki/ca-trust, ssl/certs, cacerts,
|
|
1622
|
+
// var/lib/ca-certificates) are deliberately NOT excluded any more: their
|
|
1623
|
+
// original extract failures came from the hash-named symlink farms, and
|
|
1624
|
+
// symlinks/hardlinks are excluded by type below, while the regular
|
|
1625
|
+
// certificate files are exactly what a CBOM must inventory.
|
|
1589
1626
|
const EXTRACT_EXCLUDE_PATHS = [
|
|
1590
1627
|
"etc/machine-id",
|
|
1591
1628
|
"etc/gshadow",
|
|
1592
1629
|
"etc/shadow",
|
|
1593
1630
|
"etc/passwd",
|
|
1594
|
-
"etc/ssl/certs",
|
|
1595
|
-
"etc/pki/ca-trust",
|
|
1596
1631
|
"usr/lib/systemd/",
|
|
1597
1632
|
"usr/lib64/libdevmapper.so",
|
|
1598
1633
|
"usr/sbin/",
|
|
1599
|
-
"cacerts",
|
|
1600
|
-
"ssl/certs",
|
|
1601
1634
|
"logs/",
|
|
1602
1635
|
"dev/",
|
|
1603
1636
|
"proc/",
|
|
@@ -1607,7 +1640,6 @@ const EXTRACT_EXCLUDE_PATHS = [
|
|
|
1607
1640
|
"usr/share/man/",
|
|
1608
1641
|
"usr/share/icons/",
|
|
1609
1642
|
"usr/share/i18n/",
|
|
1610
|
-
"var/lib/ca-certificates",
|
|
1611
1643
|
"root/.gnupg",
|
|
1612
1644
|
"root/.dotnet",
|
|
1613
1645
|
"usr/share/licenses/device-mapper-libs",
|
|
@@ -1633,16 +1665,18 @@ const MEDIA_EXTENSIONS = new Set([
|
|
|
1633
1665
|
".eot",
|
|
1634
1666
|
]);
|
|
1635
1667
|
|
|
1636
|
-
// These
|
|
1668
|
+
// These entry types are known to cause extract errors. The names are the
|
|
1669
|
+
// ones node-tar's header parser assigns (types.js in the tar package):
|
|
1670
|
+
// symlinks and hardlinks ("SymbolicLink", "Link") are how CA-store
|
|
1671
|
+
// hash-named entries appear, which is why the CA paths could be un-excluded
|
|
1672
|
+
// above once these were dropped by type.
|
|
1637
1673
|
const EXTRACT_EXCLUDE_TYPES = new Set([
|
|
1638
1674
|
"BlockDevice",
|
|
1639
1675
|
"CharacterDevice",
|
|
1640
1676
|
"FIFO",
|
|
1641
|
-
"
|
|
1642
|
-
"
|
|
1677
|
+
"ContinuationFile",
|
|
1678
|
+
"TapeVolumeHeader",
|
|
1643
1679
|
"SymbolicLink",
|
|
1644
|
-
"RenamedOrSymlinked",
|
|
1645
|
-
"HardLink",
|
|
1646
1680
|
"Link",
|
|
1647
1681
|
]);
|
|
1648
1682
|
|
|
@@ -1993,6 +2027,126 @@ const resolveContainedArchivePath = (tempDir, archiveRef, kind) => {
|
|
|
1993
2027
|
return join(tempDir, archiveRef);
|
|
1994
2028
|
};
|
|
1995
2029
|
|
|
2030
|
+
const WHITEOUT_PREFIX = ".wh.";
|
|
2031
|
+
const WHITEOUT_OPAQUE = ".wh..wh..opq";
|
|
2032
|
+
|
|
2033
|
+
/**
|
|
2034
|
+
* Split an untrusted tar entry path into safe segments. Returns undefined when
|
|
2035
|
+
* the path contains a parent-directory segment.
|
|
2036
|
+
*
|
|
2037
|
+
* @param {string} entryPath Raw entry path from a layer
|
|
2038
|
+
* @returns {string[]|undefined} Path segments, or undefined when unsafe
|
|
2039
|
+
*/
|
|
2040
|
+
const safeEntrySegments = (entryPath) => {
|
|
2041
|
+
const stripped = stripAbsolutePath(String(entryPath).replaceAll("\\", "/"));
|
|
2042
|
+
const parts = stripped.split("/").filter((p) => p && p !== ".");
|
|
2043
|
+
return parts.includes("..") ? undefined : parts;
|
|
2044
|
+
};
|
|
2045
|
+
|
|
2046
|
+
/**
|
|
2047
|
+
* Walk down from rootDir through real directories only. A symlink or a
|
|
2048
|
+
* missing component stops the walk, so removals never leave rootDir.
|
|
2049
|
+
*
|
|
2050
|
+
* @param {string} rootDir Extraction root
|
|
2051
|
+
* @param {string[]} parts Directory segments below the root
|
|
2052
|
+
* @returns {string|undefined} The directory path, or undefined
|
|
2053
|
+
*/
|
|
2054
|
+
const resolveRealDir = (rootDir, parts) => {
|
|
2055
|
+
let current = rootDir;
|
|
2056
|
+
for (const part of parts) {
|
|
2057
|
+
current = join(current, part);
|
|
2058
|
+
let st;
|
|
2059
|
+
try {
|
|
2060
|
+
st = lstatSync(current);
|
|
2061
|
+
} catch (_err) {
|
|
2062
|
+
return undefined;
|
|
2063
|
+
}
|
|
2064
|
+
if (!st.isDirectory()) {
|
|
2065
|
+
return undefined;
|
|
2066
|
+
}
|
|
2067
|
+
}
|
|
2068
|
+
return current;
|
|
2069
|
+
};
|
|
2070
|
+
|
|
2071
|
+
/**
|
|
2072
|
+
* Apply the OCI/Docker whiteouts of one layer to the merged extraction
|
|
2073
|
+
* directory. `.wh.<name>` removes <name>, and `.wh..wh..opq` empties the
|
|
2074
|
+
* directory it sits in, both only for content from earlier layers, so call
|
|
2075
|
+
* this before extracting the layer itself. Matches
|
|
2076
|
+
* ci/reconstruct-staged-rootfs.py.
|
|
2077
|
+
* https://github.com/opencontainers/image-spec/blob/v1.1.0/layer.md#whiteouts
|
|
2078
|
+
*
|
|
2079
|
+
* @param {string} layerPath Layer tar (optionally compressed)
|
|
2080
|
+
* @param {string} rootDir Merged extraction directory
|
|
2081
|
+
*/
|
|
2082
|
+
// Applies one whiteout entry of a layer to the merged root.
|
|
2083
|
+
const applyWhiteout = (entryPath, rootDir) => {
|
|
2084
|
+
const parts = safeEntrySegments(entryPath);
|
|
2085
|
+
if (!parts?.length) {
|
|
2086
|
+
return;
|
|
2087
|
+
}
|
|
2088
|
+
const name = parts[parts.length - 1];
|
|
2089
|
+
const parentParts = parts.slice(0, -1);
|
|
2090
|
+
if (name === WHITEOUT_OPAQUE) {
|
|
2091
|
+
const dir = resolveRealDir(rootDir, parentParts);
|
|
2092
|
+
if (!dir) {
|
|
2093
|
+
return;
|
|
2094
|
+
}
|
|
2095
|
+
for (const child of readdirSync(dir)) {
|
|
2096
|
+
safeRmSync(join(dir, child), { recursive: true, force: true });
|
|
2097
|
+
}
|
|
2098
|
+
return;
|
|
2099
|
+
}
|
|
2100
|
+
// Other .wh..wh.* names are AUFS metadata, not deletions.
|
|
2101
|
+
if (name.startsWith(".wh..wh.")) {
|
|
2102
|
+
return;
|
|
2103
|
+
}
|
|
2104
|
+
const target = name.slice(WHITEOUT_PREFIX.length);
|
|
2105
|
+
if (!target || target === "." || target === "..") {
|
|
2106
|
+
return;
|
|
2107
|
+
}
|
|
2108
|
+
const dir = resolveRealDir(rootDir, parentParts);
|
|
2109
|
+
if (dir) {
|
|
2110
|
+
safeRmSync(join(dir, target), { recursive: true, force: true });
|
|
2111
|
+
}
|
|
2112
|
+
};
|
|
2113
|
+
|
|
2114
|
+
const applyLayerWhiteouts = async (layerPath, rootDir) => {
|
|
2115
|
+
const whiteouts = [];
|
|
2116
|
+
try {
|
|
2117
|
+
await listTar({
|
|
2118
|
+
file: layerPath,
|
|
2119
|
+
strict: false,
|
|
2120
|
+
onwarn: () => {
|
|
2121
|
+
// extractTar reports damaged layers
|
|
2122
|
+
},
|
|
2123
|
+
onReadEntry: (entry) => {
|
|
2124
|
+
if (
|
|
2125
|
+
basename(String(entry.path).replaceAll("\\", "/")).startsWith(
|
|
2126
|
+
WHITEOUT_PREFIX,
|
|
2127
|
+
)
|
|
2128
|
+
) {
|
|
2129
|
+
whiteouts.push(entry.path);
|
|
2130
|
+
}
|
|
2131
|
+
entry.resume();
|
|
2132
|
+
},
|
|
2133
|
+
});
|
|
2134
|
+
} catch (_err) {
|
|
2135
|
+
// extractTar reports unreadable layers
|
|
2136
|
+
}
|
|
2137
|
+
for (const entryPath of whiteouts) {
|
|
2138
|
+
// One whiteout that cannot be applied (name too long, EACCES) must not
|
|
2139
|
+
// abort the layer's extraction, which would hide everything it adds.
|
|
2140
|
+
try {
|
|
2141
|
+
applyWhiteout(entryPath, rootDir);
|
|
2142
|
+
} catch (err) {
|
|
2143
|
+
if (DEBUG_MODE) {
|
|
2144
|
+
console.log(`Skipping whiteout ${entryPath}: ${err.message}`);
|
|
2145
|
+
}
|
|
2146
|
+
}
|
|
2147
|
+
}
|
|
2148
|
+
};
|
|
2149
|
+
|
|
1996
2150
|
/**
|
|
1997
2151
|
* Parse a Docker/containerd manifest file and extract all image layers into a
|
|
1998
2152
|
* single merged directory. Resolves the last layer's config to determine the
|
|
@@ -2073,6 +2227,7 @@ export const extractFromManifest = async (
|
|
|
2073
2227
|
console.log(`Extracting layer ${layer} to ${allLayersExplodedDir}`);
|
|
2074
2228
|
}
|
|
2075
2229
|
try {
|
|
2230
|
+
await applyLayerWhiteouts(containedLayerPath, allLayersExplodedDir);
|
|
2076
2231
|
await extractTar(containedLayerPath, allLayersExplodedDir, options);
|
|
2077
2232
|
} catch (err) {
|
|
2078
2233
|
if (err.code === "TAR_BAD_ARCHIVE") {
|
package/lib/managers/oci.js
CHANGED
|
@@ -283,7 +283,10 @@ async function getOciToken(registry, repository, scope) {
|
|
|
283
283
|
if (params.service)
|
|
284
284
|
reqUrl.searchParams.set("service", params.service);
|
|
285
285
|
reqUrl.searchParams.set("scope", `repository:${repository}:${scope}`);
|
|
286
|
+
// Tokens expire within minutes, so a cached one would be replayed
|
|
287
|
+
// after it stopped working.
|
|
286
288
|
const options = {
|
|
289
|
+
cache: false,
|
|
287
290
|
responseType: "json",
|
|
288
291
|
timeout: getOciTimeoutMs(),
|
|
289
292
|
};
|
|
@@ -410,11 +413,18 @@ async function pullBlob(registry, repository, digest, token) {
|
|
|
410
413
|
*
|
|
411
414
|
* @param {string} image OCI image reference (e.g. `"registry.example.com/org/app:tag"`)
|
|
412
415
|
* @param {string} [platform] OCI platform string (e.g. `"linux/amd64"`); no-op for JS implementation
|
|
416
|
+
* @param {Object} [options]
|
|
417
|
+
* @param {function(Buffer): void} [options.checkBytes] Called with the raw bytes of the BOM layer that is about to be returned. An error it throws is rethrown, and no other referrer is tried.
|
|
413
418
|
* @returns {Promise<Object|undefined>} Parsed CycloneDX BOM JSON object, or `undefined` if not found
|
|
414
419
|
*/
|
|
415
|
-
export async function getBomWithOras(
|
|
420
|
+
export async function getBomWithOras(
|
|
421
|
+
image,
|
|
422
|
+
_platform = undefined,
|
|
423
|
+
options = {},
|
|
424
|
+
) {
|
|
416
425
|
const { registry, repository, reference } = parseImageRef(image);
|
|
417
426
|
const token = await getOciToken(registry, repository, "pull");
|
|
427
|
+
let rejection;
|
|
418
428
|
|
|
419
429
|
try {
|
|
420
430
|
const targetManifest = await fetchManifest(
|
|
@@ -488,9 +498,10 @@ export async function getBomWithOras(image, _platform = undefined) {
|
|
|
488
498
|
bomLayer.digest,
|
|
489
499
|
token,
|
|
490
500
|
);
|
|
501
|
+
const text = blob.toString("utf8");
|
|
491
502
|
let bomJson;
|
|
492
503
|
try {
|
|
493
|
-
bomJson = JSON.parse(
|
|
504
|
+
bomJson = JSON.parse(text);
|
|
494
505
|
} catch {
|
|
495
506
|
// Defensive: the mediaType claimed JSON but the layer did not parse
|
|
496
507
|
// (truncated/corrupt blob). Skip it and try the next candidate.
|
|
@@ -509,6 +520,14 @@ export async function getBomWithOras(image, _platform = undefined) {
|
|
|
509
520
|
}
|
|
510
521
|
|
|
511
522
|
if (isCycloneDxBom(bomJson)) {
|
|
523
|
+
if (options.checkBytes) {
|
|
524
|
+
try {
|
|
525
|
+
options.checkBytes(blob);
|
|
526
|
+
} catch (err) {
|
|
527
|
+
rejection = err;
|
|
528
|
+
break;
|
|
529
|
+
}
|
|
530
|
+
}
|
|
512
531
|
return bomJson;
|
|
513
532
|
}
|
|
514
533
|
}
|
|
@@ -517,6 +536,9 @@ export async function getBomWithOras(image, _platform = undefined) {
|
|
|
517
536
|
`Unable to pull the SBOM attachment for ${image} natively! ${e.message}`,
|
|
518
537
|
);
|
|
519
538
|
}
|
|
539
|
+
if (rejection) {
|
|
540
|
+
throw rejection;
|
|
541
|
+
}
|
|
520
542
|
return undefined;
|
|
521
543
|
}
|
|
522
544
|
|
|
@@ -197,3 +197,72 @@ export function resolveCmakeCacheFacts(map) {
|
|
|
197
197
|
fetchContentBase,
|
|
198
198
|
};
|
|
199
199
|
}
|
|
200
|
+
|
|
201
|
+
/** CMake's compiler ids, mapped to the family names the C/C++ toolchain uses. */
|
|
202
|
+
const CMAKE_COMPILER_FAMILIES = {
|
|
203
|
+
GNU: "gcc",
|
|
204
|
+
Clang: "clang",
|
|
205
|
+
AppleClang: "apple-clang",
|
|
206
|
+
MSVC: "msvc",
|
|
207
|
+
IntelLLVM: "icx",
|
|
208
|
+
Intel: "icc",
|
|
209
|
+
NVIDIA: "nvcc",
|
|
210
|
+
NVHPC: "nvhpc",
|
|
211
|
+
PGI: "nvhpc",
|
|
212
|
+
};
|
|
213
|
+
|
|
214
|
+
/**
|
|
215
|
+
* Parse a compiler description CMake writes when it configures a build
|
|
216
|
+
* (`CMakeFiles/<cmake version>/CMake<LANG>Compiler.cmake`): the compiler's
|
|
217
|
+
* path, CMake's id for it and its version, all identified by CMake itself.
|
|
218
|
+
*
|
|
219
|
+
* @param {string} text File contents
|
|
220
|
+
* @returns {{language: string, compiler: string, family: string, id: string, version: string}|null}
|
|
221
|
+
* `null` when the text names no compiler
|
|
222
|
+
*/
|
|
223
|
+
export function parseCmakeCompilerFile(text) {
|
|
224
|
+
if (!text || typeof text !== "string") {
|
|
225
|
+
return null;
|
|
226
|
+
}
|
|
227
|
+
const values = new Map();
|
|
228
|
+
for (const rawLine of text.split(/\r\n|\r|\n/)) {
|
|
229
|
+
const line = rawLine.trim();
|
|
230
|
+
if (!line.startsWith("set(CMAKE_") || !line.endsWith(")")) {
|
|
231
|
+
continue;
|
|
232
|
+
}
|
|
233
|
+
const body = line.slice(4, -1).trim();
|
|
234
|
+
const space = body.search(/\s/);
|
|
235
|
+
if (space < 0) {
|
|
236
|
+
continue;
|
|
237
|
+
}
|
|
238
|
+
const key = body.slice(0, space);
|
|
239
|
+
let value = body.slice(space).trim();
|
|
240
|
+
if (value.startsWith('"') && value.endsWith('"') && value.length >= 2) {
|
|
241
|
+
value = value.slice(1, -1);
|
|
242
|
+
}
|
|
243
|
+
if (!values.has(key)) {
|
|
244
|
+
values.set(key, value);
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
for (const [key, compiler] of values) {
|
|
248
|
+
const match = key.match(/^CMAKE_([A-Z]+)_COMPILER$/);
|
|
249
|
+
if (!match || !compiler) {
|
|
250
|
+
continue;
|
|
251
|
+
}
|
|
252
|
+
const language = match[1];
|
|
253
|
+
const id = values.get(`CMAKE_${language}_COMPILER_ID`) || "";
|
|
254
|
+
const variant = values.get(`CMAKE_${language}_COMPILER_FRONTEND_VARIANT`);
|
|
255
|
+
let family = CMAKE_COMPILER_FAMILIES[id] || id.toLowerCase() || "unknown";
|
|
256
|
+
if (id === "Clang" && variant === "MSVC") {
|
|
257
|
+
family = "clang-cl";
|
|
258
|
+
}
|
|
259
|
+
return {
|
|
260
|
+
language,
|
|
261
|
+
compiler,
|
|
262
|
+
family,
|
|
263
|
+
id,
|
|
264
|
+
version: values.get(`CMAKE_${language}_COMPILER_VERSION`) || "",
|
|
265
|
+
};
|
|
266
|
+
}
|
|
267
|
+
return null;
|
|
268
|
+
}
|
|
@@ -188,10 +188,15 @@ export function parseCmakeCommands(text) {
|
|
|
188
188
|
return commands;
|
|
189
189
|
}
|
|
190
190
|
|
|
191
|
+
// Upper bound on an expanded value; a set() chain that doubles a variable can
|
|
192
|
+
// otherwise grow it beyond the maximum string length.
|
|
193
|
+
const MAX_EXPANDED_LENGTH = 65536;
|
|
194
|
+
|
|
191
195
|
/**
|
|
192
196
|
* Replace `${VAR}` references with the values of simple `set()` calls. A
|
|
193
197
|
* reference to an unknown variable is left in place, so callers can tell a
|
|
194
|
-
* resolved value from an unresolved one.
|
|
198
|
+
* resolved value from an unresolved one. Expansion stops at the previous
|
|
199
|
+
* round once the text would exceed 64 KiB.
|
|
195
200
|
*
|
|
196
201
|
* @param {string} value Argument text
|
|
197
202
|
* @param {Map<string,string>} variables Known variable values
|
|
@@ -203,6 +208,9 @@ export function expandCmakeVariables(value, variables) {
|
|
|
203
208
|
let next = "";
|
|
204
209
|
let i = 0;
|
|
205
210
|
while (i < result.length) {
|
|
211
|
+
if (next.length > MAX_EXPANDED_LENGTH) {
|
|
212
|
+
return result;
|
|
213
|
+
}
|
|
206
214
|
const start = result.indexOf("${", i);
|
|
207
215
|
if (start === -1) {
|
|
208
216
|
next += result.slice(i);
|
|
@@ -247,7 +255,13 @@ export function cmakeSetVariables(commands) {
|
|
|
247
255
|
rest[0] === "CACHE" ||
|
|
248
256
|
rest[0] === "PARENT_SCOPE"
|
|
249
257
|
) {
|
|
250
|
-
|
|
258
|
+
// An appending set(FOO "${FOO} ...") of an undefined FOO starts from an
|
|
259
|
+
// empty value in CMake; dropping the self-reference also keeps it from
|
|
260
|
+
// being substituted into itself on every later expansion round.
|
|
261
|
+
variables.set(
|
|
262
|
+
key,
|
|
263
|
+
expandCmakeVariables(value, variables).replaceAll(`\${${key}}`, ""),
|
|
264
|
+
);
|
|
251
265
|
}
|
|
252
266
|
}
|
|
253
267
|
return variables;
|