mirror of
https://github.com/anchore/syft.git
synced 2026-10-17 08:37:19 +02:00
Compare commits
+1
-1
@@ -111,7 +111,7 @@ tools:
|
||||
# used for triggering a release
|
||||
- name: gh
|
||||
version:
|
||||
want: v2.58.0
|
||||
want: v2.59.0
|
||||
method: github-release
|
||||
with:
|
||||
repo: cli/cli
|
||||
|
||||
@@ -17,13 +17,13 @@ jobs:
|
||||
# the job by event.
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0
|
||||
uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1
|
||||
|
||||
- name: Bootstrap environment
|
||||
uses: ./.github/actions/bootstrap
|
||||
|
||||
- name: Restore base benchmark result
|
||||
uses: actions/cache@2cdf405574d6ef1f33a1d12acccd3ae82f47b3f2 #v4.1.0
|
||||
uses: actions/cache@3624ceb22c1c5a301c8db4169662070a689d9ea8 #v4.1.1
|
||||
with:
|
||||
path: test/results/benchmark-main.txt
|
||||
# use base sha for PR or new commit hash for main push in benchmark result key
|
||||
@@ -39,7 +39,7 @@ jobs:
|
||||
OUTPUT="${OUTPUT//$'\r'/'%0D'}" # URL encode all '\r' characters
|
||||
echo "result=$OUTPUT" >> $GITHUB_OUTPUT
|
||||
|
||||
- uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0
|
||||
- uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
|
||||
with:
|
||||
name: benchmark-test-results
|
||||
path: test/results/**/*
|
||||
|
||||
@@ -36,7 +36,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 #v4.2.0
|
||||
uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 #v4.2.1
|
||||
|
||||
- name: Install Go
|
||||
uses: actions/setup-go@0a12ed9d6a96ab950c8f026ed9f722fe0da7ef32 #v5.0.2
|
||||
@@ -45,7 +45,7 @@ jobs:
|
||||
|
||||
# Initializes the CodeQL tools for scanning.
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@6db8d6351fd0be61f9ed8ebd12ccd35dcec51fea #v3.26.11
|
||||
uses: github/codeql-action/init@f779452ac5af1c261dce0346a8f964149f49322b #v3.26.13
|
||||
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@6db8d6351fd0be61f9ed8ebd12ccd35dcec51fea #v3.26.11
|
||||
uses: github/codeql-action/autobuild@f779452ac5af1c261dce0346a8f964149f49322b #v3.26.13
|
||||
|
||||
# ℹ️ 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@6db8d6351fd0be61f9ed8ebd12ccd35dcec51fea #v3.26.11
|
||||
uses: github/codeql-action/analyze@f779452ac5af1c261dce0346a8f964149f49322b #v3.26.13
|
||||
|
||||
@@ -30,7 +30,7 @@ jobs:
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
|
||||
- uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 #v4.2.0
|
||||
- uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 #v4.2.1
|
||||
|
||||
- run: python .github/scripts/labeler.py
|
||||
env:
|
||||
|
||||
@@ -20,7 +20,7 @@ jobs:
|
||||
release:
|
||||
runs-on: ubuntu-20.04
|
||||
steps:
|
||||
- uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 #v4.2.0
|
||||
- uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 #v4.2.1
|
||||
|
||||
- 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@d632683dd7b4114ad314bca15554477dd762a938 #v4.2.0
|
||||
- uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 #v4.2.1
|
||||
|
||||
- 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@d632683dd7b4114ad314bca15554477dd762a938 #v4.2.0
|
||||
- uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 #v4.2.1
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
@@ -148,7 +148,7 @@ jobs:
|
||||
# for updating brew formula in anchore/homebrew-syft
|
||||
GITHUB_BREW_TOKEN: ${{ secrets.ANCHOREOPS_GITHUB_OSS_WRITE_TOKEN }}
|
||||
|
||||
- uses: anchore/sbom-action@61119d458adab75f756bc0b9e4bde25725f86a7a #v0.17.2
|
||||
- uses: anchore/sbom-action@8d0a6505bf28ced3e85154d13dc6af83299e13f1 #v0.17.4
|
||||
continue-on-error: true
|
||||
with:
|
||||
artifact-name: sbom.spdx.json
|
||||
|
||||
@@ -18,7 +18,7 @@ jobs:
|
||||
permissions:
|
||||
packages: write
|
||||
steps:
|
||||
- uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 #v4.2.0
|
||||
- uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 #v4.2.1
|
||||
|
||||
- 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@d632683dd7b4114ad314bca15554477dd762a938 #v4.2.0
|
||||
- uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 #v4.2.1
|
||||
|
||||
- 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@d632683dd7b4114ad314bca15554477dd762a938 #v4.2.0
|
||||
- uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 #v4.2.1
|
||||
|
||||
- name: Bootstrap environment
|
||||
uses: ./.github/actions/bootstrap
|
||||
|
||||
@@ -17,7 +17,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
if: github.repository == 'anchore/syft' # only run for main repo
|
||||
steps:
|
||||
- uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 #v4.2.0
|
||||
- uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 #v4.2.1
|
||||
|
||||
- uses: actions/setup-go@0a12ed9d6a96ab950c8f026ed9f722fe0da7ef32 #v5.0.2
|
||||
with:
|
||||
|
||||
@@ -17,7 +17,7 @@ jobs:
|
||||
name: "Static analysis"
|
||||
runs-on: ubuntu-20.04
|
||||
steps:
|
||||
- uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 #v4.2.0
|
||||
- uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 #v4.2.1
|
||||
|
||||
- name: Bootstrap environment
|
||||
uses: ./.github/actions/bootstrap
|
||||
@@ -31,7 +31,7 @@ jobs:
|
||||
name: "Unit tests"
|
||||
runs-on: ubuntu-20.04
|
||||
steps:
|
||||
- uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 #v4.2.0
|
||||
- uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 #v4.2.1
|
||||
|
||||
- name: Bootstrap environment
|
||||
uses: ./.github/actions/bootstrap
|
||||
@@ -47,7 +47,7 @@ jobs:
|
||||
name: "Integration tests"
|
||||
runs-on: ubuntu-20.04
|
||||
steps:
|
||||
- uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 #v4.2.0
|
||||
- uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 #v4.2.1
|
||||
|
||||
- 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@d632683dd7b4114ad314bca15554477dd762a938 #v4.2.0
|
||||
- uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 #v4.2.1
|
||||
|
||||
- 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@2cdf405574d6ef1f33a1d12acccd3ae82f47b3f2 #v4.1.0
|
||||
uses: actions/cache/save@3624ceb22c1c5a301c8db4169662070a689d9ea8 #v4.1.1
|
||||
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@d632683dd7b4114ad314bca15554477dd762a938 #v4.2.0
|
||||
- uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 #v4.2.1
|
||||
|
||||
- name: Bootstrap environment
|
||||
uses: ./.github/actions/bootstrap
|
||||
@@ -104,7 +104,7 @@ jobs:
|
||||
|
||||
- name: Download snapshot build
|
||||
id: snapshot-cache
|
||||
uses: actions/cache/restore@2cdf405574d6ef1f33a1d12acccd3ae82f47b3f2 #v4.1.0
|
||||
uses: actions/cache/restore@3624ceb22c1c5a301c8db4169662070a689d9ea8 #v4.1.1
|
||||
with:
|
||||
path: |
|
||||
snapshot
|
||||
@@ -141,7 +141,7 @@ jobs:
|
||||
- name: Install Cosign
|
||||
uses: sigstore/cosign-installer@v3.7.0
|
||||
|
||||
- uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 #v4.2.0
|
||||
- uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 #v4.2.1
|
||||
|
||||
- name: Bootstrap environment
|
||||
uses: ./.github/actions/bootstrap
|
||||
@@ -152,7 +152,7 @@ jobs:
|
||||
|
||||
- name: Download snapshot build
|
||||
id: snapshot-cache
|
||||
uses: actions/cache/restore@2cdf405574d6ef1f33a1d12acccd3ae82f47b3f2 #v4.1.0
|
||||
uses: actions/cache/restore@3624ceb22c1c5a301c8db4169662070a689d9ea8 #v4.1.1
|
||||
with:
|
||||
path: |
|
||||
snapshot
|
||||
@@ -178,7 +178,7 @@ jobs:
|
||||
needs: [Build-Snapshot-Artifacts]
|
||||
runs-on: ubuntu-20.04
|
||||
steps:
|
||||
- uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 #v4.2.0
|
||||
- uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 #v4.2.1
|
||||
|
||||
- name: Bootstrap environment
|
||||
uses: ./.github/actions/bootstrap
|
||||
@@ -187,7 +187,7 @@ jobs:
|
||||
|
||||
- name: Download snapshot build
|
||||
id: snapshot-cache
|
||||
uses: actions/cache/restore@2cdf405574d6ef1f33a1d12acccd3ae82f47b3f2 #v4.1.0
|
||||
uses: actions/cache/restore@3624ceb22c1c5a301c8db4169662070a689d9ea8 #v4.1.1
|
||||
with:
|
||||
path: |
|
||||
snapshot
|
||||
@@ -215,7 +215,7 @@ jobs:
|
||||
- Acceptance-Mac
|
||||
- Cli-Linux
|
||||
steps:
|
||||
- uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 #v4.2.0
|
||||
- uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 #v4.2.1
|
||||
|
||||
- name: Delete snapshot cache
|
||||
run: gh cache delete "snapshot-build-${{ github.run_id }}"
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
<a href="https://github.com/anchore/syft" target="_blank"><img alt="GitHub go.mod Go version" src="https://img.shields.io/github/go-mod/go-version/anchore/syft.svg"></a>
|
||||
<a href="" target="_blank"><img alt="License: Apache-2.0" src="https://img.shields.io/badge/License-Apache%202.0-blue.svg"></a>
|
||||
<a href="https://anchore.com/discourse" target="_blank"><img alt="Join our Discourse" src="https://img.shields.io/badge/Discourse-Join-blue?logo=discourse"/></a>
|
||||
<a rel="me" href="https://fosstodon.org/@syft"><img alt="Follow on Mastodon" src="https://img.shields.io/badge/Mastodon-Follow-blue?logoColor=white&logo=mastodon"/></a>
|
||||
</p>
|
||||
|
||||

|
||||
|
||||
+13
-86
@@ -1,5 +1,16 @@
|
||||
# Release
|
||||
|
||||
A release of syft comprises:
|
||||
- a new semver git tag from the current tip of the main branch
|
||||
- a new [github release](https://github.com/anchore/syft/releases) with a changelog and archived binary assets
|
||||
- docker images published to `ghcr.io` and `dockerhub`, including multi architecture images + manifest
|
||||
- [`anchore/homebrew-syft`](https://github.com/anchore/homebrew-syft) tap updated to point to assets in the latest github release
|
||||
|
||||
Ideally releasing should be done often with small increments when possible. Unless a
|
||||
breaking change is blocking the release, or no fixes/features have been merged, a good
|
||||
target release cadence is between every 1 or 2 weeks.
|
||||
|
||||
|
||||
## Creating a release
|
||||
|
||||
This release process itself should be as automated as possible, and has only a few steps:
|
||||
@@ -9,16 +20,10 @@ This release process itself should be as automated as possible, and has only a f
|
||||
you can abort and adjust the labels on the PRs and issues to be included in the release and
|
||||
re-run the release trigger command.
|
||||
|
||||
1. A release admin must approve the release on the GitHub Actions release pipeline run page.
|
||||
1. A release admin must approve the release on the GitHub Actions [release pipeline](https://github.com/anchore/syft/actions/workflows/release.yaml) run page.
|
||||
Once approved, the release pipeline will generate all assets and publish a GitHub Release.
|
||||
|
||||
1. If there is a release Milestone, close it.
|
||||
|
||||
Ideally releasing should be done often with small increments when possible. Unless a
|
||||
breaking change is blocking the release, or no fixes/features have been merged, a good
|
||||
target release cadence is between every 1 or 2 weeks.
|
||||
|
||||
|
||||
|
||||
## Retracting a release
|
||||
|
||||
If a release is found to be problematic, it can be retracted with the following steps:
|
||||
@@ -32,81 +37,3 @@ If a release is found to be problematic, it can be retracted with the following
|
||||
in the go proxy, which will cause confusion when trying to reuse the tag later (the H1 hash will not match and there
|
||||
will be a warning when users try to pull the new release).
|
||||
|
||||
|
||||
## Background
|
||||
|
||||
A good release process has the following qualities:
|
||||
|
||||
1. There is a way to plan what should be in a release
|
||||
1. There is a way to see what is actually in a release
|
||||
1. Allow for different kinds of releases (major breaking vs backwards compatible enhancements vs patch updates)
|
||||
1. Specify a repeatable way to build and publish software artifacts
|
||||
|
||||
|
||||
### Planning a release
|
||||
|
||||
To indicate a set of features to be released together add each issue to an in-repository
|
||||
Milestone named with major-minor version to be released (e.g. `v0.1`). It is OK for other
|
||||
features to be in the release that were not originally planned, and these issues and PRs
|
||||
do not need to be added to the Milestone in question. Only the set of features that, when
|
||||
completed, would allow the release to be considered complete. A Milestone is only used to:
|
||||
|
||||
- Plan what is desired to be in a release
|
||||
- Track progress to indicate when we may be ready to cut a new release
|
||||
|
||||
Not all releases need to be planned. For instance, patch releases for fixes should be
|
||||
released when they are ready and when releasing would not interfere with another current
|
||||
release (where some partial or breaking features have already been merged).
|
||||
|
||||
Unless necessary, feature releases should be small and frequent, which may obviate the
|
||||
need for regular release planning under a Milestone.
|
||||
|
||||
|
||||
### What is in a release
|
||||
|
||||
Milestones are specifically for planning a release, not necessarily tracking all changes
|
||||
that a release may bring (and more importantly, not all releases are necessarily planned
|
||||
either).
|
||||
|
||||
This is one of the (many) reasons for a Changelog. A good Changelog lists changes grouped
|
||||
by the type of change (new, enhancement, deprecation, breaking, bug fix, security fix), in
|
||||
chronological order (within groups), linking the PR where the change was made in the
|
||||
Changelog line. Furthermore, there should be a place to see all released versions, the
|
||||
release date for each release, the semantic version of the release, and the set of changes
|
||||
for each release.
|
||||
|
||||
**This project auto-generates the Changelog contents for each current release and posts the
|
||||
generated contents to the GitHub Release page**. Leveraging the GitHub Releases feature
|
||||
allows GitHub to manage the Changelog on each release outside of the git source tree while
|
||||
still being hosted with the released assets.
|
||||
|
||||
The Changelog is generated from the metadata from in-repository issues and PRs, using
|
||||
labels to guide what kind of change each item is (e.g. breaking, new feature, bug fix,
|
||||
etx). Only issues/PRs with select labels are included in the Changelog, and only if the
|
||||
issue/PR was created after the last release. Additional labels are used to exclude items
|
||||
from the Changelog.
|
||||
|
||||
The above suggestions imply that we should:
|
||||
|
||||
- Ensure there is a sufficient title for each PR and issue title to be included in the
|
||||
Changelog
|
||||
- The appropriate label is applied to PRs and/or issues to drive specific change type
|
||||
sections (deprecated, breaking, security, bug, etc)
|
||||
|
||||
**With this approach as we cultivate good organization of PRs and issues we automatically
|
||||
get an equally good Changelog.**
|
||||
|
||||
|
||||
### Major, minor, and patch releases
|
||||
|
||||
The latest version of the tool is the only supported version, which implies that multiple
|
||||
parallel release branches will not be a regular process (if ever). Multiple releases can
|
||||
be planned in parallel, however, only one can be actively developed at a time. That is, if
|
||||
PRs attached to a release Milestone have been merged into the main branch, that release is
|
||||
now the "next" release. **This implies that the source of truth for release lies with the
|
||||
git log and Changelog, not with the release Milestones** (which are purely for planning and
|
||||
tracking).
|
||||
|
||||
Semantic versioning should be used to indicate breaking changes, new features, and fixes.
|
||||
The exception to this is `< 1.0`, where the major version is not bumped for breaking changes,
|
||||
instead the minor version indicates both new features and breaking changes.
|
||||
|
||||
@@ -28,7 +28,7 @@ func (o *OutputFile) AddFlags(flags clio.FlagSet) {
|
||||
|
||||
if pfp, ok := flags.(fangs.PFlagSetProvider); ok {
|
||||
flagSet := pfp.PFlagSet()
|
||||
flagSet.Lookup("file").Deprecated = "use: output"
|
||||
flagSet.Lookup("file").Deprecated = "use: --output FORMAT=PATH"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
module github.com/anchore/syft
|
||||
|
||||
go 1.22.0
|
||||
go 1.22.5
|
||||
|
||||
toolchain go1.22.8
|
||||
|
||||
require (
|
||||
github.com/CycloneDX/cyclonedx-go v0.9.1
|
||||
@@ -16,13 +18,13 @@ require (
|
||||
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.20240507183024-848e011fc24f
|
||||
github.com/anchore/stereoscope v0.0.4-0.20241005180410-efa76446cc1c
|
||||
github.com/anchore/packageurl-go v0.1.1-0.20241018175412-5c22e6360c4f
|
||||
github.com/anchore/stereoscope v0.0.5-0.20241018131503-a38c93517fc7
|
||||
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.6.1
|
||||
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
|
||||
@@ -46,7 +48,7 @@ require (
|
||||
github.com/hashicorp/go-multierror v1.1.1
|
||||
github.com/iancoleman/strcase v0.3.0
|
||||
github.com/invopop/jsonschema v0.7.0
|
||||
github.com/jedib0t/go-pretty/v6 v6.6.0
|
||||
github.com/jedib0t/go-pretty/v6 v6.6.1
|
||||
github.com/jinzhu/copier v0.4.0
|
||||
github.com/kastenhq/goversion v0.0.0-20230811215019-93b2f8823953
|
||||
github.com/knqyf263/go-rpmdb v0.1.1
|
||||
@@ -89,7 +91,7 @@ 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.0
|
||||
github.com/adrg/xdg v0.5.1
|
||||
github.com/magiconair/properties v1.8.7
|
||||
golang.org/x/exp v0.0.0-20231108232855-2478ac86f678
|
||||
)
|
||||
@@ -101,8 +103,8 @@ require (
|
||||
github.com/DataDog/zstd v1.5.5 // indirect
|
||||
github.com/Masterminds/goutils v1.1.1 // indirect
|
||||
github.com/Masterminds/semver/v3 v3.3.0 // indirect
|
||||
github.com/Microsoft/go-winio v0.6.1 // indirect
|
||||
github.com/Microsoft/hcsshim v0.11.4 // 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/anchore/go-struct-converter v0.0.0-20221118182256-c68fdcfa2092 // indirect
|
||||
github.com/andybalholm/brotli v1.0.4 // indirect
|
||||
@@ -115,16 +117,19 @@ require (
|
||||
github.com/charmbracelet/x/term v0.2.0 // indirect
|
||||
github.com/cloudflare/circl v1.3.8 // indirect
|
||||
github.com/containerd/cgroups v1.1.0 // indirect
|
||||
github.com/containerd/containerd v1.7.11 // indirect
|
||||
github.com/containerd/containerd v1.7.23 // indirect
|
||||
github.com/containerd/containerd/api v1.7.19 // indirect
|
||||
github.com/containerd/continuity v0.4.2 // indirect
|
||||
github.com/containerd/errdefs v0.3.0 // indirect
|
||||
github.com/containerd/fifo v1.1.0 // indirect
|
||||
github.com/containerd/log v0.1.0 // indirect
|
||||
github.com/containerd/platforms v0.2.1 // indirect
|
||||
github.com/containerd/stargz-snapshotter/estargz v0.14.3 // indirect
|
||||
github.com/containerd/ttrpc v1.2.2 // 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/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
|
||||
github.com/docker/cli v27.1.1+incompatible // indirect
|
||||
github.com/docker/cli v27.3.1+incompatible // indirect
|
||||
github.com/docker/distribution v2.8.3+incompatible // indirect
|
||||
github.com/docker/docker-credential-helpers v0.7.0 // indirect
|
||||
github.com/docker/go-connections v0.4.0 // indirect
|
||||
@@ -137,7 +142,7 @@ require (
|
||||
github.com/felixge/fgprof v0.9.3 // indirect
|
||||
github.com/felixge/httpsnoop v1.0.4 // indirect
|
||||
github.com/fsnotify/fsnotify v1.7.0 // indirect
|
||||
github.com/gabriel-vasile/mimetype v1.4.4 // indirect
|
||||
github.com/gabriel-vasile/mimetype v1.4.6 // indirect
|
||||
github.com/gkampitakis/ciinfo v0.3.0 // indirect
|
||||
github.com/gkampitakis/go-diff v1.3.2 // indirect
|
||||
github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect
|
||||
@@ -146,7 +151,7 @@ require (
|
||||
github.com/go-restruct/restruct v1.2.0-alpha // indirect
|
||||
github.com/gogo/protobuf v1.3.2 // indirect
|
||||
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
|
||||
github.com/golang/protobuf v1.5.3 // indirect
|
||||
github.com/golang/protobuf v1.5.4 // indirect
|
||||
github.com/golang/snappy v0.0.4 // indirect
|
||||
github.com/google/pprof v0.0.0-20240409012703-83162a5b38cd // indirect
|
||||
github.com/hashicorp/errwrap v1.1.0 // indirect
|
||||
@@ -175,14 +180,15 @@ require (
|
||||
github.com/moby/locker v1.0.1 // indirect
|
||||
github.com/moby/sys/sequential v0.5.0 // indirect
|
||||
github.com/moby/sys/signal v0.7.0 // indirect
|
||||
github.com/moby/sys/user v0.3.0 // indirect
|
||||
github.com/moby/sys/userns v0.1.0 // indirect
|
||||
github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 // indirect
|
||||
github.com/muesli/cancelreader v0.2.2 // indirect
|
||||
github.com/muesli/termenv v0.15.2 // indirect
|
||||
github.com/ncruces/go-strftime v0.1.9 // indirect
|
||||
github.com/nwaples/rardecode v1.1.0 // indirect
|
||||
github.com/opencontainers/image-spec v1.1.0 // indirect
|
||||
github.com/opencontainers/runc v1.1.14 // indirect
|
||||
github.com/opencontainers/runtime-spec v1.1.0-rc.1 // indirect
|
||||
github.com/opencontainers/runtime-spec v1.1.0 // indirect
|
||||
github.com/opencontainers/selinux v1.11.0 // indirect
|
||||
github.com/pborman/indent v1.2.1 // indirect
|
||||
github.com/pelletier/go-toml/v2 v2.2.2 // indirect
|
||||
@@ -206,7 +212,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.17.1 // indirect
|
||||
github.com/sylabs/sif/v2 v2.19.1 // 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
|
||||
@@ -232,11 +238,10 @@ require (
|
||||
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/tools v0.21.1-0.20240508182429-e35e4ccd0d2d // 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
|
||||
google.golang.org/protobuf v1.33.0 // indirect
|
||||
google.golang.org/protobuf v1.34.2 // indirect
|
||||
gopkg.in/ini.v1 v1.67.0 // indirect
|
||||
gopkg.in/warnings.v0 v0.1.2 // indirect
|
||||
modernc.org/gc/v3 v3.0.0-20240107210532-573471604cb6 // indirect
|
||||
|
||||
@@ -74,10 +74,10 @@ github.com/Masterminds/semver/v3 v3.3.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lpr
|
||||
github.com/Masterminds/sprig/v3 v3.3.0 h1:mQh0Yrg1XPo6vjYXgtf5OtijNAKJRNcTdOOGZe3tPhs=
|
||||
github.com/Masterminds/sprig/v3 v3.3.0/go.mod h1:Zy1iXRYNqNLUolqCpL4uhk6SHUMAOSCzdgBfDb35Lz0=
|
||||
github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY=
|
||||
github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow=
|
||||
github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM=
|
||||
github.com/Microsoft/hcsshim v0.11.4 h1:68vKo2VN8DE9AdN4tnkWnmdhqdbpUFM8OF3Airm7fz8=
|
||||
github.com/Microsoft/hcsshim v0.11.4/go.mod h1:smjE4dvqPX9Zldna+t5FG3rnoHhaB7QYxPRqGcpAD9w=
|
||||
github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY=
|
||||
github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU=
|
||||
github.com/Microsoft/hcsshim v0.11.7 h1:vl/nj3Bar/CvJSYo7gIQPyRWc9f3c6IeSNavBTSZNZQ=
|
||||
github.com/Microsoft/hcsshim v0.11.7/go.mod h1:MV8xMfmECjl5HdO7U/3/hFVnkmSBjAjmA09d4bExKcU=
|
||||
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=
|
||||
@@ -87,8 +87,8 @@ github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d h1:licZJFw2RwpH
|
||||
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.0 h1:dDaZvhMXatArP1NPHhnfaQUqWBLBsmx1h1HXQdMoFCY=
|
||||
github.com/adrg/xdg v0.5.0/go.mod h1:dDdY4M4DF9Rjy4kHPeNL+ilVF+p2lK8IdM9/rTSGcI4=
|
||||
github.com/adrg/xdg v0.5.1 h1:Im8iDbEFARltY09yOJlSGu4Asjk2vF85+3Dyru8uJ0U=
|
||||
github.com/adrg/xdg v0.5.1/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=
|
||||
@@ -113,10 +113,10 @@ github.com/anchore/go-testutils v0.0.0-20200925183923-d5f45b0d3c04 h1:VzprUTpc0v
|
||||
github.com/anchore/go-testutils v0.0.0-20200925183923-d5f45b0d3c04/go.mod h1:6dK64g27Qi1qGQZ67gFmBFvEHScy0/C8qhQhNe5B5pQ=
|
||||
github.com/anchore/go-version v1.2.2-0.20200701162849-18adb9c92b9b h1:e1bmaoJfZVsCYMrIZBpFxwV26CbsuoEh5muXD5I1Ods=
|
||||
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.20240507183024-848e011fc24f h1:B/E9ixKNCasntpoch61NDaQyGPDXLEJlL+B9B/PbdbA=
|
||||
github.com/anchore/packageurl-go v0.1.1-0.20240507183024-848e011fc24f/go.mod h1:Blo6OgJNiYF41ufcgHKkbCKF2MDOMlrqhXv/ij6ocR4=
|
||||
github.com/anchore/stereoscope v0.0.4-0.20241005180410-efa76446cc1c h1:JXezMk8fF5ns4AgRGW49SGfoRgDjJHsDmcpNw272jkU=
|
||||
github.com/anchore/stereoscope v0.0.4-0.20241005180410-efa76446cc1c/go.mod h1:GMupz2FoBhy5RTTmawU06c2pZxgVTceahLWiwJef2uI=
|
||||
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/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=
|
||||
@@ -145,8 +145,8 @@ github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24
|
||||
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
|
||||
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
|
||||
github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
|
||||
github.com/bmatcuk/doublestar/v4 v4.6.1 h1:FH9SifrbvJhnlQpztAx++wlkk70QBf0iBWDwNy7PA4I=
|
||||
github.com/bmatcuk/doublestar/v4 v4.6.1/go.mod h1:xBQ8jztBU6kakFMg+8WGxn0c6z1fTSPVIjEY1Wr7jzc=
|
||||
github.com/bmatcuk/doublestar/v4 v4.7.1 h1:fdDeAqgT47acgwd9bd9HxJRDmc9UAmPpc+2m0CXv75Q=
|
||||
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=
|
||||
@@ -190,18 +190,24 @@ github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWH
|
||||
github.com/cncf/xds/go v0.0.0-20211130200136-a8f946100490/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
|
||||
github.com/containerd/cgroups v1.1.0 h1:v8rEWFl6EoqHB+swVNjVoCJE8o3jX7e8nqBGPLaDFBM=
|
||||
github.com/containerd/cgroups v1.1.0/go.mod h1:6ppBcbh/NOOUU+dMKrykgaBnK9lCIBxHqJDGwsa1mIw=
|
||||
github.com/containerd/containerd v1.7.11 h1:lfGKw3eU35sjV0aG2eYZTiwFEY1pCzxdzicHP3SZILw=
|
||||
github.com/containerd/containerd v1.7.11/go.mod h1:5UluHxHTX2rdvYuZ5OJTC5m/KJNs0Zs9wVoJm9zf5ZE=
|
||||
github.com/containerd/containerd v1.7.23 h1:H2CClyUkmpKAGlhQp95g2WXHfLYc7whAuvZGBNYOOwQ=
|
||||
github.com/containerd/containerd v1.7.23/go.mod h1:7QUzfURqZWCZV7RLNEn1XjUCQLEf0bkaK4GjUaZehxw=
|
||||
github.com/containerd/containerd/api v1.7.19 h1:VWbJL+8Ap4Ju2mx9c9qS1uFSB1OVYr5JJrW2yT5vFoA=
|
||||
github.com/containerd/containerd/api v1.7.19/go.mod h1:fwGavl3LNwAV5ilJ0sbrABL44AQxmNjDRcwheXDb6Ig=
|
||||
github.com/containerd/continuity v0.4.2 h1:v3y/4Yz5jwnvqPKJJ+7Wf93fyWoCB3F5EclWG023MDM=
|
||||
github.com/containerd/continuity v0.4.2/go.mod h1:F6PTNCKepoxEaXLQp3wDAjygEnImnZ/7o4JzpodfroQ=
|
||||
github.com/containerd/errdefs v0.3.0 h1:FSZgGOeK4yuT/+DnF07/Olde/q4KBoMsaamhXxIMDp4=
|
||||
github.com/containerd/errdefs v0.3.0/go.mod h1:+YBYIdtsnF4Iw6nWZhJcqGSg/dwvV7tyJ/kCkyJ2k+M=
|
||||
github.com/containerd/fifo v1.1.0 h1:4I2mbh5stb1u6ycIABlBw9zgtlK8viPI9QkQNRQEEmY=
|
||||
github.com/containerd/fifo v1.1.0/go.mod h1:bmC4NWMbXlt2EZ0Hc7Fx7QzTFxgPID13eH0Qu+MAb2o=
|
||||
github.com/containerd/log v0.1.0 h1:TCJt7ioM2cr/tfR8GPbGf9/VRAX8D2B4PjzCpfX540I=
|
||||
github.com/containerd/log v0.1.0/go.mod h1:VRRf09a7mHDIRezVKTRCrOq78v577GXq3bSa3EhrzVo=
|
||||
github.com/containerd/platforms v0.2.1 h1:zvwtM3rz2YHPQsF2CHYM8+KtB5dvhISiXh5ZpSBQv6A=
|
||||
github.com/containerd/platforms v0.2.1/go.mod h1:XHCb+2/hzowdiut9rkudds9bE5yJ7npe7dG/wG+uFPw=
|
||||
github.com/containerd/stargz-snapshotter/estargz v0.14.3 h1:OqlDCK3ZVUO6C3B/5FSkDwbkEETK84kQgEeFwDC+62k=
|
||||
github.com/containerd/stargz-snapshotter/estargz v0.14.3/go.mod h1:KY//uOCIkSuNAHhJogcZtrNHdKrA99/FCCRjE3HD36o=
|
||||
github.com/containerd/ttrpc v1.2.2 h1:9vqZr0pxwOF5koz6N0N3kJ0zDHokrcPxIR/ZR2YFtOs=
|
||||
github.com/containerd/ttrpc v1.2.2/go.mod h1:sIT6l32Ph/H9cvnJsfXM5drIVzTr5A2flTf1G5tYZak=
|
||||
github.com/containerd/ttrpc v1.2.5 h1:IFckT1EFQoFBMG4c3sMdT8EP3/aKfumK1msY+Ze4oLU=
|
||||
github.com/containerd/ttrpc v1.2.5/go.mod h1:YCXHsb32f+Sq5/72xHubdiJRQY9inL4a4ZQrAbN1q9o=
|
||||
github.com/containerd/typeurl/v2 v2.1.1 h1:3Q4Pt7i8nYwy2KmQWIw2+1hTvwTE/6w9FqcttATPO/4=
|
||||
github.com/containerd/typeurl/v2 v2.1.1/go.mod h1:IDp2JFvbwZ31H8dQbEIY7sDl2L3o3HZj1hsSQlywkQ0=
|
||||
github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
|
||||
@@ -225,8 +231,8 @@ github.com/deitch/magic v0.0.0-20230404182410-1ff89d7342da/go.mod h1:B3tI9iGHi4i
|
||||
github.com/dgrijalva/jwt-go/v4 v4.0.0-preview1/go.mod h1:+hnT3ywWDTAFrW5aE+u2Sa/wT555ZqwoCS+pk3p6ry4=
|
||||
github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk=
|
||||
github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E=
|
||||
github.com/docker/cli v27.1.1+incompatible h1:goaZxOqs4QKxznZjjBWKONQci/MywhtRv2oNn0GkeZE=
|
||||
github.com/docker/cli v27.1.1+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
|
||||
github.com/docker/cli v27.3.1+incompatible h1:qEGdFBF3Xu6SCvCYhc7CzaQTlBmqDuzxPDpigSyeKQQ=
|
||||
github.com/docker/cli v27.3.1+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
|
||||
github.com/docker/distribution v2.8.3+incompatible h1:AtKxIZ36LoNK51+Z6RpzLpddBirtxJnzDrHLEKxTAYk=
|
||||
github.com/docker/distribution v2.8.3+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
|
||||
github.com/docker/docker v27.3.1+incompatible h1:KttF0XoteNTicmUtBO0L2tP+J7FGRFTjaEF4k6WdhfI=
|
||||
@@ -282,8 +288,8 @@ github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7z
|
||||
github.com/fsnotify/fsnotify v1.5.1/go.mod h1:T3375wBYaZdLLcVNkcVbzGHY7f1l/uK5T5Ai1i3InKU=
|
||||
github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA=
|
||||
github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM=
|
||||
github.com/gabriel-vasile/mimetype v1.4.4 h1:QjV6pZ7/XZ7ryI2KuyeEDE8wnh7fHP9YnQy+R0LnH8I=
|
||||
github.com/gabriel-vasile/mimetype v1.4.4/go.mod h1:JwLei5XPtWdGiMFB5Pjle1oEeoSeEuJfJE+TtfvdB/s=
|
||||
github.com/gabriel-vasile/mimetype v1.4.6 h1:3+PzJTKLkvgjeTbts6msPJt4DixhT4YtFNf1gtGe3zc=
|
||||
github.com/gabriel-vasile/mimetype v1.4.6/go.mod h1:JX1qVKqZd40hUPpAfiNTe0Sne7hdfKSbOqqmkq8GCXc=
|
||||
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||
github.com/github/go-spdx/v2 v2.3.2 h1:IfdyNHTqzs4zAJjXdVQfRnxt1XMfycXoHBE2Vsm1bjs=
|
||||
github.com/github/go-spdx/v2 v2.3.2/go.mod h1:2ZxKsOhvBp+OYBDlsGnUMcchLeo2mrpEBn2L1C+U3IQ=
|
||||
@@ -359,8 +365,8 @@ github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw
|
||||
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
|
||||
github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM=
|
||||
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
|
||||
github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=
|
||||
github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
|
||||
github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
|
||||
github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
|
||||
github.com/golang/snappy v0.0.2/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM=
|
||||
@@ -477,8 +483,8 @@ github.com/invopop/jsonschema v0.7.0 h1:2vgQcBz1n256N+FpX3Jq7Y17AjYt46Ig3zIWyy77
|
||||
github.com/invopop/jsonschema v0.7.0/go.mod h1:O9uiLokuu0+MGFlyiaqtWxwqJm41/+8Nj0lD7A36YH0=
|
||||
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A=
|
||||
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo=
|
||||
github.com/jedib0t/go-pretty/v6 v6.6.0 h1:wmZVuAcEkZRT+Aq1xXpE8IGat4vE5WXOMmBpbQqERXw=
|
||||
github.com/jedib0t/go-pretty/v6 v6.6.0/go.mod h1:zbn98qrYlh95FIhwwsbIip0LYpwSG8SUOScs+v9/t0E=
|
||||
github.com/jedib0t/go-pretty/v6 v6.6.1 h1:iJ65Xjb680rHcikRj6DSIbzCex2huitmc7bDtxYVWyc=
|
||||
github.com/jedib0t/go-pretty/v6 v6.6.1/go.mod h1:zbn98qrYlh95FIhwwsbIip0LYpwSG8SUOScs+v9/t0E=
|
||||
github.com/jinzhu/copier v0.4.0 h1:w3ciUoD19shMCRargcpm0cm91ytaBhDvuRpz1ODO/U8=
|
||||
github.com/jinzhu/copier v0.4.0/go.mod h1:DfbEm0FYsaqBcKcFuvmOZb218JkPGtvSHsKg8S8hyyg=
|
||||
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
||||
@@ -581,6 +587,10 @@ github.com/moby/sys/sequential v0.5.0 h1:OPvI35Lzn9K04PBbCLW0g4LcFAJgHsvXsRyewg5
|
||||
github.com/moby/sys/sequential v0.5.0/go.mod h1:tH2cOOs5V9MlPiXcQzRC+eEyab644PWKGRYaaV5ZZlo=
|
||||
github.com/moby/sys/signal v0.7.0 h1:25RW3d5TnQEoKvRbEKUGay6DCQ46IxAVTT9CUMgmsSI=
|
||||
github.com/moby/sys/signal v0.7.0/go.mod h1:GQ6ObYZfqacOwTtlXvcmh9A26dVRul/hbOZn88Kg8Tg=
|
||||
github.com/moby/sys/user v0.3.0 h1:9ni5DlcW5an3SvRSx4MouotOygvzaXbaSrc/wGDFWPo=
|
||||
github.com/moby/sys/user v0.3.0/go.mod h1:bG+tYYYJgaMtRKgEmuueC0hJEAZWwtIbZTB+85uoHjs=
|
||||
github.com/moby/sys/userns v0.1.0 h1:tVLXkFOxVu9A64/yh59slHVv9ahO9UIev4JZusOLG/g=
|
||||
github.com/moby/sys/userns v0.1.0/go.mod h1:IHUYgu/kao6N8YZlp9Cf444ySSvCmDlmzUcYfDHOl28=
|
||||
github.com/moby/term v0.0.0-20221205130635-1aeaba878587 h1:HfkjXDfhgVaN5rmueG8cL8KKeFNecRCXFhaJ2qZ5SKA=
|
||||
github.com/moby/term v0.0.0-20221205130635-1aeaba878587/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y=
|
||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
@@ -609,10 +619,8 @@ github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8
|
||||
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=
|
||||
github.com/opencontainers/image-spec v1.1.0/go.mod h1:W4s4sFTMaBeK1BQLXbG4AdM2szdn85PY75RI83NrTrM=
|
||||
github.com/opencontainers/runc v1.1.14 h1:rgSuzbmgz5DUJjeSnw337TxDbRuqjs6iqQck/2weR6w=
|
||||
github.com/opencontainers/runc v1.1.14/go.mod h1:E4C2z+7BxR7GHXp0hAY53mek+x49X1LjPNeMTfRGvOA=
|
||||
github.com/opencontainers/runtime-spec v1.1.0-rc.1 h1:wHa9jroFfKGQqFHj0I1fMRKLl0pfj+ynAqBxo3v6u9w=
|
||||
github.com/opencontainers/runtime-spec v1.1.0-rc.1/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
|
||||
github.com/opencontainers/runtime-spec v1.1.0 h1:HHUyrt9mwHUjtasSbXSMvs4cyFxh+Bll4AjJ9odEGpg=
|
||||
github.com/opencontainers/runtime-spec v1.1.0/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
|
||||
github.com/opencontainers/selinux v1.11.0 h1:+5Zbo97w3Lbmb3PeqQtpmTkMwsW5nRI3YaLpt7tQ7oU=
|
||||
github.com/opencontainers/selinux v1.11.0/go.mod h1:E5dMC3VPuVvVHDYmi78qvhJp8+M586T4DlDRYpFkyec=
|
||||
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
|
||||
@@ -655,7 +663,6 @@ github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8b
|
||||
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||
github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
|
||||
github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A=
|
||||
github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
|
||||
github.com/prometheus/procfs v0.8.0 h1:ODq8ZFEaYeCaZOJlZZdJA2AbQR98dSHSM1KW/You5mo=
|
||||
github.com/prometheus/procfs v0.8.0/go.mod h1:z7EfXMXOkbkqb9IINtpCn86r/to3BnA0uaxHdg830/4=
|
||||
github.com/quasilyte/go-ruleguard/dsl v0.3.22 h1:wd8zkOhSNr+I+8Qeciml08ivDt1pSXe60+5DqOpCjPE=
|
||||
@@ -691,8 +698,8 @@ github.com/sassoftware/go-rpmutils v0.4.0/go.mod h1:3goNWi7PGAT3/dlql2lv3+MSN5jN
|
||||
github.com/scylladb/go-set v1.0.3-0.20200225121959-cc7b2070d91e h1:7q6NSFZDeGfvvtIRwBrU/aegEYJYmvev0cHAwo17zZQ=
|
||||
github.com/scylladb/go-set v1.0.3-0.20200225121959-cc7b2070d91e/go.mod h1:DkpGd78rljTxKAnTDPFqXSGxvETQnJyuSOQwsHycqfs=
|
||||
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
|
||||
github.com/sebdah/goldie/v2 v2.5.3 h1:9ES/mNN+HNUbNWpVAlrzuZ7jE+Nrczbj8uFRjM7624Y=
|
||||
github.com/sebdah/goldie/v2 v2.5.3/go.mod h1:oZ9fp0+se1eapSRjfYbsV/0Hqhbuu3bJVvKI/NNtssI=
|
||||
github.com/sebdah/goldie/v2 v2.5.5 h1:rx1mwF95RxZ3/83sdS4Yp7t2C5TCokvWP4TBRbAyEWY=
|
||||
github.com/sebdah/goldie/v2 v2.5.5/go.mod h1:oZ9fp0+se1eapSRjfYbsV/0Hqhbuu3bJVvKI/NNtssI=
|
||||
github.com/secDre4mer/pkcs7 v0.0.0-20240322103146-665324a4461d h1:RQqyEogx5J6wPdoxqL132b100j8KjcVHO1c0KLRoIhc=
|
||||
github.com/secDre4mer/pkcs7 v0.0.0-20240322103146-665324a4461d/go.mod h1:PegD7EVqlN88z7TpCqH92hHP+GBpfomGCCnw1PFtNOA=
|
||||
github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
|
||||
@@ -705,7 +712,6 @@ github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeV
|
||||
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
||||
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
|
||||
github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
|
||||
github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
|
||||
github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
|
||||
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
|
||||
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
|
||||
@@ -756,8 +762,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.17.1 h1:p6Sl0LWyShXBj2SBsS1dMOMIMrZHe8pwBnBrYt6uo4M=
|
||||
github.com/sylabs/sif/v2 v2.17.1/go.mod h1:XUGB6AQUXGkms3qPOPdevctT3lBLRLWZNWHVnt5HMKE=
|
||||
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/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=
|
||||
@@ -834,8 +840,8 @@ go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.19.0 h1:IeMey
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.19.0/go.mod h1:oVdCUtjq9MK9BlS7TtucsQwUcXcymNiEDjgDD2jMtZU=
|
||||
go.opentelemetry.io/otel/metric v1.24.0 h1:6EhoGWWK28x1fbpA4tYTOWBkPefTDQnb8WSGXlc88kI=
|
||||
go.opentelemetry.io/otel/metric v1.24.0/go.mod h1:VYhLe1rFfxuTXLgj4CBiyz+9WYBA8pNGJgDcSFRKBco=
|
||||
go.opentelemetry.io/otel/sdk v1.19.0 h1:6USY6zH+L8uMH8L3t1enZPR3WFEmSTADlqldyHtJi3o=
|
||||
go.opentelemetry.io/otel/sdk v1.19.0/go.mod h1:NedEbbS4w3C6zElbLdPJKOpJQOrGUJ+GfzpjUvI0v1A=
|
||||
go.opentelemetry.io/otel/sdk v1.21.0 h1:FTt8qirL1EysG6sTQRZ5TokkU8d0ugCj8htOgThZXQ8=
|
||||
go.opentelemetry.io/otel/sdk v1.21.0/go.mod h1:Nna6Yv7PWTdgJHVRD9hIYywQBRx7pbox6nwBnZIxl/E=
|
||||
go.opentelemetry.io/otel/trace v1.24.0 h1:CsKnnL4dUAr/0llH9FKuc698G04IrpWV0MQA/Y1YELI=
|
||||
go.opentelemetry.io/otel/trace v1.24.0/go.mod h1:HPc3Xr/cOApsBI154IU0OI0HJexz+aw5uPdbs3UCjNU=
|
||||
go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI=
|
||||
@@ -1062,7 +1068,6 @@ 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.1.0/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=
|
||||
@@ -1310,8 +1315,8 @@ google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlba
|
||||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
||||
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI=
|
||||
google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
|
||||
google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg=
|
||||
google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw=
|
||||
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
package licenses
|
||||
|
||||
import (
|
||||
"context"
|
||||
)
|
||||
|
||||
type licenseScannerKey struct{}
|
||||
|
||||
func SetContextLicenseScanner(ctx context.Context, s Scanner) context.Context {
|
||||
return context.WithValue(ctx, licenseScannerKey{}, s)
|
||||
}
|
||||
|
||||
func ContextLicenseScanner(ctx context.Context) Scanner {
|
||||
if s, ok := ctx.Value(licenseScannerKey{}).(Scanner); ok {
|
||||
return s
|
||||
}
|
||||
return NewDefaultScanner()
|
||||
}
|
||||
@@ -1,45 +0,0 @@
|
||||
package licenses
|
||||
|
||||
import (
|
||||
"io"
|
||||
|
||||
"github.com/google/licensecheck"
|
||||
|
||||
"github.com/anchore/syft/syft/file"
|
||||
"github.com/anchore/syft/syft/license"
|
||||
"github.com/anchore/syft/syft/pkg"
|
||||
)
|
||||
|
||||
const (
|
||||
coverageThreshold = 75
|
||||
unknownLicenseType = "UNKNOWN"
|
||||
)
|
||||
|
||||
// Parse scans the contents of a license file to attempt to determine the type of license it is
|
||||
func Parse(reader io.Reader, l file.Location) (licenses []pkg.License, err error) {
|
||||
licenses = make([]pkg.License, 0)
|
||||
contents, err := io.ReadAll(reader)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
scanner, err := licensecheck.NewScanner(licensecheck.BuiltinLicenses())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
cov := scanner.Scan(contents)
|
||||
if cov.Percent < coverageThreshold {
|
||||
// unknown or no licenses here?
|
||||
return licenses, nil
|
||||
}
|
||||
|
||||
for _, m := range cov.Match {
|
||||
lic := pkg.NewLicenseFromLocations(m.ID, l)
|
||||
lic.Type = license.Concluded
|
||||
|
||||
licenses = append(licenses, lic)
|
||||
}
|
||||
|
||||
return licenses, nil
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
package licenses
|
||||
|
||||
import (
|
||||
"context"
|
||||
"io"
|
||||
|
||||
"github.com/google/licensecheck"
|
||||
|
||||
"github.com/anchore/syft/internal/log"
|
||||
)
|
||||
|
||||
const coverageThreshold = 75 // determined by experimentation
|
||||
|
||||
type Scanner interface {
|
||||
IdentifyLicenseIDs(context.Context, io.Reader) ([]string, error)
|
||||
}
|
||||
|
||||
var _ Scanner = (*scanner)(nil)
|
||||
|
||||
type scanner struct {
|
||||
coverageThreshold float64 // between 0 and 100
|
||||
scanner func([]byte) licensecheck.Coverage
|
||||
}
|
||||
|
||||
// NewDefaultScanner returns a scanner that uses a new instance of the default licensecheck package scanner.
|
||||
func NewDefaultScanner() Scanner {
|
||||
s, err := licensecheck.NewScanner(licensecheck.BuiltinLicenses())
|
||||
if err != nil {
|
||||
log.WithFields("error", err).Trace("unable to create default license scanner")
|
||||
s = nil
|
||||
}
|
||||
return &scanner{
|
||||
coverageThreshold: coverageThreshold,
|
||||
scanner: s.Scan,
|
||||
}
|
||||
}
|
||||
|
||||
// TestingOnlyScanner returns a scanner that uses the built-in license scanner from the licensecheck package.
|
||||
// THIS IS ONLY MEANT FOR TEST CODE, NOT PRODUCTION CODE.
|
||||
func TestingOnlyScanner() Scanner {
|
||||
return &scanner{
|
||||
coverageThreshold: coverageThreshold,
|
||||
scanner: licensecheck.Scan,
|
||||
}
|
||||
}
|
||||
|
||||
func (s scanner) IdentifyLicenseIDs(_ context.Context, reader io.Reader) ([]string, error) {
|
||||
if s.scanner == nil {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
content, err := io.ReadAll(reader)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
cov := s.scanner(content)
|
||||
if cov.Percent < s.coverageThreshold {
|
||||
// unknown or no licenses here?
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
var ids []string
|
||||
for _, m := range cov.Match {
|
||||
ids = append(ids, m.ID)
|
||||
}
|
||||
return ids, nil
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package licenses
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/anchore/syft/syft/file"
|
||||
"github.com/anchore/syft/syft/license"
|
||||
"github.com/anchore/syft/syft/pkg"
|
||||
)
|
||||
|
||||
// Search scans the contents of a license file to attempt to determine the type of license it is
|
||||
func Search(ctx context.Context, scanner Scanner, reader file.LocationReadCloser) (licenses []pkg.License, err error) {
|
||||
licenses = make([]pkg.License, 0)
|
||||
|
||||
ids, err := scanner.IdentifyLicenseIDs(ctx, reader)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, id := range ids {
|
||||
lic := pkg.NewLicenseFromLocations(id, reader.Location)
|
||||
lic.Type = license.Concluded
|
||||
|
||||
licenses = append(licenses, lic)
|
||||
}
|
||||
|
||||
return licenses, nil
|
||||
}
|
||||
@@ -9,6 +9,7 @@ import (
|
||||
"github.com/scylladb/go-set/strset"
|
||||
|
||||
"github.com/anchore/syft/internal/bus"
|
||||
"github.com/anchore/syft/internal/licenses"
|
||||
"github.com/anchore/syft/internal/sbomsync"
|
||||
"github.com/anchore/syft/internal/task"
|
||||
"github.com/anchore/syft/syft/artifact"
|
||||
@@ -60,6 +61,9 @@ func CreateSBOM(ctx context.Context, src source.Source, cfg *CreateSBOMConfig) (
|
||||
},
|
||||
}
|
||||
|
||||
// inject a single license scanner for all package cataloging tasks into context
|
||||
ctx = licenses.SetContextLicenseScanner(ctx, licenses.NewDefaultScanner())
|
||||
|
||||
catalogingProgress := monitorCatalogingTask(src.ID(), taskGroups)
|
||||
packageCatalogingProgress := monitorPackageCatalogingTask()
|
||||
|
||||
|
||||
@@ -112,7 +112,7 @@ func Test_PackageURL(t *testing.T) {
|
||||
ID: "alpine",
|
||||
VersionID: "3.4.6",
|
||||
},
|
||||
expected: "pkg:apk/alpine/p@v?arch=a&upstream=origin&distro=alpine-3.4.6",
|
||||
expected: "pkg:apk/alpine/p@v?arch=a&distro=alpine-3.4.6&upstream=origin",
|
||||
},
|
||||
{
|
||||
name: "wolfi distro",
|
||||
|
||||
@@ -108,7 +108,7 @@ func Test_PackageURL(t *testing.T) {
|
||||
ID: "arch",
|
||||
BuildID: "rolling",
|
||||
},
|
||||
expected: "pkg:alpm/arch/p@v?arch=a&upstream=origin&distro=arch-rolling",
|
||||
expected: "pkg:alpm/arch/p@v?arch=a&distro=arch-rolling&upstream=origin",
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
@@ -351,7 +351,7 @@ func DefaultClassifiers() []Classifier {
|
||||
},
|
||||
{
|
||||
Class: "mariadb-binary",
|
||||
FileGlob: "**/mariadb",
|
||||
FileGlob: "**/{mariadb,mysql}",
|
||||
EvidenceMatcher: FileContentsVersionMatcher(
|
||||
// 10.6.15-MariaDB
|
||||
`(?m)(?P<version>[0-9]+(\.[0-9]+)?(\.[0-9]+)?(alpha[0-9]|beta[0-9]|rc[0-9])?)-MariaDB`),
|
||||
|
||||
@@ -27,19 +27,7 @@ func newELFPackage(metadata elfBinaryPackageNotes, locations file.LocationSet) p
|
||||
func packageURL(metadata elfBinaryPackageNotes) string {
|
||||
var qualifiers []packageurl.Qualifier
|
||||
|
||||
os := metadata.OS
|
||||
osVersion := metadata.OSVersion
|
||||
|
||||
var atts cpe.Attributes
|
||||
atts, err := cpe.NewAttributes(metadata.OSCPE)
|
||||
if err != nil {
|
||||
log.WithFields("error", err).Warn("unable to parse cpe attributes for elf binary package")
|
||||
}
|
||||
// only "upgrade" the OS information if there is something more specific to use in it's place
|
||||
if os == "" && osVersion == "" || os == "" && atts.Version != "" || atts.Product != "" && osVersion == "" {
|
||||
os = atts.Product
|
||||
osVersion = atts.Version
|
||||
}
|
||||
os, osVersion := osNameAndVersionFromMetadata(metadata)
|
||||
|
||||
if os != "" {
|
||||
osQualifier := os
|
||||
@@ -70,6 +58,26 @@ func packageURL(metadata elfBinaryPackageNotes) string {
|
||||
).ToString()
|
||||
}
|
||||
|
||||
func osNameAndVersionFromMetadata(metadata elfBinaryPackageNotes) (string, string) {
|
||||
os := metadata.OS
|
||||
osVersion := metadata.OSVersion
|
||||
|
||||
if os != "" && osVersion != "" {
|
||||
return os, osVersion
|
||||
}
|
||||
|
||||
if metadata.OSCPE == "" {
|
||||
return "", ""
|
||||
}
|
||||
|
||||
attrs, err := cpe.NewAttributes(metadata.OSCPE)
|
||||
if err != nil {
|
||||
log.WithFields("error", err).Trace("unable to parse cpe attributes for elf binary package")
|
||||
return "", ""
|
||||
}
|
||||
return attrs.Product, attrs.Version
|
||||
}
|
||||
|
||||
const alpmType = "alpm"
|
||||
|
||||
func purlDistroType(ty string) string {
|
||||
|
||||
@@ -81,7 +81,7 @@ func Test_packageURL(t *testing.T) {
|
||||
Source: "s",
|
||||
Version: "v",
|
||||
},
|
||||
expected: "pkg:deb/debian/p@v?upstream=s&distro=debian-11",
|
||||
expected: "pkg:deb/debian/p@v?distro=debian-11&upstream=s",
|
||||
},
|
||||
{
|
||||
name: "with upstream qualifier with source pkg name and version info",
|
||||
@@ -98,7 +98,7 @@ func Test_packageURL(t *testing.T) {
|
||||
Version: "v",
|
||||
SourceVersion: "2.3",
|
||||
},
|
||||
expected: "pkg:deb/debian/p@v?upstream=s%402.3&distro=debian-11",
|
||||
expected: "pkg:deb/debian/p@v?distro=debian-11&upstream=s%402.3",
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
@@ -154,7 +154,7 @@ func (c *Cataloger) Catalog(ctx context.Context, resolver file.Resolver) ([]pkg.
|
||||
var relationships []artifact.Relationship
|
||||
var errs error
|
||||
|
||||
logger := log.Nested("cataloger", c.upstreamCataloger)
|
||||
lgr := log.Nested("cataloger", c.upstreamCataloger)
|
||||
|
||||
env := Environment{
|
||||
// TODO: consider passing into the cataloger, this would affect the cataloger interface (and all implementations). This can be deferred until later.
|
||||
@@ -166,7 +166,7 @@ func (c *Cataloger) Catalog(ctx context.Context, resolver file.Resolver) ([]pkg.
|
||||
|
||||
log.WithFields("path", location.RealPath).Trace("parsing file contents")
|
||||
|
||||
discoveredPackages, discoveredRelationships, err := invokeParser(ctx, resolver, location, logger, parser, &env)
|
||||
discoveredPackages, discoveredRelationships, err := invokeParser(ctx, resolver, location, lgr, parser, &env)
|
||||
if err != nil {
|
||||
// parsers may return errors and valid packages / relationships
|
||||
errs = unknown.Append(errs, location, err)
|
||||
|
||||
@@ -3,6 +3,7 @@ package golang
|
||||
import (
|
||||
"archive/zip"
|
||||
"bytes"
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/fs"
|
||||
@@ -79,9 +80,9 @@ func remotesForModule(proxies []string, noProxy []string, module string) []strin
|
||||
return proxies
|
||||
}
|
||||
|
||||
func (c *goLicenseResolver) getLicenses(resolver file.Resolver, moduleName, moduleVersion string) ([]pkg.License, error) {
|
||||
func (c *goLicenseResolver) getLicenses(ctx context.Context, scanner licenses.Scanner, resolver file.Resolver, moduleName, moduleVersion string) ([]pkg.License, error) {
|
||||
// search the scan target first, ignoring local and remote sources
|
||||
goLicenses, err := c.findLicensesInSource(resolver,
|
||||
goLicenses, err := c.findLicensesInSource(ctx, scanner, resolver,
|
||||
fmt.Sprintf(`**/go/pkg/mod/%s@%s/*`, processCaps(moduleName), moduleVersion),
|
||||
)
|
||||
if err != nil || len(goLicenses) > 0 {
|
||||
@@ -90,7 +91,7 @@ func (c *goLicenseResolver) getLicenses(resolver file.Resolver, moduleName, modu
|
||||
|
||||
// look in the local host mod directory...
|
||||
if c.opts.SearchLocalModCacheLicenses {
|
||||
goLicenses, err = c.getLicensesFromLocal(moduleName, moduleVersion)
|
||||
goLicenses, err = c.getLicensesFromLocal(ctx, scanner, moduleName, moduleVersion)
|
||||
if err != nil || len(goLicenses) > 0 {
|
||||
return toPkgLicenses(goLicenses), err
|
||||
}
|
||||
@@ -98,13 +99,13 @@ func (c *goLicenseResolver) getLicenses(resolver file.Resolver, moduleName, modu
|
||||
|
||||
// download from remote sources
|
||||
if c.opts.SearchRemoteLicenses {
|
||||
goLicenses, err = c.getLicensesFromRemote(moduleName, moduleVersion)
|
||||
goLicenses, err = c.getLicensesFromRemote(ctx, scanner, moduleName, moduleVersion)
|
||||
}
|
||||
|
||||
return toPkgLicenses(goLicenses), err
|
||||
}
|
||||
|
||||
func (c *goLicenseResolver) getLicensesFromLocal(moduleName, moduleVersion string) ([]goLicense, error) {
|
||||
func (c *goLicenseResolver) getLicensesFromLocal(ctx context.Context, scanner licenses.Scanner, moduleName, moduleVersion string) ([]goLicense, error) {
|
||||
if c.localModCacheDir == nil {
|
||||
return nil, nil
|
||||
}
|
||||
@@ -120,10 +121,10 @@ func (c *goLicenseResolver) getLicensesFromLocal(moduleName, moduleVersion strin
|
||||
// if we're running against a directory on the filesystem, it may not include the
|
||||
// user's homedir / GOPATH, so we defer to using the localModCacheResolver
|
||||
// we use $GOPATH/pkg/mod to avoid leaking information about the user's system
|
||||
return c.findLicensesInFS("file://$GOPATH/pkg/mod/"+subdir+"/", dir)
|
||||
return c.findLicensesInFS(ctx, scanner, "file://$GOPATH/pkg/mod/"+subdir+"/", dir)
|
||||
}
|
||||
|
||||
func (c *goLicenseResolver) getLicensesFromRemote(moduleName, moduleVersion string) ([]goLicense, error) {
|
||||
func (c *goLicenseResolver) getLicensesFromRemote(ctx context.Context, scanner licenses.Scanner, moduleName, moduleVersion string) ([]goLicense, error) {
|
||||
return c.licenseCache.Resolve(fmt.Sprintf("%s/%s", moduleName, moduleVersion), func() ([]goLicense, error) {
|
||||
proxies := remotesForModule(c.opts.Proxies, c.opts.NoProxy, moduleName)
|
||||
|
||||
@@ -132,11 +133,11 @@ func (c *goLicenseResolver) getLicensesFromRemote(moduleName, moduleVersion stri
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return c.findLicensesInFS(urlPrefix, fsys)
|
||||
return c.findLicensesInFS(ctx, scanner, urlPrefix, fsys)
|
||||
})
|
||||
}
|
||||
|
||||
func (c *goLicenseResolver) findLicensesInFS(urlPrefix string, fsys fs.FS) ([]goLicense, error) {
|
||||
func (c *goLicenseResolver) findLicensesInFS(ctx context.Context, scanner licenses.Scanner, urlPrefix string, fsys fs.FS) ([]goLicense, error) {
|
||||
var out []goLicense
|
||||
err := fs.WalkDir(fsys, ".", func(filePath string, d fs.DirEntry, err error) error {
|
||||
if err != nil {
|
||||
@@ -156,7 +157,8 @@ func (c *goLicenseResolver) findLicensesInFS(urlPrefix string, fsys fs.FS) ([]go
|
||||
return nil
|
||||
}
|
||||
defer internal.CloseAndLogError(rdr, filePath)
|
||||
parsed, err := licenses.Parse(rdr, file.NewLocation(filePath))
|
||||
|
||||
parsed, err := licenses.Search(ctx, scanner, file.NewLocationReadCloser(file.NewLocation(filePath), rdr))
|
||||
if err != nil {
|
||||
log.Debugf("error parsing license file %s: %v", filePath, err)
|
||||
return nil
|
||||
@@ -174,7 +176,7 @@ func (c *goLicenseResolver) findLicensesInFS(urlPrefix string, fsys fs.FS) ([]go
|
||||
return out, err
|
||||
}
|
||||
|
||||
func (c *goLicenseResolver) findLicensesInSource(resolver file.Resolver, globMatch string) ([]goLicense, error) {
|
||||
func (c *goLicenseResolver) findLicensesInSource(ctx context.Context, scanner licenses.Scanner, resolver file.Resolver, globMatch string) ([]goLicense, error) {
|
||||
var out []goLicense
|
||||
locations, err := resolver.FilesByGlob(globMatch)
|
||||
if err != nil {
|
||||
@@ -182,7 +184,7 @@ func (c *goLicenseResolver) findLicensesInSource(resolver file.Resolver, globMat
|
||||
}
|
||||
|
||||
for _, l := range locations {
|
||||
parsed, err := c.parseLicenseFromLocation(l, resolver)
|
||||
parsed, err := c.parseLicenseFromLocation(ctx, scanner, l, resolver)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -200,7 +202,7 @@ func (c *goLicenseResolver) findLicensesInSource(resolver file.Resolver, globMat
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *goLicenseResolver) parseLicenseFromLocation(l file.Location, resolver file.Resolver) ([]goLicense, error) {
|
||||
func (c *goLicenseResolver) parseLicenseFromLocation(ctx context.Context, scanner licenses.Scanner, l file.Location, resolver file.Resolver) ([]goLicense, error) {
|
||||
var out []goLicense
|
||||
fileName := path.Base(l.RealPath)
|
||||
if c.lowerLicenseFileNames.Has(strings.ToLower(fileName)) {
|
||||
@@ -209,7 +211,7 @@ func (c *goLicenseResolver) parseLicenseFromLocation(l file.Location, resolver f
|
||||
return nil, err
|
||||
}
|
||||
defer internal.CloseAndLogError(contents, l.RealPath)
|
||||
parsed, err := licenses.Parse(contents, l)
|
||||
parsed, err := licenses.Search(ctx, scanner, file.NewLocationReadCloser(l, contents))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ package golang
|
||||
import (
|
||||
"archive/zip"
|
||||
"bytes"
|
||||
"context"
|
||||
"fmt"
|
||||
"io/fs"
|
||||
"net/http"
|
||||
@@ -15,6 +16,7 @@ import (
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/anchore/syft/internal/licenses"
|
||||
"github.com/anchore/syft/syft/file"
|
||||
"github.com/anchore/syft/syft/internal/fileresolver"
|
||||
"github.com/anchore/syft/syft/license"
|
||||
@@ -26,6 +28,8 @@ func Test_LocalLicenseSearch(t *testing.T) {
|
||||
loc2 := file.NewLocation("github.com/!cap!o!r!g/!cap!project@v4.111.5/LICENSE.txt")
|
||||
loc3 := file.NewLocation("github.com/someorg/strangelicense@v1.2.3/LiCeNsE.tXt")
|
||||
|
||||
licenseScanner := licenses.TestingOnlyScanner()
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
version string
|
||||
@@ -78,12 +82,12 @@ func Test_LocalLicenseSearch(t *testing.T) {
|
||||
LocalModCacheDir: filepath.Join(wd, "test-fixtures", "licenses", "pkg", "mod"),
|
||||
},
|
||||
)
|
||||
licenses, err := l.getLicenses(fileresolver.Empty{}, test.name, test.version)
|
||||
lics, err := l.getLicenses(context.Background(), licenseScanner, fileresolver.Empty{}, test.name, test.version)
|
||||
require.NoError(t, err)
|
||||
|
||||
require.Len(t, licenses, 1)
|
||||
require.Len(t, lics, 1)
|
||||
|
||||
require.Equal(t, test.expected, licenses[0])
|
||||
require.Equal(t, test.expected, lics[0])
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -92,6 +96,8 @@ func Test_RemoteProxyLicenseSearch(t *testing.T) {
|
||||
loc1 := file.NewLocation("github.com/someorg/somename@v0.3.2/LICENSE")
|
||||
loc2 := file.NewLocation("github.com/!cap!o!r!g/!cap!project@v4.111.5/LICENSE.txt")
|
||||
|
||||
licenseScanner := licenses.TestingOnlyScanner()
|
||||
|
||||
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
buf := &bytes.Buffer{}
|
||||
uri := strings.TrimPrefix(strings.TrimSuffix(r.RequestURI, ".zip"), "/")
|
||||
@@ -169,12 +175,12 @@ func Test_RemoteProxyLicenseSearch(t *testing.T) {
|
||||
},
|
||||
)
|
||||
|
||||
licenses, err := l.getLicenses(fileresolver.Empty{}, test.name, test.version)
|
||||
lics, err := l.getLicenses(context.Background(), licenseScanner, fileresolver.Empty{}, test.name, test.version)
|
||||
require.NoError(t, err)
|
||||
|
||||
require.Len(t, licenses, 1)
|
||||
require.Len(t, lics, 1)
|
||||
|
||||
require.Equal(t, test.expected, licenses[0])
|
||||
require.Equal(t, test.expected, lics[0])
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -248,7 +254,7 @@ func Test_findVersionPath(t *testing.T) {
|
||||
|
||||
func Test_walkDirErrors(t *testing.T) {
|
||||
resolver := newGoLicenseResolver("", CatalogerConfig{})
|
||||
_, err := resolver.findLicensesInFS("somewhere", badFS{})
|
||||
_, err := resolver.findLicensesInFS(context.Background(), licenses.TestingOnlyScanner(), "somewhere", badFS{})
|
||||
require.Error(t, err)
|
||||
}
|
||||
|
||||
@@ -266,6 +272,8 @@ func Test_noLocalGoModDir(t *testing.T) {
|
||||
validTmp := t.TempDir()
|
||||
require.NoError(t, os.MkdirAll(filepath.Join(validTmp, "mod@ver"), 0700|os.ModeDir))
|
||||
|
||||
licenseScanner := licenses.TestingOnlyScanner()
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
dir string
|
||||
@@ -299,7 +307,7 @@ func Test_noLocalGoModDir(t *testing.T) {
|
||||
SearchLocalModCacheLicenses: true,
|
||||
LocalModCacheDir: test.dir,
|
||||
})
|
||||
_, err := resolver.getLicensesFromLocal("mod", "ver")
|
||||
_, err := resolver.getLicensesFromLocal(context.Background(), licenseScanner, "mod", "ver")
|
||||
test.wantErr(t, err)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -5,21 +5,15 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/anchore/packageurl-go"
|
||||
"github.com/anchore/syft/internal/log"
|
||||
"github.com/anchore/syft/syft/file"
|
||||
"github.com/anchore/syft/syft/pkg"
|
||||
)
|
||||
|
||||
func (c *goBinaryCataloger) newGoBinaryPackage(resolver file.Resolver, dep *debug.Module, mainModule, goVersion, architecture string, buildSettings pkg.KeyValues, cryptoSettings, experiments []string, 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, locations ...file.Location) pkg.Package {
|
||||
if dep.Replace != nil {
|
||||
dep = dep.Replace
|
||||
}
|
||||
|
||||
licenses, err := c.licenseResolver.getLicenses(resolver, dep.Path, dep.Version)
|
||||
if err != nil {
|
||||
log.Tracef("error getting licenses for golang package: %s %v", dep.Path, err)
|
||||
}
|
||||
|
||||
p := pkg.Package{
|
||||
Name: dep.Path,
|
||||
Version: dep.Version,
|
||||
|
||||
@@ -18,6 +18,7 @@ import (
|
||||
"golang.org/x/mod/module"
|
||||
|
||||
"github.com/anchore/syft/internal"
|
||||
"github.com/anchore/syft/internal/licenses"
|
||||
"github.com/anchore/syft/internal/log"
|
||||
"github.com/anchore/syft/syft/artifact"
|
||||
"github.com/anchore/syft/syft/file"
|
||||
@@ -59,9 +60,11 @@ func newGoBinaryCataloger(opts CatalogerConfig) *goBinaryCataloger {
|
||||
}
|
||||
|
||||
// parseGoBinary catalogs packages found in the "buildinfo" section of a binary built by the go compiler.
|
||||
func (c *goBinaryCataloger) parseGoBinary(_ context.Context, resolver file.Resolver, _ *generic.Environment, reader file.LocationReadCloser) ([]pkg.Package, []artifact.Relationship, error) {
|
||||
func (c *goBinaryCataloger) parseGoBinary(ctx context.Context, resolver file.Resolver, _ *generic.Environment, reader file.LocationReadCloser) ([]pkg.Package, []artifact.Relationship, error) {
|
||||
var pkgs []pkg.Package
|
||||
|
||||
licenseScanner := licenses.ContextLicenseScanner(ctx)
|
||||
|
||||
unionReader, err := unionreader.GetUnionReader(reader.ReadCloser)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
@@ -73,7 +76,7 @@ func (c *goBinaryCataloger) parseGoBinary(_ context.Context, resolver file.Resol
|
||||
var rels []artifact.Relationship
|
||||
for _, mod := range mods {
|
||||
var depPkgs []pkg.Package
|
||||
mainPkg, depPkgs := c.buildGoPkgInfo(resolver, reader.Location, mod, mod.arch, unionReader)
|
||||
mainPkg, depPkgs := c.buildGoPkgInfo(ctx, licenseScanner, resolver, reader.Location, mod, mod.arch, unionReader)
|
||||
if mainPkg != nil {
|
||||
rels = createModuleRelationships(*mainPkg, depPkgs)
|
||||
pkgs = append(pkgs, *mainPkg)
|
||||
@@ -101,7 +104,7 @@ func createModuleRelationships(main pkg.Package, deps []pkg.Package) []artifact.
|
||||
var emptyModule debug.Module
|
||||
var moduleFromPartialPackageBuild = debug.Module{Path: "command-line-arguments"}
|
||||
|
||||
func (c *goBinaryCataloger) buildGoPkgInfo(resolver file.Resolver, location file.Location, mod *extendedBuildInfo, arch string, reader io.ReadSeekCloser) (*pkg.Package, []pkg.Package) {
|
||||
func (c *goBinaryCataloger) buildGoPkgInfo(ctx context.Context, licenseScanner licenses.Scanner, resolver file.Resolver, location file.Location, mod *extendedBuildInfo, arch string, reader io.ReadSeekCloser) (*pkg.Package, []pkg.Package) {
|
||||
if mod == nil {
|
||||
return nil, nil
|
||||
}
|
||||
@@ -116,9 +119,13 @@ func (c *goBinaryCataloger) buildGoPkgInfo(resolver file.Resolver, location file
|
||||
continue
|
||||
}
|
||||
|
||||
lics, err := c.licenseResolver.getLicenses(ctx, licenseScanner, resolver, dep.Path, dep.Version)
|
||||
if err != nil {
|
||||
log.Tracef("error getting licenses for golang package: %s %v", dep.Path, err)
|
||||
}
|
||||
|
||||
gover, experiments := getExperimentsFromVersion(mod.GoVersion)
|
||||
p := c.newGoBinaryPackage(
|
||||
resolver,
|
||||
dep,
|
||||
mod.Main.Path,
|
||||
gover,
|
||||
@@ -126,6 +133,7 @@ func (c *goBinaryCataloger) buildGoPkgInfo(resolver file.Resolver, location file
|
||||
nil,
|
||||
mod.cryptoSettings,
|
||||
experiments,
|
||||
lics,
|
||||
location.WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation),
|
||||
)
|
||||
if pkg.IsValid(&p) {
|
||||
@@ -137,7 +145,7 @@ func (c *goBinaryCataloger) buildGoPkgInfo(resolver file.Resolver, location file
|
||||
return nil, pkgs
|
||||
}
|
||||
|
||||
main := c.makeGoMainPackage(resolver, mod, arch, location, reader)
|
||||
main := c.makeGoMainPackage(ctx, licenseScanner, resolver, mod, arch, location, reader)
|
||||
|
||||
return &main, pkgs
|
||||
}
|
||||
@@ -152,11 +160,16 @@ func missingMainModule(mod *extendedBuildInfo) bool {
|
||||
return mod.Main == moduleFromPartialPackageBuild
|
||||
}
|
||||
|
||||
func (c *goBinaryCataloger) makeGoMainPackage(resolver file.Resolver, mod *extendedBuildInfo, arch string, location file.Location, reader io.ReadSeekCloser) pkg.Package {
|
||||
func (c *goBinaryCataloger) makeGoMainPackage(ctx context.Context, licenseScanner licenses.Scanner, resolver file.Resolver, mod *extendedBuildInfo, arch string, location file.Location, reader io.ReadSeekCloser) pkg.Package {
|
||||
gbs := getBuildSettings(mod.Settings)
|
||||
|
||||
lics, err := c.licenseResolver.getLicenses(ctx, licenseScanner, resolver, mod.Main.Path, mod.Main.Version)
|
||||
if err != nil {
|
||||
log.Tracef("error getting licenses for golang package: %s %v", mod.Main.Path, err)
|
||||
}
|
||||
|
||||
gover, experiments := getExperimentsFromVersion(mod.GoVersion)
|
||||
main := c.newGoBinaryPackage(
|
||||
resolver,
|
||||
&mod.Main,
|
||||
mod.Main.Path,
|
||||
gover,
|
||||
@@ -164,6 +177,7 @@ func (c *goBinaryCataloger) makeGoMainPackage(resolver file.Resolver, mod *exten
|
||||
gbs,
|
||||
mod.cryptoSettings,
|
||||
experiments,
|
||||
lics,
|
||||
location.WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation),
|
||||
)
|
||||
|
||||
@@ -196,7 +210,7 @@ func (c *goBinaryCataloger) makeGoMainPackage(resolver file.Resolver, mod *exten
|
||||
// this is checking for (.L)? because at least one binary seems to have \xA0L preceding the version string, but for some reason
|
||||
// this is unable to be matched by the regex here as \x00\xA0L;
|
||||
// the only thing that seems to work is to just look for version strings following both \x00 and \x00.L for now
|
||||
var semverPattern = regexp.MustCompile(`\x00(.L)?(?P<version>v?(\d+\.\d+\.\d+[-\w]*[+\w]*))\x00`)
|
||||
var semverPattern = regexp.MustCompile(`(\x00|\x{FFFD})(.L)?(?P<version>v?(\d+\.\d+\.\d+[-\w]*[+\w]*))\x00`)
|
||||
|
||||
func (c *goBinaryCataloger) findMainModuleVersion(metadata *pkg.GolangBinaryBuildinfoEntry, gbs pkg.KeyValues, reader io.ReadSeekCloser) string {
|
||||
vcsVersion, hasVersion := gbs.Get("vcs.revision")
|
||||
|
||||
@@ -3,6 +3,7 @@ package golang
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"context"
|
||||
"errors"
|
||||
"io"
|
||||
"os"
|
||||
@@ -17,6 +18,7 @@ import (
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/anchore/syft/internal/licenses"
|
||||
"github.com/anchore/syft/syft/file"
|
||||
"github.com/anchore/syft/syft/internal/fileresolver"
|
||||
"github.com/anchore/syft/syft/internal/unionreader"
|
||||
@@ -167,6 +169,8 @@ func TestBuildGoPkgInfo(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
licenseScanner := licenses.TestingOnlyScanner()
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
mod *extendedBuildInfo
|
||||
@@ -1053,7 +1057,7 @@ func TestBuildGoPkgInfo(t *testing.T) {
|
||||
c := newGoBinaryCataloger(DefaultCatalogerConfig())
|
||||
reader, err := unionreader.GetUnionReader(io.NopCloser(strings.NewReader(test.binaryContent)))
|
||||
require.NoError(t, err)
|
||||
mainPkg, pkgs := c.buildGoPkgInfo(fileresolver.Empty{}, location, test.mod, test.mod.arch, reader)
|
||||
mainPkg, pkgs := c.buildGoPkgInfo(context.Background(), licenseScanner, fileresolver.Empty{}, location, test.mod, test.mod.arch, reader)
|
||||
if mainPkg != nil {
|
||||
pkgs = append(pkgs, *mainPkg)
|
||||
}
|
||||
@@ -1305,6 +1309,14 @@ func Test_extractVersionFromContents(t *testing.T) {
|
||||
contents: strings.NewReader("\x0e\x74\x5a\x3b\x00\x00\xa0\x4cv1.9.5\x00\x00"),
|
||||
want: "v1.9.5",
|
||||
},
|
||||
{
|
||||
// 06168a34: f98f b0be 332e 312e 3200 0000 636f 6d74 ....3.1.2...comt from /usr/local/bin/traefik
|
||||
// in traefik:v3.1.2@sha256:3f92eba47bd4bfda91d47b72d16fef2d7ae15db61a92b2057cf0cb389f8938f6
|
||||
// TODO: eventually use something for managing snippets, similar to what's used with binary classifier tests
|
||||
name: "parse traefik version",
|
||||
contents: strings.NewReader("\xf9\x8f\xb0\xbe\x33\x2e\x31\x2e\x32\x00\x00\x00\x63\x6f\x6d\x74"),
|
||||
want: "3.1.2",
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
|
||||
@@ -11,6 +11,7 @@ import (
|
||||
"golang.org/x/mod/modfile"
|
||||
|
||||
"github.com/anchore/syft/internal"
|
||||
"github.com/anchore/syft/internal/licenses"
|
||||
"github.com/anchore/syft/internal/log"
|
||||
"github.com/anchore/syft/syft/artifact"
|
||||
"github.com/anchore/syft/syft/file"
|
||||
@@ -31,9 +32,11 @@ func newGoModCataloger(opts CatalogerConfig) *goModCataloger {
|
||||
// parseGoModFile takes a go.mod and lists all packages discovered.
|
||||
//
|
||||
//nolint:funlen
|
||||
func (c *goModCataloger) parseGoModFile(_ context.Context, resolver file.Resolver, _ *generic.Environment, reader file.LocationReadCloser) ([]pkg.Package, []artifact.Relationship, error) {
|
||||
func (c *goModCataloger) parseGoModFile(ctx context.Context, resolver file.Resolver, _ *generic.Environment, reader file.LocationReadCloser) ([]pkg.Package, []artifact.Relationship, error) {
|
||||
packages := make(map[string]pkg.Package)
|
||||
|
||||
licenseScanner := licenses.ContextLicenseScanner(ctx)
|
||||
|
||||
contents, err := io.ReadAll(reader)
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("failed to read go module: %w", err)
|
||||
@@ -50,7 +53,7 @@ func (c *goModCataloger) parseGoModFile(_ context.Context, resolver file.Resolve
|
||||
}
|
||||
|
||||
for _, m := range f.Require {
|
||||
licenses, err := c.licenseResolver.getLicenses(resolver, m.Mod.Path, m.Mod.Version)
|
||||
lics, err := c.licenseResolver.getLicenses(ctx, licenseScanner, resolver, m.Mod.Path, m.Mod.Version)
|
||||
if err != nil {
|
||||
log.Tracef("error getting licenses for package: %s %v", m.Mod.Path, err)
|
||||
}
|
||||
@@ -58,7 +61,7 @@ func (c *goModCataloger) parseGoModFile(_ context.Context, resolver file.Resolve
|
||||
packages[m.Mod.Path] = pkg.Package{
|
||||
Name: m.Mod.Path,
|
||||
Version: m.Mod.Version,
|
||||
Licenses: pkg.NewLicenseSet(licenses...),
|
||||
Licenses: pkg.NewLicenseSet(lics...),
|
||||
Locations: file.NewLocationSet(reader.Location.WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation)),
|
||||
PURL: packageURL(m.Mod.Path, m.Mod.Version),
|
||||
Language: pkg.Go,
|
||||
@@ -71,7 +74,7 @@ func (c *goModCataloger) parseGoModFile(_ context.Context, resolver file.Resolve
|
||||
|
||||
// remove any old packages and replace with new ones...
|
||||
for _, m := range f.Replace {
|
||||
licenses, err := c.licenseResolver.getLicenses(resolver, m.New.Path, m.New.Version)
|
||||
lics, err := c.licenseResolver.getLicenses(ctx, licenseScanner, resolver, m.New.Path, m.New.Version)
|
||||
if err != nil {
|
||||
log.Tracef("error getting licenses for package: %s %v", m.New.Path, err)
|
||||
}
|
||||
@@ -83,7 +86,7 @@ func (c *goModCataloger) parseGoModFile(_ context.Context, resolver file.Resolve
|
||||
packages[m.New.Path] = pkg.Package{
|
||||
Name: m.New.Path,
|
||||
Version: m.New.Version,
|
||||
Licenses: pkg.NewLicenseSet(licenses...),
|
||||
Licenses: pkg.NewLicenseSet(lics...),
|
||||
Locations: file.NewLocationSet(reader.Location.WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation)),
|
||||
PURL: packageURL(m.New.Path, m.New.Version),
|
||||
Language: pkg.Go,
|
||||
|
||||
@@ -100,6 +100,9 @@
|
||||
"github.com/sap/cloud-security-client-go": [
|
||||
"cpe:2.3:a:sap:cloud-security-client-go:*:*:*:*:*:go:*:*"
|
||||
],
|
||||
"github.com/satori/go.uuid": [
|
||||
"cpe:2.3:a:satori:uuid:*:*:*:*:*:go:*:*"
|
||||
],
|
||||
"github.com/sigstore/gitsign": [
|
||||
"cpe:2.3:a:sigstore:gitsign:*:*:*:*:*:go:*:*"
|
||||
],
|
||||
@@ -2934,7 +2937,7 @@
|
||||
"cpe:2.3:a:electron-packager_project:electron-packager:*:*:*:*:*:node.js:*:*"
|
||||
],
|
||||
"elliptic": [
|
||||
"cpe:2.3:a:elliptic_project:elliptic:*:*:*:*:*:node.js:*:*"
|
||||
"cpe:2.3:a:indutny:elliptic:*:*:*:*:*:node.js:*:*"
|
||||
],
|
||||
"embedza": [
|
||||
"cpe:2.3:a:embedza_project:embedza:*:*:*:*:*:node.js:*:*"
|
||||
@@ -5691,6 +5694,9 @@
|
||||
"jw.util": [
|
||||
"cpe:2.3:a:python:jw.util:*:*:*:*:*:python:*:*"
|
||||
],
|
||||
"jwcrypto": [
|
||||
"cpe:2.3:a:latchset:jwcrypto:*:*:*:*:*:*:*:*"
|
||||
],
|
||||
"keep": [
|
||||
"cpe:2.3:a:keep_project:keep:*:*:*:*:*:*:*:*"
|
||||
],
|
||||
@@ -5839,7 +5845,7 @@
|
||||
"cpe:2.3:a:python-scciclient_project:python-scciclient:*:*:*:*:*:python:*:*"
|
||||
],
|
||||
"pytorch-lightning": [
|
||||
"cpe:2.3:a:pytorchlightning:pytorch_lightning:*:*:*:*:*:python:*:*"
|
||||
"cpe:2.3:a:lightningai:pytorch_lightning:*:*:*:*:*:python:*:*"
|
||||
],
|
||||
"rencode": [
|
||||
"cpe:2.3:a:rencode_project:rencode:*:*:*:*:*:python:*:*"
|
||||
@@ -6346,6 +6352,9 @@
|
||||
"show_in_browser": [
|
||||
"cpe:2.3:a:jonathan_leung:show_in_browser:*:*:*:*:*:ruby:*:*"
|
||||
],
|
||||
"sidekiq-unique-jobs": [
|
||||
"cpe:2.3:a:mhenrixon:sidekiq-unique-jobs:*:*:*:*:*:ruby:*:*"
|
||||
],
|
||||
"simple_captcha2": [
|
||||
"cpe:2.3:a:simple_captcha2_project:simple_captcha2:*:*:*:*:*:ruby:*:*"
|
||||
],
|
||||
@@ -7010,6 +7019,9 @@
|
||||
"404like": [
|
||||
"cpe:2.3:a:404like_project:404like:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"404page": [
|
||||
"cpe:2.3:a:nerdpress:smart_custom_404_error_page:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"4ecps-webforms": [
|
||||
"cpe:2.3:a:jumpdemand:4ecps_web_forms:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -7343,6 +7355,9 @@
|
||||
"advanced-ajax-page-loader": [
|
||||
"cpe:2.3:a:advanced_ajax_page_loader_project:advanced_ajax_page_loader:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"advanced-backgrounds": [
|
||||
"cpe:2.3:a:wpbackgrounds:advanced_wordpress_backgrounds:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"advanced-booking-calendar": [
|
||||
"cpe:2.3:a:elbtide:advanced_booking_calendar:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -7490,6 +7505,9 @@
|
||||
"albo-pretorio-on-line": [
|
||||
"cpe:2.3:a:albo_pretorio_on_line_project:albo_pretorio_on_line:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"album-and-image-gallery-plus-lightbox": [
|
||||
"cpe:2.3:a:essentialplugin:album_and_image_gallery_plus_lightbox:*:*:*:*:free:wordpress:*:*"
|
||||
],
|
||||
"alfred-click-collect": [
|
||||
"cpe:2.3:a:alfred24_click_\\\u0026_collect_project:alfred24_click_\\\u0026_collect:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -7622,6 +7640,9 @@
|
||||
"analytics-cat": [
|
||||
"cpe:2.3:a:fatcatapps:analytics_cat:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"analytics-insights": [
|
||||
"cpe:2.3:a:deconf:analytics_insights:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"analytics-tracker": [
|
||||
"cpe:2.3:a:analytics_tracker_project:analytics_tracker:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -7730,6 +7751,9 @@
|
||||
"ari-adminer": [
|
||||
"cpe:2.3:a:ari-soft:ari_adminer:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"ari-cf7-connector": [
|
||||
"cpe:2.3:a:ari-soft:contact_form_7_connector:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"ari-fancy-lightbox": [
|
||||
"cpe:2.3:a:ari-soft:ari_fancy_lightbox:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -7918,7 +7942,8 @@
|
||||
"cpe:2.3:a:aysproextensions:popup_like:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"ays-popup-box": [
|
||||
"cpe:2.3:a:ays-pro:popup_box:*:*:*:*:*:wordpress:*:*"
|
||||
"cpe:2.3:a:ays-pro:popup_box:*:*:*:*:*:wordpress:*:*",
|
||||
"cpe:2.3:a:ays-pro:popup_box:*:*:*:*:pro:wordpress:*:*"
|
||||
],
|
||||
"azurecurve-toggle-showhide": [
|
||||
"cpe:2.3:a:azurecurve:toggle_show\\/hide:*:*:*:*:*:wordpress:*:*"
|
||||
@@ -7926,6 +7951,9 @@
|
||||
"b2bking-wholesale-for-woocommerce": [
|
||||
"cpe:2.3:a:webwizards:b2bking:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"ba-book-everything": [
|
||||
"cpe:2.3:a:ba-booking:ba_book_everything:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"ba-plus-before-after-image-slider-free": [
|
||||
"cpe:2.3:a:aluka:ba_plus:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -8163,6 +8191,9 @@
|
||||
"blogger-importer": [
|
||||
"cpe:2.3:a:wordpress:blogger_importer:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"blogintroduction-wordpress-plugin": [
|
||||
"cpe:2.3:a:kimhuebel:blog_introduction:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"blogmentor": [
|
||||
"cpe:2.3:a:auburnforest:blogmentor:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -8198,7 +8229,8 @@
|
||||
],
|
||||
"booking": [
|
||||
"cpe:2.3:a:booking_calendar_project:booking_calendar:*:*:*:*:*:wordpress:*:*",
|
||||
"cpe:2.3:a:wpbookingcalendar:booking_calendar:*:*:*:*:*:wordpress:*:*"
|
||||
"cpe:2.3:a:wpbookingcalendar:booking_calendar:*:*:*:*:*:wordpress:*:*",
|
||||
"cpe:2.3:a:wpbookingcalendar:wp_booking_calendar:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"booking-and-rental-manager-for-woocommerce": [
|
||||
"cpe:2.3:a:magepeople:booking_\\\u0026_rental_manager:*:*:*:*:*:wordpress:*:*"
|
||||
@@ -9329,6 +9361,9 @@
|
||||
"cssable-countdown": [
|
||||
"cpe:2.3:a:dmonnier:cssable_countdown:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"cssjockey-add-ons": [
|
||||
"cpe:2.3:a:cssjockey:wp_builder:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"csv-import-export": [
|
||||
"cpe:2.3:a:csv-import-export_project:csv-import-export:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -9351,6 +9386,9 @@
|
||||
"cube-slider": [
|
||||
"cpe:2.3:a:webpsilon:cube_slider:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"curatorio": [
|
||||
"cpe:2.3:a:curator:curator.io:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"currency-converter-calculator": [
|
||||
"cpe:2.3:a:currencyratetoday:currency_converter_calculator:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -9618,6 +9656,9 @@
|
||||
"demo-awesome": [
|
||||
"cpe:2.3:a:theme4press:demo_awesome:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"demo-importer-plus": [
|
||||
"cpe:2.3:a:kraftplugins:demo_importer_plus:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"democracy-poll": [
|
||||
"cpe:2.3:a:wp-kama:democracy_poll:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -10096,11 +10137,14 @@
|
||||
"cpe:2.3:a:elementor:elementor_page_builder:*:*:*:*:*:wordpress:*:*",
|
||||
"cpe:2.3:a:elementor:elementor_page_builder:*:*:*:*:pro:wordpress:*:*",
|
||||
"cpe:2.3:a:elementor:page_builder:*:*:*:*:*:wordpress:*:*",
|
||||
"cpe:2.3:a:elementor:website_builder:*:*:*:*:*:wordpress:*:*"
|
||||
"cpe:2.3:a:elementor:website_builder:*:*:*:*:free:wordpress:*:*"
|
||||
],
|
||||
"elementor-pro": [
|
||||
"cpe:2.3:a:elementor:elementor_pro:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"elementskit": [
|
||||
"cpe:2.3:a:wpmet:elementskit:*:*:*:*:pro:wordpress:*:*"
|
||||
],
|
||||
"elementskit-lite": [
|
||||
"cpe:2.3:a:wpmet:elements_kit_elementor_addons:*:*:*:*:*:wordpress:*:*",
|
||||
"cpe:2.3:a:wpmet:elementskit_elementor_addons:*:*:*:*:*:wordpress:*:*"
|
||||
@@ -10239,7 +10283,8 @@
|
||||
"cpe:2.3:a:wpdeveloper:essential_addons_for_elementor:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"essential-blocks": [
|
||||
"cpe:2.3:a:wpdeveloper:essential_blocks:*:*:*:*:*:wordpress:*:*"
|
||||
"cpe:2.3:a:wpdeveloper:essential_blocks:*:*:*:*:*:wordpress:*:*",
|
||||
"cpe:2.3:a:wpdeveloper:essential_blocks:*:*:*:*:free:wordpress:*:*"
|
||||
],
|
||||
"essential-content-types": [
|
||||
"cpe:2.3:a:catchplugins:essential_content_types:*:*:*:*:*:wordpress:*:*"
|
||||
@@ -10262,6 +10307,9 @@
|
||||
"eu-cookie-law": [
|
||||
"cpe:2.3:a:eu_cookie_law_project:eu_cookie_law:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"eu-vat-for-woocommerce": [
|
||||
"cpe:2.3:a:wpfactory:eu\\/uk_vat_manager_for_woocommerce:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"eupago-gateway-for-woocommerce": [
|
||||
"cpe:2.3:a:eupago:eupago_gateway_woocommerce:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -10308,7 +10356,8 @@
|
||||
"cpe:2.3:a:eventify_project:eventify:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"eventon-lite": [
|
||||
"cpe:2.3:a:myeventon:eventon-lite:*:*:*:*:*:wordpress:*:*"
|
||||
"cpe:2.3:a:myeventon:eventon-lite:*:*:*:*:*:wordpress:*:*",
|
||||
"cpe:2.3:a:myeventon:eventon:*:*:*:*:lite:wordpress:*:*"
|
||||
],
|
||||
"eventprime-event-calendar-management": [
|
||||
"cpe:2.3:a:metagauss:eventprime:*:*:*:*:*:wordpress:*:*"
|
||||
@@ -10323,8 +10372,7 @@
|
||||
"cpe:2.3:a:e-dynamics:events_made_easy:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"events-manager": [
|
||||
"cpe:2.3:a:pixelite:events_manager:*:*:*:*:*:wordpress:*:*",
|
||||
"cpe:2.3:a:wp-events-plugin:events_manager:*:*:*:*:*:wordpress:*:*"
|
||||
"cpe:2.3:a:pixelite:events_manager:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"ever-compare": [
|
||||
"cpe:2.3:a:hasthemes:ever_compare:*:*:*:*:*:wordpress:*:*"
|
||||
@@ -10598,6 +10646,9 @@
|
||||
"final-tiles-grid-gallery-lite": [
|
||||
"cpe:2.3:a:machothemes:image_photo_gallery_final_tiles_grid:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"finale-woocommerce-sales-countdown-timer-discount": [
|
||||
"cpe:2.3:a:xlplugins:finale:*:*:*:*:lite:wordpress:*:*"
|
||||
],
|
||||
"find-and-replace-all": [
|
||||
"cpe:2.3:a:find_and_replace_all_project:find_and_replace_all:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -10607,6 +10658,9 @@
|
||||
"find-my-blocks": [
|
||||
"cpe:2.3:a:find_my_blocks_project:find_my_blocks:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"fish-and-ships": [
|
||||
"cpe:2.3:a:wp-centrics:fish_and_ships:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"fitness-calculators": [
|
||||
"cpe:2.3:a:codeinitiator:fitness_calculators:*:*:*:*:*:wordpress:*:*",
|
||||
"cpe:2.3:a:codeinitiator:fitness_calculators_plugin:*:*:*:*:*:wordpress:*:*"
|
||||
@@ -10657,6 +10711,9 @@
|
||||
"cpe:2.3:a:floating_social_bar_project:floating_social_bar:*:*:*:*:*:wordpress:*:*",
|
||||
"cpe:2.3:a:wpbeginner:floating_social_bar:*:*:*:*:wordpress:*:*:*"
|
||||
],
|
||||
"floating-social-buttons": [
|
||||
"cpe:2.3:a:click2check:floating_social_buttons:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"floating-social-media-icon": [
|
||||
"cpe:2.3:a:acurax:floating_social_media_icon:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -10721,10 +10778,11 @@
|
||||
"cpe:2.3:a:fivestarplugins:five_star_restaurant_menu:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"foogallery": [
|
||||
"cpe:2.3:a:fooplugins:foogallery:*:*:*:*:*:wordpress:*:*"
|
||||
"cpe:2.3:a:fooplugins:foogallery:*:*:*:*:-:wordpress:*:*",
|
||||
"cpe:2.3:a:fooplugins:foogallery:*:*:*:*:premium:wordpress:*:*"
|
||||
],
|
||||
"foogallery-premium": [
|
||||
"cpe:2.3:a:fooplugins:foogallery:*:*:*:*:*:wordpress:*:*"
|
||||
"cpe:2.3:a:fooplugins:foogallery:*:*:*:*:-:wordpress:*:*"
|
||||
],
|
||||
"football-leagues-by-anwppro": [
|
||||
"cpe:2.3:a:anwp:football_leagues:*:*:*:*:free:wordpress:*:*",
|
||||
@@ -11273,6 +11331,9 @@
|
||||
"gsheetconnector-wpforms": [
|
||||
"cpe:2.3:a:gsheetconnector:wpforms_google_sheet_connector:*:*:*:*:free:wordpress:*:*"
|
||||
],
|
||||
"gtm-server-side": [
|
||||
"cpe:2.3:a:stape:gtm_server_side:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"gtmetrix-for-wordpress": [
|
||||
"cpe:2.3:a:gtmetrix:gtmetrix:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -11370,6 +11431,9 @@
|
||||
"heateor-social-login": [
|
||||
"cpe:2.3:a:heateor:social_login:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"hello-world": [
|
||||
"cpe:2.3:a:kau-boys:hello_world:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"helloprint": [
|
||||
"cpe:2.3:a:helloprint:helloprint:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -11713,6 +11777,9 @@
|
||||
"inline-google-spreadsheet-viewer": [
|
||||
"cpe:2.3:a:inline_google_spreadsheet_viewer_project:inline_google_spreadsheet_viewer:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"inline-svg-elementor": [
|
||||
"cpe:2.3:a:namogo:elementor_inline_svg:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"inline-tweet-sharer": [
|
||||
"cpe:2.3:a:winwar:inline_tweet_sharer:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -11856,6 +11923,9 @@
|
||||
"iubenda-cookie-law-solution": [
|
||||
"cpe:2.3:a:iubenda:iubenda-cookie-law-solution:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"iworks-pwa": [
|
||||
"cpe:2.3:a:iworks:pwa:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"iwp-client": [
|
||||
"cpe:2.3:a:revmakx:infinitewp_client:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -12186,6 +12256,9 @@
|
||||
"leira-cron-jobs": [
|
||||
"cpe:2.3:a:leira:cron_jobs:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"leira-roles": [
|
||||
"cpe:2.3:a:leira:roles_\\\u0026_capabilities:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"letterpress": [
|
||||
"cpe:2.3:a:themeqx:letterpress:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -12248,7 +12321,7 @@
|
||||
"cpe:2.3:a:link_juice_keeper_project:link_juice_keeper:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"link-library": [
|
||||
"cpe:2.3:a:link_library_project:link_library:*:*:*:*:*:wordpress:*:*"
|
||||
"cpe:2.3:a:ylefebvre:link_library:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"link-log": [
|
||||
"cpe:2.3:a:perafox:link_log:*:*:*:*:*:wordpress:*:*",
|
||||
@@ -12381,6 +12454,9 @@
|
||||
"cpe:2.3:a:custom_popup_builder_project:custom_popup_builder:*:*:*:*:*:wordpress:*:*",
|
||||
"cpe:2.3:a:popup_\\|_custom_popup_builder_project:popup_\\|_custom_popup_builder:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"magazine-blocks": [
|
||||
"cpe:2.3:a:themegrill:magazine_blocks:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"mage-eventpress": [
|
||||
"cpe:2.3:a:mage-people:event_manager_and_tickets_selling_for_woocommerce:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -12424,10 +12500,14 @@
|
||||
"mailchimp-subscribe-sm": [
|
||||
"cpe:2.3:a:pluginops:mailchimp_subscribe_form:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"mailchimp-top-bar": [
|
||||
"cpe:2.3:a:ibericode:mailchimp_top_bar:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"mailcwp": [
|
||||
"cpe:2.3:a:mailcwp_project:mailcwp:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"mailin": [
|
||||
"cpe:2.3:a:brevo:newsletter\\,_smtp\\,_email_marketing_and_subscribe:*:*:*:*:*:wordpress:*:*",
|
||||
"cpe:2.3:a:sendinblue:newsletter\\,_smtp\\,_email_marketing_and_subscribe:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"mailmunch": [
|
||||
@@ -12524,6 +12604,9 @@
|
||||
"martins-link-network": [
|
||||
"cpe:2.3:a:martinstools:free_\\\u0026_easy_link_building:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"mas-static-content": [
|
||||
"cpe:2.3:a:madrasthemes:mas_static_content:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"mashsharer": [
|
||||
"cpe:2.3:a:social_media_share_buttons_project:social_media_share_buttons:*:*:*:*:*:wordpress:*:*",
|
||||
"cpe:2.3:a:wpchill:mashshare:*:*:*:*:*:wordpress:*:*"
|
||||
@@ -12555,6 +12638,9 @@
|
||||
"maxbuttons": [
|
||||
"cpe:2.3:a:maxfoundry:maxbuttons:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"maximum-products-per-user-for-woocommerce": [
|
||||
"cpe:2.3:a:wpfactory:maximum_products_per_user_for_woocommerce:*:*:*:*:free:wordpress:*:*"
|
||||
],
|
||||
"maz-loader": [
|
||||
"cpe:2.3:a:feataholic:maz_loader:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -12639,6 +12725,9 @@
|
||||
"member-hero": [
|
||||
"cpe:2.3:a:memberhero:member_hero:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"memberful-wp": [
|
||||
"cpe:2.3:a:memberful:memberful:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"memberlite-shortcodes": [
|
||||
"cpe:2.3:a:strangerstudios:memberlite_shortcodes:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -13057,6 +13146,9 @@
|
||||
"new-image-gallery": [
|
||||
"cpe:2.3:a:awplife:image_gallery:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"new-order-notification-for-woocommerce": [
|
||||
"cpe:2.3:a:mrebabi:new_order_notification_for_woocommerce:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"new-user-approve": [
|
||||
"cpe:2.3:a:wpexperts:new_user_approve:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -13173,6 +13265,9 @@
|
||||
"notification": [
|
||||
"cpe:2.3:a:bracketspace:notification:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"notification-for-telegram": [
|
||||
"cpe:2.3:a:andreamarinucci:notification_for_telegram:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"notificationx": [
|
||||
"cpe:2.3:a:wpdeveloper:notificationx:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -13525,6 +13620,9 @@
|
||||
"pdf-print": [
|
||||
"cpe:2.3:a:bestwebsoft:pdf_\\\u0026_print:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"pdf-thumbnail-generator": [
|
||||
"cpe:2.3:a:kubiq:pdf_thumbnail_generator:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"pdf-viewer-block": [
|
||||
"cpe:2.3:a:gutenberg_pdf_viewer_block_project:gutenberg_pdf_viewer_block:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -13666,7 +13764,7 @@
|
||||
"cpe:2.3:a:pixabay_images_project:pixabay_images:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"pixelyoursite": [
|
||||
"cpe:2.3:a:pixelyoursite:pixelyoursite:*:*:*:*:*:wordpress:*:*"
|
||||
"cpe:2.3:a:pixelyoursite:pixelyoursite:*:*:*:*:-:wordpress:*:*"
|
||||
],
|
||||
"pixtypes": [
|
||||
"cpe:2.3:a:pixelgrade:pixtypes:*:*:*:*:*:wordpress:*:*"
|
||||
@@ -13732,7 +13830,8 @@
|
||||
"cpe:2.3:a:ays-pro:poll_maker:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"poll-wp": [
|
||||
"cpe:2.3:a:total-soft:responsive_poll:*:*:*:*:*:wordpress:*:*"
|
||||
"cpe:2.3:a:total-soft:responsive_poll:*:*:*:*:*:wordpress:*:*",
|
||||
"cpe:2.3:a:total-soft:ts_poll:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"polldaddy": [
|
||||
"cpe:2.3:a:automattic:crowdsignal_dashboard:*:*:*:*:*:wordpress:*:*"
|
||||
@@ -13758,6 +13857,9 @@
|
||||
"poptin": [
|
||||
"cpe:2.3:a:poptin:popups:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"popularis-extra": [
|
||||
"cpe:2.3:a:themes4wp:popularis_extra:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"popup-anything-on-click": [
|
||||
"cpe:2.3:a:essentialplugin:popup_anything:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -14016,6 +14118,9 @@
|
||||
"process-steps-template-designer": [
|
||||
"cpe:2.3:a:coolplugins:process_steps_template_designer:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"product-blocks": [
|
||||
"cpe:2.3:a:wpxpo:wowstore:*:*:*:*:free:wordpress:*:*"
|
||||
],
|
||||
"product-carousel-slider-for-woocommerce": [
|
||||
"cpe:2.3:a:aazztech:woocommerce_product_carousel_slider:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -14126,6 +14231,9 @@
|
||||
"q2w3-post-order": [
|
||||
"cpe:2.3:a:q2w3:q2w3_post_order:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"qa-heatmap-analytics": [
|
||||
"cpe:2.3:a:quarka:qa_analytics:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"qi-addons-for-elementor": [
|
||||
"cpe:2.3:a:qodeinteractive:qi_addons_for_elementor:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -14529,6 +14637,9 @@
|
||||
"revision-manager-tmc": [
|
||||
"cpe:2.3:a:jetplugs:revision_manager_tmc:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"revolut-gateway-for-woocommerce": [
|
||||
"cpe:2.3:a:revolut:revolut_gateway_for_woocommerce:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"rezgo": [
|
||||
"cpe:2.3:a:rezgo:rezgo_online_booking:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -14586,6 +14697,9 @@
|
||||
"rsfirewall": [
|
||||
"cpe:2.3:a:rsjoomla:rsfirewall\\!:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"rss-feed-post-generator-echo": [
|
||||
"cpe:2.3:a:coderevolution:echo_rss_feed_post_generator:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"rss-feed-widget": [
|
||||
"cpe:2.3:a:rss_feed_widget_project:rss_feed_widget:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -15041,6 +15155,9 @@
|
||||
"simple-e-commerce-shopping-cart": [
|
||||
"cpe:2.3:a:simple-e-commerce-shopping-cart_project:simple-e-commerce-shopping-cart:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"simple-embed-code": [
|
||||
"cpe:2.3:a:davidartiss:code_embed:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"simple-event-planner": [
|
||||
"cpe:2.3:a:press_tigers:simple_event_planner:*:*:*:*:*:wordpress:*:*",
|
||||
"cpe:2.3:a:presstigers:simple_event_planner:*:*:*:*:*:wordpress:*:*"
|
||||
@@ -15383,6 +15500,9 @@
|
||||
"smart-logo-showcase-lite": [
|
||||
"cpe:2.3:a:accesspressthemes:smart_logo_showcase_lite:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"smart-manager-for-wp-e-commerce": [
|
||||
"cpe:2.3:a:storeapps:smart_manager:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"smart-marketing-for-wp": [
|
||||
"cpe:2.3:a:e-goi:smart_marketing_sms_and_newsletters_forms:*:*:*:*:*:*:*:*"
|
||||
],
|
||||
@@ -15401,6 +15521,9 @@
|
||||
"smartcrawl-seo": [
|
||||
"cpe:2.3:a:wpmudev:smartcrawl:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"smartsearchwp": [
|
||||
"cpe:2.3:a:smartsearchwp:smartsearchwp:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"smartsoftbutton-widget-de-botones-de-chat": [
|
||||
"cpe:2.3:a:smartsoft:button_widget_smartsoft:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -15455,6 +15578,9 @@
|
||||
"social-buttons-pack": [
|
||||
"cpe:2.3:a:bestwebsoft:social_buttons_pack:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"social-icons-widget-by-wpzoom": [
|
||||
"cpe:2.3:a:wpzoom:social_icons_widget:*:*:*:*:free:wordpress:*:*"
|
||||
],
|
||||
"social-locker": [
|
||||
"cpe:2.3:a:byonepress:social_locker:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -15961,7 +16087,7 @@
|
||||
"cpe:2.3:a:thank_me_later_project:thank_me_later:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"the-events-calendar": [
|
||||
"cpe:2.3:a:tri:the_events_calendar:*:*:*:*:*:wordpress:*:*"
|
||||
"cpe:2.3:a:stellarwp:the_events_calendar:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"the-hackers-diet": [
|
||||
"cpe:2.3:a:wp-plugins:the_hackers_diet:*:*:*:*:*:wordpress:*:*"
|
||||
@@ -16056,6 +16182,9 @@
|
||||
"thumbs-rating": [
|
||||
"cpe:2.3:a:quicoto:thumbs_rating:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"ti-woocommerce-wishlist": [
|
||||
"cpe:2.3:a:templateinvaders:ti_woocommerce_wishlist:*:*:*:*:free:wordpress:*:*"
|
||||
],
|
||||
"tickera-event-ticketing-system": [
|
||||
"cpe:2.3:a:tickera:tickera:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -16234,6 +16363,9 @@
|
||||
"two-factor-authentication": [
|
||||
"cpe:2.3:a:simbahosting:two-factor-authentication:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"two-factor-login-telegram": [
|
||||
"cpe:2.3:a:dueclic:wp_2fa_with_telegram:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"typebot": [
|
||||
"cpe:2.3:a:typebot:typebot:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -16369,6 +16501,9 @@
|
||||
"uncanny-automator": [
|
||||
"cpe:2.3:a:uncannyowl:uncanny_automator:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"uncanny-learndash-groups": [
|
||||
"cpe:2.3:a:uncannyowl:uncanny_groups_for_learndash:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"uncanny-learndash-toolkit": [
|
||||
"cpe:2.3:a:uncannyowl:uncanny_toolkit_for_learndash:*:*:*:*:*:*:*:*",
|
||||
"cpe:2.3:a:uncannyowl:uncanny_toolkit_for_learndash:*:*:*:*:*:wordpress:*:*"
|
||||
@@ -16398,7 +16533,7 @@
|
||||
"cpe:2.3:a:unitecms:unlimited_addons_for_wpbakery_page_builder:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"unlimited-elements-for-elementor": [
|
||||
"cpe:2.3:a:unlimited-elements:unlimited_elements_for_elementor_\\(free_widgets\\,_addons\\,_templates\\):*:*:*:*:*:wordpress:*:*"
|
||||
"cpe:2.3:a:unlimited-elements:unlimited_elements_for_elementor:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"unlimited-popups": [
|
||||
"cpe:2.3:a:unlimited_popups_project:unlimited_popups:*:*:*:*:*:wordpress:*:*"
|
||||
@@ -16889,6 +17024,9 @@
|
||||
"whizz": [
|
||||
"cpe:2.3:a:browserweb:whizz:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"wholesale-pricing-woocommerce": [
|
||||
"cpe:2.3:a:wpfactory:quantity_dynamic_pricing_\\\u0026_bulk_discounts_for_woocommerce:*:*:*:*:free:wordpress:*:*"
|
||||
],
|
||||
"whydowork-adsense": [
|
||||
"cpe:2.3:a:whydowork_adsense_project:whydowork_adsense:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -17083,6 +17221,9 @@
|
||||
"woo-thank-you-page-customizer": [
|
||||
"cpe:2.3:a:villatheme:thank_you_page_customizer_for_woocommerce:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"woo-thank-you-page-nextmove-lite": [
|
||||
"cpe:2.3:a:xlplugins:nextmove:*:*:*:*:lite:wordpress:*:*"
|
||||
],
|
||||
"woo-tranzila-gateway": [
|
||||
"cpe:2.3:a:antonbond:woocommerce_tranzila_payment_gateway:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -17107,6 +17248,7 @@
|
||||
],
|
||||
"woocommerce": [
|
||||
"cpe:2.3:a:woocommerce:woocommerce:*:*:*:*:*:wordpress:*:*",
|
||||
"cpe:2.3:a:woocommerce:woocommerce:*:*:*:*:free:wordpress:*:*",
|
||||
"cpe:2.3:a:woothemes:woocommerce:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"woocommerce-abandoned-cart": [
|
||||
@@ -17157,6 +17299,9 @@
|
||||
"woocommerce-multi-currency": [
|
||||
"cpe:2.3:a:villatheme:woocommerce_multi_currency:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"woocommerce-multilingual": [
|
||||
"cpe:2.3:a:onthegosystems:woocommerce_multilingual_\\\u0026_multicurrency:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"woocommerce-payments": [
|
||||
"cpe:2.3:a:automattic:woopayments:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -17319,7 +17464,7 @@
|
||||
"cpe:2.3:a:wp_admin_logo_changer_project:wp_admin_logo_changer:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"wp-advanced-search": [
|
||||
"cpe:2.3:a:wp-advanced-search_project:wp-advanced-search:*:*:*:*:*:wordpress:*:*"
|
||||
"cpe:2.3:a:internet-formation:wp-advanced-search:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"wp-airbnb-review-slider": [
|
||||
"cpe:2.3:a:ljapps:wp_airbnb_review_slider:*:*:*:*:*:wordpress:*:*"
|
||||
@@ -17704,10 +17849,11 @@
|
||||
"cpe:2.3:a:surniaulula:jsm_file_get_contents\\(\\)_shortcode:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"wp-file-manager": [
|
||||
"cpe:2.3:a:filemanagerpro:file_manager:*:*:*:*:free:wordpress:*:*",
|
||||
"cpe:2.3:a:webdesi9:file_manager:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"wp-file-manager-pro": [
|
||||
"cpe:2.3:a:filemanagerpro:file_manager_pro:*:*:*:*:*:wordpress:*:*"
|
||||
"cpe:2.3:a:filemanagerpro:file_manager:*:*:*:*:pro:wordpress:*:*"
|
||||
],
|
||||
"wp-file-upload": [
|
||||
"cpe:2.3:a:iptanus:wordpress_file_upload:*:*:*:*:*:wordpress:*:*"
|
||||
@@ -18327,6 +18473,9 @@
|
||||
"wp-songbook": [
|
||||
"cpe:2.3:a:wp_songbook_project:wp_songbook:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"wp-sort-order": [
|
||||
"cpe:2.3:a:androidbubble:wp_sort_order:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"wp-source-control": [
|
||||
"cpe:2.3:a:wp_content_source_control_project:wp_content_source_control:*:*:-:-:-:wordpress:*:*"
|
||||
],
|
||||
@@ -18417,6 +18566,9 @@
|
||||
"wp-terms-popup": [
|
||||
"cpe:2.3:a:linksoftwarellc:wp_terms_popup:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"wp-testimonial-widget": [
|
||||
"cpe:2.3:a:starkdigital:wp_testimonial_widget:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"wp-testing": [
|
||||
"cpe:2.3:a:psychological_tests_\\\u0026_quizzes_project:psychological_tests_\\\u0026_quizzes:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -18519,6 +18671,9 @@
|
||||
"wp-voting-contest": [
|
||||
"cpe:2.3:a:ohiowebtech:wp_voting_contest:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"wp-wc-affiliate-program": [
|
||||
"cpe:2.3:a:redefiningtheweb:affiliate_pro:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"wp-whatsapp": [
|
||||
"cpe:2.3:a:ninjateam:wp_chat_app:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -18874,6 +19029,9 @@
|
||||
"ymc-smart-filter": [
|
||||
"cpe:2.3:a:ymc-22:filter_\\\u0026_grids:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"yml-for-yandex-market": [
|
||||
"cpe:2.3:a:icopydoc:yml_for_yandex_market:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"yookassa": [
|
||||
"cpe:2.3:a:yookassa:yukassa_for_woocommerce:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -18922,7 +19080,7 @@
|
||||
"cpe:2.3:a:stefanoai:widget_responsive_for_youtube:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"youzify": [
|
||||
"cpe:2.3:a:kainelabs:youzify:*:*:*:*:*:wordpress:*:*"
|
||||
"cpe:2.3:a:kainelabs:youzify:*:*:*:*:free:wordpress:*:*"
|
||||
],
|
||||
"yt-player": [
|
||||
"cpe:2.3:a:video_player_for_youtube_project:video_player_for_youtube:*:*:*:*:*:wordpress:*:*"
|
||||
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"context"
|
||||
"crypto"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"path"
|
||||
"slices"
|
||||
@@ -49,14 +50,15 @@ var javaArchiveHashes = []crypto.Hash{
|
||||
}
|
||||
|
||||
type archiveParser struct {
|
||||
fileManifest intFile.ZipFileManifest
|
||||
location file.Location
|
||||
archivePath string
|
||||
contentPath string
|
||||
fileInfo archiveFilename
|
||||
detectNested bool
|
||||
cfg ArchiveCatalogerConfig
|
||||
maven *mavenResolver
|
||||
fileManifest intFile.ZipFileManifest
|
||||
location file.Location
|
||||
archivePath string
|
||||
contentPath string
|
||||
fileInfo archiveFilename
|
||||
detectNested bool
|
||||
cfg ArchiveCatalogerConfig
|
||||
maven *mavenResolver
|
||||
licenseScanner licenses.Scanner
|
||||
}
|
||||
|
||||
type genericArchiveParserAdapter struct {
|
||||
@@ -69,7 +71,7 @@ func newGenericArchiveParserAdapter(cfg ArchiveCatalogerConfig) genericArchivePa
|
||||
|
||||
// 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) {
|
||||
parser, cleanupFn, err := newJavaArchiveParser(reader, true, gap.cfg)
|
||||
parser, cleanupFn, err := newJavaArchiveParser(ctx, reader, true, gap.cfg)
|
||||
// note: even on error, we should always run cleanup functions
|
||||
defer cleanupFn()
|
||||
if err != nil {
|
||||
@@ -88,7 +90,9 @@ func uniquePkgKey(groupID string, p *pkg.Package) string {
|
||||
|
||||
// newJavaArchiveParser returns a new java archive parser object for the given archive. Can be configured to discover
|
||||
// and parse nested archives or ignore them.
|
||||
func newJavaArchiveParser(reader file.LocationReadCloser, detectNested bool, cfg ArchiveCatalogerConfig) (*archiveParser, func(), error) {
|
||||
func newJavaArchiveParser(ctx context.Context, reader file.LocationReadCloser, detectNested bool, cfg ArchiveCatalogerConfig) (*archiveParser, func(), error) {
|
||||
licenseScanner := licenses.ContextLicenseScanner(ctx)
|
||||
|
||||
// fetch the last element of the virtual path
|
||||
virtualElements := strings.Split(reader.Path(), ":")
|
||||
currentFilepath := virtualElements[len(virtualElements)-1]
|
||||
@@ -104,14 +108,15 @@ func newJavaArchiveParser(reader file.LocationReadCloser, detectNested bool, cfg
|
||||
}
|
||||
|
||||
return &archiveParser{
|
||||
fileManifest: fileManifest,
|
||||
location: reader.Location,
|
||||
archivePath: archivePath,
|
||||
contentPath: contentPath,
|
||||
fileInfo: newJavaArchiveFilename(currentFilepath),
|
||||
detectNested: detectNested,
|
||||
cfg: cfg,
|
||||
maven: newMavenResolver(nil, cfg),
|
||||
fileManifest: fileManifest,
|
||||
location: reader.Location,
|
||||
archivePath: archivePath,
|
||||
contentPath: contentPath,
|
||||
fileInfo: newJavaArchiveFilename(currentFilepath),
|
||||
detectNested: detectNested,
|
||||
cfg: cfg,
|
||||
maven: newMavenResolver(nil, cfg),
|
||||
licenseScanner: licenseScanner,
|
||||
}, cleanupFn, nil
|
||||
}
|
||||
|
||||
@@ -220,7 +225,7 @@ func (j *archiveParser) discoverMainPackage(ctx context.Context) (*pkg.Package,
|
||||
return nil, err
|
||||
}
|
||||
|
||||
name, version, licenses, err := j.discoverNameVersionLicense(ctx, manifest)
|
||||
name, version, lics, err := j.discoverNameVersionLicense(ctx, manifest)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -230,7 +235,7 @@ func (j *archiveParser) discoverMainPackage(ctx context.Context) (*pkg.Package,
|
||||
Name: name,
|
||||
Version: version,
|
||||
Language: pkg.Java,
|
||||
Licenses: pkg.NewLicenseSet(licenses...),
|
||||
Licenses: pkg.NewLicenseSet(lics...),
|
||||
Locations: file.NewLocationSet(
|
||||
j.location.WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation),
|
||||
),
|
||||
@@ -246,7 +251,7 @@ func (j *archiveParser) discoverMainPackage(ctx context.Context) (*pkg.Package,
|
||||
func (j *archiveParser) discoverNameVersionLicense(ctx context.Context, manifest *pkg.JavaManifest) (string, string, []pkg.License, error) {
|
||||
// we use j.location because we want to associate the license declaration with where we discovered the contents in the manifest
|
||||
// TODO: when we support locations of paths within archives we should start passing the specific manifest location object instead of the top jar
|
||||
licenses := pkg.NewLicensesFromLocation(j.location, selectLicenses(manifest)...)
|
||||
lics := pkg.NewLicensesFromLocation(j.location, selectLicenses(manifest)...)
|
||||
/*
|
||||
We should name and version from, in this order:
|
||||
1. pom.properties if we find exactly 1
|
||||
@@ -262,25 +267,25 @@ func (j *archiveParser) discoverNameVersionLicense(ctx context.Context, manifest
|
||||
version = selectVersion(manifest, j.fileInfo)
|
||||
}
|
||||
|
||||
if len(licenses) == 0 {
|
||||
fileLicenses, err := j.getLicenseFromFileInArchive()
|
||||
if len(lics) == 0 {
|
||||
fileLicenses, err := j.getLicenseFromFileInArchive(ctx)
|
||||
if err != nil {
|
||||
return "", "", nil, err
|
||||
}
|
||||
if fileLicenses != nil {
|
||||
licenses = append(licenses, fileLicenses...)
|
||||
lics = append(lics, fileLicenses...)
|
||||
}
|
||||
}
|
||||
|
||||
// If we didn't find any licenses in the archive so far, we'll try again in Maven Central using groupIDFromJavaMetadata
|
||||
if len(licenses) == 0 {
|
||||
if len(lics) == 0 {
|
||||
// Today we don't have a way to distinguish between licenses from the manifest and licenses from the pom.xml
|
||||
// until the file.Location object can support sub-paths (i.e. paths within archives, recursively; issue https://github.com/anchore/syft/issues/2211).
|
||||
// Until then it's less confusing to use the licenses from the pom.xml only if the manifest did not list any.
|
||||
licenses = j.findLicenseFromJavaMetadata(ctx, groupID, artifactID, version, parsedPom, manifest)
|
||||
lics = j.findLicenseFromJavaMetadata(ctx, groupID, artifactID, version, parsedPom, manifest)
|
||||
}
|
||||
|
||||
return artifactID, version, licenses, nil
|
||||
return artifactID, version, lics, nil
|
||||
}
|
||||
|
||||
// findLicenseFromJavaMetadata attempts to find license information from all available maven metadata properties and pom info
|
||||
@@ -446,7 +451,7 @@ func getDigestsFromArchive(archivePath string) ([]file.Digest, error) {
|
||||
return digests, nil
|
||||
}
|
||||
|
||||
func (j *archiveParser) getLicenseFromFileInArchive() ([]pkg.License, error) {
|
||||
func (j *archiveParser) getLicenseFromFileInArchive(ctx context.Context) ([]pkg.License, error) {
|
||||
var fileLicenses []pkg.License
|
||||
for _, filename := range licenses.FileNames() {
|
||||
licenseMatches := j.fileManifest.GlobMatch(true, "/META-INF/"+filename)
|
||||
@@ -463,7 +468,8 @@ func (j *archiveParser) getLicenseFromFileInArchive() ([]pkg.License, error) {
|
||||
|
||||
for _, licenseMatch := range licenseMatches {
|
||||
licenseContents := contents[licenseMatch]
|
||||
parsed, err := licenses.Parse(strings.NewReader(licenseContents), j.location)
|
||||
r := strings.NewReader(licenseContents)
|
||||
parsed, err := licenses.Search(ctx, j.licenseScanner, file.NewLocationReadCloser(j.location, io.NopCloser(r)))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ import (
|
||||
"github.com/stretchr/testify/require"
|
||||
"github.com/vifraa/gopom"
|
||||
|
||||
"github.com/anchore/syft/internal/licenses"
|
||||
"github.com/anchore/syft/syft/artifact"
|
||||
"github.com/anchore/syft/syft/file"
|
||||
"github.com/anchore/syft/syft/license"
|
||||
@@ -30,6 +31,8 @@ import (
|
||||
func TestSearchMavenForLicenses(t *testing.T) {
|
||||
url := mockMavenRepo(t)
|
||||
|
||||
ctx := licenses.SetContextLicenseScanner(context.Background(), licenses.TestingOnlyScanner())
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
fixture string
|
||||
@@ -71,6 +74,7 @@ func TestSearchMavenForLicenses(t *testing.T) {
|
||||
|
||||
// setup parser
|
||||
ap, cleanupFn, err := newJavaArchiveParser(
|
||||
ctx,
|
||||
file.LocationReadCloser{
|
||||
Location: file.NewLocation(fixture.Name()),
|
||||
ReadCloser: fixture,
|
||||
@@ -86,6 +90,8 @@ func TestSearchMavenForLicenses(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestParseJar(t *testing.T) {
|
||||
ctx := licenses.SetContextLicenseScanner(context.Background(), licenses.TestingOnlyScanner())
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
fixture string
|
||||
@@ -347,10 +353,12 @@ func TestParseJar(t *testing.T) {
|
||||
UseNetwork: false,
|
||||
UseMavenLocalRepository: false,
|
||||
}
|
||||
parser, cleanupFn, err := newJavaArchiveParser(file.LocationReadCloser{
|
||||
Location: file.NewLocation(fixture.Name()),
|
||||
ReadCloser: fixture,
|
||||
}, false, cfg)
|
||||
parser, cleanupFn, err := newJavaArchiveParser(
|
||||
ctx,
|
||||
file.LocationReadCloser{
|
||||
Location: file.NewLocation(fixture.Name()),
|
||||
ReadCloser: fixture,
|
||||
}, false, cfg)
|
||||
defer cleanupFn()
|
||||
require.NoError(t, err)
|
||||
|
||||
@@ -1352,6 +1360,8 @@ func Test_parseJavaArchive_regressions(t *testing.T) {
|
||||
}
|
||||
|
||||
func Test_deterministicMatchingPomProperties(t *testing.T) {
|
||||
ctx := licenses.SetContextLicenseScanner(context.Background(), licenses.TestingOnlyScanner())
|
||||
|
||||
tests := []struct {
|
||||
fixture string
|
||||
expected mavenID
|
||||
@@ -1371,10 +1381,12 @@ func Test_deterministicMatchingPomProperties(t *testing.T) {
|
||||
fixture, err := os.Open(fixturePath)
|
||||
require.NoError(t, err)
|
||||
|
||||
parser, cleanupFn, err := newJavaArchiveParser(file.LocationReadCloser{
|
||||
Location: file.NewLocation(fixture.Name()),
|
||||
ReadCloser: fixture,
|
||||
}, false, ArchiveCatalogerConfig{UseNetwork: false})
|
||||
parser, cleanupFn, err := newJavaArchiveParser(
|
||||
ctx,
|
||||
file.LocationReadCloser{
|
||||
Location: file.NewLocation(fixture.Name()),
|
||||
ReadCloser: fixture,
|
||||
}, false, ArchiveCatalogerConfig{UseNetwork: false})
|
||||
defer cleanupFn()
|
||||
require.NoError(t, err)
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"testing"
|
||||
|
||||
"github.com/anchore/syft/syft/artifact"
|
||||
"github.com/anchore/syft/syft/cpe"
|
||||
"github.com/anchore/syft/syft/file"
|
||||
"github.com/anchore/syft/syft/pkg"
|
||||
"github.com/anchore/syft/syft/pkg/cataloger/internal/pkgtest"
|
||||
@@ -22,6 +23,7 @@ func Test_KernelCataloger(t *testing.T) {
|
||||
),
|
||||
Type: pkg.LinuxKernelPkg,
|
||||
PURL: "pkg:generic/linux-kernel@6.0.7-301.fc37.x86_64",
|
||||
CPEs: []cpe.CPE{cpe.Must("cpe:2.3:o:linux:linux_kernel:6.0.7-301.fc37.x86_64:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource)},
|
||||
Metadata: pkg.LinuxKernel{
|
||||
Name: "",
|
||||
Architecture: "x86",
|
||||
|
||||
@@ -4,12 +4,26 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/anchore/packageurl-go"
|
||||
"github.com/anchore/syft/syft/cpe"
|
||||
"github.com/anchore/syft/syft/file"
|
||||
"github.com/anchore/syft/syft/pkg"
|
||||
)
|
||||
|
||||
const linuxKernelPackageName = "linux-kernel"
|
||||
|
||||
func createLinuxKernelCPEs(version string) []cpe.CPE {
|
||||
c := cpe.NewWithAny()
|
||||
c.Part = "o"
|
||||
c.Product = "linux_kernel"
|
||||
c.Vendor = "linux"
|
||||
c.Version = version
|
||||
if cpe.ValidateString(c.String()) != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
return []cpe.CPE{{Attributes: c, Source: cpe.NVDDictionaryLookupSource}}
|
||||
}
|
||||
|
||||
func newLinuxKernelPackage(metadata pkg.LinuxKernel, archiveLocation file.Location) pkg.Package {
|
||||
p := pkg.Package{
|
||||
Name: linuxKernelPackageName,
|
||||
@@ -18,6 +32,7 @@ func newLinuxKernelPackage(metadata pkg.LinuxKernel, archiveLocation file.Locati
|
||||
PURL: packageURL(linuxKernelPackageName, metadata.Version),
|
||||
Type: pkg.LinuxKernelPkg,
|
||||
Metadata: metadata,
|
||||
CPEs: createLinuxKernelCPEs(metadata.Version),
|
||||
}
|
||||
|
||||
p.SetID()
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package python
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"regexp"
|
||||
"strings"
|
||||
@@ -72,7 +73,26 @@ func newPackageForRequirementsWithMetadata(name, version string, metadata pkg.Py
|
||||
return p
|
||||
}
|
||||
|
||||
func newPackageForPackage(resolver file.Resolver, m parsedData, sources ...file.Location) pkg.Package {
|
||||
func newPackageForPackage(m parsedData, licenses pkg.LicenseSet, sources ...file.Location) pkg.Package {
|
||||
name := normalize(m.Name)
|
||||
|
||||
p := pkg.Package{
|
||||
Name: name,
|
||||
Version: m.Version,
|
||||
PURL: packageURL(name, m.Version, &m.PythonPackage),
|
||||
Locations: file.NewLocationSet(sources...),
|
||||
Licenses: licenses,
|
||||
Language: pkg.Python,
|
||||
Type: pkg.PythonPkg,
|
||||
Metadata: m.PythonPackage,
|
||||
}
|
||||
|
||||
p.SetID()
|
||||
|
||||
return p
|
||||
}
|
||||
|
||||
func findLicenses(ctx context.Context, scanner licenses.Scanner, resolver file.Resolver, m parsedData) pkg.LicenseSet {
|
||||
var licenseSet pkg.LicenseSet
|
||||
|
||||
switch {
|
||||
@@ -89,7 +109,7 @@ func newPackageForPackage(resolver file.Resolver, m parsedData, sources ...file.
|
||||
if len(found) > 0 {
|
||||
metadataContents, err := resolver.FileContentsByLocation(found[0])
|
||||
if err == nil {
|
||||
parsed, err := licenses.Parse(metadataContents, m.LicenseLocation)
|
||||
parsed, err := licenses.Search(ctx, scanner, file.NewLocationReadCloser(m.LicenseLocation, metadataContents))
|
||||
if err != nil {
|
||||
log.WithFields("error", err).Tracef("unable to parse a license from the file in %s", m.LicenseLocation.Path())
|
||||
}
|
||||
@@ -101,23 +121,7 @@ func newPackageForPackage(resolver file.Resolver, m parsedData, sources ...file.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
name := normalize(m.Name)
|
||||
|
||||
p := pkg.Package{
|
||||
Name: name,
|
||||
Version: m.Version,
|
||||
PURL: packageURL(name, m.Version, &m.PythonPackage),
|
||||
Locations: file.NewLocationSet(sources...),
|
||||
Licenses: licenseSet,
|
||||
Language: pkg.Python,
|
||||
Type: pkg.PythonPkg,
|
||||
Metadata: m.PythonPackage,
|
||||
}
|
||||
|
||||
p.SetID()
|
||||
|
||||
return p
|
||||
return licenseSet
|
||||
}
|
||||
|
||||
func packageURL(name, version string, m *pkg.PythonPackage) string {
|
||||
|
||||
@@ -9,6 +9,7 @@ import (
|
||||
"path/filepath"
|
||||
|
||||
"github.com/anchore/syft/internal"
|
||||
"github.com/anchore/syft/internal/licenses"
|
||||
"github.com/anchore/syft/internal/log"
|
||||
"github.com/anchore/syft/syft/artifact"
|
||||
"github.com/anchore/syft/syft/file"
|
||||
@@ -18,7 +19,9 @@ import (
|
||||
|
||||
// parseWheelOrEgg takes the primary metadata file reference and returns the python package it represents. Contained
|
||||
// fields are governed by the PyPA core metadata specification (https://packaging.python.org/en/latest/specifications/core-metadata/).
|
||||
func parseWheelOrEgg(_ context.Context, resolver file.Resolver, _ *generic.Environment, reader file.LocationReadCloser) ([]pkg.Package, []artifact.Relationship, error) {
|
||||
func parseWheelOrEgg(ctx context.Context, resolver file.Resolver, _ *generic.Environment, reader file.LocationReadCloser) ([]pkg.Package, []artifact.Relationship, error) {
|
||||
licenseScanner := licenses.ContextLicenseScanner(ctx)
|
||||
|
||||
pd, sources, err := assembleEggOrWheelMetadata(resolver, reader.Location)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
@@ -33,7 +36,13 @@ func parseWheelOrEgg(_ context.Context, resolver file.Resolver, _ *generic.Envir
|
||||
return nil, nil, nil
|
||||
}
|
||||
|
||||
pkgs := []pkg.Package{newPackageForPackage(resolver, *pd, sources...)}
|
||||
pkgs := []pkg.Package{
|
||||
newPackageForPackage(
|
||||
*pd,
|
||||
findLicenses(ctx, licenseScanner, resolver, *pd),
|
||||
sources...,
|
||||
),
|
||||
}
|
||||
|
||||
return pkgs, nil, nil
|
||||
}
|
||||
@@ -60,7 +69,7 @@ func fetchInstalledFiles(resolver file.Resolver, metadataLocation file.Location,
|
||||
// parse the installed-files contents
|
||||
installedFiles, err := parseInstalledFiles(installedFilesContents, metadataLocation.RealPath, sitePackagesRootPath)
|
||||
if err != nil {
|
||||
log.Warnf("unable to parse installed-files.txt for python package=%+v: %w", metadataLocation.RealPath, err)
|
||||
log.WithFields("error", err, "path", metadataLocation.RealPath).Trace("unable to parse installed-files.txt for python package")
|
||||
return files, sources, nil
|
||||
}
|
||||
|
||||
|
||||
@@ -43,7 +43,7 @@ func Test_packageURL(t *testing.T) {
|
||||
Release: "r",
|
||||
Epoch: intRef(1),
|
||||
},
|
||||
expected: "pkg:rpm/centos/p@v-r?arch=a&epoch=1&distro=centos-7",
|
||||
expected: "pkg:rpm/centos/p@v-r?arch=a&distro=centos-7&epoch=1",
|
||||
},
|
||||
{
|
||||
name: "missing distro",
|
||||
@@ -67,7 +67,7 @@ func Test_packageURL(t *testing.T) {
|
||||
Release: "r",
|
||||
SourceRpm: "sourcerpm",
|
||||
},
|
||||
expected: "pkg:rpm/redhat/p@v-r?upstream=sourcerpm&distro=rhel-8.4",
|
||||
expected: "pkg:rpm/redhat/p@v-r?distro=rhel-8.4&upstream=sourcerpm",
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
@@ -87,7 +87,7 @@ func TestLanguageFromPURL(t *testing.T) {
|
||||
want: Lua,
|
||||
},
|
||||
{
|
||||
purl: "pkg:opam/ocaml-base-compiler@ 5.2.0",
|
||||
purl: "pkg:opam/ocaml-base-compiler@5.2.0",
|
||||
want: OCaml,
|
||||
},
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user