mirror of
https://github.com/anchore/syft.git
synced 2026-10-12 14:17:20 +02:00
Compare commits
54
Commits
+5
-5
@@ -18,7 +18,7 @@ tools:
|
||||
# used to sign mac binaries at release
|
||||
- name: quill
|
||||
version:
|
||||
want: v0.4.2
|
||||
want: v0.5.0
|
||||
method: github-release
|
||||
with:
|
||||
repo: anchore/quill
|
||||
@@ -26,7 +26,7 @@ tools:
|
||||
# used for linting
|
||||
- name: golangci-lint
|
||||
version:
|
||||
want: v1.61.0
|
||||
want: v1.62.0
|
||||
method: github-release
|
||||
with:
|
||||
repo: golangci/golangci-lint
|
||||
@@ -58,7 +58,7 @@ tools:
|
||||
# used to release all artifacts
|
||||
- name: goreleaser
|
||||
version:
|
||||
want: v2.3.2
|
||||
want: v2.4.5
|
||||
method: github-release
|
||||
with:
|
||||
repo: goreleaser/goreleaser
|
||||
@@ -103,7 +103,7 @@ tools:
|
||||
# used for running all local and CI tasks
|
||||
- name: task
|
||||
version:
|
||||
want: v3.39.2
|
||||
want: v3.40.0
|
||||
method: github-release
|
||||
with:
|
||||
repo: go-task/task
|
||||
@@ -111,7 +111,7 @@ tools:
|
||||
# used for triggering a release
|
||||
- name: gh
|
||||
version:
|
||||
want: v2.59.0
|
||||
want: v2.62.0
|
||||
method: github-release
|
||||
with:
|
||||
repo: cli/cli
|
||||
|
||||
@@ -17,13 +17,13 @@ jobs:
|
||||
# the job by event.
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1
|
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||
|
||||
- name: Bootstrap environment
|
||||
uses: ./.github/actions/bootstrap
|
||||
|
||||
- name: Restore base benchmark result
|
||||
uses: actions/cache@3624ceb22c1c5a301c8db4169662070a689d9ea8 #v4.1.1
|
||||
uses: actions/cache@6849a6489940f00c2f30c0fb92c6274307ccb58a #v4.1.2
|
||||
with:
|
||||
path: test/results/benchmark-main.txt
|
||||
# use base sha for PR or new commit hash for main push in benchmark result key
|
||||
|
||||
@@ -36,16 +36,16 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 #v4.2.1
|
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 #v4.2.2
|
||||
|
||||
- name: Install Go
|
||||
uses: actions/setup-go@0a12ed9d6a96ab950c8f026ed9f722fe0da7ef32 #v5.0.2
|
||||
uses: actions/setup-go@41dfa10bad2bb2ae585af6ee5bb4d7d973ad74ed #v5.1.0
|
||||
with:
|
||||
go-version-file: go.mod
|
||||
|
||||
# Initializes the CodeQL tools for scanning.
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@f779452ac5af1c261dce0346a8f964149f49322b #v3.26.13
|
||||
uses: github/codeql-action/init@ea9e4e37992a54ee68a9622e985e60c8e8f12d9f #v3.27.4
|
||||
with:
|
||||
languages: ${{ matrix.language }}
|
||||
# If you wish to specify custom queries, you can do so here or in a config file.
|
||||
@@ -56,7 +56,7 @@ jobs:
|
||||
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
|
||||
# If this step fails, then you should remove it and run the build manually (see below)
|
||||
- name: Autobuild
|
||||
uses: github/codeql-action/autobuild@f779452ac5af1c261dce0346a8f964149f49322b #v3.26.13
|
||||
uses: github/codeql-action/autobuild@ea9e4e37992a54ee68a9622e985e60c8e8f12d9f #v3.27.4
|
||||
|
||||
# ℹ️ Command-line programs to run using the OS shell.
|
||||
# 📚 https://git.io/JvXDl
|
||||
@@ -70,4 +70,4 @@ jobs:
|
||||
# make release
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@f779452ac5af1c261dce0346a8f964149f49322b #v3.26.13
|
||||
uses: github/codeql-action/analyze@ea9e4e37992a54ee68a9622e985e60c8e8f12d9f #v3.27.4
|
||||
|
||||
@@ -30,7 +30,7 @@ jobs:
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
|
||||
- uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 #v4.2.1
|
||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 #v4.2.2
|
||||
|
||||
- run: python .github/scripts/labeler.py
|
||||
env:
|
||||
|
||||
@@ -20,7 +20,7 @@ jobs:
|
||||
release:
|
||||
runs-on: ubuntu-20.04
|
||||
steps:
|
||||
- uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 #v4.2.1
|
||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 #v4.2.2
|
||||
|
||||
- name: Update version file
|
||||
run: make ci-release-version-file
|
||||
|
||||
@@ -15,7 +15,7 @@ jobs:
|
||||
environment: release
|
||||
runs-on: ubuntu-20.04
|
||||
steps:
|
||||
- uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 #v4.2.1
|
||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 #v4.2.2
|
||||
|
||||
- name: Check if running on main
|
||||
if: github.ref != 'refs/heads/main'
|
||||
@@ -105,7 +105,7 @@ jobs:
|
||||
# required for goreleaser signs section with cosign
|
||||
id-token: write
|
||||
steps:
|
||||
- uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 #v4.2.1
|
||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 #v4.2.2
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
@@ -148,9 +148,10 @@ jobs:
|
||||
# for updating brew formula in anchore/homebrew-syft
|
||||
GITHUB_BREW_TOKEN: ${{ secrets.ANCHOREOPS_GITHUB_OSS_WRITE_TOKEN }}
|
||||
|
||||
- uses: anchore/sbom-action@8d0a6505bf28ced3e85154d13dc6af83299e13f1 #v0.17.4
|
||||
- uses: anchore/sbom-action@fc46e51fd3cb168ffb36c6d1915723c47db58abb #v0.17.7
|
||||
continue-on-error: true
|
||||
with:
|
||||
file: go.mod
|
||||
artifact-name: sbom.spdx.json
|
||||
|
||||
- uses: 8398a7/action-slack@28ba43ae48961b90635b50953d216767a6bea486 #v3.16.2
|
||||
|
||||
@@ -18,7 +18,7 @@ jobs:
|
||||
permissions:
|
||||
packages: write
|
||||
steps:
|
||||
- uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 #v4.2.1
|
||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 #v4.2.2
|
||||
|
||||
- name: Bootstrap environment
|
||||
uses: ./.github/actions/bootstrap
|
||||
|
||||
@@ -13,7 +13,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
if: github.repository == 'anchore/syft' # only run for main repo
|
||||
steps:
|
||||
- uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 #v4.2.1
|
||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 #v4.2.2
|
||||
|
||||
- name: Bootstrap environment
|
||||
uses: ./.github/actions/bootstrap
|
||||
|
||||
@@ -16,7 +16,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
if: github.repository == 'anchore/syft' # only run for main repo
|
||||
steps:
|
||||
- uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 #v4.2.1
|
||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 #v4.2.2
|
||||
|
||||
- name: Bootstrap environment
|
||||
uses: ./.github/actions/bootstrap
|
||||
|
||||
@@ -17,9 +17,9 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
if: github.repository == 'anchore/syft' # only run for main repo
|
||||
steps:
|
||||
- uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 #v4.2.1
|
||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 #v4.2.2
|
||||
|
||||
- uses: actions/setup-go@0a12ed9d6a96ab950c8f026ed9f722fe0da7ef32 #v5.0.2
|
||||
- uses: actions/setup-go@41dfa10bad2bb2ae585af6ee5bb4d7d973ad74ed #v5.1.0
|
||||
with:
|
||||
go-version: ${{ env.GO_VERSION }}
|
||||
stable: ${{ env.GO_STABLE_VERSION }}
|
||||
|
||||
@@ -17,7 +17,7 @@ jobs:
|
||||
name: "Static analysis"
|
||||
runs-on: ubuntu-20.04
|
||||
steps:
|
||||
- uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 #v4.2.1
|
||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 #v4.2.2
|
||||
|
||||
- name: Bootstrap environment
|
||||
uses: ./.github/actions/bootstrap
|
||||
@@ -31,7 +31,7 @@ jobs:
|
||||
name: "Unit tests"
|
||||
runs-on: ubuntu-20.04
|
||||
steps:
|
||||
- uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 #v4.2.1
|
||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 #v4.2.2
|
||||
|
||||
- name: Bootstrap environment
|
||||
uses: ./.github/actions/bootstrap
|
||||
@@ -47,7 +47,7 @@ jobs:
|
||||
name: "Integration tests"
|
||||
runs-on: ubuntu-20.04
|
||||
steps:
|
||||
- uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 #v4.2.1
|
||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 #v4.2.2
|
||||
|
||||
- name: Bootstrap environment
|
||||
uses: ./.github/actions/bootstrap
|
||||
@@ -65,7 +65,7 @@ jobs:
|
||||
name: "Build snapshot artifacts"
|
||||
runs-on: ubuntu-20.04
|
||||
steps:
|
||||
- uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 #v4.2.1
|
||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 #v4.2.2
|
||||
|
||||
- name: Bootstrap environment
|
||||
uses: ./.github/actions/bootstrap
|
||||
@@ -78,7 +78,7 @@ jobs:
|
||||
# why not use actions/upload-artifact? It is very slow (3 minutes to upload ~600MB of data, vs 10 seconds with this approach).
|
||||
# see https://github.com/actions/upload-artifact/issues/199 for more info
|
||||
- name: Upload snapshot artifacts
|
||||
uses: actions/cache/save@3624ceb22c1c5a301c8db4169662070a689d9ea8 #v4.1.1
|
||||
uses: actions/cache/save@6849a6489940f00c2f30c0fb92c6274307ccb58a #v4.1.2
|
||||
with:
|
||||
# we need to preserve the snapshot data itself as well as the task data that confirms if the
|
||||
# snapshot build is stale or not. Otherwise the downstream jobs will attempt to rebuild the snapshot
|
||||
@@ -95,7 +95,7 @@ jobs:
|
||||
needs: [Build-Snapshot-Artifacts]
|
||||
runs-on: ubuntu-20.04
|
||||
steps:
|
||||
- uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 #v4.2.1
|
||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 #v4.2.2
|
||||
|
||||
- name: Bootstrap environment
|
||||
uses: ./.github/actions/bootstrap
|
||||
@@ -104,7 +104,7 @@ jobs:
|
||||
|
||||
- name: Download snapshot build
|
||||
id: snapshot-cache
|
||||
uses: actions/cache/restore@3624ceb22c1c5a301c8db4169662070a689d9ea8 #v4.1.1
|
||||
uses: actions/cache/restore@6849a6489940f00c2f30c0fb92c6274307ccb58a #v4.1.2
|
||||
with:
|
||||
path: |
|
||||
snapshot
|
||||
@@ -141,7 +141,7 @@ jobs:
|
||||
- name: Install Cosign
|
||||
uses: sigstore/cosign-installer@v3.7.0
|
||||
|
||||
- uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 #v4.2.1
|
||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 #v4.2.2
|
||||
|
||||
- name: Bootstrap environment
|
||||
uses: ./.github/actions/bootstrap
|
||||
@@ -152,7 +152,7 @@ jobs:
|
||||
|
||||
- name: Download snapshot build
|
||||
id: snapshot-cache
|
||||
uses: actions/cache/restore@3624ceb22c1c5a301c8db4169662070a689d9ea8 #v4.1.1
|
||||
uses: actions/cache/restore@6849a6489940f00c2f30c0fb92c6274307ccb58a #v4.1.2
|
||||
with:
|
||||
path: |
|
||||
snapshot
|
||||
@@ -178,7 +178,7 @@ jobs:
|
||||
needs: [Build-Snapshot-Artifacts]
|
||||
runs-on: ubuntu-20.04
|
||||
steps:
|
||||
- uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 #v4.2.1
|
||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 #v4.2.2
|
||||
|
||||
- name: Bootstrap environment
|
||||
uses: ./.github/actions/bootstrap
|
||||
@@ -187,7 +187,7 @@ jobs:
|
||||
|
||||
- name: Download snapshot build
|
||||
id: snapshot-cache
|
||||
uses: actions/cache/restore@3624ceb22c1c5a301c8db4169662070a689d9ea8 #v4.1.1
|
||||
uses: actions/cache/restore@6849a6489940f00c2f30c0fb92c6274307ccb58a #v4.1.2
|
||||
with:
|
||||
path: |
|
||||
snapshot
|
||||
@@ -215,7 +215,7 @@ jobs:
|
||||
- Acceptance-Mac
|
||||
- Cli-Linux
|
||||
steps:
|
||||
- uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 #v4.2.1
|
||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 #v4.2.2
|
||||
|
||||
- name: Delete snapshot cache
|
||||
run: gh cache delete "snapshot-build-${{ github.run_id }}"
|
||||
|
||||
@@ -179,3 +179,7 @@ The Syft Team hold regular community meetings online. All are welcome to join to
|
||||
- Check the [calendar](https://calendar.google.com/calendar/u/0/r?cid=Y182OTM4dGt0MjRtajI0NnNzOThiaGtnM29qNEBncm91cC5jYWxlbmRhci5nb29nbGUuY29t) for the next meeting date.
|
||||
- Add items to the [agenda](https://docs.google.com/document/d/1ZtSAa6fj2a6KRWviTn3WoJm09edvrNUp4Iz_dOjjyY8/edit?usp=sharing) (join [this group](https://groups.google.com/g/anchore-oss-community) for write access to the [agenda](https://docs.google.com/document/d/1ZtSAa6fj2a6KRWviTn3WoJm09edvrNUp4Iz_dOjjyY8/edit?usp=sharing))
|
||||
- See you there!
|
||||
|
||||
## Syft Logo
|
||||
|
||||
<p xmlns:cc="http://creativecommons.org/ns#" xmlns:dct="http://purl.org/dc/terms/"><a property="dct:title" rel="cc:attributionURL" href="https://anchore.com/wp-content/uploads/2024/11/syft-logo.svg">Syft Logo</a> by <a rel="cc:attributionURL dct:creator" property="cc:attributionName" href="https://anchore.com/">Anchore</a> is licensed under <a href="https://creativecommons.org/licenses/by/4.0/" target="_blank" rel="license noopener noreferrer" style="display:inline-block;">CC BY 4.0<img style="height:22px!important;margin-left:3px;vertical-align:text-bottom;" src="https://mirrors.creativecommons.org/presskit/icons/cc.svg" alt=""><img style="height:22px!important;margin-left:3px;vertical-align:text-bottom;" src="https://mirrors.creativecommons.org/presskit/icons/by.svg" alt=""></a></p>
|
||||
|
||||
@@ -20,18 +20,18 @@ func AppClioSetupConfig(id clio.Identification, out io.Writer) *clio.SetupConfig
|
||||
WithConfigInRootHelp(). // --help on the root command renders the full application config in the help text
|
||||
WithUIConstructor(
|
||||
// select a UI based on the logging configuration and state of stdin (if stdin is a tty)
|
||||
func(cfg clio.Config) ([]clio.UI, error) {
|
||||
func(cfg clio.Config) (*clio.UICollection, error) {
|
||||
noUI := ui.None(out, cfg.Log.Quiet)
|
||||
if !cfg.Log.AllowUI(os.Stdin) || cfg.Log.Quiet {
|
||||
return []clio.UI{noUI}, nil
|
||||
return clio.NewUICollection(noUI), nil
|
||||
}
|
||||
|
||||
return []clio.UI{
|
||||
return clio.NewUICollection(
|
||||
ui.New(out, cfg.Log.Quiet,
|
||||
ui2.New(ui2.DefaultHandlerConfig()),
|
||||
),
|
||||
noUI,
|
||||
}, nil
|
||||
), nil
|
||||
},
|
||||
).
|
||||
WithInitializers(
|
||||
|
||||
@@ -17,7 +17,7 @@ import (
|
||||
|
||||
const (
|
||||
convertExample = ` {{.appName}} {{.command}} img.syft.json -o spdx-json convert a syft SBOM to spdx-json, output goes to stdout
|
||||
{{.appName}} {{.command}} img.syft.json -o cyclonedx-json=img.cdx.json convert a syft SBOM to CycloneDX, output is written to the file "img.cdx.json""
|
||||
{{.appName}} {{.command}} img.syft.json -o cyclonedx-json=img.cdx.json convert a syft SBOM to CycloneDX, output is written to the file "img.cdx.json"
|
||||
{{.appName}} {{.command}} - -o spdx-json convert an SBOM from STDIN to spdx-json
|
||||
`
|
||||
)
|
||||
@@ -39,7 +39,7 @@ func Convert(app clio.Application) *cobra.Command {
|
||||
return app.SetupCommand(&cobra.Command{
|
||||
Use: "convert [SOURCE-SBOM] -o [FORMAT]",
|
||||
Short: "Convert between SBOM formats",
|
||||
Long: "[Experimental] Convert SBOM files to, and from, SPDX, CycloneDX and Syft's format. For more info about data loss between formats see https://github.com/anchore/syft#format-conversion-experimental",
|
||||
Long: "[Experimental] Convert SBOM files to, and from, SPDX, CycloneDX and Syft's format. For more info about data loss between formats see https://github.com/anchore/syft/wiki/format-conversion",
|
||||
Example: internal.Tprintf(convertExample, map[string]interface{}{
|
||||
"appName": id.Name,
|
||||
"command": "convert",
|
||||
|
||||
@@ -13,6 +13,7 @@ import (
|
||||
"gopkg.in/yaml.v3"
|
||||
|
||||
"github.com/anchore/clio"
|
||||
"github.com/anchore/fangs"
|
||||
"github.com/anchore/go-collections"
|
||||
"github.com/anchore/stereoscope"
|
||||
"github.com/anchore/stereoscope/pkg/image"
|
||||
@@ -109,7 +110,7 @@ func (o *scanOptions) PostLoad() error {
|
||||
}
|
||||
|
||||
func (o *scanOptions) validateLegacyOptionsNotUsed() error {
|
||||
if o.Config.ConfigFile == "" {
|
||||
if len(fangs.Flatten(o.Config.ConfigFile)) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -121,32 +122,33 @@ func (o *scanOptions) validateLegacyOptionsNotUsed() error {
|
||||
File any `yaml:"file" json:"file" mapstructure:"file"`
|
||||
}
|
||||
|
||||
by, err := os.ReadFile(o.Config.ConfigFile)
|
||||
if err != nil {
|
||||
return fmt.Errorf("unable to read config file during validations %q: %w", o.Config.ConfigFile, err)
|
||||
}
|
||||
for _, f := range fangs.Flatten(o.Config.ConfigFile) {
|
||||
by, err := os.ReadFile(f)
|
||||
if err != nil {
|
||||
return fmt.Errorf("unable to read config file during validations %q: %w", f, err)
|
||||
}
|
||||
|
||||
var legacy legacyConfig
|
||||
if err := yaml.Unmarshal(by, &legacy); err != nil {
|
||||
return fmt.Errorf("unable to parse config file during validations %q: %w", o.Config.ConfigFile, err)
|
||||
}
|
||||
var legacy legacyConfig
|
||||
if err := yaml.Unmarshal(by, &legacy); err != nil {
|
||||
return fmt.Errorf("unable to parse config file during validations %q: %w", f, err)
|
||||
}
|
||||
|
||||
if legacy.DefaultImagePullSource != nil {
|
||||
return fmt.Errorf("the config file option 'default-image-pull-source' has been removed, please use 'source.image.default-pull-source' instead")
|
||||
}
|
||||
if legacy.DefaultImagePullSource != nil {
|
||||
return fmt.Errorf("the config file option 'default-image-pull-source' has been removed, please use 'source.image.default-pull-source' instead")
|
||||
}
|
||||
|
||||
if legacy.ExcludeBinaryOverlapByOwnership != nil {
|
||||
return fmt.Errorf("the config file option 'exclude-binary-overlap-by-ownership' has been removed, please use 'package.exclude-binary-overlap-by-ownership' instead")
|
||||
}
|
||||
if legacy.ExcludeBinaryOverlapByOwnership != nil {
|
||||
return fmt.Errorf("the config file option 'exclude-binary-overlap-by-ownership' has been removed, please use 'package.exclude-binary-overlap-by-ownership' instead")
|
||||
}
|
||||
|
||||
if legacy.BasePath != nil {
|
||||
return fmt.Errorf("the config file option 'base-path' has been removed, please use 'source.base-path' instead")
|
||||
}
|
||||
if legacy.BasePath != nil {
|
||||
return fmt.Errorf("the config file option 'base-path' has been removed, please use 'source.base-path' instead")
|
||||
}
|
||||
|
||||
if legacy.File != nil && reflect.TypeOf(legacy.File).Kind() == reflect.String {
|
||||
return fmt.Errorf("the config file option 'file' has been removed, please use 'outputs' instead")
|
||||
if legacy.File != nil && reflect.TypeOf(legacy.File).Kind() == reflect.String {
|
||||
return fmt.Errorf("the config file option 'file' has been removed, please use 'outputs' instead")
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -154,13 +156,13 @@ func validateScanArgs(cmd *cobra.Command, args []string) error {
|
||||
return validateArgs(cmd, args, "an image/directory argument is required")
|
||||
}
|
||||
|
||||
func validateArgs(cmd *cobra.Command, args []string, error string) error {
|
||||
func validateArgs(cmd *cobra.Command, args []string, err string) error {
|
||||
if len(args) == 0 {
|
||||
// in the case that no arguments are given we want to show the help text and return with a non-0 return code.
|
||||
if err := cmd.Help(); err != nil {
|
||||
return fmt.Errorf("unable to display help: %w", err)
|
||||
}
|
||||
return fmt.Errorf("%v", error)
|
||||
return fmt.Errorf("%v", err)
|
||||
}
|
||||
|
||||
return cobra.MaximumNArgs(1)(cmd, args)
|
||||
|
||||
@@ -166,6 +166,7 @@ func (cfg Catalog) ToPackagesConfig() pkgcataloging.Config {
|
||||
WithFromLDFlags(cfg.Golang.MainModuleVersion.FromLDFlags),
|
||||
),
|
||||
JavaScript: javascript.DefaultCatalogerConfig().
|
||||
WithIncludeDevDependencies(*multiLevelOption(false, cfg.JavaScript.IncludeDevDependencies)).
|
||||
WithSearchRemoteLicenses(*multiLevelOption(false, enrichmentEnabled(cfg.Enrich, task.JavaScript, task.Node, task.NPM), cfg.JavaScript.SearchRemoteLicenses)).
|
||||
WithNpmBaseURL(cfg.JavaScript.NpmBaseURL),
|
||||
LinuxKernel: kernel.LinuxKernelCatalogerConfig{
|
||||
@@ -179,7 +180,8 @@ func (cfg Catalog) ToPackagesConfig() pkgcataloging.Config {
|
||||
WithMavenLocalRepositoryDir(cfg.Java.MavenLocalRepositoryDir).
|
||||
WithUseNetwork(*multiLevelOption(false, enrichmentEnabled(cfg.Enrich, task.Java, task.Maven), cfg.Java.UseNetwork)).
|
||||
WithMavenBaseURL(cfg.Java.MavenURL).
|
||||
WithArchiveTraversal(archiveSearch, cfg.Java.MaxParentRecursiveDepth),
|
||||
WithArchiveTraversal(archiveSearch, cfg.Java.MaxParentRecursiveDepth).
|
||||
WithResolveTransitiveDependencies(cfg.Java.ResolveTransitiveDependencies),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2,11 +2,11 @@ package options
|
||||
|
||||
import "github.com/anchore/fangs"
|
||||
|
||||
// Config holds a reference to the specific config file that was used to load application configuration
|
||||
// Config holds a reference to the specific config file(s) that were used to load application configuration
|
||||
type Config struct {
|
||||
ConfigFile string `yaml:"config" json:"config" mapstructure:"config"`
|
||||
}
|
||||
|
||||
func (cfg *Config) DescribeFields(descriptions fangs.FieldDescriptionSet) {
|
||||
descriptions.Add(&cfg.ConfigFile, "the configuration file that was used to load application configuration")
|
||||
descriptions.Add(&cfg.ConfigFile, "the configuration file(s) used to load application configuration")
|
||||
}
|
||||
|
||||
@@ -6,22 +6,24 @@ import (
|
||||
)
|
||||
|
||||
type javaConfig struct {
|
||||
UseNetwork *bool `yaml:"use-network" json:"use-network" mapstructure:"use-network"`
|
||||
UseMavenLocalRepository *bool `yaml:"use-maven-local-repository" json:"use-maven-local-repository" mapstructure:"use-maven-local-repository"`
|
||||
MavenLocalRepositoryDir string `yaml:"maven-local-repository-dir" json:"maven-local-repository-dir" mapstructure:"maven-local-repository-dir"`
|
||||
MavenURL string `yaml:"maven-url" json:"maven-url" mapstructure:"maven-url"`
|
||||
MaxParentRecursiveDepth int `yaml:"max-parent-recursive-depth" json:"max-parent-recursive-depth" mapstructure:"max-parent-recursive-depth"`
|
||||
UseNetwork *bool `yaml:"use-network" json:"use-network" mapstructure:"use-network"`
|
||||
UseMavenLocalRepository *bool `yaml:"use-maven-local-repository" json:"use-maven-local-repository" mapstructure:"use-maven-local-repository"`
|
||||
MavenLocalRepositoryDir string `yaml:"maven-local-repository-dir" json:"maven-local-repository-dir" mapstructure:"maven-local-repository-dir"`
|
||||
MavenURL string `yaml:"maven-url" json:"maven-url" mapstructure:"maven-url"`
|
||||
MaxParentRecursiveDepth int `yaml:"max-parent-recursive-depth" json:"max-parent-recursive-depth" mapstructure:"max-parent-recursive-depth"`
|
||||
ResolveTransitiveDependencies bool `yaml:"resolve-transitive-dependencies" json:"resolve-transitive-dependencies" mapstructure:"resolve-transitive-dependencies"`
|
||||
}
|
||||
|
||||
func defaultJavaConfig() javaConfig {
|
||||
def := java.DefaultArchiveCatalogerConfig()
|
||||
|
||||
return javaConfig{
|
||||
UseNetwork: nil, // this defaults to false, which is the API default
|
||||
MaxParentRecursiveDepth: def.MaxParentRecursiveDepth,
|
||||
UseMavenLocalRepository: nil, // this defaults to false, which is the API default
|
||||
MavenLocalRepositoryDir: def.MavenLocalRepositoryDir,
|
||||
MavenURL: def.MavenBaseURL,
|
||||
UseNetwork: nil, // this defaults to false, which is the API default
|
||||
MaxParentRecursiveDepth: def.MaxParentRecursiveDepth,
|
||||
UseMavenLocalRepository: nil, // this defaults to false, which is the API default
|
||||
MavenLocalRepositoryDir: def.MavenLocalRepositoryDir,
|
||||
MavenURL: def.MavenBaseURL,
|
||||
ResolveTransitiveDependencies: def.ResolveTransitiveDependencies,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,4 +45,5 @@ TIP: If you want to download all required pom files to the local repository with
|
||||
build, run 'mvn help:effective-pom' before performing the scan with syft.`)
|
||||
descriptions.Add(&o.MavenLocalRepositoryDir, `override the default location of the local Maven repository.
|
||||
the default is the subdirectory '.m2/repository' in your home directory`)
|
||||
descriptions.Add(&o.ResolveTransitiveDependencies, `resolve transient dependencies such as those defined in a dependency's POM on Maven central`)
|
||||
}
|
||||
|
||||
@@ -3,8 +3,9 @@ package options
|
||||
import "github.com/anchore/clio"
|
||||
|
||||
type javaScriptConfig struct {
|
||||
SearchRemoteLicenses *bool `json:"search-remote-licenses" yaml:"search-remote-licenses" mapstructure:"search-remote-licenses"`
|
||||
NpmBaseURL string `json:"npm-base-url" yaml:"npm-base-url" mapstructure:"npm-base-url"`
|
||||
SearchRemoteLicenses *bool `json:"search-remote-licenses" yaml:"search-remote-licenses" mapstructure:"search-remote-licenses"`
|
||||
NpmBaseURL string `json:"npm-base-url" yaml:"npm-base-url" mapstructure:"npm-base-url"`
|
||||
IncludeDevDependencies *bool `json:"include-dev-dependencies" yaml:"include-dev-dependencies" mapstructure:"include-dev-dependencies"`
|
||||
}
|
||||
|
||||
var _ interface {
|
||||
@@ -14,4 +15,5 @@ var _ interface {
|
||||
func (o *javaScriptConfig) DescribeFields(descriptions clio.FieldDescriptionSet) {
|
||||
descriptions.Add(&o.SearchRemoteLicenses, `enables Syft to use the network to fill in more detailed license information`)
|
||||
descriptions.Add(&o.NpmBaseURL, `base NPM url to use`)
|
||||
descriptions.Add(&o.IncludeDevDependencies, `include development-scoped dependencies`)
|
||||
}
|
||||
|
||||
@@ -265,7 +265,7 @@ var dirOnlyTestCases = []testCase{
|
||||
name: "find java packages including pom.xml", // directory scans can include packages that have yet to be installed
|
||||
pkgType: pkg.JavaPkg,
|
||||
pkgLanguage: pkg.Java,
|
||||
duplicates: 1, // joda-time is included in both pom.xml AND the .jar collection
|
||||
duplicates: 2, // joda-time and example-java-app-maven are included in both pom.xml AND the .jar collection
|
||||
pkgInfo: map[string]string{
|
||||
"example-java-app-maven": "0.1.0",
|
||||
"joda-time": "2.9.2",
|
||||
|
||||
@@ -25,7 +25,7 @@ func TestNpmPackageLockDirectory(t *testing.T) {
|
||||
}
|
||||
|
||||
// ensure that integration test commonTestCases stay in sync with the available catalogers
|
||||
const expectedPackageCount = 6
|
||||
const expectedPackageCount = 2
|
||||
if foundPackages.Size() != expectedPackageCount {
|
||||
t.Errorf("found the wrong set of npm package-lock.json packages (expected: %d, actual: %d)", expectedPackageCount, foundPackages.Size())
|
||||
}
|
||||
|
||||
@@ -17,11 +17,11 @@ const defaultStdoutLogBufferSize = 1024
|
||||
// restore := CaptureStdoutToTraceLog()
|
||||
// // here, stdout will be captured and redirected to the provided writer
|
||||
// restore() // block until the output has all been sent to the writer and restore the original stdout
|
||||
func CaptureStdoutToTraceLog() (close func()) {
|
||||
func CaptureStdoutToTraceLog() func() {
|
||||
return capture(&os.Stdout, newLogWriter(), defaultStdoutLogBufferSize)
|
||||
}
|
||||
|
||||
func capture(target **os.File, writer io.Writer, bufSize int) (close func()) {
|
||||
func capture(target **os.File, writer io.Writer, bufSize int) func() {
|
||||
original := *target
|
||||
|
||||
r, w, _ := os.Pipe()
|
||||
|
||||
@@ -78,6 +78,13 @@ func (m *UI) Handle(e partybus.Event) error {
|
||||
}
|
||||
|
||||
func (m *UI) Teardown(force bool) error {
|
||||
defer func() {
|
||||
// allow for traditional logging to resume now that the UI is shutting down
|
||||
if logWrapper, ok := log.Get().(logger.Controller); ok {
|
||||
logWrapper.SetOutput(m.err)
|
||||
}
|
||||
}()
|
||||
|
||||
if !force {
|
||||
m.handler.Wait()
|
||||
m.program.Quit()
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
module github.com/anchore/syft
|
||||
|
||||
go 1.22.5
|
||||
|
||||
toolchain go1.22.8
|
||||
go 1.22.9
|
||||
|
||||
require (
|
||||
github.com/CycloneDX/cyclonedx-go v0.9.1
|
||||
@@ -11,23 +9,23 @@ require (
|
||||
github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d
|
||||
github.com/acobaugh/osrelease v0.1.0
|
||||
github.com/anchore/bubbly v0.0.0-20231115134915-def0aba654a9
|
||||
github.com/anchore/clio v0.0.0-20240522144804-d81e109008aa
|
||||
github.com/anchore/fangs v0.0.0-20240903175602-e716ef12c23d
|
||||
github.com/anchore/clio v0.0.0-20241015191535-f538a9016e10
|
||||
github.com/anchore/fangs v0.0.0-20241014201141-b6e4b3469f10
|
||||
github.com/anchore/go-collections v0.0.0-20240216171411-9321230ce537
|
||||
github.com/anchore/go-logger v0.0.0-20230725134548-c21dafa1ec5a
|
||||
github.com/anchore/go-macholibre v0.0.0-20220308212642-53e6d0aaf6fb
|
||||
github.com/anchore/go-testutils v0.0.0-20200925183923-d5f45b0d3c04
|
||||
github.com/anchore/go-version v1.2.2-0.20200701162849-18adb9c92b9b
|
||||
github.com/anchore/packageurl-go v0.1.1-0.20241018175412-5c22e6360c4f
|
||||
github.com/anchore/stereoscope v0.0.5-0.20241018131503-a38c93517fc7
|
||||
github.com/anchore/stereoscope v0.0.9-0.20241113211114-aa3a3ef4efe8
|
||||
github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be
|
||||
// we are hinting brotli to latest due to warning when installing archiver v3:
|
||||
// go: warning: github.com/andybalholm/brotli@v1.0.1: retracted by module author: occasional panics and data corruption
|
||||
github.com/aquasecurity/go-pep440-version v0.0.0-20210121094942-22b2f8951d46
|
||||
github.com/bmatcuk/doublestar/v4 v4.7.1
|
||||
github.com/charmbracelet/bubbles v0.20.0
|
||||
github.com/charmbracelet/bubbletea v1.1.1
|
||||
github.com/charmbracelet/lipgloss v0.13.0
|
||||
github.com/charmbracelet/bubbletea v1.2.2
|
||||
github.com/charmbracelet/lipgloss v1.0.0
|
||||
github.com/dave/jennifer v1.7.1
|
||||
github.com/deitch/magic v0.0.0-20230404182410-1ff89d7342da
|
||||
github.com/distribution/reference v0.6.0
|
||||
@@ -37,7 +35,7 @@ require (
|
||||
github.com/facebookincubator/nvdtools v0.1.5
|
||||
github.com/github/go-spdx/v2 v2.3.2
|
||||
github.com/gkampitakis/go-snaps v0.5.7
|
||||
github.com/go-git/go-billy/v5 v5.5.0
|
||||
github.com/go-git/go-billy/v5 v5.6.0
|
||||
github.com/go-git/go-git/v5 v5.12.0
|
||||
github.com/go-test/deep v1.1.1
|
||||
github.com/google/go-cmp v0.6.0
|
||||
@@ -62,7 +60,7 @@ require (
|
||||
github.com/opencontainers/go-digest v1.0.0
|
||||
github.com/pelletier/go-toml v1.9.5
|
||||
github.com/quasilyte/go-ruleguard/dsl v0.3.22
|
||||
github.com/saferwall/pe v1.5.4
|
||||
github.com/saferwall/pe v1.5.5
|
||||
github.com/saintfish/chardet v0.0.0-20230101081208-5e3ef4b5456d
|
||||
github.com/sanity-io/litter v1.5.5
|
||||
github.com/sassoftware/go-rpmutils v0.4.0
|
||||
@@ -80,8 +78,8 @@ require (
|
||||
github.com/xeipuuv/gojsonschema v1.2.0
|
||||
github.com/zyedidia/generic v1.2.2-0.20230320175451-4410d2372cb1
|
||||
go.uber.org/goleak v1.3.0
|
||||
golang.org/x/mod v0.21.0
|
||||
golang.org/x/net v0.30.0
|
||||
golang.org/x/mod v0.22.0
|
||||
golang.org/x/net v0.31.0
|
||||
gopkg.in/yaml.v3 v3.0.1
|
||||
modernc.org/sqlite v1.33.1
|
||||
)
|
||||
@@ -91,9 +89,9 @@ require google.golang.org/genproto v0.0.0-20240213162025-012b6fc9bca9 // indirec
|
||||
require (
|
||||
github.com/BurntSushi/toml v1.4.0
|
||||
github.com/OneOfOne/xxhash v1.2.8
|
||||
github.com/adrg/xdg v0.5.1
|
||||
github.com/adrg/xdg v0.5.3
|
||||
github.com/magiconair/properties v1.8.7
|
||||
golang.org/x/exp v0.0.0-20231108232855-2478ac86f678
|
||||
golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56
|
||||
)
|
||||
|
||||
require (
|
||||
@@ -105,7 +103,7 @@ require (
|
||||
github.com/Masterminds/semver/v3 v3.3.0 // indirect
|
||||
github.com/Microsoft/go-winio v0.6.2 // indirect
|
||||
github.com/Microsoft/hcsshim v0.11.7 // indirect
|
||||
github.com/ProtonMail/go-crypto v1.0.0 // indirect
|
||||
github.com/ProtonMail/go-crypto v1.1.2 // indirect
|
||||
github.com/anchore/go-struct-converter v0.0.0-20221118182256-c68fdcfa2092 // indirect
|
||||
github.com/andybalholm/brotli v1.0.4 // indirect
|
||||
github.com/aquasecurity/go-version v0.0.0-20210121072130-637058cfe492 // indirect
|
||||
@@ -113,8 +111,8 @@ require (
|
||||
github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect
|
||||
github.com/becheran/wildmatch-go v1.0.0 // indirect
|
||||
github.com/charmbracelet/harmonica v0.2.0 // indirect
|
||||
github.com/charmbracelet/x/ansi v0.2.3 // indirect
|
||||
github.com/charmbracelet/x/term v0.2.0 // indirect
|
||||
github.com/charmbracelet/x/ansi v0.4.5 // indirect
|
||||
github.com/charmbracelet/x/term v0.2.1 // indirect
|
||||
github.com/cloudflare/circl v1.3.8 // indirect
|
||||
github.com/containerd/cgroups v1.1.0 // indirect
|
||||
github.com/containerd/containerd v1.7.23 // indirect
|
||||
@@ -127,7 +125,7 @@ require (
|
||||
github.com/containerd/stargz-snapshotter/estargz v0.14.3 // indirect
|
||||
github.com/containerd/ttrpc v1.2.5 // indirect
|
||||
github.com/containerd/typeurl/v2 v2.1.1 // indirect
|
||||
github.com/cyphar/filepath-securejoin v0.2.4 // indirect
|
||||
github.com/cyphar/filepath-securejoin v0.2.5 // indirect
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
|
||||
github.com/docker/cli v27.3.1+incompatible // indirect
|
||||
github.com/docker/distribution v2.8.3+incompatible // indirect
|
||||
@@ -212,7 +210,7 @@ require (
|
||||
github.com/spf13/pflag v1.0.5 // indirect
|
||||
github.com/spf13/viper v1.19.0 // indirect
|
||||
github.com/subosito/gotenv v1.6.0 // indirect
|
||||
github.com/sylabs/sif/v2 v2.19.1 // indirect
|
||||
github.com/sylabs/sif/v2 v2.20.0 // indirect
|
||||
github.com/sylabs/squashfs v1.0.0 // indirect
|
||||
github.com/therootcompany/xz v1.0.1 // indirect
|
||||
github.com/tidwall/gjson v1.17.0 // indirect
|
||||
@@ -233,11 +231,11 @@ require (
|
||||
go.opentelemetry.io/otel/trace v1.24.0 // indirect
|
||||
go.uber.org/atomic v1.9.0 // indirect
|
||||
go.uber.org/multierr v1.9.0 // indirect
|
||||
golang.org/x/crypto v0.28.0 // indirect
|
||||
golang.org/x/sync v0.8.0 // indirect
|
||||
golang.org/x/sys v0.26.0 // indirect
|
||||
golang.org/x/term v0.25.0 // indirect
|
||||
golang.org/x/text v0.19.0 // indirect
|
||||
golang.org/x/crypto v0.29.0 // indirect
|
||||
golang.org/x/sync v0.9.0 // indirect
|
||||
golang.org/x/sys v0.27.0 // indirect
|
||||
golang.org/x/term v0.26.0 // indirect
|
||||
golang.org/x/text v0.20.0 // indirect
|
||||
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240314234333-6e1732d8331c // indirect
|
||||
google.golang.org/grpc v1.62.1 // indirect
|
||||
|
||||
@@ -81,14 +81,14 @@ github.com/Microsoft/hcsshim v0.11.7/go.mod h1:MV8xMfmECjl5HdO7U/3/hFVnkmSBjAjmA
|
||||
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
|
||||
github.com/OneOfOne/xxhash v1.2.8 h1:31czK/TI9sNkxIKfaUfGlU47BAxQ0ztGgd9vPyqimf8=
|
||||
github.com/OneOfOne/xxhash v1.2.8/go.mod h1:eZbhyaAYD41SGSSsnmcpxVoRiQ/MPUTjUdIIOT9Um7Q=
|
||||
github.com/ProtonMail/go-crypto v1.0.0 h1:LRuvITjQWX+WIfr930YHG2HNfjR1uOfyf5vE0kC2U78=
|
||||
github.com/ProtonMail/go-crypto v1.0.0/go.mod h1:EjAoLdwvbIOoOQr3ihjnSoLZRtE8azugULFRteWMNc0=
|
||||
github.com/ProtonMail/go-crypto v1.1.2 h1:A7JbD57ThNqh7XjmHE+PXpQ3Dqt3BrSAC0AL0Go3KS0=
|
||||
github.com/ProtonMail/go-crypto v1.1.2/go.mod h1:rA3QumHc/FZ8pAHreoekgiAbzpNsfQAosU5td4SnOrE=
|
||||
github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d h1:licZJFw2RwpHMqeKTCYkitsPqHNxTmd4SNR5r94FGM8=
|
||||
github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d/go.mod h1:asat636LX7Bqt5lYEZ27JNDcqxfjdBQuJ/MM4CN/Lzo=
|
||||
github.com/acobaugh/osrelease v0.1.0 h1:Yb59HQDGGNhCj4suHaFQQfBps5wyoKLSSX/J/+UifRE=
|
||||
github.com/acobaugh/osrelease v0.1.0/go.mod h1:4bFEs0MtgHNHBrmHCt67gNisnabCRAlzdVasCEGHTWY=
|
||||
github.com/adrg/xdg v0.5.1 h1:Im8iDbEFARltY09yOJlSGu4Asjk2vF85+3Dyru8uJ0U=
|
||||
github.com/adrg/xdg v0.5.1/go.mod h1:nlTsY+NNiCBGCK2tpm09vRqfVzrc2fLmXGpBLF0zlTQ=
|
||||
github.com/adrg/xdg v0.5.3 h1:xRnxJXne7+oWDatRhR1JLnvuccuIeCoBu2rtuLqQB78=
|
||||
github.com/adrg/xdg v0.5.3/go.mod h1:nlTsY+NNiCBGCK2tpm09vRqfVzrc2fLmXGpBLF0zlTQ=
|
||||
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||
@@ -97,10 +97,10 @@ github.com/anchore/archiver/v3 v3.5.2 h1:Bjemm2NzuRhmHy3m0lRe5tNoClB9A4zYyDV58Pa
|
||||
github.com/anchore/archiver/v3 v3.5.2/go.mod h1:e3dqJ7H78uzsRSEACH1joayhuSyhnonssnDhppzS1L4=
|
||||
github.com/anchore/bubbly v0.0.0-20231115134915-def0aba654a9 h1:p0ZIe0htYOX284Y4axJaGBvXHU0VCCzLN5Wf5XbKStU=
|
||||
github.com/anchore/bubbly v0.0.0-20231115134915-def0aba654a9/go.mod h1:3ZsFB9tzW3vl4gEiUeuSOMDnwroWxIxJelOOHUp8dSw=
|
||||
github.com/anchore/clio v0.0.0-20240522144804-d81e109008aa h1:pwlAn4O9SBUnlgfa69YcqIynbUyobLVFYu8HxSoCffA=
|
||||
github.com/anchore/clio v0.0.0-20240522144804-d81e109008aa/go.mod h1:nD3H5uIvjxlfmakOBgtyFQbk5Zjp3l538kxfpHPslzI=
|
||||
github.com/anchore/fangs v0.0.0-20240903175602-e716ef12c23d h1:ZD4wdCBgJJzJybjTUIEiiupLF7B9H3WLuBTjspBO2Mc=
|
||||
github.com/anchore/fangs v0.0.0-20240903175602-e716ef12c23d/go.mod h1:Xh4ObY3fmoMzOEVXwDtS1uK44JC7+nRD0n29/1KYFYg=
|
||||
github.com/anchore/clio v0.0.0-20241015191535-f538a9016e10 h1:3xmanFdoQEH0REvPA+gLm3Km0/981F4z2a/7ADTlv8k=
|
||||
github.com/anchore/clio v0.0.0-20241015191535-f538a9016e10/go.mod h1:h6Ly2hlKjQoPtI3rA8oB5afSmB/XimhcY55xbuW4Dwo=
|
||||
github.com/anchore/fangs v0.0.0-20241014201141-b6e4b3469f10 h1:w+HibE+e/heP6ysADh7sWxg5LhYdVqrpB1A4Hmgjyx8=
|
||||
github.com/anchore/fangs v0.0.0-20241014201141-b6e4b3469f10/go.mod h1:s0L1//Sxn6Rq0Dcxx+dmT/RRmD9HhsaJjJkPUJHLJLM=
|
||||
github.com/anchore/go-collections v0.0.0-20240216171411-9321230ce537 h1:GjNGuwK5jWjJMyVppBjYS54eOiiSNv4Ba869k4wh72Q=
|
||||
github.com/anchore/go-collections v0.0.0-20240216171411-9321230ce537/go.mod h1:1aiktV46ATCkuVg0O573ZrH56BUawTECPETbZyBcqT8=
|
||||
github.com/anchore/go-logger v0.0.0-20230725134548-c21dafa1ec5a h1:nJ2G8zWKASyVClGVgG7sfM5mwoZlZ2zYpIzN2OhjWkw=
|
||||
@@ -115,8 +115,8 @@ github.com/anchore/go-version v1.2.2-0.20200701162849-18adb9c92b9b h1:e1bmaoJfZV
|
||||
github.com/anchore/go-version v1.2.2-0.20200701162849-18adb9c92b9b/go.mod h1:Bkc+JYWjMCF8OyZ340IMSIi2Ebf3uwByOk6ho4wne1E=
|
||||
github.com/anchore/packageurl-go v0.1.1-0.20241018175412-5c22e6360c4f h1:dAQPIrQ3a5PBqZeZ+B9NGZsGmodk4NO9OjDIsQmQyQM=
|
||||
github.com/anchore/packageurl-go v0.1.1-0.20241018175412-5c22e6360c4f/go.mod h1:KoYIv7tdP5+CC9VGkeZV4/vGCKsY55VvoG+5dadg4YI=
|
||||
github.com/anchore/stereoscope v0.0.5-0.20241018131503-a38c93517fc7 h1:CBKDfuMWKRt12EnKtgT/an9FQSQI83mOU1KT57z81IU=
|
||||
github.com/anchore/stereoscope v0.0.5-0.20241018131503-a38c93517fc7/go.mod h1:wH79ZauZcd3erKPocg9+qhDC6Q/z125sD+Isi4d61a4=
|
||||
github.com/anchore/stereoscope v0.0.9-0.20241113211114-aa3a3ef4efe8 h1:gYed/fx5OeW+isRay2q60JGt8+ED/odEPiJ/SWlbw8s=
|
||||
github.com/anchore/stereoscope v0.0.9-0.20241113211114-aa3a3ef4efe8/go.mod h1:c2oGDU0R+llJObsatBSenjYPV1raKhMq9GEqe8J56EI=
|
||||
github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8=
|
||||
github.com/andybalholm/brotli v1.0.1/go.mod h1:loMXtMfwqflxFJPmdbJO0a3KNoPuLBgiu3qAvBg8x/Y=
|
||||
github.com/andybalholm/brotli v1.0.4 h1:V7DdXeJtZscaqfNuAdSRuRFzuiKlHSC/Zh3zl9qY3JY=
|
||||
@@ -149,7 +149,6 @@ github.com/bmatcuk/doublestar/v4 v4.7.1 h1:fdDeAqgT47acgwd9bd9HxJRDmc9UAmPpc+2m0
|
||||
github.com/bmatcuk/doublestar/v4 v4.7.1/go.mod h1:xBQ8jztBU6kakFMg+8WGxn0c6z1fTSPVIjEY1Wr7jzc=
|
||||
github.com/bradleyjkemp/cupaloy/v2 v2.8.0 h1:any4BmKE+jGIaMpnU8YgH/I2LPiLBufr6oMMlVBbn9M=
|
||||
github.com/bradleyjkemp/cupaloy/v2 v2.8.0/go.mod h1:bm7JXdkRd4BHJk9HpwqAI8BoAY1lps46Enkdqw6aRX0=
|
||||
github.com/bwesterb/go-ristretto v1.2.3/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0=
|
||||
github.com/cenkalti/backoff/v4 v4.2.1 h1:y4OZtCnogmCPw98Zjyt5a6+QwPLGkiQsYW5oUqylYbM=
|
||||
github.com/cenkalti/backoff/v4 v4.2.1/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE=
|
||||
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||
@@ -159,23 +158,22 @@ github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XL
|
||||
github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
github.com/charmbracelet/bubbles v0.20.0 h1:jSZu6qD8cRQ6k9OMfR1WlM+ruM8fkPWkHvQWD9LIutE=
|
||||
github.com/charmbracelet/bubbles v0.20.0/go.mod h1:39slydyswPy+uVOHZ5x/GjwVAFkCsV8IIVy+4MhzwwU=
|
||||
github.com/charmbracelet/bubbletea v1.1.1 h1:KJ2/DnmpfqFtDNVTvYZ6zpPFL9iRCRr0qqKOCvppbPY=
|
||||
github.com/charmbracelet/bubbletea v1.1.1/go.mod h1:9Ogk0HrdbHolIKHdjfFpyXJmiCzGwy+FesYkZr7hYU4=
|
||||
github.com/charmbracelet/bubbletea v1.2.2 h1:EMz//Ky/aFS2uLcKqpCst5UOE6z5CFDGRsUpyXz0chs=
|
||||
github.com/charmbracelet/bubbletea v1.2.2/go.mod h1:Qr6fVQw+wX7JkWWkVyXYk/ZUQ92a6XNekLXa3rR18MM=
|
||||
github.com/charmbracelet/harmonica v0.2.0 h1:8NxJWRWg/bzKqqEaaeFNipOu77YR5t8aSwG4pgaUBiQ=
|
||||
github.com/charmbracelet/harmonica v0.2.0/go.mod h1:KSri/1RMQOZLbw7AHqgcBycp8pgJnQMYYT8QZRqZ1Ao=
|
||||
github.com/charmbracelet/lipgloss v0.13.0 h1:4X3PPeoWEDCMvzDvGmTajSyYPcZM4+y8sCA/SsA3cjw=
|
||||
github.com/charmbracelet/lipgloss v0.13.0/go.mod h1:nw4zy0SBX/F/eAO1cWdcvy6qnkDUxr8Lw7dvFrAIbbY=
|
||||
github.com/charmbracelet/x/ansi v0.2.3 h1:VfFN0NUpcjBRd4DnKfRaIRo53KRgey/nhOoEqosGDEY=
|
||||
github.com/charmbracelet/x/ansi v0.2.3/go.mod h1:dk73KoMTT5AX5BsX0KrqhsTqAnhZZoCBjs7dGWp4Ktw=
|
||||
github.com/charmbracelet/x/term v0.2.0 h1:cNB9Ot9q8I711MyZ7myUR5HFWL/lc3OpU8jZ4hwm0x0=
|
||||
github.com/charmbracelet/x/term v0.2.0/go.mod h1:GVxgxAbjUrmpvIINHIQnJJKpMlHiZ4cktEQCN6GWyF0=
|
||||
github.com/charmbracelet/lipgloss v1.0.0 h1:O7VkGDvqEdGi93X+DeqsQ7PKHDgtQfF8j8/O2qFMQNg=
|
||||
github.com/charmbracelet/lipgloss v1.0.0/go.mod h1:U5fy9Z+C38obMs+T+tJqst9VGzlOYGj4ri9reL3qUlo=
|
||||
github.com/charmbracelet/x/ansi v0.4.5 h1:LqK4vwBNaXw2AyGIICa5/29Sbdq58GbGdFngSexTdRM=
|
||||
github.com/charmbracelet/x/ansi v0.4.5/go.mod h1:dk73KoMTT5AX5BsX0KrqhsTqAnhZZoCBjs7dGWp4Ktw=
|
||||
github.com/charmbracelet/x/term v0.2.1 h1:AQeHeLZ1OqSXhrAWpYUtZyX1T3zVxfpZuEQMIQaGIAQ=
|
||||
github.com/charmbracelet/x/term v0.2.1/go.mod h1:oQ4enTYFV7QN4m0i9mzHrViD7TQKvNEEkHUMCmsxdUg=
|
||||
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
|
||||
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
|
||||
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
|
||||
github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible/go.mod h1:nmEj6Dob7S7YxXgwXpfOuvO54S+tGdZdw9fuRZt25Ag=
|
||||
github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I=
|
||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||
github.com/cloudflare/circl v1.3.3/go.mod h1:5XYMA4rFBvNIrhs50XuiBJ15vF2pZn4nnUKZrLbUZFA=
|
||||
github.com/cloudflare/circl v1.3.8 h1:j+V8jJt09PoeMFIu2uh5JUyEaIHTXVOHslFoLNAKqwI=
|
||||
github.com/cloudflare/circl v1.3.8/go.mod h1:PDRU+oXvdD7KCtgKxW95M5Z8BpSCJXQORiZFnBQS5QU=
|
||||
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
|
||||
@@ -217,8 +215,8 @@ github.com/cpuguy83/go-md2man/v2 v2.0.1/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46t
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
|
||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
github.com/cyphar/filepath-securejoin v0.2.4 h1:Ugdm7cg7i6ZK6x3xDF1oEu1nfkyfH53EtKeQYTC3kyg=
|
||||
github.com/cyphar/filepath-securejoin v0.2.4/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4=
|
||||
github.com/cyphar/filepath-securejoin v0.2.5 h1:6iR5tXJ/e6tJZzzdMc1km3Sa7RRIVBKAK32O2s7AYfo=
|
||||
github.com/cyphar/filepath-securejoin v0.2.5/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4=
|
||||
github.com/dave/jennifer v1.7.1 h1:B4jJJDHelWcDhlRQxWeo0Npa/pYKBLrirAQoTN45txo=
|
||||
github.com/dave/jennifer v1.7.1/go.mod h1:nXbxhEmQfOZhWml3D1cDK5M1FLnMSozpbFN/m3RmGZc=
|
||||
github.com/davecgh/go-spew v0.0.0-20161028175848-04cdfd42973b/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
@@ -305,8 +303,8 @@ github.com/gliderlabs/ssh v0.3.7 h1:iV3Bqi942d9huXnzEF2Mt+CY9gLu8DNM4Obd+8bODRE=
|
||||
github.com/gliderlabs/ssh v0.3.7/go.mod h1:zpHEXBstFnQYtGnB8k8kQLol82umzn/2/snG7alWVD8=
|
||||
github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 h1:+zs/tPmkDkHx3U66DAb0lQFJrpS6731Oaa12ikc+DiI=
|
||||
github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376/go.mod h1:an3vInlBmSxCcxctByoQdvwPiA7DTK7jaaFDBTtu0ic=
|
||||
github.com/go-git/go-billy/v5 v5.5.0 h1:yEY4yhzCDuMGSv83oGxiBotRzhwhNr8VZyphhiu+mTU=
|
||||
github.com/go-git/go-billy/v5 v5.5.0/go.mod h1:hmexnoNsr2SJU1Ju67OaNz5ASJY3+sHgFRpCtpDCKow=
|
||||
github.com/go-git/go-billy/v5 v5.6.0 h1:w2hPNtoehvJIxR00Vb4xX94qHQi/ApZfX+nBE2Cjio8=
|
||||
github.com/go-git/go-billy/v5 v5.6.0/go.mod h1:sFDq7xD3fn3E0GOwUSZqHo9lrkmx8xJhA0ZrfvjBRGM=
|
||||
github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399 h1:eMje31YglSBqCdIqdhKBW8lokaMrL3uTkpGYlE2OOT4=
|
||||
github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399/go.mod h1:1OCfN199q1Jm3HZlxleg+Dw/mwps2Wbk9frAWm+4FII=
|
||||
github.com/go-git/go-git/v5 v5.12.0 h1:7Md+ndsjrzZxbddRDZjF14qK+NN56sy6wkqaVrjZtys=
|
||||
@@ -613,8 +611,8 @@ github.com/nwaples/rardecode v1.1.0 h1:vSxaY8vQhOcVr4mm5e8XllHWTiM4JF507A0Katqw7
|
||||
github.com/nwaples/rardecode v1.1.0/go.mod h1:5DzqNKiOdpKKBH87u8VlvAnPZMXcGRhxWkRpHbbfGS0=
|
||||
github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec=
|
||||
github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY=
|
||||
github.com/onsi/gomega v1.27.10 h1:naR28SdDFlqrG6kScpT8VWpu1xWY5nJRCF3XaYyBjhI=
|
||||
github.com/onsi/gomega v1.27.10/go.mod h1:RsS8tutOdbdgzbPtzzATp12yT7kM5I5aElG3evPbQ0M=
|
||||
github.com/onsi/gomega v1.34.1 h1:EUMJIKUjM8sKjYbtxQI9A4z2o+rruxnzNvpknOXie6k=
|
||||
github.com/onsi/gomega v1.34.1/go.mod h1:kU1QgUvBDLXBJq618Xvm2LUX6rSAfRaFRTcdOeDLwwY=
|
||||
github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=
|
||||
github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
|
||||
github.com/opencontainers/image-spec v1.1.0 h1:8SG7/vwALn54lVB/0yZ/MMwhFrPYtpEHQb2IpWsCzug=
|
||||
@@ -680,8 +678,8 @@ github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99
|
||||
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
|
||||
github.com/saferwall/pe v1.5.4 h1:tLmMggEMUfeqrpJ25zS/okUQmyFdD5xWKL2+z9njCqg=
|
||||
github.com/saferwall/pe v1.5.4/go.mod h1:mJx+PuptmNpoPFBNhWs/uDMFL/kTHVZIkg0d4OUJFbQ=
|
||||
github.com/saferwall/pe v1.5.5 h1:GGbzKjXDm7i+1K6riOgtgblyTdRmTbr3r11IzjovAK8=
|
||||
github.com/saferwall/pe v1.5.5/go.mod h1:mJx+PuptmNpoPFBNhWs/uDMFL/kTHVZIkg0d4OUJFbQ=
|
||||
github.com/sagikazarmark/crypt v0.3.0/go.mod h1:uD/D+6UF4SrIR1uGEv7bBNkNqLGqUr43MRiaGWX1Nig=
|
||||
github.com/sagikazarmark/locafero v0.4.0 h1:HApY1R9zGo4DBgr7dqsTH/JJxLTTsOt7u6keLGt6kNQ=
|
||||
github.com/sagikazarmark/locafero v0.4.0/go.mod h1:Pe1W6UlPYUk/+wc/6KFhbORCfqzgYEpgQ3O5fPuL3H4=
|
||||
@@ -762,8 +760,8 @@ github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8
|
||||
github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
|
||||
github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8=
|
||||
github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU=
|
||||
github.com/sylabs/sif/v2 v2.19.1 h1:1eeMmFc8elqJe60ZiWwXgL3gMheb0IP4GmNZ4q0IEA0=
|
||||
github.com/sylabs/sif/v2 v2.19.1/go.mod h1:U1SUhvl8X1JIxAylC0DYz1fa/Xba6EMZD1dGPGBH83E=
|
||||
github.com/sylabs/sif/v2 v2.20.0 h1:RfDHEltUrchZbp/XGcWaw3nRSbufoNWqvwmf91/Q2gI=
|
||||
github.com/sylabs/sif/v2 v2.20.0/go.mod h1:z6dq3B7QXK0pD71n15kAapven+gE+PZAIPOewBTNDpU=
|
||||
github.com/sylabs/squashfs v1.0.0 h1:xAyMS21ogglkuR5HaY55PCfqY3H32ma9GkasTYo28Zg=
|
||||
github.com/sylabs/squashfs v1.0.0/go.mod h1:rhWzvgefq1X+R+LZdts10hfMsTg3g74OfGunW8tvg/4=
|
||||
github.com/terminalstatic/go-xsd-validate v0.1.5 h1:RqpJnf6HGE2CB/lZB1A8BYguk8uRtcvYAPLCF15qguo=
|
||||
@@ -868,10 +866,8 @@ golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPh
|
||||
golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/crypto v0.3.1-0.20221117191849-2c476679df9a/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4=
|
||||
golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU=
|
||||
golang.org/x/crypto v0.28.0 h1:GBDwsMXVQi34v5CCYUm2jkJvu4cbtru2U4TN2PSyQnw=
|
||||
golang.org/x/crypto v0.28.0/go.mod h1:rmgy+3RHxRZMyY0jjAJShp2zgEdOqj2AO7U0pYmeQ7U=
|
||||
golang.org/x/crypto v0.29.0 h1:L5SG1JTTXupVV3n6sUqMTeWbjAyfPwoda2DLX8J8FrQ=
|
||||
golang.org/x/crypto v0.29.0/go.mod h1:+F4F4N5hv6v38hfeYwTdx20oUvLLc+QfrE9Ax9HtgRg=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
|
||||
@@ -882,8 +878,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0
|
||||
golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
|
||||
golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
|
||||
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
|
||||
golang.org/x/exp v0.0.0-20231108232855-2478ac86f678 h1:mchzmB1XO2pMaKFRqk/+MV3mgGG96aqaPXaMifQU47w=
|
||||
golang.org/x/exp v0.0.0-20231108232855-2478ac86f678/go.mod h1:zk2irFbV9DP96SEBUUAy67IdHUaZuSnrz1n472HUCLE=
|
||||
golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8=
|
||||
golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY=
|
||||
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
|
||||
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
@@ -911,9 +907,8 @@ golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.5.0/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro=
|
||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||
golang.org/x/mod v0.21.0 h1:vvrHzRwRfVKSiLrG+d4FMl/Qi4ukBCE6kZlTUkDYRT0=
|
||||
golang.org/x/mod v0.21.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY=
|
||||
golang.org/x/mod v0.22.0 h1:D4nJWe9zXqHOmWqj4VMOJhvzj7bEZg4wEYa759z1pH4=
|
||||
golang.org/x/mod v0.22.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY=
|
||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
@@ -957,11 +952,8 @@ golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qx
|
||||
golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||
golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY=
|
||||
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
||||
golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc=
|
||||
golang.org/x/net v0.30.0 h1:AcW1SDZMkb8IpzCdQUaIq2sP4sZ4zw+55h6ynffypl4=
|
||||
golang.org/x/net v0.30.0/go.mod h1:2wGyMJ5iFasEhkwi13ChkO/t1ECNC4X4eBKkVFyYFlU=
|
||||
golang.org/x/net v0.31.0 h1:68CPQngjLL0r2AlUKiSxtQFKvzRVbnzLwMUn5SzcLHo=
|
||||
golang.org/x/net v0.31.0/go.mod h1:P4fl1q7dY2hnZFxEk4pPSkDHF+QqjitcnDjUQyMM+pM=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
@@ -991,9 +983,8 @@ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJ
|
||||
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ=
|
||||
golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/sync v0.9.0 h1:fEo0HyrW1GIgZdpbhCRO0PkJajUS5H9IFUztCgEo2jQ=
|
||||
golang.org/x/sync v0.9.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
@@ -1068,19 +1059,13 @@ golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBc
|
||||
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220906165534-d0df966e6959/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo=
|
||||
golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.27.0 h1:wBqf8DvsY9Y/2P8gAfPDEYNuS30J4lPHJxXSb/nJZ+s=
|
||||
golang.org/x/sys v0.27.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc=
|
||||
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
|
||||
golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U=
|
||||
golang.org/x/term v0.25.0 h1:WtHI/ltw4NvSUig5KARz9h521QvRC8RmF/cuYqifU24=
|
||||
golang.org/x/term v0.25.0/go.mod h1:RPyXicDX+6vLxogjjRxjgD2TKtmAO6NZBsBRfrOLu7M=
|
||||
golang.org/x/term v0.26.0 h1:WEQa6V3Gja/BhNxg540hBip/kkaYtRg3cxg4oXSw4AU=
|
||||
golang.org/x/term v0.26.0/go.mod h1:Si5m1o57C5nBNQo5z1iq+XDijt21BDBDp2bK0QI8e3E=
|
||||
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
@@ -1090,11 +1075,9 @@ golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||
golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
||||
golang.org/x/text v0.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM=
|
||||
golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
|
||||
golang.org/x/text v0.20.0 h1:gK/Kv2otX8gz+wn7Rmb3vT96ZwuoxnQlY+HlJVj7Qug=
|
||||
golang.org/x/text v0.20.0/go.mod h1:D4IsuqiFMhST5bX19pQ9ikHC2GsaKyk/oF+pn3ducp4=
|
||||
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
@@ -1155,9 +1138,8 @@ golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||
golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||
golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
|
||||
golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d h1:vU5i/LfpvrRCpgM/VPfJLg5KjxD3E+hfT1SH+d9zLwg=
|
||||
golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk=
|
||||
golang.org/x/tools v0.23.0 h1:SGsXPZ+2l4JsgaCKkx+FQ9YZ5XEtA1GZYuoDjenLjvg=
|
||||
golang.org/x/tools v0.23.0/go.mod h1:pnu6ufv6vQkll6szChhK3C3L/ruaIv5eBeztNG8wtsI=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
|
||||
@@ -3,5 +3,5 @@ package internal
|
||||
const (
|
||||
// JSONSchemaVersion is the current schema version output by the JSON encoder
|
||||
// This is roughly following the "SchemaVer" guidelines for versioning the JSON schema. Please see schema/json/README.md for details on how to increment.
|
||||
JSONSchemaVersion = "16.0.18"
|
||||
JSONSchemaVersion = "16.0.19"
|
||||
)
|
||||
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"context"
|
||||
"fmt"
|
||||
"runtime/debug"
|
||||
"slices"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
@@ -57,14 +58,14 @@ func (p *Executor) Execute(ctx context.Context, resolver file.Resolver, s sbomsy
|
||||
}
|
||||
|
||||
err := runTaskSafely(ctx, tsk, resolver, s)
|
||||
unknowns, err := unknown.ExtractCoordinateErrors(err)
|
||||
unknowns, remainingErrors := unknown.ExtractCoordinateErrors(err)
|
||||
if len(unknowns) > 0 {
|
||||
appendUnknowns(s, tsk.Name(), unknowns)
|
||||
}
|
||||
if err != nil {
|
||||
if remainingErrors != nil {
|
||||
withLock(func() {
|
||||
errs = multierror.Append(errs, fmt.Errorf("failed to run task: %w", err))
|
||||
prog.SetError(err)
|
||||
errs = multierror.Append(errs, fmt.Errorf("failed to run task: %w", remainingErrors))
|
||||
prog.SetError(remainingErrors)
|
||||
})
|
||||
}
|
||||
prog.Increment()
|
||||
@@ -84,7 +85,13 @@ func appendUnknowns(builder sbomsync.Builder, taskName string, unknowns []unknow
|
||||
if sb.Artifacts.Unknowns == nil {
|
||||
sb.Artifacts.Unknowns = map[file.Coordinates][]string{}
|
||||
}
|
||||
sb.Artifacts.Unknowns[u.Coordinates] = append(sb.Artifacts.Unknowns[u.Coordinates], formatUnknown(u.Reason.Error(), taskName))
|
||||
unknownText := formatUnknown(u.Reason.Error(), taskName)
|
||||
existing := sb.Artifacts.Unknowns[u.Coordinates]
|
||||
// don't include duplicate unknowns
|
||||
if slices.Contains(existing, unknownText) {
|
||||
continue
|
||||
}
|
||||
sb.Artifacts.Unknowns[u.Coordinates] = append(existing, unknownText)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@@ -110,6 +110,8 @@ func NewPackageTask(cfg CatalogingFactoryConfig, c pkg.Cataloger, tags ...string
|
||||
|
||||
pkgs, relationships = applyCompliance(cfg.ComplianceConfig, pkgs, relationships)
|
||||
|
||||
finalizeDependencyCompleteness(pkgs)
|
||||
|
||||
sbom.AddPackages(pkgs...)
|
||||
sbom.AddRelationships(relationships...)
|
||||
t.Add(int64(len(pkgs)))
|
||||
@@ -124,6 +126,13 @@ func NewPackageTask(cfg CatalogingFactoryConfig, c pkg.Cataloger, tags ...string
|
||||
return NewTask(c.Name(), fn, tags...)
|
||||
}
|
||||
|
||||
func finalizeDependencyCompleteness(pkgs []pkg.Package) {
|
||||
// ensure that all packages have a non-empty dependency list
|
||||
for i := range pkgs {
|
||||
pkgs[i].Dependencies = pkg.ParseDependencyCompleteness(string(pkgs[i].Dependencies))
|
||||
}
|
||||
}
|
||||
|
||||
func finalizePkgCatalogerResults(cfg CatalogingFactoryConfig, resolver file.PathResolver, catalogerName string, pkgs []pkg.Package, relationships []artifact.Relationship) ([]pkg.Package, []artifact.Relationship) {
|
||||
for i, p := range pkgs {
|
||||
if p.FoundBy == "" {
|
||||
|
||||
@@ -68,7 +68,7 @@ func DefaultPackageTaskFactories() PackageTaskFactories {
|
||||
newSimplePackageTaskFactory(php.NewComposerInstalledCataloger, pkgcataloging.InstalledTag, pkgcataloging.ImageTag, pkgcataloging.LanguageTag, "php", "composer"),
|
||||
newSimplePackageTaskFactory(r.NewPackageCataloger, pkgcataloging.InstalledTag, pkgcataloging.ImageTag, pkgcataloging.LanguageTag, "r"),
|
||||
newSimplePackageTaskFactory(ruby.NewInstalledGemSpecCataloger, pkgcataloging.InstalledTag, pkgcataloging.ImageTag, pkgcataloging.LanguageTag, "ruby", "gem", "gemspec"),
|
||||
newSimplePackageTaskFactory(rust.NewAuditBinaryCataloger, pkgcataloging.InstalledTag, pkgcataloging.ImageTag, pkgcataloging.LanguageTag, "rust", "binary"),
|
||||
newSimplePackageTaskFactory(rust.NewAuditBinaryCataloger, pkgcataloging.DirectoryTag, pkgcataloging.InstalledTag, pkgcataloging.ImageTag, pkgcataloging.LanguageTag, "rust", "binary"),
|
||||
|
||||
// language-specific package declared catalogers ///////////////////////////////////////////////////////////////////////////
|
||||
newSimplePackageTaskFactory(cpp.NewConanCataloger, pkgcataloging.DeclaredTag, pkgcataloging.DirectoryTag, pkgcataloging.LanguageTag, "cpp", "conan"),
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
package unknown
|
||||
|
||||
import (
|
||||
"regexp"
|
||||
|
||||
"github.com/anchore/syft/internal/log"
|
||||
"github.com/anchore/syft/syft/file"
|
||||
)
|
||||
|
||||
var pathErrorRegex = regexp.MustCompile(`.*path="([^"]+)".*`)
|
||||
|
||||
// ProcessPathErrors replaces "path" errors returned from the file.Resolver into unknowns,
|
||||
// and warn logs non-unknown errors, returning only the unknown errors
|
||||
func ProcessPathErrors(err error) error {
|
||||
if err == nil {
|
||||
return nil
|
||||
}
|
||||
errText := err.Error()
|
||||
if pathErrorRegex.MatchString(errText) {
|
||||
foundPath := pathErrorRegex.ReplaceAllString(err.Error(), "$1")
|
||||
if foundPath != "" {
|
||||
return New(file.NewLocation(foundPath), err)
|
||||
}
|
||||
}
|
||||
unknowns, remainingErrors := ExtractCoordinateErrors(err)
|
||||
log.Warn(remainingErrors)
|
||||
|
||||
var out []error
|
||||
for _, u := range unknowns {
|
||||
out = append(out, &u)
|
||||
}
|
||||
return Join(out...)
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
package unknown
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/anchore/syft/syft/file"
|
||||
)
|
||||
|
||||
func Test_ProcessPathErrors(t *testing.T) {
|
||||
tests := []struct {
|
||||
errorText string
|
||||
expected error
|
||||
}{
|
||||
{
|
||||
errorText: `prefix path="/var/lib/thing" suffix`,
|
||||
expected: &CoordinateError{
|
||||
Coordinates: file.Coordinates{
|
||||
RealPath: "/var/lib/thing",
|
||||
},
|
||||
Reason: fmt.Errorf(`prefix path="/var/lib/thing" suffix`),
|
||||
},
|
||||
},
|
||||
{
|
||||
errorText: `prefix path="/var/lib/thing"`,
|
||||
expected: &CoordinateError{
|
||||
Coordinates: file.Coordinates{
|
||||
RealPath: "/var/lib/thing",
|
||||
},
|
||||
Reason: fmt.Errorf(`prefix path="/var/lib/thing"`),
|
||||
},
|
||||
},
|
||||
{
|
||||
errorText: `path="/var/lib/thing" suffix`,
|
||||
expected: &CoordinateError{
|
||||
Coordinates: file.Coordinates{
|
||||
RealPath: "/var/lib/thing",
|
||||
},
|
||||
Reason: fmt.Errorf(`path="/var/lib/thing" suffix`),
|
||||
},
|
||||
},
|
||||
{
|
||||
errorText: "all your base are belong to us",
|
||||
expected: nil,
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run(test.errorText, func(t *testing.T) {
|
||||
got := ProcessPathErrors(fmt.Errorf("%s", test.errorText))
|
||||
require.Equal(t, test.expected, got)
|
||||
})
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "anchore.io/schema/syft/json/16.0.18/document",
|
||||
"$id": "anchore.io/schema/syft/json/16.0.19/document",
|
||||
"$ref": "#/$defs/Document",
|
||||
"$defs": {
|
||||
"AlpmDbEntry": {
|
||||
@@ -1610,6 +1610,9 @@
|
||||
"purl": {
|
||||
"type": "string"
|
||||
},
|
||||
"dependencies": {
|
||||
"type": "string"
|
||||
},
|
||||
"metadataType": {
|
||||
"type": "string"
|
||||
},
|
||||
@@ -1773,7 +1776,8 @@
|
||||
"licenses",
|
||||
"language",
|
||||
"cpes",
|
||||
"purl"
|
||||
"purl",
|
||||
"dependencies"
|
||||
]
|
||||
},
|
||||
"PhpComposerAuthors": {
|
||||
|
||||
@@ -121,7 +121,8 @@ func newDirectoryCatalog() *pkg.Collection {
|
||||
},
|
||||
},
|
||||
},
|
||||
PURL: "a-purl-2", // intentionally a bad pURL for test fixtures
|
||||
PURL: "a-purl-2", // intentionally a bad pURL for test fixtures
|
||||
Dependencies: pkg.CompleteDependencies,
|
||||
CPEs: []cpe.CPE{
|
||||
cpe.Must("cpe:2.3:*:some:package:2:*:*:*:*:*:*:*", cpe.Source("")),
|
||||
},
|
||||
@@ -138,7 +139,8 @@ func newDirectoryCatalog() *pkg.Collection {
|
||||
Package: "package-2",
|
||||
Version: "2.0.1",
|
||||
},
|
||||
PURL: "pkg:deb/debian/package-2@2.0.1",
|
||||
PURL: "pkg:deb/debian/package-2@2.0.1",
|
||||
Dependencies: pkg.CompleteDependencies,
|
||||
CPEs: []cpe.CPE{
|
||||
cpe.Must("cpe:2.3:*:some:package:2:*:*:*:*:*:*:*", cpe.Source("")),
|
||||
},
|
||||
@@ -163,6 +165,7 @@ func newDirectoryCatalogWithAuthorField() *pkg.Collection {
|
||||
Licenses: pkg.NewLicenseSet(
|
||||
pkg.NewLicense("MIT"),
|
||||
),
|
||||
Dependencies: pkg.CompleteDependencies,
|
||||
Metadata: pkg.PythonPackage{
|
||||
Name: "package-1",
|
||||
Version: "1.0.1",
|
||||
@@ -190,7 +193,8 @@ func newDirectoryCatalogWithAuthorField() *pkg.Collection {
|
||||
Package: "package-2",
|
||||
Version: "2.0.1",
|
||||
},
|
||||
PURL: "pkg:deb/debian/package-2@2.0.1",
|
||||
Dependencies: pkg.CompleteDependencies,
|
||||
PURL: "pkg:deb/debian/package-2@2.0.1",
|
||||
CPEs: []cpe.CPE{
|
||||
cpe.Must("cpe:2.3:*:some:package:2:*:*:*:*:*:*:*", "another-test-source"),
|
||||
},
|
||||
|
||||
@@ -117,7 +117,8 @@ func populateImageCatalog(catalog *pkg.Collection, img *image.Image) {
|
||||
Name: "package-1",
|
||||
Version: "1.0.1",
|
||||
},
|
||||
PURL: "a-purl-1", // intentionally a bad pURL for test fixtures
|
||||
PURL: "a-purl-1", // intentionally a bad pURL for test fixtures
|
||||
Dependencies: pkg.CompleteDependencies,
|
||||
CPEs: []cpe.CPE{
|
||||
cpe.Must("cpe:2.3:*:some:package:1:*:*:*:*:*:*:*", cpe.GeneratedSource),
|
||||
},
|
||||
@@ -137,7 +138,8 @@ func populateImageCatalog(catalog *pkg.Collection, img *image.Image) {
|
||||
Package: "package-2",
|
||||
Version: "2.0.1",
|
||||
},
|
||||
PURL: "pkg:deb/debian/package-2@2.0.1",
|
||||
PURL: "pkg:deb/debian/package-2@2.0.1",
|
||||
Dependencies: pkg.CompleteDependencies,
|
||||
CPEs: []cpe.CPE{
|
||||
cpe.Must("cpe:2.3:*:some:package:2:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
|
||||
},
|
||||
|
||||
@@ -141,10 +141,11 @@ func TestEncodeFullJSONDocument(t *testing.T) {
|
||||
RealPath: "/a/place/a",
|
||||
}),
|
||||
),
|
||||
Type: pkg.PythonPkg,
|
||||
FoundBy: "the-cataloger-1",
|
||||
Language: pkg.Python,
|
||||
Licenses: pkg.NewLicenseSet(pkg.NewLicense("MIT")),
|
||||
Type: pkg.PythonPkg,
|
||||
FoundBy: "the-cataloger-1",
|
||||
Language: pkg.Python,
|
||||
Licenses: pkg.NewLicenseSet(pkg.NewLicense("MIT")),
|
||||
Dependencies: pkg.CompleteDependencies,
|
||||
Metadata: pkg.PythonPackage{
|
||||
Name: "package-1",
|
||||
Version: "1.0.1",
|
||||
@@ -164,8 +165,9 @@ func TestEncodeFullJSONDocument(t *testing.T) {
|
||||
RealPath: "/b/place/b",
|
||||
}),
|
||||
),
|
||||
Type: pkg.DebPkg,
|
||||
FoundBy: "the-cataloger-2",
|
||||
Type: pkg.DebPkg,
|
||||
FoundBy: "the-cataloger-2",
|
||||
Dependencies: pkg.CompleteDependencies,
|
||||
Metadata: pkg.DpkgDBEntry{
|
||||
Package: "package-2",
|
||||
Version: "2.0.1",
|
||||
|
||||
@@ -24,16 +24,17 @@ type Package struct {
|
||||
|
||||
// PackageBasicData contains non-ambiguous values (type-wise) from pkg.Package.
|
||||
type PackageBasicData struct {
|
||||
ID string `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Version string `json:"version"`
|
||||
Type pkg.Type `json:"type"`
|
||||
FoundBy string `json:"foundBy"`
|
||||
Locations []file.Location `json:"locations"`
|
||||
Licenses licenses `json:"licenses"`
|
||||
Language pkg.Language `json:"language"`
|
||||
CPEs cpes `json:"cpes"`
|
||||
PURL string `json:"purl"`
|
||||
ID string `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Version string `json:"version"`
|
||||
Type pkg.Type `json:"type"`
|
||||
FoundBy string `json:"foundBy"`
|
||||
Locations []file.Location `json:"locations"`
|
||||
Licenses licenses `json:"licenses"`
|
||||
Language pkg.Language `json:"language"`
|
||||
CPEs cpes `json:"cpes"`
|
||||
PURL string `json:"purl"`
|
||||
Dependencies pkg.DependencyCompleteness `json:"dependencies"`
|
||||
}
|
||||
|
||||
type cpes []CPE
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
}
|
||||
],
|
||||
"purl": "a-purl-2",
|
||||
"dependencies": "complete",
|
||||
"metadataType": "python-package",
|
||||
"metadata": {
|
||||
"name": "package-1",
|
||||
@@ -63,6 +64,7 @@
|
||||
}
|
||||
],
|
||||
"purl": "pkg:deb/debian/package-2@2.0.1",
|
||||
"dependencies": "complete",
|
||||
"metadataType": "dpkg-db-entry",
|
||||
"metadata": {
|
||||
"package": "package-2",
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
}
|
||||
],
|
||||
"purl": "a-purl-1",
|
||||
"dependencies": "complete",
|
||||
"metadataType": "python-package",
|
||||
"metadata": {
|
||||
"name": "package-1",
|
||||
@@ -60,6 +61,7 @@
|
||||
}
|
||||
],
|
||||
"purl": "a-purl-2",
|
||||
"dependencies": "complete",
|
||||
"metadataType": "dpkg-db-entry",
|
||||
"metadata": {
|
||||
"package": "package-2",
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
}
|
||||
],
|
||||
"purl": "a-purl-1",
|
||||
"dependencies": "complete",
|
||||
"metadataType": "python-package",
|
||||
"metadata": {
|
||||
"name": "package-1",
|
||||
@@ -62,6 +63,7 @@
|
||||
}
|
||||
],
|
||||
"purl": "pkg:deb/debian/package-2@2.0.1",
|
||||
"dependencies": "complete",
|
||||
"metadataType": "dpkg-db-entry",
|
||||
"metadata": {
|
||||
"package": "package-2",
|
||||
|
||||
@@ -259,16 +259,17 @@ func toPackageModel(p pkg.Package, cfg EncoderConfig) model.Package {
|
||||
|
||||
return model.Package{
|
||||
PackageBasicData: model.PackageBasicData{
|
||||
ID: string(p.ID()),
|
||||
Name: p.Name,
|
||||
Version: p.Version,
|
||||
Type: p.Type,
|
||||
FoundBy: p.FoundBy,
|
||||
Locations: p.Locations.ToSlice(),
|
||||
Licenses: licenses,
|
||||
Language: p.Language,
|
||||
CPEs: cpes,
|
||||
PURL: p.PURL,
|
||||
ID: string(p.ID()),
|
||||
Name: p.Name,
|
||||
Version: p.Version,
|
||||
Type: p.Type,
|
||||
FoundBy: p.FoundBy,
|
||||
Locations: p.Locations.ToSlice(),
|
||||
Licenses: licenses,
|
||||
Language: p.Language,
|
||||
CPEs: cpes,
|
||||
PURL: p.PURL,
|
||||
Dependencies: p.Dependencies,
|
||||
},
|
||||
PackageCustomData: model.PackageCustomData{
|
||||
MetadataType: metadataType(p.Metadata, cfg.Legacy),
|
||||
|
||||
@@ -338,16 +338,17 @@ func toSyftPackage(p model.Package, idAliases map[string]string) pkg.Package {
|
||||
}
|
||||
|
||||
out := pkg.Package{
|
||||
Name: p.Name,
|
||||
Version: p.Version,
|
||||
FoundBy: p.FoundBy,
|
||||
Locations: file.NewLocationSet(p.Locations...),
|
||||
Licenses: pkg.NewLicenseSet(toSyftLicenses(p.Licenses)...),
|
||||
Language: p.Language,
|
||||
Type: p.Type,
|
||||
CPEs: cpes,
|
||||
PURL: p.PURL,
|
||||
Metadata: p.Metadata,
|
||||
Name: p.Name,
|
||||
Version: p.Version,
|
||||
FoundBy: p.FoundBy,
|
||||
Locations: file.NewLocationSet(p.Locations...),
|
||||
Licenses: pkg.NewLicenseSet(toSyftLicenses(p.Licenses)...),
|
||||
Language: p.Language,
|
||||
Type: p.Type,
|
||||
CPEs: cpes,
|
||||
PURL: p.PURL,
|
||||
Dependencies: p.Dependencies,
|
||||
Metadata: p.Metadata,
|
||||
}
|
||||
|
||||
// we don't know if this package ID is truly unique, however, we need to trust the user input in case there are
|
||||
|
||||
@@ -23,7 +23,8 @@ func TestApkDBCataloger(t *testing.T) {
|
||||
Licenses: pkg.NewLicenseSet(
|
||||
pkg.NewLicenseFromLocations("GPL-3.0-or-later", dbLocation),
|
||||
),
|
||||
Locations: file.NewLocationSet(dbLocation),
|
||||
Locations: file.NewLocationSet(dbLocation),
|
||||
Dependencies: pkg.CompleteDependencies,
|
||||
Metadata: pkg.ApkDBEntry{
|
||||
Package: "bash",
|
||||
OriginPackage: "bash",
|
||||
@@ -52,7 +53,8 @@ func TestApkDBCataloger(t *testing.T) {
|
||||
Licenses: pkg.NewLicenseSet(
|
||||
pkg.NewLicenseFromLocations("GPL-2.0-only", dbLocation),
|
||||
),
|
||||
Locations: file.NewLocationSet(dbLocation),
|
||||
Locations: file.NewLocationSet(dbLocation),
|
||||
Dependencies: pkg.CompleteDependencies,
|
||||
Metadata: pkg.ApkDBEntry{
|
||||
Package: "busybox-binsh",
|
||||
OriginPackage: "busybox",
|
||||
@@ -81,7 +83,8 @@ func TestApkDBCataloger(t *testing.T) {
|
||||
Licenses: pkg.NewLicenseSet(
|
||||
pkg.NewLicenseFromLocations("MIT", dbLocation),
|
||||
),
|
||||
Locations: file.NewLocationSet(dbLocation),
|
||||
Locations: file.NewLocationSet(dbLocation),
|
||||
Dependencies: pkg.CompleteDependencies,
|
||||
Metadata: pkg.ApkDBEntry{
|
||||
Package: "musl",
|
||||
OriginPackage: "musl",
|
||||
@@ -108,7 +111,8 @@ func TestApkDBCataloger(t *testing.T) {
|
||||
Licenses: pkg.NewLicenseSet(
|
||||
pkg.NewLicenseFromLocations("GPL-2.0-or-later", dbLocation),
|
||||
),
|
||||
Locations: file.NewLocationSet(dbLocation),
|
||||
Locations: file.NewLocationSet(dbLocation),
|
||||
Dependencies: pkg.CompleteDependencies,
|
||||
Metadata: pkg.ApkDBEntry{
|
||||
Package: "readline",
|
||||
OriginPackage: "readline",
|
||||
|
||||
@@ -20,13 +20,14 @@ func newPackage(d parsedData, release *linux.Release, dbLocation file.Location)
|
||||
}
|
||||
|
||||
p := pkg.Package{
|
||||
Name: d.Package,
|
||||
Version: d.Version,
|
||||
Locations: file.NewLocationSet(dbLocation.WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation)),
|
||||
Licenses: pkg.NewLicenseSet(pkg.NewLicensesFromLocation(dbLocation, licenseStrings...)...),
|
||||
PURL: packageURL(d.ApkDBEntry, release),
|
||||
Type: pkg.ApkPkg,
|
||||
Metadata: d.ApkDBEntry,
|
||||
Name: d.Package,
|
||||
Version: d.Version,
|
||||
Locations: file.NewLocationSet(dbLocation.WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation)),
|
||||
Licenses: pkg.NewLicenseSet(pkg.NewLicensesFromLocation(dbLocation, licenseStrings...)...),
|
||||
PURL: packageURL(d.ApkDBEntry, release),
|
||||
Type: pkg.ApkPkg,
|
||||
Dependencies: pkg.CompleteDependencies,
|
||||
Metadata: d.ApkDBEntry,
|
||||
}
|
||||
|
||||
p.SetID()
|
||||
|
||||
@@ -90,7 +90,8 @@ func TestSinglePackageDetails(t *testing.T) {
|
||||
pkg.NewLicense("BSD"),
|
||||
pkg.NewLicense("GPL2+"),
|
||||
),
|
||||
Type: pkg.ApkPkg,
|
||||
Type: pkg.ApkPkg,
|
||||
Dependencies: pkg.CompleteDependencies,
|
||||
Metadata: pkg.ApkDBEntry{
|
||||
Package: "musl-utils",
|
||||
OriginPackage: "musl",
|
||||
@@ -177,7 +178,8 @@ func TestSinglePackageDetails(t *testing.T) {
|
||||
Licenses: pkg.NewLicenseSet(
|
||||
pkg.NewLicense("GPL-2.0-only"),
|
||||
),
|
||||
Type: pkg.ApkPkg,
|
||||
Type: pkg.ApkPkg,
|
||||
Dependencies: pkg.CompleteDependencies,
|
||||
Metadata: pkg.ApkDBEntry{
|
||||
Package: "alpine-baselayout-data",
|
||||
OriginPackage: "alpine-baselayout",
|
||||
@@ -221,8 +223,8 @@ func TestSinglePackageDetails(t *testing.T) {
|
||||
Licenses: pkg.NewLicenseSet(
|
||||
pkg.NewLicense("GPL-2.0-only"),
|
||||
),
|
||||
Type: pkg.ApkPkg,
|
||||
PURL: "",
|
||||
Type: pkg.ApkPkg,
|
||||
Dependencies: pkg.CompleteDependencies,
|
||||
Metadata: pkg.ApkDBEntry{
|
||||
Package: "alpine-baselayout",
|
||||
OriginPackage: "alpine-baselayout",
|
||||
|
||||
@@ -34,7 +34,8 @@ func TestAlpmCataloger(t *testing.T) {
|
||||
Licenses: pkg.NewLicenseSet(
|
||||
pkg.NewLicenseFromLocations("MIT", treeSitterDbLocation),
|
||||
),
|
||||
Locations: file.NewLocationSet(treeSitterDbLocation),
|
||||
Locations: file.NewLocationSet(treeSitterDbLocation),
|
||||
Dependencies: pkg.CompleteDependencies,
|
||||
Metadata: pkg.AlpmDBEntry{
|
||||
BasePackage: "tree-sitter",
|
||||
Package: "tree-sitter",
|
||||
@@ -60,7 +61,8 @@ func TestAlpmCataloger(t *testing.T) {
|
||||
Licenses: pkg.NewLicenseSet(
|
||||
pkg.NewLicenseFromLocations("GPL3", emacsDbLocation),
|
||||
),
|
||||
Locations: file.NewLocationSet(emacsDbLocation),
|
||||
Locations: file.NewLocationSet(emacsDbLocation),
|
||||
Dependencies: pkg.CompleteDependencies,
|
||||
Metadata: pkg.AlpmDBEntry{
|
||||
BasePackage: "emacs",
|
||||
Package: "emacs",
|
||||
@@ -86,6 +88,7 @@ func TestAlpmCataloger(t *testing.T) {
|
||||
fuzzyDbLocation,
|
||||
file.NewLocation("var/lib/pacman/local/fuzzy-1.2-3/files"),
|
||||
),
|
||||
Dependencies: pkg.CompleteDependencies,
|
||||
Metadata: pkg.AlpmDBEntry{
|
||||
Package: "fuzzy",
|
||||
Version: "1.2-3",
|
||||
@@ -103,11 +106,12 @@ func TestAlpmCataloger(t *testing.T) {
|
||||
}
|
||||
|
||||
madeupPkg := pkg.Package{
|
||||
Name: "madeup",
|
||||
Version: "20.30-4",
|
||||
Type: pkg.AlpmPkg,
|
||||
FoundBy: "alpm-db-cataloger",
|
||||
Locations: file.NewLocationSet(madeupDbLocation),
|
||||
Name: "madeup",
|
||||
Version: "20.30-4",
|
||||
Type: pkg.AlpmPkg,
|
||||
FoundBy: "alpm-db-cataloger",
|
||||
Locations: file.NewLocationSet(madeupDbLocation),
|
||||
Dependencies: pkg.CompleteDependencies,
|
||||
Metadata: pkg.AlpmDBEntry{
|
||||
Package: "madeup",
|
||||
Version: "20.30-4",
|
||||
@@ -131,6 +135,7 @@ func TestAlpmCataloger(t *testing.T) {
|
||||
file.NewLocation("var/lib/pacman/local/gmp-6.2.1-2/files"),
|
||||
file.NewLocation("var/lib/pacman/local/gmp-6.2.1-2/mtree"),
|
||||
),
|
||||
Dependencies: pkg.CompleteDependencies,
|
||||
Metadata: pkg.AlpmDBEntry{
|
||||
BasePackage: "gmp",
|
||||
Package: "gmp",
|
||||
|
||||
@@ -16,13 +16,14 @@ func newPackage(m *parsedData, release *linux.Release, dbLocation file.Location,
|
||||
locs.Add(otherLocations...)
|
||||
|
||||
p := pkg.Package{
|
||||
Name: m.Package,
|
||||
Version: m.Version,
|
||||
Locations: locs,
|
||||
Licenses: pkg.NewLicenseSet(pkg.NewLicensesFromLocation(dbLocation.WithoutAnnotations(), licenseCandidates...)...),
|
||||
Type: pkg.AlpmPkg,
|
||||
PURL: packageURL(m, release),
|
||||
Metadata: m.AlpmDBEntry,
|
||||
Name: m.Package,
|
||||
Version: m.Version,
|
||||
Locations: locs,
|
||||
Licenses: pkg.NewLicenseSet(pkg.NewLicensesFromLocation(dbLocation.WithoutAnnotations(), licenseCandidates...)...),
|
||||
Type: pkg.AlpmPkg,
|
||||
PURL: packageURL(m, release),
|
||||
Dependencies: pkg.CompleteDependencies,
|
||||
Metadata: m.AlpmDBEntry,
|
||||
}
|
||||
p.SetID()
|
||||
|
||||
|
||||
@@ -105,6 +105,7 @@ func catalog(resolver file.Resolver, cls Classifier) (packages []pkg.Package, er
|
||||
var errs error
|
||||
locations, err := resolver.FilesByGlob(cls.FileGlob)
|
||||
if err != nil {
|
||||
err = unknown.ProcessPathErrors(err) // convert any file.Resolver path errors to unknowns with locations
|
||||
return nil, err
|
||||
}
|
||||
for _, location := range locations {
|
||||
|
||||
@@ -1668,7 +1668,7 @@ func Test_Cataloger_ResilientToErrors(t *testing.T) {
|
||||
|
||||
resolver := &panicyResolver{}
|
||||
_, _, err := c.Catalog(context.Background(), resolver)
|
||||
assert.Error(t, err)
|
||||
assert.Nil(t, err) // non-coordinate-based FindBy* errors are now logged and not returned
|
||||
assert.True(t, resolver.searchCalled)
|
||||
}
|
||||
|
||||
|
||||
@@ -35,6 +35,9 @@ func newClassifierPackage(classifier Classifier, location file.Location, matchMe
|
||||
Type: pkg.BinaryPkg,
|
||||
CPEs: cpes,
|
||||
FoundBy: catalogerName,
|
||||
// classifiers are limited to identifying package identities, but have no information about dependencies.
|
||||
// Furthermore, we have no understanding about the mechanisms for dependency resolution for these packages.
|
||||
Dependencies: pkg.UnknownDependencyCompleteness,
|
||||
Metadata: pkg.BinarySignature{
|
||||
Matches: []pkg.ClassifierMatch{
|
||||
{
|
||||
|
||||
@@ -158,7 +158,7 @@ func DefaultClassifiers() []Classifier {
|
||||
// [NUL]v0.12.18[NUL]
|
||||
// [NUL]v4.9.1[NUL]
|
||||
// node.js/v22.9.0
|
||||
FileContentsVersionMatcher(`(?m)\x00(node )?v(?P<version>(0|4|5)\.[0-9]+\.[0-9]+)\x00`),
|
||||
FileContentsVersionMatcher(`(?m)\x00(node )?v(?P<version>(0|4|5|6)\.[0-9]+\.[0-9]+)\x00`),
|
||||
FileContentsVersionMatcher(`(?m)node\.js\/v(?P<version>[0-9]+\.[0-9]+\.[0-9]+)`),
|
||||
),
|
||||
Package: "node",
|
||||
|
||||
@@ -16,7 +16,10 @@ func newELFPackage(metadata elfBinaryPackageNotes, locations file.LocationSet) p
|
||||
PURL: packageURL(metadata),
|
||||
Type: pkgType(metadata.Type),
|
||||
Locations: locations,
|
||||
Metadata: metadata.ELFBinaryPackageNoteJSONPayload,
|
||||
// though we can look for shared libs, we cannot see static dependencies nor dynamic dependencies using dlopen.
|
||||
// this means that, even in cases where the dep info is actually complete, we can't programmatically determine that.
|
||||
Dependencies: pkg.UnknownDependencyCompleteness,
|
||||
Metadata: metadata.ELFBinaryPackageNoteJSONPayload,
|
||||
}
|
||||
|
||||
p.SetID()
|
||||
|
||||
@@ -35,7 +35,8 @@ func Test_ELF_Package_Cataloger(t *testing.T) {
|
||||
pkg.License{Value: "MIT", SPDXExpression: "MIT", Type: "declared"},
|
||||
),
|
||||
|
||||
Type: pkg.BinaryPkg,
|
||||
Type: pkg.BinaryPkg,
|
||||
Dependencies: pkg.UnknownDependencyCompleteness,
|
||||
Metadata: pkg.ELFBinaryPackageNoteJSONPayload{
|
||||
Type: "testfixture",
|
||||
Vendor: "syft",
|
||||
@@ -56,7 +57,8 @@ func Test_ELF_Package_Cataloger(t *testing.T) {
|
||||
Licenses: pkg.NewLicenseSet(
|
||||
pkg.License{Value: "MIT", SPDXExpression: "MIT", Type: "declared"},
|
||||
),
|
||||
Type: pkg.BinaryPkg,
|
||||
Type: pkg.BinaryPkg,
|
||||
Dependencies: pkg.UnknownDependencyCompleteness,
|
||||
Metadata: pkg.ELFBinaryPackageNoteJSONPayload{
|
||||
Type: "testfixture",
|
||||
Vendor: "syft",
|
||||
@@ -80,8 +82,9 @@ func Test_ELF_Package_Cataloger(t *testing.T) {
|
||||
file.NewLocation("/sha256sum").WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation),
|
||||
file.NewLocation("/sha1sum").WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation),
|
||||
),
|
||||
Licenses: pkg.NewLicenseSet(),
|
||||
Type: pkg.RpmPkg,
|
||||
Licenses: pkg.NewLicenseSet(),
|
||||
Type: pkg.RpmPkg,
|
||||
Dependencies: pkg.UnknownDependencyCompleteness,
|
||||
Metadata: pkg.ELFBinaryPackageNoteJSONPayload{
|
||||
Type: "rpm",
|
||||
Architecture: "x86_64",
|
||||
@@ -102,8 +105,9 @@ func Test_ELF_Package_Cataloger(t *testing.T) {
|
||||
file.NewLocation("/sha256sum").WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation),
|
||||
file.NewLocation("/sha1sum").WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation),
|
||||
),
|
||||
Licenses: pkg.NewLicenseSet(),
|
||||
Type: pkg.RpmPkg,
|
||||
Licenses: pkg.NewLicenseSet(),
|
||||
Type: pkg.RpmPkg,
|
||||
Dependencies: pkg.UnknownDependencyCompleteness,
|
||||
Metadata: pkg.ELFBinaryPackageNoteJSONPayload{
|
||||
Type: "rpm",
|
||||
Architecture: "arm",
|
||||
|
||||
@@ -154,10 +154,11 @@ func Test_newELFPackage(t *testing.T) {
|
||||
},
|
||||
|
||||
expected: pkg.Package{
|
||||
Name: "syfttestfixture",
|
||||
Version: "0.01",
|
||||
Type: "binary",
|
||||
PURL: "pkg:generic/syftsys/syfttestfixture@0.01",
|
||||
Name: "syfttestfixture",
|
||||
Version: "0.01",
|
||||
Type: "binary",
|
||||
PURL: "pkg:generic/syftsys/syfttestfixture@0.01",
|
||||
Dependencies: pkg.UnknownDependencyCompleteness,
|
||||
Metadata: pkg.ELFBinaryPackageNoteJSONPayload{
|
||||
Type: "binary",
|
||||
System: "syftsys",
|
||||
|
||||
@@ -67,35 +67,43 @@ func splitConanRef(ref string) *conanRef {
|
||||
}
|
||||
|
||||
func newConanfilePackage(m pkg.ConanfileEntry, locations ...file.Location) *pkg.Package {
|
||||
return newConanPackage(m.Ref, m, locations...)
|
||||
// though a conanfile is a listing of direct dependencies, we are not capturing these today, so are forced to answer unknown
|
||||
return newConanPackage(m.Ref, m, pkg.UnknownDependencyCompleteness, locations...)
|
||||
}
|
||||
|
||||
func newConanlockPackage(m pkg.ConanV1LockEntry, locations ...file.Location) *pkg.Package {
|
||||
return newConanPackage(m.Ref, m, locations...)
|
||||
func newConanlockV1Package(m pkg.ConanV1LockEntry, locations ...file.Location) *pkg.Package {
|
||||
// conan.lock is primarily used to lock the dependency graph at specific versions to ensure consistent builds,
|
||||
// and the dependency tree can be inferred from the contents (distinguishing between direct and transitive dependencies)
|
||||
return newConanPackage(m.Ref, m, pkg.CompleteDependencies, locations...)
|
||||
}
|
||||
|
||||
func newConanReferencePackage(m pkg.ConanV2LockEntry, locations ...file.Location) *pkg.Package {
|
||||
return newConanPackage(m.Ref, m, locations...)
|
||||
func newConanLockv2Package(m pkg.ConanV2LockEntry, locations ...file.Location) *pkg.Package {
|
||||
// conan.lock is primarily used to lock the dependency graph at specific versions to ensure consistent builds,
|
||||
// and the dependency tree can be inferred from the contents (distinguishing between direct and transitive dependencies)
|
||||
return newConanPackage(m.Ref, m, pkg.CompleteDependencies, locations...)
|
||||
}
|
||||
|
||||
func newConaninfoPackage(m pkg.ConaninfoEntry, locations ...file.Location) *pkg.Package {
|
||||
return newConanPackage(m.Ref, m, locations...)
|
||||
// conaninfo.txt is generated during the build and contains detailed information about the entire dependency tree,
|
||||
// and today the codebase does infer direct dependencies from this source
|
||||
return newConanPackage(m.Ref, m, pkg.CompleteDependencies, locations...)
|
||||
}
|
||||
|
||||
func newConanPackage(refStr string, metadata any, locations ...file.Location) *pkg.Package {
|
||||
func newConanPackage(refStr string, metadata any, dep pkg.DependencyCompleteness, locations ...file.Location) *pkg.Package {
|
||||
ref := splitConanRef(refStr)
|
||||
if ref == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
p := pkg.Package{
|
||||
Name: ref.Name,
|
||||
Version: ref.Version,
|
||||
Locations: file.NewLocationSet(locations...),
|
||||
PURL: packageURL(ref),
|
||||
Language: pkg.CPP,
|
||||
Type: pkg.ConanPkg,
|
||||
Metadata: metadata,
|
||||
Name: ref.Name,
|
||||
Version: ref.Version,
|
||||
Locations: file.NewLocationSet(locations...),
|
||||
PURL: packageURL(ref),
|
||||
Language: pkg.CPP,
|
||||
Type: pkg.ConanPkg,
|
||||
Dependencies: dep,
|
||||
Metadata: metadata,
|
||||
}
|
||||
|
||||
p.SetID()
|
||||
|
||||
@@ -22,11 +22,12 @@ func parseConanfile(_ context.Context, _ file.Resolver, _ *generic.Environment,
|
||||
r := bufio.NewReader(reader)
|
||||
inRequirements := false
|
||||
var pkgs []pkg.Package
|
||||
loop:
|
||||
for {
|
||||
line, err := r.ReadString('\n')
|
||||
switch {
|
||||
case errors.Is(err, io.EOF):
|
||||
return pkgs, nil, unknown.IfEmptyf(pkgs, "unable to determine packages")
|
||||
break loop
|
||||
case err != nil:
|
||||
return nil, nil, fmt.Errorf("failed to parse conanfile.txt file: %w", err)
|
||||
}
|
||||
@@ -56,4 +57,5 @@ func parseConanfile(_ context.Context, _ file.Resolver, _ *generic.Environment,
|
||||
|
||||
pkgs = append(pkgs, *p)
|
||||
}
|
||||
return pkgs, nil, unknown.IfEmptyf(pkgs, "unable to determine packages")
|
||||
}
|
||||
|
||||
@@ -14,67 +14,73 @@ func TestParseConanfile(t *testing.T) {
|
||||
fixtureLocationSet := file.NewLocationSet(file.NewLocation(fixture))
|
||||
expected := []pkg.Package{
|
||||
{
|
||||
Name: "catch2",
|
||||
Version: "2.13.8",
|
||||
PURL: "pkg:conan/catch2@2.13.8",
|
||||
Locations: fixtureLocationSet,
|
||||
Language: pkg.CPP,
|
||||
Type: pkg.ConanPkg,
|
||||
Name: "catch2",
|
||||
Version: "2.13.8",
|
||||
PURL: "pkg:conan/catch2@2.13.8",
|
||||
Locations: fixtureLocationSet,
|
||||
Language: pkg.CPP,
|
||||
Type: pkg.ConanPkg,
|
||||
Dependencies: pkg.UnknownDependencyCompleteness,
|
||||
Metadata: pkg.ConanfileEntry{
|
||||
Ref: "catch2/2.13.8",
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "docopt.cpp",
|
||||
Version: "0.6.3",
|
||||
PURL: "pkg:conan/docopt.cpp@0.6.3",
|
||||
Locations: fixtureLocationSet,
|
||||
Language: pkg.CPP,
|
||||
Type: pkg.ConanPkg,
|
||||
Name: "docopt.cpp",
|
||||
Version: "0.6.3",
|
||||
PURL: "pkg:conan/docopt.cpp@0.6.3",
|
||||
Locations: fixtureLocationSet,
|
||||
Language: pkg.CPP,
|
||||
Type: pkg.ConanPkg,
|
||||
Dependencies: pkg.UnknownDependencyCompleteness,
|
||||
Metadata: pkg.ConanfileEntry{
|
||||
Ref: "docopt.cpp/0.6.3",
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "fmt",
|
||||
Version: "8.1.1",
|
||||
PURL: "pkg:conan/fmt@8.1.1",
|
||||
Locations: fixtureLocationSet,
|
||||
Language: pkg.CPP,
|
||||
Type: pkg.ConanPkg,
|
||||
Name: "fmt",
|
||||
Version: "8.1.1",
|
||||
PURL: "pkg:conan/fmt@8.1.1",
|
||||
Locations: fixtureLocationSet,
|
||||
Language: pkg.CPP,
|
||||
Type: pkg.ConanPkg,
|
||||
Dependencies: pkg.UnknownDependencyCompleteness,
|
||||
Metadata: pkg.ConanfileEntry{
|
||||
Ref: "fmt/8.1.1",
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "spdlog",
|
||||
Version: "1.9.2",
|
||||
PURL: "pkg:conan/my_user/spdlog@1.9.2?channel=my_channel",
|
||||
Locations: fixtureLocationSet,
|
||||
Language: pkg.CPP,
|
||||
Type: pkg.ConanPkg,
|
||||
Name: "spdlog",
|
||||
Version: "1.9.2",
|
||||
PURL: "pkg:conan/my_user/spdlog@1.9.2?channel=my_channel",
|
||||
Locations: fixtureLocationSet,
|
||||
Language: pkg.CPP,
|
||||
Type: pkg.ConanPkg,
|
||||
Dependencies: pkg.UnknownDependencyCompleteness,
|
||||
Metadata: pkg.ConanfileEntry{
|
||||
Ref: "spdlog/1.9.2@my_user/my_channel#1234567%%987654",
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "sdl",
|
||||
Version: "2.0.20",
|
||||
PURL: "pkg:conan/sdl@2.0.20",
|
||||
Locations: fixtureLocationSet,
|
||||
Language: pkg.CPP,
|
||||
Type: pkg.ConanPkg,
|
||||
Name: "sdl",
|
||||
Version: "2.0.20",
|
||||
PURL: "pkg:conan/sdl@2.0.20",
|
||||
Locations: fixtureLocationSet,
|
||||
Language: pkg.CPP,
|
||||
Type: pkg.ConanPkg,
|
||||
Dependencies: pkg.UnknownDependencyCompleteness,
|
||||
Metadata: pkg.ConanfileEntry{
|
||||
Ref: "sdl/2.0.20#1234567%%987654",
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "fltk",
|
||||
Version: "1.3.8",
|
||||
PURL: "pkg:conan/my_user/fltk@1.3.8?channel=my_channel",
|
||||
Locations: fixtureLocationSet,
|
||||
Language: pkg.CPP,
|
||||
Type: pkg.ConanPkg,
|
||||
Name: "fltk",
|
||||
Version: "1.3.8",
|
||||
PURL: "pkg:conan/my_user/fltk@1.3.8?channel=my_channel",
|
||||
Locations: fixtureLocationSet,
|
||||
Language: pkg.CPP,
|
||||
Type: pkg.ConanPkg,
|
||||
Dependencies: pkg.UnknownDependencyCompleteness,
|
||||
Metadata: pkg.ConanfileEntry{
|
||||
Ref: "fltk/1.3.8@my_user/my_channel",
|
||||
},
|
||||
|
||||
@@ -13,72 +13,78 @@ func TestParseConaninfo(t *testing.T) {
|
||||
fixture := "test-fixtures/conaninfo/mfast/1.2.2/my_user/my_channel/package/9d1f076b471417647c2022a78d5e2c1f834289ac/conaninfo.txt"
|
||||
expected := []pkg.Package{
|
||||
{
|
||||
Name: "mfast",
|
||||
Version: "1.2.2",
|
||||
PURL: "pkg:conan/my_user/mfast@1.2.2?channel=my_channel",
|
||||
Locations: file.NewLocationSet(file.NewLocation(fixture)),
|
||||
Language: pkg.CPP,
|
||||
Type: pkg.ConanPkg,
|
||||
Name: "mfast",
|
||||
Version: "1.2.2",
|
||||
PURL: "pkg:conan/my_user/mfast@1.2.2?channel=my_channel",
|
||||
Locations: file.NewLocationSet(file.NewLocation(fixture)),
|
||||
Language: pkg.CPP,
|
||||
Type: pkg.ConanPkg,
|
||||
Dependencies: pkg.CompleteDependencies,
|
||||
Metadata: pkg.ConaninfoEntry{
|
||||
Ref: "mfast/1.2.2@my_user/my_channel#c6f6387c9b99780f0ee05e25f99d0f39",
|
||||
PackageID: "9d1f076b471417647c2022a78d5e2c1f834289ac",
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "boost",
|
||||
Version: "1.75.0",
|
||||
PURL: "pkg:conan/boost@1.75.0",
|
||||
Locations: file.NewLocationSet(file.NewLocation(fixture)),
|
||||
Language: pkg.CPP,
|
||||
Type: pkg.ConanPkg,
|
||||
Name: "boost",
|
||||
Version: "1.75.0",
|
||||
PURL: "pkg:conan/boost@1.75.0",
|
||||
Locations: file.NewLocationSet(file.NewLocation(fixture)),
|
||||
Language: pkg.CPP,
|
||||
Type: pkg.ConanPkg,
|
||||
Dependencies: pkg.CompleteDependencies,
|
||||
Metadata: pkg.ConaninfoEntry{
|
||||
Ref: "boost/1.75.0:dc8aedd23a0f0a773a5fcdcfe1ae3e89c4205978",
|
||||
PackageID: "dc8aedd23a0f0a773a5fcdcfe1ae3e89c4205978",
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "zlib",
|
||||
Version: "1.2.13",
|
||||
PURL: "pkg:conan/zlib@1.2.13",
|
||||
Locations: file.NewLocationSet(file.NewLocation(fixture)),
|
||||
Language: pkg.CPP,
|
||||
Type: pkg.ConanPkg,
|
||||
Name: "zlib",
|
||||
Version: "1.2.13",
|
||||
PURL: "pkg:conan/zlib@1.2.13",
|
||||
Locations: file.NewLocationSet(file.NewLocation(fixture)),
|
||||
Language: pkg.CPP,
|
||||
Type: pkg.ConanPkg,
|
||||
Dependencies: pkg.CompleteDependencies,
|
||||
Metadata: pkg.ConaninfoEntry{
|
||||
Ref: "zlib/1.2.13:dfbe50feef7f3c6223a476cd5aeadb687084a646",
|
||||
PackageID: "dfbe50feef7f3c6223a476cd5aeadb687084a646",
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "bzip2",
|
||||
Version: "1.0.8",
|
||||
PURL: "pkg:conan/bzip2@1.0.8",
|
||||
Locations: file.NewLocationSet(file.NewLocation(fixture)),
|
||||
Language: pkg.CPP,
|
||||
Type: pkg.ConanPkg,
|
||||
Name: "bzip2",
|
||||
Version: "1.0.8",
|
||||
PURL: "pkg:conan/bzip2@1.0.8",
|
||||
Locations: file.NewLocationSet(file.NewLocation(fixture)),
|
||||
Language: pkg.CPP,
|
||||
Type: pkg.ConanPkg,
|
||||
Dependencies: pkg.CompleteDependencies,
|
||||
Metadata: pkg.ConaninfoEntry{
|
||||
Ref: "bzip2/1.0.8:c32092bf4d4bb47cf962af898e02823f499b017e",
|
||||
PackageID: "c32092bf4d4bb47cf962af898e02823f499b017e",
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "libbacktrace",
|
||||
Version: "cci.20210118",
|
||||
PURL: "pkg:conan/libbacktrace@cci.20210118",
|
||||
Locations: file.NewLocationSet(file.NewLocation(fixture)),
|
||||
Language: pkg.CPP,
|
||||
Type: pkg.ConanPkg,
|
||||
Name: "libbacktrace",
|
||||
Version: "cci.20210118",
|
||||
PURL: "pkg:conan/libbacktrace@cci.20210118",
|
||||
Locations: file.NewLocationSet(file.NewLocation(fixture)),
|
||||
Language: pkg.CPP,
|
||||
Type: pkg.ConanPkg,
|
||||
Dependencies: pkg.CompleteDependencies,
|
||||
Metadata: pkg.ConaninfoEntry{
|
||||
Ref: "libbacktrace/cci.20210118:dfbe50feef7f3c6223a476cd5aeadb687084a646",
|
||||
PackageID: "dfbe50feef7f3c6223a476cd5aeadb687084a646",
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "tinyxml2",
|
||||
Version: "9.0.0",
|
||||
PURL: "pkg:conan/tinyxml2@9.0.0",
|
||||
Locations: file.NewLocationSet(file.NewLocation(fixture)),
|
||||
Language: pkg.CPP,
|
||||
Type: pkg.ConanPkg,
|
||||
Name: "tinyxml2",
|
||||
Version: "9.0.0",
|
||||
PURL: "pkg:conan/tinyxml2@9.0.0",
|
||||
Locations: file.NewLocationSet(file.NewLocation(fixture)),
|
||||
Language: pkg.CPP,
|
||||
Type: pkg.ConanPkg,
|
||||
Dependencies: pkg.CompleteDependencies,
|
||||
Metadata: pkg.ConaninfoEntry{
|
||||
Ref: "tinyxml2/9.0.0:6557f18ca99c0b6a233f43db00e30efaa525e27e",
|
||||
PackageID: "6557f18ca99c0b6a233f43db00e30efaa525e27e",
|
||||
|
||||
@@ -89,7 +89,7 @@ func handleConanLockV1(cl conanLock, reader file.LocationReadCloser, parsedPkgRe
|
||||
Prev: node.Prev,
|
||||
}
|
||||
|
||||
p := newConanlockPackage(
|
||||
p := newConanlockV1Package(
|
||||
metadata,
|
||||
reader.Location.WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation),
|
||||
)
|
||||
@@ -113,7 +113,7 @@ func handleConanLockV2(cl conanLock, reader file.LocationReadCloser, indexToPkgM
|
||||
continue
|
||||
}
|
||||
|
||||
p := newConanReferencePackage(
|
||||
p := newConanLockv2Package(
|
||||
reference,
|
||||
reader.Location.WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation),
|
||||
)
|
||||
|
||||
@@ -13,12 +13,13 @@ func TestParseConanLock(t *testing.T) {
|
||||
fixture := "test-fixtures/conan.lock"
|
||||
expected := []pkg.Package{
|
||||
{
|
||||
Name: "mfast",
|
||||
Version: "1.2.2",
|
||||
PURL: "pkg:conan/my_user/mfast@1.2.2?channel=my_channel",
|
||||
Locations: file.NewLocationSet(file.NewLocation(fixture)),
|
||||
Language: pkg.CPP,
|
||||
Type: pkg.ConanPkg,
|
||||
Name: "mfast",
|
||||
Version: "1.2.2",
|
||||
PURL: "pkg:conan/my_user/mfast@1.2.2?channel=my_channel",
|
||||
Locations: file.NewLocationSet(file.NewLocation(fixture)),
|
||||
Language: pkg.CPP,
|
||||
Type: pkg.ConanPkg,
|
||||
Dependencies: pkg.CompleteDependencies,
|
||||
Metadata: pkg.ConanV1LockEntry{
|
||||
Ref: "mfast/1.2.2@my_user/my_channel#c6f6387c9b99780f0ee05e25f99d0f39",
|
||||
Options: pkg.KeyValues{
|
||||
@@ -104,12 +105,13 @@ func TestParseConanLock(t *testing.T) {
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "boost",
|
||||
Version: "1.75.0",
|
||||
PURL: "pkg:conan/boost@1.75.0",
|
||||
Locations: file.NewLocationSet(file.NewLocation(fixture)),
|
||||
Language: pkg.CPP,
|
||||
Type: pkg.ConanPkg,
|
||||
Name: "boost",
|
||||
Version: "1.75.0",
|
||||
PURL: "pkg:conan/boost@1.75.0",
|
||||
Locations: file.NewLocationSet(file.NewLocation(fixture)),
|
||||
Language: pkg.CPP,
|
||||
Type: pkg.ConanPkg,
|
||||
Dependencies: pkg.CompleteDependencies,
|
||||
Metadata: pkg.ConanV1LockEntry{
|
||||
Ref: "boost/1.75.0#a9c318f067216f900900e044e7af4ab1",
|
||||
Options: pkg.KeyValues{
|
||||
@@ -190,12 +192,13 @@ func TestParseConanLock(t *testing.T) {
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "zlib",
|
||||
Version: "1.2.12",
|
||||
PURL: "pkg:conan/zlib@1.2.12",
|
||||
Locations: file.NewLocationSet(file.NewLocation(fixture)),
|
||||
Language: pkg.CPP,
|
||||
Type: pkg.ConanPkg,
|
||||
Name: "zlib",
|
||||
Version: "1.2.12",
|
||||
PURL: "pkg:conan/zlib@1.2.12",
|
||||
Locations: file.NewLocationSet(file.NewLocation(fixture)),
|
||||
Language: pkg.CPP,
|
||||
Type: pkg.ConanPkg,
|
||||
Dependencies: pkg.CompleteDependencies,
|
||||
Metadata: pkg.ConanV1LockEntry{
|
||||
Ref: "zlib/1.2.12#c67ce17f2e96b972d42393ce50a76a1a",
|
||||
Options: pkg.KeyValues{
|
||||
@@ -214,12 +217,13 @@ func TestParseConanLock(t *testing.T) {
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "bzip2",
|
||||
Version: "1.0.8",
|
||||
PURL: "pkg:conan/bzip2@1.0.8",
|
||||
Locations: file.NewLocationSet(file.NewLocation(fixture)),
|
||||
Language: pkg.CPP,
|
||||
Type: pkg.ConanPkg,
|
||||
Name: "bzip2",
|
||||
Version: "1.0.8",
|
||||
PURL: "pkg:conan/bzip2@1.0.8",
|
||||
Locations: file.NewLocationSet(file.NewLocation(fixture)),
|
||||
Language: pkg.CPP,
|
||||
Type: pkg.ConanPkg,
|
||||
Dependencies: pkg.CompleteDependencies,
|
||||
Metadata: pkg.ConanV1LockEntry{
|
||||
Ref: "bzip2/1.0.8#62a8031289639043797cf53fa876d0ef",
|
||||
Options: []pkg.KeyValue{
|
||||
@@ -242,12 +246,13 @@ func TestParseConanLock(t *testing.T) {
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "libbacktrace",
|
||||
Version: "cci.20210118",
|
||||
PURL: "pkg:conan/libbacktrace@cci.20210118",
|
||||
Locations: file.NewLocationSet(file.NewLocation(fixture)),
|
||||
Language: pkg.CPP,
|
||||
Type: pkg.ConanPkg,
|
||||
Name: "libbacktrace",
|
||||
Version: "cci.20210118",
|
||||
PURL: "pkg:conan/libbacktrace@cci.20210118",
|
||||
Locations: file.NewLocationSet(file.NewLocation(fixture)),
|
||||
Language: pkg.CPP,
|
||||
Type: pkg.ConanPkg,
|
||||
Dependencies: pkg.CompleteDependencies,
|
||||
Metadata: pkg.ConanV1LockEntry{
|
||||
Ref: "libbacktrace/cci.20210118#76e40b760e0bcd602d46db56b22820ab",
|
||||
Options: []pkg.KeyValue{
|
||||
@@ -266,12 +271,13 @@ func TestParseConanLock(t *testing.T) {
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "tinyxml2",
|
||||
Version: "9.0.0",
|
||||
PURL: "pkg:conan/tinyxml2@9.0.0",
|
||||
Locations: file.NewLocationSet(file.NewLocation(fixture)),
|
||||
Language: pkg.CPP,
|
||||
Type: pkg.ConanPkg,
|
||||
Name: "tinyxml2",
|
||||
Version: "9.0.0",
|
||||
PURL: "pkg:conan/tinyxml2@9.0.0",
|
||||
Locations: file.NewLocationSet(file.NewLocation(fixture)),
|
||||
Language: pkg.CPP,
|
||||
Type: pkg.ConanPkg,
|
||||
Dependencies: pkg.CompleteDependencies,
|
||||
Metadata: pkg.ConanV1LockEntry{
|
||||
Ref: "tinyxml2/9.0.0#9f13a36ebfc222cd55fe531a0a8d94d1",
|
||||
Options: []pkg.KeyValue{
|
||||
@@ -337,12 +343,13 @@ func TestParseConanLockV2(t *testing.T) {
|
||||
fixture := "test-fixtures/conanlock-v2/conan.lock"
|
||||
expected := []pkg.Package{
|
||||
{
|
||||
Name: "matrix",
|
||||
Version: "1.1",
|
||||
PURL: "pkg:conan/matrix@1.1",
|
||||
Locations: file.NewLocationSet(file.NewLocation(fixture)),
|
||||
Language: pkg.CPP,
|
||||
Type: pkg.ConanPkg,
|
||||
Name: "matrix",
|
||||
Version: "1.1",
|
||||
PURL: "pkg:conan/matrix@1.1",
|
||||
Locations: file.NewLocationSet(file.NewLocation(fixture)),
|
||||
Language: pkg.CPP,
|
||||
Type: pkg.ConanPkg,
|
||||
Dependencies: pkg.CompleteDependencies,
|
||||
Metadata: pkg.ConanV2LockEntry{
|
||||
Ref: "matrix/1.1#905c3f0babc520684c84127378fefdd0%1675278901.7527816",
|
||||
RecipeRevision: "905c3f0babc520684c84127378fefdd0",
|
||||
@@ -350,12 +357,13 @@ func TestParseConanLockV2(t *testing.T) {
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "sound32",
|
||||
Version: "1.0",
|
||||
PURL: "pkg:conan/sound32@1.0",
|
||||
Locations: file.NewLocationSet(file.NewLocation(fixture)),
|
||||
Language: pkg.CPP,
|
||||
Type: pkg.ConanPkg,
|
||||
Name: "sound32",
|
||||
Version: "1.0",
|
||||
PURL: "pkg:conan/sound32@1.0",
|
||||
Locations: file.NewLocationSet(file.NewLocation(fixture)),
|
||||
Language: pkg.CPP,
|
||||
Type: pkg.ConanPkg,
|
||||
Dependencies: pkg.CompleteDependencies,
|
||||
Metadata: pkg.ConanV2LockEntry{
|
||||
Ref: "sound32/1.0#83d4b7bf607b3b60a6546f8b58b5cdd7%1675278904.0791488",
|
||||
RecipeRevision: "83d4b7bf607b3b60a6546f8b58b5cdd7",
|
||||
|
||||
@@ -21,7 +21,9 @@ func newPubspecLockPackage(name string, raw pubspecLockPackage, locations ...fil
|
||||
PURL: packageURL(metadata),
|
||||
Language: pkg.Dart,
|
||||
Type: pkg.DartPubPkg,
|
||||
Metadata: metadata,
|
||||
// since we capture no dependencies today we know that the dep info is unknown
|
||||
Dependencies: pkg.UnknownDependencyCompleteness,
|
||||
Metadata: metadata,
|
||||
}
|
||||
|
||||
p.SetID()
|
||||
|
||||
@@ -14,12 +14,13 @@ func TestParsePubspecLock(t *testing.T) {
|
||||
fixtureLocationSet := file.NewLocationSet(file.NewLocation(fixture))
|
||||
expected := []pkg.Package{
|
||||
{
|
||||
Name: "ale",
|
||||
Version: "3.3.0",
|
||||
PURL: "pkg:pub/ale@3.3.0?hosted_url=pub.hosted.org",
|
||||
Locations: fixtureLocationSet,
|
||||
Language: pkg.Dart,
|
||||
Type: pkg.DartPubPkg,
|
||||
Name: "ale",
|
||||
Version: "3.3.0",
|
||||
PURL: "pkg:pub/ale@3.3.0?hosted_url=pub.hosted.org",
|
||||
Locations: fixtureLocationSet,
|
||||
Language: pkg.Dart,
|
||||
Type: pkg.DartPubPkg,
|
||||
Dependencies: pkg.UnknownDependencyCompleteness,
|
||||
Metadata: pkg.DartPubspecLockEntry{
|
||||
Name: "ale",
|
||||
Version: "3.3.0",
|
||||
@@ -27,72 +28,78 @@ func TestParsePubspecLock(t *testing.T) {
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "analyzer",
|
||||
Version: "0.40.7",
|
||||
PURL: "pkg:pub/analyzer@0.40.7",
|
||||
Locations: fixtureLocationSet,
|
||||
Language: pkg.Dart,
|
||||
Type: pkg.DartPubPkg,
|
||||
Name: "analyzer",
|
||||
Version: "0.40.7",
|
||||
PURL: "pkg:pub/analyzer@0.40.7",
|
||||
Locations: fixtureLocationSet,
|
||||
Language: pkg.Dart,
|
||||
Type: pkg.DartPubPkg,
|
||||
Dependencies: pkg.UnknownDependencyCompleteness,
|
||||
Metadata: pkg.DartPubspecLockEntry{
|
||||
Name: "analyzer",
|
||||
Version: "0.40.7",
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "ansicolor",
|
||||
Version: "1.1.1",
|
||||
PURL: "pkg:pub/ansicolor@1.1.1",
|
||||
Locations: fixtureLocationSet,
|
||||
Language: pkg.Dart,
|
||||
Type: pkg.DartPubPkg,
|
||||
Name: "ansicolor",
|
||||
Version: "1.1.1",
|
||||
PURL: "pkg:pub/ansicolor@1.1.1",
|
||||
Locations: fixtureLocationSet,
|
||||
Language: pkg.Dart,
|
||||
Type: pkg.DartPubPkg,
|
||||
Dependencies: pkg.UnknownDependencyCompleteness,
|
||||
Metadata: pkg.DartPubspecLockEntry{
|
||||
Name: "ansicolor",
|
||||
Version: "1.1.1",
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "archive",
|
||||
Version: "2.0.13",
|
||||
PURL: "pkg:pub/archive@2.0.13",
|
||||
Locations: fixtureLocationSet,
|
||||
Language: pkg.Dart,
|
||||
Type: pkg.DartPubPkg,
|
||||
Name: "archive",
|
||||
Version: "2.0.13",
|
||||
PURL: "pkg:pub/archive@2.0.13",
|
||||
Locations: fixtureLocationSet,
|
||||
Language: pkg.Dart,
|
||||
Type: pkg.DartPubPkg,
|
||||
Dependencies: pkg.UnknownDependencyCompleteness,
|
||||
Metadata: pkg.DartPubspecLockEntry{
|
||||
Name: "archive",
|
||||
Version: "2.0.13",
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "args",
|
||||
Version: "1.6.0",
|
||||
PURL: "pkg:pub/args@1.6.0",
|
||||
Locations: fixtureLocationSet,
|
||||
Language: pkg.Dart,
|
||||
Type: pkg.DartPubPkg,
|
||||
Name: "args",
|
||||
Version: "1.6.0",
|
||||
PURL: "pkg:pub/args@1.6.0",
|
||||
Locations: fixtureLocationSet,
|
||||
Language: pkg.Dart,
|
||||
Type: pkg.DartPubPkg,
|
||||
Dependencies: pkg.UnknownDependencyCompleteness,
|
||||
Metadata: pkg.DartPubspecLockEntry{
|
||||
Name: "args",
|
||||
Version: "1.6.0",
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "flutter",
|
||||
Version: "0.0.0",
|
||||
PURL: "pkg:pub/flutter@0.0.0",
|
||||
Locations: fixtureLocationSet,
|
||||
Language: pkg.Dart,
|
||||
Type: pkg.DartPubPkg,
|
||||
Name: "flutter",
|
||||
Version: "0.0.0",
|
||||
PURL: "pkg:pub/flutter@0.0.0",
|
||||
Locations: fixtureLocationSet,
|
||||
Language: pkg.Dart,
|
||||
Type: pkg.DartPubPkg,
|
||||
Dependencies: pkg.UnknownDependencyCompleteness,
|
||||
Metadata: pkg.DartPubspecLockEntry{
|
||||
Name: "flutter",
|
||||
Version: "0.0.0",
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "key_binder",
|
||||
Version: "1.11.20",
|
||||
PURL: "pkg:pub/key_binder@1.11.20?vcs_url=git%40github.com:Workiva/key_binder.git%403f7b3a6350e73c7dcac45301c0e18fbd42af02f7",
|
||||
Locations: fixtureLocationSet,
|
||||
Language: pkg.Dart,
|
||||
Type: pkg.DartPubPkg,
|
||||
Name: "key_binder",
|
||||
Version: "1.11.20",
|
||||
PURL: "pkg:pub/key_binder@1.11.20?vcs_url=git%40github.com:Workiva/key_binder.git%403f7b3a6350e73c7dcac45301c0e18fbd42af02f7",
|
||||
Locations: fixtureLocationSet,
|
||||
Language: pkg.Dart,
|
||||
Type: pkg.DartPubPkg,
|
||||
Dependencies: pkg.UnknownDependencyCompleteness,
|
||||
Metadata: pkg.DartPubspecLockEntry{
|
||||
Name: "key_binder",
|
||||
Version: "1.11.20",
|
||||
|
||||
@@ -14,6 +14,6 @@ func NewDBCataloger() pkg.Cataloger {
|
||||
return generic.NewCataloger("dpkg-db-cataloger").
|
||||
// note: these globs have been intentionally split up in order to improve search performance,
|
||||
// please do NOT combine into: "**/var/lib/dpkg/{status,status.d/*}"
|
||||
WithParserByGlobs(parseDpkgDB, "**/var/lib/dpkg/status", "**/var/lib/dpkg/status.d/*", "**/lib/opkg/info/*.control", "**/lib/opkg/status").
|
||||
WithParserByGlobs(parseDpkgDB, "**/lib/dpkg/status", "**/lib/dpkg/status.d/*", "**/lib/opkg/info/*.control", "**/lib/opkg/status").
|
||||
WithProcessors(dependency.Processor(dbEntryDependencySpecifier))
|
||||
}
|
||||
|
||||
@@ -36,7 +36,8 @@ func TestDpkgCataloger(t *testing.T) {
|
||||
file.NewLocation("/var/lib/dpkg/info/libpam-runtime.conffiles"),
|
||||
file.NewLocation("/usr/share/doc/libpam-runtime/copyright"),
|
||||
),
|
||||
Type: pkg.DebPkg,
|
||||
Type: pkg.DebPkg,
|
||||
Dependencies: pkg.CompleteDependencies,
|
||||
Metadata: pkg.DpkgDBEntry{
|
||||
Package: "libpam-runtime",
|
||||
Source: "pam",
|
||||
@@ -109,7 +110,8 @@ func TestDpkgCataloger(t *testing.T) {
|
||||
file.NewLocation("/var/lib/dpkg/status.d/libsqlite3-0.preinst"),
|
||||
file.NewLocation("/usr/share/doc/libsqlite3-0/copyright"),
|
||||
),
|
||||
Type: pkg.DebPkg,
|
||||
Type: pkg.DebPkg,
|
||||
Dependencies: pkg.CompleteDependencies,
|
||||
Metadata: pkg.DpkgDBEntry{
|
||||
Package: "libsqlite3-0",
|
||||
Source: "sqlite3",
|
||||
@@ -234,10 +236,12 @@ func TestCataloger_Globs(t *testing.T) {
|
||||
name: "obtain db status files",
|
||||
fixture: "test-fixtures/glob-paths",
|
||||
expected: []string{
|
||||
"usr/lib/dpkg/status",
|
||||
"var/lib/dpkg/status",
|
||||
"usr/lib/dpkg/status.d/pkg-1.0",
|
||||
"var/lib/dpkg/status.d/pkg-1.0",
|
||||
"usr/lib/opkg/status",
|
||||
"usr/lib/opkg/info/pkg-1.0.control",
|
||||
"usr/lib/opkg/status",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@@ -30,13 +30,14 @@ func newDpkgPackage(d pkg.DpkgDBEntry, dbLocation file.Location, resolver file.R
|
||||
locations.Add(evidence...)
|
||||
|
||||
p := pkg.Package{
|
||||
Name: d.Package,
|
||||
Version: d.Version,
|
||||
Licenses: pkg.NewLicenseSet(licenses...),
|
||||
Locations: locations,
|
||||
PURL: packageURL(d, release),
|
||||
Type: pkg.DebPkg,
|
||||
Metadata: d,
|
||||
Name: d.Package,
|
||||
Version: d.Version,
|
||||
Licenses: pkg.NewLicenseSet(licenses...),
|
||||
Locations: locations,
|
||||
PURL: packageURL(d, release),
|
||||
Type: pkg.DebPkg,
|
||||
Dependencies: pkg.CompleteDependencies,
|
||||
Metadata: d,
|
||||
}
|
||||
|
||||
if resolver != nil {
|
||||
|
||||
@@ -349,11 +349,12 @@ Installed-Size: 10kib
|
||||
`,
|
||||
want: []pkg.Package{
|
||||
{
|
||||
Name: "apt",
|
||||
Type: "deb",
|
||||
PURL: "pkg:deb/debian/apt?distro=debian-10",
|
||||
Licenses: pkg.NewLicenseSet(),
|
||||
Locations: file.NewLocationSet(file.NewLocation("place")),
|
||||
Name: "apt",
|
||||
Type: "deb",
|
||||
PURL: "pkg:deb/debian/apt?distro=debian-10",
|
||||
Licenses: pkg.NewLicenseSet(),
|
||||
Locations: file.NewLocationSet(file.NewLocation("place")),
|
||||
Dependencies: pkg.CompleteDependencies,
|
||||
Metadata: pkg.DpkgDBEntry{
|
||||
Package: "apt",
|
||||
InstalledSize: 10240,
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
bogus status
|
||||
@@ -0,0 +1 @@
|
||||
bogus package
|
||||
@@ -22,13 +22,14 @@ func newDotnetDepsPackage(nameVersion string, lib dotnetDepsLibrary, locations .
|
||||
}
|
||||
|
||||
p := &pkg.Package{
|
||||
Name: name,
|
||||
Version: version,
|
||||
Locations: file.NewLocationSet(locations...),
|
||||
PURL: packageURL(m),
|
||||
Language: pkg.Dotnet,
|
||||
Type: pkg.DotnetPkg,
|
||||
Metadata: m,
|
||||
Name: name,
|
||||
Version: version,
|
||||
Locations: file.NewLocationSet(locations...),
|
||||
PURL: packageURL(m),
|
||||
Language: pkg.Dotnet,
|
||||
Type: pkg.DotnetPkg,
|
||||
Dependencies: pkg.CompleteDependencies,
|
||||
Metadata: m,
|
||||
}
|
||||
|
||||
p.SetID()
|
||||
|
||||
@@ -20,36 +20,39 @@ func TestParseDotnetDeps(t *testing.T) {
|
||||
fixture := "test-fixtures/TestLibrary.deps.json"
|
||||
fixtureLocationSet := file.NewLocationSet(file.NewLocation(fixture))
|
||||
rootPkg := pkg.Package{
|
||||
Name: "TestLibrary",
|
||||
Version: "1.0.0",
|
||||
PURL: "pkg:nuget/TestLibrary@1.0.0",
|
||||
Locations: fixtureLocationSet,
|
||||
Language: pkg.Dotnet,
|
||||
Type: pkg.DotnetPkg,
|
||||
Name: "TestLibrary",
|
||||
Version: "1.0.0",
|
||||
PURL: "pkg:nuget/TestLibrary@1.0.0",
|
||||
Locations: fixtureLocationSet,
|
||||
Language: pkg.Dotnet,
|
||||
Type: pkg.DotnetPkg,
|
||||
Dependencies: pkg.CompleteDependencies,
|
||||
Metadata: pkg.DotnetDepsEntry{
|
||||
Name: "TestLibrary",
|
||||
Version: "1.0.0",
|
||||
},
|
||||
}
|
||||
testCommon := pkg.Package{
|
||||
Name: "TestCommon",
|
||||
Version: "1.0.0",
|
||||
PURL: "pkg:nuget/TestCommon@1.0.0",
|
||||
Locations: fixtureLocationSet,
|
||||
Language: pkg.Dotnet,
|
||||
Type: pkg.DotnetPkg,
|
||||
Name: "TestCommon",
|
||||
Version: "1.0.0",
|
||||
PURL: "pkg:nuget/TestCommon@1.0.0",
|
||||
Locations: fixtureLocationSet,
|
||||
Language: pkg.Dotnet,
|
||||
Type: pkg.DotnetPkg,
|
||||
Dependencies: pkg.CompleteDependencies,
|
||||
Metadata: pkg.DotnetDepsEntry{
|
||||
Name: "TestCommon",
|
||||
Version: "1.0.0",
|
||||
},
|
||||
}
|
||||
awssdkcore := pkg.Package{
|
||||
Name: "AWSSDK.Core",
|
||||
Version: "3.7.10.6",
|
||||
PURL: "pkg:nuget/AWSSDK.Core@3.7.10.6",
|
||||
Locations: fixtureLocationSet,
|
||||
Language: pkg.Dotnet,
|
||||
Type: pkg.DotnetPkg,
|
||||
Name: "AWSSDK.Core",
|
||||
Version: "3.7.10.6",
|
||||
PURL: "pkg:nuget/AWSSDK.Core@3.7.10.6",
|
||||
Locations: fixtureLocationSet,
|
||||
Language: pkg.Dotnet,
|
||||
Type: pkg.DotnetPkg,
|
||||
Dependencies: pkg.CompleteDependencies,
|
||||
Metadata: pkg.DotnetDepsEntry{
|
||||
Name: "AWSSDK.Core",
|
||||
Version: "3.7.10.6",
|
||||
@@ -59,12 +62,13 @@ func TestParseDotnetDeps(t *testing.T) {
|
||||
},
|
||||
}
|
||||
msftDependencyInjectionAbstractions := pkg.Package{
|
||||
Name: "Microsoft.Extensions.DependencyInjection.Abstractions",
|
||||
Version: "6.0.0",
|
||||
PURL: "pkg:nuget/Microsoft.Extensions.DependencyInjection.Abstractions@6.0.0",
|
||||
Locations: fixtureLocationSet,
|
||||
Language: pkg.Dotnet,
|
||||
Type: pkg.DotnetPkg,
|
||||
Name: "Microsoft.Extensions.DependencyInjection.Abstractions",
|
||||
Version: "6.0.0",
|
||||
PURL: "pkg:nuget/Microsoft.Extensions.DependencyInjection.Abstractions@6.0.0",
|
||||
Locations: fixtureLocationSet,
|
||||
Language: pkg.Dotnet,
|
||||
Type: pkg.DotnetPkg,
|
||||
Dependencies: pkg.CompleteDependencies,
|
||||
Metadata: pkg.DotnetDepsEntry{
|
||||
Name: "Microsoft.Extensions.DependencyInjection.Abstractions",
|
||||
Version: "6.0.0",
|
||||
@@ -74,12 +78,13 @@ func TestParseDotnetDeps(t *testing.T) {
|
||||
},
|
||||
}
|
||||
msftDependencyInjection := pkg.Package{
|
||||
Name: "Microsoft.Extensions.DependencyInjection",
|
||||
Version: "6.0.0",
|
||||
PURL: "pkg:nuget/Microsoft.Extensions.DependencyInjection@6.0.0",
|
||||
Locations: fixtureLocationSet,
|
||||
Language: pkg.Dotnet,
|
||||
Type: pkg.DotnetPkg,
|
||||
Name: "Microsoft.Extensions.DependencyInjection",
|
||||
Version: "6.0.0",
|
||||
PURL: "pkg:nuget/Microsoft.Extensions.DependencyInjection@6.0.0",
|
||||
Locations: fixtureLocationSet,
|
||||
Language: pkg.Dotnet,
|
||||
Type: pkg.DotnetPkg,
|
||||
Dependencies: pkg.CompleteDependencies,
|
||||
Metadata: pkg.DotnetDepsEntry{
|
||||
Name: "Microsoft.Extensions.DependencyInjection",
|
||||
Version: "6.0.0",
|
||||
@@ -89,12 +94,13 @@ func TestParseDotnetDeps(t *testing.T) {
|
||||
},
|
||||
}
|
||||
msftLoggingAbstractions := pkg.Package{
|
||||
Name: "Microsoft.Extensions.Logging.Abstractions",
|
||||
Version: "6.0.0",
|
||||
PURL: "pkg:nuget/Microsoft.Extensions.Logging.Abstractions@6.0.0",
|
||||
Locations: fixtureLocationSet,
|
||||
Language: pkg.Dotnet,
|
||||
Type: pkg.DotnetPkg,
|
||||
Name: "Microsoft.Extensions.Logging.Abstractions",
|
||||
Version: "6.0.0",
|
||||
PURL: "pkg:nuget/Microsoft.Extensions.Logging.Abstractions@6.0.0",
|
||||
Locations: fixtureLocationSet,
|
||||
Language: pkg.Dotnet,
|
||||
Type: pkg.DotnetPkg,
|
||||
Dependencies: pkg.CompleteDependencies,
|
||||
Metadata: pkg.DotnetDepsEntry{
|
||||
Name: "Microsoft.Extensions.Logging.Abstractions",
|
||||
Version: "6.0.0",
|
||||
@@ -104,12 +110,13 @@ func TestParseDotnetDeps(t *testing.T) {
|
||||
},
|
||||
}
|
||||
msftExtensionsLogging := pkg.Package{
|
||||
Name: "Microsoft.Extensions.Logging",
|
||||
Version: "6.0.0",
|
||||
PURL: "pkg:nuget/Microsoft.Extensions.Logging@6.0.0",
|
||||
Locations: fixtureLocationSet,
|
||||
Language: pkg.Dotnet,
|
||||
Type: pkg.DotnetPkg,
|
||||
Name: "Microsoft.Extensions.Logging",
|
||||
Version: "6.0.0",
|
||||
PURL: "pkg:nuget/Microsoft.Extensions.Logging@6.0.0",
|
||||
Locations: fixtureLocationSet,
|
||||
Language: pkg.Dotnet,
|
||||
Type: pkg.DotnetPkg,
|
||||
Dependencies: pkg.CompleteDependencies,
|
||||
Metadata: pkg.DotnetDepsEntry{
|
||||
Name: "Microsoft.Extensions.Logging",
|
||||
Version: "6.0.0",
|
||||
@@ -119,12 +126,13 @@ func TestParseDotnetDeps(t *testing.T) {
|
||||
},
|
||||
}
|
||||
msftExtensionsOptions := pkg.Package{
|
||||
Name: "Microsoft.Extensions.Options",
|
||||
Version: "6.0.0",
|
||||
PURL: "pkg:nuget/Microsoft.Extensions.Options@6.0.0",
|
||||
Locations: fixtureLocationSet,
|
||||
Language: pkg.Dotnet,
|
||||
Type: pkg.DotnetPkg,
|
||||
Name: "Microsoft.Extensions.Options",
|
||||
Version: "6.0.0",
|
||||
PURL: "pkg:nuget/Microsoft.Extensions.Options@6.0.0",
|
||||
Locations: fixtureLocationSet,
|
||||
Language: pkg.Dotnet,
|
||||
Type: pkg.DotnetPkg,
|
||||
Dependencies: pkg.CompleteDependencies,
|
||||
Metadata: pkg.DotnetDepsEntry{
|
||||
Name: "Microsoft.Extensions.Options",
|
||||
Version: "6.0.0",
|
||||
@@ -134,12 +142,13 @@ func TestParseDotnetDeps(t *testing.T) {
|
||||
},
|
||||
}
|
||||
msftExtensionsPrimitives := pkg.Package{
|
||||
Name: "Microsoft.Extensions.Primitives",
|
||||
Version: "6.0.0",
|
||||
PURL: "pkg:nuget/Microsoft.Extensions.Primitives@6.0.0",
|
||||
Locations: fixtureLocationSet,
|
||||
Language: pkg.Dotnet,
|
||||
Type: pkg.DotnetPkg,
|
||||
Name: "Microsoft.Extensions.Primitives",
|
||||
Version: "6.0.0",
|
||||
PURL: "pkg:nuget/Microsoft.Extensions.Primitives@6.0.0",
|
||||
Locations: fixtureLocationSet,
|
||||
Language: pkg.Dotnet,
|
||||
Type: pkg.DotnetPkg,
|
||||
Dependencies: pkg.CompleteDependencies,
|
||||
Metadata: pkg.DotnetDepsEntry{
|
||||
Name: "Microsoft.Extensions.Primitives",
|
||||
Version: "6.0.0",
|
||||
@@ -149,12 +158,13 @@ func TestParseDotnetDeps(t *testing.T) {
|
||||
},
|
||||
}
|
||||
newtonsoftJson := pkg.Package{
|
||||
Name: "Newtonsoft.Json",
|
||||
Version: "13.0.1",
|
||||
PURL: "pkg:nuget/Newtonsoft.Json@13.0.1",
|
||||
Locations: fixtureLocationSet,
|
||||
Language: pkg.Dotnet,
|
||||
Type: pkg.DotnetPkg,
|
||||
Name: "Newtonsoft.Json",
|
||||
Version: "13.0.1",
|
||||
PURL: "pkg:nuget/Newtonsoft.Json@13.0.1",
|
||||
Locations: fixtureLocationSet,
|
||||
Language: pkg.Dotnet,
|
||||
Type: pkg.DotnetPkg,
|
||||
Dependencies: pkg.CompleteDependencies,
|
||||
Metadata: pkg.DotnetDepsEntry{
|
||||
Name: "Newtonsoft.Json",
|
||||
Version: "13.0.1",
|
||||
@@ -164,12 +174,13 @@ func TestParseDotnetDeps(t *testing.T) {
|
||||
},
|
||||
}
|
||||
serilogSinksConsole := pkg.Package{
|
||||
Name: "Serilog.Sinks.Console",
|
||||
Version: "4.0.1",
|
||||
PURL: "pkg:nuget/Serilog.Sinks.Console@4.0.1",
|
||||
Locations: fixtureLocationSet,
|
||||
Language: pkg.Dotnet,
|
||||
Type: pkg.DotnetPkg,
|
||||
Name: "Serilog.Sinks.Console",
|
||||
Version: "4.0.1",
|
||||
PURL: "pkg:nuget/Serilog.Sinks.Console@4.0.1",
|
||||
Locations: fixtureLocationSet,
|
||||
Language: pkg.Dotnet,
|
||||
Type: pkg.DotnetPkg,
|
||||
Dependencies: pkg.CompleteDependencies,
|
||||
Metadata: pkg.DotnetDepsEntry{
|
||||
Name: "Serilog.Sinks.Console",
|
||||
Version: "4.0.1",
|
||||
@@ -179,12 +190,13 @@ func TestParseDotnetDeps(t *testing.T) {
|
||||
},
|
||||
}
|
||||
serilog := pkg.Package{
|
||||
Name: "Serilog",
|
||||
Version: "2.10.0",
|
||||
PURL: "pkg:nuget/Serilog@2.10.0",
|
||||
Locations: fixtureLocationSet,
|
||||
Language: pkg.Dotnet,
|
||||
Type: pkg.DotnetPkg,
|
||||
Name: "Serilog",
|
||||
Version: "2.10.0",
|
||||
PURL: "pkg:nuget/Serilog@2.10.0",
|
||||
Locations: fixtureLocationSet,
|
||||
Language: pkg.Dotnet,
|
||||
Type: pkg.DotnetPkg,
|
||||
Dependencies: pkg.CompleteDependencies,
|
||||
Metadata: pkg.DotnetDepsEntry{
|
||||
Name: "Serilog",
|
||||
Version: "2.10.0",
|
||||
@@ -194,12 +206,13 @@ func TestParseDotnetDeps(t *testing.T) {
|
||||
},
|
||||
}
|
||||
systemDiagnosticsDiagnosticsource := pkg.Package{
|
||||
Name: "System.Diagnostics.DiagnosticSource",
|
||||
Version: "6.0.0",
|
||||
PURL: "pkg:nuget/System.Diagnostics.DiagnosticSource@6.0.0",
|
||||
Locations: fixtureLocationSet,
|
||||
Language: pkg.Dotnet,
|
||||
Type: pkg.DotnetPkg,
|
||||
Name: "System.Diagnostics.DiagnosticSource",
|
||||
Version: "6.0.0",
|
||||
PURL: "pkg:nuget/System.Diagnostics.DiagnosticSource@6.0.0",
|
||||
Locations: fixtureLocationSet,
|
||||
Language: pkg.Dotnet,
|
||||
Type: pkg.DotnetPkg,
|
||||
Dependencies: pkg.CompleteDependencies,
|
||||
Metadata: pkg.DotnetDepsEntry{
|
||||
Name: "System.Diagnostics.DiagnosticSource",
|
||||
Version: "6.0.0",
|
||||
@@ -209,12 +222,13 @@ func TestParseDotnetDeps(t *testing.T) {
|
||||
},
|
||||
}
|
||||
systemRuntimeCompilerServicesUnsafe := pkg.Package{
|
||||
Name: "System.Runtime.CompilerServices.Unsafe",
|
||||
Version: "6.0.0",
|
||||
PURL: "pkg:nuget/System.Runtime.CompilerServices.Unsafe@6.0.0",
|
||||
Locations: fixtureLocationSet,
|
||||
Language: pkg.Dotnet,
|
||||
Type: pkg.DotnetPkg,
|
||||
Name: "System.Runtime.CompilerServices.Unsafe",
|
||||
Version: "6.0.0",
|
||||
PURL: "pkg:nuget/System.Runtime.CompilerServices.Unsafe@6.0.0",
|
||||
Locations: fixtureLocationSet,
|
||||
Language: pkg.Dotnet,
|
||||
Type: pkg.DotnetPkg,
|
||||
Dependencies: pkg.CompleteDependencies,
|
||||
Metadata: pkg.DotnetDepsEntry{
|
||||
Name: "System.Runtime.CompilerServices.Unsafe",
|
||||
Version: "6.0.0",
|
||||
|
||||
@@ -9,7 +9,7 @@ import (
|
||||
|
||||
"github.com/saferwall/pe"
|
||||
|
||||
version "github.com/anchore/go-version"
|
||||
"github.com/anchore/go-version"
|
||||
"github.com/anchore/packageurl-go"
|
||||
"github.com/anchore/syft/internal/log"
|
||||
"github.com/anchore/syft/syft/artifact"
|
||||
@@ -44,7 +44,7 @@ func parseDotnetPortableExecutable(_ context.Context, _ file.Resolver, _ *generi
|
||||
return nil, nil, fmt.Errorf("unable to parse version resources in PE file: %w", err)
|
||||
}
|
||||
|
||||
dotNetPkg, err := buildDotNetPackage(versionResources, f)
|
||||
dotNetPkg, err := buildDotNetPEPackage(versionResources, f)
|
||||
if err != nil {
|
||||
log.Tracef("unable to build dotnet package for: %v %v", f.RealPath, err)
|
||||
return nil, nil, err
|
||||
@@ -53,14 +53,14 @@ func parseDotnetPortableExecutable(_ context.Context, _ file.Resolver, _ *generi
|
||||
return []pkg.Package{dotNetPkg}, nil, nil
|
||||
}
|
||||
|
||||
func buildDotNetPackage(versionResources map[string]string, f file.LocationReadCloser) (dnpkg pkg.Package, err error) {
|
||||
func buildDotNetPEPackage(versionResources map[string]string, f file.LocationReadCloser) (dnpkg pkg.Package, err error) {
|
||||
name := findName(versionResources)
|
||||
if name == "" {
|
||||
return dnpkg, fmt.Errorf("unable to find PE name in file")
|
||||
}
|
||||
|
||||
version := findVersion(versionResources)
|
||||
if version == "" {
|
||||
ver := findVersion(versionResources)
|
||||
if ver == "" {
|
||||
return dnpkg, fmt.Errorf("unable to find PE version in file")
|
||||
}
|
||||
|
||||
@@ -76,12 +76,14 @@ func buildDotNetPackage(versionResources map[string]string, f file.LocationReadC
|
||||
|
||||
dnpkg = pkg.Package{
|
||||
Name: name,
|
||||
Version: version,
|
||||
Version: ver,
|
||||
Locations: file.NewLocationSet(f.Location.WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation)),
|
||||
Type: pkg.DotnetPkg,
|
||||
Language: pkg.Dotnet,
|
||||
PURL: portableExecutablePackageURL(name, version),
|
||||
Metadata: metadata,
|
||||
PURL: portableExecutablePackageURL(name, ver),
|
||||
// by nature PE file metadata does not have any dependency information, thus we are forced to claim unknown completeness
|
||||
Dependencies: pkg.UnknownDependencyCompleteness,
|
||||
Metadata: metadata,
|
||||
}
|
||||
|
||||
dnpkg.SetID()
|
||||
|
||||
@@ -32,8 +32,9 @@ func TestParseDotnetPortableExecutable(t *testing.T) {
|
||||
"Assembly Version": "3.14.2.11",
|
||||
},
|
||||
expectedPackage: pkg.Package{
|
||||
Name: "Active Directory Authentication Library",
|
||||
Version: "3.14.40721.0918",
|
||||
Name: "Active Directory Authentication Library",
|
||||
Version: "3.14.40721.0918",
|
||||
Dependencies: pkg.UnknownDependencyCompleteness,
|
||||
Metadata: pkg.DotnetPortableExecutableEntry{
|
||||
AssemblyVersion: "3.14.2.11",
|
||||
LegalCopyright: "Copyright (c) Microsoft Corporation. All rights reserved.",
|
||||
@@ -57,9 +58,10 @@ func TestParseDotnetPortableExecutable(t *testing.T) {
|
||||
"ProductVersion": "4.6.25512.01 built by: dlab-DDVSOWINAGE016. Commit Hash: d0d5c7b49271cadb6d97de26d8e623e98abdc8db",
|
||||
},
|
||||
expectedPackage: pkg.Package{
|
||||
Name: "äbFileVersi on",
|
||||
Version: "4.6.25512.01",
|
||||
PURL: "pkg:nuget/%C3%A4bFileVersi%20on@4.6.25512.01",
|
||||
Name: "äbFileVersi on",
|
||||
Version: "4.6.25512.01",
|
||||
PURL: "pkg:nuget/%C3%A4bFileVersi%20on@4.6.25512.01",
|
||||
Dependencies: pkg.UnknownDependencyCompleteness,
|
||||
Metadata: pkg.DotnetPortableExecutableEntry{
|
||||
LegalCopyright: "© Microsoft Corporation. All rights reserved.",
|
||||
InternalName: "äb\x01FileVersion",
|
||||
@@ -82,8 +84,9 @@ func TestParseDotnetPortableExecutable(t *testing.T) {
|
||||
"ProductVersion": "4.7.3190.0",
|
||||
},
|
||||
expectedPackage: pkg.Package{
|
||||
Name: "System.Data.Linq.dll",
|
||||
Version: "4.7.3190.0",
|
||||
Name: "System.Data.Linq.dll",
|
||||
Version: "4.7.3190.0",
|
||||
Dependencies: pkg.UnknownDependencyCompleteness,
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -99,8 +102,9 @@ func TestParseDotnetPortableExecutable(t *testing.T) {
|
||||
"ProductVersion": "8.4.0",
|
||||
},
|
||||
expectedPackage: pkg.Package{
|
||||
Name: "The curl executable",
|
||||
Version: "8.4.0",
|
||||
Name: "The curl executable",
|
||||
Version: "8.4.0",
|
||||
Dependencies: pkg.UnknownDependencyCompleteness,
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -116,8 +120,9 @@ func TestParseDotnetPortableExecutable(t *testing.T) {
|
||||
"ProductVersion": "8.0.1",
|
||||
},
|
||||
expectedPackage: pkg.Package{
|
||||
Name: "Prometheus.AspNetCore.dll",
|
||||
Version: "8.0.1",
|
||||
Name: "Prometheus.AspNetCore.dll",
|
||||
Version: "8.0.1",
|
||||
Dependencies: pkg.UnknownDependencyCompleteness,
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -132,8 +137,9 @@ func TestParseDotnetPortableExecutable(t *testing.T) {
|
||||
"ProductVersion": "1, 0, 0, 0",
|
||||
},
|
||||
expectedPackage: pkg.Package{
|
||||
Name: "Hidden Input",
|
||||
Version: "1, 0, 0, 0",
|
||||
Name: "Hidden Input",
|
||||
Version: "1, 0, 0, 0",
|
||||
Dependencies: pkg.UnknownDependencyCompleteness,
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -148,8 +154,9 @@ func TestParseDotnetPortableExecutable(t *testing.T) {
|
||||
"ProductVersion": "3.23.2",
|
||||
},
|
||||
expectedPackage: pkg.Package{
|
||||
Name: "SQLite",
|
||||
Version: "3.23.2",
|
||||
Name: "SQLite",
|
||||
Version: "3.23.2",
|
||||
Dependencies: pkg.UnknownDependencyCompleteness,
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -165,8 +172,9 @@ func TestParseDotnetPortableExecutable(t *testing.T) {
|
||||
"ProductVersion": "80.1.7.92",
|
||||
},
|
||||
expectedPackage: pkg.Package{
|
||||
Name: "Brave Browser",
|
||||
Version: "80.1.7.92",
|
||||
Name: "Brave Browser",
|
||||
Version: "80.1.7.92",
|
||||
Dependencies: pkg.UnknownDependencyCompleteness,
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -177,8 +185,9 @@ func TestParseDotnetPortableExecutable(t *testing.T) {
|
||||
"ProductVersion": "80.1.7.92",
|
||||
},
|
||||
expectedPackage: pkg.Package{
|
||||
Name: "Better version",
|
||||
Version: "80.1.7.92",
|
||||
Name: "Better version",
|
||||
Version: "80.1.7.92",
|
||||
Dependencies: pkg.UnknownDependencyCompleteness,
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -189,8 +198,9 @@ func TestParseDotnetPortableExecutable(t *testing.T) {
|
||||
"ProductVersion": "80.1.7",
|
||||
},
|
||||
expectedPackage: pkg.Package{
|
||||
Name: "Better version",
|
||||
Version: "80.1.7.92",
|
||||
Name: "Better version",
|
||||
Version: "80.1.7.92",
|
||||
Dependencies: pkg.UnknownDependencyCompleteness,
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -201,8 +211,9 @@ func TestParseDotnetPortableExecutable(t *testing.T) {
|
||||
"ProductVersion": "3.0.1+b86b61bf676163639795b163d8d753b20aad6207",
|
||||
},
|
||||
expectedPackage: pkg.Package{
|
||||
Name: "Higher semantic version Product Version",
|
||||
Version: "3.0.1+b86b61bf676163639795b163d8d753b20aad6207",
|
||||
Name: "Higher semantic version Product Version",
|
||||
Version: "3.0.1+b86b61bf676163639795b163d8d753b20aad6207",
|
||||
Dependencies: pkg.UnknownDependencyCompleteness,
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -213,8 +224,9 @@ func TestParseDotnetPortableExecutable(t *testing.T) {
|
||||
"ProductVersion": "3.0.0",
|
||||
},
|
||||
expectedPackage: pkg.Package{
|
||||
Name: "Higher semantic version File Version",
|
||||
Version: "3.0.1+b86b61bf676163639795b163d8d753b20aad6207",
|
||||
Name: "Higher semantic version File Version",
|
||||
Version: "3.0.1+b86b61bf676163639795b163d8d753b20aad6207",
|
||||
Dependencies: pkg.UnknownDependencyCompleteness,
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -225,8 +237,9 @@ func TestParseDotnetPortableExecutable(t *testing.T) {
|
||||
"ProductVersion": "3.0.1+b86b61bf676163639795b163d8d753b20aad6207",
|
||||
},
|
||||
expectedPackage: pkg.Package{
|
||||
Name: "Invalid semantic version File Version",
|
||||
Version: "3.0.1+b86b61bf676163639795b163d8d753b20aad6207",
|
||||
Name: "Invalid semantic version File Version",
|
||||
Version: "3.0.1+b86b61bf676163639795b163d8d753b20aad6207",
|
||||
Dependencies: pkg.UnknownDependencyCompleteness,
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -237,8 +250,9 @@ func TestParseDotnetPortableExecutable(t *testing.T) {
|
||||
"ProductVersion": "3.0.1+b86b61bf676163639795b163d8d753b20aad6207",
|
||||
},
|
||||
expectedPackage: pkg.Package{
|
||||
Name: "Invalid semantic version File Version",
|
||||
Version: "3.0.1+b86b61bf676163639795b163d8d753b20aad6207",
|
||||
Name: "Invalid semantic version File Version",
|
||||
Version: "3.0.1+b86b61bf676163639795b163d8d753b20aad6207",
|
||||
Dependencies: pkg.UnknownDependencyCompleteness,
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -249,8 +263,9 @@ func TestParseDotnetPortableExecutable(t *testing.T) {
|
||||
"ProductVersion": "A",
|
||||
},
|
||||
expectedPackage: pkg.Package{
|
||||
Name: "Invalid semantic version Product Version",
|
||||
Version: "3.0.1+b86b61bf676163639795b163d8d753b20aad6207",
|
||||
Name: "Invalid semantic version Product Version",
|
||||
Version: "3.0.1+b86b61bf676163639795b163d8d753b20aad6207",
|
||||
Dependencies: pkg.UnknownDependencyCompleteness,
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -261,8 +276,9 @@ func TestParseDotnetPortableExecutable(t *testing.T) {
|
||||
"ProductVersion": "3.0.0",
|
||||
},
|
||||
expectedPackage: pkg.Package{
|
||||
Name: "Semantically equal falls through, chooses File Version with more components",
|
||||
Version: "3.0.0.0",
|
||||
Name: "Semantically equal falls through, chooses File Version with more components",
|
||||
Version: "3.0.0.0",
|
||||
Dependencies: pkg.UnknownDependencyCompleteness,
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -273,7 +289,7 @@ func TestParseDotnetPortableExecutable(t *testing.T) {
|
||||
f := file.LocationReadCloser{
|
||||
Location: location,
|
||||
}
|
||||
got, err := buildDotNetPackage(tc.versionResources, f)
|
||||
got, err := buildDotNetPEPackage(tc.versionResources, f)
|
||||
assert.NoErrorf(t, err, "failed to build package from version resources: %+v", tc.versionResources)
|
||||
|
||||
// ignore certain metadata
|
||||
|
||||
@@ -14,7 +14,9 @@ func newPackage(d pkg.ElixirMixLockEntry, locations ...file.Location) pkg.Packag
|
||||
Locations: file.NewLocationSet(locations...),
|
||||
PURL: packageURL(d),
|
||||
Type: pkg.HexPkg,
|
||||
Metadata: d,
|
||||
// we do not attempt to parse dependencies from the mix.lock file
|
||||
Dependencies: pkg.UnknownDependencyCompleteness,
|
||||
Metadata: d,
|
||||
}
|
||||
|
||||
p.SetID()
|
||||
|
||||
@@ -13,12 +13,13 @@ func TestParseMixLock(t *testing.T) {
|
||||
locations := file.NewLocationSet(file.NewLocation("test-fixtures/mix.lock"))
|
||||
expected := []pkg.Package{
|
||||
{
|
||||
Name: "castore",
|
||||
Version: "0.1.17",
|
||||
Language: pkg.Elixir,
|
||||
Type: pkg.HexPkg,
|
||||
Locations: locations,
|
||||
PURL: "pkg:hex/castore@0.1.17",
|
||||
Name: "castore",
|
||||
Version: "0.1.17",
|
||||
Language: pkg.Elixir,
|
||||
Type: pkg.HexPkg,
|
||||
Locations: locations,
|
||||
PURL: "pkg:hex/castore@0.1.17",
|
||||
Dependencies: pkg.UnknownDependencyCompleteness,
|
||||
Metadata: pkg.ElixirMixLockEntry{
|
||||
Name: "castore",
|
||||
Version: "0.1.17",
|
||||
@@ -27,12 +28,13 @@ func TestParseMixLock(t *testing.T) {
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "connection",
|
||||
Version: "1.1.0",
|
||||
Language: pkg.Elixir,
|
||||
Type: pkg.HexPkg,
|
||||
Locations: locations,
|
||||
PURL: "pkg:hex/connection@1.1.0",
|
||||
Name: "connection",
|
||||
Version: "1.1.0",
|
||||
Language: pkg.Elixir,
|
||||
Type: pkg.HexPkg,
|
||||
Locations: locations,
|
||||
PURL: "pkg:hex/connection@1.1.0",
|
||||
Dependencies: pkg.UnknownDependencyCompleteness,
|
||||
Metadata: pkg.ElixirMixLockEntry{
|
||||
Name: "connection",
|
||||
Version: "1.1.0",
|
||||
@@ -41,12 +43,13 @@ func TestParseMixLock(t *testing.T) {
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "cowboy",
|
||||
Version: "2.9.0",
|
||||
Language: pkg.Elixir,
|
||||
Type: pkg.HexPkg,
|
||||
Locations: locations,
|
||||
PURL: "pkg:hex/cowboy@2.9.0",
|
||||
Name: "cowboy",
|
||||
Version: "2.9.0",
|
||||
Language: pkg.Elixir,
|
||||
Type: pkg.HexPkg,
|
||||
Locations: locations,
|
||||
PURL: "pkg:hex/cowboy@2.9.0",
|
||||
Dependencies: pkg.UnknownDependencyCompleteness,
|
||||
Metadata: pkg.ElixirMixLockEntry{
|
||||
Name: "cowboy",
|
||||
Version: "2.9.0",
|
||||
@@ -55,12 +58,13 @@ func TestParseMixLock(t *testing.T) {
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "cowboy_telemetry",
|
||||
Version: "0.4.0",
|
||||
Language: pkg.Elixir,
|
||||
Type: pkg.HexPkg,
|
||||
Locations: locations,
|
||||
PURL: "pkg:hex/cowboy_telemetry@0.4.0",
|
||||
Name: "cowboy_telemetry",
|
||||
Version: "0.4.0",
|
||||
Language: pkg.Elixir,
|
||||
Type: pkg.HexPkg,
|
||||
Locations: locations,
|
||||
PURL: "pkg:hex/cowboy_telemetry@0.4.0",
|
||||
Dependencies: pkg.UnknownDependencyCompleteness,
|
||||
Metadata: pkg.ElixirMixLockEntry{
|
||||
Name: "cowboy_telemetry",
|
||||
Version: "0.4.0",
|
||||
@@ -69,12 +73,13 @@ func TestParseMixLock(t *testing.T) {
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "cowlib",
|
||||
Version: "2.11.0",
|
||||
Language: pkg.Elixir,
|
||||
Type: pkg.HexPkg,
|
||||
Locations: locations,
|
||||
PURL: "pkg:hex/cowlib@2.11.0",
|
||||
Name: "cowlib",
|
||||
Version: "2.11.0",
|
||||
Language: pkg.Elixir,
|
||||
Type: pkg.HexPkg,
|
||||
Locations: locations,
|
||||
PURL: "pkg:hex/cowlib@2.11.0",
|
||||
Dependencies: pkg.UnknownDependencyCompleteness,
|
||||
Metadata: pkg.ElixirMixLockEntry{
|
||||
Name: "cowlib",
|
||||
Version: "2.11.0",
|
||||
@@ -83,12 +88,13 @@ func TestParseMixLock(t *testing.T) {
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "db_connection",
|
||||
Version: "2.4.2",
|
||||
Language: pkg.Elixir,
|
||||
Type: pkg.HexPkg,
|
||||
Locations: locations,
|
||||
PURL: "pkg:hex/db_connection@2.4.2",
|
||||
Name: "db_connection",
|
||||
Version: "2.4.2",
|
||||
Language: pkg.Elixir,
|
||||
Type: pkg.HexPkg,
|
||||
Locations: locations,
|
||||
PURL: "pkg:hex/db_connection@2.4.2",
|
||||
Dependencies: pkg.UnknownDependencyCompleteness,
|
||||
Metadata: pkg.ElixirMixLockEntry{
|
||||
Name: "db_connection",
|
||||
Version: "2.4.2",
|
||||
@@ -97,12 +103,13 @@ func TestParseMixLock(t *testing.T) {
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "decimal",
|
||||
Version: "2.0.0",
|
||||
Language: pkg.Elixir,
|
||||
Type: pkg.HexPkg,
|
||||
Locations: locations,
|
||||
PURL: "pkg:hex/decimal@2.0.0",
|
||||
Name: "decimal",
|
||||
Version: "2.0.0",
|
||||
Language: pkg.Elixir,
|
||||
Type: pkg.HexPkg,
|
||||
Locations: locations,
|
||||
PURL: "pkg:hex/decimal@2.0.0",
|
||||
Dependencies: pkg.UnknownDependencyCompleteness,
|
||||
Metadata: pkg.ElixirMixLockEntry{
|
||||
Name: "decimal",
|
||||
Version: "2.0.0",
|
||||
@@ -111,12 +118,13 @@ func TestParseMixLock(t *testing.T) {
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "earmark_parser",
|
||||
Version: "1.4.25",
|
||||
Language: pkg.Elixir,
|
||||
Type: pkg.HexPkg,
|
||||
Locations: locations,
|
||||
PURL: "pkg:hex/earmark_parser@1.4.25",
|
||||
Name: "earmark_parser",
|
||||
Version: "1.4.25",
|
||||
Language: pkg.Elixir,
|
||||
Type: pkg.HexPkg,
|
||||
Locations: locations,
|
||||
PURL: "pkg:hex/earmark_parser@1.4.25",
|
||||
Dependencies: pkg.UnknownDependencyCompleteness,
|
||||
Metadata: pkg.ElixirMixLockEntry{
|
||||
Name: "earmark_parser",
|
||||
Version: "1.4.25",
|
||||
@@ -125,12 +133,13 @@ func TestParseMixLock(t *testing.T) {
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "ecto",
|
||||
Version: "3.8.1",
|
||||
Language: pkg.Elixir,
|
||||
Type: pkg.HexPkg,
|
||||
Locations: locations,
|
||||
PURL: "pkg:hex/ecto@3.8.1",
|
||||
Name: "ecto",
|
||||
Version: "3.8.1",
|
||||
Language: pkg.Elixir,
|
||||
Type: pkg.HexPkg,
|
||||
Locations: locations,
|
||||
PURL: "pkg:hex/ecto@3.8.1",
|
||||
Dependencies: pkg.UnknownDependencyCompleteness,
|
||||
Metadata: pkg.ElixirMixLockEntry{
|
||||
Name: "ecto",
|
||||
Version: "3.8.1",
|
||||
@@ -139,12 +148,13 @@ func TestParseMixLock(t *testing.T) {
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "ecto_sql",
|
||||
Version: "3.8.1",
|
||||
Language: pkg.Elixir,
|
||||
Type: pkg.HexPkg,
|
||||
Locations: locations,
|
||||
PURL: "pkg:hex/ecto_sql@3.8.1",
|
||||
Name: "ecto_sql",
|
||||
Version: "3.8.1",
|
||||
Language: pkg.Elixir,
|
||||
Type: pkg.HexPkg,
|
||||
Locations: locations,
|
||||
PURL: "pkg:hex/ecto_sql@3.8.1",
|
||||
Dependencies: pkg.UnknownDependencyCompleteness,
|
||||
Metadata: pkg.ElixirMixLockEntry{
|
||||
Name: "ecto_sql",
|
||||
Version: "3.8.1",
|
||||
@@ -153,12 +163,13 @@ func TestParseMixLock(t *testing.T) {
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "esbuild",
|
||||
Version: "0.5.0",
|
||||
Language: pkg.Elixir,
|
||||
Type: pkg.HexPkg,
|
||||
Locations: locations,
|
||||
PURL: "pkg:hex/esbuild@0.5.0",
|
||||
Name: "esbuild",
|
||||
Version: "0.5.0",
|
||||
Language: pkg.Elixir,
|
||||
Type: pkg.HexPkg,
|
||||
Locations: locations,
|
||||
PURL: "pkg:hex/esbuild@0.5.0",
|
||||
Dependencies: pkg.UnknownDependencyCompleteness,
|
||||
Metadata: pkg.ElixirMixLockEntry{
|
||||
Name: "esbuild",
|
||||
Version: "0.5.0",
|
||||
@@ -167,12 +178,13 @@ func TestParseMixLock(t *testing.T) {
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "ex_doc",
|
||||
Version: "0.28.4",
|
||||
Language: pkg.Elixir,
|
||||
Type: pkg.HexPkg,
|
||||
Locations: locations,
|
||||
PURL: "pkg:hex/ex_doc@0.28.4",
|
||||
Name: "ex_doc",
|
||||
Version: "0.28.4",
|
||||
Language: pkg.Elixir,
|
||||
Type: pkg.HexPkg,
|
||||
Locations: locations,
|
||||
PURL: "pkg:hex/ex_doc@0.28.4",
|
||||
Dependencies: pkg.UnknownDependencyCompleteness,
|
||||
Metadata: pkg.ElixirMixLockEntry{
|
||||
Name: "ex_doc",
|
||||
Version: "0.28.4",
|
||||
@@ -181,12 +193,13 @@ func TestParseMixLock(t *testing.T) {
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "gettext",
|
||||
Version: "0.19.1",
|
||||
Language: pkg.Elixir,
|
||||
Type: pkg.HexPkg,
|
||||
Locations: locations,
|
||||
PURL: "pkg:hex/gettext@0.19.1",
|
||||
Name: "gettext",
|
||||
Version: "0.19.1",
|
||||
Language: pkg.Elixir,
|
||||
Type: pkg.HexPkg,
|
||||
Locations: locations,
|
||||
PURL: "pkg:hex/gettext@0.19.1",
|
||||
Dependencies: pkg.UnknownDependencyCompleteness,
|
||||
Metadata: pkg.ElixirMixLockEntry{
|
||||
Name: "gettext",
|
||||
Version: "0.19.1",
|
||||
@@ -195,12 +208,13 @@ func TestParseMixLock(t *testing.T) {
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "hpax",
|
||||
Version: "0.1.1",
|
||||
Language: pkg.Elixir,
|
||||
Type: pkg.HexPkg,
|
||||
Locations: locations,
|
||||
PURL: "pkg:hex/hpax@0.1.1",
|
||||
Name: "hpax",
|
||||
Version: "0.1.1",
|
||||
Language: pkg.Elixir,
|
||||
Type: pkg.HexPkg,
|
||||
Locations: locations,
|
||||
PURL: "pkg:hex/hpax@0.1.1",
|
||||
Dependencies: pkg.UnknownDependencyCompleteness,
|
||||
Metadata: pkg.ElixirMixLockEntry{
|
||||
Name: "hpax",
|
||||
Version: "0.1.1",
|
||||
@@ -209,12 +223,13 @@ func TestParseMixLock(t *testing.T) {
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "jason",
|
||||
Version: "1.3.0",
|
||||
Language: pkg.Elixir,
|
||||
Type: pkg.HexPkg,
|
||||
Locations: locations,
|
||||
PURL: "pkg:hex/jason@1.3.0",
|
||||
Name: "jason",
|
||||
Version: "1.3.0",
|
||||
Language: pkg.Elixir,
|
||||
Type: pkg.HexPkg,
|
||||
Locations: locations,
|
||||
PURL: "pkg:hex/jason@1.3.0",
|
||||
Dependencies: pkg.UnknownDependencyCompleteness,
|
||||
Metadata: pkg.ElixirMixLockEntry{
|
||||
Name: "jason",
|
||||
Version: "1.3.0",
|
||||
|
||||
@@ -14,7 +14,9 @@ func newPackageFromRebar(d pkg.ErlangRebarLockEntry, locations ...file.Location)
|
||||
Locations: file.NewLocationSet(locations...),
|
||||
PURL: packageURLFromRebar(d),
|
||||
Type: pkg.HexPkg,
|
||||
Metadata: d,
|
||||
// we do not attempt to parse dependencies from the rebar.lock file
|
||||
Dependencies: pkg.UnknownDependencyCompleteness,
|
||||
Metadata: d,
|
||||
}
|
||||
|
||||
p.SetID()
|
||||
@@ -42,7 +44,9 @@ func newPackageFromOTP(name, version string, locations ...file.Location) pkg.Pac
|
||||
Language: pkg.Erlang,
|
||||
Locations: file.NewLocationSet(locations...),
|
||||
PURL: packageURLFromOTP(name, version),
|
||||
Type: pkg.ErlangOTPPkg,
|
||||
// we do not attempt to parse dependencies from app files
|
||||
Dependencies: pkg.UnknownDependencyCompleteness,
|
||||
Type: pkg.ErlangOTPPkg,
|
||||
}
|
||||
|
||||
p.SetID()
|
||||
|
||||
@@ -18,11 +18,12 @@ func TestParseOTPApplication(t *testing.T) {
|
||||
fixture: "test-fixtures/rabbitmq.app",
|
||||
expected: []pkg.Package{
|
||||
{
|
||||
Name: "rabbit",
|
||||
Version: "3.12.10",
|
||||
Language: pkg.Erlang,
|
||||
Type: pkg.ErlangOTPPkg,
|
||||
PURL: "pkg:otp/rabbit@3.12.10",
|
||||
Name: "rabbit",
|
||||
Version: "3.12.10",
|
||||
Language: pkg.Erlang,
|
||||
Type: pkg.ErlangOTPPkg,
|
||||
PURL: "pkg:otp/rabbit@3.12.10",
|
||||
Dependencies: pkg.UnknownDependencyCompleteness,
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
@@ -18,11 +18,12 @@ func TestParseRebarLock(t *testing.T) {
|
||||
fixture: "test-fixtures/rebar.lock",
|
||||
expected: []pkg.Package{
|
||||
{
|
||||
Name: "certifi",
|
||||
Version: "2.9.0",
|
||||
Language: pkg.Erlang,
|
||||
Type: pkg.HexPkg,
|
||||
PURL: "pkg:hex/certifi@2.9.0",
|
||||
Name: "certifi",
|
||||
Version: "2.9.0",
|
||||
Language: pkg.Erlang,
|
||||
Type: pkg.HexPkg,
|
||||
PURL: "pkg:hex/certifi@2.9.0",
|
||||
Dependencies: pkg.UnknownDependencyCompleteness,
|
||||
Metadata: pkg.ErlangRebarLockEntry{
|
||||
Name: "certifi",
|
||||
Version: "2.9.0",
|
||||
@@ -31,11 +32,12 @@ func TestParseRebarLock(t *testing.T) {
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "idna",
|
||||
Version: "6.1.1",
|
||||
Language: pkg.Erlang,
|
||||
Type: pkg.HexPkg,
|
||||
PURL: "pkg:hex/idna@6.1.1",
|
||||
Name: "idna",
|
||||
Version: "6.1.1",
|
||||
Language: pkg.Erlang,
|
||||
Type: pkg.HexPkg,
|
||||
PURL: "pkg:hex/idna@6.1.1",
|
||||
Dependencies: pkg.UnknownDependencyCompleteness,
|
||||
Metadata: pkg.ErlangRebarLockEntry{
|
||||
Name: "idna",
|
||||
Version: "6.1.1",
|
||||
@@ -44,11 +46,12 @@ func TestParseRebarLock(t *testing.T) {
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "metrics",
|
||||
Version: "1.0.1",
|
||||
Language: pkg.Erlang,
|
||||
Type: pkg.HexPkg,
|
||||
PURL: "pkg:hex/metrics@1.0.1",
|
||||
Name: "metrics",
|
||||
Version: "1.0.1",
|
||||
Language: pkg.Erlang,
|
||||
Type: pkg.HexPkg,
|
||||
PURL: "pkg:hex/metrics@1.0.1",
|
||||
Dependencies: pkg.UnknownDependencyCompleteness,
|
||||
Metadata: pkg.ErlangRebarLockEntry{
|
||||
Name: "metrics",
|
||||
Version: "1.0.1",
|
||||
@@ -57,11 +60,12 @@ func TestParseRebarLock(t *testing.T) {
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "mimerl",
|
||||
Version: "1.2.0",
|
||||
Language: pkg.Erlang,
|
||||
Type: pkg.HexPkg,
|
||||
PURL: "pkg:hex/mimerl@1.2.0",
|
||||
Name: "mimerl",
|
||||
Version: "1.2.0",
|
||||
Language: pkg.Erlang,
|
||||
Type: pkg.HexPkg,
|
||||
PURL: "pkg:hex/mimerl@1.2.0",
|
||||
Dependencies: pkg.UnknownDependencyCompleteness,
|
||||
Metadata: pkg.ErlangRebarLockEntry{
|
||||
Name: "mimerl",
|
||||
Version: "1.2.0",
|
||||
@@ -70,11 +74,12 @@ func TestParseRebarLock(t *testing.T) {
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "parse_trans",
|
||||
Version: "3.3.1",
|
||||
Language: pkg.Erlang,
|
||||
Type: pkg.HexPkg,
|
||||
PURL: "pkg:hex/parse_trans@3.3.1",
|
||||
Name: "parse_trans",
|
||||
Version: "3.3.1",
|
||||
Language: pkg.Erlang,
|
||||
Type: pkg.HexPkg,
|
||||
PURL: "pkg:hex/parse_trans@3.3.1",
|
||||
Dependencies: pkg.UnknownDependencyCompleteness,
|
||||
Metadata: pkg.ErlangRebarLockEntry{
|
||||
Name: "parse_trans",
|
||||
Version: "3.3.1",
|
||||
@@ -83,11 +88,12 @@ func TestParseRebarLock(t *testing.T) {
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "ssl_verify_fun",
|
||||
Version: "1.1.6",
|
||||
Language: pkg.Erlang,
|
||||
Type: pkg.HexPkg,
|
||||
PURL: "pkg:hex/ssl_verify_fun@1.1.6",
|
||||
Name: "ssl_verify_fun",
|
||||
Version: "1.1.6",
|
||||
Language: pkg.Erlang,
|
||||
Type: pkg.HexPkg,
|
||||
PURL: "pkg:hex/ssl_verify_fun@1.1.6",
|
||||
Dependencies: pkg.UnknownDependencyCompleteness,
|
||||
Metadata: pkg.ErlangRebarLockEntry{
|
||||
Name: "ssl_verify_fun",
|
||||
Version: "1.1.6",
|
||||
@@ -96,11 +102,12 @@ func TestParseRebarLock(t *testing.T) {
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "unicode_util_compat",
|
||||
Version: "0.7.0",
|
||||
Language: pkg.Erlang,
|
||||
Type: pkg.HexPkg,
|
||||
PURL: "pkg:hex/unicode_util_compat@0.7.0",
|
||||
Name: "unicode_util_compat",
|
||||
Version: "0.7.0",
|
||||
Language: pkg.Erlang,
|
||||
Type: pkg.HexPkg,
|
||||
PURL: "pkg:hex/unicode_util_compat@0.7.0",
|
||||
Dependencies: pkg.UnknownDependencyCompleteness,
|
||||
Metadata: pkg.ErlangRebarLockEntry{
|
||||
Name: "unicode_util_compat",
|
||||
Version: "0.7.0",
|
||||
@@ -117,11 +124,12 @@ func TestParseRebarLock(t *testing.T) {
|
||||
// {<<"bcrypt">>, <<"A6763BD4E1AF46D34776F85B7995E63A02978DE110C077E9570ED17006E03386">>},
|
||||
// {<<"bcrypt">>, <<"3418821BC17CE6E96A4A77D1A88D7485BF783E212069FACFC79510AFBFF95352">>},
|
||||
{
|
||||
Name: "bcrypt",
|
||||
Version: "1.1.5",
|
||||
Language: pkg.Erlang,
|
||||
Type: pkg.HexPkg,
|
||||
PURL: "pkg:hex/bcrypt@1.1.5",
|
||||
Name: "bcrypt",
|
||||
Version: "1.1.5",
|
||||
Language: pkg.Erlang,
|
||||
Type: pkg.HexPkg,
|
||||
PURL: "pkg:hex/bcrypt@1.1.5",
|
||||
Dependencies: pkg.UnknownDependencyCompleteness,
|
||||
Metadata: pkg.ErlangRebarLockEntry{
|
||||
Name: "bcrypt",
|
||||
Version: "1.1.5",
|
||||
@@ -134,11 +142,12 @@ func TestParseRebarLock(t *testing.T) {
|
||||
// {ref,"14308ab927cfa69324742c3de720578094e0bb19"}},
|
||||
// 1},
|
||||
{
|
||||
Name: "bson",
|
||||
Version: "14308ab927cfa69324742c3de720578094e0bb19",
|
||||
Language: pkg.Erlang,
|
||||
Type: pkg.HexPkg,
|
||||
PURL: "pkg:hex/bson@14308ab927cfa69324742c3de720578094e0bb19",
|
||||
Name: "bson",
|
||||
Version: "14308ab927cfa69324742c3de720578094e0bb19",
|
||||
Language: pkg.Erlang,
|
||||
Type: pkg.HexPkg,
|
||||
PURL: "pkg:hex/bson@14308ab927cfa69324742c3de720578094e0bb19",
|
||||
Dependencies: pkg.UnknownDependencyCompleteness,
|
||||
Metadata: pkg.ErlangRebarLockEntry{
|
||||
Name: "bson",
|
||||
Version: "14308ab927cfa69324742c3de720578094e0bb19",
|
||||
@@ -148,11 +157,12 @@ func TestParseRebarLock(t *testing.T) {
|
||||
// {<<"certifi">>, <<"6F2A475689DD47F19FB74334859D460A2DC4E3252A3324BD2111B8F0429E7E21">>}, {<<"stdout_formatter">>, <<"EC24868D8619757A68F0798357C7190807A1CFC42CE90C18C23760E59249A21A">>},
|
||||
// {<<"certifi">>, <<"266DA46BDB06D6C6D35FDE799BCB28D36D985D424AD7C08B5BB48F5B5CDD4641">>},
|
||||
{
|
||||
Name: "certifi",
|
||||
Version: "2.9.0",
|
||||
Language: pkg.Erlang,
|
||||
Type: pkg.HexPkg,
|
||||
PURL: "pkg:hex/certifi@2.9.0",
|
||||
Name: "certifi",
|
||||
Version: "2.9.0",
|
||||
Language: pkg.Erlang,
|
||||
Type: pkg.HexPkg,
|
||||
PURL: "pkg:hex/certifi@2.9.0",
|
||||
Dependencies: pkg.UnknownDependencyCompleteness,
|
||||
Metadata: pkg.ErlangRebarLockEntry{
|
||||
Name: "certifi",
|
||||
Version: "2.9.0",
|
||||
@@ -164,11 +174,12 @@ func TestParseRebarLock(t *testing.T) {
|
||||
// {<<"stdout_formatter">>, <<"EC24868D8619757A68F0798357C7190807A1CFC42CE90C18C23760E59249A21A">>},
|
||||
// {<<"stdout_formatter">>, <<"6B9CAAD8930006F9BB35680C5D3311917AC67690C3AF1BA018623324C015ABE5">>},
|
||||
{
|
||||
Name: "stdout_formatter",
|
||||
Version: "0.2.3",
|
||||
Language: pkg.Erlang,
|
||||
Type: pkg.HexPkg,
|
||||
PURL: "pkg:hex/stdout_formatter@0.2.3",
|
||||
Name: "stdout_formatter",
|
||||
Version: "0.2.3",
|
||||
Language: pkg.Erlang,
|
||||
Type: pkg.HexPkg,
|
||||
PURL: "pkg:hex/stdout_formatter@0.2.3",
|
||||
Dependencies: pkg.UnknownDependencyCompleteness,
|
||||
Metadata: pkg.ErlangRebarLockEntry{
|
||||
Name: "stdout_formatter",
|
||||
Version: "0.2.3",
|
||||
@@ -181,11 +192,12 @@ func TestParseRebarLock(t *testing.T) {
|
||||
// {ref,"4835239dca5a5f4ac7202dd94d7effcaa617d575"}},
|
||||
// 0},
|
||||
{
|
||||
Name: "swc",
|
||||
Version: "4835239dca5a5f4ac7202dd94d7effcaa617d575",
|
||||
Language: pkg.Erlang,
|
||||
Type: pkg.HexPkg,
|
||||
PURL: "pkg:hex/swc@4835239dca5a5f4ac7202dd94d7effcaa617d575",
|
||||
Name: "swc",
|
||||
Version: "4835239dca5a5f4ac7202dd94d7effcaa617d575",
|
||||
Language: pkg.Erlang,
|
||||
Type: pkg.HexPkg,
|
||||
PURL: "pkg:hex/swc@4835239dca5a5f4ac7202dd94d7effcaa617d575",
|
||||
Dependencies: pkg.UnknownDependencyCompleteness,
|
||||
Metadata: pkg.ErlangRebarLockEntry{
|
||||
Name: "swc",
|
||||
Version: "4835239dca5a5f4ac7202dd94d7effcaa617d575",
|
||||
@@ -195,11 +207,12 @@ func TestParseRebarLock(t *testing.T) {
|
||||
// {<<"syslog">>, <<"6419A232BEA84F07B56DC575225007FFE34D9FDC91ABE6F1B2F254FD71D8EFC2">>},
|
||||
// {<<"syslog">>, <<"4C6A41373C7E20587BE33EF841D3DE6F3BEBA08519809329ECC4D27B15B659E1">>},
|
||||
{
|
||||
Name: "syslog",
|
||||
Version: "1.1.0",
|
||||
Language: pkg.Erlang,
|
||||
Type: pkg.HexPkg,
|
||||
PURL: "pkg:hex/syslog@1.1.0",
|
||||
Name: "syslog",
|
||||
Version: "1.1.0",
|
||||
Language: pkg.Erlang,
|
||||
Type: pkg.HexPkg,
|
||||
PURL: "pkg:hex/syslog@1.1.0",
|
||||
Dependencies: pkg.UnknownDependencyCompleteness,
|
||||
Metadata: pkg.ErlangRebarLockEntry{
|
||||
Name: "syslog",
|
||||
Version: "1.1.0",
|
||||
@@ -211,11 +224,12 @@ func TestParseRebarLock(t *testing.T) {
|
||||
// {<<"unicode_util_compat">>, <<"BC84380C9AB48177092F43AC89E4DFA2C6D62B40B8BD132B1059ECC7232F9A78">>}]},
|
||||
// {<<"unicode_util_compat">>, <<"25EEE6D67DF61960CF6A794239566599B09E17E668D3700247BC498638152521">>}]}
|
||||
{
|
||||
Name: "unicode_util_compat",
|
||||
Version: "0.7.0",
|
||||
Language: pkg.Erlang,
|
||||
Type: pkg.HexPkg,
|
||||
PURL: "pkg:hex/unicode_util_compat@0.7.0",
|
||||
Name: "unicode_util_compat",
|
||||
Version: "0.7.0",
|
||||
Language: pkg.Erlang,
|
||||
Type: pkg.HexPkg,
|
||||
PURL: "pkg:hex/unicode_util_compat@0.7.0",
|
||||
Dependencies: pkg.UnknownDependencyCompleteness,
|
||||
Metadata: pkg.ErlangRebarLockEntry{
|
||||
Name: "unicode_util_compat",
|
||||
Version: "0.7.0",
|
||||
@@ -228,11 +242,12 @@ func TestParseRebarLock(t *testing.T) {
|
||||
// {ref,"6d622aa8c901ae7777433aef2bd049e380c474a6"}},
|
||||
// 0}]}.
|
||||
{
|
||||
Name: "vernemq_dev",
|
||||
Version: "6d622aa8c901ae7777433aef2bd049e380c474a6",
|
||||
Language: pkg.Erlang,
|
||||
Type: pkg.HexPkg,
|
||||
PURL: "pkg:hex/vernemq_dev@6d622aa8c901ae7777433aef2bd049e380c474a6",
|
||||
Name: "vernemq_dev",
|
||||
Version: "6d622aa8c901ae7777433aef2bd049e380c474a6",
|
||||
Language: pkg.Erlang,
|
||||
Type: pkg.HexPkg,
|
||||
PURL: "pkg:hex/vernemq_dev@6d622aa8c901ae7777433aef2bd049e380c474a6",
|
||||
Dependencies: pkg.UnknownDependencyCompleteness,
|
||||
Metadata: pkg.ErlangRebarLockEntry{
|
||||
Name: "vernemq_dev",
|
||||
Version: "6d622aa8c901ae7777433aef2bd049e380c474a6",
|
||||
|
||||
@@ -108,7 +108,7 @@ func newSpyReturningFileResolver(s *spyingIoReadCloser, paths ...string) file.Re
|
||||
}
|
||||
|
||||
func (s *spyingIoReadCloser) Read(p []byte) (n int, err error) {
|
||||
return s.Read(p)
|
||||
return s.rc.Read(p)
|
||||
}
|
||||
|
||||
func (s *spyingIoReadCloser) Close() error {
|
||||
|
||||
@@ -22,8 +22,9 @@ func TestPortageCataloger(t *testing.T) {
|
||||
file.NewLocation("var/db/pkg/app-containers/skopeo-1.5.1/SIZE"),
|
||||
expectedLicenseLocation,
|
||||
),
|
||||
Licenses: pkg.NewLicenseSet(pkg.NewLicensesFromLocation(expectedLicenseLocation, "Apache-2.0", "BSD", "BSD-2", "CC-BY-SA-4.0", "ISC", "MIT")...),
|
||||
Type: pkg.PortagePkg,
|
||||
Licenses: pkg.NewLicenseSet(pkg.NewLicensesFromLocation(expectedLicenseLocation, "Apache-2.0", "BSD", "BSD-2", "CC-BY-SA-4.0", "ISC", "MIT")...),
|
||||
Type: pkg.PortagePkg,
|
||||
Dependencies: pkg.UnknownDependencyCompleteness,
|
||||
Metadata: pkg.PortageEntry{
|
||||
InstalledSize: 27937835,
|
||||
Files: []pkg.PortageFileRecord{
|
||||
|
||||
@@ -45,7 +45,8 @@ func parsePortageContents(_ context.Context, resolver file.Resolver, _ *generic.
|
||||
Locations: file.NewLocationSet(
|
||||
reader.Location.WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation),
|
||||
),
|
||||
Type: pkg.PortagePkg,
|
||||
Dependencies: pkg.UnknownDependencyCompleteness,
|
||||
Type: pkg.PortagePkg,
|
||||
Metadata: pkg.PortageEntry{
|
||||
// ensure the default value for a collection is never nil since this may be shown as JSON
|
||||
Files: make([]pkg.PortageFileRecord, 0),
|
||||
|
||||
@@ -31,7 +31,9 @@ func newGithubActionWorkflowPackageUsage(name, version string, workflowLocation
|
||||
Version: version,
|
||||
Locations: file.NewLocationSet(workflowLocation.WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation)),
|
||||
PURL: packageURL(name, version),
|
||||
Type: pkg.GithubActionWorkflowPkg,
|
||||
// we have full visibility into the dependencies of a workflow file except for when using shared workflows
|
||||
Dependencies: pkg.CompleteDependencies,
|
||||
Type: pkg.GithubActionWorkflowPkg,
|
||||
}
|
||||
|
||||
p.SetID()
|
||||
@@ -45,7 +47,9 @@ func newGithubActionPackageUsage(name, version string, workflowLocation file.Loc
|
||||
Version: version,
|
||||
Locations: file.NewLocationSet(workflowLocation.WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation)),
|
||||
PURL: packageURL(name, version),
|
||||
Type: pkg.GithubActionPkg,
|
||||
// we cannot see what the dependencies are for a github action are locally from workflow yaml files
|
||||
Dependencies: pkg.UnknownDependencyCompleteness,
|
||||
Type: pkg.GithubActionPkg,
|
||||
}
|
||||
|
||||
p.SetID()
|
||||
|
||||
@@ -15,18 +15,20 @@ func Test_parseCompositeActionForActionUsage(t *testing.T) {
|
||||
|
||||
expected := []pkg.Package{
|
||||
{
|
||||
Name: "actions/setup-go",
|
||||
Version: "v4",
|
||||
Type: pkg.GithubActionPkg,
|
||||
Locations: fixtureLocationSet,
|
||||
PURL: "pkg:github/actions/setup-go@v4",
|
||||
Name: "actions/setup-go",
|
||||
Version: "v4",
|
||||
Type: pkg.GithubActionPkg,
|
||||
Locations: fixtureLocationSet,
|
||||
PURL: "pkg:github/actions/setup-go@v4",
|
||||
Dependencies: pkg.UnknownDependencyCompleteness,
|
||||
},
|
||||
{
|
||||
Name: "actions/cache",
|
||||
Version: "v3",
|
||||
Type: pkg.GithubActionPkg,
|
||||
Locations: fixtureLocationSet,
|
||||
PURL: "pkg:github/actions/cache@v3",
|
||||
Name: "actions/cache",
|
||||
Version: "v3",
|
||||
Type: pkg.GithubActionPkg,
|
||||
Locations: fixtureLocationSet,
|
||||
PURL: "pkg:github/actions/cache@v3",
|
||||
Dependencies: pkg.UnknownDependencyCompleteness,
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
@@ -15,39 +15,44 @@ func Test_parseWorkflowForActionUsage(t *testing.T) {
|
||||
|
||||
expected := []pkg.Package{
|
||||
{
|
||||
Name: "./.github/actions/bootstrap",
|
||||
Version: "",
|
||||
Type: pkg.GithubActionPkg,
|
||||
Locations: fixtureLocationSet,
|
||||
PURL: "", // don't have enough context without parsing the git origin, which still may not be accurate
|
||||
Name: "./.github/actions/bootstrap",
|
||||
Version: "",
|
||||
Type: pkg.GithubActionPkg,
|
||||
Locations: fixtureLocationSet,
|
||||
PURL: "", // don't have enough context without parsing the git origin, which still may not be accurate
|
||||
Dependencies: pkg.UnknownDependencyCompleteness,
|
||||
},
|
||||
{
|
||||
Name: "actions/cache",
|
||||
Version: "v3",
|
||||
Type: pkg.GithubActionPkg,
|
||||
Locations: fixtureLocationSet,
|
||||
PURL: "pkg:github/actions/cache@v3",
|
||||
Name: "actions/cache",
|
||||
Version: "v3",
|
||||
Type: pkg.GithubActionPkg,
|
||||
Locations: fixtureLocationSet,
|
||||
PURL: "pkg:github/actions/cache@v3",
|
||||
Dependencies: pkg.UnknownDependencyCompleteness,
|
||||
},
|
||||
{
|
||||
Name: "actions/cache/restore",
|
||||
Version: "v3",
|
||||
Type: pkg.GithubActionPkg,
|
||||
Locations: fixtureLocationSet,
|
||||
PURL: "pkg:github/actions/cache@v3#restore",
|
||||
Name: "actions/cache/restore",
|
||||
Version: "v3",
|
||||
Type: pkg.GithubActionPkg,
|
||||
Locations: fixtureLocationSet,
|
||||
PURL: "pkg:github/actions/cache@v3#restore",
|
||||
Dependencies: pkg.UnknownDependencyCompleteness,
|
||||
},
|
||||
{
|
||||
Name: "actions/cache/save",
|
||||
Version: "v3",
|
||||
Type: pkg.GithubActionPkg,
|
||||
Locations: fixtureLocationSet,
|
||||
PURL: "pkg:github/actions/cache@v3#save",
|
||||
Name: "actions/cache/save",
|
||||
Version: "v3",
|
||||
Type: pkg.GithubActionPkg,
|
||||
Locations: fixtureLocationSet,
|
||||
PURL: "pkg:github/actions/cache@v3#save",
|
||||
Dependencies: pkg.UnknownDependencyCompleteness,
|
||||
},
|
||||
{
|
||||
Name: "actions/checkout",
|
||||
Version: "v4",
|
||||
Type: pkg.GithubActionPkg,
|
||||
Locations: fixtureLocationSet,
|
||||
PURL: "pkg:github/actions/checkout@v4",
|
||||
Name: "actions/checkout",
|
||||
Version: "v4",
|
||||
Type: pkg.GithubActionPkg,
|
||||
Locations: fixtureLocationSet,
|
||||
PURL: "pkg:github/actions/checkout@v4",
|
||||
Dependencies: pkg.UnknownDependencyCompleteness,
|
||||
},
|
||||
}
|
||||
|
||||
@@ -61,25 +66,28 @@ func Test_parseWorkflowForWorkflowUsage(t *testing.T) {
|
||||
|
||||
expected := []pkg.Package{
|
||||
{
|
||||
Name: "octo-org/this-repo/.github/workflows/workflow-1.yml",
|
||||
Version: "172239021f7ba04fe7327647b213799853a9eb89",
|
||||
Type: pkg.GithubActionWorkflowPkg,
|
||||
Locations: fixtureLocationSet,
|
||||
PURL: "pkg:github/octo-org/this-repo@172239021f7ba04fe7327647b213799853a9eb89#.github/workflows/workflow-1.yml",
|
||||
Name: "octo-org/this-repo/.github/workflows/workflow-1.yml",
|
||||
Version: "172239021f7ba04fe7327647b213799853a9eb89",
|
||||
Type: pkg.GithubActionWorkflowPkg,
|
||||
Locations: fixtureLocationSet,
|
||||
PURL: "pkg:github/octo-org/this-repo@172239021f7ba04fe7327647b213799853a9eb89#.github/workflows/workflow-1.yml",
|
||||
Dependencies: pkg.CompleteDependencies,
|
||||
},
|
||||
{
|
||||
Name: "./.github/workflows/workflow-2.yml",
|
||||
Version: "",
|
||||
Type: pkg.GithubActionWorkflowPkg,
|
||||
Locations: fixtureLocationSet,
|
||||
PURL: "", // don't have enough context without parsing the git origin, which still may not be accurate
|
||||
Name: "./.github/workflows/workflow-2.yml",
|
||||
Version: "",
|
||||
Type: pkg.GithubActionWorkflowPkg,
|
||||
Locations: fixtureLocationSet,
|
||||
PURL: "", // don't have enough context without parsing the git origin, which still may not be accurate
|
||||
Dependencies: pkg.CompleteDependencies,
|
||||
},
|
||||
{
|
||||
Name: "octo-org/another-repo/.github/workflows/workflow.yml",
|
||||
Version: "v1",
|
||||
Type: pkg.GithubActionWorkflowPkg,
|
||||
Locations: fixtureLocationSet,
|
||||
PURL: "pkg:github/octo-org/another-repo@v1#.github/workflows/workflow.yml",
|
||||
Name: "octo-org/another-repo/.github/workflows/workflow.yml",
|
||||
Version: "v1",
|
||||
Type: pkg.GithubActionWorkflowPkg,
|
||||
Locations: fixtureLocationSet,
|
||||
PURL: "pkg:github/octo-org/another-repo@v1#.github/workflows/workflow.yml",
|
||||
Dependencies: pkg.CompleteDependencies,
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
@@ -9,19 +9,20 @@ import (
|
||||
"github.com/anchore/syft/syft/pkg"
|
||||
)
|
||||
|
||||
func (c *goBinaryCataloger) newGoBinaryPackage(dep *debug.Module, mainModule, goVersion, architecture string, buildSettings pkg.KeyValues, cryptoSettings, experiments []string, licenses []pkg.License, locations ...file.Location) pkg.Package {
|
||||
func (c *goBinaryCataloger) newGoBinaryPackage(dep *debug.Module, mainModule, goVersion, architecture string, buildSettings pkg.KeyValues, cryptoSettings, experiments []string, licenses []pkg.License, dependencies pkg.DependencyCompleteness, locations ...file.Location) pkg.Package {
|
||||
if dep.Replace != nil {
|
||||
dep = dep.Replace
|
||||
}
|
||||
|
||||
p := pkg.Package{
|
||||
Name: dep.Path,
|
||||
Version: dep.Version,
|
||||
Licenses: pkg.NewLicenseSet(licenses...),
|
||||
PURL: packageURL(dep.Path, dep.Version),
|
||||
Language: pkg.Go,
|
||||
Type: pkg.GoModulePkg,
|
||||
Locations: file.NewLocationSet(locations...),
|
||||
Name: dep.Path,
|
||||
Version: dep.Version,
|
||||
Licenses: pkg.NewLicenseSet(licenses...),
|
||||
PURL: packageURL(dep.Path, dep.Version),
|
||||
Language: pkg.Go,
|
||||
Type: pkg.GoModulePkg,
|
||||
Locations: file.NewLocationSet(locations...),
|
||||
Dependencies: dependencies,
|
||||
Metadata: pkg.GolangBinaryBuildinfoEntry{
|
||||
GoCompiledVersion: goVersion,
|
||||
H1Digest: dep.Sum,
|
||||
|
||||
@@ -134,6 +134,10 @@ func (c *goBinaryCataloger) buildGoPkgInfo(ctx context.Context, licenseScanner l
|
||||
mod.cryptoSettings,
|
||||
experiments,
|
||||
lics,
|
||||
// the buildinfo section is a flat list of dependencies missing all edge information. So all direct and indirect
|
||||
// dependencies are related directly to the main module. This means that we don't have any way to discover
|
||||
// the completeness of the dependency's dependencies, thus they are unknown.
|
||||
pkg.UnknownDependencyCompleteness,
|
||||
location.WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation),
|
||||
)
|
||||
if pkg.IsValid(&p) {
|
||||
@@ -178,6 +182,11 @@ func (c *goBinaryCataloger) makeGoMainPackage(ctx context.Context, licenseScanne
|
||||
mod.cryptoSettings,
|
||||
experiments,
|
||||
lics,
|
||||
// the buildinfo section is a flat list of dependencies missing all edge information. So all direct and indirect
|
||||
// dependencies are related directly to the main module. Also, we don't have a way to express on a package or
|
||||
// relationship the nature of "//indirect" markings on dependencies so though the dependencies are complete
|
||||
// and separable with the raw data, the data in the SBOM is not separable.
|
||||
pkg.CompleteWithIndirectDependencies,
|
||||
location.WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation),
|
||||
)
|
||||
|
||||
|
||||
@@ -161,6 +161,7 @@ func TestBuildGoPkgInfo(t *testing.T) {
|
||||
},
|
||||
).WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation),
|
||||
),
|
||||
Dependencies: pkg.CompleteWithIndirectDependencies,
|
||||
Metadata: pkg.GolangBinaryBuildinfoEntry{
|
||||
GoCompiledVersion: goCompiledVersion,
|
||||
Architecture: archDetails,
|
||||
@@ -208,7 +209,8 @@ func TestBuildGoPkgInfo(t *testing.T) {
|
||||
},
|
||||
).WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation),
|
||||
),
|
||||
Metadata: pkg.GolangBinaryBuildinfoEntry{},
|
||||
Dependencies: pkg.UnknownDependencyCompleteness,
|
||||
Metadata: pkg.GolangBinaryBuildinfoEntry{},
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -253,6 +255,7 @@ func TestBuildGoPkgInfo(t *testing.T) {
|
||||
},
|
||||
).WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation),
|
||||
),
|
||||
Dependencies: pkg.UnknownDependencyCompleteness,
|
||||
Metadata: pkg.GolangBinaryBuildinfoEntry{
|
||||
GoCompiledVersion: goCompiledVersion,
|
||||
Architecture: archDetails,
|
||||
@@ -291,6 +294,7 @@ func TestBuildGoPkgInfo(t *testing.T) {
|
||||
},
|
||||
).WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation),
|
||||
),
|
||||
Dependencies: pkg.CompleteWithIndirectDependencies,
|
||||
Metadata: pkg.GolangBinaryBuildinfoEntry{
|
||||
GoCompiledVersion: goCompiledVersion,
|
||||
Architecture: archDetails,
|
||||
@@ -365,6 +369,7 @@ func TestBuildGoPkgInfo(t *testing.T) {
|
||||
},
|
||||
).WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation),
|
||||
),
|
||||
Dependencies: pkg.CompleteWithIndirectDependencies,
|
||||
Metadata: pkg.GolangBinaryBuildinfoEntry{
|
||||
GoCompiledVersion: goCompiledVersion,
|
||||
Architecture: archDetails,
|
||||
@@ -432,6 +437,7 @@ func TestBuildGoPkgInfo(t *testing.T) {
|
||||
},
|
||||
).WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation),
|
||||
),
|
||||
Dependencies: pkg.CompleteWithIndirectDependencies,
|
||||
Metadata: pkg.GolangBinaryBuildinfoEntry{
|
||||
GoCompiledVersion: goCompiledVersion,
|
||||
Architecture: archDetails,
|
||||
@@ -497,6 +503,7 @@ func TestBuildGoPkgInfo(t *testing.T) {
|
||||
},
|
||||
).WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation),
|
||||
),
|
||||
Dependencies: pkg.CompleteWithIndirectDependencies,
|
||||
Metadata: pkg.GolangBinaryBuildinfoEntry{
|
||||
GoCompiledVersion: goCompiledVersion,
|
||||
Architecture: archDetails,
|
||||
@@ -554,6 +561,7 @@ func TestBuildGoPkgInfo(t *testing.T) {
|
||||
},
|
||||
).WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation),
|
||||
),
|
||||
Dependencies: pkg.CompleteWithIndirectDependencies,
|
||||
Metadata: pkg.GolangBinaryBuildinfoEntry{
|
||||
GoCompiledVersion: goCompiledVersion,
|
||||
Architecture: archDetails,
|
||||
@@ -611,6 +619,7 @@ func TestBuildGoPkgInfo(t *testing.T) {
|
||||
},
|
||||
).WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation),
|
||||
),
|
||||
Dependencies: pkg.CompleteWithIndirectDependencies,
|
||||
Metadata: pkg.GolangBinaryBuildinfoEntry{
|
||||
GoCompiledVersion: goCompiledVersion,
|
||||
Architecture: archDetails,
|
||||
@@ -669,6 +678,7 @@ func TestBuildGoPkgInfo(t *testing.T) {
|
||||
},
|
||||
).WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation),
|
||||
),
|
||||
Dependencies: pkg.CompleteWithIndirectDependencies,
|
||||
Metadata: pkg.GolangBinaryBuildinfoEntry{
|
||||
GoCompiledVersion: goCompiledVersion,
|
||||
Architecture: archDetails,
|
||||
@@ -741,6 +751,7 @@ func TestBuildGoPkgInfo(t *testing.T) {
|
||||
},
|
||||
).WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation),
|
||||
),
|
||||
Dependencies: pkg.UnknownDependencyCompleteness,
|
||||
Metadata: pkg.GolangBinaryBuildinfoEntry{
|
||||
GoCompiledVersion: goCompiledVersion,
|
||||
Architecture: archDetails,
|
||||
@@ -762,6 +773,7 @@ func TestBuildGoPkgInfo(t *testing.T) {
|
||||
},
|
||||
).WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation),
|
||||
),
|
||||
Dependencies: pkg.UnknownDependencyCompleteness,
|
||||
Metadata: pkg.GolangBinaryBuildinfoEntry{
|
||||
GoCompiledVersion: goCompiledVersion,
|
||||
Architecture: archDetails,
|
||||
@@ -819,12 +831,14 @@ func TestBuildGoPkgInfo(t *testing.T) {
|
||||
},
|
||||
).WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation),
|
||||
),
|
||||
Dependencies: pkg.UnknownDependencyCompleteness,
|
||||
Metadata: pkg.GolangBinaryBuildinfoEntry{
|
||||
GoCompiledVersion: goCompiledVersion,
|
||||
Architecture: archDetails,
|
||||
H1Digest: "h1:PjhxBct4MZii8FFR8+oeS7QOvxKOTZXgk63EU2XpfJE=",
|
||||
MainModule: "github.com/anchore/syft",
|
||||
}},
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "golang.org/x/term",
|
||||
Version: "v0.0.0-20210916214954-140adaaadfaf",
|
||||
@@ -839,6 +853,7 @@ func TestBuildGoPkgInfo(t *testing.T) {
|
||||
},
|
||||
).WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation),
|
||||
),
|
||||
Dependencies: pkg.UnknownDependencyCompleteness,
|
||||
Metadata: pkg.GolangBinaryBuildinfoEntry{
|
||||
GoCompiledVersion: goCompiledVersion,
|
||||
Architecture: archDetails,
|
||||
@@ -882,6 +897,7 @@ func TestBuildGoPkgInfo(t *testing.T) {
|
||||
},
|
||||
).WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation),
|
||||
),
|
||||
Dependencies: pkg.CompleteWithIndirectDependencies,
|
||||
Metadata: pkg.GolangBinaryBuildinfoEntry{
|
||||
GoCompiledVersion: goCompiledVersion,
|
||||
Architecture: archDetails,
|
||||
@@ -941,6 +957,7 @@ func TestBuildGoPkgInfo(t *testing.T) {
|
||||
},
|
||||
).WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation),
|
||||
),
|
||||
Dependencies: pkg.CompleteWithIndirectDependencies,
|
||||
Metadata: pkg.GolangBinaryBuildinfoEntry{
|
||||
GoCompiledVersion: "go1.22.2",
|
||||
Architecture: archDetails,
|
||||
@@ -993,6 +1010,7 @@ func TestBuildGoPkgInfo(t *testing.T) {
|
||||
},
|
||||
).WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation),
|
||||
),
|
||||
Dependencies: pkg.UnknownDependencyCompleteness,
|
||||
Metadata: pkg.GolangBinaryBuildinfoEntry{
|
||||
GoCompiledVersion: "go1.22.2",
|
||||
Architecture: archDetails,
|
||||
@@ -1013,6 +1031,7 @@ func TestBuildGoPkgInfo(t *testing.T) {
|
||||
},
|
||||
).WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation),
|
||||
),
|
||||
Dependencies: pkg.CompleteWithIndirectDependencies,
|
||||
Metadata: pkg.GolangBinaryBuildinfoEntry{
|
||||
GoCompiledVersion: "go1.22.2",
|
||||
BuildSettings: []pkg.KeyValue{
|
||||
|
||||
@@ -66,6 +66,9 @@ func (c *goModCataloger) parseGoModFile(ctx context.Context, resolver file.Resol
|
||||
PURL: packageURL(m.Mod.Path, m.Mod.Version),
|
||||
Language: pkg.Go,
|
||||
Type: pkg.GoModulePkg,
|
||||
// we don't have a way to express on a package or relationship the nature of "//indirect" markings on dependencies
|
||||
// so though the dependencies are complete and separable with the raw data, the data in the SBOM is not separable.
|
||||
Dependencies: pkg.UnknownDependencyCompleteness,
|
||||
Metadata: pkg.GolangModuleEntry{
|
||||
H1Digest: digests[fmt.Sprintf("%s %s", m.Mod.Path, m.Mod.Version)],
|
||||
},
|
||||
@@ -91,6 +94,9 @@ func (c *goModCataloger) parseGoModFile(ctx context.Context, resolver file.Resol
|
||||
PURL: packageURL(m.New.Path, m.New.Version),
|
||||
Language: pkg.Go,
|
||||
Type: pkg.GoModulePkg,
|
||||
// we don't have a way to express on a package or relationship the nature of "//indirect" markings on dependencies
|
||||
// so though the dependencies are complete and separable with the raw data, the data in the SBOM is not separable.
|
||||
Dependencies: pkg.UnknownDependencyCompleteness,
|
||||
Metadata: pkg.GolangModuleEntry{
|
||||
H1Digest: digests[fmt.Sprintf("%s %s", m.New.Path, m.New.Version)],
|
||||
},
|
||||
|
||||
@@ -18,13 +18,14 @@ func TestParseGoMod(t *testing.T) {
|
||||
fixture: "test-fixtures/one-package",
|
||||
expected: []pkg.Package{
|
||||
{
|
||||
Name: "github.com/bmatcuk/doublestar",
|
||||
Version: "v1.3.1",
|
||||
PURL: "pkg:golang/github.com/bmatcuk/doublestar@v1.3.1",
|
||||
Locations: file.NewLocationSet(file.NewLocation("test-fixtures/one-package")),
|
||||
Language: pkg.Go,
|
||||
Type: pkg.GoModulePkg,
|
||||
Metadata: pkg.GolangModuleEntry{},
|
||||
Name: "github.com/bmatcuk/doublestar",
|
||||
Version: "v1.3.1",
|
||||
PURL: "pkg:golang/github.com/bmatcuk/doublestar@v1.3.1",
|
||||
Locations: file.NewLocationSet(file.NewLocation("test-fixtures/one-package")),
|
||||
Language: pkg.Go,
|
||||
Type: pkg.GoModulePkg,
|
||||
Dependencies: pkg.UnknownDependencyCompleteness,
|
||||
Metadata: pkg.GolangModuleEntry{},
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -33,58 +34,64 @@ func TestParseGoMod(t *testing.T) {
|
||||
fixture: "test-fixtures/many-packages",
|
||||
expected: []pkg.Package{
|
||||
{
|
||||
Name: "github.com/anchore/archiver/v3",
|
||||
Version: "v3.5.2",
|
||||
PURL: "pkg:golang/github.com/anchore/archiver@v3.5.2#v3",
|
||||
Locations: file.NewLocationSet(file.NewLocation("test-fixtures/many-packages")),
|
||||
Language: pkg.Go,
|
||||
Type: pkg.GoModulePkg,
|
||||
Metadata: pkg.GolangModuleEntry{},
|
||||
Name: "github.com/anchore/archiver/v3",
|
||||
Version: "v3.5.2",
|
||||
PURL: "pkg:golang/github.com/anchore/archiver@v3.5.2#v3",
|
||||
Locations: file.NewLocationSet(file.NewLocation("test-fixtures/many-packages")),
|
||||
Language: pkg.Go,
|
||||
Type: pkg.GoModulePkg,
|
||||
Dependencies: pkg.UnknownDependencyCompleteness,
|
||||
Metadata: pkg.GolangModuleEntry{},
|
||||
},
|
||||
{
|
||||
Name: "github.com/anchore/go-testutils",
|
||||
Version: "v0.0.0-20200624184116-66aa578126db",
|
||||
PURL: "pkg:golang/github.com/anchore/go-testutils@v0.0.0-20200624184116-66aa578126db",
|
||||
Locations: file.NewLocationSet(file.NewLocation("test-fixtures/many-packages")),
|
||||
Language: pkg.Go,
|
||||
Type: pkg.GoModulePkg,
|
||||
Metadata: pkg.GolangModuleEntry{},
|
||||
Name: "github.com/anchore/go-testutils",
|
||||
Version: "v0.0.0-20200624184116-66aa578126db",
|
||||
PURL: "pkg:golang/github.com/anchore/go-testutils@v0.0.0-20200624184116-66aa578126db",
|
||||
Locations: file.NewLocationSet(file.NewLocation("test-fixtures/many-packages")),
|
||||
Language: pkg.Go,
|
||||
Type: pkg.GoModulePkg,
|
||||
Dependencies: pkg.UnknownDependencyCompleteness,
|
||||
Metadata: pkg.GolangModuleEntry{},
|
||||
},
|
||||
{
|
||||
Name: "github.com/anchore/go-version",
|
||||
Version: "v1.2.2-0.20200701162849-18adb9c92b9b",
|
||||
PURL: "pkg:golang/github.com/anchore/go-version@v1.2.2-0.20200701162849-18adb9c92b9b",
|
||||
Locations: file.NewLocationSet(file.NewLocation("test-fixtures/many-packages")),
|
||||
Language: pkg.Go,
|
||||
Type: pkg.GoModulePkg,
|
||||
Metadata: pkg.GolangModuleEntry{},
|
||||
Name: "github.com/anchore/go-version",
|
||||
Version: "v1.2.2-0.20200701162849-18adb9c92b9b",
|
||||
PURL: "pkg:golang/github.com/anchore/go-version@v1.2.2-0.20200701162849-18adb9c92b9b",
|
||||
Locations: file.NewLocationSet(file.NewLocation("test-fixtures/many-packages")),
|
||||
Language: pkg.Go,
|
||||
Type: pkg.GoModulePkg,
|
||||
Dependencies: pkg.UnknownDependencyCompleteness,
|
||||
Metadata: pkg.GolangModuleEntry{},
|
||||
},
|
||||
{
|
||||
Name: "github.com/anchore/stereoscope",
|
||||
Version: "v0.0.0-20200706164556-7cf39d7f4639",
|
||||
PURL: "pkg:golang/github.com/anchore/stereoscope@v0.0.0-20200706164556-7cf39d7f4639",
|
||||
Locations: file.NewLocationSet(file.NewLocation("test-fixtures/many-packages")),
|
||||
Language: pkg.Go,
|
||||
Type: pkg.GoModulePkg,
|
||||
Metadata: pkg.GolangModuleEntry{},
|
||||
Name: "github.com/anchore/stereoscope",
|
||||
Version: "v0.0.0-20200706164556-7cf39d7f4639",
|
||||
PURL: "pkg:golang/github.com/anchore/stereoscope@v0.0.0-20200706164556-7cf39d7f4639",
|
||||
Locations: file.NewLocationSet(file.NewLocation("test-fixtures/many-packages")),
|
||||
Language: pkg.Go,
|
||||
Type: pkg.GoModulePkg,
|
||||
Dependencies: pkg.UnknownDependencyCompleteness,
|
||||
Metadata: pkg.GolangModuleEntry{},
|
||||
},
|
||||
{
|
||||
Name: "github.com/bmatcuk/doublestar",
|
||||
Version: "v8.8.8",
|
||||
PURL: "pkg:golang/github.com/bmatcuk/doublestar@v8.8.8",
|
||||
Locations: file.NewLocationSet(file.NewLocation("test-fixtures/many-packages")),
|
||||
Language: pkg.Go,
|
||||
Type: pkg.GoModulePkg,
|
||||
Metadata: pkg.GolangModuleEntry{},
|
||||
Name: "github.com/bmatcuk/doublestar",
|
||||
Version: "v8.8.8",
|
||||
PURL: "pkg:golang/github.com/bmatcuk/doublestar@v8.8.8",
|
||||
Locations: file.NewLocationSet(file.NewLocation("test-fixtures/many-packages")),
|
||||
Language: pkg.Go,
|
||||
Type: pkg.GoModulePkg,
|
||||
Dependencies: pkg.UnknownDependencyCompleteness,
|
||||
Metadata: pkg.GolangModuleEntry{},
|
||||
},
|
||||
{
|
||||
Name: "github.com/go-test/deep",
|
||||
Version: "v1.0.6",
|
||||
PURL: "pkg:golang/github.com/go-test/deep@v1.0.6",
|
||||
Locations: file.NewLocationSet(file.NewLocation("test-fixtures/many-packages")),
|
||||
Language: pkg.Go,
|
||||
Type: pkg.GoModulePkg,
|
||||
Metadata: pkg.GolangModuleEntry{},
|
||||
Name: "github.com/go-test/deep",
|
||||
Version: "v1.0.6",
|
||||
PURL: "pkg:golang/github.com/go-test/deep@v1.0.6",
|
||||
Locations: file.NewLocationSet(file.NewLocation("test-fixtures/many-packages")),
|
||||
Language: pkg.Go,
|
||||
Type: pkg.GoModulePkg,
|
||||
Dependencies: pkg.UnknownDependencyCompleteness,
|
||||
Metadata: pkg.GolangModuleEntry{},
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -111,35 +118,38 @@ func Test_GoSumHashes(t *testing.T) {
|
||||
fixture: "test-fixtures/go-sum-hashes",
|
||||
expected: []pkg.Package{
|
||||
{
|
||||
Name: "github.com/CycloneDX/cyclonedx-go",
|
||||
Version: "v0.6.0",
|
||||
PURL: "pkg:golang/github.com/CycloneDX/cyclonedx-go@v0.6.0",
|
||||
Locations: file.NewLocationSet(file.NewLocation("go.mod")),
|
||||
FoundBy: "go-module-file-cataloger",
|
||||
Language: pkg.Go,
|
||||
Type: pkg.GoModulePkg,
|
||||
Metadata: pkg.GolangModuleEntry{},
|
||||
Name: "github.com/CycloneDX/cyclonedx-go",
|
||||
Version: "v0.6.0",
|
||||
PURL: "pkg:golang/github.com/CycloneDX/cyclonedx-go@v0.6.0",
|
||||
Locations: file.NewLocationSet(file.NewLocation("go.mod")),
|
||||
FoundBy: "go-module-file-cataloger",
|
||||
Language: pkg.Go,
|
||||
Type: pkg.GoModulePkg,
|
||||
Dependencies: pkg.UnknownDependencyCompleteness,
|
||||
Metadata: pkg.GolangModuleEntry{},
|
||||
},
|
||||
{
|
||||
Name: "github.com/acarl005/stripansi",
|
||||
Version: "v0.0.0-20180116102854-5a71ef0e047d",
|
||||
PURL: "pkg:golang/github.com/acarl005/stripansi@v0.0.0-20180116102854-5a71ef0e047d",
|
||||
Locations: file.NewLocationSet(file.NewLocation("go.mod")),
|
||||
FoundBy: "go-module-file-cataloger",
|
||||
Language: pkg.Go,
|
||||
Type: pkg.GoModulePkg,
|
||||
Name: "github.com/acarl005/stripansi",
|
||||
Version: "v0.0.0-20180116102854-5a71ef0e047d",
|
||||
PURL: "pkg:golang/github.com/acarl005/stripansi@v0.0.0-20180116102854-5a71ef0e047d",
|
||||
Locations: file.NewLocationSet(file.NewLocation("go.mod")),
|
||||
FoundBy: "go-module-file-cataloger",
|
||||
Language: pkg.Go,
|
||||
Type: pkg.GoModulePkg,
|
||||
Dependencies: pkg.UnknownDependencyCompleteness,
|
||||
Metadata: pkg.GolangModuleEntry{
|
||||
H1Digest: "h1:licZJFw2RwpHMqeKTCYkitsPqHNxTmd4SNR5r94FGM8=",
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "github.com/mgutz/ansi",
|
||||
Version: "v0.0.0-20200706080929-d51e80ef957d",
|
||||
PURL: "pkg:golang/github.com/mgutz/ansi@v0.0.0-20200706080929-d51e80ef957d",
|
||||
Locations: file.NewLocationSet(file.NewLocation("go.mod")),
|
||||
FoundBy: "go-module-file-cataloger",
|
||||
Language: pkg.Go,
|
||||
Type: pkg.GoModulePkg,
|
||||
Name: "github.com/mgutz/ansi",
|
||||
Version: "v0.0.0-20200706080929-d51e80ef957d",
|
||||
PURL: "pkg:golang/github.com/mgutz/ansi@v0.0.0-20200706080929-d51e80ef957d",
|
||||
Locations: file.NewLocationSet(file.NewLocation("go.mod")),
|
||||
FoundBy: "go-module-file-cataloger",
|
||||
Language: pkg.Go,
|
||||
Type: pkg.GoModulePkg,
|
||||
Dependencies: pkg.UnknownDependencyCompleteness,
|
||||
Metadata: pkg.GolangModuleEntry{
|
||||
H1Digest: "h1:5PJl274Y63IEHC+7izoQE9x6ikvDFZS2mDVS3drnohI=",
|
||||
},
|
||||
|
||||
@@ -14,7 +14,9 @@ func newPackage(name, version string, m any, location file.Location) pkg.Package
|
||||
PURL: packageURL(name, version),
|
||||
Language: pkg.Haskell,
|
||||
Type: pkg.HackagePkg,
|
||||
Metadata: m,
|
||||
// in all cases (cabal, stack, etc.) we do not attempt to glean dependency information
|
||||
Dependencies: pkg.UnknownDependencyCompleteness,
|
||||
Metadata: m,
|
||||
}
|
||||
|
||||
p.SetID()
|
||||
|
||||
@@ -15,92 +15,103 @@ func TestParseCabalFreeze(t *testing.T) {
|
||||
|
||||
expectedPkgs := []pkg.Package{
|
||||
{
|
||||
Name: "Cabal",
|
||||
Version: "3.2.1.0",
|
||||
PURL: "pkg:hackage/Cabal@3.2.1.0",
|
||||
Locations: locationSet,
|
||||
Language: pkg.Haskell,
|
||||
Type: pkg.HackagePkg,
|
||||
Name: "Cabal",
|
||||
Version: "3.2.1.0",
|
||||
PURL: "pkg:hackage/Cabal@3.2.1.0",
|
||||
Locations: locationSet,
|
||||
Language: pkg.Haskell,
|
||||
Type: pkg.HackagePkg,
|
||||
Dependencies: pkg.UnknownDependencyCompleteness,
|
||||
},
|
||||
{
|
||||
Name: "Diff",
|
||||
Version: "0.4.1",
|
||||
PURL: "pkg:hackage/Diff@0.4.1",
|
||||
Locations: locationSet,
|
||||
Language: pkg.Haskell,
|
||||
Type: pkg.HackagePkg,
|
||||
Name: "Diff",
|
||||
Version: "0.4.1",
|
||||
PURL: "pkg:hackage/Diff@0.4.1",
|
||||
Locations: locationSet,
|
||||
Language: pkg.Haskell,
|
||||
Type: pkg.HackagePkg,
|
||||
Dependencies: pkg.UnknownDependencyCompleteness,
|
||||
},
|
||||
{
|
||||
Name: "HTTP",
|
||||
Version: "4000.3.16",
|
||||
PURL: "pkg:hackage/HTTP@4000.3.16",
|
||||
Locations: locationSet,
|
||||
Language: pkg.Haskell,
|
||||
Type: pkg.HackagePkg,
|
||||
Name: "HTTP",
|
||||
Version: "4000.3.16",
|
||||
PURL: "pkg:hackage/HTTP@4000.3.16",
|
||||
Locations: locationSet,
|
||||
Language: pkg.Haskell,
|
||||
Type: pkg.HackagePkg,
|
||||
Dependencies: pkg.UnknownDependencyCompleteness,
|
||||
},
|
||||
{
|
||||
Name: "HUnit",
|
||||
Version: "1.6.2.0",
|
||||
PURL: "pkg:hackage/HUnit@1.6.2.0",
|
||||
Locations: locationSet,
|
||||
Language: pkg.Haskell,
|
||||
Type: pkg.HackagePkg,
|
||||
Name: "HUnit",
|
||||
Version: "1.6.2.0",
|
||||
PURL: "pkg:hackage/HUnit@1.6.2.0",
|
||||
Locations: locationSet,
|
||||
Language: pkg.Haskell,
|
||||
Type: pkg.HackagePkg,
|
||||
Dependencies: pkg.UnknownDependencyCompleteness,
|
||||
},
|
||||
{
|
||||
Name: "OneTuple",
|
||||
Version: "0.3.1",
|
||||
PURL: "pkg:hackage/OneTuple@0.3.1",
|
||||
Locations: locationSet,
|
||||
Language: pkg.Haskell,
|
||||
Type: pkg.HackagePkg,
|
||||
Name: "OneTuple",
|
||||
Version: "0.3.1",
|
||||
PURL: "pkg:hackage/OneTuple@0.3.1",
|
||||
Locations: locationSet,
|
||||
Language: pkg.Haskell,
|
||||
Type: pkg.HackagePkg,
|
||||
Dependencies: pkg.UnknownDependencyCompleteness,
|
||||
},
|
||||
{
|
||||
Name: "Only",
|
||||
Version: "0.1",
|
||||
PURL: "pkg:hackage/Only@0.1",
|
||||
Locations: locationSet,
|
||||
Language: pkg.Haskell,
|
||||
Type: pkg.HackagePkg,
|
||||
Name: "Only",
|
||||
Version: "0.1",
|
||||
PURL: "pkg:hackage/Only@0.1",
|
||||
Locations: locationSet,
|
||||
Language: pkg.Haskell,
|
||||
Type: pkg.HackagePkg,
|
||||
Dependencies: pkg.UnknownDependencyCompleteness,
|
||||
},
|
||||
{
|
||||
Name: "PyF",
|
||||
Version: "0.10.2.0",
|
||||
PURL: "pkg:hackage/PyF@0.10.2.0",
|
||||
Locations: locationSet,
|
||||
Language: pkg.Haskell,
|
||||
Type: pkg.HackagePkg,
|
||||
Name: "PyF",
|
||||
Version: "0.10.2.0",
|
||||
PURL: "pkg:hackage/PyF@0.10.2.0",
|
||||
Locations: locationSet,
|
||||
Language: pkg.Haskell,
|
||||
Type: pkg.HackagePkg,
|
||||
Dependencies: pkg.UnknownDependencyCompleteness,
|
||||
},
|
||||
{
|
||||
Name: "QuickCheck",
|
||||
Version: "2.14.2",
|
||||
PURL: "pkg:hackage/QuickCheck@2.14.2",
|
||||
Locations: locationSet,
|
||||
Language: pkg.Haskell,
|
||||
Type: pkg.HackagePkg,
|
||||
Name: "QuickCheck",
|
||||
Version: "2.14.2",
|
||||
PURL: "pkg:hackage/QuickCheck@2.14.2",
|
||||
Locations: locationSet,
|
||||
Language: pkg.Haskell,
|
||||
Type: pkg.HackagePkg,
|
||||
Dependencies: pkg.UnknownDependencyCompleteness,
|
||||
},
|
||||
{
|
||||
Name: "RSA",
|
||||
Version: "2.4.1",
|
||||
PURL: "pkg:hackage/RSA@2.4.1",
|
||||
Locations: locationSet,
|
||||
Language: pkg.Haskell,
|
||||
Type: pkg.HackagePkg,
|
||||
Name: "RSA",
|
||||
Version: "2.4.1",
|
||||
PURL: "pkg:hackage/RSA@2.4.1",
|
||||
Locations: locationSet,
|
||||
Language: pkg.Haskell,
|
||||
Type: pkg.HackagePkg,
|
||||
Dependencies: pkg.UnknownDependencyCompleteness,
|
||||
},
|
||||
{
|
||||
Name: "SHA",
|
||||
Version: "1.6.4.4",
|
||||
PURL: "pkg:hackage/SHA@1.6.4.4",
|
||||
Locations: locationSet,
|
||||
Language: pkg.Haskell,
|
||||
Type: pkg.HackagePkg,
|
||||
Name: "SHA",
|
||||
Version: "1.6.4.4",
|
||||
PURL: "pkg:hackage/SHA@1.6.4.4",
|
||||
Locations: locationSet,
|
||||
Language: pkg.Haskell,
|
||||
Type: pkg.HackagePkg,
|
||||
Dependencies: pkg.UnknownDependencyCompleteness,
|
||||
},
|
||||
{
|
||||
Name: "Spock",
|
||||
Version: "0.14.0.0",
|
||||
PURL: "pkg:hackage/Spock@0.14.0.0",
|
||||
Locations: locationSet,
|
||||
Language: pkg.Haskell,
|
||||
Type: pkg.HackagePkg,
|
||||
Name: "Spock",
|
||||
Version: "0.14.0.0",
|
||||
PURL: "pkg:hackage/Spock@0.14.0.0",
|
||||
Locations: locationSet,
|
||||
Language: pkg.Haskell,
|
||||
Type: pkg.HackagePkg,
|
||||
Dependencies: pkg.UnknownDependencyCompleteness,
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
@@ -16,108 +16,117 @@ func TestParseStackLock(t *testing.T) {
|
||||
|
||||
expectedPkgs := []pkg.Package{
|
||||
{
|
||||
Name: "HTTP",
|
||||
Version: "4000.3.16",
|
||||
PURL: "pkg:hackage/HTTP@4000.3.16",
|
||||
Locations: locationSet,
|
||||
Language: pkg.Haskell,
|
||||
Type: pkg.HackagePkg,
|
||||
Name: "HTTP",
|
||||
Version: "4000.3.16",
|
||||
PURL: "pkg:hackage/HTTP@4000.3.16",
|
||||
Locations: locationSet,
|
||||
Language: pkg.Haskell,
|
||||
Type: pkg.HackagePkg,
|
||||
Dependencies: pkg.UnknownDependencyCompleteness,
|
||||
Metadata: pkg.HackageStackYamlLockEntry{
|
||||
PkgHash: "6042643c15a0b43e522a6693f1e322f05000d519543a84149cb80aeffee34f71",
|
||||
SnapshotURL: url,
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "configurator-pg",
|
||||
Version: "0.2.6",
|
||||
PURL: "pkg:hackage/configurator-pg@0.2.6",
|
||||
Locations: locationSet,
|
||||
Language: pkg.Haskell,
|
||||
Type: pkg.HackagePkg,
|
||||
Name: "configurator-pg",
|
||||
Version: "0.2.6",
|
||||
PURL: "pkg:hackage/configurator-pg@0.2.6",
|
||||
Locations: locationSet,
|
||||
Language: pkg.Haskell,
|
||||
Type: pkg.HackagePkg,
|
||||
Dependencies: pkg.UnknownDependencyCompleteness,
|
||||
Metadata: pkg.HackageStackYamlLockEntry{
|
||||
PkgHash: "cd9b06a458428e493a4d6def725af7ab1ab0fef678fbd871f9586fc7f9aa70be",
|
||||
SnapshotURL: url,
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "hasql-dynamic-statements",
|
||||
Version: "0.3.1.1",
|
||||
PURL: "pkg:hackage/hasql-dynamic-statements@0.3.1.1",
|
||||
Locations: locationSet,
|
||||
Language: pkg.Haskell,
|
||||
Type: pkg.HackagePkg,
|
||||
Name: "hasql-dynamic-statements",
|
||||
Version: "0.3.1.1",
|
||||
PURL: "pkg:hackage/hasql-dynamic-statements@0.3.1.1",
|
||||
Locations: locationSet,
|
||||
Language: pkg.Haskell,
|
||||
Type: pkg.HackagePkg,
|
||||
Dependencies: pkg.UnknownDependencyCompleteness,
|
||||
Metadata: pkg.HackageStackYamlLockEntry{
|
||||
PkgHash: "2cfe6e75990e690f595a87cbe553f2e90fcd738610f6c66749c81cc4396b2cc4",
|
||||
SnapshotURL: url,
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "hasql-implicits",
|
||||
Version: "0.1.0.4",
|
||||
PURL: "pkg:hackage/hasql-implicits@0.1.0.4",
|
||||
Locations: locationSet,
|
||||
Language: pkg.Haskell,
|
||||
Type: pkg.HackagePkg,
|
||||
Name: "hasql-implicits",
|
||||
Version: "0.1.0.4",
|
||||
PURL: "pkg:hackage/hasql-implicits@0.1.0.4",
|
||||
Locations: locationSet,
|
||||
Language: pkg.Haskell,
|
||||
Type: pkg.HackagePkg,
|
||||
Dependencies: pkg.UnknownDependencyCompleteness,
|
||||
Metadata: pkg.HackageStackYamlLockEntry{
|
||||
PkgHash: "0848d3cbc9d94e1e539948fa0be4d0326b26335034161bf8076785293444ca6f",
|
||||
SnapshotURL: url,
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "hasql-pool",
|
||||
Version: "0.5.2.2",
|
||||
PURL: "pkg:hackage/hasql-pool@0.5.2.2",
|
||||
Locations: locationSet,
|
||||
Language: pkg.Haskell,
|
||||
Type: pkg.HackagePkg,
|
||||
Name: "hasql-pool",
|
||||
Version: "0.5.2.2",
|
||||
PURL: "pkg:hackage/hasql-pool@0.5.2.2",
|
||||
Locations: locationSet,
|
||||
Language: pkg.Haskell,
|
||||
Type: pkg.HackagePkg,
|
||||
Dependencies: pkg.UnknownDependencyCompleteness,
|
||||
Metadata: pkg.HackageStackYamlLockEntry{
|
||||
PkgHash: "b56d4dea112d97a2ef4b2749508c0ca646828cb2d77b827e8dc433d249bb2062",
|
||||
SnapshotURL: url,
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "lens-aeson",
|
||||
Version: "1.1.3",
|
||||
PURL: "pkg:hackage/lens-aeson@1.1.3",
|
||||
Locations: locationSet,
|
||||
Language: pkg.Haskell,
|
||||
Type: pkg.HackagePkg,
|
||||
Name: "lens-aeson",
|
||||
Version: "1.1.3",
|
||||
PURL: "pkg:hackage/lens-aeson@1.1.3",
|
||||
Locations: locationSet,
|
||||
Language: pkg.Haskell,
|
||||
Type: pkg.HackagePkg,
|
||||
Dependencies: pkg.UnknownDependencyCompleteness,
|
||||
Metadata: pkg.HackageStackYamlLockEntry{
|
||||
PkgHash: "52c8eaecd2d1c2a969c0762277c4a8ee72c339a686727d5785932e72ef9c3050",
|
||||
SnapshotURL: url,
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "optparse-applicative",
|
||||
Version: "0.16.1.0",
|
||||
PURL: "pkg:hackage/optparse-applicative@0.16.1.0",
|
||||
Locations: locationSet,
|
||||
Language: pkg.Haskell,
|
||||
Type: pkg.HackagePkg,
|
||||
Name: "optparse-applicative",
|
||||
Version: "0.16.1.0",
|
||||
PURL: "pkg:hackage/optparse-applicative@0.16.1.0",
|
||||
Locations: locationSet,
|
||||
Language: pkg.Haskell,
|
||||
Type: pkg.HackagePkg,
|
||||
Dependencies: pkg.UnknownDependencyCompleteness,
|
||||
Metadata: pkg.HackageStackYamlLockEntry{
|
||||
PkgHash: "418c22ed6a19124d457d96bc66bd22c93ac22fad0c7100fe4972bbb4ac989731",
|
||||
SnapshotURL: url,
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "protolude",
|
||||
Version: "0.3.2",
|
||||
PURL: "pkg:hackage/protolude@0.3.2",
|
||||
Locations: locationSet,
|
||||
Language: pkg.Haskell,
|
||||
Type: pkg.HackagePkg,
|
||||
Name: "protolude",
|
||||
Version: "0.3.2",
|
||||
PURL: "pkg:hackage/protolude@0.3.2",
|
||||
Locations: locationSet,
|
||||
Language: pkg.Haskell,
|
||||
Type: pkg.HackagePkg,
|
||||
Dependencies: pkg.UnknownDependencyCompleteness,
|
||||
Metadata: pkg.HackageStackYamlLockEntry{
|
||||
PkgHash: "2a38b3dad40d238ab644e234b692c8911423f9d3ed0e36b62287c4a698d92cd1",
|
||||
SnapshotURL: url,
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "ptr",
|
||||
Version: "0.16.8.2",
|
||||
PURL: "pkg:hackage/ptr@0.16.8.2",
|
||||
Locations: locationSet,
|
||||
Language: pkg.Haskell,
|
||||
Type: pkg.HackagePkg,
|
||||
Name: "ptr",
|
||||
Version: "0.16.8.2",
|
||||
PURL: "pkg:hackage/ptr@0.16.8.2",
|
||||
Locations: locationSet,
|
||||
Language: pkg.Haskell,
|
||||
Type: pkg.HackagePkg,
|
||||
Dependencies: pkg.UnknownDependencyCompleteness,
|
||||
Metadata: pkg.HackageStackYamlLockEntry{
|
||||
PkgHash: "708ebb95117f2872d2c5a554eb6804cf1126e86abe793b2673f913f14e5eb1ac",
|
||||
SnapshotURL: url,
|
||||
|
||||
@@ -15,89 +15,97 @@ func TestParseStackYaml(t *testing.T) {
|
||||
|
||||
expectedPkgs := []pkg.Package{
|
||||
{
|
||||
Name: "ShellCheck",
|
||||
Version: "0.8.0",
|
||||
PURL: "pkg:hackage/ShellCheck@0.8.0",
|
||||
Locations: locationSet,
|
||||
Language: pkg.Haskell,
|
||||
Type: pkg.HackagePkg,
|
||||
Name: "ShellCheck",
|
||||
Version: "0.8.0",
|
||||
PURL: "pkg:hackage/ShellCheck@0.8.0",
|
||||
Locations: locationSet,
|
||||
Language: pkg.Haskell,
|
||||
Type: pkg.HackagePkg,
|
||||
Dependencies: pkg.UnknownDependencyCompleteness,
|
||||
Metadata: pkg.HackageStackYamlEntry{
|
||||
PkgHash: "353c9322847b661e4c6f7c83c2acf8e5c08b682fbe516c7d46c29605937543df",
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "colourista",
|
||||
Version: "0.1.0.1",
|
||||
PURL: "pkg:hackage/colourista@0.1.0.1",
|
||||
Locations: locationSet,
|
||||
Language: pkg.Haskell,
|
||||
Type: pkg.HackagePkg,
|
||||
Name: "colourista",
|
||||
Version: "0.1.0.1",
|
||||
PURL: "pkg:hackage/colourista@0.1.0.1",
|
||||
Locations: locationSet,
|
||||
Language: pkg.Haskell,
|
||||
Type: pkg.HackagePkg,
|
||||
Dependencies: pkg.UnknownDependencyCompleteness,
|
||||
Metadata: pkg.HackageStackYamlEntry{
|
||||
PkgHash: "98353ee0e2f5d97d2148513f084c1cd37dfda03e48aa9dd7a017c9d9c0ba710e",
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "language-docker",
|
||||
Version: "11.0.0",
|
||||
PURL: "pkg:hackage/language-docker@11.0.0",
|
||||
Locations: locationSet,
|
||||
Language: pkg.Haskell,
|
||||
Type: pkg.HackagePkg,
|
||||
Name: "language-docker",
|
||||
Version: "11.0.0",
|
||||
PURL: "pkg:hackage/language-docker@11.0.0",
|
||||
Locations: locationSet,
|
||||
Language: pkg.Haskell,
|
||||
Type: pkg.HackagePkg,
|
||||
Dependencies: pkg.UnknownDependencyCompleteness,
|
||||
Metadata: pkg.HackageStackYamlEntry{
|
||||
PkgHash: "3406ff0c1d592490f53ead8cf2cd22bdf3d79fd125ccaf3add683f6d71c24d55",
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "spdx",
|
||||
Version: "1.0.0.2",
|
||||
PURL: "pkg:hackage/spdx@1.0.0.2",
|
||||
Locations: locationSet,
|
||||
Language: pkg.Haskell,
|
||||
Type: pkg.HackagePkg,
|
||||
Name: "spdx",
|
||||
Version: "1.0.0.2",
|
||||
PURL: "pkg:hackage/spdx@1.0.0.2",
|
||||
Locations: locationSet,
|
||||
Language: pkg.Haskell,
|
||||
Type: pkg.HackagePkg,
|
||||
Dependencies: pkg.UnknownDependencyCompleteness,
|
||||
Metadata: pkg.HackageStackYamlEntry{
|
||||
PkgHash: "7dfac9b454ff2da0abb7560f0ffbe00ae442dd5cb76e8be469f77e6988a70fed",
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "hspec",
|
||||
Version: "2.9.4",
|
||||
PURL: "pkg:hackage/hspec@2.9.4",
|
||||
Locations: locationSet,
|
||||
Language: pkg.Haskell,
|
||||
Type: pkg.HackagePkg,
|
||||
Name: "hspec",
|
||||
Version: "2.9.4",
|
||||
PURL: "pkg:hackage/hspec@2.9.4",
|
||||
Locations: locationSet,
|
||||
Language: pkg.Haskell,
|
||||
Type: pkg.HackagePkg,
|
||||
Dependencies: pkg.UnknownDependencyCompleteness,
|
||||
Metadata: pkg.HackageStackYamlEntry{
|
||||
PkgHash: "658a6a74d5a70c040edd6df2a12228c6d9e63082adaad1ed4d0438ad082a0ef3",
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "hspec-core",
|
||||
Version: "2.9.4",
|
||||
PURL: "pkg:hackage/hspec-core@2.9.4",
|
||||
Locations: locationSet,
|
||||
Language: pkg.Haskell,
|
||||
Type: pkg.HackagePkg,
|
||||
Name: "hspec-core",
|
||||
Version: "2.9.4",
|
||||
PURL: "pkg:hackage/hspec-core@2.9.4",
|
||||
Locations: locationSet,
|
||||
Language: pkg.Haskell,
|
||||
Type: pkg.HackagePkg,
|
||||
Dependencies: pkg.UnknownDependencyCompleteness,
|
||||
Metadata: pkg.HackageStackYamlEntry{
|
||||
PkgHash: "a126e9087409fef8dcafcd2f8656456527ac7bb163ed4d9cb3a57589042a5fe8",
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "hspec-discover",
|
||||
Version: "2.9.4",
|
||||
PURL: "pkg:hackage/hspec-discover@2.9.4",
|
||||
Locations: locationSet,
|
||||
Language: pkg.Haskell,
|
||||
Type: pkg.HackagePkg,
|
||||
Name: "hspec-discover",
|
||||
Version: "2.9.4",
|
||||
PURL: "pkg:hackage/hspec-discover@2.9.4",
|
||||
Locations: locationSet,
|
||||
Language: pkg.Haskell,
|
||||
Type: pkg.HackagePkg,
|
||||
Dependencies: pkg.UnknownDependencyCompleteness,
|
||||
Metadata: pkg.HackageStackYamlEntry{
|
||||
PkgHash: "fbcf49ecfc3d4da53e797fd0275264cba776ffa324ee223e2a3f4ec2d2c9c4a6",
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "stm",
|
||||
Version: "2.5.0.2",
|
||||
PURL: "pkg:hackage/stm@2.5.0.2",
|
||||
Locations: locationSet,
|
||||
Language: pkg.Haskell,
|
||||
Type: pkg.HackagePkg,
|
||||
Name: "stm",
|
||||
Version: "2.5.0.2",
|
||||
PURL: "pkg:hackage/stm@2.5.0.2",
|
||||
Locations: locationSet,
|
||||
Language: pkg.Haskell,
|
||||
Type: pkg.HackagePkg,
|
||||
Dependencies: pkg.UnknownDependencyCompleteness,
|
||||
Metadata: pkg.HackageStackYamlEntry{
|
||||
PkgHash: "e4dc6473faaa75fbd7eccab4e3ee1d651d75bb0e49946ef0b8b751ccde771a55",
|
||||
},
|
||||
|
||||
@@ -7269,6 +7269,9 @@
|
||||
"add-to-cart-direct-checkout-for-woocommerce": [
|
||||
"cpe:2.3:a:piwebsolution:add-to-cart-direct-checkout-for-woocommerce:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"add-widget-after-content": [
|
||||
"cpe:2.3:a:arelthiaphillips:add_widget_after_content:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"addon-elements-for-elementor-page-builder": [
|
||||
"cpe:2.3:a:webtechstreet:elementor_addon_elements:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -7541,7 +7544,7 @@
|
||||
"cpe:2.3:a:plugins360:all-in-one_video_gallery:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"all-in-one-wp-migration": [
|
||||
"cpe:2.3:a:servmask:all-in-one_wp_migration:*:*:*:*:*:wordpress:*:*"
|
||||
"cpe:2.3:a:servmask:all-in-one_wp_migration:*:*:*:*:free:wordpress:*:*"
|
||||
],
|
||||
"all-in-one-wp-security-and-firewall": [
|
||||
"cpe:2.3:a:tips_and_tricks_hq:all_in_one_wordpress_security_and_firewall:*:*:*:*:*:wordpress:*:*",
|
||||
@@ -7552,6 +7555,9 @@
|
||||
"allow-php-in-posts-and-pages": [
|
||||
"cpe:2.3:a:hitreach:allow_php_in_posts_and_pages:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"allpost-contactform": [
|
||||
"cpe:2.3:a:rainbow-link:all_post_contact_form:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"alma-gateway-for-woocommerce": [
|
||||
"cpe:2.3:a:almapay:alma:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -7646,6 +7652,9 @@
|
||||
"analytics-tracker": [
|
||||
"cpe:2.3:a:analytics_tracker_project:analytics_tracker:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"anchor-episodes-index": [
|
||||
"cpe:2.3:a:jesweb:anchor_episodes_index:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"animate-it": [
|
||||
"cpe:2.3:a:eleopard:animate_it\\!:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -8016,6 +8025,9 @@
|
||||
"baslider": [
|
||||
"cpe:2.3:a:nextcode:image_slider_by_nextcode:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"basticom-framework": [
|
||||
"cpe:2.3:a:basticom:framework:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"batch-cat": [
|
||||
"cpe:2.3:a:batch_cat_project:batch_cat:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -8023,6 +8035,9 @@
|
||||
"cpe:2.3:a:brainstormforce:cards_for_beaver_builder:*:*:*:*:*:wordpress:*:*",
|
||||
"cpe:2.3:a:ultimateaddons:cards_for_beaver_builder:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"bbp-core": [
|
||||
"cpe:2.3:a:spider-themes:bbp_core:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"bbp-move-topics": [
|
||||
"cpe:2.3:a:bbpress_move_topics_project:bbpress_move_topics:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -8051,6 +8066,9 @@
|
||||
"bdthemes-element-pack-lite#tags": [
|
||||
"cpe:2.3:a:bdthemes:element_pack:*:*:*:*:lite:wordpress:*:*"
|
||||
],
|
||||
"bdthemes-prime-slider-lite": [
|
||||
"cpe:2.3:a:bdthemes:prime_slider:*:*:*:*:free:wordpress:*:*"
|
||||
],
|
||||
"bdvs-password-reset": [
|
||||
"cpe:2.3:a:bedevious:password_reset_with_code_for_wordpress_rest_api:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -8104,7 +8122,7 @@
|
||||
"cpe:2.3:a:solidwp:solid_security:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"betterlinks": [
|
||||
"cpe:2.3:a:wpdeveloper:betterlinks:*:*:*:*:*:wordpress:*:*"
|
||||
"cpe:2.3:a:wpdeveloper:betterlinks:*:*:*:*:free:wordpress:*:*"
|
||||
],
|
||||
"bft-autoresponder": [
|
||||
"cpe:2.3:a:kibokolabs:arigato_autoresponder_and_newsletter:*:*:*:*:*:wordpress:*:*"
|
||||
@@ -8261,7 +8279,7 @@
|
||||
"cpe:2.3:a:bookingholdings:booking.com_product_helper:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"bookingpress-appointment-booking": [
|
||||
"cpe:2.3:a:reputeinfosystems:bookingpress:*:*:*:*:*:wordpress:*:*"
|
||||
"cpe:2.3:a:reputeinfosystems:bookingpress:*:*:*:*:free:wordpress:*:*"
|
||||
],
|
||||
"bookit": [
|
||||
"cpe:2.3:a:stylemixthemes:bookit:*:*:*:*:*:wordpress:*:*"
|
||||
@@ -8765,6 +8783,9 @@
|
||||
"clerkio": [
|
||||
"cpe:2.3:a:clerk:clerk.io:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"clever-fox": [
|
||||
"cpe:2.3:a:nayrathemes:clever_fox:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"click-datos-lopd": [
|
||||
"cpe:2.3:a:clickdatos:proteccion_de_datos_rgpd:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -9260,6 +9281,9 @@
|
||||
"cpe:2.3:a:codeless:cowidgets_-_elementor:*:*:*:*:*:wordpress:*:*",
|
||||
"cpe:2.3:a:codeless:cowidgets_elementor_addons:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"cozy-addons": [
|
||||
"cpe:2.3:a:cozythemes:cozy_blocks:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"cp-appointment-calendar": [
|
||||
"cpe:2.3:a:codepeople:cp_appointment_calendar:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -10226,6 +10250,9 @@
|
||||
"enable-svg-webp-ico-upload": [
|
||||
"cpe:2.3:a:ideastocode:enable_svg\\,_webp_\\\u0026_ico_upload:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"endless-posts-navigation": [
|
||||
"cpe:2.3:a:androidbubbles:endless_posts_navigation:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"english-wp-admin": [
|
||||
"cpe:2.3:a:english_wordpress_admin_project:english_wordpress_admin:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -10280,7 +10307,8 @@
|
||||
"cpe:2.3:a:eshop_project:eshop:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"essential-addons-for-elementor-lite": [
|
||||
"cpe:2.3:a:wpdeveloper:essential_addons_for_elementor:*:*:*:*:*:wordpress:*:*"
|
||||
"cpe:2.3:a:wpdeveloper:essential_addons_for_elementor:*:*:*:*:*:wordpress:*:*",
|
||||
"cpe:2.3:a:wpdeveloper:essential_addons_for_elementor:*:*:*:*:lite:wordpress:*:*"
|
||||
],
|
||||
"essential-blocks": [
|
||||
"cpe:2.3:a:wpdeveloper:essential_blocks:*:*:*:*:*:wordpress:*:*",
|
||||
@@ -10443,7 +10471,7 @@
|
||||
"cpe:2.3:a:export_users_to_csv_project:export_users_to_csv:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"export-woocommerce": [
|
||||
"cpe:2.3:a:wpfactory:products\\,_order_\\\u0026_customers_export_for_woocommerce:*:*:*:*:*:wordpress:*:*"
|
||||
"cpe:2.3:a:wpfactory:products\\,_order_\\\u0026_customers_export_for_woocommerce:*:*:*:*:free:wordpress:*:*"
|
||||
],
|
||||
"export-woocommerce-customer-list": [
|
||||
"cpe:2.3:a:piwebsolution:export_customers_list_csv_for_woocommerce:*:*:*:*:*:*:*:*"
|
||||
@@ -10683,9 +10711,16 @@
|
||||
"flexi-quote-rotator": [
|
||||
"cpe:2.3:a:flexi_quote_rotator_project:flexi_quote_rotator:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"flexible-checkout-fields": [
|
||||
"cpe:2.3:a:wpdesk:flexible_checkout_fields:*:*:*:*:free:wordpress:*:*"
|
||||
],
|
||||
"flexible-elementor-panel": [
|
||||
"cpe:2.3:a:webmat:flexible_elementor_panel:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"flexible-shipping-ups": [
|
||||
"cpe:2.3:a:octolize:woocommerce_ups_shipping:*:*:*:*:free:wordpress:*:*",
|
||||
"cpe:2.3:a:octolize:woocommerce_ups_shipping:*:*:*:*:pro:wordpress:*:*"
|
||||
],
|
||||
"flickr-justified-gallery": [
|
||||
"cpe:2.3:a:flickr_justified_gallery_project:flickr_justified_gallery:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -11920,6 +11955,9 @@
|
||||
"iq-block-country": [
|
||||
"cpe:2.3:a:webence:iq_block_country:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"ithemelandco-woo-report": [
|
||||
"cpe:2.3:a:ithemelandco:woocommerce_report:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"iubenda-cookie-law-solution": [
|
||||
"cpe:2.3:a:iubenda:iubenda-cookie-law-solution:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -12082,6 +12120,9 @@
|
||||
"kangu": [
|
||||
"cpe:2.3:a:kangu:kangu:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"kata-plus": [
|
||||
"cpe:2.3:a:climaxthemes:kata_plus:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"kau-boys-backend-localization": [
|
||||
"cpe:2.3:a:kau-boys:backend_localization:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -12121,6 +12162,9 @@
|
||||
"klaviyo": [
|
||||
"cpe:2.3:a:klaviyo:klavio:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"knowledgebase": [
|
||||
"cpe:2.3:a:webberzone:knowledge_base:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"kodex-posts-likes": [
|
||||
"cpe:2.3:a:pierros:kodex_posts_likes:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -12604,6 +12648,9 @@
|
||||
"martins-link-network": [
|
||||
"cpe:2.3:a:martinstools:free_\\\u0026_easy_link_building:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"mas-addons-for-elementor": [
|
||||
"cpe:2.3:a:madrasthemes:mas_elementor:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"mas-static-content": [
|
||||
"cpe:2.3:a:madrasthemes:mas_static_content:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -12710,12 +12757,18 @@
|
||||
"meks-audio-player": [
|
||||
"cpe:2.3:a:mekshq:meks_audio_player:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"meks-easy-ads-widget": [
|
||||
"cpe:2.3:a:mekshq:meks_easy_ads_widget:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"meks-easy-instagram-widget": [
|
||||
"cpe:2.3:a:mekshq:meks_easy_photo_feed_widget:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"meks-flexible-shortcodes": [
|
||||
"cpe:2.3:a:mekshq:meks_flexible_shortcodes:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"meks-smart-author-widget": [
|
||||
"cpe:2.3:a:mekshq:meks_smart_author_widget:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"meks-smart-social-widget": [
|
||||
"cpe:2.3:a:mekshq:meks_smart_social_widget:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -12852,6 +12905,9 @@
|
||||
"mobile-login-woocommerce": [
|
||||
"cpe:2.3:a:xootix:otp_login_woocommerce_\\\u0026_gravity_forms:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"mobile-menu": [
|
||||
"cpe:2.3:a:freshlightlab:wp_mobile_menu:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"modal-dialog": [
|
||||
"cpe:2.3:a:modal_dialog_project:modal_dialog:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -13158,6 +13214,9 @@
|
||||
"news-announcement-scroll": [
|
||||
"cpe:2.3:a:storeapps:news_announcement_scroll:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"news-kit-elementor-addons": [
|
||||
"cpe:2.3:a:blazethemes:news_kit_elementor_addons:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"newsletter": [
|
||||
"cpe:2.3:a:thenewsletterplugin:newsletter:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -13220,6 +13279,9 @@
|
||||
"cpe:2.3:a:ninjaforms:contact_form:*:*:*:*:*:wordpress:*:*",
|
||||
"cpe:2.3:a:ninjaforms:ninja_forms:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"ninja-gdpr-compliance": [
|
||||
"cpe:2.3:a:ninjateam:gdpr_ccpa_compliance_\\\u0026_cookie_consent_banner:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"ninja-job-board": [
|
||||
"cpe:2.3:a:wpmanageninja:ninja_job_board:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -13785,6 +13847,9 @@
|
||||
"cpe:2.3:a:web-dorado:spidervplayer:*:*:*:*:*:wordpress:*:*",
|
||||
"cpe:2.3:a:web-dorado:web-dorado_spider_video_player:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"plexx-elementor-extension": [
|
||||
"cpe:2.3:a:themeworm:plexx_elementor_extension:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"plugin-logic": [
|
||||
"cpe:2.3:a:plugin_logic_project:plugin_logic:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -14040,6 +14105,9 @@
|
||||
"cpe:2.3:a:leap13:premium_addons_for_elementor:*:*:*:*:*:wordpress:*:*",
|
||||
"cpe:2.3:a:leap13:premium_addons_for_elementor:*:*:*:*:pro:wordpress:*:*"
|
||||
],
|
||||
"premium-seo-pack": [
|
||||
"cpe:2.3:a:squirrly:premium_seo_pack:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"premmerce": [
|
||||
"cpe:2.3:a:premmerce:premmerce:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -14131,6 +14199,9 @@
|
||||
"cpe:2.3:a:awesometogi:product-category-tree:*:*:*:*:*:wordpress:*:*",
|
||||
"cpe:2.3:a:awesometogi:product_category_tree:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"product-delivery-date-for-woocommerce-lite": [
|
||||
"cpe:2.3:a:tychesoftwares:product_delivery_date_for_woocommerce:*:*:*:*:lite:wordpress:*:*"
|
||||
],
|
||||
"product-designer": [
|
||||
"cpe:2.3:a:pickplugins:product_designer:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -14159,6 +14230,9 @@
|
||||
"profilegrid-user-profiles-groups-and-communities": [
|
||||
"cpe:2.3:a:metagauss:profilegrid:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"profilepress-pro": [
|
||||
"cpe:2.3:a:properfraction:profilepress:*:*:*:*:pro:wordpress:*:*"
|
||||
],
|
||||
"profit-products-tables-for-woocommerce": [
|
||||
"cpe:2.3:a:pluginus:woot:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -14701,6 +14775,7 @@
|
||||
"cpe:2.3:a:coderevolution:echo_rss_feed_post_generator:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"rss-feed-widget": [
|
||||
"cpe:2.3:a:fahadmahmood:rss_feed_widget:*:*:*:*:*:wordpress:*:*",
|
||||
"cpe:2.3:a:rss_feed_widget_project:rss_feed_widget:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"rss-for-yandex-turbo": [
|
||||
@@ -15045,7 +15120,8 @@
|
||||
"cpe:2.3:a:bainternet:shortcodes_ui:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"shortcodes-ultimate": [
|
||||
"cpe:2.3:a:getshortcodes:shortcodes_ultimate:*:*:*:*:*:wordpress:*:*"
|
||||
"cpe:2.3:a:getshortcodes:shortcodes_ultimate:*:*:*:*:*:wordpress:*:*",
|
||||
"cpe:2.3:a:getshortcodes:shortcodes_ultimate:*:*:*:*:-:wordpress:*:*"
|
||||
],
|
||||
"shortcut-macros": [
|
||||
"cpe:2.3:a:shortcut_macros_project:shortcut_macros:*:*:*:*:*:wordpress:*:*"
|
||||
@@ -15350,7 +15426,8 @@
|
||||
"cpe:2.3:a:simplygallery:simply_gallery_blocks_with_lightbox:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"simply-schedule-appointments": [
|
||||
"cpe:2.3:a:nsqua:simply_schedule_appointments:*:*:*:*:*:wordpress:*:*"
|
||||
"cpe:2.3:a:nsqua:simply_schedule_appointments:*:*:*:*:*:wordpress:*:*",
|
||||
"cpe:2.3:a:nsquared:simply_schedule_appointments:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"sina-extension-for-elementor": [
|
||||
"cpe:2.3:a:shaosina:sina_extension_for_elementor:*:*:*:*:*:wordpress:*:*",
|
||||
@@ -15840,7 +15917,7 @@
|
||||
"cpe:2.3:a:instawp:string_locator:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"strong-testimonials": [
|
||||
"cpe:2.3:a:machothemes:strong_testimonials:*:*:*:*:*:wordpress:*:*"
|
||||
"cpe:2.3:a:wpchill:strong_testimonials:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"structured-content": [
|
||||
"cpe:2.3:a:wpsc-plugin:structured_content:*:*:*:*:*:wordpress:*:*"
|
||||
@@ -16284,6 +16361,9 @@
|
||||
"transbank-webpay-plus-rest": [
|
||||
"cpe:2.3:a:transbank:transbank_webpay_rest:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"transients-manager": [
|
||||
"cpe:2.3:a:wpbeginner:transients_manager:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"transition-slider-lite": [
|
||||
"cpe:2.3:a:creativeinteractivemedia:transition_slider:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -16790,6 +16870,9 @@
|
||||
"vm-backups": [
|
||||
"cpe:2.3:a:vm_backups_project:vm_backups:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"vod-infomaniak": [
|
||||
"cpe:2.3:a:infomaniak:vod_infomaniak:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"vospari-forms": [
|
||||
"cpe:2.3:a:vospari_forms_project:vospari_forms:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -16872,6 +16955,7 @@
|
||||
"cpe:2.3:a:ilghera:woocommerce_support_system:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"wc-vendors": [
|
||||
"cpe:2.3:a:rymera:wc_vendors:*:*:*:*:free:wordpress:*:*",
|
||||
"cpe:2.3:a:wcvendors:woocommerce_multi-vendor\\,_woocommerce_marketplace\\,_product_vendors:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"wc4bp": [
|
||||
@@ -17024,6 +17108,9 @@
|
||||
"whizz": [
|
||||
"cpe:2.3:a:browserweb:whizz:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"whizzy": [
|
||||
"cpe:2.3:a:upqode:whizzy:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"wholesale-pricing-woocommerce": [
|
||||
"cpe:2.3:a:wpfactory:quantity_dynamic_pricing_\\\u0026_bulk_discounts_for_woocommerce:*:*:*:*:free:wordpress:*:*"
|
||||
],
|
||||
@@ -17209,12 +17296,18 @@
|
||||
"woo-related-products-refresh-on-reload": [
|
||||
"cpe:2.3:a:peachpay:related_products_for_woocommerce:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"woo-save-abandoned-carts": [
|
||||
"cpe:2.3:a:majas-lapu-izstrade:cartbounty:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"woo-shipping-dpd-baltic": [
|
||||
"cpe:2.3:a:dpdgroup:woocommerce_shipping:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"woo-smart-wishlist": [
|
||||
"cpe:2.3:a:wpclever:wpc_smart_wishlist_for_woocommerce:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"woo-social-login": [
|
||||
"cpe:2.3:a:wpwebelite:woocommerce_social_login:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"woo-stripe-payment": [
|
||||
"cpe:2.3:a:paymentplugins:stripe_for_woocommerce:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -17246,6 +17339,9 @@
|
||||
"woo-zoho": [
|
||||
"cpe:2.3:a:crmperks:integration_for_woocommerce_and_zoho_crm\\,_books\\,_invoice\\,_inventory\\,_bigin:*:*:*:*:*:*:*:*"
|
||||
],
|
||||
"wooCommerce-order-proposal": [
|
||||
"cpe:2.3:a:wpovernight:woocommerce_order_proposal:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"woocommerce": [
|
||||
"cpe:2.3:a:woocommerce:woocommerce:*:*:*:*:*:wordpress:*:*",
|
||||
"cpe:2.3:a:woocommerce:woocommerce:*:*:*:*:free:wordpress:*:*",
|
||||
@@ -17370,6 +17466,9 @@
|
||||
"woovirtualwallet": [
|
||||
"cpe:2.3:a:longwatchstudio:woovirtualwallet:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"woozone": [
|
||||
"cpe:2.3:a:aa-team:wzone:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"word-balloon": [
|
||||
"cpe:2.3:a:back2nature:word_balloon:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -17882,6 +17981,9 @@
|
||||
"wp-football": [
|
||||
"cpe:2.3:a:wp-football_project:wp-football:*:*:*:*:*:*:*:*"
|
||||
],
|
||||
"wp-force-ssl": [
|
||||
"cpe:2.3:a:webfactoryltd:wp_force_ssl:*:*:*:*:free:wordpress:*:*"
|
||||
],
|
||||
"wp-forms-puzzle-captcha": [
|
||||
"cpe:2.3:a:nitinrathod:wp_forms_puzzle_captcha:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -18034,6 +18136,9 @@
|
||||
"wp-jobs": [
|
||||
"cpe:2.3:a:intensewp:wp_jobs:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"wp-jquery-lightbox": [
|
||||
"cpe:2.3:a:lightpress:lightbox:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"wp-js": [
|
||||
"cpe:2.3:a:wp-js_project:wp-js:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -18141,7 +18246,7 @@
|
||||
"cpe:2.3:a:jeffrey-wp:media_library_categories:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"wp-members": [
|
||||
"cpe:2.3:a:wp-members_project:wp-members:*:*:*:*:*:wordpress:*:*"
|
||||
"cpe:2.3:a:butlerblog:wp-members:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"wp-memory": [
|
||||
"cpe:2.3:a:wp-memory_project:wp-memory:*:*:*:*:*:wordpress:*:*"
|
||||
@@ -18302,6 +18407,9 @@
|
||||
"wp-product-gallery-lite": [
|
||||
"cpe:2.3:a:accesspressthemes:wp_product_gallery_lite:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"wp-propagator": [
|
||||
"cpe:2.3:a:widgilabs:plugin_propagator:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"wp-publications": [
|
||||
"cpe:2.3:a:wp-publications_project:wp-publications:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -18317,6 +18425,9 @@
|
||||
"wp-recall": [
|
||||
"cpe:2.3:a:plechevandrey:wp-recall:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"wp-recaptcha-integration": [
|
||||
"cpe:2.3:a:wedevs:recaptcha_integration:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"wp-recipe-maker": [
|
||||
"cpe:2.3:a:bootstrapped:wp_recipe_maker:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -18514,6 +18625,9 @@
|
||||
"wp-stripe-checkout": [
|
||||
"cpe:2.3:a:noorsplugin:wp_stripe_checkout:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"wp-stripe-donation": [
|
||||
"cpe:2.3:a:hmplugin:aidwp:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"wp-structuring-markup": [
|
||||
"cpe:2.3:a:terakoya:markup_\\(json-ld\\)_structured_in_schema.org:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -18632,7 +18746,8 @@
|
||||
"wp-user-avatar": [
|
||||
"cpe:2.3:a:profilepress:profilepress:*:*:*:*:*:wordpress:*:*",
|
||||
"cpe:2.3:a:profilepress:user_registration\\,_login_form\\,_user_profile_\\\u0026_membership:*:*:*:*:*:wordpress:*:*",
|
||||
"cpe:2.3:a:properfraction:profilepress:*:*:*:*:*:wordpress:*:*"
|
||||
"cpe:2.3:a:properfraction:profilepress:*:*:*:*:*:wordpress:*:*",
|
||||
"cpe:2.3:a:properfraction:profilepress:*:*:*:*:free:wordpress:*:*"
|
||||
],
|
||||
"wp-user-frontend": [
|
||||
"cpe:2.3:a:wedevs:wp_user_frontend:*:*:*:*:*:wordpress:*:*"
|
||||
@@ -18729,6 +18844,9 @@
|
||||
"wpbulky-wp-bulk-edit-post-types": [
|
||||
"cpe:2.3:a:villatheme:wpbulky:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"wpc-shop-as-customer": [
|
||||
"cpe:2.3:a:wpclever:wpc_shop_as_a_customer_for_woocommerce:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"wpcalc": [
|
||||
"cpe:2.3:a:wow-company:wpcalc:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -18892,7 +19010,7 @@
|
||||
"cpe:2.3:a:wpvivid:migration\\,_backup\\,_staging:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"wpvr": [
|
||||
"cpe:2.3:a:coderex:wp_vr:*:*:*:*:*:wordpress:*:*"
|
||||
"cpe:2.3:a:rextheme:wp_vr:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"wpzoom-elementor-addons": [
|
||||
"cpe:2.3:a:wpzoom:wpzoom_elementor_addons:*:*:*:*:*:wordpress:*:*"
|
||||
@@ -19007,6 +19125,10 @@
|
||||
"cpe:2.3:a:codeparrots:easy_forms_for_mailchimp:*:*:*:*:*:wordpress:*:*",
|
||||
"cpe:2.3:a:yikesinc:easy_forms_for_mailchimp:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"yith-custom-login": [
|
||||
"cpe:2.3:a:yithemes:yith_custom_login:*:*:*:*:*:wordpress:*:*",
|
||||
"cpe:2.3:a:yithemes:yith_custom_login:*:*:*:*:wordpress:*:*:*"
|
||||
],
|
||||
"yith-desktop-notifications-for-woocommerce": [
|
||||
"cpe:2.3:a:yithemes:yith_desktop_notifications_for_woocommerce:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -19154,6 +19276,7 @@
|
||||
"cpe:2.3:a:zoho:salesiq:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"zotpress": [
|
||||
"cpe:2.3:a:katieseaborn:zotpress:*:*:*:*:*:wordpress:*:*",
|
||||
"cpe:2.3:a:zotpress_project:zotpress:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"zx-csv-upload": [
|
||||
@@ -19289,6 +19412,9 @@
|
||||
"fluida": [
|
||||
"cpe:2.3:a:cryoutcreations:fluida:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"formula": [
|
||||
"cpe:2.3:a:awplife:formula:*:*:*:*:free:wordpress:*:*"
|
||||
],
|
||||
"fullbase": [
|
||||
"cpe:2.3:a:marchettidesign:fullbase:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -19367,6 +19493,9 @@
|
||||
"nexter": [
|
||||
"cpe:2.3:a:posimyth:nexter:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"nioland": [
|
||||
"cpe:2.3:a:steelthemes:nioland:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"nirvana": [
|
||||
"cpe:2.3:a:cryoutcreations:nirvana:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -19388,6 +19517,9 @@
|
||||
"pixova-lite": [
|
||||
"cpe:2.3:a:colorlib:pixova_lite:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"posterity": [
|
||||
"cpe:2.3:a:sktthemes:posterity:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"regina-lite": [
|
||||
"cpe:2.3:a:machothemes:regina_lite:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
|
||||
@@ -44,6 +44,7 @@ type CatalogTester struct {
|
||||
licenseComparer cmptest.LicenseComparer
|
||||
packageStringer func(pkg.Package) string
|
||||
customAssertions []func(t *testing.T, pkgs []pkg.Package, relationships []artifact.Relationship)
|
||||
ctx context.Context
|
||||
}
|
||||
|
||||
func NewCatalogTester() *CatalogTester {
|
||||
@@ -106,6 +107,11 @@ func (p *CatalogTester) WithLinuxRelease(r linux.Release) *CatalogTester {
|
||||
return p
|
||||
}
|
||||
|
||||
func (p *CatalogTester) WithContext(ctx context.Context) *CatalogTester {
|
||||
p.ctx = ctx
|
||||
return p
|
||||
}
|
||||
|
||||
func (p *CatalogTester) WithEnv(env *generic.Environment) *CatalogTester {
|
||||
p.env = env
|
||||
return p
|
||||
@@ -236,7 +242,14 @@ func (p *CatalogTester) TestCataloger(t *testing.T, cataloger pkg.Cataloger) {
|
||||
|
||||
resolver := NewObservingResolver(p.resolver)
|
||||
|
||||
pkgs, relationships, err := cataloger.Catalog(context.Background(), resolver)
|
||||
var ctx context.Context
|
||||
if p.ctx != nil {
|
||||
ctx = p.ctx
|
||||
} else {
|
||||
ctx = context.Background()
|
||||
}
|
||||
|
||||
pkgs, relationships, err := cataloger.Catalog(ctx, resolver)
|
||||
|
||||
// this is a minimum set, the resolver may return more that just this list
|
||||
for _, path := range p.expectedPathResponses {
|
||||
|
||||
@@ -10,7 +10,6 @@ import (
|
||||
"slices"
|
||||
"strings"
|
||||
|
||||
"github.com/vifraa/gopom"
|
||||
"golang.org/x/exp/maps"
|
||||
|
||||
"github.com/anchore/syft/internal"
|
||||
@@ -22,6 +21,7 @@ import (
|
||||
"github.com/anchore/syft/syft/file"
|
||||
"github.com/anchore/syft/syft/pkg"
|
||||
"github.com/anchore/syft/syft/pkg/cataloger/generic"
|
||||
"github.com/anchore/syft/syft/pkg/cataloger/java/internal/maven"
|
||||
)
|
||||
|
||||
var archiveFormatGlobs = []string{
|
||||
@@ -57,7 +57,7 @@ type archiveParser struct {
|
||||
fileInfo archiveFilename
|
||||
detectNested bool
|
||||
cfg ArchiveCatalogerConfig
|
||||
maven *mavenResolver
|
||||
maven *maven.Resolver
|
||||
licenseScanner licenses.Scanner
|
||||
}
|
||||
|
||||
@@ -69,15 +69,20 @@ func newGenericArchiveParserAdapter(cfg ArchiveCatalogerConfig) genericArchivePa
|
||||
return genericArchiveParserAdapter{cfg: cfg}
|
||||
}
|
||||
|
||||
// parseJavaArchive is a parser function for java archive contents, returning all Java libraries and nested archives.
|
||||
// parseJavaArchive is a parser function for java archive contents, returning all Java libraries and nested archives
|
||||
func (gap genericArchiveParserAdapter) parseJavaArchive(ctx context.Context, _ file.Resolver, _ *generic.Environment, reader file.LocationReadCloser) ([]pkg.Package, []artifact.Relationship, error) {
|
||||
return gap.processJavaArchive(ctx, reader, nil)
|
||||
}
|
||||
|
||||
// processJavaArchive processes an archive for java contents, returning all Java libraries and nested archives
|
||||
func (gap genericArchiveParserAdapter) processJavaArchive(ctx context.Context, reader file.LocationReadCloser, parentPkg *pkg.Package) ([]pkg.Package, []artifact.Relationship, error) {
|
||||
parser, cleanupFn, err := newJavaArchiveParser(ctx, reader, true, gap.cfg)
|
||||
// note: even on error, we should always run cleanup functions
|
||||
defer cleanupFn()
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
return parser.parse(ctx)
|
||||
return parser.parse(ctx, parentPkg)
|
||||
}
|
||||
|
||||
// uniquePkgKey creates a unique string to identify the given package.
|
||||
@@ -115,34 +120,62 @@ func newJavaArchiveParser(ctx context.Context, reader file.LocationReadCloser, d
|
||||
fileInfo: newJavaArchiveFilename(currentFilepath),
|
||||
detectNested: detectNested,
|
||||
cfg: cfg,
|
||||
maven: newMavenResolver(nil, cfg),
|
||||
maven: maven.NewResolver(nil, cfg.mavenConfig()),
|
||||
licenseScanner: licenseScanner,
|
||||
}, cleanupFn, nil
|
||||
}
|
||||
|
||||
// parse the loaded archive and return all packages found.
|
||||
func (j *archiveParser) parse(ctx context.Context) ([]pkg.Package, []artifact.Relationship, error) {
|
||||
func (j *archiveParser) parse(ctx context.Context, parentPkg *pkg.Package) ([]pkg.Package, []artifact.Relationship, error) {
|
||||
var pkgs []pkg.Package
|
||||
var relationships []artifact.Relationship
|
||||
|
||||
// find the parent package from the java manifest
|
||||
parentPkg, err := j.discoverMainPackage(ctx)
|
||||
mainPkg, err := j.discoverMainPackage(ctx)
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("could not generate package from %s: %w", j.location, err)
|
||||
}
|
||||
|
||||
// find aux packages from pom.properties/pom.xml and potentially modify the existing parentPkg
|
||||
// NOTE: we cannot generate sha1 digests from packages discovered via pom.properties/pom.xml
|
||||
auxPkgs, err := j.discoverPkgsFromAllMavenFiles(ctx, parentPkg)
|
||||
// IMPORTANT!: discoverPkgsFromAllMavenFiles may change mainPkg information, so needs to be called before SetID and before copying for relationships, etc.
|
||||
auxPkgs, err := j.discoverPkgsFromAllMavenFiles(ctx, mainPkg)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
pkgs = append(pkgs, auxPkgs...)
|
||||
|
||||
if mainPkg != nil {
|
||||
finalizePackage(mainPkg)
|
||||
pkgs = append(pkgs, *mainPkg)
|
||||
|
||||
if parentPkg != nil {
|
||||
relationships = append(relationships, artifact.Relationship{
|
||||
From: *mainPkg,
|
||||
To: *parentPkg,
|
||||
Type: artifact.DependencyOfRelationship,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
for i := range auxPkgs {
|
||||
auxPkg := &auxPkgs[i]
|
||||
|
||||
finalizePackage(auxPkg)
|
||||
pkgs = append(pkgs, *auxPkg)
|
||||
|
||||
if mainPkg != nil {
|
||||
relationships = append(relationships, artifact.Relationship{
|
||||
From: *auxPkg,
|
||||
To: *mainPkg,
|
||||
Type: artifact.DependencyOfRelationship,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
var errs error
|
||||
if j.detectNested {
|
||||
// find nested java archive packages
|
||||
nestedPkgs, nestedRelationships, err := j.discoverPkgsFromNestedArchives(ctx, parentPkg)
|
||||
nestedPkgs, nestedRelationships, err := j.discoverPkgsFromNestedArchives(ctx, mainPkg)
|
||||
if err != nil {
|
||||
errs = unknown.Append(errs, j.location, err)
|
||||
}
|
||||
@@ -157,29 +190,6 @@ func (j *archiveParser) parse(ctx context.Context) ([]pkg.Package, []artifact.Re
|
||||
}
|
||||
}
|
||||
|
||||
// lastly, add the parent package to the list (assuming the parent exists)
|
||||
if parentPkg != nil {
|
||||
pkgs = append([]pkg.Package{*parentPkg}, pkgs...)
|
||||
}
|
||||
|
||||
// add pURLs to all packages found
|
||||
// note: since package information may change after initial creation when parsing multiple locations within the
|
||||
// jar, we wait until the conclusion of the parsing process before synthesizing pURLs.
|
||||
for i := range pkgs {
|
||||
p := &pkgs[i]
|
||||
if m, ok := p.Metadata.(pkg.JavaArchive); ok {
|
||||
p.PURL = packageURL(p.Name, p.Version, m)
|
||||
|
||||
if strings.Contains(p.PURL, "io.jenkins.plugins") || strings.Contains(p.PURL, "org.jenkins-ci.plugins") {
|
||||
p.Type = pkg.JenkinsPluginPkg
|
||||
}
|
||||
} else {
|
||||
log.WithFields("package", p.String()).Warn("unable to extract java metadata to generate purl")
|
||||
}
|
||||
|
||||
p.SetID()
|
||||
}
|
||||
|
||||
if len(pkgs) == 0 {
|
||||
errs = unknown.Appendf(errs, j.location, "no package identified in archive")
|
||||
}
|
||||
@@ -187,6 +197,22 @@ func (j *archiveParser) parse(ctx context.Context) ([]pkg.Package, []artifact.Re
|
||||
return pkgs, relationships, errs
|
||||
}
|
||||
|
||||
// finalizePackage potentially updates some package information such as classifying the package as a Jenkins plugin,
|
||||
// sets the PURL, and calls p.SetID()
|
||||
func finalizePackage(p *pkg.Package) {
|
||||
if m, ok := p.Metadata.(pkg.JavaArchive); ok {
|
||||
p.PURL = packageURL(p.Name, p.Version, m)
|
||||
|
||||
if strings.Contains(p.PURL, "io.jenkins.plugins") || strings.Contains(p.PURL, "org.jenkins-ci.plugins") {
|
||||
p.Type = pkg.JenkinsPluginPkg
|
||||
}
|
||||
} else {
|
||||
log.WithFields("package", p.String()).Warn("unable to extract java metadata to generate purl")
|
||||
}
|
||||
|
||||
p.SetID()
|
||||
}
|
||||
|
||||
// discoverMainPackage parses the root Java manifest used as the parent package to all discovered nested packages.
|
||||
func (j *archiveParser) discoverMainPackage(ctx context.Context) (*pkg.Package, error) {
|
||||
// search and parse java manifest files
|
||||
@@ -297,18 +323,18 @@ func (j *archiveParser) findLicenseFromJavaMetadata(ctx context.Context, groupID
|
||||
}
|
||||
|
||||
var err error
|
||||
var pomLicenses []gopom.License
|
||||
var pomLicenses []maven.License
|
||||
if parsedPom != nil {
|
||||
pomLicenses, err = j.maven.resolveLicenses(ctx, parsedPom.project)
|
||||
pomLicenses, err = j.maven.ResolveLicenses(ctx, parsedPom.project)
|
||||
if err != nil {
|
||||
log.WithFields("error", err, "mavenID", j.maven.getMavenID(ctx, parsedPom.project)).Trace("error attempting to resolve pom licenses")
|
||||
log.WithFields("error", err, "mavenID", j.maven.ResolveID(ctx, parsedPom.project)).Trace("error attempting to resolve pom licenses")
|
||||
}
|
||||
}
|
||||
|
||||
if err == nil && len(pomLicenses) == 0 {
|
||||
pomLicenses, err = j.maven.findLicenses(ctx, groupID, artifactID, version)
|
||||
pomLicenses, err = j.maven.FindLicenses(ctx, groupID, artifactID, version)
|
||||
if err != nil {
|
||||
log.WithFields("error", err, "mavenID", mavenID{groupID, artifactID, version}).Trace("error attempting to find licenses")
|
||||
log.WithFields("error", err, "mavenID", maven.NewID(groupID, artifactID, version)).Trace("error attempting to find licenses")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -316,26 +342,37 @@ func (j *archiveParser) findLicenseFromJavaMetadata(ctx context.Context, groupID
|
||||
// Try removing the last part of the groupId, as sometimes it duplicates the artifactId
|
||||
packages := strings.Split(groupID, ".")
|
||||
groupID = strings.Join(packages[:len(packages)-1], ".")
|
||||
pomLicenses, err = j.maven.findLicenses(ctx, groupID, artifactID, version)
|
||||
pomLicenses, err = j.maven.FindLicenses(ctx, groupID, artifactID, version)
|
||||
if err != nil {
|
||||
log.WithFields("error", err, "mavenID", mavenID{groupID, artifactID, version}).Trace("error attempting to find sub-group licenses")
|
||||
log.WithFields("error", err, "mavenID", maven.NewID(groupID, artifactID, version)).Trace("error attempting to find sub-group licenses")
|
||||
}
|
||||
}
|
||||
|
||||
return toPkgLicenses(&j.location, pomLicenses)
|
||||
}
|
||||
|
||||
func toPkgLicenses(location *file.Location, licenses []gopom.License) []pkg.License {
|
||||
func toPkgLicenses(location *file.Location, licenses []maven.License) []pkg.License {
|
||||
var out []pkg.License
|
||||
for _, license := range licenses {
|
||||
out = append(out, pkg.NewLicenseFromFields(deref(license.Name), deref(license.URL), location))
|
||||
name := ""
|
||||
if license.Name != nil {
|
||||
name = *license.Name
|
||||
}
|
||||
url := ""
|
||||
if license.URL != nil {
|
||||
url = *license.URL
|
||||
}
|
||||
if name == "" && url == "" {
|
||||
continue
|
||||
}
|
||||
out = append(out, pkg.NewLicenseFromFields(name, url, location))
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
type parsedPomProject struct {
|
||||
path string
|
||||
project *gopom.Project
|
||||
project *maven.Project
|
||||
}
|
||||
|
||||
// discoverMainPackageFromPomInfo attempts to resolve maven groupId, artifactId, version and other info from found pom information
|
||||
@@ -370,7 +407,7 @@ func (j *archiveParser) discoverMainPackageFromPomInfo(ctx context.Context) (gro
|
||||
version = pomProperties.Version
|
||||
|
||||
if parsedPom != nil && parsedPom.project != nil {
|
||||
id := j.maven.getMavenID(ctx, parsedPom.project)
|
||||
id := j.maven.ResolveID(ctx, parsedPom.project)
|
||||
if group == "" {
|
||||
group = id.GroupID
|
||||
}
|
||||
@@ -507,7 +544,7 @@ func discoverPkgsFromOpeners(ctx context.Context, location file.Location, opener
|
||||
var relationships []artifact.Relationship
|
||||
|
||||
for pathWithinArchive, archiveOpener := range openers {
|
||||
nestedPkgs, nestedRelationships, err := discoverPkgsFromOpener(ctx, location, pathWithinArchive, archiveOpener, cfg)
|
||||
nestedPkgs, nestedRelationships, err := discoverPkgsFromOpener(ctx, location, pathWithinArchive, archiveOpener, cfg, parentPkg)
|
||||
if err != nil {
|
||||
log.WithFields("location", location.Path()).Warnf("unable to discover java packages from opener: %+v", err)
|
||||
continue
|
||||
@@ -531,7 +568,7 @@ func discoverPkgsFromOpeners(ctx context.Context, location file.Location, opener
|
||||
}
|
||||
|
||||
// discoverPkgsFromOpener finds Java archives within the given file.
|
||||
func discoverPkgsFromOpener(ctx context.Context, location file.Location, pathWithinArchive string, archiveOpener intFile.Opener, cfg ArchiveCatalogerConfig) ([]pkg.Package, []artifact.Relationship, error) {
|
||||
func discoverPkgsFromOpener(ctx context.Context, location file.Location, pathWithinArchive string, archiveOpener intFile.Opener, cfg ArchiveCatalogerConfig, parentPkg *pkg.Package) ([]pkg.Package, []artifact.Relationship, error) {
|
||||
archiveReadCloser, err := archiveOpener.Open()
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("unable to open archived file from tempdir: %w", err)
|
||||
@@ -546,10 +583,10 @@ func discoverPkgsFromOpener(ctx context.Context, location file.Location, pathWit
|
||||
nestedLocation := file.NewLocationFromCoordinates(location.Coordinates)
|
||||
nestedLocation.AccessPath = nestedPath
|
||||
gap := newGenericArchiveParserAdapter(cfg)
|
||||
nestedPkgs, nestedRelationships, err := gap.parseJavaArchive(ctx, nil, nil, file.LocationReadCloser{
|
||||
nestedPkgs, nestedRelationships, err := gap.processJavaArchive(ctx, file.LocationReadCloser{
|
||||
Location: nestedLocation,
|
||||
ReadCloser: archiveReadCloser,
|
||||
})
|
||||
}, parentPkg)
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("unable to process nested java archive (%s): %w", pathWithinArchive, err)
|
||||
}
|
||||
@@ -595,7 +632,7 @@ func pomProjectByParentPath(archivePath string, location file.Location, extractP
|
||||
projectByParentPath := make(map[string]*parsedPomProject)
|
||||
for filePath, fileContents := range contentsOfMavenProjectFiles {
|
||||
// TODO: when we support locations of paths within archives we should start passing the specific pom.xml location object instead of the top jar
|
||||
pom, err := decodePomXML(strings.NewReader(fileContents))
|
||||
pom, err := maven.ParsePomXML(strings.NewReader(fileContents))
|
||||
if err != nil {
|
||||
log.WithFields("contents-path", filePath, "location", location.Path()).Warnf("failed to parse pom.xml: %+v", err)
|
||||
continue
|
||||
@@ -614,7 +651,7 @@ func pomProjectByParentPath(archivePath string, location file.Location, extractP
|
||||
|
||||
// newPackageFromMavenData processes a single Maven POM properties for a given parent package, returning all listed Java packages found and
|
||||
// associating each discovered package to the given parent package. Note the pom.xml is optional, the pom.properties is not.
|
||||
func newPackageFromMavenData(ctx context.Context, r *mavenResolver, pomProperties pkg.JavaPomProperties, parsedPom *parsedPomProject, parentPkg *pkg.Package, location file.Location) *pkg.Package {
|
||||
func newPackageFromMavenData(ctx context.Context, r *maven.Resolver, pomProperties pkg.JavaPomProperties, parsedPom *parsedPomProject, parentPkg *pkg.Package, location file.Location) *pkg.Package {
|
||||
// keep the artifact name within the virtual path if this package does not match the parent package
|
||||
vPathSuffix := ""
|
||||
groupID := ""
|
||||
@@ -639,23 +676,20 @@ func newPackageFromMavenData(ctx context.Context, r *mavenResolver, pomPropertie
|
||||
var pkgPomProject *pkg.JavaPomProject
|
||||
|
||||
var err error
|
||||
var pomLicenses []gopom.License
|
||||
var pomLicenses []maven.License
|
||||
if parsedPom == nil {
|
||||
// If we have no pom.xml, check maven central using pom.properties
|
||||
pomLicenses, err = r.findLicenses(ctx, pomProperties.GroupID, pomProperties.ArtifactID, pomProperties.Version)
|
||||
pomLicenses, err = r.FindLicenses(ctx, pomProperties.GroupID, pomProperties.ArtifactID, pomProperties.Version)
|
||||
} else {
|
||||
pkgPomProject = newPomProject(ctx, r, parsedPom.path, parsedPom.project)
|
||||
pomLicenses, err = r.resolveLicenses(ctx, parsedPom.project)
|
||||
pomLicenses, err = r.ResolveLicenses(ctx, parsedPom.project)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
log.WithFields("error", err, "mavenID", mavenID{pomProperties.GroupID, pomProperties.ArtifactID, pomProperties.Version}).Trace("error attempting to resolve licenses")
|
||||
log.WithFields("error", err, "mavenID", maven.NewID(pomProperties.GroupID, pomProperties.ArtifactID, pomProperties.Version)).Trace("error attempting to resolve licenses")
|
||||
}
|
||||
|
||||
licenses := make([]pkg.License, 0)
|
||||
for _, license := range pomLicenses {
|
||||
licenses = append(licenses, pkg.NewLicenseFromFields(deref(license.Name), deref(license.URL), &location))
|
||||
}
|
||||
licenseSet := pkg.NewLicenseSet(toPkgLicenses(&location, pomLicenses)...)
|
||||
|
||||
p := pkg.Package{
|
||||
Name: pomProperties.ArtifactID,
|
||||
@@ -663,7 +697,7 @@ func newPackageFromMavenData(ctx context.Context, r *mavenResolver, pomPropertie
|
||||
Locations: file.NewLocationSet(
|
||||
location.WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation),
|
||||
),
|
||||
Licenses: pkg.NewLicenseSet(licenses...),
|
||||
Licenses: licenseSet,
|
||||
Language: pkg.Java,
|
||||
Type: pomProperties.PkgTypeIndicated(),
|
||||
Metadata: pkg.JavaArchive{
|
||||
|
||||
@@ -18,7 +18,6 @@ import (
|
||||
"github.com/scylladb/go-set/strset"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"github.com/vifraa/gopom"
|
||||
|
||||
"github.com/anchore/syft/internal/licenses"
|
||||
"github.com/anchore/syft/syft/artifact"
|
||||
@@ -26,10 +25,12 @@ import (
|
||||
"github.com/anchore/syft/syft/license"
|
||||
"github.com/anchore/syft/syft/pkg"
|
||||
"github.com/anchore/syft/syft/pkg/cataloger/internal/pkgtest"
|
||||
"github.com/anchore/syft/syft/pkg/cataloger/java/internal/maven"
|
||||
maventest "github.com/anchore/syft/syft/pkg/cataloger/java/internal/maven/test"
|
||||
)
|
||||
|
||||
func TestSearchMavenForLicenses(t *testing.T) {
|
||||
url := mockMavenRepo(t)
|
||||
url := maventest.MockRepo(t, "internal/maven/test-fixtures/maven-repo")
|
||||
|
||||
ctx := licenses.SetContextLicenseScanner(context.Background(), licenses.TestingOnlyScanner())
|
||||
|
||||
@@ -83,8 +84,8 @@ func TestSearchMavenForLicenses(t *testing.T) {
|
||||
|
||||
// assert licenses are discovered from upstream
|
||||
_, _, _, parsedPom := ap.discoverMainPackageFromPomInfo(context.Background())
|
||||
licenses, _ := ap.maven.resolveLicenses(context.Background(), parsedPom.project)
|
||||
assert.Equal(t, tc.expectedLicenses, toPkgLicenses(nil, licenses))
|
||||
resolvedLicenses, _ := ap.maven.ResolveLicenses(context.Background(), parsedPom.project)
|
||||
assert.Equal(t, tc.expectedLicenses, toPkgLicenses(nil, resolvedLicenses))
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -362,9 +363,11 @@ func TestParseJar(t *testing.T) {
|
||||
defer cleanupFn()
|
||||
require.NoError(t, err)
|
||||
|
||||
actual, _, err := parser.parse(context.Background())
|
||||
actual, _, err := parser.parse(context.Background(), nil)
|
||||
if test.wantErr != nil {
|
||||
test.wantErr(t, err)
|
||||
} else {
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
if len(actual) != len(test.expected) {
|
||||
@@ -434,6 +437,7 @@ func TestParseJar(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestParseNestedJar(t *testing.T) {
|
||||
ctx := licenses.SetContextLicenseScanner(context.Background(), licenses.TestingOnlyScanner())
|
||||
tests := []struct {
|
||||
fixture string
|
||||
expected []pkg.Package
|
||||
@@ -635,10 +639,10 @@ func TestParseNestedJar(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
gap := newGenericArchiveParserAdapter(ArchiveCatalogerConfig{})
|
||||
|
||||
actual, _, err := gap.parseJavaArchive(context.Background(), nil, nil, file.LocationReadCloser{
|
||||
actual, _, err := gap.processJavaArchive(ctx, file.LocationReadCloser{
|
||||
Location: file.NewLocation(fixture.Name()),
|
||||
ReadCloser: fixture,
|
||||
})
|
||||
}, nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
expectedNameVersionPairSet := strset.New()
|
||||
@@ -776,8 +780,8 @@ func Test_newPackageFromMavenData(t *testing.T) {
|
||||
Version: "1.0",
|
||||
},
|
||||
project: &parsedPomProject{
|
||||
project: &gopom.Project{
|
||||
Parent: &gopom.Parent{
|
||||
project: &maven.Project{
|
||||
Parent: &maven.Parent{
|
||||
GroupID: ptr("some-parent-group-id"),
|
||||
ArtifactID: ptr("some-parent-artifact-id"),
|
||||
Version: ptr("1.0-parent"),
|
||||
@@ -788,7 +792,7 @@ func Test_newPackageFromMavenData(t *testing.T) {
|
||||
Version: ptr("1.0"),
|
||||
Description: ptr("desc"),
|
||||
URL: ptr("aweso.me"),
|
||||
Licenses: &[]gopom.License{
|
||||
Licenses: &[]maven.License{
|
||||
{
|
||||
Name: ptr("MIT"),
|
||||
URL: ptr("https://opensource.org/licenses/MIT"),
|
||||
@@ -1052,7 +1056,7 @@ func Test_newPackageFromMavenData(t *testing.T) {
|
||||
}
|
||||
test.expectedParent.Locations = locations
|
||||
|
||||
r := newMavenResolver(nil, DefaultArchiveCatalogerConfig())
|
||||
r := maven.NewResolver(nil, maven.DefaultConfig())
|
||||
actualPackage := newPackageFromMavenData(context.Background(), r, test.props, test.project, test.parent, file.NewLocation(virtualPath))
|
||||
if test.expectedPackage == nil {
|
||||
require.Nil(t, actualPackage)
|
||||
@@ -1093,6 +1097,78 @@ func Test_artifactIDMatchesFilename(t *testing.T) {
|
||||
}
|
||||
|
||||
func Test_parseJavaArchive_regressions(t *testing.T) {
|
||||
apiAll := pkg.Package{
|
||||
Name: "api-all",
|
||||
Version: "2.0.0",
|
||||
Type: pkg.JavaPkg,
|
||||
Language: pkg.Java,
|
||||
PURL: "pkg:maven/org.apache.directory.api/api-all@2.0.0",
|
||||
Locations: file.NewLocationSet(file.NewLocation("test-fixtures/jar-metadata/cache/api-all-2.0.0-sources.jar")),
|
||||
Metadata: pkg.JavaArchive{
|
||||
VirtualPath: "test-fixtures/jar-metadata/cache/api-all-2.0.0-sources.jar",
|
||||
Manifest: &pkg.JavaManifest{
|
||||
Main: []pkg.KeyValue{
|
||||
{
|
||||
Key: "Manifest-Version",
|
||||
Value: "1.0",
|
||||
},
|
||||
{
|
||||
Key: "Built-By",
|
||||
Value: "elecharny",
|
||||
},
|
||||
{
|
||||
Key: "Created-By",
|
||||
Value: "Apache Maven 3.6.0",
|
||||
},
|
||||
{
|
||||
Key: "Build-Jdk",
|
||||
Value: "1.8.0_191",
|
||||
},
|
||||
},
|
||||
},
|
||||
PomProperties: &pkg.JavaPomProperties{
|
||||
Path: "META-INF/maven/org.apache.directory.api/api-all/pom.properties",
|
||||
GroupID: "org.apache.directory.api",
|
||||
ArtifactID: "api-all",
|
||||
Version: "2.0.0",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
apiAsn1Api := pkg.Package{
|
||||
Name: "api-asn1-api",
|
||||
Version: "2.0.0",
|
||||
PURL: "pkg:maven/org.apache.directory.api/api-asn1-api@2.0.0",
|
||||
Locations: file.NewLocationSet(file.NewLocation("test-fixtures/jar-metadata/cache/api-all-2.0.0-sources.jar")),
|
||||
Type: pkg.JavaPkg,
|
||||
Language: pkg.Java,
|
||||
Metadata: pkg.JavaArchive{
|
||||
VirtualPath: "test-fixtures/jar-metadata/cache/api-all-2.0.0-sources.jar:org.apache.directory.api:api-asn1-api",
|
||||
PomProperties: &pkg.JavaPomProperties{
|
||||
Path: "META-INF/maven/org.apache.directory.api/api-asn1-api/pom.properties",
|
||||
GroupID: "org.apache.directory.api",
|
||||
ArtifactID: "api-asn1-api",
|
||||
Version: "2.0.0",
|
||||
},
|
||||
PomProject: &pkg.JavaPomProject{
|
||||
Path: "META-INF/maven/org.apache.directory.api/api-asn1-api/pom.xml",
|
||||
ArtifactID: "api-asn1-api",
|
||||
GroupID: "org.apache.directory.api",
|
||||
Version: "2.0.0",
|
||||
Name: "Apache Directory API ASN.1 API",
|
||||
Description: "ASN.1 API",
|
||||
Parent: &pkg.JavaPomParent{
|
||||
GroupID: "org.apache.directory.api",
|
||||
ArtifactID: "api-asn1-parent",
|
||||
Version: "2.0.0",
|
||||
},
|
||||
},
|
||||
Parent: &apiAll,
|
||||
},
|
||||
}
|
||||
|
||||
ctx := licenses.SetContextLicenseScanner(context.Background(), licenses.TestingOnlyScanner())
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
fixtureName string
|
||||
@@ -1214,73 +1290,14 @@ func Test_parseJavaArchive_regressions(t *testing.T) {
|
||||
fixtureName: "api-all-2.0.0-sources",
|
||||
assignParent: true,
|
||||
expectedPkgs: []pkg.Package{
|
||||
apiAll,
|
||||
apiAsn1Api,
|
||||
},
|
||||
expectedRelationships: []artifact.Relationship{
|
||||
{
|
||||
Name: "api-all",
|
||||
Version: "2.0.0",
|
||||
Type: pkg.JavaPkg,
|
||||
Language: pkg.Java,
|
||||
PURL: "pkg:maven/org.apache.directory.api/api-all@2.0.0",
|
||||
Locations: file.NewLocationSet(file.NewLocation("test-fixtures/jar-metadata/cache/api-all-2.0.0-sources.jar")),
|
||||
Metadata: pkg.JavaArchive{
|
||||
VirtualPath: "test-fixtures/jar-metadata/cache/api-all-2.0.0-sources.jar",
|
||||
Manifest: &pkg.JavaManifest{
|
||||
Main: []pkg.KeyValue{
|
||||
{
|
||||
Key: "Manifest-Version",
|
||||
Value: "1.0",
|
||||
},
|
||||
{
|
||||
Key: "Built-By",
|
||||
Value: "elecharny",
|
||||
},
|
||||
{
|
||||
Key: "Created-By",
|
||||
Value: "Apache Maven 3.6.0",
|
||||
},
|
||||
{
|
||||
Key: "Build-Jdk",
|
||||
Value: "1.8.0_191",
|
||||
},
|
||||
},
|
||||
},
|
||||
PomProperties: &pkg.JavaPomProperties{
|
||||
Path: "META-INF/maven/org.apache.directory.api/api-all/pom.properties",
|
||||
GroupID: "org.apache.directory.api",
|
||||
ArtifactID: "api-all",
|
||||
Version: "2.0.0",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "api-asn1-api",
|
||||
Version: "2.0.0",
|
||||
PURL: "pkg:maven/org.apache.directory.api/api-asn1-api@2.0.0",
|
||||
Locations: file.NewLocationSet(file.NewLocation("test-fixtures/jar-metadata/cache/api-all-2.0.0-sources.jar")),
|
||||
Type: pkg.JavaPkg,
|
||||
Language: pkg.Java,
|
||||
Metadata: pkg.JavaArchive{
|
||||
VirtualPath: "test-fixtures/jar-metadata/cache/api-all-2.0.0-sources.jar:org.apache.directory.api:api-asn1-api",
|
||||
PomProperties: &pkg.JavaPomProperties{
|
||||
Path: "META-INF/maven/org.apache.directory.api/api-asn1-api/pom.properties",
|
||||
GroupID: "org.apache.directory.api",
|
||||
ArtifactID: "api-asn1-api",
|
||||
Version: "2.0.0",
|
||||
},
|
||||
PomProject: &pkg.JavaPomProject{
|
||||
Path: "META-INF/maven/org.apache.directory.api/api-asn1-api/pom.xml",
|
||||
ArtifactID: "api-asn1-api",
|
||||
GroupID: "org.apache.directory.api",
|
||||
Version: "2.0.0",
|
||||
Name: "Apache Directory API ASN.1 API",
|
||||
Description: "ASN.1 API",
|
||||
Parent: &pkg.JavaPomParent{
|
||||
GroupID: "org.apache.directory.api",
|
||||
ArtifactID: "api-asn1-parent",
|
||||
Version: "2.0.0",
|
||||
},
|
||||
},
|
||||
Parent: nil,
|
||||
},
|
||||
From: apiAsn1Api,
|
||||
To: apiAll,
|
||||
Type: artifact.DependencyOfRelationship,
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -1341,6 +1358,7 @@ func Test_parseJavaArchive_regressions(t *testing.T) {
|
||||
pkgtest.NewCatalogTester().
|
||||
FromFile(t, generateJavaMetadataJarFixture(t, tt.fixtureName, tt.fileExtension)).
|
||||
Expects(tt.expectedPkgs, tt.expectedRelationships).
|
||||
WithContext(ctx).
|
||||
WithCompareOptions(
|
||||
cmpopts.IgnoreFields(pkg.JavaArchive{}, "ArchiveDigests"),
|
||||
cmp.Comparer(func(x, y pkg.KeyValue) bool {
|
||||
@@ -1364,11 +1382,11 @@ func Test_deterministicMatchingPomProperties(t *testing.T) {
|
||||
|
||||
tests := []struct {
|
||||
fixture string
|
||||
expected mavenID
|
||||
expected maven.ID
|
||||
}{
|
||||
{
|
||||
fixture: "multiple-matching-2.11.5",
|
||||
expected: mavenID{"org.multiple", "multiple-matching-1", "2.11.5"},
|
||||
expected: maven.NewID("org.multiple", "multiple-matching-1", "2.11.5"),
|
||||
},
|
||||
}
|
||||
|
||||
@@ -1391,7 +1409,7 @@ func Test_deterministicMatchingPomProperties(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
|
||||
groupID, artifactID, version, _ := parser.discoverMainPackageFromPomInfo(context.TODO())
|
||||
require.Equal(t, test.expected, mavenID{groupID, artifactID, version})
|
||||
require.Equal(t, test.expected, maven.NewID(groupID, artifactID, version))
|
||||
}()
|
||||
}
|
||||
})
|
||||
@@ -1401,10 +1419,7 @@ func Test_deterministicMatchingPomProperties(t *testing.T) {
|
||||
func assignParent(parent *pkg.Package, childPackages ...pkg.Package) {
|
||||
for i, jp := range childPackages {
|
||||
if v, ok := jp.Metadata.(pkg.JavaArchive); ok {
|
||||
parent := *parent
|
||||
// PURL are not calculated after the fact for parent
|
||||
parent.PURL = ""
|
||||
v.Parent = &parent
|
||||
v.Parent = parent
|
||||
childPackages[i].Metadata = v
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
package java
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/anchore/syft/internal/licenses"
|
||||
"github.com/anchore/syft/syft/cataloging"
|
||||
"github.com/anchore/syft/syft/cpe"
|
||||
"github.com/anchore/syft/syft/file"
|
||||
@@ -11,6 +13,8 @@ import (
|
||||
)
|
||||
|
||||
func Test_ArchiveCataloger_Globs(t *testing.T) {
|
||||
ctx := licenses.SetContextLicenseScanner(context.Background(), licenses.TestingOnlyScanner())
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
fixture string
|
||||
@@ -59,6 +63,7 @@ func Test_ArchiveCataloger_Globs(t *testing.T) {
|
||||
pkgtest.NewCatalogTester().
|
||||
FromDirectory(t, test.fixture).
|
||||
ExpectsResolverContentQueries(test.expected).
|
||||
WithContext(ctx).
|
||||
TestCataloger(t,
|
||||
NewArchiveCataloger(
|
||||
ArchiveCatalogerConfig{
|
||||
@@ -128,7 +133,8 @@ func TestJvmDistributionCataloger(t *testing.T) {
|
||||
cpe.Must("cpe:2.3:a:oracle:jre:1.8.0:update411:*:*:*:*:*:*", cpe.DeclaredSource),
|
||||
cpe.Must("cpe:2.3:a:oracle:jdk:1.8.0:update411:*:*:*:*:*:*", cpe.DeclaredSource),
|
||||
},
|
||||
PURL: "pkg:generic/oracle/jdk@1.8.0_411-b25",
|
||||
PURL: "pkg:generic/oracle/jdk@1.8.0_411-b25",
|
||||
Dependencies: pkg.UnknownDependencyCompleteness,
|
||||
Metadata: pkg.JavaVMInstallation{
|
||||
Release: pkg.JavaVMRelease{
|
||||
JavaRuntimeVersion: "1.8.0_411-b25",
|
||||
@@ -150,14 +156,15 @@ func TestJvmDistributionCataloger(t *testing.T) {
|
||||
name: "valid post-jep223",
|
||||
fixture: "test-fixtures/jvm-installs/valid-post-jep223",
|
||||
expected: pkg.Package{
|
||||
Name: "openjdk",
|
||||
Version: "21.0.4+7-LTS",
|
||||
FoundBy: "java-jvm-cataloger",
|
||||
Locations: file.NewLocationSet(file.NewLocation("jvm/openjdk/release")),
|
||||
Licenses: pkg.NewLicenseSet(),
|
||||
Type: pkg.BinaryPkg,
|
||||
CPEs: []cpe.CPE{cpe.Must("cpe:2.3:a:oracle:openjdk:21.0.4:*:*:*:*:*:*:*", cpe.DeclaredSource)},
|
||||
PURL: "pkg:generic/oracle/openjdk@21.0.4%2B7-LTS?repository_url=https://github.com/adoptium/jdk21u.git",
|
||||
Name: "openjdk",
|
||||
Version: "21.0.4+7-LTS",
|
||||
FoundBy: "java-jvm-cataloger",
|
||||
Locations: file.NewLocationSet(file.NewLocation("jvm/openjdk/release")),
|
||||
Licenses: pkg.NewLicenseSet(),
|
||||
Type: pkg.BinaryPkg,
|
||||
CPEs: []cpe.CPE{cpe.Must("cpe:2.3:a:oracle:openjdk:21.0.4:*:*:*:*:*:*:*", cpe.DeclaredSource)},
|
||||
PURL: "pkg:generic/oracle/openjdk@21.0.4%2B7-LTS?repository_url=https://github.com/adoptium/jdk21u.git",
|
||||
Dependencies: pkg.UnknownDependencyCompleteness,
|
||||
Metadata: pkg.JavaVMInstallation{
|
||||
Release: pkg.JavaVMRelease{
|
||||
Implementor: "Eclipse Adoptium",
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
package java
|
||||
|
||||
import "github.com/anchore/syft/syft/cataloging"
|
||||
import (
|
||||
"strings"
|
||||
|
||||
const mavenBaseURL = "https://repo1.maven.org/maven2"
|
||||
"github.com/anchore/syft/syft/cataloging"
|
||||
"github.com/anchore/syft/syft/pkg/cataloger/java/internal/maven"
|
||||
)
|
||||
|
||||
type ArchiveCatalogerConfig struct {
|
||||
cataloging.ArchiveSearchConfig `yaml:",inline" json:"" mapstructure:",squash"`
|
||||
@@ -11,16 +14,19 @@ type ArchiveCatalogerConfig struct {
|
||||
MavenLocalRepositoryDir string `yaml:"maven-localrepository-dir" json:"maven-localrepository-dir" mapstructure:"maven-localrepository-dir"`
|
||||
MavenBaseURL string `yaml:"maven-base-url" json:"maven-base-url" mapstructure:"maven-base-url"`
|
||||
MaxParentRecursiveDepth int `yaml:"max-parent-recursive-depth" json:"max-parent-recursive-depth" mapstructure:"max-parent-recursive-depth"`
|
||||
ResolveTransitiveDependencies bool `yaml:"resolve-transitive-dependencies" json:"resolve-transitive-dependencies" mapstructure:"resolve-transitive-dependencies"`
|
||||
}
|
||||
|
||||
func DefaultArchiveCatalogerConfig() ArchiveCatalogerConfig {
|
||||
mavenCfg := maven.DefaultConfig()
|
||||
return ArchiveCatalogerConfig{
|
||||
ArchiveSearchConfig: cataloging.DefaultArchiveSearchConfig(),
|
||||
UseNetwork: false,
|
||||
UseMavenLocalRepository: false,
|
||||
MavenLocalRepositoryDir: defaultMavenLocalRepoDir(),
|
||||
MavenBaseURL: mavenBaseURL,
|
||||
MaxParentRecursiveDepth: 0, // unlimited
|
||||
ArchiveSearchConfig: cataloging.DefaultArchiveSearchConfig(),
|
||||
UseNetwork: mavenCfg.UseNetwork,
|
||||
UseMavenLocalRepository: mavenCfg.UseLocalRepository,
|
||||
MavenLocalRepositoryDir: mavenCfg.LocalRepositoryDir,
|
||||
MavenBaseURL: strings.Join(mavenCfg.Repositories, ","),
|
||||
MaxParentRecursiveDepth: mavenCfg.MaxParentRecursiveDepth,
|
||||
ResolveTransitiveDependencies: false,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,8 +52,23 @@ func (j ArchiveCatalogerConfig) WithMavenBaseURL(input string) ArchiveCatalogerC
|
||||
return j
|
||||
}
|
||||
|
||||
func (j ArchiveCatalogerConfig) WithResolveTransitiveDependencies(resolveTransitiveDependencies bool) ArchiveCatalogerConfig {
|
||||
j.ResolveTransitiveDependencies = resolveTransitiveDependencies
|
||||
return j
|
||||
}
|
||||
|
||||
func (j ArchiveCatalogerConfig) WithArchiveTraversal(search cataloging.ArchiveSearchConfig, maxDepth int) ArchiveCatalogerConfig {
|
||||
j.MaxParentRecursiveDepth = maxDepth
|
||||
j.ArchiveSearchConfig = search
|
||||
return j
|
||||
}
|
||||
|
||||
func (j ArchiveCatalogerConfig) mavenConfig() maven.Config {
|
||||
return maven.Config{
|
||||
UseNetwork: j.UseNetwork,
|
||||
UseLocalRepository: j.UseMavenLocalRepository,
|
||||
LocalRepositoryDir: j.MavenLocalRepositoryDir,
|
||||
Repositories: strings.Split(j.MavenBaseURL, ","),
|
||||
MaxParentRecursiveDepth: j.MaxParentRecursiveDepth,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,7 +8,6 @@ import (
|
||||
"debug/macho"
|
||||
"debug/pe"
|
||||
"encoding/binary"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
@@ -18,34 +17,14 @@ import (
|
||||
"github.com/anchore/syft/internal/log"
|
||||
"github.com/anchore/syft/internal/mimetype"
|
||||
"github.com/anchore/syft/syft/artifact"
|
||||
"github.com/anchore/syft/syft/cpe"
|
||||
"github.com/anchore/syft/syft/file"
|
||||
"github.com/anchore/syft/syft/format/cyclonedxjson"
|
||||
"github.com/anchore/syft/syft/internal/unionreader"
|
||||
"github.com/anchore/syft/syft/pkg"
|
||||
)
|
||||
|
||||
type nativeImageCycloneDX struct {
|
||||
BomFormat string `json:"bomFormat"`
|
||||
SpecVersion string `json:"specVersion"`
|
||||
Version int `json:"version"`
|
||||
Components []nativeImageComponent `json:"components"`
|
||||
}
|
||||
|
||||
type nativeImageComponent struct {
|
||||
Type string `json:"type"`
|
||||
Group string `json:"group"`
|
||||
Name string `json:"name"`
|
||||
Version string `json:"version"`
|
||||
Properties []nativeImageCPE `json:"properties"`
|
||||
}
|
||||
|
||||
type nativeImageCPE struct {
|
||||
Name string `json:"name"`
|
||||
Value string `json:"value"`
|
||||
}
|
||||
|
||||
type nativeImage interface {
|
||||
fetchPkgs() ([]pkg.Package, error)
|
||||
fetchPkgs() ([]pkg.Package, []artifact.Relationship, error)
|
||||
}
|
||||
|
||||
type nativeImageElf struct {
|
||||
@@ -113,40 +92,12 @@ func (c *nativeImageCataloger) Name() string {
|
||||
return nativeImageCatalogerName
|
||||
}
|
||||
|
||||
// getPackage returns the package given within a NativeImageComponent.
|
||||
func getPackage(component nativeImageComponent) pkg.Package {
|
||||
var cpes []cpe.CPE
|
||||
for _, property := range component.Properties {
|
||||
c, err := cpe.New(property.Value, cpe.DeclaredSource)
|
||||
if err != nil {
|
||||
log.Debugf("unable to parse Attributes: %v", err)
|
||||
continue
|
||||
}
|
||||
cpes = append(cpes, c)
|
||||
}
|
||||
return pkg.Package{
|
||||
Name: component.Name,
|
||||
Version: component.Version,
|
||||
Language: pkg.Java,
|
||||
Type: pkg.GraalVMNativeImagePkg,
|
||||
FoundBy: nativeImageCatalogerName,
|
||||
Metadata: pkg.JavaArchive{
|
||||
PomProperties: &pkg.JavaPomProperties{
|
||||
GroupID: component.Group,
|
||||
},
|
||||
},
|
||||
CPEs: cpes,
|
||||
}
|
||||
}
|
||||
|
||||
// decompressSbom returns the packages given within a native image executable's SBOM.
|
||||
func decompressSbom(dataBuf []byte, sbomStart uint64, lengthStart uint64) ([]pkg.Package, error) {
|
||||
var pkgs []pkg.Package
|
||||
|
||||
func decompressSbom(dataBuf []byte, sbomStart uint64, lengthStart uint64) ([]pkg.Package, []artifact.Relationship, error) {
|
||||
lengthEnd := lengthStart + 8
|
||||
bufLen := len(dataBuf)
|
||||
if lengthEnd > uint64(bufLen) {
|
||||
return nil, errors.New("the 'sbom_length' symbol overflows the binary")
|
||||
return nil, nil, errors.New("the 'sbom_length' symbol overflows the binary")
|
||||
}
|
||||
|
||||
length := dataBuf[lengthStart:lengthEnd]
|
||||
@@ -154,39 +105,31 @@ func decompressSbom(dataBuf []byte, sbomStart uint64, lengthStart uint64) ([]pkg
|
||||
var storedLength uint64
|
||||
err := binary.Read(p, binary.LittleEndian, &storedLength)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("could not read from binary file: %w", err)
|
||||
return nil, nil, fmt.Errorf("could not read from binary file: %w", err)
|
||||
}
|
||||
|
||||
log.WithFields("len", storedLength).Trace("found java native-image SBOM")
|
||||
sbomEnd := sbomStart + storedLength
|
||||
if sbomEnd > uint64(bufLen) {
|
||||
return nil, errors.New("the sbom symbol overflows the binary")
|
||||
return nil, nil, errors.New("the sbom symbol overflows the binary")
|
||||
}
|
||||
|
||||
sbomCompressed := dataBuf[sbomStart:sbomEnd]
|
||||
p = bytes.NewBuffer(sbomCompressed)
|
||||
gzreader, err := gzip.NewReader(p)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("could not decompress the java native-image SBOM: %w", err)
|
||||
return nil, nil, fmt.Errorf("could not decompress the java native-image SBOM: %w", err)
|
||||
}
|
||||
|
||||
output, err := io.ReadAll(gzreader)
|
||||
sbom, _, _, err := cyclonedxjson.NewFormatDecoder().Decode(gzreader)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("could not read the java native-image SBOM: %w", err)
|
||||
return nil, nil, fmt.Errorf("could not unmarshal the java native-image SBOM: %w", err)
|
||||
}
|
||||
|
||||
var sbomContent nativeImageCycloneDX
|
||||
err = json.Unmarshal(output, &sbomContent)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("could not unmarshal the java native-image SBOM: %w", err)
|
||||
}
|
||||
|
||||
for _, component := range sbomContent.Components {
|
||||
p := getPackage(component)
|
||||
var pkgs []pkg.Package
|
||||
for p := range sbom.Artifacts.Packages.Enumerate() {
|
||||
pkgs = append(pkgs, p)
|
||||
}
|
||||
|
||||
return pkgs, nil
|
||||
return pkgs, sbom.Relationships, nil
|
||||
}
|
||||
|
||||
// fileError logs an error message when an executable cannot be read.
|
||||
@@ -294,7 +237,7 @@ func newPE(filename string, r io.ReaderAt) (nativeImage, error) {
|
||||
}
|
||||
|
||||
// fetchPkgs obtains the packages given in the binary.
|
||||
func (ni nativeImageElf) fetchPkgs() (pkgs []pkg.Package, retErr error) {
|
||||
func (ni nativeImageElf) fetchPkgs() (pkgs []pkg.Package, relationships []artifact.Relationship, retErr error) {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
// this can happen in cases where a malformed binary is passed in can be initially parsed, but not
|
||||
@@ -310,10 +253,10 @@ func (ni nativeImageElf) fetchPkgs() (pkgs []pkg.Package, retErr error) {
|
||||
|
||||
si, err := bi.Symbols()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("no symbols found in binary: %w", err)
|
||||
return nil, nil, fmt.Errorf("no symbols found in binary: %w", err)
|
||||
}
|
||||
if si == nil {
|
||||
return nil, errors.New(nativeImageMissingSymbolsError)
|
||||
return nil, nil, errors.New(nativeImageMissingSymbolsError)
|
||||
}
|
||||
for _, s := range si {
|
||||
switch s.Name {
|
||||
@@ -326,16 +269,16 @@ func (ni nativeImageElf) fetchPkgs() (pkgs []pkg.Package, retErr error) {
|
||||
}
|
||||
}
|
||||
if sbom.Value == 0 || sbomLength.Value == 0 || svmVersion.Value == 0 {
|
||||
return nil, errors.New(nativeImageMissingSymbolsError)
|
||||
return nil, nil, errors.New(nativeImageMissingSymbolsError)
|
||||
}
|
||||
dataSection := bi.Section(".data")
|
||||
if dataSection == nil {
|
||||
return nil, fmt.Errorf("no .data section found in binary: %w", err)
|
||||
return nil, nil, fmt.Errorf("no .data section found in binary: %w", err)
|
||||
}
|
||||
dataSectionBase := dataSection.SectionHeader.Addr
|
||||
data, err := dataSection.Data()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("cannot read the .data section: %w", err)
|
||||
return nil, nil, fmt.Errorf("cannot read the .data section: %w", err)
|
||||
}
|
||||
sbomLocation := sbom.Value - dataSectionBase
|
||||
lengthLocation := sbomLength.Value - dataSectionBase
|
||||
@@ -344,7 +287,7 @@ func (ni nativeImageElf) fetchPkgs() (pkgs []pkg.Package, retErr error) {
|
||||
}
|
||||
|
||||
// fetchPkgs obtains the packages from a Native Image given as a Mach O file.
|
||||
func (ni nativeImageMachO) fetchPkgs() (pkgs []pkg.Package, retErr error) {
|
||||
func (ni nativeImageMachO) fetchPkgs() (pkgs []pkg.Package, relationships []artifact.Relationship, retErr error) {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
// this can happen in cases where a malformed binary is passed in can be initially parsed, but not
|
||||
@@ -359,7 +302,7 @@ func (ni nativeImageMachO) fetchPkgs() (pkgs []pkg.Package, retErr error) {
|
||||
|
||||
bi := ni.file
|
||||
if bi.Symtab == nil {
|
||||
return nil, errors.New(nativeImageMissingSymbolsError)
|
||||
return nil, nil, errors.New(nativeImageMissingSymbolsError)
|
||||
}
|
||||
for _, s := range bi.Symtab.Syms {
|
||||
switch s.Name {
|
||||
@@ -372,17 +315,17 @@ func (ni nativeImageMachO) fetchPkgs() (pkgs []pkg.Package, retErr error) {
|
||||
}
|
||||
}
|
||||
if sbom.Value == 0 || sbomLength.Value == 0 || svmVersion.Value == 0 {
|
||||
return nil, errors.New(nativeImageMissingSymbolsError)
|
||||
return nil, nil, errors.New(nativeImageMissingSymbolsError)
|
||||
}
|
||||
|
||||
dataSegment := bi.Segment("__DATA")
|
||||
if dataSegment == nil {
|
||||
return nil, nil
|
||||
return nil, nil, nil
|
||||
}
|
||||
dataBuf, err := dataSegment.Data()
|
||||
if err != nil {
|
||||
log.Tracef("cannot obtain buffer from data segment")
|
||||
return nil, nil
|
||||
return nil, nil, nil
|
||||
}
|
||||
sbomLocation := sbom.Value - dataSegment.Addr
|
||||
lengthLocation := sbomLength.Value - dataSegment.Addr
|
||||
@@ -494,7 +437,7 @@ func (ni nativeImagePE) fetchSbomSymbols(content *exportContentPE) {
|
||||
}
|
||||
|
||||
// fetchPkgs obtains the packages from a Native Image given as a PE file.
|
||||
func (ni nativeImagePE) fetchPkgs() (pkgs []pkg.Package, retErr error) {
|
||||
func (ni nativeImagePE) fetchPkgs() (pkgs []pkg.Package, relationships []artifact.Relationship, retErr error) {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
// this can happen in cases where a malformed binary is passed in can be initially parsed, but not
|
||||
@@ -506,32 +449,32 @@ func (ni nativeImagePE) fetchPkgs() (pkgs []pkg.Package, retErr error) {
|
||||
content, err := ni.fetchExportContent()
|
||||
if err != nil {
|
||||
log.Debugf("could not fetch the content of the export directory entry: %v", err)
|
||||
return nil, err
|
||||
return nil, nil, err
|
||||
}
|
||||
ni.fetchSbomSymbols(content)
|
||||
if content.addressOfSbom == uint32(0) || content.addressOfSbomLength == uint32(0) || content.addressOfSvmVersion == uint32(0) {
|
||||
return nil, errors.New(nativeImageMissingSymbolsError)
|
||||
return nil, nil, errors.New(nativeImageMissingSymbolsError)
|
||||
}
|
||||
functionsBase := content.addressOfFunctions - ni.exportSymbols.VirtualAddress
|
||||
sbomOffset := content.addressOfSbom
|
||||
sbomAddress, err := ni.fetchExportFunctionPointer(functionsBase, sbomOffset)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("could not fetch SBOM pointer from exported functions: %w", err)
|
||||
return nil, nil, fmt.Errorf("could not fetch SBOM pointer from exported functions: %w", err)
|
||||
}
|
||||
sbomLengthOffset := content.addressOfSbomLength
|
||||
sbomLengthAddress, err := ni.fetchExportFunctionPointer(functionsBase, sbomLengthOffset)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("could not fetch SBOM length pointer from exported functions: %w", err)
|
||||
return nil, nil, fmt.Errorf("could not fetch SBOM length pointer from exported functions: %w", err)
|
||||
}
|
||||
bi := ni.file
|
||||
dataSection := bi.Section(".data")
|
||||
if dataSection == nil {
|
||||
return nil, nil
|
||||
return nil, nil, nil
|
||||
}
|
||||
dataBuf, err := dataSection.Data()
|
||||
if err != nil {
|
||||
log.Tracef("cannot obtain buffer from the java native-image .data section")
|
||||
return nil, nil
|
||||
return nil, nil, nil
|
||||
}
|
||||
sbomLocation := sbomAddress - dataSection.VirtualAddress
|
||||
lengthLocation := sbomLengthAddress - dataSection.VirtualAddress
|
||||
@@ -540,8 +483,9 @@ func (ni nativeImagePE) fetchPkgs() (pkgs []pkg.Package, retErr error) {
|
||||
}
|
||||
|
||||
// fetchPkgs provides the packages available in a UnionReader.
|
||||
func fetchPkgs(reader unionreader.UnionReader, filename string) []pkg.Package {
|
||||
func fetchPkgs(reader unionreader.UnionReader, filename string) ([]pkg.Package, []artifact.Relationship) {
|
||||
var pkgs []pkg.Package
|
||||
var relationships []artifact.Relationship
|
||||
imageFormats := []func(string, io.ReaderAt) (nativeImage, error){newElf, newMachO, newPE}
|
||||
|
||||
// NOTE: multiple readers are returned to cover universal binaries, which are files
|
||||
@@ -549,7 +493,7 @@ func fetchPkgs(reader unionreader.UnionReader, filename string) []pkg.Package {
|
||||
readers, err := unionreader.GetReaders(reader)
|
||||
if err != nil {
|
||||
log.Debugf("failed to open the java native-image binary: %v", err)
|
||||
return nil
|
||||
return nil, nil
|
||||
}
|
||||
for _, r := range readers {
|
||||
for _, makeNativeImage := range imageFormats {
|
||||
@@ -560,47 +504,51 @@ func fetchPkgs(reader unionreader.UnionReader, filename string) []pkg.Package {
|
||||
if ni == nil {
|
||||
continue
|
||||
}
|
||||
newPkgs, err := ni.fetchPkgs()
|
||||
newPkgs, newRelationships, err := ni.fetchPkgs()
|
||||
if err != nil {
|
||||
log.Tracef("unable to extract SBOM from possible java native-image %s: %v", filename, err)
|
||||
continue
|
||||
}
|
||||
pkgs = append(pkgs, newPkgs...)
|
||||
relationships = append(relationships, newRelationships...)
|
||||
}
|
||||
}
|
||||
return pkgs
|
||||
return pkgs, relationships
|
||||
}
|
||||
|
||||
// Catalog attempts to find any native image executables reachable from a resolver.
|
||||
func (c *nativeImageCataloger) Catalog(_ context.Context, resolver file.Resolver) ([]pkg.Package, []artifact.Relationship, error) {
|
||||
var pkgs []pkg.Package
|
||||
var relationships []artifact.Relationship
|
||||
fileMatches, err := resolver.FilesByMIMEType(mimetype.ExecutableMIMETypeSet.List()...)
|
||||
if err != nil {
|
||||
return pkgs, nil, fmt.Errorf("failed to find binaries by mime types: %w", err)
|
||||
}
|
||||
|
||||
for _, location := range fileMatches {
|
||||
newPkgs, err := processLocation(location, resolver)
|
||||
newPkgs, newRelationships, err := processLocation(location, resolver)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
pkgs = append(pkgs, newPkgs...)
|
||||
relationships = append(relationships, newRelationships...)
|
||||
}
|
||||
|
||||
return pkgs, nil, nil
|
||||
return pkgs, relationships, nil
|
||||
}
|
||||
|
||||
func processLocation(location file.Location, resolver file.Resolver) ([]pkg.Package, error) {
|
||||
func processLocation(location file.Location, resolver file.Resolver) ([]pkg.Package, []artifact.Relationship, error) {
|
||||
readerCloser, err := resolver.FileContentsByLocation(location)
|
||||
if err != nil {
|
||||
log.Debugf("error opening file: %v", err)
|
||||
return nil, nil
|
||||
return nil, nil, nil
|
||||
}
|
||||
defer internal.CloseAndLogError(readerCloser, location.RealPath)
|
||||
|
||||
reader, err := unionreader.GetUnionReader(readerCloser)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, nil, err
|
||||
}
|
||||
return fetchPkgs(reader, location.RealPath), nil
|
||||
pkgs, relationships := fetchPkgs(reader, location.RealPath)
|
||||
return pkgs, relationships, nil
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
"bytes"
|
||||
"compress/gzip"
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"path"
|
||||
@@ -12,6 +13,7 @@ import (
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/anchore/syft/syft/artifact"
|
||||
"github.com/anchore/syft/syft/cpe"
|
||||
"github.com/anchore/syft/syft/internal/unionreader"
|
||||
"github.com/anchore/syft/syft/pkg"
|
||||
@@ -40,10 +42,11 @@ func TestParseNativeImage(t *testing.T) {
|
||||
assert.NoError(t, err)
|
||||
parsed := false
|
||||
readers, err := unionreader.GetReaders(reader)
|
||||
assert.NoError(t, err)
|
||||
for _, r := range readers {
|
||||
ni, err := test.newFn(test.fixture, r)
|
||||
assert.NoError(t, err)
|
||||
_, err = ni.fetchPkgs()
|
||||
_, _, err = ni.fetchPkgs()
|
||||
if err == nil {
|
||||
t.Fatalf("should have failed to extract SBOM.")
|
||||
}
|
||||
@@ -60,77 +63,205 @@ func TestParseNativeImage(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestParseNativeImageSbom(t *testing.T) {
|
||||
const (
|
||||
nettyPurl = "pkg:maven/io.netty/netty-codec-http2@4.1.104.Final"
|
||||
micronautPurl = "pkg:maven/io.micronaut/core@4.2.3"
|
||||
mainAppPurl = "pkg:maven/com.oracle/main-test-app@1.0-SNAPSHOT"
|
||||
)
|
||||
|
||||
mainAppPkg := makePackage("main-test-app", "1.0-SNAPSHOT", mainAppPurl, []cpe.CPE{
|
||||
{
|
||||
Attributes: cpe.Attributes{
|
||||
Part: "a",
|
||||
Vendor: "app",
|
||||
Product: "main-test-app",
|
||||
Version: "1.0-SNAPSHOT",
|
||||
},
|
||||
Source: "declared",
|
||||
},
|
||||
})
|
||||
|
||||
nettyPkg := makePackage("netty-codec-http2", "4.1.73.Final", nettyPurl, []cpe.CPE{
|
||||
{
|
||||
Attributes: cpe.Attributes{
|
||||
Part: "a",
|
||||
Vendor: "codec",
|
||||
Product: "codec",
|
||||
Version: "4.1.73.Final",
|
||||
},
|
||||
Source: "declared",
|
||||
},
|
||||
{
|
||||
Attributes: cpe.Attributes{
|
||||
Part: "a",
|
||||
Vendor: "codec",
|
||||
Product: "netty-codec-http2",
|
||||
Version: "4.1.73.Final",
|
||||
},
|
||||
Source: "declared",
|
||||
},
|
||||
{
|
||||
Attributes: cpe.Attributes{
|
||||
Part: "a",
|
||||
Vendor: "codec",
|
||||
Product: "netty_codec_http2",
|
||||
Version: "4.1.73.Final",
|
||||
},
|
||||
Source: "declared",
|
||||
},
|
||||
})
|
||||
|
||||
micronautPkg := makePackage("core", "4.2.3", micronautPurl, []cpe.CPE{
|
||||
{
|
||||
Attributes: cpe.Attributes{
|
||||
Part: "a",
|
||||
Vendor: "core",
|
||||
Product: "core",
|
||||
Version: "4.2.3",
|
||||
},
|
||||
Source: "declared",
|
||||
},
|
||||
{
|
||||
Attributes: cpe.Attributes{
|
||||
Part: "a",
|
||||
Vendor: "micronaut",
|
||||
Product: "core",
|
||||
Version: "4.2.3",
|
||||
},
|
||||
Source: "declared",
|
||||
},
|
||||
})
|
||||
|
||||
basicPkg := makePackage("basic-lib", "1.0", "", nil)
|
||||
|
||||
tests := []struct {
|
||||
fixture string
|
||||
expected []pkg.Package
|
||||
fixture string
|
||||
expectedPackages []pkg.Package
|
||||
expectedRelations []artifact.Relationship
|
||||
}{
|
||||
{
|
||||
fixture: "test-fixtures/graalvm-sbom/micronaut.json",
|
||||
expected: []pkg.Package{
|
||||
fixture: "test-fixtures/graalvm-sbom/micronaut.json",
|
||||
expectedPackages: []pkg.Package{nettyPkg, micronautPkg, basicPkg, mainAppPkg},
|
||||
expectedRelations: []artifact.Relationship{
|
||||
{
|
||||
Name: "netty-codec-http2",
|
||||
Version: "4.1.73.Final",
|
||||
Language: pkg.Java,
|
||||
Type: pkg.GraalVMNativeImagePkg,
|
||||
FoundBy: nativeImageCatalogerName,
|
||||
Metadata: pkg.JavaArchive{
|
||||
PomProperties: &pkg.JavaPomProperties{
|
||||
GroupID: "io.netty",
|
||||
},
|
||||
},
|
||||
CPEs: []cpe.CPE{
|
||||
{
|
||||
Attributes: cpe.Attributes{
|
||||
Part: "a",
|
||||
Vendor: "codec",
|
||||
Product: "codec",
|
||||
Version: "4.1.73.Final",
|
||||
},
|
||||
Source: "declared",
|
||||
},
|
||||
{
|
||||
Attributes: cpe.Attributes{
|
||||
Part: "a",
|
||||
Vendor: "codec",
|
||||
Product: "netty-codec-http2",
|
||||
Version: "4.1.73.Final",
|
||||
},
|
||||
Source: "declared",
|
||||
},
|
||||
{
|
||||
Attributes: cpe.Attributes{
|
||||
Part: "a",
|
||||
Vendor: "codec",
|
||||
Product: "netty_codec_http2",
|
||||
Version: "4.1.73.Final",
|
||||
},
|
||||
Source: "declared",
|
||||
},
|
||||
},
|
||||
From: nettyPkg,
|
||||
To: micronautPkg,
|
||||
Type: artifact.DependencyOfRelationship,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run(path.Base(test.fixture), func(t *testing.T) {
|
||||
// Create a buffer to resemble a compressed SBOM in a native image.
|
||||
sbom, err := os.ReadFile(test.fixture)
|
||||
assert.NoError(t, err)
|
||||
var b bytes.Buffer
|
||||
writebytes := bufio.NewWriter(&b)
|
||||
z := gzip.NewWriter(writebytes)
|
||||
_, err = z.Write(sbom)
|
||||
assert.NoError(t, err)
|
||||
_ = z.Close()
|
||||
_ = writebytes.Flush()
|
||||
compressedsbom := b.Bytes()
|
||||
sbomlength := uint64(len(compressedsbom))
|
||||
_ = binary.Write(writebytes, binary.LittleEndian, sbomlength)
|
||||
_ = writebytes.Flush()
|
||||
compressedsbom = b.Bytes()
|
||||
actual, err := decompressSbom(compressedsbom, 0, sbomlength)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, test.expected, actual)
|
||||
compressed, length := createCompressedSbom(t, test.fixture)
|
||||
actualPkgs, actualRels, err := decompressSbom(compressed, 0, length)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
verifyPackages(t, test.expectedPackages, actualPkgs)
|
||||
verifyRelationships(t, test.expectedRelations, actualRels)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// makePackage makes a package using the data that we know must be in the parsed package
|
||||
func makePackage(name, version, purl string, cpes []cpe.CPE) pkg.Package {
|
||||
p := pkg.Package{
|
||||
Name: name,
|
||||
Version: version,
|
||||
CPEs: cpes,
|
||||
PURL: purl,
|
||||
}
|
||||
return p
|
||||
}
|
||||
|
||||
// createCompressedSbom creates a compressed a buffer to resemble a compressed SBOM in a native image.
|
||||
func createCompressedSbom(t *testing.T, filename string) ([]byte, uint64) {
|
||||
sbom, err := os.ReadFile(filename)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
var b bytes.Buffer
|
||||
w := bufio.NewWriter(&b)
|
||||
z := gzip.NewWriter(w)
|
||||
|
||||
if _, err := z.Write(sbom); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
z.Close()
|
||||
w.Flush()
|
||||
|
||||
compressedSbom := b.Bytes()
|
||||
sbomLength := uint64(len(compressedSbom))
|
||||
|
||||
if err := binary.Write(w, binary.LittleEndian, sbomLength); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
w.Flush()
|
||||
|
||||
return b.Bytes(), sbomLength
|
||||
}
|
||||
|
||||
func verifyPackages(t *testing.T, expected, actual []pkg.Package) {
|
||||
expectedPkgMap := buildPackageMap(expected)
|
||||
actualPkgMap := buildPackageMap(actual)
|
||||
|
||||
for name, expectedPkg := range expectedPkgMap {
|
||||
actualPkg, exists := actualPkgMap[name]
|
||||
if !exists {
|
||||
t.Errorf("Expected package %s not found in actual packages", name)
|
||||
continue
|
||||
}
|
||||
verifyPackageFields(t, expectedPkg, actualPkg)
|
||||
}
|
||||
}
|
||||
|
||||
func buildPackageMap(packages []pkg.Package) map[string]pkg.Package {
|
||||
pkgMap := make(map[string]pkg.Package)
|
||||
for _, p := range packages {
|
||||
pkgMap[p.Name] = p
|
||||
}
|
||||
return pkgMap
|
||||
}
|
||||
|
||||
func verifyPackageFields(t *testing.T, expected, actual pkg.Package) {
|
||||
assert.Equal(t, expected.Name, actual.Name)
|
||||
assert.Equal(t, expected.Version, actual.Version)
|
||||
assert.Equal(t, expected.FoundBy, actual.FoundBy)
|
||||
assert.Equal(t, expected.PURL, actual.PURL)
|
||||
assert.ElementsMatch(t, expected.CPEs, actual.CPEs)
|
||||
}
|
||||
|
||||
func verifyRelationships(t *testing.T, expected, actual []artifact.Relationship) {
|
||||
expectedRelMap := buildRelationshipMap(expected)
|
||||
actualRelMap := buildRelationshipMap(actual)
|
||||
|
||||
for key, expectedRels := range expectedRelMap {
|
||||
actualRels, exists := actualRelMap[key]
|
||||
if !exists {
|
||||
t.Errorf("Expected relationship %s not found in actual relationships", key)
|
||||
continue
|
||||
}
|
||||
verifyRelationshipFields(t, expectedRels, actualRels)
|
||||
}
|
||||
}
|
||||
|
||||
func buildRelationshipMap(relationships []artifact.Relationship) map[string][]artifact.Relationship {
|
||||
relMap := make(map[string][]artifact.Relationship)
|
||||
for _, rel := range relationships {
|
||||
// we cannot control the id, so use the names instead
|
||||
key := fmt.Sprintf("%s->%s", rel.From.(pkg.Package).Name, rel.To.(pkg.Package).Name)
|
||||
relMap[key] = append(relMap[key], rel)
|
||||
}
|
||||
return relMap
|
||||
}
|
||||
|
||||
func verifyRelationshipFields(t *testing.T, expected, actual []artifact.Relationship) {
|
||||
assert.Equal(t, len(expected), len(actual))
|
||||
for i := range expected {
|
||||
assert.Equal(t, expected[i].Type, actual[i].Type)
|
||||
}
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user