mirror of
https://github.com/anchore/syft.git
synced 2026-10-26 12:02:23 +01:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a4b5dcd0df | ||
|
|
06526e2931 | ||
|
|
a2042e629c | ||
|
|
a35e410c75 | ||
|
|
8dd7c9c0b9 | ||
|
|
490e05adb2 | ||
|
|
1cd75b7d68 | ||
|
|
4882d2e8ce | ||
|
|
b3848f780f | ||
|
|
36f95d6828 | ||
|
|
68b96ae444 | ||
|
|
3917989f86 | ||
|
|
741c8fb9bd | ||
|
|
9573f557d1 | ||
|
|
ca945d16e0 | ||
|
|
fe7c5a7174 | ||
|
|
125c787e40 | ||
|
|
bfe6f5204a | ||
|
|
aead40e1de | ||
|
|
536611fa25 | ||
|
|
d0a7d4c43e | ||
|
|
0c53a087f0 | ||
|
|
b263b1ec1f | ||
|
|
034a98f029 | ||
|
|
69031b0646 | ||
|
|
761a161e7f | ||
|
|
ba31c2f1ae | ||
|
|
5d729a5e9e | ||
|
|
276df95768 | ||
|
|
cca9a06a64 | ||
|
|
4d23990dd4 | ||
|
|
d4fa61e0a2 | ||
|
|
d4d4e003e9 | ||
|
|
6bf91a410d | ||
|
|
77c300d617 | ||
|
|
75902b0540 | ||
|
|
278b72d39b | ||
|
|
37245a21cc | ||
|
|
e2fe955262 | ||
|
|
4e09908ba1 | ||
|
|
863793a3cc | ||
|
|
f7ffcc534f | ||
|
|
b101f44aba | ||
|
|
de3313cfb6 | ||
|
|
b2f9904d74 | ||
|
|
13d01ecaff | ||
|
|
7dc1b1ce27 | ||
|
|
b8dce675fe | ||
|
|
6dda9edd7c | ||
|
|
04c861bf77 | ||
|
|
573440b7cf | ||
|
|
c816039e91 | ||
|
|
7f3ca65cf6 | ||
|
|
43e5b1b45f | ||
|
|
a876aaccb2 | ||
|
|
875669bfd1 | ||
|
|
5283c4687a | ||
|
|
4d48adfa3f | ||
|
|
c8b449c92b | ||
|
|
ceced5eb27 | ||
|
|
7da15890eb | ||
|
|
580c09b01c | ||
|
|
0dce67872e | ||
|
|
1eae9333a9 | ||
|
|
863891f325 | ||
|
|
bd1c1d260c | ||
|
|
f5a917a5a2 | ||
|
|
ae0683074e | ||
|
|
9b178174a7 | ||
|
|
e947779886 | ||
|
|
7a35de04ee | ||
|
|
246df97ae7 | ||
|
|
750d37f075 | ||
|
|
5061b905dc | ||
|
|
ed3774afa7 |
+5
-5
@@ -18,7 +18,7 @@ tools:
|
||||
# used to sign mac binaries at release
|
||||
- name: quill
|
||||
version:
|
||||
want: v0.4.1
|
||||
want: v0.4.2
|
||||
method: github-release
|
||||
with:
|
||||
repo: anchore/quill
|
||||
@@ -42,7 +42,7 @@ tools:
|
||||
# used for signing the checksums file at release
|
||||
- name: cosign
|
||||
version:
|
||||
want: v2.2.4
|
||||
want: v2.3.0
|
||||
method: github-release
|
||||
with:
|
||||
repo: sigstore/cosign
|
||||
@@ -58,7 +58,7 @@ tools:
|
||||
# used to release all artifacts
|
||||
- name: goreleaser
|
||||
version:
|
||||
want: v2.0.1
|
||||
want: v2.1.0
|
||||
method: github-release
|
||||
with:
|
||||
repo: goreleaser/goreleaser
|
||||
@@ -103,7 +103,7 @@ tools:
|
||||
# used for running all local and CI tasks
|
||||
- name: task
|
||||
version:
|
||||
want: v3.37.2
|
||||
want: v3.38.0
|
||||
method: github-release
|
||||
with:
|
||||
repo: go-task/task
|
||||
@@ -111,7 +111,7 @@ tools:
|
||||
# used for triggering a release
|
||||
- name: gh
|
||||
version:
|
||||
want: v2.51.0
|
||||
want: v2.53.0
|
||||
method: github-release
|
||||
with:
|
||||
repo: cli/cli
|
||||
|
||||
@@ -6,6 +6,7 @@ permit:
|
||||
- MPL.*
|
||||
- ISC
|
||||
- WTFPL
|
||||
- Unlicense
|
||||
|
||||
ignore-packages:
|
||||
# packageurl-go is released under the MIT license located in the root of the repo at /mit.LICENSE
|
||||
|
||||
@@ -27,14 +27,14 @@ runs:
|
||||
using: "composite"
|
||||
steps:
|
||||
# note: go mod and build is automatically cached on default with v4+
|
||||
- uses: actions/setup-go@cdcb36043654635271a94b9a6d1392de5bb323a7 #v5.0.1
|
||||
- uses: actions/setup-go@cdcb36043654635271a94b9a6d1392de5bb323a7 # v5.0.1
|
||||
if: inputs.go-version != ''
|
||||
with:
|
||||
go-version: ${{ inputs.go-version }}
|
||||
|
||||
- name: Restore tool cache
|
||||
id: tool-cache
|
||||
uses: actions/cache@704facf57e6136b1bc63b828d79edcd491f0ee84 #v3.3.2
|
||||
uses: actions/cache@704facf57e6136b1bc63b828d79edcd491f0ee84 # v3.3.2
|
||||
with:
|
||||
path: ${{ github.workspace }}/.tool
|
||||
key: ${{ inputs.cache-key-prefix }}-${{ runner.os }}-tool-${{ hashFiles('.binny.yaml') }}
|
||||
|
||||
@@ -17,3 +17,11 @@ updates:
|
||||
open-pull-requests-limit: 10
|
||||
labels:
|
||||
- "dependencies"
|
||||
|
||||
- package-ecosystem: "github-actions"
|
||||
directory: "/.github/actions/boostrap"
|
||||
schedule:
|
||||
interval: "daily"
|
||||
open-pull-requests-limit: 10
|
||||
labels:
|
||||
- "dependencies"
|
||||
|
||||
@@ -39,7 +39,7 @@ jobs:
|
||||
OUTPUT="${OUTPUT//$'\r'/'%0D'}" # URL encode all '\r' characters
|
||||
echo "result=$OUTPUT" >> $GITHUB_OUTPUT
|
||||
|
||||
- uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3
|
||||
- uses: actions/upload-artifact@0b2256b8c012f0828dc542b3febcab082c67f72b # v4.3.4
|
||||
with:
|
||||
name: benchmark-test-results
|
||||
path: test/results/**/*
|
||||
|
||||
@@ -39,13 +39,13 @@ jobs:
|
||||
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 #v4.1.7
|
||||
|
||||
- name: Install Go
|
||||
uses: actions/setup-go@cdcb36043654635271a94b9a6d1392de5bb323a7 #v5.0.1
|
||||
uses: actions/setup-go@0a12ed9d6a96ab950c8f026ed9f722fe0da7ef32 #v5.0.2
|
||||
with:
|
||||
go-version-file: go.mod
|
||||
|
||||
# Initializes the CodeQL tools for scanning.
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@23acc5c183826b7a8a97bce3cecc52db901f8251 #v3.25.10
|
||||
uses: github/codeql-action/init@afb54ba388a7dca6ecae48f608c4ff05ff4cc77a #v3.25.15
|
||||
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@23acc5c183826b7a8a97bce3cecc52db901f8251 #v3.25.10
|
||||
uses: github/codeql-action/autobuild@afb54ba388a7dca6ecae48f608c4ff05ff4cc77a #v3.25.15
|
||||
|
||||
# ℹ️ 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@23acc5c183826b7a8a97bce3cecc52db901f8251 #v3.25.10
|
||||
uses: github/codeql-action/analyze@afb54ba388a7dca6ecae48f608c4ff05ff4cc77a #v3.25.15
|
||||
|
||||
@@ -113,13 +113,13 @@ jobs:
|
||||
uses: ./.github/actions/bootstrap
|
||||
|
||||
- name: Login to Docker Hub
|
||||
uses: docker/login-action@0d4c9c5ea7693da7b068278f7b52bda2a190a446 #v3.2.0
|
||||
uses: docker/login-action@9780b0c442fbb1117ed29e0efdff1e18412f7567 #v3.3.0
|
||||
with:
|
||||
username: ${{ secrets.ANCHOREOSSWRITE_DH_USERNAME }}
|
||||
password: ${{ secrets.ANCHOREOSSWRITE_DH_PAT }}
|
||||
|
||||
- name: Login to GitHub Container Registry
|
||||
uses: docker/login-action@0d4c9c5ea7693da7b068278f7b52bda2a190a446 #v3.2.0
|
||||
uses: docker/login-action@9780b0c442fbb1117ed29e0efdff1e18412f7567 #v3.3.0
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.actor }}
|
||||
@@ -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@e8d2a6937ecead383dfe75190d104edd1f9c5751 #v0.16.0
|
||||
- uses: anchore/sbom-action@d94f46e13c6c62f59525ac9a1e147a99dc0b9bf5 #v0.17.0
|
||||
continue-on-error: true
|
||||
with:
|
||||
artifact-name: sbom.spdx.json
|
||||
|
||||
@@ -50,7 +50,7 @@ jobs:
|
||||
app_id: ${{ secrets.TOKEN_APP_ID }}
|
||||
private_key: ${{ secrets.TOKEN_APP_PRIVATE_KEY }}
|
||||
|
||||
- uses: peter-evans/create-pull-request@6d6857d36972b65feb161a90e484f2984215f83e #v6.0.5
|
||||
- uses: peter-evans/create-pull-request@c5a7806660adbe173f04e3e038b0ccdcd758773c #v6.1.0
|
||||
with:
|
||||
signoff: true
|
||||
delete-branch: true
|
||||
|
||||
@@ -33,7 +33,7 @@ jobs:
|
||||
app_id: ${{ secrets.TOKEN_APP_ID }}
|
||||
private_key: ${{ secrets.TOKEN_APP_PRIVATE_KEY }}
|
||||
|
||||
- uses: peter-evans/create-pull-request@6d6857d36972b65feb161a90e484f2984215f83e #v6.0.5
|
||||
- uses: peter-evans/create-pull-request@c5a7806660adbe173f04e3e038b0ccdcd758773c #v6.1.0
|
||||
with:
|
||||
signoff: true
|
||||
delete-branch: true
|
||||
|
||||
@@ -19,7 +19,7 @@ jobs:
|
||||
steps:
|
||||
- uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 #v4.1.7
|
||||
|
||||
- uses: actions/setup-go@cdcb36043654635271a94b9a6d1392de5bb323a7 #v5.0.1
|
||||
- uses: actions/setup-go@0a12ed9d6a96ab950c8f026ed9f722fe0da7ef32 #v5.0.2
|
||||
with:
|
||||
go-version: ${{ env.GO_VERSION }}
|
||||
stable: ${{ env.GO_STABLE_VERSION }}
|
||||
@@ -44,7 +44,7 @@ jobs:
|
||||
app_id: ${{ secrets.TOKEN_APP_ID }}
|
||||
private_key: ${{ secrets.TOKEN_APP_PRIVATE_KEY }}
|
||||
|
||||
- uses: peter-evans/create-pull-request@6d6857d36972b65feb161a90e484f2984215f83e #v6.0.5
|
||||
- uses: peter-evans/create-pull-request@c5a7806660adbe173f04e3e038b0ccdcd758773c #v6.1.0
|
||||
with:
|
||||
signoff: true
|
||||
delete-branch: true
|
||||
|
||||
@@ -0,0 +1,128 @@
|
||||
# Contributor Covenant Code of Conduct
|
||||
|
||||
## Our Pledge
|
||||
|
||||
We as members, contributors, and leaders pledge to make participation in our
|
||||
community a harassment-free experience for everyone, regardless of age, body
|
||||
size, visible or invisible disability, ethnicity, sex characteristics, gender
|
||||
identity and expression, level of experience, education, socio-economic status,
|
||||
nationality, personal appearance, race, religion, or sexual identity
|
||||
and orientation.
|
||||
|
||||
We pledge to act and interact in ways that contribute to an open, welcoming,
|
||||
diverse, inclusive, and healthy community.
|
||||
|
||||
## Our Standards
|
||||
|
||||
Examples of behavior that contributes to a positive environment for our
|
||||
community include:
|
||||
|
||||
* Demonstrating empathy and kindness toward other people
|
||||
* Being respectful of differing opinions, viewpoints, and experiences
|
||||
* Giving and gracefully accepting constructive feedback
|
||||
* Accepting responsibility and apologizing to those affected by our mistakes,
|
||||
and learning from the experience
|
||||
* Focusing on what is best not just for us as individuals, but for the
|
||||
overall community
|
||||
|
||||
Examples of unacceptable behavior include:
|
||||
|
||||
* The use of sexualized language or imagery, and sexual attention or
|
||||
advances of any kind
|
||||
* Trolling, insulting or derogatory comments, and personal or political attacks
|
||||
* Public or private harassment
|
||||
* Publishing others' private information, such as a physical or email
|
||||
address, without their explicit permission
|
||||
* Other conduct which could reasonably be considered inappropriate in a
|
||||
professional setting
|
||||
|
||||
## Enforcement Responsibilities
|
||||
|
||||
Community leaders are responsible for clarifying and enforcing our standards of
|
||||
acceptable behavior and will take appropriate and fair corrective action in
|
||||
response to any behavior that they deem inappropriate, threatening, offensive,
|
||||
or harmful.
|
||||
|
||||
Community leaders have the right and responsibility to remove, edit, or reject
|
||||
comments, commits, code, wiki edits, issues, and other contributions that are
|
||||
not aligned to this Code of Conduct, and will communicate reasons for moderation
|
||||
decisions when appropriate.
|
||||
|
||||
## Scope
|
||||
|
||||
This Code of Conduct applies within all community spaces, and also applies when
|
||||
an individual is officially representing the community in public spaces.
|
||||
Examples of representing our community include using an official e-mail address,
|
||||
posting via an official social media account, or acting as an appointed
|
||||
representative at an online or offline event.
|
||||
|
||||
## Enforcement
|
||||
|
||||
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
||||
reported to the community leaders responsible for enforcement at
|
||||
[opensource@anchore.com](mailto:opensource@anchore.com).
|
||||
All complaints will be reviewed and investigated promptly and fairly.
|
||||
|
||||
All community leaders are obligated to respect the privacy and security of the
|
||||
reporter of any incident.
|
||||
|
||||
## Enforcement Guidelines
|
||||
|
||||
Community leaders will follow these Community Impact Guidelines in determining
|
||||
the consequences for any action they deem in violation of this Code of Conduct:
|
||||
|
||||
### 1. Correction
|
||||
|
||||
**Community Impact**: Use of inappropriate language or other behavior deemed
|
||||
unprofessional or unwelcome in the community.
|
||||
|
||||
**Consequence**: A private, written warning from community leaders, providing
|
||||
clarity around the nature of the violation and an explanation of why the
|
||||
behavior was inappropriate. A public apology may be requested.
|
||||
|
||||
### 2. Warning
|
||||
|
||||
**Community Impact**: A violation through a single incident or series
|
||||
of actions.
|
||||
|
||||
**Consequence**: A warning with consequences for continued behavior. No
|
||||
interaction with the people involved, including unsolicited interaction with
|
||||
those enforcing the Code of Conduct, for a specified period of time. This
|
||||
includes avoiding interactions in community spaces as well as external channels
|
||||
like social media. Violating these terms may lead to a temporary or
|
||||
permanent ban.
|
||||
|
||||
### 3. Temporary Ban
|
||||
|
||||
**Community Impact**: A serious violation of community standards, including
|
||||
sustained inappropriate behavior.
|
||||
|
||||
**Consequence**: A temporary ban from any sort of interaction or public
|
||||
communication with the community for a specified period of time. No public or
|
||||
private interaction with the people involved, including unsolicited interaction
|
||||
with those enforcing the Code of Conduct, is allowed during this period.
|
||||
Violating these terms may lead to a permanent ban.
|
||||
|
||||
### 4. Permanent Ban
|
||||
|
||||
**Community Impact**: Demonstrating a pattern of violation of community
|
||||
standards, including sustained inappropriate behavior, harassment of an
|
||||
individual, or aggression toward or disparagement of classes of individuals.
|
||||
|
||||
**Consequence**: A permanent ban from any sort of public interaction within
|
||||
the community.
|
||||
|
||||
## Attribution
|
||||
|
||||
This Code of Conduct is adapted from the [Contributor Covenant][homepage],
|
||||
version 2.0, available at
|
||||
https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.
|
||||
|
||||
Community Impact Guidelines were inspired by [Mozilla's code of conduct
|
||||
enforcement ladder](https://github.com/mozilla/diversity).
|
||||
|
||||
[homepage]: https://www.contributor-covenant.org
|
||||
|
||||
For answers to common questions about this code of conduct, see the FAQ at
|
||||
https://www.contributor-covenant.org/faq. Translations are available at
|
||||
https://www.contributor-covenant.org/translations.
|
||||
@@ -11,7 +11,7 @@
|
||||
<a href="https://goreportcard.com/report/github.com/anchore/syft" target="_blank"><img alt="Go Report Card" src="https://goreportcard.com/badge/github.com/anchore/syft"></a>
|
||||
<a href="https://github.com/anchore/syft/releases/latest" target="_blank"><img alt="GitHub release" src="https://img.shields.io/github/release/anchore/syft.svg"></a>
|
||||
<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="" 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/slack" target="_blank"><img alt="Slack" src="https://img.shields.io/badge/Slack-Join-blue?logo=slack"></a>
|
||||
</p>
|
||||
|
||||
@@ -105,8 +105,10 @@ syft <image> -o <format>
|
||||
Where the `formats` available are:
|
||||
- `syft-json`: Use this to get as much information out of Syft as possible!
|
||||
- `syft-text`: A row-oriented, human-and-machine-friendly output.
|
||||
- `cyclonedx-xml`: A XML report conforming to the [CycloneDX 1.4 specification](https://cyclonedx.org/specification/overview/).
|
||||
- `cyclonedx-json`: A JSON report conforming to the [CycloneDX 1.4 specification](https://cyclonedx.org/specification/overview/).
|
||||
- `cyclonedx-xml`: A XML report conforming to the [CycloneDX 1.6 specification](https://cyclonedx.org/specification/overview/).
|
||||
- `cyclonedx-xml@1.5`: A XML report conforming to the [CycloneDX 1.5 specification](https://cyclonedx.org/specification/overview/).
|
||||
- `cyclonedx-json`: A JSON report conforming to the [CycloneDX 1.6 specification](https://cyclonedx.org/specification/overview/).
|
||||
- `cyclonedx-json@1.5`: A JSON report conforming to the [CycloneDX 1.5 specification](https://cyclonedx.org/specification/overview/).
|
||||
- `spdx-tag-value`: A tag-value formatted report conforming to the [SPDX 2.3 specification](https://spdx.github.io/spdx-spec/v2.3/).
|
||||
- `spdx-tag-value@2.2`: A tag-value formatted report conforming to the [SPDX 2.2 specification](https://spdx.github.io/spdx-spec/v2.2.2/).
|
||||
- `spdx-json`: A JSON report conforming to the [SPDX 2.3 JSON Schema](https://github.com/spdx/spdx-spec/blob/v2.3/schemas/spdx-schema.json).
|
||||
@@ -115,6 +117,8 @@ Where the `formats` available are:
|
||||
- `syft-table`: A columnar summary (default).
|
||||
- `template`: Lets the user specify the output format. See ["Using templates"](#using-templates) below.
|
||||
|
||||
Note that flags using the @<version> can be used for earlier versions of each specification as well.
|
||||
|
||||
### Supported Ecosystems
|
||||
|
||||
- Alpine (apk)
|
||||
@@ -164,6 +168,10 @@ Our [wiki](https://github.com/anchore/syft/wiki) contains further details on the
|
||||
* [Adding an SBOM to an image as an attestation using Syft](https://github.com/anchore/syft/wiki/attestation#adding-an-sbom-to-an-image-as-an-attestation-using-syft)
|
||||
* [Configuration](https://github.com/anchore/syft/wiki/configuration)
|
||||
|
||||
## Contributing
|
||||
|
||||
Check out our [contributing](/CONTRIBUTING.md) guide and [developer](/DEVELOPING.md) docs.
|
||||
|
||||
## Syft Team Meetings
|
||||
|
||||
The Syft Team hold regular community meetings online. All are welcome to join to bring topics for discussion.
|
||||
|
||||
@@ -35,7 +35,7 @@ var imageOnlyTestCases = []testCase{
|
||||
pkgType: pkg.PythonPkg,
|
||||
pkgLanguage: pkg.Python,
|
||||
pkgInfo: map[string]string{
|
||||
"Pygments": "2.6.1",
|
||||
"pygments": "2.6.1",
|
||||
"requests": "2.22.0",
|
||||
"somerequests": "3.22.0",
|
||||
"someotherpkg": "3.19.0",
|
||||
@@ -172,7 +172,7 @@ var dirOnlyTestCases = []testCase{
|
||||
"passlib": "1.7.2",
|
||||
"mypy": "v0.770",
|
||||
// common to image and directory
|
||||
"Pygments": "2.6.1",
|
||||
"pygments": "2.6.1",
|
||||
"requests": "2.22.0",
|
||||
"somerequests": "3.22.0",
|
||||
"someotherpkg": "3.19.0",
|
||||
|
||||
@@ -10,7 +10,8 @@ import (
|
||||
func TestMarinerDistroless(t *testing.T) {
|
||||
sbom, _ := catalogFixtureImage(t, "image-mariner-distroless", source.SquashedScope)
|
||||
|
||||
expectedPkgs := 12
|
||||
// 12 RPMs + 2 binaries with ELF package notes claiming to be RPMs
|
||||
expectedPkgs := 14
|
||||
actualPkgs := 0
|
||||
for range sbom.Artifacts.Packages.Enumerate(pkg.RpmPkg) {
|
||||
actualPkgs += 1
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/anchore/syft/internal/relationship"
|
||||
"github.com/anchore/syft/syft/artifact"
|
||||
"github.com/anchore/syft/syft/source"
|
||||
)
|
||||
@@ -44,12 +45,13 @@ func TestBinaryElfRelationships(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
relationshipIndex := relationship.NewIndex(sbom.Relationships...)
|
||||
for name, expectedDepNames := range expectedGraph {
|
||||
pkgId := nameToId[name]
|
||||
p := sbom.Artifacts.Packages.Package(pkgId)
|
||||
require.NotNil(t, p, "expected package %q to be present in the SBOM", name)
|
||||
|
||||
rels := sbom.RelationshipsForPackage(*p, artifact.DependencyOfRelationship)
|
||||
rels := relationshipIndex.References(*p, artifact.DependencyOfRelationship)
|
||||
require.NotEmpty(t, rels, "expected package %q to have relationships", name)
|
||||
|
||||
toIds := map[artifact.ID]struct{}{}
|
||||
|
||||
@@ -17,29 +17,29 @@ require (
|
||||
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.3-0.20240501181043-2e9894674185
|
||||
github.com/anchore/stereoscope v0.0.3-0.20240725180315-50ce3be7aa1f
|
||||
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/charmbracelet/bubbles v0.18.0
|
||||
github.com/charmbracelet/bubbletea v0.26.4
|
||||
github.com/charmbracelet/lipgloss v0.11.0
|
||||
github.com/charmbracelet/bubbletea v0.26.6
|
||||
github.com/charmbracelet/lipgloss v0.12.1
|
||||
github.com/dave/jennifer v1.7.0
|
||||
github.com/deitch/magic v0.0.0-20230404182410-1ff89d7342da
|
||||
github.com/distribution/reference v0.6.0
|
||||
github.com/docker/docker v26.1.4+incompatible
|
||||
github.com/docker/docker v27.1.1+incompatible
|
||||
github.com/dustin/go-humanize v1.0.1
|
||||
github.com/elliotchance/phpserialize v1.4.0
|
||||
github.com/facebookincubator/nvdtools v0.1.5
|
||||
github.com/github/go-spdx/v2 v2.2.0
|
||||
github.com/gkampitakis/go-snaps v0.5.4
|
||||
github.com/github/go-spdx/v2 v2.3.1
|
||||
github.com/gkampitakis/go-snaps v0.5.6
|
||||
github.com/go-git/go-billy/v5 v5.5.0
|
||||
github.com/go-git/go-git/v5 v5.12.0
|
||||
github.com/go-test/deep v1.1.0
|
||||
github.com/go-test/deep v1.1.1
|
||||
github.com/google/go-cmp v0.6.0
|
||||
github.com/google/go-containerregistry v0.19.1
|
||||
github.com/google/go-containerregistry v0.20.1
|
||||
github.com/google/licensecheck v0.3.1
|
||||
github.com/google/uuid v1.6.0
|
||||
github.com/gookit/color v1.5.4
|
||||
@@ -55,21 +55,21 @@ require (
|
||||
github.com/mitchellh/go-homedir v1.1.0
|
||||
github.com/mitchellh/hashstructure/v2 v2.0.2
|
||||
github.com/mitchellh/mapstructure v1.5.0
|
||||
github.com/moby/sys/mountinfo v0.7.1
|
||||
github.com/moby/sys/mountinfo v0.7.2
|
||||
github.com/olekukonko/tablewriter v0.0.5
|
||||
github.com/opencontainers/go-digest v1.0.0
|
||||
github.com/pelletier/go-toml v1.9.5
|
||||
github.com/quasilyte/go-ruleguard/dsl v0.3.22
|
||||
github.com/saferwall/pe v1.5.3
|
||||
github.com/saferwall/pe v1.5.4
|
||||
github.com/saintfish/chardet v0.0.0-20230101081208-5e3ef4b5456d
|
||||
github.com/sanity-io/litter v1.5.5
|
||||
github.com/sassoftware/go-rpmutils v0.4.0
|
||||
// pinned to pull in 386 arch fix: https://github.com/scylladb/go-set/commit/cc7b2070d91ebf40d233207b633e28f5bd8f03a5
|
||||
github.com/scylladb/go-set v1.0.3-0.20200225121959-cc7b2070d91e
|
||||
github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3
|
||||
github.com/spdx/tools-golang v0.5.4
|
||||
github.com/spdx/tools-golang v0.5.5
|
||||
github.com/spf13/afero v1.11.0
|
||||
github.com/spf13/cobra v1.8.0
|
||||
github.com/spf13/cobra v1.8.1
|
||||
github.com/stretchr/testify v1.9.0
|
||||
github.com/vbatts/go-mtree v0.5.4
|
||||
github.com/vifraa/gopom v1.0.0
|
||||
@@ -78,18 +78,19 @@ require (
|
||||
github.com/xeipuuv/gojsonschema v1.2.0
|
||||
github.com/zyedidia/generic v1.2.2-0.20230320175451-4410d2372cb1
|
||||
go.uber.org/goleak v1.3.0
|
||||
golang.org/x/mod v0.18.0
|
||||
golang.org/x/net v0.26.0
|
||||
golang.org/x/mod v0.19.0
|
||||
golang.org/x/net v0.27.0
|
||||
gopkg.in/yaml.v3 v3.0.1
|
||||
modernc.org/sqlite v1.30.1
|
||||
modernc.org/sqlite v1.31.1
|
||||
)
|
||||
|
||||
require google.golang.org/genproto v0.0.0-20231106174013-bbf56f31fb17 // indirect
|
||||
|
||||
require (
|
||||
github.com/BurntSushi/toml v1.4.0
|
||||
github.com/adrg/xdg v0.4.0
|
||||
github.com/adrg/xdg v0.5.0
|
||||
github.com/magiconair/properties v1.8.7
|
||||
golang.org/x/exp v0.0.0-20231108232855-2478ac86f678
|
||||
)
|
||||
|
||||
require (
|
||||
@@ -109,7 +110,7 @@ require (
|
||||
github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect
|
||||
github.com/becheran/wildmatch-go v1.0.0 // indirect
|
||||
github.com/charmbracelet/harmonica v0.2.0 // indirect
|
||||
github.com/charmbracelet/x/ansi v0.1.2 // indirect
|
||||
github.com/charmbracelet/x/ansi v0.1.4 // indirect
|
||||
github.com/charmbracelet/x/input v0.1.0 // indirect
|
||||
github.com/charmbracelet/x/term v0.1.1 // indirect
|
||||
github.com/charmbracelet/x/windows v0.1.0 // indirect
|
||||
@@ -124,7 +125,7 @@ require (
|
||||
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 v24.0.0+incompatible // indirect
|
||||
github.com/docker/cli v27.0.3+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 +138,7 @@ require (
|
||||
github.com/felixge/fgprof v0.9.3 // indirect
|
||||
github.com/felixge/httpsnoop v1.0.3 // indirect
|
||||
github.com/fsnotify/fsnotify v1.7.0 // indirect
|
||||
github.com/gabriel-vasile/mimetype v1.4.0 // indirect
|
||||
github.com/gabriel-vasile/mimetype v1.4.4 // 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
|
||||
@@ -162,7 +163,7 @@ require (
|
||||
github.com/klauspost/pgzip v1.2.5 // indirect
|
||||
github.com/kr/pretty v0.3.1 // indirect
|
||||
github.com/kr/text v0.2.0 // indirect
|
||||
github.com/logrusorgru/aurora v0.0.0-20200102142835-e9ef32dff381 // indirect
|
||||
github.com/logrusorgru/aurora v2.0.3+incompatible // indirect
|
||||
github.com/lucasb-eyer/go-colorful v1.2.0 // indirect
|
||||
github.com/maruel/natural v1.1.1 // indirect
|
||||
github.com/mattn/go-colorable v0.1.13 // indirect
|
||||
@@ -182,13 +183,13 @@ require (
|
||||
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-rc3 // indirect
|
||||
github.com/opencontainers/image-spec v1.1.0 // indirect
|
||||
github.com/opencontainers/runc v1.1.12 // indirect
|
||||
github.com/opencontainers/runtime-spec v1.1.0-rc.1 // indirect
|
||||
github.com/opencontainers/selinux v1.11.0 // indirect
|
||||
github.com/pborman/indent v1.2.1 // indirect
|
||||
github.com/pelletier/go-toml/v2 v2.1.0 // indirect
|
||||
github.com/pierrec/lz4/v4 v4.1.15 // indirect
|
||||
github.com/pierrec/lz4/v4 v4.1.19 // indirect
|
||||
github.com/pjbgf/sha1cd v0.3.0 // indirect
|
||||
github.com/pkg/errors v0.9.1 // indirect
|
||||
github.com/pkg/profile v1.7.0 // indirect
|
||||
@@ -208,8 +209,8 @@ require (
|
||||
github.com/spf13/pflag v1.0.5 // indirect
|
||||
github.com/spf13/viper v1.18.2 // indirect
|
||||
github.com/subosito/gotenv v1.6.0 // indirect
|
||||
github.com/sylabs/sif/v2 v2.11.5 // indirect
|
||||
github.com/sylabs/squashfs v0.6.1 // indirect
|
||||
github.com/sylabs/sif/v2 v2.17.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
|
||||
github.com/tidwall/match v1.1.1 // indirect
|
||||
@@ -229,11 +230,10 @@ require (
|
||||
go.opentelemetry.io/otel/trace v1.19.0 // indirect
|
||||
go.uber.org/atomic v1.9.0 // indirect
|
||||
go.uber.org/multierr v1.9.0 // indirect
|
||||
golang.org/x/crypto v0.24.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20231108232855-2478ac86f678 // indirect
|
||||
golang.org/x/crypto v0.25.0 // indirect
|
||||
golang.org/x/sync v0.7.0 // indirect
|
||||
golang.org/x/sys v0.21.0 // indirect
|
||||
golang.org/x/term v0.21.0 // indirect
|
||||
golang.org/x/sys v0.22.0 // indirect
|
||||
golang.org/x/term v0.22.0 // indirect
|
||||
golang.org/x/text v0.16.0 // indirect
|
||||
golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d // indirect
|
||||
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect
|
||||
@@ -243,7 +243,7 @@ require (
|
||||
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
|
||||
modernc.org/libc v1.52.1 // indirect
|
||||
modernc.org/libc v1.55.3 // indirect
|
||||
modernc.org/mathutil v1.6.0 // indirect
|
||||
modernc.org/memory v1.8.0 // indirect
|
||||
modernc.org/strutil v1.2.0 // indirect
|
||||
|
||||
@@ -85,8 +85,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.4.0 h1:RzRqFcjH4nE5C6oTAxhBtoE2IRyjBSa62SCbyPidvls=
|
||||
github.com/adrg/xdg v0.4.0/go.mod h1:N6ag73EX4wyxeaoeHctc1mas01KZgsj5tYiAIwqJE/E=
|
||||
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/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,8 +113,8 @@ github.com/anchore/go-version v1.2.2-0.20200701162849-18adb9c92b9b h1:e1bmaoJfZV
|
||||
github.com/anchore/go-version v1.2.2-0.20200701162849-18adb9c92b9b/go.mod h1:Bkc+JYWjMCF8OyZ340IMSIi2Ebf3uwByOk6ho4wne1E=
|
||||
github.com/anchore/packageurl-go v0.1.1-0.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.3-0.20240501181043-2e9894674185 h1:SuViDJ27nZ+joGdKbAkxAlm7tYMt9NTxTZZ05po4hls=
|
||||
github.com/anchore/stereoscope v0.0.3-0.20240501181043-2e9894674185/go.mod h1:ckIamHiRMp8iBwWoTtE5Xkt9VQ5QC+6+O4VzwqyZr5Q=
|
||||
github.com/anchore/stereoscope v0.0.3-0.20240725180315-50ce3be7aa1f h1:xuBvotcht1Ns8IdaC4UuYV1U8MFln9c5ELeo5bzDEO8=
|
||||
github.com/anchore/stereoscope v0.0.3-0.20240725180315-50ce3be7aa1f/go.mod h1:DcQdMes8SwpFli3rDH0v+Vd9qU9Jariq7JSHNJV5X/A=
|
||||
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=
|
||||
@@ -157,14 +157,14 @@ github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XL
|
||||
github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
github.com/charmbracelet/bubbles v0.18.0 h1:PYv1A036luoBGroX6VWjQIE9Syf2Wby2oOl/39KLfy0=
|
||||
github.com/charmbracelet/bubbles v0.18.0/go.mod h1:08qhZhtIwzgrtBjAcJnij1t1H0ZRjwHyGsy6AL11PSw=
|
||||
github.com/charmbracelet/bubbletea v0.26.4 h1:2gDkkzLZaTjMl/dQBpNVtnvcCxsh/FCkimep7FC9c40=
|
||||
github.com/charmbracelet/bubbletea v0.26.4/go.mod h1:P+r+RRA5qtI1DOHNFn0otoNwB4rn+zNAzSj/EXz6xU0=
|
||||
github.com/charmbracelet/bubbletea v0.26.6 h1:zTCWSuST+3yZYZnVSvbXwKOPRSNZceVeqpzOLN2zq1s=
|
||||
github.com/charmbracelet/bubbletea v0.26.6/go.mod h1:dz8CWPlfCCGLFbBlTY4N7bjLiyOGDJEnd2Muu7pOWhk=
|
||||
github.com/charmbracelet/harmonica v0.2.0 h1:8NxJWRWg/bzKqqEaaeFNipOu77YR5t8aSwG4pgaUBiQ=
|
||||
github.com/charmbracelet/harmonica v0.2.0/go.mod h1:KSri/1RMQOZLbw7AHqgcBycp8pgJnQMYYT8QZRqZ1Ao=
|
||||
github.com/charmbracelet/lipgloss v0.11.0 h1:UoAcbQ6Qml8hDwSWs0Y1cB5TEQuZkDPH/ZqwWWYTG4g=
|
||||
github.com/charmbracelet/lipgloss v0.11.0/go.mod h1:1UdRTH9gYgpcdNN5oBtjbu/IzNKtzVtb7sqN1t9LNn8=
|
||||
github.com/charmbracelet/x/ansi v0.1.2 h1:6+LR39uG8DE6zAmbu023YlqjJHkYXDF1z36ZwzO4xZY=
|
||||
github.com/charmbracelet/x/ansi v0.1.2/go.mod h1:dk73KoMTT5AX5BsX0KrqhsTqAnhZZoCBjs7dGWp4Ktw=
|
||||
github.com/charmbracelet/lipgloss v0.12.1 h1:/gmzszl+pedQpjCOH+wFkZr/N90Snz40J/NR7A0zQcs=
|
||||
github.com/charmbracelet/lipgloss v0.12.1/go.mod h1:V2CiwIuhx9S1S1ZlADfOj9HmxeMAORuz5izHb0zGbB8=
|
||||
github.com/charmbracelet/x/ansi v0.1.4 h1:IEU3D6+dWwPSgZ6HBH+v6oUuZ/nVawMiWj5831KfiLM=
|
||||
github.com/charmbracelet/x/ansi v0.1.4/go.mod h1:dk73KoMTT5AX5BsX0KrqhsTqAnhZZoCBjs7dGWp4Ktw=
|
||||
github.com/charmbracelet/x/input v0.1.0 h1:TEsGSfZYQyOtp+STIjyBq6tpRaorH0qpwZUj8DavAhQ=
|
||||
github.com/charmbracelet/x/input v0.1.0/go.mod h1:ZZwaBxPF7IG8gWWzPUVqHEtWhc1+HXJPNuerJGRGZ28=
|
||||
github.com/charmbracelet/x/term v0.1.1 h1:3cosVAiPOig+EV4X9U+3LDgtwwAoEzJjNdwbXDjF6yI=
|
||||
@@ -211,7 +211,7 @@ github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSV
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.1/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
|
||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
github.com/cyphar/filepath-securejoin v0.2.4 h1:Ugdm7cg7i6ZK6x3xDF1oEu1nfkyfH53EtKeQYTC3kyg=
|
||||
github.com/cyphar/filepath-securejoin v0.2.4/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4=
|
||||
@@ -227,12 +227,12 @@ 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 v24.0.0+incompatible h1:0+1VshNwBQzQAx9lOl+OYCTCEAD8fKs/qeXMx3O0wqM=
|
||||
github.com/docker/cli v24.0.0+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
|
||||
github.com/docker/cli v27.0.3+incompatible h1:usGs0/BoBW8MWxGeEtqPMkzOY56jZ6kYlSN5BLDioCQ=
|
||||
github.com/docker/cli v27.0.3+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 v26.1.4+incompatible h1:vuTpXDuoga+Z38m1OZHzl7NKisKWaWlhjQk7IDPSLsU=
|
||||
github.com/docker/docker v26.1.4+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
|
||||
github.com/docker/docker v27.1.1+incompatible h1:hO/M4MtV36kzKldqnA37IWhebRA+LnqqcqDja6kVaKY=
|
||||
github.com/docker/docker v27.1.1+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
|
||||
github.com/docker/docker-credential-helpers v0.7.0 h1:xtCHsjxogADNZcdv1pKUHXryefjlVRqWqIhk/uXJp0A=
|
||||
github.com/docker/docker-credential-helpers v0.7.0/go.mod h1:rETQfLdHNT3foU5kuNkFR1R1V12OJRRO5lzt2D1b5X0=
|
||||
github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ=
|
||||
@@ -284,17 +284,17 @@ 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.0 h1:Cn9dkdYsMIu56tGho+fqzh7XmvY2YyGU0FnbhiOsEro=
|
||||
github.com/gabriel-vasile/mimetype v1.4.0/go.mod h1:fA8fi6KUiG7MgQQ+mEWotXoEOvmxRtOJlERCzSmRvr8=
|
||||
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/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||
github.com/github/go-spdx/v2 v2.2.0 h1:yBBLMasHA70Ujd35OpL/OjJOWWVNXcJGbars0GinGRI=
|
||||
github.com/github/go-spdx/v2 v2.2.0/go.mod h1:hMCrsFgT0QnCwn7G8gxy/MxMpy67WgZrwFeISTn0o6w=
|
||||
github.com/github/go-spdx/v2 v2.3.1 h1:ffGuHTbHuHzWPt53n8f9o8clGutuLPObo3zB4JAjxU8=
|
||||
github.com/github/go-spdx/v2 v2.3.1/go.mod h1:2ZxKsOhvBp+OYBDlsGnUMcchLeo2mrpEBn2L1C+U3IQ=
|
||||
github.com/gkampitakis/ciinfo v0.3.0 h1:gWZlOC2+RYYttL0hBqcoQhM7h1qNkVqvRCV1fOvpAv8=
|
||||
github.com/gkampitakis/ciinfo v0.3.0/go.mod h1:1NIwaOcFChN4fa/B0hEBdAb6npDlFL8Bwx4dfRLRqAo=
|
||||
github.com/gkampitakis/go-diff v1.3.2 h1:Qyn0J9XJSDTgnsgHRdz9Zp24RaJeKMUHg2+PDZZdC4M=
|
||||
github.com/gkampitakis/go-diff v1.3.2/go.mod h1:LLgOrpqleQe26cte8s36HTWcTmMEur6OPYerdAAS9tk=
|
||||
github.com/gkampitakis/go-snaps v0.5.4 h1:GX+dkKmVsRenz7SoTbdIEL4KQARZctkMiZ8ZKprRwT8=
|
||||
github.com/gkampitakis/go-snaps v0.5.4/go.mod h1:ZABkO14uCuVxBHAXAfKG+bqNz+aa1bGPAg8jkI0Nk8Y=
|
||||
github.com/gkampitakis/go-snaps v0.5.6 h1:kAal5JbqTycI+6xeS3K0nPqvNDAxqKX5W3dRXKxIJpA=
|
||||
github.com/gkampitakis/go-snaps v0.5.6/go.mod h1:ZABkO14uCuVxBHAXAfKG+bqNz+aa1bGPAg8jkI0Nk8Y=
|
||||
github.com/glebarez/go-sqlite v1.20.3 h1:89BkqGOXR9oRmG58ZrzgoY/Fhy5x0M+/WV48U5zVrZ4=
|
||||
github.com/glebarez/go-sqlite v1.20.3/go.mod h1:u3N6D/wftiAzIOJtZl6BmedqxmmkDfH3q+ihjqxC9u0=
|
||||
github.com/gliderlabs/ssh v0.3.7 h1:iV3Bqi942d9huXnzEF2Mt+CY9gLu8DNM4Obd+8bODRE=
|
||||
@@ -323,8 +323,8 @@ github.com/go-restruct/restruct v1.2.0-alpha h1:2Lp474S/9660+SJjpVxoKuWX09JsXHSr
|
||||
github.com/go-restruct/restruct v1.2.0-alpha/go.mod h1:KqrpKpn4M8OLznErihXTGLlsXFGeLxHUrLRRI/1YjGk=
|
||||
github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
|
||||
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
||||
github.com/go-test/deep v1.1.0 h1:WOcxcdHcvdgThNXjw0t76K42FXTU7HpNQWHpA2HHNlg=
|
||||
github.com/go-test/deep v1.1.0/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE=
|
||||
github.com/go-test/deep v1.1.1 h1:0r/53hagsehfO4bzD2Pgr/+RgHqhmf+k1Bpse2cTu1U=
|
||||
github.com/go-test/deep v1.1.1/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE=
|
||||
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
||||
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
||||
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
|
||||
@@ -384,8 +384,8 @@ github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
|
||||
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
|
||||
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/go-containerregistry v0.19.1 h1:yMQ62Al6/V0Z7CqIrrS1iYoA5/oQCm88DeNujc7C1KY=
|
||||
github.com/google/go-containerregistry v0.19.1/go.mod h1:YCMFNQeeXeLF+dnhhWkqDItx/JSkH01j1Kis4PsjzFI=
|
||||
github.com/google/go-containerregistry v0.20.1 h1:eTgx9QNYugV4DN5mz4U8hiAGTi1ybXn0TPi4Smd8du0=
|
||||
github.com/google/go-containerregistry v0.20.1/go.mod h1:YCMFNQeeXeLF+dnhhWkqDItx/JSkH01j1Kis4PsjzFI=
|
||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/google/licensecheck v0.3.1 h1:QoxgoDkaeC4nFrtGN1jV7IPmDCHFNIVh54e5hSt6sPs=
|
||||
github.com/google/licensecheck v0.3.1/go.mod h1:ORkR35t/JjW+emNKtfJDII0zlciG9JgbT7SmsohlHmY=
|
||||
@@ -522,8 +522,9 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
|
||||
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
|
||||
github.com/logrusorgru/aurora v0.0.0-20200102142835-e9ef32dff381 h1:bqDmpDG49ZRnB5PcgP0RXtQvnMSgIF14M7CBd2shtXs=
|
||||
github.com/logrusorgru/aurora v0.0.0-20200102142835-e9ef32dff381/go.mod h1:7rIyQOR62GCctdiQpZ/zOJlFyk6y+94wXzv6RNZgaR4=
|
||||
github.com/logrusorgru/aurora v2.0.3+incompatible h1:tOpm7WcpBTn4fjmVfgpQq0EfczGlG91VSDkswnjF5A8=
|
||||
github.com/logrusorgru/aurora v2.0.3+incompatible/go.mod h1:7rIyQOR62GCctdiQpZ/zOJlFyk6y+94wXzv6RNZgaR4=
|
||||
github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY=
|
||||
github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0=
|
||||
github.com/lyft/protoc-gen-star v0.5.3/go.mod h1:V0xaHgaf5oCCqmcxYcWiDfTiKsZsRc87/1qhoTACD8w=
|
||||
@@ -583,8 +584,8 @@ github.com/moby/docker-image-spec v1.3.1 h1:jMKff3w6PgbfSa69GfNg+zN/XLhfXJGnEx3N
|
||||
github.com/moby/docker-image-spec v1.3.1/go.mod h1:eKmb5VW8vQEh/BAr2yvVNvuiJuY6UIocYsFu/DxxRpo=
|
||||
github.com/moby/locker v1.0.1 h1:fOXqR41zeveg4fFODix+1Ch4mj/gT0NE1XJbp/epuBg=
|
||||
github.com/moby/locker v1.0.1/go.mod h1:S7SDdo5zpBK84bzzVlKr2V0hz+7x9hWbYC/kq7oQppc=
|
||||
github.com/moby/sys/mountinfo v0.7.1 h1:/tTvQaSJRr2FshkhXiIpux6fQ2Zvc4j7tAhMTStAG2g=
|
||||
github.com/moby/sys/mountinfo v0.7.1/go.mod h1:IJb6JQeOklcdMU9F5xQ8ZALD+CUr5VlGpwtX+VE0rpI=
|
||||
github.com/moby/sys/mountinfo v0.7.2 h1:1shs6aH5s4o5H2zQLn796ADW1wMrIwHsyJ2v9KouLrg=
|
||||
github.com/moby/sys/mountinfo v0.7.2/go.mod h1:1YOa8w8Ih7uW0wALDUgT1dTTSBrZ+HiBLGws92L2RU4=
|
||||
github.com/moby/sys/sequential v0.5.0 h1:OPvI35Lzn9K04PBbCLW0g4LcFAJgHsvXsRyewg5lXtc=
|
||||
github.com/moby/sys/sequential v0.5.0/go.mod h1:tH2cOOs5V9MlPiXcQzRC+eEyab644PWKGRYaaV5ZZlo=
|
||||
github.com/moby/sys/signal v0.7.0 h1:25RW3d5TnQEoKvRbEKUGay6DCQ46IxAVTT9CUMgmsSI=
|
||||
@@ -617,8 +618,8 @@ github.com/onsi/gomega v1.27.10 h1:naR28SdDFlqrG6kScpT8VWpu1xWY5nJRCF3XaYyBjhI=
|
||||
github.com/onsi/gomega v1.27.10/go.mod h1:RsS8tutOdbdgzbPtzzATp12yT7kM5I5aElG3evPbQ0M=
|
||||
github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=
|
||||
github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
|
||||
github.com/opencontainers/image-spec v1.1.0-rc3 h1:fzg1mXZFj8YdPeNkRXMg+zb88BFV0Ys52cJydRwBkb8=
|
||||
github.com/opencontainers/image-spec v1.1.0-rc3/go.mod h1:X4pATf0uXsnn3g5aiGIsVnJBR4mxhKzfwmvK/B2NTm8=
|
||||
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.12 h1:BOIssBaW1La0/qbNZHXOOa71dZfZEQOzW7dqQf3phss=
|
||||
github.com/opencontainers/runc v1.1.12/go.mod h1:S+lQwSfncpBha7XTy/5lBwWgm5+y5Ma/O44Ekby9FK8=
|
||||
github.com/opencontainers/runtime-spec v1.1.0-rc.1 h1:wHa9jroFfKGQqFHj0I1fMRKLl0pfj+ynAqBxo3v6u9w=
|
||||
@@ -635,8 +636,8 @@ github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCko
|
||||
github.com/pelletier/go-toml/v2 v2.1.0 h1:FnwAJ4oYMvbT/34k9zzHuZNrhlz48GB3/s6at6/MHO4=
|
||||
github.com/pelletier/go-toml/v2 v2.1.0/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc=
|
||||
github.com/pierrec/lz4/v4 v4.1.2/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4=
|
||||
github.com/pierrec/lz4/v4 v4.1.15 h1:MO0/ucJhngq7299dKLwIMtgTfbkoSPF6AoMYDd8Q4q0=
|
||||
github.com/pierrec/lz4/v4 v4.1.15/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4=
|
||||
github.com/pierrec/lz4/v4 v4.1.19 h1:tYLzDnjDXh9qIxSTKHwXwOYmm9d887Y7Y1ZkyXYHAN4=
|
||||
github.com/pierrec/lz4/v4 v4.1.19/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4=
|
||||
github.com/pjbgf/sha1cd v0.3.0 h1:4D5XXmUUBUl/xQ6IjCkEAbqXskkq/4O7LmGn0AqMDs4=
|
||||
github.com/pjbgf/sha1cd v0.3.0/go.mod h1:nZ1rrWOcGJ5uZgEEVL1VUM9iRQiZvWdbZjkKyFzPPsI=
|
||||
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
|
||||
@@ -684,8 +685,8 @@ github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99
|
||||
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
|
||||
github.com/saferwall/pe v1.5.3 h1:tZ2KJWeJK6N2jjJx+B9hm+wq6qe0o56pql2PXUaQ9eI=
|
||||
github.com/saferwall/pe v1.5.3/go.mod h1:mJx+PuptmNpoPFBNhWs/uDMFL/kTHVZIkg0d4OUJFbQ=
|
||||
github.com/saferwall/pe v1.5.4 h1:tLmMggEMUfeqrpJ25zS/okUQmyFdD5xWKL2+z9njCqg=
|
||||
github.com/saferwall/pe v1.5.4/go.mod h1:mJx+PuptmNpoPFBNhWs/uDMFL/kTHVZIkg0d4OUJFbQ=
|
||||
github.com/sagikazarmark/crypt v0.3.0/go.mod h1:uD/D+6UF4SrIR1uGEv7bBNkNqLGqUr43MRiaGWX1Nig=
|
||||
github.com/sagikazarmark/locafero v0.4.0 h1:HApY1R9zGo4DBgr7dqsTH/JJxLTTsOt7u6keLGt6kNQ=
|
||||
github.com/sagikazarmark/locafero v0.4.0/go.mod h1:Pe1W6UlPYUk/+wc/6KFhbORCfqzgYEpgQ3O5fPuL3H4=
|
||||
@@ -726,8 +727,8 @@ github.com/sourcegraph/conc v0.3.0 h1:OQTbbt6P72L20UqAkXXuLOj79LfEanQ+YQFNpLA9yS
|
||||
github.com/sourcegraph/conc v0.3.0/go.mod h1:Sdozi7LEKbFPqYX2/J+iBAM6HpqSLTASQIKqDmF7Mt0=
|
||||
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
|
||||
github.com/spdx/gordf v0.0.0-20201111095634-7098f93598fb/go.mod h1:uKWaldnbMnjsSAXRurWqqrdyZen1R7kxl8TkmWk2OyM=
|
||||
github.com/spdx/tools-golang v0.5.4 h1:fRW4iz16P1ZCUtWStFqS6YiMgnK7WgfTFU/lrsYlvqY=
|
||||
github.com/spdx/tools-golang v0.5.4/go.mod h1:MVIsXx8ZZzaRWNQpUDhC4Dud34edUYJYecciXgrw5vE=
|
||||
github.com/spdx/tools-golang v0.5.5 h1:61c0KLfAcNqAjlg6UNMdkwpMernhw3zVRwDZ2x9XOmk=
|
||||
github.com/spdx/tools-golang v0.5.5/go.mod h1:MVIsXx8ZZzaRWNQpUDhC4Dud34edUYJYecciXgrw5vE=
|
||||
github.com/spf13/afero v1.3.3/go.mod h1:5KUK8ByomD5Ti5Artl0RtHeI5pTF7MIDuXL3yY520V4=
|
||||
github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I=
|
||||
github.com/spf13/afero v1.11.0 h1:WJQKhtpdm3v2IzqG8VMqrr6Rf3UYpEF239Jy9wNepM8=
|
||||
@@ -737,8 +738,8 @@ github.com/spf13/cast v1.4.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkU
|
||||
github.com/spf13/cast v1.6.0 h1:GEiTHELF+vaR5dhz3VqZfFSzZjYbgeKDpBxQVS4GYJ0=
|
||||
github.com/spf13/cast v1.6.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo=
|
||||
github.com/spf13/cobra v1.3.0/go.mod h1:BrRVncBjOJa/eUcVVm9CE+oC6as8k+VYr4NY7WCi9V4=
|
||||
github.com/spf13/cobra v1.8.0 h1:7aJaZx1B85qltLMc546zn58BxxfZdR/W22ej9CFoEf0=
|
||||
github.com/spf13/cobra v1.8.0/go.mod h1:WXLWApfZ71AjXPya3WOlMsY9yMs7YeiHhFVlvLyhcho=
|
||||
github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM=
|
||||
github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y=
|
||||
github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo=
|
||||
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
|
||||
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||
@@ -768,10 +769,10 @@ 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.11.5 h1:7ssPH3epSonsTrzbS1YxeJ9KuqAN7ISlSM61a7j/mQM=
|
||||
github.com/sylabs/sif/v2 v2.11.5/go.mod h1:GBoZs9LU3e4yJH1dcZ3Akf/jsqYgy5SeguJQC+zd75Y=
|
||||
github.com/sylabs/squashfs v0.6.1 h1:4hgvHnD9JGlYWwT0bPYNt9zaz23mAV3Js+VEgQoRGYQ=
|
||||
github.com/sylabs/squashfs v0.6.1/go.mod h1:ZwpbPCj0ocIvMy2br6KZmix6Gzh6fsGQcCnydMF+Kx8=
|
||||
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/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=
|
||||
github.com/terminalstatic/go-xsd-validate v0.1.5/go.mod h1:18lsvYFofBflqCrvo1umpABZ99+GneNTw2kEEc8UPJw=
|
||||
github.com/therootcompany/xz v1.0.1 h1:CmOtsn1CbtmyYiusbfmhmkpAAETj0wBIH6kCYaX+xzw=
|
||||
@@ -877,8 +878,8 @@ golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0
|
||||
golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4=
|
||||
golang.org/x/crypto v0.3.1-0.20221117191849-2c476679df9a/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4=
|
||||
golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU=
|
||||
golang.org/x/crypto v0.24.0 h1:mnl8DM0o513X8fdIkmyFE/5hTYxbwYOjDS/+rK6qpRI=
|
||||
golang.org/x/crypto v0.24.0/go.mod h1:Z1PMYSOR5nyMcyAVAIQSKCDwalqy85Aqn1x3Ws4L5DM=
|
||||
golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30=
|
||||
golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
|
||||
@@ -919,8 +920,8 @@ golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.5.0/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro=
|
||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||
golang.org/x/mod v0.18.0 h1:5+9lSbEzPSdWkH32vYPBwEpX8KwDbM52Ud9xBUvNlb0=
|
||||
golang.org/x/mod v0.18.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
|
||||
golang.org/x/mod v0.19.0 h1:fEdghXQSo20giMthA7cd28ZC+jts4amQ3YMXiP5oMQ8=
|
||||
golang.org/x/mod v0.19.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
|
||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
@@ -961,15 +962,14 @@ golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLd
|
||||
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
|
||||
golang.org/x/net v0.0.0-20210410081132-afb366fc7cd1/go.mod h1:9tjilg8BloeKEkVJvy7fQ90B1CfIiPueXVOjqfkSzI8=
|
||||
golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20210505024714-0287a6fb4125/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||
golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY=
|
||||
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
||||
golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc=
|
||||
golang.org/x/net v0.26.0 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ=
|
||||
golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE=
|
||||
golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys=
|
||||
golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
@@ -1081,15 +1081,15 @@ golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws=
|
||||
golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI=
|
||||
golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc=
|
||||
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
|
||||
golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U=
|
||||
golang.org/x/term v0.21.0 h1:WVXCp+/EBEHOj53Rvu+7KiT/iElMrO8ACK16SMZ3jaA=
|
||||
golang.org/x/term v0.21.0/go.mod h1:ooXLefLobQVslOqselCNF4SxFAaoS6KujMbsGzSDmX0=
|
||||
golang.org/x/term v0.22.0 h1:BbsgPEJULsl2fV/AT3v15Mjva5yXKQDyKf+TbDz7QJk=
|
||||
golang.org/x/term v0.22.0/go.mod h1:F3qCibpT5AMpCRfhfT53vVJwhLtIVHhB9XDjfFvnMI4=
|
||||
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
@@ -1359,18 +1359,18 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWh
|
||||
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
|
||||
honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
||||
honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
||||
modernc.org/cc/v4 v4.21.2 h1:dycHFB/jDc3IyacKipCNSDrjIC0Lm1hyoWOZTRR20Lk=
|
||||
modernc.org/cc/v4 v4.21.2/go.mod h1:HM7VJTZbUCR3rV8EYBi9wxnJ0ZBRiGE5OeGXNA0IsLQ=
|
||||
modernc.org/ccgo/v4 v4.17.10 h1:6wrtRozgrhCxieCeJh85QsxkX/2FFrT9hdaWPlbn4Zo=
|
||||
modernc.org/ccgo/v4 v4.17.10/go.mod h1:0NBHgsqTTpm9cA5z2ccErvGZmtntSM9qD2kFAs6pjXM=
|
||||
modernc.org/cc/v4 v4.21.4 h1:3Be/Rdo1fpr8GrQ7IVw9OHtplU4gWbb+wNgeoBMmGLQ=
|
||||
modernc.org/cc/v4 v4.21.4/go.mod h1:HM7VJTZbUCR3rV8EYBi9wxnJ0ZBRiGE5OeGXNA0IsLQ=
|
||||
modernc.org/ccgo/v4 v4.19.2 h1:lwQZgvboKD0jBwdaeVCTouxhxAyN6iawF3STraAal8Y=
|
||||
modernc.org/ccgo/v4 v4.19.2/go.mod h1:ysS3mxiMV38XGRTTcgo0DQTeTmAO4oCmJl1nX9VFI3s=
|
||||
modernc.org/fileutil v1.3.0 h1:gQ5SIzK3H9kdfai/5x41oQiKValumqNTDXMvKo62HvE=
|
||||
modernc.org/fileutil v1.3.0/go.mod h1:XatxS8fZi3pS8/hKG2GH/ArUogfxjpEKs3Ku3aK4JyQ=
|
||||
modernc.org/gc/v2 v2.4.1 h1:9cNzOqPyMJBvrUipmynX0ZohMhcxPtMccYgGOJdOiBw=
|
||||
modernc.org/gc/v2 v2.4.1/go.mod h1:wzN5dK1AzVGoH6XOzc3YZ+ey/jPgYHLuVckd62P0GYU=
|
||||
modernc.org/gc/v3 v3.0.0-20240107210532-573471604cb6 h1:5D53IMaUuA5InSeMu9eJtlQXS2NxAhyWQvkKEgXZhHI=
|
||||
modernc.org/gc/v3 v3.0.0-20240107210532-573471604cb6/go.mod h1:Qz0X07sNOR1jWYCrJMEnbW/X55x206Q7Vt4mz6/wHp4=
|
||||
modernc.org/libc v1.52.1 h1:uau0VoiT5hnR+SpoWekCKbLqm7v6dhRL3hI+NQhgN3M=
|
||||
modernc.org/libc v1.52.1/go.mod h1:HR4nVzFDSDizP620zcMCgjb1/8xk2lg5p/8yjfGv1IQ=
|
||||
modernc.org/libc v1.55.3 h1:AzcW1mhlPNrRtjS5sS+eW2ISCgSOLLNyFzRh/V3Qj/U=
|
||||
modernc.org/libc v1.55.3/go.mod h1:qFXepLhz+JjFThQ4kzwzOjA/y/artDeg+pcYnY+Q83w=
|
||||
modernc.org/mathutil v1.6.0 h1:fRe9+AmYlaej+64JsEEhoWuAYBkOtQiMEU7n/XgfYi4=
|
||||
modernc.org/mathutil v1.6.0/go.mod h1:Ui5Q9q1TR2gFm0AQRqQUaBWFLAhQpCwNcuhBOSedWPo=
|
||||
modernc.org/memory v1.8.0 h1:IqGTL6eFMaDZZhEWwcREgeMXYwmW83LYW8cROZYkg+E=
|
||||
@@ -1379,8 +1379,8 @@ modernc.org/opt v0.1.3 h1:3XOZf2yznlhC+ibLltsDGzABUGVx8J6pnFMS3E4dcq4=
|
||||
modernc.org/opt v0.1.3/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0=
|
||||
modernc.org/sortutil v1.2.0 h1:jQiD3PfS2REGJNzNCMMaLSp/wdMNieTbKX920Cqdgqc=
|
||||
modernc.org/sortutil v1.2.0/go.mod h1:TKU2s7kJMf1AE84OoiGppNHJwvB753OYfNl2WRb++Ss=
|
||||
modernc.org/sqlite v1.30.1 h1:YFhPVfu2iIgUf9kuA1CR7iiHdcEEsI2i+yjRYHscyxk=
|
||||
modernc.org/sqlite v1.30.1/go.mod h1:DUmsiWQDaAvU4abhc/N+djlom/L2o8f7gZ95RCvyoLU=
|
||||
modernc.org/sqlite v1.31.1 h1:XVU0VyzxrYHlBhIs1DiEgSl0ZtdnPtbLVy8hSkzxGrs=
|
||||
modernc.org/sqlite v1.31.1/go.mod h1:UqoylwmTb9F+IqXERT8bW9zzOWN8qwAIcLdzeBZs4hA=
|
||||
modernc.org/strutil v1.2.0 h1:agBi9dp1I+eOnxXeiZawM8F4LawKv4NzGWSaLfyeNZA=
|
||||
modernc.org/strutil v1.2.0/go.mod h1:/mdcBmfOibveCTBxUl5B5l6W+TTH1FXPLHZE6bTosX0=
|
||||
modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y=
|
||||
|
||||
Vendored
+1
-1
@@ -87,7 +87,7 @@ func subFs(fsys afero.Fs, subDirs ...string) (afero.Fs, error) {
|
||||
if errors.Is(err, afero.ErrFileNotFound) {
|
||||
err = fsys.MkdirAll(dir, dirPermissions)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unable to create directory at '%s/%s': %v", dir, strings.Join(subDirs, "/"), err)
|
||||
return nil, fmt.Errorf("unable to create directory at '%s': %v", dir, err)
|
||||
}
|
||||
stat, err = fsys.Stat(dir)
|
||||
if err != nil {
|
||||
|
||||
Vendored
+12
@@ -1,6 +1,7 @@
|
||||
package cache
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"net/url"
|
||||
"os"
|
||||
@@ -92,3 +93,14 @@ func Test_makeDiskKey(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func Test_errors(t *testing.T) {
|
||||
tmp := t.TempDir()
|
||||
cache := filepath.Join(tmp, "cache")
|
||||
// make a non-writable directory
|
||||
require.NoError(t, os.MkdirAll(cache, 0500|os.ModeDir))
|
||||
// attempt to make cache in non-writable directory
|
||||
dir := filepath.Join(cache, "dir")
|
||||
_, err := NewFromDir(dir, time.Hour)
|
||||
require.ErrorContains(t, err, fmt.Sprintf("unable to create directory at '%s':", dir))
|
||||
}
|
||||
|
||||
@@ -21,27 +21,22 @@ func NewDependencyRelationships(resolver file.Resolver, accessor sbomsync.Access
|
||||
|
||||
// 3. craft package-to-package relationships for each binary that represent shared library dependencies
|
||||
//note: we only care about package-to-package relationships
|
||||
var relIndex *relationship.Index
|
||||
accessor.ReadFromSBOM(func(s *sbom.SBOM) {
|
||||
relIndex = relationship.NewIndex(s.Relationships...)
|
||||
})
|
||||
|
||||
return generateRelationships(resolver, accessor, index, relIndex)
|
||||
return generateRelationships(resolver, accessor, index)
|
||||
}
|
||||
|
||||
func generateRelationships(resolver file.Resolver, accessor sbomsync.Accessor, index *sharedLibraryIndex, relIndex *relationship.Index) []artifact.Relationship {
|
||||
// read all existing dependencyOf relationships
|
||||
accessor.ReadFromSBOM(func(s *sbom.SBOM) {
|
||||
for _, r := range s.Relationships {
|
||||
if r.Type != artifact.DependencyOfRelationship {
|
||||
continue
|
||||
}
|
||||
relIndex.Track(r)
|
||||
}
|
||||
})
|
||||
func generateRelationships(resolver file.Resolver, accessor sbomsync.Accessor, index *sharedLibraryIndex) []artifact.Relationship {
|
||||
newRelationships := relationship.NewIndex()
|
||||
|
||||
// find all package-to-package relationships for shared library dependencies
|
||||
accessor.ReadFromSBOM(func(s *sbom.SBOM) {
|
||||
relIndex := relationship.NewIndex(s.Relationships...)
|
||||
|
||||
addRelationship := func(r artifact.Relationship) {
|
||||
if !relIndex.Contains(r) {
|
||||
newRelationships.Add(r)
|
||||
}
|
||||
}
|
||||
|
||||
for _, parentPkg := range s.Artifacts.Packages.Sorted(pkg.BinaryPkg) {
|
||||
for _, evidentLocation := range parentPkg.Locations.ToSlice() {
|
||||
if evidentLocation.Annotations[pkg.EvidenceAnnotationKey] != pkg.PrimaryEvidenceAnnotation {
|
||||
@@ -54,12 +49,12 @@ func generateRelationships(resolver file.Resolver, accessor sbomsync.Accessor, i
|
||||
continue
|
||||
}
|
||||
|
||||
populateRelationships(exec, parentPkg, resolver, relIndex, index)
|
||||
populateRelationships(exec, parentPkg, resolver, addRelationship, index)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
return relIndex.NewRelationships()
|
||||
return newRelationships.All()
|
||||
}
|
||||
|
||||
// PackagesToRemove returns a list of binary packages (resolved by the ELF cataloger) that should be removed from the SBOM
|
||||
@@ -147,7 +142,7 @@ func getBinaryPackagesToDelete(resolver file.Resolver, s *sbom.SBOM) []artifact.
|
||||
return pkgsToDelete
|
||||
}
|
||||
|
||||
func populateRelationships(exec file.Executable, parentPkg pkg.Package, resolver file.Resolver, relIndex *relationship.Index, index *sharedLibraryIndex) {
|
||||
func populateRelationships(exec file.Executable, parentPkg pkg.Package, resolver file.Resolver, addRelationship func(artifact.Relationship), index *sharedLibraryIndex) {
|
||||
for _, libReference := range exec.ImportedLibraries {
|
||||
// for each library reference, check s.Artifacts.Packages.Sorted(pkg.BinaryPkg) for a binary package that represents that library
|
||||
// if found, create a relationship between the parent package and the library package
|
||||
@@ -167,7 +162,7 @@ func populateRelationships(exec file.Executable, parentPkg pkg.Package, resolver
|
||||
realBaseName := path.Base(loc.RealPath)
|
||||
pkgCollection := index.owningLibraryPackage(realBaseName)
|
||||
if pkgCollection.PackageCount() < 1 {
|
||||
relIndex.Add(
|
||||
addRelationship(
|
||||
artifact.Relationship{
|
||||
From: loc.Coordinates,
|
||||
To: parentPkg,
|
||||
@@ -176,7 +171,7 @@ func populateRelationships(exec file.Executable, parentPkg pkg.Package, resolver
|
||||
)
|
||||
}
|
||||
for _, p := range pkgCollection.Sorted() {
|
||||
relIndex.Add(
|
||||
addRelationship(
|
||||
artifact.Relationship{
|
||||
From: p,
|
||||
To: parentPkg,
|
||||
|
||||
@@ -2,6 +2,7 @@ package binary
|
||||
|
||||
import (
|
||||
"path"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/google/go-cmp/cmp"
|
||||
@@ -328,7 +329,20 @@ func relationshipComparer(x, y []artifact.Relationship) string {
|
||||
artifact.Relationship{},
|
||||
file.LocationSet{},
|
||||
pkg.LicenseSet{},
|
||||
))
|
||||
), cmpopts.SortSlices(lessRelationships))
|
||||
}
|
||||
|
||||
func lessRelationships(r1, r2 artifact.Relationship) bool {
|
||||
c := strings.Compare(string(r1.Type), string(r2.Type))
|
||||
if c != 0 {
|
||||
return c < 0
|
||||
}
|
||||
c = strings.Compare(string(r1.From.ID()), string(r2.From.ID()))
|
||||
if c != 0 {
|
||||
return c < 0
|
||||
}
|
||||
c = strings.Compare(string(r1.To.ID()), string(r2.To.ID()))
|
||||
return c < 0
|
||||
}
|
||||
|
||||
func newAccessor(pkgs []pkg.Package, coordinateIndex map[file.Coordinates]file.Executable, preexistingRelationships []artifact.Relationship) sbomsync.Accessor {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package relationship
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"slices"
|
||||
|
||||
"github.com/anchore/syft/internal/sbomsync"
|
||||
@@ -21,6 +22,10 @@ var (
|
||||
binaryCatalogerTypes = []pkg.Type{
|
||||
pkg.BinaryPkg,
|
||||
}
|
||||
binaryMetadataTypes = []string{
|
||||
reflect.TypeOf(pkg.ELFBinaryPackageNoteJSONPayload{}).Name(),
|
||||
reflect.TypeOf(pkg.BinarySignature{}).Name(),
|
||||
}
|
||||
)
|
||||
|
||||
func ExcludeBinariesByFileOwnershipOverlap(accessor sbomsync.Accessor) {
|
||||
@@ -60,5 +65,15 @@ func excludeBinaryByFileOwnershipOverlap(r artifact.Relationship, c *pkg.Collect
|
||||
return false
|
||||
}
|
||||
|
||||
return slices.Contains(binaryCatalogerTypes, child.Type)
|
||||
if slices.Contains(binaryCatalogerTypes, child.Type) {
|
||||
return true
|
||||
}
|
||||
|
||||
if child.Metadata == nil {
|
||||
return false
|
||||
}
|
||||
|
||||
childMetadataType := reflect.TypeOf(child.Metadata)
|
||||
|
||||
return slices.Contains(binaryMetadataTypes, childMetadataType.Name())
|
||||
}
|
||||
|
||||
@@ -12,7 +12,9 @@ func TestExclude(t *testing.T) {
|
||||
packageB := pkg.Package{Name: "package-a", Type: pkg.PythonPkg}
|
||||
packageC := pkg.Package{Name: "package-a", Type: pkg.BinaryPkg}
|
||||
packageD := pkg.Package{Name: "package-d", Type: pkg.BinaryPkg}
|
||||
for _, p := range []*pkg.Package{&packageA, &packageB, &packageC, &packageD} {
|
||||
packageE := pkg.Package{Name: "package-e", Type: pkg.RpmPkg, Metadata: pkg.ELFBinaryPackageNoteJSONPayload{Type: "rpm"}}
|
||||
packageF := pkg.Package{Name: "package-f", Type: pkg.RpmPkg, Metadata: pkg.BinarySignature{}}
|
||||
for _, p := range []*pkg.Package{&packageA, &packageB, &packageC, &packageD, &packageE, &packageF} {
|
||||
p := p
|
||||
p.SetID()
|
||||
}
|
||||
@@ -43,6 +45,26 @@ func TestExclude(t *testing.T) {
|
||||
packages: pkg.NewCollection(packageA, packageC),
|
||||
shouldExclude: true,
|
||||
},
|
||||
{
|
||||
name: "exclusions from os -> elf binary (as RPM)",
|
||||
relationship: artifact.Relationship{
|
||||
Type: artifact.OwnershipByFileOverlapRelationship,
|
||||
From: packageA,
|
||||
To: packageE,
|
||||
},
|
||||
packages: pkg.NewCollection(packageA, packageE),
|
||||
shouldExclude: true,
|
||||
},
|
||||
{
|
||||
name: "exclusions from os -> binary (masquerading as RPM)",
|
||||
relationship: artifact.Relationship{
|
||||
Type: artifact.OwnershipByFileOverlapRelationship,
|
||||
From: packageA,
|
||||
To: packageF,
|
||||
},
|
||||
packages: pkg.NewCollection(packageA, packageF),
|
||||
shouldExclude: true,
|
||||
},
|
||||
{
|
||||
name: "no exclusions from python -> binary",
|
||||
relationship: artifact.Relationship{
|
||||
|
||||
+149
-56
@@ -1,88 +1,181 @@
|
||||
package relationship
|
||||
|
||||
import (
|
||||
"github.com/scylladb/go-set/strset"
|
||||
"slices"
|
||||
"strings"
|
||||
|
||||
"github.com/anchore/syft/syft/artifact"
|
||||
"github.com/anchore/syft/syft/file"
|
||||
)
|
||||
|
||||
// Index indexes relationships, preventing duplicates
|
||||
type Index struct {
|
||||
typesByFromTo map[artifact.ID]map[artifact.ID]*strset.Set
|
||||
existing []artifact.Relationship
|
||||
additional []artifact.Relationship
|
||||
all []*sortableRelationship
|
||||
fromID map[artifact.ID]*mappedRelationships
|
||||
toID map[artifact.ID]*mappedRelationships
|
||||
}
|
||||
|
||||
func NewIndex(existing ...artifact.Relationship) *Index {
|
||||
r := &Index{
|
||||
typesByFromTo: make(map[artifact.ID]map[artifact.ID]*strset.Set),
|
||||
}
|
||||
r.TrackAll(existing...)
|
||||
return r
|
||||
// NewIndex returns a new relationship Index
|
||||
func NewIndex(relationships ...artifact.Relationship) *Index {
|
||||
out := Index{}
|
||||
out.Add(relationships...)
|
||||
return &out
|
||||
}
|
||||
|
||||
func (i *Index) track(r artifact.Relationship) bool {
|
||||
fromID := r.From.ID()
|
||||
if _, ok := i.typesByFromTo[fromID]; !ok {
|
||||
i.typesByFromTo[fromID] = make(map[artifact.ID]*strset.Set)
|
||||
// Add adds all the given relationships to the index, without adding duplicates
|
||||
func (i *Index) Add(relationships ...artifact.Relationship) {
|
||||
if i.fromID == nil {
|
||||
i.fromID = map[artifact.ID]*mappedRelationships{}
|
||||
}
|
||||
if i.toID == nil {
|
||||
i.toID = map[artifact.ID]*mappedRelationships{}
|
||||
}
|
||||
|
||||
toID := r.To.ID()
|
||||
if _, ok := i.typesByFromTo[fromID][toID]; !ok {
|
||||
i.typesByFromTo[fromID][toID] = strset.New()
|
||||
// store appropriate indexes for stable ordering to minimize ID() calls
|
||||
for _, r := range relationships {
|
||||
// prevent duplicates
|
||||
if i.Contains(r) {
|
||||
continue
|
||||
}
|
||||
|
||||
fromID := r.From.ID()
|
||||
toID := r.To.ID()
|
||||
|
||||
relationship := &sortableRelationship{
|
||||
from: fromID,
|
||||
to: toID,
|
||||
relationship: r,
|
||||
}
|
||||
|
||||
// add to all relationships
|
||||
i.all = append(i.all, relationship)
|
||||
|
||||
// add from -> to mapping
|
||||
mapped := i.fromID[fromID]
|
||||
if mapped == nil {
|
||||
mapped = &mappedRelationships{}
|
||||
i.fromID[fromID] = mapped
|
||||
}
|
||||
mapped.add(toID, relationship)
|
||||
|
||||
// add to -> from mapping
|
||||
mapped = i.toID[toID]
|
||||
if mapped == nil {
|
||||
mapped = &mappedRelationships{}
|
||||
i.toID[toID] = mapped
|
||||
}
|
||||
mapped.add(fromID, relationship)
|
||||
}
|
||||
|
||||
var exists bool
|
||||
if i.typesByFromTo[fromID][toID].Has(string(r.Type)) {
|
||||
exists = true
|
||||
}
|
||||
|
||||
i.typesByFromTo[fromID][toID].Add(string(r.Type))
|
||||
|
||||
return !exists
|
||||
}
|
||||
|
||||
// Track this relationship as "exists" in the index (this is used to prevent duplicate relationships from being added).
|
||||
// returns true if the relationship is new to the index, false otherwise.
|
||||
func (i *Index) Track(r artifact.Relationship) bool {
|
||||
unique := i.track(r)
|
||||
if unique {
|
||||
i.existing = append(i.existing, r)
|
||||
}
|
||||
return unique
|
||||
// From returns all relationships from the given identifiable, with specified types
|
||||
func (i *Index) From(identifiable artifact.Identifiable, types ...artifact.RelationshipType) []artifact.Relationship {
|
||||
return toSortedSlice(fromMapped(i.fromID, identifiable), types)
|
||||
}
|
||||
|
||||
// Add a new relationship to the index, returning true if the relationship is new to the index, false otherwise (thus is a duplicate).
|
||||
func (i *Index) Add(r artifact.Relationship) bool {
|
||||
if i.track(r) {
|
||||
i.additional = append(i.additional, r)
|
||||
return true
|
||||
// To returns all relationships to the given identifiable, with specified types
|
||||
func (i *Index) To(identifiable artifact.Identifiable, types ...artifact.RelationshipType) []artifact.Relationship {
|
||||
return toSortedSlice(fromMapped(i.toID, identifiable), types)
|
||||
}
|
||||
|
||||
// References returns all relationships that reference to or from the given identifiable
|
||||
func (i *Index) References(identifiable artifact.Identifiable, types ...artifact.RelationshipType) []artifact.Relationship {
|
||||
return toSortedSlice(append(fromMapped(i.fromID, identifiable), fromMapped(i.toID, identifiable)...), types)
|
||||
}
|
||||
|
||||
// Coordinates returns all coordinates for the provided identifiable for provided relationship types
|
||||
// If no types are provided, all relationship types are considered.
|
||||
func (i *Index) Coordinates(identifiable artifact.Identifiable, types ...artifact.RelationshipType) []file.Coordinates {
|
||||
var coordinates []file.Coordinates
|
||||
for _, relationship := range i.References(identifiable, types...) {
|
||||
cords := extractCoordinates(relationship)
|
||||
coordinates = append(coordinates, cords...)
|
||||
}
|
||||
return coordinates
|
||||
}
|
||||
|
||||
// Contains indicates the relationship is present in this index
|
||||
func (i *Index) Contains(r artifact.Relationship) bool {
|
||||
if mapped := i.fromID[r.From.ID()]; mapped != nil {
|
||||
if ids := mapped.typeMap[r.Type]; ids != nil {
|
||||
return ids[r.To.ID()] != nil
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (i *Index) TrackAll(rs ...artifact.Relationship) {
|
||||
for _, r := range rs {
|
||||
i.Track(r)
|
||||
// All returns a sorted set of relationships matching all types, or all relationships if no types specified
|
||||
func (i *Index) All(types ...artifact.RelationshipType) []artifact.Relationship {
|
||||
return toSortedSlice(i.all, types)
|
||||
}
|
||||
|
||||
func fromMapped(idMap map[artifact.ID]*mappedRelationships, identifiable artifact.Identifiable) []*sortableRelationship {
|
||||
if identifiable == nil || idMap == nil {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func (i *Index) AddAll(rs ...artifact.Relationship) {
|
||||
for _, r := range rs {
|
||||
i.Add(r)
|
||||
mapped := idMap[identifiable.ID()]
|
||||
if mapped == nil {
|
||||
return nil
|
||||
}
|
||||
return mapped.allRelated
|
||||
}
|
||||
|
||||
func (i *Index) NewRelationships() []artifact.Relationship {
|
||||
return i.additional
|
||||
func toSortedSlice(relationships []*sortableRelationship, types []artifact.RelationshipType) []artifact.Relationship {
|
||||
// always return sorted for SBOM stability
|
||||
slices.SortFunc(relationships, sortFunc)
|
||||
var out []artifact.Relationship
|
||||
for _, r := range relationships {
|
||||
if len(types) == 0 || slices.Contains(types, r.relationship.Type) {
|
||||
out = append(out, r.relationship)
|
||||
}
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
func (i *Index) ExistingRelationships() []artifact.Relationship {
|
||||
return i.existing
|
||||
func extractCoordinates(relationship artifact.Relationship) (results []file.Coordinates) {
|
||||
if coordinates, exists := relationship.From.(file.Coordinates); exists {
|
||||
results = append(results, coordinates)
|
||||
}
|
||||
|
||||
if coordinates, exists := relationship.To.(file.Coordinates); exists {
|
||||
results = append(results, coordinates)
|
||||
}
|
||||
|
||||
return results
|
||||
}
|
||||
|
||||
func (i *Index) AllUniqueRelationships() []artifact.Relationship {
|
||||
var all []artifact.Relationship
|
||||
all = append(all, i.existing...)
|
||||
all = append(all, i.additional...)
|
||||
return all
|
||||
type mappedRelationships struct {
|
||||
typeMap map[artifact.RelationshipType]map[artifact.ID]*sortableRelationship
|
||||
allRelated []*sortableRelationship
|
||||
}
|
||||
|
||||
func (m *mappedRelationships) add(id artifact.ID, newRelationship *sortableRelationship) {
|
||||
m.allRelated = append(m.allRelated, newRelationship)
|
||||
if m.typeMap == nil {
|
||||
m.typeMap = map[artifact.RelationshipType]map[artifact.ID]*sortableRelationship{}
|
||||
}
|
||||
typeMap := m.typeMap[newRelationship.relationship.Type]
|
||||
if typeMap == nil {
|
||||
typeMap = map[artifact.ID]*sortableRelationship{}
|
||||
m.typeMap[newRelationship.relationship.Type] = typeMap
|
||||
}
|
||||
typeMap[id] = newRelationship
|
||||
}
|
||||
|
||||
type sortableRelationship struct {
|
||||
from artifact.ID
|
||||
to artifact.ID
|
||||
relationship artifact.Relationship
|
||||
}
|
||||
|
||||
func sortFunc(a, b *sortableRelationship) int {
|
||||
cmp := strings.Compare(string(a.relationship.Type), string(b.relationship.Type))
|
||||
if cmp != 0 {
|
||||
return cmp
|
||||
}
|
||||
cmp = strings.Compare(string(a.from), string(b.from))
|
||||
if cmp != 0 {
|
||||
return cmp
|
||||
}
|
||||
return strings.Compare(string(a.to), string(b.to))
|
||||
}
|
||||
|
||||
+208
-200
@@ -3,223 +3,231 @@ package relationship
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/google/go-cmp/cmp"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/anchore/syft/syft/artifact"
|
||||
"github.com/anchore/syft/syft/file"
|
||||
"github.com/anchore/syft/syft/pkg"
|
||||
)
|
||||
|
||||
func Test_newRelationshipIndex(t *testing.T) {
|
||||
from := fakeIdentifiable{id: "from"}
|
||||
to := fakeIdentifiable{id: "to"}
|
||||
tests := []struct {
|
||||
name string
|
||||
given []artifact.Relationship
|
||||
track []artifact.Relationship
|
||||
add []artifact.Relationship
|
||||
wantExisting []string
|
||||
wantAdditional []string
|
||||
}{
|
||||
{
|
||||
name: "empty",
|
||||
},
|
||||
{
|
||||
name: "tracks existing relationships",
|
||||
given: []artifact.Relationship{
|
||||
{
|
||||
From: from,
|
||||
To: to,
|
||||
Type: artifact.EvidentByRelationship,
|
||||
},
|
||||
},
|
||||
wantExisting: []string{"from [evident-by] to"},
|
||||
},
|
||||
{
|
||||
name: "deduplicate tracked relationships",
|
||||
given: []artifact.Relationship{
|
||||
{
|
||||
From: from,
|
||||
To: to,
|
||||
Type: artifact.EvidentByRelationship,
|
||||
},
|
||||
{
|
||||
From: from,
|
||||
To: to,
|
||||
Type: artifact.EvidentByRelationship,
|
||||
},
|
||||
{
|
||||
From: from,
|
||||
To: to,
|
||||
Type: artifact.EvidentByRelationship,
|
||||
},
|
||||
},
|
||||
track: []artifact.Relationship{
|
||||
{
|
||||
From: from,
|
||||
To: to,
|
||||
Type: artifact.EvidentByRelationship,
|
||||
},
|
||||
{
|
||||
From: from,
|
||||
To: to,
|
||||
Type: artifact.EvidentByRelationship,
|
||||
},
|
||||
},
|
||||
wantExisting: []string{"from [evident-by] to"},
|
||||
},
|
||||
{
|
||||
name: "deduplicate any input relationships",
|
||||
given: []artifact.Relationship{
|
||||
{
|
||||
From: from,
|
||||
To: to,
|
||||
Type: artifact.EvidentByRelationship,
|
||||
},
|
||||
{
|
||||
From: from,
|
||||
To: to,
|
||||
Type: artifact.EvidentByRelationship,
|
||||
},
|
||||
},
|
||||
track: []artifact.Relationship{
|
||||
{
|
||||
From: from,
|
||||
To: to,
|
||||
Type: artifact.EvidentByRelationship,
|
||||
},
|
||||
{
|
||||
From: from,
|
||||
To: to,
|
||||
Type: artifact.EvidentByRelationship,
|
||||
},
|
||||
},
|
||||
add: []artifact.Relationship{
|
||||
{
|
||||
From: from,
|
||||
To: to,
|
||||
Type: artifact.EvidentByRelationship,
|
||||
},
|
||||
{
|
||||
From: from,
|
||||
To: to,
|
||||
Type: artifact.EvidentByRelationship,
|
||||
},
|
||||
},
|
||||
wantExisting: []string{"from [evident-by] to"},
|
||||
},
|
||||
{
|
||||
name: "deduplicate any added relationships",
|
||||
add: []artifact.Relationship{
|
||||
{
|
||||
From: from,
|
||||
To: to,
|
||||
Type: artifact.EvidentByRelationship,
|
||||
},
|
||||
{
|
||||
From: from,
|
||||
To: to,
|
||||
Type: artifact.EvidentByRelationship,
|
||||
},
|
||||
},
|
||||
wantAdditional: []string{"from [evident-by] to"},
|
||||
},
|
||||
func Test_Index(t *testing.T) {
|
||||
p1 := pkg.Package{
|
||||
Name: "pkg-1",
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
idx := NewIndex(tt.given...)
|
||||
idx.TrackAll(tt.track...)
|
||||
idx.AddAll(tt.add...)
|
||||
diffRelationships(t, tt.wantExisting, idx.existing)
|
||||
diffRelationships(t, tt.wantAdditional, idx.additional)
|
||||
})
|
||||
p2 := pkg.Package{
|
||||
Name: "pkg-2",
|
||||
}
|
||||
p3 := pkg.Package{
|
||||
Name: "pkg-3",
|
||||
}
|
||||
c1 := file.Coordinates{
|
||||
RealPath: "/coords/1",
|
||||
}
|
||||
c2 := file.Coordinates{
|
||||
RealPath: "/coords/2",
|
||||
}
|
||||
|
||||
for _, p := range []*pkg.Package{&p1, &p2, &p3} {
|
||||
p.SetID()
|
||||
}
|
||||
|
||||
r1 := artifact.Relationship{
|
||||
From: p1,
|
||||
To: p2,
|
||||
Type: artifact.DependencyOfRelationship,
|
||||
}
|
||||
r2 := artifact.Relationship{
|
||||
From: p1,
|
||||
To: p3,
|
||||
Type: artifact.DependencyOfRelationship,
|
||||
}
|
||||
r3 := artifact.Relationship{
|
||||
From: p1,
|
||||
To: c1,
|
||||
Type: artifact.ContainsRelationship,
|
||||
}
|
||||
r4 := artifact.Relationship{
|
||||
From: p2,
|
||||
To: c2,
|
||||
Type: artifact.ContainsRelationship,
|
||||
}
|
||||
r5 := artifact.Relationship{
|
||||
From: p3,
|
||||
To: c2,
|
||||
Type: artifact.ContainsRelationship,
|
||||
}
|
||||
|
||||
dup := artifact.Relationship{
|
||||
From: p3,
|
||||
To: c2,
|
||||
Type: artifact.ContainsRelationship,
|
||||
}
|
||||
|
||||
idx := NewIndex(r1, r2, r3, r4, r5, dup)
|
||||
require.ElementsMatch(t, slice(r1, r2, r3, r4, r5), idx.All())
|
||||
|
||||
require.ElementsMatch(t, slice(r1, r4), idx.References(p2))
|
||||
require.ElementsMatch(t, slice(r4), idx.References(p2, artifact.ContainsRelationship))
|
||||
|
||||
require.ElementsMatch(t, slice(r1), idx.To(p2))
|
||||
require.ElementsMatch(t, []artifact.Relationship(nil), idx.To(p2, artifact.ContainsRelationship))
|
||||
|
||||
require.ElementsMatch(t, slice(r4), idx.From(p2))
|
||||
require.ElementsMatch(t, slice(r4), idx.From(p2, artifact.ContainsRelationship))
|
||||
}
|
||||
|
||||
func diffRelationships(t *testing.T, expected []string, actual []artifact.Relationship) {
|
||||
if d := cmp.Diff(expected, stringRelationships(actual)); d != "" {
|
||||
t.Errorf("unexpected relationships (-want, +got): %s", d)
|
||||
func Test_sortOrder(t *testing.T) {
|
||||
r1 := artifact.Relationship{
|
||||
From: id("1"),
|
||||
To: id("2"),
|
||||
Type: "1",
|
||||
}
|
||||
}
|
||||
|
||||
func stringRelationships(relationships []artifact.Relationship) []string {
|
||||
var result []string
|
||||
for _, r := range relationships {
|
||||
result = append(result, string(r.From.ID())+" ["+string(r.Type)+"] "+string(r.To.ID()))
|
||||
r2 := artifact.Relationship{
|
||||
From: id("2"),
|
||||
To: id("3"),
|
||||
Type: "1",
|
||||
}
|
||||
return result
|
||||
|
||||
}
|
||||
|
||||
func Test_relationshipIndex_track(t *testing.T) {
|
||||
from := fakeIdentifiable{id: "from"}
|
||||
to := fakeIdentifiable{id: "to"}
|
||||
relationship := artifact.Relationship{From: from, To: to, Type: artifact.EvidentByRelationship}
|
||||
tests := []struct {
|
||||
name string
|
||||
existing []artifact.Relationship
|
||||
given artifact.Relationship
|
||||
want bool
|
||||
}{
|
||||
{
|
||||
name: "track returns true for a new relationship",
|
||||
existing: []artifact.Relationship{},
|
||||
given: relationship,
|
||||
want: true,
|
||||
},
|
||||
{
|
||||
name: "track returns false for an existing relationship",
|
||||
existing: []artifact.Relationship{relationship},
|
||||
given: relationship,
|
||||
want: false,
|
||||
},
|
||||
r3 := artifact.Relationship{
|
||||
From: id("3"),
|
||||
To: id("4"),
|
||||
Type: "1",
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
i := NewIndex(tt.existing...)
|
||||
if got := i.Track(tt.given); got != tt.want {
|
||||
t.Errorf("track() = %v, want %v", got, tt.want)
|
||||
}
|
||||
})
|
||||
r4 := artifact.Relationship{
|
||||
From: id("1"),
|
||||
To: id("2"),
|
||||
Type: "2",
|
||||
}
|
||||
}
|
||||
|
||||
func Test_relationshipIndex_add(t *testing.T) {
|
||||
from := fakeIdentifiable{id: "from"}
|
||||
to := fakeIdentifiable{id: "to"}
|
||||
relationship := artifact.Relationship{From: from, To: to, Type: artifact.EvidentByRelationship}
|
||||
tests := []struct {
|
||||
name string
|
||||
existing []artifact.Relationship
|
||||
given artifact.Relationship
|
||||
want bool
|
||||
}{
|
||||
{
|
||||
name: "add returns true for a new relationship",
|
||||
existing: []artifact.Relationship{},
|
||||
given: relationship,
|
||||
want: true,
|
||||
},
|
||||
{
|
||||
name: "add returns false for an existing relationship",
|
||||
existing: []artifact.Relationship{relationship},
|
||||
given: relationship,
|
||||
want: false,
|
||||
},
|
||||
r5 := artifact.Relationship{
|
||||
From: id("2"),
|
||||
To: id("3"),
|
||||
Type: "2",
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
i := NewIndex(tt.existing...)
|
||||
if got := i.Add(tt.given); got != tt.want {
|
||||
t.Errorf("add() = %v, want %v", got, tt.want)
|
||||
}
|
||||
})
|
||||
dup := artifact.Relationship{
|
||||
From: id("2"),
|
||||
To: id("3"),
|
||||
Type: "2",
|
||||
}
|
||||
r6 := artifact.Relationship{
|
||||
From: id("2"),
|
||||
To: id("3"),
|
||||
Type: "3",
|
||||
}
|
||||
|
||||
idx := NewIndex(r5, r2, r6, r4, r1, r3, dup)
|
||||
require.EqualValues(t, slice(r1, r2, r3, r4, r5, r6), idx.All())
|
||||
|
||||
require.EqualValues(t, slice(r1, r4), idx.From(id("1")))
|
||||
|
||||
require.EqualValues(t, slice(r2, r5, r6), idx.To(id("3")))
|
||||
|
||||
rLast := artifact.Relationship{
|
||||
From: id("0"),
|
||||
To: id("3"),
|
||||
Type: "9999",
|
||||
}
|
||||
|
||||
rFirst := artifact.Relationship{
|
||||
From: id("0"),
|
||||
To: id("3"),
|
||||
Type: "1",
|
||||
}
|
||||
|
||||
rMid := artifact.Relationship{
|
||||
From: id("0"),
|
||||
To: id("1"),
|
||||
Type: "2",
|
||||
}
|
||||
|
||||
idx.Add(rLast, rFirst, rMid)
|
||||
|
||||
require.EqualValues(t, slice(rFirst, r1, r2, r3, rMid, r4, r5, r6, rLast), idx.All())
|
||||
|
||||
require.EqualValues(t, slice(rFirst, r2, r5, r6, rLast), idx.To(id("3")))
|
||||
}
|
||||
|
||||
type fakeIdentifiable struct {
|
||||
id string
|
||||
func Test_Coordinates(t *testing.T) {
|
||||
p1 := pkg.Package{
|
||||
Name: "pkg-1",
|
||||
}
|
||||
p2 := pkg.Package{
|
||||
Name: "pkg-2",
|
||||
}
|
||||
p3 := pkg.Package{
|
||||
Name: "pkg-3",
|
||||
}
|
||||
c1 := file.Coordinates{
|
||||
RealPath: "/coords/1",
|
||||
}
|
||||
c2 := file.Coordinates{
|
||||
RealPath: "/coords/2",
|
||||
}
|
||||
c3 := file.Coordinates{
|
||||
RealPath: "/coords/3",
|
||||
}
|
||||
c4 := file.Coordinates{
|
||||
RealPath: "/coords/4",
|
||||
}
|
||||
|
||||
for _, p := range []*pkg.Package{&p1, &p2, &p3} {
|
||||
p.SetID()
|
||||
}
|
||||
|
||||
r1 := artifact.Relationship{
|
||||
From: p1,
|
||||
To: p2,
|
||||
Type: artifact.DependencyOfRelationship,
|
||||
}
|
||||
r2 := artifact.Relationship{
|
||||
From: p1,
|
||||
To: p3,
|
||||
Type: artifact.DependencyOfRelationship,
|
||||
}
|
||||
r3 := artifact.Relationship{
|
||||
From: p1,
|
||||
To: c1,
|
||||
Type: artifact.ContainsRelationship,
|
||||
}
|
||||
r4 := artifact.Relationship{
|
||||
From: p2,
|
||||
To: c2,
|
||||
Type: artifact.ContainsRelationship,
|
||||
}
|
||||
r5 := artifact.Relationship{
|
||||
From: p3,
|
||||
To: c1,
|
||||
Type: artifact.ContainsRelationship,
|
||||
}
|
||||
r6 := artifact.Relationship{
|
||||
From: p3,
|
||||
To: c2,
|
||||
Type: artifact.ContainsRelationship,
|
||||
}
|
||||
r7 := artifact.Relationship{
|
||||
From: c1,
|
||||
To: c3,
|
||||
Type: artifact.ContainsRelationship,
|
||||
}
|
||||
r8 := artifact.Relationship{
|
||||
From: c3,
|
||||
To: c4,
|
||||
Type: artifact.ContainsRelationship,
|
||||
}
|
||||
|
||||
idx := NewIndex(r1, r2, r3, r4, r5, r6, r7, r8)
|
||||
|
||||
got := idx.Coordinates(p1)
|
||||
require.ElementsMatch(t, slice(c1), got)
|
||||
|
||||
got = idx.Coordinates(p3)
|
||||
require.ElementsMatch(t, slice(c1, c2), got)
|
||||
}
|
||||
|
||||
func (f fakeIdentifiable) ID() artifact.ID {
|
||||
return artifact.ID(f.id)
|
||||
type id string
|
||||
|
||||
func (i id) ID() artifact.ID {
|
||||
return artifact.ID(i)
|
||||
}
|
||||
|
||||
func slice[T any](values ...T) []T {
|
||||
return values
|
||||
}
|
||||
|
||||
@@ -7,3 +7,12 @@ For this reason we've included a copy of all schemas needed to validate `syft` o
|
||||
to reference local copies of dependent schemas.
|
||||
|
||||
You can get the latest schemas from the [CycloneDX specifications repo](https://github.com/CycloneDX/specification/tree/master/schema).
|
||||
|
||||
When the spec version is bumped an approach to determining prior modifications is to compare the
|
||||
prior spec version (e.g. if updating to 1.7, compare the files in this directory against the 1.6
|
||||
equivalents).
|
||||
|
||||
One can also update the schemas and observe the errors in order to make the necessary updates.
|
||||
At the time of writing, the cyclonedx.xsd needed modifications to link to the local spdx.xsd,
|
||||
and also to changes the minOccurs for a license tag to 0. (The json schema does not require
|
||||
modification for the generated file to lint properly, but can simply be copy/pasted).
|
||||
|
||||
+2104
-230
File diff suppressed because one or more lines are too long
+2918
-92
File diff suppressed because it is too large
Load Diff
+126
-1
@@ -2,7 +2,7 @@
|
||||
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
|
||||
elementFormDefault="qualified"
|
||||
targetNamespace="http://cyclonedx.org/schema/spdx"
|
||||
version="1.0-3.23">
|
||||
version="1.0-3.24.0">
|
||||
|
||||
<xs:simpleType name="licenseId">
|
||||
<xs:restriction base="xs:string">
|
||||
@@ -12,6 +12,11 @@
|
||||
<xs:documentation>BSD Zero Clause License</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:enumeration>
|
||||
<xs:enumeration value="3D-Slicer-1.0">
|
||||
<xs:annotation>
|
||||
<xs:documentation>3D Slicer License v1.0</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:enumeration>
|
||||
<xs:enumeration value="AAL">
|
||||
<xs:annotation>
|
||||
<xs:documentation>Attribution Assurance License</xs:documentation>
|
||||
@@ -117,6 +122,11 @@
|
||||
<xs:documentation>Aladdin Free Public License</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:enumeration>
|
||||
<xs:enumeration value="AMD-newlib">
|
||||
<xs:annotation>
|
||||
<xs:documentation>AMD newlib License</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:enumeration>
|
||||
<xs:enumeration value="AMDPLPA">
|
||||
<xs:annotation>
|
||||
<xs:documentation>AMD's plpa_map.c License</xs:documentation>
|
||||
@@ -147,6 +157,11 @@
|
||||
<xs:documentation>ANTLR Software Rights Notice with license fallback</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:enumeration>
|
||||
<xs:enumeration value="any-OSI">
|
||||
<xs:annotation>
|
||||
<xs:documentation>Any OSI License</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:enumeration>
|
||||
<xs:enumeration value="Apache-1.0">
|
||||
<xs:annotation>
|
||||
<xs:documentation>Apache License 1.0</xs:documentation>
|
||||
@@ -322,6 +337,11 @@
|
||||
<xs:documentation>BSD 2-Clause - Ian Darwin variant</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:enumeration>
|
||||
<xs:enumeration value="BSD-2-Clause-first-lines">
|
||||
<xs:annotation>
|
||||
<xs:documentation>BSD 2-Clause - first lines requirement</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:enumeration>
|
||||
<xs:enumeration value="BSD-2-Clause-FreeBSD">
|
||||
<xs:annotation>
|
||||
<xs:documentation>BSD 2-Clause FreeBSD License</xs:documentation>
|
||||
@@ -522,6 +542,11 @@
|
||||
<xs:documentation>Caldera License (without preamble)</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:enumeration>
|
||||
<xs:enumeration value="Catharon">
|
||||
<xs:annotation>
|
||||
<xs:documentation>Catharon License</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:enumeration>
|
||||
<xs:enumeration value="CATOSL-1.1">
|
||||
<xs:annotation>
|
||||
<xs:documentation>Computer Associates Trusted Open Source License 1.1</xs:documentation>
|
||||
@@ -1002,6 +1027,11 @@
|
||||
<xs:documentation>curl License</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:enumeration>
|
||||
<xs:enumeration value="cve-tou">
|
||||
<xs:annotation>
|
||||
<xs:documentation>Common Vulnerability Enumeration ToU License</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:enumeration>
|
||||
<xs:enumeration value="D-FSL-1.0">
|
||||
<xs:annotation>
|
||||
<xs:documentation>Deutsche Freie Software Lizenz</xs:documentation>
|
||||
@@ -1482,6 +1512,11 @@
|
||||
<xs:documentation>gtkbook License</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:enumeration>
|
||||
<xs:enumeration value="Gutmann">
|
||||
<xs:annotation>
|
||||
<xs:documentation>Gutmann License</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:enumeration>
|
||||
<xs:enumeration value="HaskellReport">
|
||||
<xs:annotation>
|
||||
<xs:documentation>Haskell Language Report License</xs:documentation>
|
||||
@@ -1532,11 +1567,21 @@
|
||||
<xs:documentation>HPND with US Government export control warning</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:enumeration>
|
||||
<xs:enumeration value="HPND-export-US-acknowledgement">
|
||||
<xs:annotation>
|
||||
<xs:documentation>HPND with US Government export control warning and acknowledgment</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:enumeration>
|
||||
<xs:enumeration value="HPND-export-US-modify">
|
||||
<xs:annotation>
|
||||
<xs:documentation>HPND with US Government export control warning and modification rqmt</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:enumeration>
|
||||
<xs:enumeration value="HPND-export2-US">
|
||||
<xs:annotation>
|
||||
<xs:documentation>HPND with US Government export control and 2 disclaimers</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:enumeration>
|
||||
<xs:enumeration value="HPND-Fenneberg-Livingston">
|
||||
<xs:annotation>
|
||||
<xs:documentation>Historical Permission Notice and Disclaimer - Fenneberg-Livingston variant</xs:documentation>
|
||||
@@ -1547,6 +1592,11 @@
|
||||
<xs:documentation>Historical Permission Notice and Disclaimer - INRIA-IMAG variant</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:enumeration>
|
||||
<xs:enumeration value="HPND-Intel">
|
||||
<xs:annotation>
|
||||
<xs:documentation>Historical Permission Notice and Disclaimer - Intel variant</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:enumeration>
|
||||
<xs:enumeration value="HPND-Kevlin-Henney">
|
||||
<xs:annotation>
|
||||
<xs:documentation>Historical Permission Notice and Disclaimer - Kevlin Henney variant</xs:documentation>
|
||||
@@ -1557,6 +1607,11 @@
|
||||
<xs:documentation>Historical Permission Notice and Disclaimer - Markus Kuhn variant</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:enumeration>
|
||||
<xs:enumeration value="HPND-merchantability-variant">
|
||||
<xs:annotation>
|
||||
<xs:documentation>Historical Permission Notice and Disclaimer - merchantability variant</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:enumeration>
|
||||
<xs:enumeration value="HPND-MIT-disclaimer">
|
||||
<xs:annotation>
|
||||
<xs:documentation>Historical Permission Notice and Disclaimer with MIT disclaimer</xs:documentation>
|
||||
@@ -1587,11 +1642,21 @@
|
||||
<xs:documentation>HPND sell variant with MIT disclaimer</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:enumeration>
|
||||
<xs:enumeration value="HPND-sell-variant-MIT-disclaimer-rev">
|
||||
<xs:annotation>
|
||||
<xs:documentation>HPND sell variant with MIT disclaimer - reverse</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:enumeration>
|
||||
<xs:enumeration value="HPND-UC">
|
||||
<xs:annotation>
|
||||
<xs:documentation>Historical Permission Notice and Disclaimer - University of California variant</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:enumeration>
|
||||
<xs:enumeration value="HPND-UC-export-US">
|
||||
<xs:annotation>
|
||||
<xs:documentation>Historical Permission Notice and Disclaimer - University of California, US export warning</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:enumeration>
|
||||
<xs:enumeration value="HTMLTIDY">
|
||||
<xs:annotation>
|
||||
<xs:documentation>HTML Tidy License</xs:documentation>
|
||||
@@ -2027,6 +2092,11 @@
|
||||
<xs:documentation>MIT Festival Variant</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:enumeration>
|
||||
<xs:enumeration value="MIT-Khronos-old">
|
||||
<xs:annotation>
|
||||
<xs:documentation>MIT Khronos - old variant</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:enumeration>
|
||||
<xs:enumeration value="MIT-Modern-Variant">
|
||||
<xs:annotation>
|
||||
<xs:documentation>MIT License Modern Variant</xs:documentation>
|
||||
@@ -2162,11 +2232,21 @@
|
||||
<xs:documentation>Net Boolean Public License v1</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:enumeration>
|
||||
<xs:enumeration value="NCBI-PD">
|
||||
<xs:annotation>
|
||||
<xs:documentation>NCBI Public Domain Notice</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:enumeration>
|
||||
<xs:enumeration value="NCGL-UK-2.0">
|
||||
<xs:annotation>
|
||||
<xs:documentation>Non-Commercial Government Licence</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:enumeration>
|
||||
<xs:enumeration value="NCL">
|
||||
<xs:annotation>
|
||||
<xs:documentation>NCL Source Code License</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:enumeration>
|
||||
<xs:enumeration value="NCSA">
|
||||
<xs:annotation>
|
||||
<xs:documentation>University of Illinois/NCSA Open Source License</xs:documentation>
|
||||
@@ -2282,6 +2362,11 @@
|
||||
<xs:documentation>Open Use of Data Agreement v1.0</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:enumeration>
|
||||
<xs:enumeration value="OAR">
|
||||
<xs:annotation>
|
||||
<xs:documentation>OAR License</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:enumeration>
|
||||
<xs:enumeration value="OCCT-PL">
|
||||
<xs:annotation>
|
||||
<xs:documentation>Open CASCADE Technology Public License</xs:documentation>
|
||||
@@ -2562,6 +2647,11 @@
|
||||
<xs:documentation>Pixar License</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:enumeration>
|
||||
<xs:enumeration value="pkgconf">
|
||||
<xs:annotation>
|
||||
<xs:documentation>pkgconf License</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:enumeration>
|
||||
<xs:enumeration value="Plexus">
|
||||
<xs:annotation>
|
||||
<xs:documentation>Plexus Classworlds License</xs:documentation>
|
||||
@@ -2587,6 +2677,11 @@
|
||||
<xs:documentation>PostgreSQL License</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:enumeration>
|
||||
<xs:enumeration value="PPL">
|
||||
<xs:annotation>
|
||||
<xs:documentation>Peer Production License</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:enumeration>
|
||||
<xs:enumeration value="PSF-2.0">
|
||||
<xs:annotation>
|
||||
<xs:documentation>Python Software Foundation License 2.0</xs:documentation>
|
||||
@@ -2862,6 +2957,11 @@
|
||||
<xs:documentation>Sun PPP License</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:enumeration>
|
||||
<xs:enumeration value="Sun-PPP-2000">
|
||||
<xs:annotation>
|
||||
<xs:documentation>Sun PPP License (2000)</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:enumeration>
|
||||
<xs:enumeration value="SunPro">
|
||||
<xs:annotation>
|
||||
<xs:documentation>SunPro License</xs:documentation>
|
||||
@@ -2907,6 +3007,11 @@
|
||||
<xs:documentation>Transitive Grace Period Public Licence 1.0</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:enumeration>
|
||||
<xs:enumeration value="threeparttable">
|
||||
<xs:annotation>
|
||||
<xs:documentation>threeparttable License</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:enumeration>
|
||||
<xs:enumeration value="TMate">
|
||||
<xs:annotation>
|
||||
<xs:documentation>TMate Open Source License</xs:documentation>
|
||||
@@ -3132,6 +3237,11 @@
|
||||
<xs:documentation>XSkat License</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:enumeration>
|
||||
<xs:enumeration value="xzoom">
|
||||
<xs:annotation>
|
||||
<xs:documentation>xzoom License</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:enumeration>
|
||||
<xs:enumeration value="YPL-1.0">
|
||||
<xs:annotation>
|
||||
<xs:documentation>Yahoo! Public License v1.0</xs:documentation>
|
||||
@@ -3203,6 +3313,11 @@
|
||||
<xs:documentation>Asterisk exception</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:enumeration>
|
||||
<xs:enumeration value="Asterisk-linking-protocols-exception">
|
||||
<xs:annotation>
|
||||
<xs:documentation>Asterisk linking protocols exception</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:enumeration>
|
||||
<xs:enumeration value="Autoconf-exception-2.0">
|
||||
<xs:annotation>
|
||||
<xs:documentation>Autoconf exception 2.0</xs:documentation>
|
||||
@@ -3438,6 +3553,11 @@
|
||||
<xs:documentation>OpenVPN OpenSSL Exception</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:enumeration>
|
||||
<xs:enumeration value="PCRE2-exception">
|
||||
<xs:annotation>
|
||||
<xs:documentation>PCRE2 exception</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:enumeration>
|
||||
<xs:enumeration value="PS-or-PDF-font-exception-20170817">
|
||||
<xs:annotation>
|
||||
<xs:documentation>PS/PDF font exception (2017-08-17)</xs:documentation>
|
||||
@@ -3463,6 +3583,11 @@
|
||||
<xs:documentation>Qwt exception 1.0</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:enumeration>
|
||||
<xs:enumeration value="RRDtool-FLOSS-exception-2.0">
|
||||
<xs:annotation>
|
||||
<xs:documentation>RRDtool FLOSS exception 2.0</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:enumeration>
|
||||
<xs:enumeration value="SANE-exception">
|
||||
<xs:annotation>
|
||||
<xs:documentation>SANE Exception</xs:documentation>
|
||||
|
||||
@@ -64,6 +64,28 @@ func TestBySourceThenSpecificity(t *testing.T) {
|
||||
Must("cpe:2.3:a:some:package:*:*:*:*:*:*:*:*", "some-unknown-source"),
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "lexical sorting on equal sources puts escaped characters later",
|
||||
input: []CPE{
|
||||
Must("cpe:2.3:a:jenkins:pipeline\\\\:_supporting_apis:865.v43e78cc44e0d:*:*:*:*:jenkins:*:*", "nvd-cpe-dictionary"),
|
||||
Must("cpe:2.3:a:jenkins:pipeline_supporting_apis:865.v43e78cc44e0d:*:*:*:*:jenkins:*:*", "nvd-cpe-dictionary"),
|
||||
},
|
||||
want: []CPE{
|
||||
Must("cpe:2.3:a:jenkins:pipeline_supporting_apis:865.v43e78cc44e0d:*:*:*:*:jenkins:*:*", "nvd-cpe-dictionary"),
|
||||
Must("cpe:2.3:a:jenkins:pipeline\\\\:_supporting_apis:865.v43e78cc44e0d:*:*:*:*:jenkins:*:*", "nvd-cpe-dictionary"),
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "lexical sorting on equal sources puts more specific attributes earlier",
|
||||
input: []CPE{
|
||||
Must("cpe:2.3:a:jenkins:mailer:472.vf7c289a_4b_420:*:*:*:*:*:*:*", "nvd-cpe-dictionary"),
|
||||
Must("cpe:2.3:a:jenkins:mailer:472.vf7c289a_4b_420:*:*:*:*:jenkins:*:*", "nvd-cpe-dictionary"),
|
||||
},
|
||||
want: []CPE{
|
||||
Must("cpe:2.3:a:jenkins:mailer:472.vf7c289a_4b_420:*:*:*:*:jenkins:*:*", "nvd-cpe-dictionary"),
|
||||
Must("cpe:2.3:a:jenkins:mailer:472.vf7c289a_4b_420:*:*:*:*:*:*:*", "nvd-cpe-dictionary"),
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
|
||||
@@ -16,6 +16,7 @@ import (
|
||||
"github.com/anchore/packageurl-go"
|
||||
"github.com/anchore/syft/internal/log"
|
||||
"github.com/anchore/syft/internal/mimetype"
|
||||
"github.com/anchore/syft/internal/relationship"
|
||||
"github.com/anchore/syft/internal/spdxlicense"
|
||||
"github.com/anchore/syft/syft/artifact"
|
||||
"github.com/anchore/syft/syft/file"
|
||||
@@ -45,9 +46,10 @@ const (
|
||||
func ToFormatModel(s sbom.SBOM) *spdx.Document {
|
||||
name, namespace := helpers.DocumentNameAndNamespace(s.Source, s.Descriptor)
|
||||
|
||||
packages := toPackages(s.Artifacts.Packages, s)
|
||||
rels := relationship.NewIndex(s.Relationships...)
|
||||
packages := toPackages(rels, s.Artifacts.Packages, s)
|
||||
|
||||
relationships := toRelationships(s.RelationshipsSorted())
|
||||
allRelationships := toRelationships(rels.All())
|
||||
|
||||
// for valid SPDX we need a document describes relationship
|
||||
describesID := spdx.ElementID("DOCUMENT")
|
||||
@@ -57,7 +59,7 @@ func ToFormatModel(s sbom.SBOM) *spdx.Document {
|
||||
describesID = rootPackage.PackageSPDXIdentifier
|
||||
|
||||
// add all relationships from the document root to all other packages
|
||||
relationships = append(relationships, toRootRelationships(rootPackage, packages)...)
|
||||
allRelationships = append(allRelationships, toRootRelationships(rootPackage, packages)...)
|
||||
|
||||
// append the root package
|
||||
packages = append(packages, rootPackage)
|
||||
@@ -75,7 +77,7 @@ func ToFormatModel(s sbom.SBOM) *spdx.Document {
|
||||
}
|
||||
|
||||
// add the root document relationship
|
||||
relationships = append(relationships, documentDescribesRelationship)
|
||||
allRelationships = append(allRelationships, documentDescribesRelationship)
|
||||
|
||||
return &spdx.Document{
|
||||
// 6.1: SPDX Version; should be in the format "SPDX-x.x"
|
||||
@@ -150,7 +152,7 @@ func ToFormatModel(s sbom.SBOM) *spdx.Document {
|
||||
},
|
||||
Packages: packages,
|
||||
Files: toFiles(s),
|
||||
Relationships: relationships,
|
||||
Relationships: allRelationships,
|
||||
OtherLicenses: toOtherLicenses(s.Artifacts.Packages),
|
||||
}
|
||||
}
|
||||
@@ -302,7 +304,7 @@ func toSPDXID(identifiable artifact.Identifiable) spdx.ElementID {
|
||||
// packages populates all Package Information from the package Collection (see https://spdx.github.io/spdx-spec/3-package-information/)
|
||||
//
|
||||
//nolint:funlen
|
||||
func toPackages(catalog *pkg.Collection, sbom sbom.SBOM) (results []*spdx.Package) {
|
||||
func toPackages(rels *relationship.Index, catalog *pkg.Collection, sbom sbom.SBOM) (results []*spdx.Package) {
|
||||
for _, p := range catalog.Sorted() {
|
||||
// name should be guaranteed to be unique, but semantically useful and stable
|
||||
id := toSPDXID(p)
|
||||
@@ -318,7 +320,7 @@ func toPackages(catalog *pkg.Collection, sbom sbom.SBOM) (results []*spdx.Packag
|
||||
// 2. syft has generated a sha1 digest for the package's contents
|
||||
packageChecksums, filesAnalyzed := toPackageChecksums(p)
|
||||
|
||||
packageVerificationCode := newPackageVerificationCode(p, sbom)
|
||||
packageVerificationCode := newPackageVerificationCode(rels, p, sbom)
|
||||
if packageVerificationCode != nil {
|
||||
filesAnalyzed = true
|
||||
}
|
||||
@@ -744,12 +746,12 @@ func toOtherLicenses(catalog *pkg.Collection) []*spdx.OtherLicense {
|
||||
// f file is an "excludes" file, skip it /* exclude SPDX analysis file(s) */
|
||||
// see: https://spdx.github.io/spdx-spec/v2.3/package-information/#79-package-verification-code-field
|
||||
// the above link contains the SPDX algorithm for a package verification code
|
||||
func newPackageVerificationCode(p pkg.Package, sbom sbom.SBOM) *spdx.PackageVerificationCode {
|
||||
func newPackageVerificationCode(rels *relationship.Index, p pkg.Package, sbom sbom.SBOM) *spdx.PackageVerificationCode {
|
||||
// key off of the contains relationship;
|
||||
// spdx validator will fail if a package claims to contain a file but no sha1 provided
|
||||
// if a sha1 for a file is provided then the validator will fail if the package does not have
|
||||
// a package verification code
|
||||
coordinates := sbom.CoordinatesForPackage(p, artifact.ContainsRelationship)
|
||||
coordinates := rels.Coordinates(p, artifact.ContainsRelationship)
|
||||
var digests []file.Digest
|
||||
for _, c := range coordinates {
|
||||
digest := sbom.Artifacts.FileDigests[c]
|
||||
|
||||
@@ -12,6 +12,7 @@ import (
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/anchore/syft/internal/relationship"
|
||||
"github.com/anchore/syft/syft/artifact"
|
||||
"github.com/anchore/syft/syft/file"
|
||||
"github.com/anchore/syft/syft/format/internal/spdxutil/helpers"
|
||||
@@ -665,7 +666,7 @@ func Test_H1Digest(t *testing.T) {
|
||||
for _, test := range tests {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
catalog := pkg.NewCollection(test.pkg)
|
||||
pkgs := toPackages(catalog, s)
|
||||
pkgs := toPackages(relationship.NewIndex(), catalog, s)
|
||||
require.Len(t, pkgs, 1)
|
||||
for _, p := range pkgs {
|
||||
if test.expectedDigest == "" {
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
{
|
||||
"$schema": "http://cyclonedx.org/schema/bom-1.5.schema.json",
|
||||
"bomFormat": "CycloneDX",
|
||||
"specVersion": "1.6",
|
||||
"serialNumber": "urn:uuid:5208fea9-73dd-4624-b596-69fddccdb9e7",
|
||||
"version": 1,
|
||||
"metadata": {
|
||||
"timestamp": "2023-09-29T12:02:02-04:00",
|
||||
"tools": [
|
||||
{
|
||||
"vendor": "anchore",
|
||||
"name": "syft",
|
||||
"version": "[not provided]"
|
||||
}
|
||||
],
|
||||
"component": {
|
||||
"bom-ref": "a0ff99a6af10f11f",
|
||||
"type": "file",
|
||||
"name": "go.mod",
|
||||
"version": "sha256:sha256:dc333f342905248a52e424d8dfd061251d01867d01a4f9d7397144a775ff9ebd"
|
||||
}
|
||||
},
|
||||
"components": [
|
||||
{
|
||||
"bom-ref": "pkg:golang/github.com/wagoodman/go-partybus@v0.0.0-20230516145632-8ccac152c651?package-id=2ff71a67fb024c86",
|
||||
"type": "library",
|
||||
"name": "github.com/wagoodman/go-partybus",
|
||||
"version": "v0.0.0-20230516145632-8ccac152c651",
|
||||
"cpe": "cpe:2.3:a:wagoodman:go-partybus:v0.0.0-20230516145632-8ccac152c651:*:*:*:*:*:*:*",
|
||||
"purl": "pkg:golang/github.com/wagoodman/go-partybus@v0.0.0-20230516145632-8ccac152c651",
|
||||
"properties": [
|
||||
{
|
||||
"name": "syft:package:foundBy",
|
||||
"value": "go-module-file-cataloger"
|
||||
},
|
||||
{
|
||||
"name": "syft:package:language",
|
||||
"value": "go"
|
||||
},
|
||||
{
|
||||
"name": "syft:package:metadataType",
|
||||
"value": "GolangModMetadata"
|
||||
},
|
||||
{
|
||||
"name": "syft:package:type",
|
||||
"value": "go-module"
|
||||
},
|
||||
{
|
||||
"name": "syft:cpe23",
|
||||
"value": "cpe:2.3:a:wagoodman:go_partybus:v0.0.0-20230516145632-8ccac152c651:*:*:*:*:*:*:*"
|
||||
},
|
||||
{
|
||||
"name": "syft:location:0:path",
|
||||
"value": "/go.mod"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
{
|
||||
"bomFormat": "CycloneDX",
|
||||
"specVersion": "1.6",
|
||||
"version": 1,
|
||||
"components": [
|
||||
{
|
||||
"type": "library",
|
||||
"group": "io.netty",
|
||||
"name": "netty-codec-http2",
|
||||
"version": "4.1.73.Final",
|
||||
"properties": [
|
||||
{
|
||||
"name": "syft:cpe23",
|
||||
"value": "cpe:2.3:a:codec:codec:4.1.73.Final:*:*:*:*:*:*:*"
|
||||
},
|
||||
{
|
||||
"name": "syft:cpe23",
|
||||
"value": "cpe:2.3:a:codec:netty-codec-http2:4.1.73.Final:*:*:*:*:*:*:*"
|
||||
},
|
||||
{
|
||||
"name": "syft:cpe23",
|
||||
"value": "cpe:2.3:a:codec:netty_codec_http2:4.1.73.Final:*:*:*:*:*:*:*"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"serialNumber": "urn:uuid:3eb5ec7a-cb05-4339-b873-e27b1c1efaba"
|
||||
}
|
||||
+2
-2
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"$schema": "http://cyclonedx.org/schema/bom-1.5.schema.json",
|
||||
"$schema": "http://cyclonedx.org/schema/bom-1.6.schema.json",
|
||||
"bomFormat": "CycloneDX",
|
||||
"specVersion": "1.5",
|
||||
"specVersion": "1.6",
|
||||
"serialNumber": "urn:uuid:redacted",
|
||||
"version": 1,
|
||||
"metadata": {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"$schema": "http://cyclonedx.org/schema/bom-1.5.schema.json",
|
||||
"$schema": "http://cyclonedx.org/schema/bom-1.6.schema.json",
|
||||
"bomFormat": "CycloneDX",
|
||||
"specVersion": "1.5",
|
||||
"specVersion": "1.6",
|
||||
"serialNumber": "urn:uuid:redacted",
|
||||
"version": 1,
|
||||
"metadata": {
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<bom xmlns="http://cyclonedx.org/schema/bom/1.6" serialNumber="urn:uuid:098e8516-ecd5-4130-9d5f-c32ba1ddb0dd" version="1">
|
||||
<metadata>
|
||||
<timestamp>2023-09-29T11:48:10-04:00</timestamp>
|
||||
<tools>
|
||||
<tool>
|
||||
<vendor>anchore</vendor>
|
||||
<name>syft</name>
|
||||
<version>[not provided]</version>
|
||||
</tool>
|
||||
</tools>
|
||||
<component bom-ref="a0ff99a6af10f11f" type="file">
|
||||
<name>go.mod</name>
|
||||
<version>sha256:sha256:dc333f342905248a52e424d8dfd061251d01867d01a4f9d7397144a775ff9ebd</version>
|
||||
</component>
|
||||
</metadata>
|
||||
<components>
|
||||
<component bom-ref="pkg:golang/github.com/wagoodman/go-partybus@v0.0.0-20230516145632-8ccac152c651?package-id=2ff71a67fb024c86" type="library">
|
||||
<name>github.com/wagoodman/go-partybus</name>
|
||||
<version>v0.0.0-20230516145632-8ccac152c651</version>
|
||||
<cpe>cpe:2.3:a:wagoodman:go-partybus:v0.0.0-20230516145632-8ccac152c651:*:*:*:*:*:*:*</cpe>
|
||||
<purl>pkg:golang/github.com/wagoodman/go-partybus@v0.0.0-20230516145632-8ccac152c651</purl>
|
||||
<properties>
|
||||
<property name="syft:package:foundBy">go-module-file-cataloger</property>
|
||||
<property name="syft:package:language">go</property>
|
||||
<property name="syft:package:metadataType">GolangModMetadata</property>
|
||||
<property name="syft:package:type">go-module</property>
|
||||
<property name="syft:cpe23">cpe:2.3:a:wagoodman:go_partybus:v0.0.0-20230516145632-8ccac152c651:*:*:*:*:*:*:*</property>
|
||||
<property name="syft:location:0:path">/go.mod</property>
|
||||
</properties>
|
||||
</component>
|
||||
</components>
|
||||
</bom>
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<bom xmlns="http://cyclonedx.org/schema/bom/1.5" serialNumber="redacted" version="1">
|
||||
<bom xmlns="http://cyclonedx.org/schema/bom/1.6" serialNumber="redacted" version="1">
|
||||
<metadata>
|
||||
<timestamp>redacted</timestamp>
|
||||
<tools>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<bom xmlns="http://cyclonedx.org/schema/bom/1.5" serialNumber="redacted" version="1">
|
||||
<bom xmlns="http://cyclonedx.org/schema/bom/1.6" serialNumber="redacted" version="1">
|
||||
<metadata>
|
||||
<timestamp>redacted</timestamp>
|
||||
<tools>
|
||||
|
||||
@@ -9,7 +9,7 @@ import (
|
||||
"github.com/anchore/syft/syft/sbom"
|
||||
)
|
||||
|
||||
const DefaultVersion = "1.5"
|
||||
const DefaultVersion = "1.6"
|
||||
|
||||
type Encoder struct {
|
||||
version cyclonedx.SpecVersion
|
||||
|
||||
@@ -19,6 +19,7 @@ func SupportedVersions(id sbom.FormatID) []string {
|
||||
"1.3",
|
||||
"1.4",
|
||||
"1.5",
|
||||
"1.6",
|
||||
}
|
||||
|
||||
if id != JSONFormatID {
|
||||
@@ -43,6 +44,8 @@ func SpecVersionFromString(v string) (cyclonedx.SpecVersion, error) {
|
||||
return cyclonedx.SpecVersion1_4, nil
|
||||
case "1.5":
|
||||
return cyclonedx.SpecVersion1_5, nil
|
||||
case "1.6":
|
||||
return cyclonedx.SpecVersion1_6, nil
|
||||
}
|
||||
return -1, fmt.Errorf("unsupported CycloneDX version %q", v)
|
||||
}
|
||||
@@ -61,6 +64,8 @@ func VersionFromSpecVersion(spec cyclonedx.SpecVersion) string {
|
||||
return "1.4"
|
||||
case cyclonedx.SpecVersion1_5:
|
||||
return "1.5"
|
||||
case cyclonedx.SpecVersion1_6:
|
||||
return "1.6"
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
@@ -22,6 +22,10 @@ func DownloadLocation(p pkg.Package) string {
|
||||
return NoneIfEmpty(metadata.URL)
|
||||
case pkg.NpmPackageLockEntry:
|
||||
return NoneIfEmpty(metadata.Resolved)
|
||||
case pkg.PhpComposerLockEntry:
|
||||
return NoneIfEmpty(metadata.Dist.URL)
|
||||
case pkg.PhpComposerInstalledEntry:
|
||||
return NoneIfEmpty(metadata.Dist.URL)
|
||||
}
|
||||
}
|
||||
return NOASSERTION
|
||||
|
||||
@@ -64,6 +64,50 @@ func Test_DownloadLocation(t *testing.T) {
|
||||
},
|
||||
expected: NONE,
|
||||
},
|
||||
{
|
||||
name: "from php installed.json",
|
||||
input: pkg.Package{
|
||||
Metadata: pkg.PhpComposerInstalledEntry{
|
||||
Dist: pkg.PhpComposerExternalReference{
|
||||
URL: "http://package-lock.test",
|
||||
},
|
||||
},
|
||||
},
|
||||
expected: "http://package-lock.test",
|
||||
},
|
||||
{
|
||||
name: "empty",
|
||||
input: pkg.Package{
|
||||
Metadata: pkg.PhpComposerInstalledEntry{
|
||||
Dist: pkg.PhpComposerExternalReference{
|
||||
URL: "",
|
||||
},
|
||||
},
|
||||
},
|
||||
expected: "NONE",
|
||||
},
|
||||
{
|
||||
name: "from php composer.lock",
|
||||
input: pkg.Package{
|
||||
Metadata: pkg.PhpComposerLockEntry{
|
||||
Dist: pkg.PhpComposerExternalReference{
|
||||
URL: "http://package-lock.test",
|
||||
},
|
||||
},
|
||||
},
|
||||
expected: "http://package-lock.test",
|
||||
},
|
||||
{
|
||||
name: "empty",
|
||||
input: pkg.Package{
|
||||
Metadata: pkg.PhpComposerLockEntry{
|
||||
Dist: pkg.PhpComposerExternalReference{
|
||||
URL: "",
|
||||
},
|
||||
},
|
||||
},
|
||||
expected: "NONE",
|
||||
},
|
||||
}
|
||||
for _, test := range tests {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
|
||||
@@ -48,6 +48,17 @@ func Test_Cataloger_PositiveCases(t *testing.T) {
|
||||
Metadata: metadata("arangodb-binary"),
|
||||
},
|
||||
},
|
||||
{
|
||||
logicalFixture: "arangodb/3.12.0-2/linux-amd64",
|
||||
expected: pkg.Package{
|
||||
Name: "arangodb",
|
||||
Version: "3.12.0-2",
|
||||
Type: "binary",
|
||||
PURL: "pkg:generic/arangodb@3.12.0-2",
|
||||
Locations: locations("arangosh"),
|
||||
Metadata: metadata("arangodb-binary"),
|
||||
},
|
||||
},
|
||||
{
|
||||
logicalFixture: "postgres/15beta4/linux-amd64",
|
||||
expected: pkg.Package{
|
||||
@@ -193,6 +204,17 @@ func Test_Cataloger_PositiveCases(t *testing.T) {
|
||||
Metadata: metadata("traefik-binary"),
|
||||
},
|
||||
},
|
||||
{
|
||||
logicalFixture: "traefik/3.0.4/linux-riscv64",
|
||||
expected: pkg.Package{
|
||||
Name: "traefik",
|
||||
Version: "3.0.4",
|
||||
Type: "binary",
|
||||
PURL: "pkg:generic/traefik@3.0.4",
|
||||
Locations: locations("traefik"),
|
||||
Metadata: metadata("traefik-binary"),
|
||||
},
|
||||
},
|
||||
{
|
||||
logicalFixture: "memcached/1.6.18/linux-amd64",
|
||||
expected: pkg.Package{
|
||||
@@ -896,6 +918,17 @@ func Test_Cataloger_PositiveCases(t *testing.T) {
|
||||
Metadata: metadata("erlang-library"),
|
||||
},
|
||||
},
|
||||
{
|
||||
logicalFixture: "erlang/27.0/linux-amd64",
|
||||
expected: pkg.Package{
|
||||
Name: "erlang",
|
||||
Version: "27.0",
|
||||
Type: "binary",
|
||||
PURL: "pkg:generic/erlang@27.0",
|
||||
Locations: locations("beam.smp"),
|
||||
Metadata: metadata("erlang-alpine-binary"),
|
||||
},
|
||||
},
|
||||
{
|
||||
logicalFixture: "nginx/1.25.1/linux-amd64",
|
||||
expected: pkg.Package{
|
||||
|
||||
@@ -263,7 +263,8 @@ func DefaultClassifiers() []Classifier {
|
||||
EvidenceMatcher: FileContentsVersionMatcher(
|
||||
// [NUL]v1.7.34[NUL]
|
||||
// [NUL]2.9.6[NUL]
|
||||
`(?m)(\x00|\x{FFFD})v?(?P<version>[0-9]+\.[0-9]+\.[0-9]+(-alpha[0-9]|-beta[0-9]|-rc[0-9])?)\x00`),
|
||||
// 3.0.4[NUL]
|
||||
`(?m)(\x00|\x{FFFD})?v?(?P<version>[0-9]+\.[0-9]+\.[0-9]+(-alpha[0-9]|-beta[0-9]|-rc[0-9])?)\x00`),
|
||||
Package: "traefik",
|
||||
PURL: mustPURL("pkg:generic/traefik@version"),
|
||||
CPEs: singleCPE("cpe:2.3:a:traefik:traefik:*:*:*:*:*:*:*:*"),
|
||||
@@ -272,7 +273,7 @@ func DefaultClassifiers() []Classifier {
|
||||
Class: "arangodb-binary",
|
||||
FileGlob: "**/arangosh",
|
||||
EvidenceMatcher: FileContentsVersionMatcher(
|
||||
`(?m)ArangoDB\s\x00*(?P<version>[0-9]+\.[0-9]+\.[0-9]+)\s\[linux\]`),
|
||||
`(?m)\x00*(?P<version>[0-9]+\.[0-9]+\.[0-9]+(-[0-9]+)?)\s\[linux\]`),
|
||||
Package: "arangodb",
|
||||
PURL: mustPURL("pkg:generic/arangodb@version"),
|
||||
CPEs: singleCPE("cpe:2.3:a:arangodb:arangodb:*:*:*:*:*:*:*:*"),
|
||||
@@ -393,6 +394,23 @@ func DefaultClassifiers() []Classifier {
|
||||
PURL: mustPURL("pkg:generic/erlang@version"),
|
||||
CPEs: singleCPE("cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*"),
|
||||
},
|
||||
{
|
||||
Class: "erlang-alpine-binary",
|
||||
FileGlob: "**/beam.smp",
|
||||
EvidenceMatcher: evidenceMatchers(
|
||||
FileContentsVersionMatcher(
|
||||
// <artificial>[NUL]/usr/src/otp_src_25.3.2.6/erts/
|
||||
`(?m)/src/otp_src_(?P<version>[0-9]+\.[0-9]+(\.[0-9]+){0,2}(-rc[0-9])?)/erts/`,
|
||||
),
|
||||
FileContentsVersionMatcher(
|
||||
// <artificial>[NUL]/usr/local/src/otp-25.3.2.7/erts/
|
||||
`(?m)/usr/local/src/otp-(?P<version>[0-9]+\.[0-9]+(\.[0-9]+){0,2}(-rc[0-9])?)/erts/`,
|
||||
),
|
||||
),
|
||||
Package: "erlang",
|
||||
PURL: mustPURL("pkg:generic/erlang@version"),
|
||||
CPEs: singleCPE("cpe:2.3:a:erlang:erlang\\/otp:*:*:*:*:*:*:*:*"),
|
||||
},
|
||||
{
|
||||
Class: "erlang-library",
|
||||
FileGlob: "**/liberts_internal.a",
|
||||
|
||||
@@ -13,7 +13,7 @@ func newELFPackage(metadata elfBinaryPackageNotes, locations file.LocationSet) p
|
||||
Version: metadata.Version,
|
||||
Licenses: pkg.NewLicenseSet(pkg.NewLicense(metadata.License)),
|
||||
PURL: packageURL(metadata),
|
||||
Type: pkg.BinaryPkg,
|
||||
Type: pkgType(metadata.Type),
|
||||
Locations: locations,
|
||||
Metadata: metadata.ELFBinaryPackageNoteJSONPayload,
|
||||
}
|
||||
@@ -67,6 +67,8 @@ func packageURL(metadata elfBinaryPackageNotes) string {
|
||||
).ToString()
|
||||
}
|
||||
|
||||
const alpmType = "alpm"
|
||||
|
||||
func purlDistroType(ty string) string {
|
||||
switch ty {
|
||||
case "rpm":
|
||||
@@ -75,8 +77,22 @@ func purlDistroType(ty string) string {
|
||||
return packageurl.TypeDebian
|
||||
case "apk":
|
||||
return packageurl.TypeAlpine
|
||||
case "alpm":
|
||||
return "alpm"
|
||||
case alpmType:
|
||||
return alpmType
|
||||
}
|
||||
return packageurl.TypeGeneric
|
||||
}
|
||||
|
||||
func pkgType(ty string) pkg.Type {
|
||||
switch ty {
|
||||
case "rpm":
|
||||
return pkg.RpmPkg
|
||||
case "deb":
|
||||
return pkg.DebPkg
|
||||
case "apk":
|
||||
return pkg.ApkPkg
|
||||
case alpmType:
|
||||
return pkg.AlpmPkg
|
||||
}
|
||||
return pkg.BinaryPkg
|
||||
}
|
||||
|
||||
@@ -70,14 +70,14 @@ func Test_ELF_Package_Cataloger(t *testing.T) {
|
||||
expected: []pkg.Package{
|
||||
{
|
||||
Name: "coreutils",
|
||||
Version: "9.5-1.fc41",
|
||||
PURL: "pkg:rpm/fedora/coreutils@9.5-1.fc41?distro=fedora-40",
|
||||
Version: "9.5-3.fc41",
|
||||
PURL: "pkg:rpm/fedora/coreutils@9.5-3.fc41?distro=fedora-40",
|
||||
Locations: file.NewLocationSet(
|
||||
file.NewLocation("/sha256sum").WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation),
|
||||
file.NewLocation("/sha1sum").WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation),
|
||||
),
|
||||
Licenses: pkg.NewLicenseSet(),
|
||||
Type: pkg.BinaryPkg,
|
||||
Type: pkg.RpmPkg,
|
||||
Metadata: pkg.ELFBinaryPackageNoteJSONPayload{
|
||||
Type: "rpm",
|
||||
Architecture: "x86_64",
|
||||
@@ -99,7 +99,7 @@ func Test_ELF_Package_Cataloger(t *testing.T) {
|
||||
file.NewLocation("/sha1sum").WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation),
|
||||
),
|
||||
Licenses: pkg.NewLicenseSet(),
|
||||
Type: pkg.BinaryPkg,
|
||||
Type: pkg.RpmPkg,
|
||||
Metadata: pkg.ELFBinaryPackageNoteJSONPayload{
|
||||
Type: "rpm",
|
||||
Architecture: "arm",
|
||||
|
||||
BIN
Binary file not shown.
@@ -63,6 +63,14 @@ from-images:
|
||||
paths:
|
||||
- /usr/local/lib/erlang/erts-14.2.4/lib/internal/liberts_internal.a
|
||||
|
||||
- name: erlang
|
||||
version: 27.0
|
||||
images:
|
||||
- ref: erlang:27.0.0.0-alpine@sha256:82064a65eb1f9901a479d8ada5f622be3bfac8b474dfc876dc00c28fdef4b1b8
|
||||
platform: linux/amd64
|
||||
paths:
|
||||
- /usr/local/lib/erlang/erts-15.0/bin/beam.smp
|
||||
|
||||
- version: 1.21.3
|
||||
images:
|
||||
- ref: golang:1.21.3@sha256:3ce8313c3513515040870c55e0c041a2b94f3576a58cfd3948633604214aa811
|
||||
@@ -285,6 +293,13 @@ from-images:
|
||||
platform: linux/amd64
|
||||
paths:
|
||||
- /usr/bin/arangosh
|
||||
- name: arangodb
|
||||
version: 3.12.0-2
|
||||
images:
|
||||
- ref: arangodb:3.12.0.2@sha256:6ba2e4284cd0f4835e3ef034be90fb947c3d61225d65d07e3b2d2d893e47de25
|
||||
platform: linux/amd64
|
||||
paths:
|
||||
- /usr/bin/arangosh
|
||||
- version: 15.1
|
||||
images:
|
||||
- ref: postgres:15.1@sha256:b4140dd3a62f364f16a82c1bd88d28b9887ecb47f07dbe2941237d073574d428
|
||||
@@ -433,6 +448,12 @@ from-images:
|
||||
paths:
|
||||
- /usr/local/bin/traefik
|
||||
|
||||
- version: 3.0.4
|
||||
images:
|
||||
- ref: traefik:3.0.4@sha256:12a7cc4232b5b7fe027673da8c096144525f59a8eabc87e52260aac0ec5a1219
|
||||
platform: linux/riscv64
|
||||
paths:
|
||||
- /usr/local/bin/traefik
|
||||
|
||||
# from the original dynamic fixtures...
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
FROM --platform=linux/amd64 fedora:41 as build
|
||||
FROM --platform=linux/amd64 fedora:41@sha256:c05bf79137835bf5c521c58f8252d6031780ae865a0379ab57f412e0ac6b42aa as build
|
||||
|
||||
|
||||
FROM scratch
|
||||
COPY --from=build /bin/sha256sum /sha256sum
|
||||
|
||||
@@ -138,7 +138,15 @@ func (c *goLicenseResolver) getLicensesFromRemote(moduleName, moduleVersion stri
|
||||
|
||||
func (c *goLicenseResolver) findLicensesInFS(urlPrefix string, fsys fs.FS) ([]goLicense, error) {
|
||||
var out []goLicense
|
||||
err := fs.WalkDir(fsys, ".", func(filePath string, d fs.DirEntry, _ error) error {
|
||||
err := fs.WalkDir(fsys, ".", func(filePath string, d fs.DirEntry, err error) error {
|
||||
if err != nil {
|
||||
log.Debugf("error reading %s#%s: %v", urlPrefix, filePath, err)
|
||||
return err
|
||||
}
|
||||
if d == nil {
|
||||
log.Debugf("nil entry for %s#%s", urlPrefix, filePath)
|
||||
return nil
|
||||
}
|
||||
if !c.lowerLicenseFileNames.Has(strings.ToLower(d.Name())) {
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"archive/zip"
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io/fs"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"os"
|
||||
@@ -244,3 +245,62 @@ func Test_findVersionPath(t *testing.T) {
|
||||
vp := findVersionPath(f, ".")
|
||||
require.Equal(t, "github.com/someorg/somepkg@version", vp)
|
||||
}
|
||||
|
||||
func Test_walkDirErrors(t *testing.T) {
|
||||
resolver := newGoLicenseResolver("", CatalogerConfig{})
|
||||
_, err := resolver.findLicensesInFS("somewhere", badFS{})
|
||||
require.Error(t, err)
|
||||
}
|
||||
|
||||
type badFS struct{}
|
||||
|
||||
func (b badFS) Open(_ string) (fs.File, error) {
|
||||
return nil, fmt.Errorf("error")
|
||||
}
|
||||
|
||||
var _ fs.FS = (*badFS)(nil)
|
||||
|
||||
func Test_noLocalGoModDir(t *testing.T) {
|
||||
emptyTmp := t.TempDir()
|
||||
|
||||
validTmp := t.TempDir()
|
||||
require.NoError(t, os.MkdirAll(filepath.Join(validTmp, "mod@ver"), 0700|os.ModeDir))
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
dir string
|
||||
wantErr require.ErrorAssertionFunc
|
||||
}{
|
||||
{
|
||||
name: "empty",
|
||||
dir: "",
|
||||
wantErr: require.Error,
|
||||
},
|
||||
{
|
||||
name: "invalid dir",
|
||||
dir: filepath.Join(emptyTmp, "invalid-dir"),
|
||||
wantErr: require.Error,
|
||||
},
|
||||
{
|
||||
name: "missing mod dir",
|
||||
dir: emptyTmp,
|
||||
wantErr: require.Error,
|
||||
},
|
||||
{
|
||||
name: "valid mod dir",
|
||||
dir: validTmp,
|
||||
wantErr: require.NoError,
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
resolver := newGoLicenseResolver("", CatalogerConfig{
|
||||
SearchLocalModCacheLicenses: true,
|
||||
LocalModCacheDir: test.dir,
|
||||
})
|
||||
_, err := resolver.getLicensesFromLocal("mod", "ver")
|
||||
test.wantErr(t, err)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ import (
|
||||
"io"
|
||||
"regexp"
|
||||
"runtime/debug"
|
||||
"slices"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
@@ -97,17 +98,19 @@ func createModuleRelationships(main pkg.Package, deps []pkg.Package) []artifact.
|
||||
return relationships
|
||||
}
|
||||
|
||||
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) {
|
||||
var pkgs []pkg.Package
|
||||
if mod == nil {
|
||||
return nil, pkgs
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
var empty debug.Module
|
||||
if mod.Main == empty && mod.Path != "" {
|
||||
mod.Main = createMainModuleFromPath(mod.Path)
|
||||
if missingMainModule(mod) {
|
||||
mod.Main = createMainModuleFromPath(mod)
|
||||
}
|
||||
|
||||
var pkgs []pkg.Package
|
||||
for _, dep := range mod.Deps {
|
||||
if dep == nil {
|
||||
continue
|
||||
@@ -130,7 +133,7 @@ func (c *goBinaryCataloger) buildGoPkgInfo(resolver file.Resolver, location file
|
||||
}
|
||||
}
|
||||
|
||||
if mod.Main == empty {
|
||||
if mod.Main == emptyModule {
|
||||
return nil, pkgs
|
||||
}
|
||||
|
||||
@@ -139,6 +142,16 @@ func (c *goBinaryCataloger) buildGoPkgInfo(resolver file.Resolver, location file
|
||||
return &main, pkgs
|
||||
}
|
||||
|
||||
func missingMainModule(mod *extendedBuildInfo) bool {
|
||||
if mod.Main == emptyModule && mod.Path != "" {
|
||||
return true
|
||||
}
|
||||
// special case: when invoking go build with a source file and not a package (directory) then you will
|
||||
// see "command-line-arguments" as the main module path... even though that's not the main module. In this
|
||||
// circumstance, we should treat the main module as missing and search for it within the dependencies.
|
||||
return mod.Main == moduleFromPartialPackageBuild
|
||||
}
|
||||
|
||||
func (c *goBinaryCataloger) makeGoMainPackage(resolver file.Resolver, mod *extendedBuildInfo, arch string, location file.Location, reader io.ReadSeekCloser) pkg.Package {
|
||||
gbs := getBuildSettings(mod.Settings)
|
||||
gover, experiments := getExperimentsFromVersion(mod.GoVersion)
|
||||
@@ -195,7 +208,7 @@ func (c *goBinaryCataloger) findMainModuleVersion(metadata *pkg.GolangBinaryBuil
|
||||
// version of the package.
|
||||
ldflags, _ = metadata.BuildSettings.Get("-ldflags")
|
||||
|
||||
majorVersion, fullVersion = extractVersionFromLDFlags(ldflags)
|
||||
majorVersion, fullVersion = extractVersionFromLDFlags(ldflags, metadata.MainModule)
|
||||
if fullVersion != "" {
|
||||
return fullVersion
|
||||
}
|
||||
@@ -245,13 +258,14 @@ func extractVersionFromContents(reader io.Reader) string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func extractVersionFromLDFlags(ldflags string) (majorVersion string, fullVersion string) {
|
||||
func extractVersionFromLDFlags(ldflags string, maimModule string) (majorVersion string, fullVersion string) {
|
||||
if ldflags == "" {
|
||||
return "", ""
|
||||
}
|
||||
|
||||
for _, pattern := range knownBuildFlagPatterns {
|
||||
groups := internal.MatchNamedCaptureGroups(pattern, ldflags)
|
||||
newPattern := regexp.MustCompile(fmt.Sprintf(`(main|%s\/[^\s]*)%s`, strings.ReplaceAll(maimModule, "/", "\\/"), pattern.String()))
|
||||
groups := internal.MatchNamedCaptureGroups(newPattern, ldflags)
|
||||
v, ok := groups["version"]
|
||||
|
||||
if !ok {
|
||||
@@ -358,8 +372,29 @@ func getExperimentsFromVersion(version string) (string, []string) {
|
||||
return version, experiments
|
||||
}
|
||||
|
||||
func createMainModuleFromPath(path string) (mod debug.Module) {
|
||||
mod.Path = path
|
||||
mod.Version = devel
|
||||
return
|
||||
func createMainModuleFromPath(existing *extendedBuildInfo) debug.Module {
|
||||
// search for a main module candidate within the dependencies
|
||||
var mainModuleCandidates []debug.Module
|
||||
var usedIndex int
|
||||
for i, dep := range existing.Deps {
|
||||
if dep == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
if dep.Version == devel {
|
||||
usedIndex = i
|
||||
mainModuleCandidates = append(mainModuleCandidates, *dep)
|
||||
}
|
||||
}
|
||||
if len(mainModuleCandidates) == 1 {
|
||||
// we need to prune the dependency from module list
|
||||
existing.Deps = slices.Delete(existing.Deps, usedIndex, usedIndex+1)
|
||||
return mainModuleCandidates[0]
|
||||
}
|
||||
|
||||
// otherwise craft a main module from the path (a bit of a cop out, but allows us to have a main module)
|
||||
return debug.Module{
|
||||
Path: existing.Path,
|
||||
Version: devel,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -210,7 +210,7 @@ func TestBuildGoPkgInfo(t *testing.T) {
|
||||
},
|
||||
{
|
||||
name: "buildGoPkgInfo parses a blank mod and returns no packages",
|
||||
mod: &extendedBuildInfo{&debug.BuildInfo{}, nil, ""},
|
||||
mod: &extendedBuildInfo{BuildInfo: &debug.BuildInfo{}, cryptoSettings: nil, arch: ""},
|
||||
expected: []pkg.Package(nil),
|
||||
},
|
||||
{
|
||||
@@ -946,6 +946,95 @@ func TestBuildGoPkgInfo(t *testing.T) {
|
||||
},
|
||||
}},
|
||||
},
|
||||
{
|
||||
name: "parse a mod from path (partial build of package)",
|
||||
mod: &extendedBuildInfo{
|
||||
BuildInfo: &debug.BuildInfo{
|
||||
GoVersion: "go1.22.2",
|
||||
Main: debug.Module{Path: "command-line-arguments"},
|
||||
Settings: []debug.BuildSetting{
|
||||
{
|
||||
Key: "-ldflags",
|
||||
Value: `build -ldflags="-w -s -X github.com/kuskoman/logstash-exporter/config.Version=v1.7.0 -X github.com/kuskoman/logstash-exporter/config.GitCommit=db696dbcfe5a91d288d5ad44ce8ccbea97e65978 -X github.com/kuskoman/logstash-exporter/config.BuildDate=2024-07-17T08:12:17Z"`,
|
||||
},
|
||||
{Key: "GOARCH", Value: archDetails},
|
||||
{Key: "GOOS", Value: "darwin"},
|
||||
{Key: "GOAMD64", Value: "v1"},
|
||||
},
|
||||
Deps: []*debug.Module{
|
||||
{
|
||||
Path: "github.com/kuskoman/something-else",
|
||||
Version: "v1.2.3",
|
||||
},
|
||||
{
|
||||
Path: "github.com/kuskoman/logstash-exporter",
|
||||
Version: "(devel)",
|
||||
},
|
||||
},
|
||||
},
|
||||
arch: archDetails,
|
||||
},
|
||||
expected: []pkg.Package{
|
||||
{
|
||||
Name: "github.com/kuskoman/something-else",
|
||||
Language: pkg.Go,
|
||||
Type: pkg.GoModulePkg,
|
||||
Version: "v1.2.3",
|
||||
PURL: "pkg:golang/github.com/kuskoman/something-else@v1.2.3",
|
||||
Locations: file.NewLocationSet(
|
||||
file.NewLocationFromCoordinates(
|
||||
file.Coordinates{
|
||||
RealPath: "/a-path",
|
||||
FileSystemID: "layer-id",
|
||||
},
|
||||
).WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation),
|
||||
),
|
||||
Metadata: pkg.GolangBinaryBuildinfoEntry{
|
||||
GoCompiledVersion: "go1.22.2",
|
||||
Architecture: archDetails,
|
||||
MainModule: "github.com/kuskoman/logstash-exporter", // correctly attached the main module
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "github.com/kuskoman/logstash-exporter",
|
||||
Language: pkg.Go,
|
||||
Type: pkg.GoModulePkg,
|
||||
Version: "v1.7.0",
|
||||
PURL: "pkg:golang/github.com/kuskoman/logstash-exporter@v1.7.0",
|
||||
Locations: file.NewLocationSet(
|
||||
file.NewLocationFromCoordinates(
|
||||
file.Coordinates{
|
||||
RealPath: "/a-path",
|
||||
FileSystemID: "layer-id",
|
||||
},
|
||||
).WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation),
|
||||
),
|
||||
Metadata: pkg.GolangBinaryBuildinfoEntry{
|
||||
GoCompiledVersion: "go1.22.2",
|
||||
BuildSettings: []pkg.KeyValue{
|
||||
{
|
||||
Key: "-ldflags",
|
||||
Value: `build -ldflags="-w -s -X github.com/kuskoman/logstash-exporter/config.Version=v1.7.0 -X github.com/kuskoman/logstash-exporter/config.GitCommit=db696dbcfe5a91d288d5ad44ce8ccbea97e65978 -X github.com/kuskoman/logstash-exporter/config.BuildDate=2024-07-17T08:12:17Z"`,
|
||||
},
|
||||
{
|
||||
Key: "GOARCH",
|
||||
Value: "amd64",
|
||||
},
|
||||
{
|
||||
Key: "GOOS",
|
||||
Value: "darwin",
|
||||
},
|
||||
{
|
||||
Key: "GOAMD64",
|
||||
Value: "v1",
|
||||
},
|
||||
},
|
||||
Architecture: archDetails,
|
||||
MainModule: "github.com/kuskoman/logstash-exporter",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
@@ -979,6 +1068,7 @@ func TestBuildGoPkgInfo(t *testing.T) {
|
||||
func Test_extractVersionFromLDFlags(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
mainModule string
|
||||
ldflags string
|
||||
wantMajorVersion string
|
||||
wantFullVersion string
|
||||
@@ -989,12 +1079,14 @@ func Test_extractVersionFromLDFlags(t *testing.T) {
|
||||
},
|
||||
{
|
||||
name: "syft ldflags",
|
||||
mainModule: "github.com/anchore/syft",
|
||||
ldflags: ` build -ldflags="-w -s -extldflags '-static' -X github.com/anchore/syft/internal/version.version=0.79.0 -X github.com/anchore/syft/internal/version.gitCommit=b2b332e8b2b66af0905e98b54ebd713a922be1a8 -X github.com/anchore/syft/internal/version.buildDate=2023-04-21T16:20:25Z -X github.com/anchore/syft/internal/version.gitDescription=v0.79.0 "`,
|
||||
wantMajorVersion: "0",
|
||||
wantFullVersion: "v0.79.0",
|
||||
},
|
||||
{
|
||||
name: "kubectl ldflags",
|
||||
name: "kubectl ldflags",
|
||||
mainModule: "k8s.io/kubernetes/vendor/k8s.io/client-go",
|
||||
ldflags: ` build -asmflags=all=-trimpath=/workspace/src/k8s.io/kubernetes/_output/dockerized/go/src/k8s.io/kubernetes
|
||||
build -compiler=gc
|
||||
build -gcflags="all=-trimpath=/workspace/src/k8s.io/kubernetes/_output/dockerized/go/src/k8s.io/kubernetes "
|
||||
@@ -1004,24 +1096,28 @@ func Test_extractVersionFromLDFlags(t *testing.T) {
|
||||
},
|
||||
{
|
||||
name: "nerdctl ldflags",
|
||||
mainModule: "github.com/containerd/nerdctl",
|
||||
ldflags: ` build -ldflags="-s -w -X github.com/containerd/nerdctl/pkg/version.Version=v1.3.1 -X github.com/containerd/nerdctl/pkg/version.Revision=b224b280ff3086516763c7335fc0e0997aca617a"`,
|
||||
wantMajorVersion: "1",
|
||||
wantFullVersion: "v1.3.1",
|
||||
},
|
||||
{
|
||||
name: "limactl ldflags",
|
||||
mainModule: "github.com/lima-vm/lima",
|
||||
ldflags: ` build -ldflags="-s -w -X github.com/lima-vm/lima/pkg/version.Version=v0.15.1"`,
|
||||
wantMajorVersion: "0",
|
||||
wantFullVersion: "v0.15.1",
|
||||
},
|
||||
{
|
||||
name: "terraform ldflags",
|
||||
mainModule: "github.com/hashicorp/terraform",
|
||||
ldflags: ` build -ldflags="-w -s -X 'github.com/hashicorp/terraform/version.Version=1.4.6' -X 'github.com/hashicorp/terraform/version.Prerelease='"`,
|
||||
wantMajorVersion: "1",
|
||||
wantFullVersion: "v1.4.6",
|
||||
},
|
||||
{
|
||||
name: "kube-apiserver ldflags",
|
||||
name: "kube-apiserver ldflags",
|
||||
mainModule: "k8s.io/kubernetes/vendor/k8s.io/client-go",
|
||||
ldflags: ` build -asmflags=all=-trimpath=/workspace/src/k8s.io/kubernetes/_output/dockerized/go/src/k8s.io/kubernetes
|
||||
build -buildmode=exe
|
||||
build -compiler=gc
|
||||
@@ -1031,14 +1127,16 @@ func Test_extractVersionFromLDFlags(t *testing.T) {
|
||||
wantFullVersion: "v1.27.1",
|
||||
},
|
||||
{
|
||||
name: "prometheus ldflags",
|
||||
name: "prometheus ldflags",
|
||||
mainModule: "github.com/prometheus/common",
|
||||
ldflags: ` build -ldflags="-X github.com/prometheus/common/version.Version=2.44.0 -X github.com/prometheus/common/version.Revision=1ac5131f698ebc60f13fe2727f89b115a41f6558 -X github.com/prometheus/common/version.Branch=HEAD -X github.com/prometheus/common/version.BuildUser=root@739e8181c5db -X github.com/prometheus/common/version.BuildDate=20230514-06:18:11 -extldflags '-static'"
|
||||
build -tags=netgo,builtinassets,stringlabels`,
|
||||
wantMajorVersion: "2",
|
||||
wantFullVersion: "v2.44.0",
|
||||
},
|
||||
{
|
||||
name: "influxdb ldflags",
|
||||
name: "influxdb ldflags",
|
||||
mainModule: "github.com/influxdata/influxdb-client-go/v2",
|
||||
ldflags: ` build -ldflags="-s -w -X main.version=v2.7.1 -X main.commit=407fa622e9 -X main.date=2023-04-28T13:24:27Z -linkmode=external -extld=/musl/x86_64/bin/musl-gcc -extldflags '-fno-PIC -static-pie -Wl,-z,stack-size=8388608'"
|
||||
build -tags=assets,sqlite_foreign_keys,sqlite_json,static_build,noasm`,
|
||||
wantMajorVersion: "2",
|
||||
@@ -1046,80 +1144,106 @@ func Test_extractVersionFromLDFlags(t *testing.T) {
|
||||
},
|
||||
{
|
||||
name: "gitea ldflags",
|
||||
mainModule: "code.gitea.io/gitea",
|
||||
ldflags: ` build -ldflags=" -X \"main.MakeVersion=GNU Make 4.1\" -X \"main.Version=1.19.3\" -X \"main.Tags=bindata sqlite sqlite_unlock_notify\" "`,
|
||||
wantMajorVersion: "1",
|
||||
wantFullVersion: "v1.19.3",
|
||||
},
|
||||
{
|
||||
name: "docker sbom cli ldflags",
|
||||
mainModule: "github.com/docker/sbom-cli-plugin",
|
||||
ldflags: ` build -ldflags="-w -s -extldflags '-static' -X github.com/docker/sbom-cli-plugin/internal/version.version=0.6.1-SNAPSHOT-02cf1c8 -X github.com/docker/sbom-cli-plugin/internal/version.gitCommit=02cf1c888ad6662109ac6e3be618392514a56316 -X github.com/docker/sbom-cli-plugin/internal/version.gitDescription=v0.6.1-dirty "`,
|
||||
wantMajorVersion: "0",
|
||||
wantFullVersion: "v0.6.1-SNAPSHOT-02cf1c8",
|
||||
},
|
||||
{
|
||||
name: "docker scout ldflags",
|
||||
mainModule: "github.com/docker/scout-cli-plugin",
|
||||
ldflags: ` build -ldflags="-w -s -extldflags '-static' -X github.com/docker/scout-cli-plugin/internal.version=0.10.0 "`,
|
||||
wantMajorVersion: "0",
|
||||
wantFullVersion: "v0.10.0",
|
||||
},
|
||||
{
|
||||
name: "influx telegraf ldflags",
|
||||
mainModule: "github.com/influxdata/telegraf",
|
||||
ldflags: ` build -ldflags="-w -s -X github.com/influxdata/telegraf/internal.Commit=a3a884a1 -X github.com/influxdata/telegraf/internal.Branch=HEAD -X github.com/influxdata/telegraf/internal.Version=1.26.2"`,
|
||||
wantMajorVersion: "1",
|
||||
wantFullVersion: "v1.26.2",
|
||||
},
|
||||
{
|
||||
name: "argocd ldflags",
|
||||
mainModule: "github.com/argoproj/argo-cd/v2",
|
||||
ldflags: ` build -ldflags="-X github.com/argoproj/argo-cd/v2/common.version=2.7.2 -X github.com/argoproj/argo-cd/v2/common.buildDate=2023-05-12T14:06:49Z -X github.com/argoproj/argo-cd/v2/common.gitCommit=cbee7e6011407ed2d1066c482db74e97e0cc6bdb -X github.com/argoproj/argo-cd/v2/common.gitTreeState=clean -X github.com/argoproj/argo-cd/v2/common.kubectlVersion=v0.24.2 -extldflags=\"-static\""`,
|
||||
wantMajorVersion: "2",
|
||||
wantFullVersion: "v2.7.2",
|
||||
},
|
||||
{
|
||||
name: "kustomize ldflags",
|
||||
mainModule: "sigs.k8s.io/kustomize/api",
|
||||
ldflags: ` build -ldflags="-s -X sigs.k8s.io/kustomize/api/provenance.version=kustomize/v4.5.7 -X sigs.k8s.io/kustomize/api/provenance.gitCommit=56d82a8378dfc8dc3b3b1085e5a6e67b82966bd7 -X sigs.k8s.io/kustomize/api/provenance.buildDate=2022-08-02T16:35:54Z "`,
|
||||
wantMajorVersion: "4",
|
||||
wantFullVersion: "v4.5.7",
|
||||
},
|
||||
{
|
||||
name: "TiDB 7.5.0 ldflags",
|
||||
mainModule: "github.com/pingcap/tidb",
|
||||
ldflags: `build -ldflags="-X \"github.com/pingcap/tidb/pkg/parser/mysql.TiDBReleaseVersion=v7.5.0\" -X \"github.com/pingcap/tidb/pkg/util/versioninfo.TiDBBuildTS=2023-11-24 08:51:04\" -X \"github.com/pingcap/tidb/pkg/util/versioninfo.TiDBGitHash=069631e2ecfedc000ffb92c67207bea81380f020\" -X \"github.com/pingcap/tidb/pkg/util/versioninfo.TiDBGitBranch=heads/refs/tags/v7.5.0\" -X \"github.com/pingcap/tidb/pkg/util/versioninfo.TiDBEdition=Community\" "`,
|
||||
wantMajorVersion: "7",
|
||||
wantFullVersion: "v7.5.0",
|
||||
},
|
||||
{
|
||||
name: "TiDB 6.1.7 ldflags",
|
||||
mainModule: "github.com/pingcap/tidb",
|
||||
ldflags: `build -ldflags="-X \"github.com/pingcap/tidb/parser/mysql.TiDBReleaseVersion=v6.1.7\" -X \"github.com/pingcap/tidb/util/versioninfo.TiDBBuildTS=2023-07-04 12:06:03\" -X \"github.com/pingcap/tidb/util/versioninfo.TiDBGitHash=613ecc5f731b2843e1d53a43915e2cd8da795936\" -X \"github.com/pingcap/tidb/util/versioninfo.TiDBGitBranch=heads/refs/tags/v6.1.7\" -X \"github.com/pingcap/tidb/util/versioninfo.TiDBEdition=Community\" "`,
|
||||
wantMajorVersion: "6",
|
||||
wantFullVersion: "v6.1.7",
|
||||
},
|
||||
{
|
||||
name: "logstash-exporter",
|
||||
ldflags: `build -ldflags="-w -s -X github.com/kuskoman/logstash-exporter/config.Version=v1.7.0 -X github.com/kuskoman/logstash-exporter/config.GitCommit=db696dbcfe5a91d288d5ad44ce8ccbea97e65978 -X github.com/kuskoman/logstash-exporter/config.BuildDate=2024-07-17T08:12:17Z"`,
|
||||
wantMajorVersion: "1",
|
||||
wantFullVersion: "v1.7.0",
|
||||
},
|
||||
//////////////////////////////////////////////////////////////////
|
||||
// negative cases
|
||||
{
|
||||
name: "hugo ldflags",
|
||||
ldflags: ` build -ldflags="-s -w -X github.com/gohugoio/hugo/common/hugo.vendorInfo=gohugoio"`,
|
||||
name: "hugo ldflags",
|
||||
mainModule: "github.com/gohugoio/hugo",
|
||||
ldflags: ` build -ldflags="-s -w -X github.com/gohugoio/hugo/common/hugo.vendorInfo=gohugoio"`,
|
||||
},
|
||||
{
|
||||
name: "ghostunnel ldflags",
|
||||
ldflags: ` build -ldflags="-X main.version=77d9aaa"`,
|
||||
name: "ghostunnel ldflags",
|
||||
mainModule: "github.com/ghostunnel/ghostunnel",
|
||||
ldflags: ` build -ldflags="-X main.version=77d9aaa"`,
|
||||
},
|
||||
{
|
||||
name: "opa ldflags",
|
||||
ldflags: `build -ldflags=" -X github.com/open-policy-agent/opa/version.Hostname=9549178459bc"`,
|
||||
name: "opa ldflags",
|
||||
mainModule: "github.com/open-policy-agent/opa",
|
||||
ldflags: `build -ldflags=" -X github.com/open-policy-agent/opa/version.Hostname=9549178459bc"`,
|
||||
},
|
||||
///////////////////////////////////////////////////////////////////
|
||||
// trickier cases
|
||||
{
|
||||
name: "macvlan plugin for cri-o ldflags",
|
||||
mainModule: "github.com/containernetworking/plugins",
|
||||
ldflags: ` build -ldflags="-extldflags -static -X github.com/containernetworking/plugins/pkg/utils/buildversion.BuildVersion=v1.2.0"`,
|
||||
wantMajorVersion: "1",
|
||||
wantFullVersion: "v1.2.0",
|
||||
},
|
||||
{
|
||||
name: "coder ldflags",
|
||||
mainModule: "github.com/coder/coder",
|
||||
ldflags: ` build -ldflags="-s -w -X 'github.com/coder/coder/buildinfo.tag=0.23.4'"`,
|
||||
wantMajorVersion: "0",
|
||||
wantFullVersion: "v0.23.4",
|
||||
},
|
||||
{
|
||||
name: "hypothetical multiple versions in ldflags",
|
||||
mainModule: "github.com/foo/baz",
|
||||
ldflags: ` build -ldflags="-extldflags -static -X github.com/foo/bar/buildversion.BuildVersion=v1.2.0 -X github.com/foo/baz/buildversion.BuildVersion=v2.4.5"`,
|
||||
wantMajorVersion: "2",
|
||||
wantFullVersion: "v2.4.5",
|
||||
},
|
||||
///////////////////////////////////////////////////////////////////
|
||||
// don't know how to handle these... yet
|
||||
//{
|
||||
@@ -1139,7 +1263,7 @@ func Test_extractVersionFromLDFlags(t *testing.T) {
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
gotMajorVersion, gotFullVersion := extractVersionFromLDFlags(tt.ldflags)
|
||||
gotMajorVersion, gotFullVersion := extractVersionFromLDFlags(tt.ldflags, tt.mainModule)
|
||||
assert.Equal(t, tt.wantMajorVersion, gotMajorVersion, "unexpected major version")
|
||||
assert.Equal(t, tt.wantFullVersion, gotFullVersion, "unexpected full version")
|
||||
})
|
||||
|
||||
@@ -56,7 +56,7 @@ func scanFile(reader unionreader.UnionReader, filename string) []*extendedBuildI
|
||||
}
|
||||
}
|
||||
|
||||
builds = append(builds, &extendedBuildInfo{bi, v, arch})
|
||||
builds = append(builds, &extendedBuildInfo{BuildInfo: bi, cryptoSettings: v, arch: arch})
|
||||
}
|
||||
return builds
|
||||
}
|
||||
|
||||
@@ -33,10 +33,11 @@ func stdlibPackageAndRelationships(pkgs []pkg.Package) ([]pkg.Package, []artifac
|
||||
}
|
||||
|
||||
stdLibPkg := newGoStdLib(mValue.GoCompiledVersion, goPkg.Locations)
|
||||
if stdLibPkg != nil {
|
||||
goCompilerPkgs = append(goCompilerPkgs, *stdLibPkg)
|
||||
totalLocations.Add(location)
|
||||
if stdLibPkg == nil {
|
||||
continue
|
||||
}
|
||||
goCompilerPkgs = append(goCompilerPkgs, *stdLibPkg)
|
||||
totalLocations.Add(location)
|
||||
|
||||
relationships = append(relationships, artifact.Relationship{
|
||||
From: *stdLibPkg,
|
||||
|
||||
@@ -68,6 +68,22 @@ func Test_stdlibPackageAndRelationships(t *testing.T) {
|
||||
wantPkgs: 1,
|
||||
wantRels: 1,
|
||||
},
|
||||
{
|
||||
name: "go binary package with devel stdlib",
|
||||
pkgs: []pkg.Package{
|
||||
{
|
||||
Name: "github.com/something/go",
|
||||
Version: "1.0.0",
|
||||
Locations: file.NewLocationSet(file.NewLocation("/bin/my-app")),
|
||||
Metadata: pkg.GolangBinaryBuildinfoEntry{
|
||||
GoCompiledVersion: "devel",
|
||||
MainModule: "github.com/something/go",
|
||||
},
|
||||
},
|
||||
},
|
||||
wantPkgs: 0,
|
||||
wantRels: 0,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
|
||||
@@ -64,6 +64,9 @@
|
||||
"github.com/hamba/avro/v2": [
|
||||
"cpe:2.3:a:avro_project:avro:*:*:*:*:*:go:*:*"
|
||||
],
|
||||
"github.com/hashicorp/go-retryablehttp": [
|
||||
"cpe:2.3:a:hashicorp:retryablehttp:*:*:*:*:*:go:*:*"
|
||||
],
|
||||
"github.com/jumpserver/koko/pkg/koko": [
|
||||
"cpe:2.3:a:fit2cloud:koko:*:*:*:*:*:go:*:*"
|
||||
],
|
||||
@@ -6977,6 +6980,9 @@
|
||||
"99fy-core": [
|
||||
"cpe:2.3:a:hasthemes:free_woocommerce_theme_99fy_extension:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"Ultimate_VC_Addons": [
|
||||
"cpe:2.3:a:brainstormforce:ultimate_addons_for_wpbakery_page_builder:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"a-forms": [
|
||||
"cpe:2.3:a:a-forms_project:a-forms:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -7011,7 +7017,8 @@
|
||||
"cpe:2.3:a:ab-wp:simple_counter:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"academy": [
|
||||
"cpe:2.3:a:creativeitem:academy_lms:*:*:*:*:*:*:*:*"
|
||||
"cpe:2.3:a:creativeitem:academy_lms:*:*:*:*:*:*:*:*",
|
||||
"cpe:2.3:a:kodezen:academy_lms:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"accelerated-mobile-pages": [
|
||||
"cpe:2.3:a:ampforwp:accelerated_mobile_pages:*:*:*:*:*:wordpress:*:*",
|
||||
@@ -7208,6 +7215,9 @@
|
||||
"addon-elements-for-elementor-page-builder": [
|
||||
"cpe:2.3:a:webtechstreet:elementor_addon_elements:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"addons-for-beaver-builder": [
|
||||
"cpe:2.3:a:livemesh:livemesh_addons_for_beaver_builder:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"addons-for-elementor": [
|
||||
"cpe:2.3:a:livemesh:elementor_addons:*:*:*:*:*:wordpress:*:*",
|
||||
"cpe:2.3:a:livemeshelementor:addons_for_elementor:*:*:*:*:*:wordpress:*:*"
|
||||
@@ -7434,6 +7444,10 @@
|
||||
"alfred-click-collect": [
|
||||
"cpe:2.3:a:alfred24_click_\\\u0026_collect_project:alfred24_click_\\\u0026_collect:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"ali2woo-lite": [
|
||||
"cpe:2.3:a:ali2woo:ali2woo:*:*:*:*:lite:wordpress:*:*",
|
||||
"cpe:2.3:a:ali2woo:aliexpress_dropshipping_with_alinext:*:*:*:*:lite:wordpress:*:*"
|
||||
],
|
||||
"alipay": [
|
||||
"cpe:2.3:a:alipay_project:alipay:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -7791,6 +7805,9 @@
|
||||
"auxin-elements": [
|
||||
"cpe:2.3:a:averta:shortcodes_and_extra_features_for_phlox_theme:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"auxin-portfolio": [
|
||||
"cpe:2.3:a:averta:auxinportfolio:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"auyautochat-for-wp": [
|
||||
"cpe:2.3:a:autochat:automatic_conversation:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -7904,6 +7921,9 @@
|
||||
"batch-cat": [
|
||||
"cpe:2.3:a:batch_cat_project:batch_cat:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"bb-bootstrap-cards": [
|
||||
"cpe:2.3:a:brainstormforce:cards_for_beaver_builder:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"bbp-move-topics": [
|
||||
"cpe:2.3:a:bbpress_move_topics_project:bbpress_move_topics:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -7920,9 +7940,15 @@
|
||||
"bbpress": [
|
||||
"cpe:2.3:a:bbpress:bbpress:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"bbpress-notify-nospam": [
|
||||
"cpe:2.3:a:usestrict:bbpress_notify:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"bcorp-shortcodes": [
|
||||
"cpe:2.3:a:bcorp_shortcodes_project:bcorp_shortcodes:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"bdthemes-element-pack-lite": [
|
||||
"cpe:2.3:a:bdthemes:element_pack_elementor_addons:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"bdvs-password-reset": [
|
||||
"cpe:2.3:a:bedevious:password_reset_with_code_for_wordpress_rest_api:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -7969,7 +7995,8 @@
|
||||
],
|
||||
"better-wp-security": [
|
||||
"cpe:2.3:a:ithemes:ithemes_security:*:*:*:*:*:wordpress:*:*",
|
||||
"cpe:2.3:a:ithemes:security:*:*:*:*:*:wordpress:*:*"
|
||||
"cpe:2.3:a:ithemes:security:*:*:*:*:*:wordpress:*:*",
|
||||
"cpe:2.3:a:solidwp:solid_security:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"betterlinks": [
|
||||
"cpe:2.3:a:wpdeveloper:betterlinks:*:*:*:*:*:wordpress:*:*"
|
||||
@@ -8040,12 +8067,18 @@
|
||||
"blog-in-blog": [
|
||||
"cpe:2.3:a:blog-in-blog_project:blog-in-blog:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"blog-posts-and-category-for-elementor": [
|
||||
"cpe:2.3:a:plugin-devs:blog\\,_posts_and_category_filter_for_elementor:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"blog2social": [
|
||||
"cpe:2.3:a:adenion:blog2social:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"blogger-importer": [
|
||||
"cpe:2.3:a:wordpress:blogger_importer:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"blogmentor": [
|
||||
"cpe:2.3:a:auburnforest:blogmentor:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"blue-admin": [
|
||||
"cpe:2.3:a:blue-admin_project:blue-admin:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -8324,7 +8357,11 @@
|
||||
"cache-images": [
|
||||
"cpe:2.3:a:cache_images_project:cache_images:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"caddy": [
|
||||
"cpe:2.3:a:madebytribe:caddy:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"cafe-lite": [
|
||||
"cpe:2.3:a:clever-soft:clever_addons_for_elementor:*:*:*:*:*:wordpress:*:*",
|
||||
"cpe:2.3:a:cleversoft:clever_addons_for_elementor:*:*:*:*:*:wordpress:*:*",
|
||||
"cpe:2.3:a:download_clever_addons_for_elementor_project:download_clever_addons_for_elementor:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -8372,6 +8409,9 @@
|
||||
"candidate-application-form": [
|
||||
"cpe:2.3:a:candidate-application-form_project:candidate-application-form:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"canto": [
|
||||
"cpe:2.3:a:canto:canto:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"canvasio3d-light": [
|
||||
"cpe:2.3:a:virtuellwerk:canvasio3d_light:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -8534,8 +8574,12 @@
|
||||
"chatbot": [
|
||||
"cpe:2.3:a:quantumcloud:ai_chatbot:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"chatbot-chatgpt": [
|
||||
"cpe:2.3:a:kognetics:kognetiks_chatbot:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"chaty": [
|
||||
"cpe:2.3:a:premio:chaty:*:*:*:*:*:wordpress:*:*"
|
||||
"cpe:2.3:a:premio:chaty:*:*:*:*:*:wordpress:*:*",
|
||||
"cpe:2.3:a:premio:floating_chat_widget:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"check-email": [
|
||||
"cpe:2.3:a:check_email_project:check_email:*:*:*:*:*:wordpress:*:*",
|
||||
@@ -8844,7 +8888,8 @@
|
||||
"cpe:2.3:a:ciphercoin:contact_form_7_database_addon:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"contact-form-entries": [
|
||||
"cpe:2.3:a:crmperks:database_for_contact_form_7\\,_wpforms\\,_elementor_forms:*:*:*:*:*:*:*:*"
|
||||
"cpe:2.3:a:crmperks:database_for_contact_form_7\\,_wpforms\\,_elementor_forms:*:*:*:*:*:*:*:*",
|
||||
"cpe:2.3:a:crmperks:database_for_contact_form_7\\,_wpforms\\,_elementor_forms:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"contact-form-generator": [
|
||||
"cpe:2.3:a:creative-solutions:contact_form_generator:*:*:*:*:*:wordpress:*:*"
|
||||
@@ -8935,6 +8980,9 @@
|
||||
"content-views-query-and-display-post-page": [
|
||||
"cpe:2.3:a:contentviewspro:content_views:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"contentlock": [
|
||||
"cpe:2.3:a:adamsolymosi:contentlock:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"contentstudio": [
|
||||
"cpe:2.3:a:contentstudio:contentstudio:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -9020,6 +9068,9 @@
|
||||
"copy-the-code": [
|
||||
"cpe:2.3:a:maheshwaghmare:copy_anything_to_clipboard:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"copymatic": [
|
||||
"cpe:2.3:a:copymatic:copymatic:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"core-control": [
|
||||
"cpe:2.3:a:dd32:core_control:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -9035,6 +9086,9 @@
|
||||
"coru-lfmember": [
|
||||
"cpe:2.3:a:marcorulicke:coru_lfmember:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"cost-calculator-builder": [
|
||||
"cpe:2.3:a:stylemixthemes:cost_calculator_builder:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"countdown-block": [
|
||||
"cpe:2.3:a:wpdeveloper:countdown_block:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -9129,6 +9183,9 @@
|
||||
"crossslide-jquery-plugin-for-wordpress": [
|
||||
"cpe:2.3:a:crossslide_jquery_project:crossslide_jquery:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"cryout-serious-slider": [
|
||||
"cpe:2.3:a:cryoutcreations:serious_slider:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"crypto-converter-widget": [
|
||||
"cpe:2.3:a:currencyratetoday:crypto_converter_widget:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -9151,6 +9208,9 @@
|
||||
"css-javascript-toolbox": [
|
||||
"cpe:2.3:a:wipeoutmedia:css_\\\u0026_javascript_toolbox:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"cssable-countdown": [
|
||||
"cpe:2.3:a:dmonnier:cssable_countdown:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"csv-import-export": [
|
||||
"cpe:2.3:a:csv-import-export_project:csv-import-export:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -9352,7 +9412,8 @@
|
||||
"cpe:2.3:a:arwebdesign:dashboard_to-do_list:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"dashboard-widgets-suite": [
|
||||
"cpe:2.3:a:plugin-planet:dashboard_widget_suite:*:*:*:*:*:wordpress:*:*"
|
||||
"cpe:2.3:a:plugin-planet:dashboard_widget_suite:*:*:*:*:*:wordpress:*:*",
|
||||
"cpe:2.3:a:plugin-planet:dashboard_widgets_suite:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"dashicons-cpt": [
|
||||
"cpe:2.3:a:halgatewood:dashicons_\\+_custom_post_types:*:*:*:*:*:wordpress:*:*"
|
||||
@@ -9425,6 +9486,9 @@
|
||||
"delhivery-logistics-courier": [
|
||||
"cpe:2.3:a:delhivery:logistics_courier:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"delucks-seo": [
|
||||
"cpe:2.3:a:delucks:delucks_seo:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"democracy-poll": [
|
||||
"cpe:2.3:a:wp-kama:democracy_poll:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -9438,9 +9502,11 @@
|
||||
"cpe:2.3:a:deny_all_firewall_project:deny_all_firewall:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"depicter": [
|
||||
"cpe:2.3:a:averta:depicter_slider:*:*:*:*:*:wordpress:*:*"
|
||||
"cpe:2.3:a:averta:depicter_slider:*:*:*:*:*:wordpress:*:*",
|
||||
"cpe:2.3:a:depicter:depicter:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"dethemekit-for-elementor": [
|
||||
"cpe:2.3:a:detheme:dethemekit_for_elementor:*:*:*:*:*:wordpress:*:*",
|
||||
"cpe:2.3:a:dethemekit_for_elementor_project:dethemekit_for_elementor:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"diary-availability-calendar": [
|
||||
@@ -9455,9 +9521,15 @@
|
||||
"digital-publications-by-supsystic": [
|
||||
"cpe:2.3:a:supsystic:digital_publications_by_supsystic:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"dimage-360": [
|
||||
"cpe:2.3:a:darteweb:dimage_360:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"directorist": [
|
||||
"cpe:2.3:a:wpwax:directorist:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"directorypress": [
|
||||
"cpe:2.3:a:designinvento:directorypress:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"disable-comments": [
|
||||
"cpe:2.3:a:disable_comments:disable_comments_project:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -9509,6 +9581,9 @@
|
||||
"dokan-lite": [
|
||||
"cpe:2.3:a:wedevs:dokan:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"dokan-pro": [
|
||||
"cpe:2.3:a:dokan:dokan_pro_plugin:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"dologin": [
|
||||
"cpe:2.3:a:wpdo:dologin_security:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -9539,6 +9614,9 @@
|
||||
"doofinder-for-woocommerce": [
|
||||
"cpe:2.3:a:doofinder:doofinder:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"dop-shortcodes": [
|
||||
"cpe:2.3:a:dotonpaper:dot_on_paper_shortcodes:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"double-opt-in-for-download": [
|
||||
"cpe:2.3:a:labwebdevelopment:double_opt-in_for_download:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -9665,6 +9743,9 @@
|
||||
"easy-accordion-free": [
|
||||
"cpe:2.3:a:techearty:easy_accordion:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"easy-age-verify": [
|
||||
"cpe:2.3:a:5starplugins:easy_age_verify:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"easy-appointments": [
|
||||
"cpe:2.3:a:easy_appointments_project:easy_appointments:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -9869,6 +9950,9 @@
|
||||
"elegant-custom-fonts": [
|
||||
"cpe:2.3:a:breakdance:elegant_custom_fonts:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"element-ready-lite": [
|
||||
"cpe:2.3:a:quomodosoft:elementsready:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"elementor": [
|
||||
"cpe:2.3:a:elementor:elementor_page_builder:*:*:*:*:*:wordpress:*:*",
|
||||
"cpe:2.3:a:elementor:elementor_page_builder:*:*:*:*:pro:wordpress:*:*",
|
||||
@@ -9879,7 +9963,11 @@
|
||||
"cpe:2.3:a:elementor:elementor_pro:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"elementskit-lite": [
|
||||
"cpe:2.3:a:wpmet:elements_kit_elementor_addons:*:*:*:*:*:wordpress:*:*"
|
||||
"cpe:2.3:a:wpmet:elements_kit_elementor_addons:*:*:*:*:*:wordpress:*:*",
|
||||
"cpe:2.3:a:wpmet:elementskit_elementor_addons:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"elespare": [
|
||||
"cpe:2.3:a:elespare:elespare:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"emag-marketplace-connector": [
|
||||
"cpe:2.3:a:zitec:emag_marketplace_connector:*:*:*:*:*:wordpress:*:*"
|
||||
@@ -10147,6 +10235,9 @@
|
||||
"expand-maker": [
|
||||
"cpe:2.3:a:edmonsoft:read_more_\\\u0026_accordion:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"expert-invoice": [
|
||||
"cpe:2.3:a:expert_invoice_project:expert_invoice:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"export-all-urls": [
|
||||
"cpe:2.3:a:atlasgondal:export_all_urls:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -10301,6 +10392,9 @@
|
||||
"feedburner-alternative-and-rss-redirect": [
|
||||
"cpe:2.3:a:inisev:rss_redirect_\\\u0026_feedburner_alternative:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"feeds-for-youtube": [
|
||||
"cpe:2.3:a:smashballoon:feeds_for_youtube:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"feedwordpress": [
|
||||
"cpe:2.3:a:feedwordpress_project:feedwordpress:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -10324,6 +10418,9 @@
|
||||
"file-manager-advanced": [
|
||||
"cpe:2.3:a:advancedfilemanager:advanced_file_manager:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"file-manager-advanced-shortcode-2": [
|
||||
"cpe:2.3:a:advancedfilemanager:file_manager_advanced_shortcode:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"filebird": [
|
||||
"cpe:2.3:a:ninjateam:filebird:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -10530,6 +10627,9 @@
|
||||
"forminator": [
|
||||
"cpe:2.3:a:incsub:forminator:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"formlift": [
|
||||
"cpe:2.3:a:formlift:formlift_for_infusionsoft_web_forms:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"forms-ada-form-builder": [
|
||||
"cpe:2.3:a:monitorclick:forms_ada:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -10539,6 +10639,9 @@
|
||||
"forms-for-campaign-monitor": [
|
||||
"cpe:2.3:a:campaignmonitor:campaign_monitor:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"forms-gutenberg": [
|
||||
"cpe:2.3:a:gutenbergforms:gutenberg_forms:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"formzu-wp": [
|
||||
"cpe:2.3:a:formzu:formzu_wp:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -11024,6 +11127,9 @@
|
||||
"gutenslider": [
|
||||
"cpe:2.3:a:gutenslider:gutenslider:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"gutenverse": [
|
||||
"cpe:2.3:a:jegstudio:gutenverse:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"gwa-autoresponder": [
|
||||
"cpe:2.3:a:\\[gwa\\]_autoresponder_project:\\[gwa\\]_autoresponder:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -11033,6 +11139,9 @@
|
||||
"gwyns-imagemap-selector": [
|
||||
"cpe:2.3:a:gwyn\\'s_imagemap_selector_project:gwyn\\'s_imagemap_selector:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"h5p": [
|
||||
"cpe:2.3:a:h5p:h5p:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"hal": [
|
||||
"cpe:2.3:a:cnrs:hal:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -11370,6 +11479,9 @@
|
||||
"imdb-widget": [
|
||||
"cpe:2.3:a:imdb-widget_project:imdb-widget:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"imgspider": [
|
||||
"cpe:2.3:a:wbolt:imgspider:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"import-legacy-media": [
|
||||
"cpe:2.3:a:import_legacy_media_project:import_legacy_media:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -11664,6 +11776,9 @@
|
||||
"jsmol2wp": [
|
||||
"cpe:2.3:a:jsmol2wp_project:jsmol2wp:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"json-api-user": [
|
||||
"cpe:2.3:a:parorrey:json_api_user:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"json-content-importer": [
|
||||
"cpe:2.3:a:json-content-importer:json_content_importer:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -11685,6 +11800,9 @@
|
||||
"jvm-rich-text-icons": [
|
||||
"cpe:2.3:a:jorisvm:jvm_gutenberg_rich_text_icons:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"kadence-blocks": [
|
||||
"cpe:2.3:a:kadencewp:gutenberg_blocks_with_ai:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"kadence-starter-templates": [
|
||||
"cpe:2.3:a:kadencewp:starter_templates:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -11721,6 +11839,9 @@
|
||||
"keyword-meta": [
|
||||
"cpe:2.3:a:keyword_meta_project:keyword_meta:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"kimili-flash-embed": [
|
||||
"cpe:2.3:a:kimili:kimili_flash_embed:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"kitestudio-core": [
|
||||
"cpe:2.3:a:kitestudio:core_plugin_for_kitestudio_themes:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -12072,6 +12193,9 @@
|
||||
"magic-post-thumbnail": [
|
||||
"cpe:2.3:a:magic-post-thumbnail:magic_post_thumbnail:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"magical-addons-for-elementor": [
|
||||
"cpe:2.3:a:wpthemespace:magical_addons_for_elementor:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"mail-control": [
|
||||
"cpe:2.3:a:instareza:mail_control:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -12216,6 +12340,9 @@
|
||||
"material-design-icons-for-elementor": [
|
||||
"cpe:2.3:a:material_design_icons_for_page_builders_project:material_design_icons_for_page_builders:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"materialis-companion": [
|
||||
"cpe:2.3:a:extendthemes:materialis_companion:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"matrix-pre-loader": [
|
||||
"cpe:2.3:a:nkb-bd:preloader_matrix:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -12268,6 +12395,9 @@
|
||||
"mediavine-control-panel": [
|
||||
"cpe:2.3:a:mediavine:mediavine_control_panel:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"mediavine-create": [
|
||||
"cpe:2.3:a:mediavine:create:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"meeting-scheduler-by-vcita": [
|
||||
"cpe:2.3:a:vcita:online_booking_\\\u0026_scheduling_calendar_for_wordpress:*:*:*:*:*:wordpress:*:*",
|
||||
"cpe:2.3:a:vcita:online_booking_\\\u0026_scheduling_calendar_for_wordpress_by_vcita:*:*:*:*:*:wordpress:*:*"
|
||||
@@ -12275,6 +12405,9 @@
|
||||
"mega-addons-for-visual-composer": [
|
||||
"cpe:2.3:a:topdigitaltrends:mega_addons_for_wpbakery_page_builder:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"mega-elements-addons-for-elementor": [
|
||||
"cpe:2.3:a:kraftplugins:mega_elements:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"megamenu": [
|
||||
"cpe:2.3:a:megamenu:max_mega_menu:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -12600,6 +12733,9 @@
|
||||
"my-content-management": [
|
||||
"cpe:2.3:a:joedolson:my_content_management:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"my-favorites": [
|
||||
"cpe:2.3:a:takashimatsuyama:my_favorites:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"my-tickets": [
|
||||
"cpe:2.3:a:my_tickets_project:my_tickets:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -12775,6 +12911,9 @@
|
||||
"cpe:2.3:a:wpconcern:coming_soon_\\\u0026_maintenance_mode_page:*:*:*:*:*:wordpress:*:*",
|
||||
"cpe:2.3:a:wpconcern:nifty_coming_soon_\\\u0026_maintenance_mode_page:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"ninja-beaver-lite-addons-for-beaver-builder": [
|
||||
"cpe:2.3:a:ninjateam:ninja_beaver_add-ons_for_beaver_builder:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"ninja-forms": [
|
||||
"cpe:2.3:a:ninjaforms:contact_form:*:*:*:*:*:wordpress:*:*",
|
||||
"cpe:2.3:a:ninjaforms:ninja_forms:*:*:*:*:*:wordpress:*:*"
|
||||
@@ -12891,6 +13030,9 @@
|
||||
"one-click-demo-import": [
|
||||
"cpe:2.3:a:ocdi:one_click_demo_import:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"one-click-order-reorder": [
|
||||
"cpe:2.3:a:cedcommerce:one_click_order_re-order:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"one-click-plugin-updater": [
|
||||
"cpe:2.3:a:one_click_plugin_updater_project:one_click_plugin_updater:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -13006,6 +13148,10 @@
|
||||
"osmapper": [
|
||||
"cpe:2.3:a:b4after:osmapper:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"otter-blocks": [
|
||||
"cpe:2.3:a:themeisle:otter_blocks:*:*:*:*:*:*:*:*",
|
||||
"cpe:2.3:a:themeisle:otter_blocks:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"our-team-enhanced": [
|
||||
"cpe:2.3:a:smartcat:our_team_showcase:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -13033,6 +13179,9 @@
|
||||
"page-builder-by-azexo": [
|
||||
"cpe:2.3:a:azexo:page_builder_with_image_map_by_azexo:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"page-builder-sandwich": [
|
||||
"cpe:2.3:a:pagebuildersandwich:page_builder_sandwich:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"page-generator": [
|
||||
"cpe:2.3:a:wpzinc:page_generator:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -13069,6 +13218,9 @@
|
||||
"paid-memberships-pro": [
|
||||
"cpe:2.3:a:strangerstudios:paid_memberships_pro:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"pandavideo": [
|
||||
"cpe:2.3:a:pandavideo:panda_video:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"parallax-image": [
|
||||
"cpe:2.3:a:howardehrenberg:parallax_image:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -13115,6 +13267,9 @@
|
||||
"paypal-payment-button-by-vcita": [
|
||||
"cpe:2.3:a:vcita:online_payments_-_get_paid_with_paypal\\,_square_\\\u0026_stripe:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"payplus-payment-gateway": [
|
||||
"cpe:2.3:a:payplus:payplus_payment_gateway:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"paytium": [
|
||||
"cpe:2.3:a:paytium:paytium:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -13656,6 +13811,9 @@
|
||||
"project-status": [
|
||||
"cpe:2.3:a:3.7designs:project_status:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"projecthuddle-child-site": [
|
||||
"cpe:2.3:a:brainstormforce:surefeedback:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"promobar": [
|
||||
"cpe:2.3:a:bestwebsoft:promobar:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -13683,6 +13841,9 @@
|
||||
"pubsubhubbub": [
|
||||
"cpe:2.3:a:pubsubhubbub:websub:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"pure-chat": [
|
||||
"cpe:2.3:a:purechat:pure_chat:*:*:*:*:*:*:*:*"
|
||||
],
|
||||
"purple-xmls-google-product-feed-for-woocommerce": [
|
||||
"cpe:2.3:a:dpl:product_feed_on_woocommerce_for_google\\,_awin\\,_shareasale\\,_bing\\,_and_more:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -13788,6 +13949,9 @@
|
||||
"quotes-collection": [
|
||||
"cpe:2.3:a:quotes_collection_project:quotes_collection:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"quotes-for-woocommerce": [
|
||||
"cpe:2.3:a:technovama:quotes_for_woocommerce:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"quotes-llama": [
|
||||
"cpe:2.3:a:quotes_llama_project:quotes_llama:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -14056,6 +14220,9 @@
|
||||
"restrict-content": [
|
||||
"cpe:2.3:a:liquidweb:restrict_content:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"restrict-for-elementor": [
|
||||
"cpe:2.3:a:tickera:restrict_for_elementor:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"restrict-usernames-emails-characters": [
|
||||
"cpe:2.3:a:benaceur-php:restrict_usernames_emails_characters:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -14226,6 +14393,9 @@
|
||||
"schedulicity-online-appointment-booking": [
|
||||
"cpe:2.3:a:schedulicity:schedulicity:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"schema-and-structured-data-for-wp": [
|
||||
"cpe:2.3:a:magazine3:schema_\\\u0026_structured_data_for_wp_\\\u0026_amp:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"school-management-system": [
|
||||
"cpe:2.3:a:weblizar:school_management_-_education_\\\u0026_learning_management:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -14253,6 +14423,9 @@
|
||||
"search-analytics": [
|
||||
"cpe:2.3:a:cornelraiu:wp_search_analytics:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"search-and-replace": [
|
||||
"cpe:2.3:a:wp-media:search_\\\u0026_replace:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"search-everything": [
|
||||
"cpe:2.3:a:search_everything_project:search_everything:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -14269,6 +14442,9 @@
|
||||
"searchiq": [
|
||||
"cpe:2.3:a:searchiq:searchiq:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"searchpro": [
|
||||
"cpe:2.3:a:berqier:berqwp:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"searchterms-tagging-2": [
|
||||
"cpe:2.3:a:seo_searchterms_tagging_2_project:seo_searchterms_tagging_2:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -14308,6 +14484,12 @@
|
||||
"sell-media": [
|
||||
"cpe:2.3:a:graphpaperpress:sell_media:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"sellkit": [
|
||||
"cpe:2.3:a:artbees:sellkit:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"send-emails-with-mandrill": [
|
||||
"cpe:2.3:a:millermedia:mandrill:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"send-users-email": [
|
||||
"cpe:2.3:a:sumanbhattarai:send_users_email:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -14457,6 +14639,9 @@
|
||||
"shortcode-to-display-post-and-user-data": [
|
||||
"cpe:2.3:a:vegacorp:display_custom_fields_in_the_frontend_-_post_and_user_profile_fields:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"shortcode-variables": [
|
||||
"cpe:2.3:a:yeken:snippet_shortcodes:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"shortcodes-finder": [
|
||||
"cpe:2.3:a:scribit:shortcodes_finder:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -14790,6 +14975,9 @@
|
||||
"skaut-bazar": [
|
||||
"cpe:2.3:a:skaut-bazar_project:skaut-bazar:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"sketchfab-oembed": [
|
||||
"cpe:2.3:a:generatewp:sketchfab_embed:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"sliced-invoices": [
|
||||
"cpe:2.3:a:slicedinvoices:sliced_invoices:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -15302,6 +15490,9 @@
|
||||
"tabbed": [
|
||||
"cpe:2.3:a:rich-web:tab:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"table-addons-for-elementor": [
|
||||
"cpe:2.3:a:fusionplugin:table_addons_for_elementor:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"table-of-contents-plus": [
|
||||
"cpe:2.3:a:dublue:table_of_contents_plus:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -15424,6 +15615,9 @@
|
||||
"the-holiday-calendar": [
|
||||
"cpe:2.3:a:theholidaycalendar:the_holiday_calendar:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"the-moneytizer": [
|
||||
"cpe:2.3:a:themoneytizer:the_moneytizer:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"the-plus-addons-for-elementor-page-builder": [
|
||||
"cpe:2.3:a:posimyth:the_plus_addons_for_elementor:*:*:*:*:free:wordpress:*:*",
|
||||
"cpe:2.3:a:posimyth:the_plus_addons_for_elementor_page_builder_lite:*:*:*:*:*:wordpress:*:*"
|
||||
@@ -15480,10 +15674,14 @@
|
||||
"themesflat-addons-for-elementor": [
|
||||
"cpe:2.3:a:themesflat:themesflat_addons_for_elementor:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"themify-builder": [
|
||||
"cpe:2.3:a:themify:themify_builder:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"themify-portfolio-post": [
|
||||
"cpe:2.3:a:themify:portfolio_post:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"themify-wc-product-filter": [
|
||||
"cpe:2.3:a:themify:product_filter:*:*:*:*:*:wordpress:*:*",
|
||||
"cpe:2.3:a:themify:woocommerce_product_filter:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"thesography": [
|
||||
@@ -15551,6 +15749,9 @@
|
||||
"toolbar-to-share": [
|
||||
"cpe:2.3:a:toolbar_to_share_project:toolbar_to_share:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"tooltip-ck": [
|
||||
"cpe:2.3:a:ceikay:tooltip_ck:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"top-10": [
|
||||
"cpe:2.3:a:top_10_project:top_10:*:*:*:*:*:wordpress:*:*",
|
||||
"cpe:2.3:a:webberzone:top_10:*:*:*:*:*:wordpress:*:*"
|
||||
@@ -15597,6 +15798,9 @@
|
||||
"transbank-webpay-plus-rest": [
|
||||
"cpe:2.3:a:transbank:transbank_webpay_rest:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"transition-slider-lite": [
|
||||
"cpe:2.3:a:creativeinteractivemedia:transition_slider:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"translatepress-multilingual": [
|
||||
"cpe:2.3:a:cozmoslabs:translatepress:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -15673,6 +15877,9 @@
|
||||
"typebot": [
|
||||
"cpe:2.3:a:typebot:typebot:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"typing-text": [
|
||||
"cpe:2.3:a:wpdeveloper:typing_text:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"typofr": [
|
||||
"cpe:2.3:a:typofr_project:typofr:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -15682,6 +15889,9 @@
|
||||
"ucontext-for-amazon": [
|
||||
"cpe:2.3:a:summitmediaconcepts:ucontext_for_amazon:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"uipress-lite": [
|
||||
"cpe:2.3:a:uipress:uipress_lite:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"uji-countdown": [
|
||||
"cpe:2.3:a:wpmanage:uji_countdown:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -15712,6 +15922,9 @@
|
||||
"ultimate-author-box-lite": [
|
||||
"cpe:2.3:a:accesspressthemes:ultimate_author_box_lite:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"ultimate-blocks": [
|
||||
"cpe:2.3:a:dotcamp:ultimate_blocks:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"ultimate-carousel-for-elementor": [
|
||||
"cpe:2.3:a:topdigitaltrends:ultimate_carousel_for_elementor:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -15780,6 +15993,9 @@
|
||||
"ultra-companion": [
|
||||
"cpe:2.3:a:wpoperation:ultra_companion:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"ultraaddons-elementor-lite": [
|
||||
"cpe:2.3:a:codeastrology:ultraaddons:*:*:*:*:*:*:*:*"
|
||||
],
|
||||
"uncanny-automator": [
|
||||
"cpe:2.3:a:uncannyowl:uncanny_automator:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -15950,6 +16166,9 @@
|
||||
"vaultpress": [
|
||||
"cpe:2.3:a:automattic:vaultpress:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"vc-tabs": [
|
||||
"cpe:2.3:a:oxilab:responsive_tabs:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"verge3d": [
|
||||
"cpe:2.3:a:soft8soft:verge3d:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -16016,6 +16235,9 @@
|
||||
"vikrentcar": [
|
||||
"cpe:2.3:a:e4jconnect:vikrentcar:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"vimeography": [
|
||||
"cpe:2.3:a:davekiss:vimeography:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"vision": [
|
||||
"cpe:2.3:a:vision_interactive_project:vision_interactive:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -16252,6 +16474,9 @@
|
||||
"weixin-robot-advanced": [
|
||||
"cpe:2.3:a:wpjam:wechat_robot:*:*:*:*:premium:wordpress:*:*"
|
||||
],
|
||||
"wemail": [
|
||||
"cpe:2.3:a:wedevs:wemail:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"wf-cookie-consent": [
|
||||
"cpe:2.3:a:wunderfarm:wf_cookie_consent:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -16759,6 +16984,9 @@
|
||||
"wp-bitly": [
|
||||
"cpe:2.3:a:bitly:bitly:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"wp-blog-post-layouts": [
|
||||
"cpe:2.3:a:codevibrant:wp_blog_post_layouts:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"wp-blogs-planetarium": [
|
||||
"cpe:2.3:a:wp-blogs-planetarium_project:wp-blogs-planetarium:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -16789,6 +17017,9 @@
|
||||
"wp-cachecom": [
|
||||
"cpe:2.3:a:kenthhagstrom:wp-cachecom:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"wp-cafe": [
|
||||
"cpe:2.3:a:themewinter:wpcafe:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"wp-calendar": [
|
||||
"cpe:2.3:a:wp_calendar_project:wp_calendar:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -16829,6 +17060,9 @@
|
||||
"wp-chgfontsize": [
|
||||
"cpe:2.3:a:wp-chgfontsize_project:wp-chgfontsize:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"wp-child-theme-generator": [
|
||||
"cpe:2.3:a:wensolutions:wp_child_theme_generator:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"wp-cirrus": [
|
||||
"cpe:2.3:a:wp-cirrus_project:wp-cirrus:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -17078,6 +17312,9 @@
|
||||
"wp-file-manager": [
|
||||
"cpe:2.3:a:webdesi9:file_manager:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"wp-file-manager-pro": [
|
||||
"cpe:2.3:a:filemanagerpro:file_manager_pro:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"wp-file-upload": [
|
||||
"cpe:2.3:a:iptanus:wordpress_file_upload:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -17178,6 +17415,9 @@
|
||||
"wp-hide": [
|
||||
"cpe:2.3:a:weberge:wp_hide:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"wp-hide-backed-notices": [
|
||||
"cpe:2.3:a:wprepublic:hide_dashboard_notifications:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"wp-hide-pages": [
|
||||
"cpe:2.3:a:nxsn:wp_hide_pages:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -17428,7 +17668,8 @@
|
||||
],
|
||||
"wp-photo-album-plus": [
|
||||
"cpe:2.3:a:wp_photo_album_plus_project:wp_photo_album_plus:*:*:*:*:*:wordpress:*:*",
|
||||
"cpe:2.3:a:wppa.opajaap:wp-photo-album-plus:*:*:*:*:*:wordpress:*:*"
|
||||
"cpe:2.3:a:wppa.opajaap:wp-photo-album-plus:*:*:*:*:*:wordpress:*:*",
|
||||
"cpe:2.3:a:wppa:wp_photo_album_plus:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"wp-photo-text-slider-50": [
|
||||
"cpe:2.3:a:gopiplus:wp_photo_text_slider_50:*:*:*:*:*:wordpress:*:*"
|
||||
@@ -17473,6 +17714,9 @@
|
||||
"wp-popups-lite": [
|
||||
"cpe:2.3:a:timersys:wp_popups:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"wp-post-author": [
|
||||
"cpe:2.3:a:afthemes:wp_post_author:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"wp-post-columns": [
|
||||
"cpe:2.3:a:wp_post_columns_project:wp_post_columns:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -17509,6 +17753,9 @@
|
||||
"wp-reactions-lite": [
|
||||
"cpe:2.3:a:wpreactions:wp_reactions_lite:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"wp-recall": [
|
||||
"cpe:2.3:a:plechevandrey:wp-recall:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"wp-recipe-maker": [
|
||||
"cpe:2.3:a:bootstrapped:wp_recipe_maker:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -17854,12 +18101,18 @@
|
||||
"wp-voting-contest": [
|
||||
"cpe:2.3:a:ohiowebtech:wp_voting_contest:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"wp-whatsapp": [
|
||||
"cpe:2.3:a:ninjateam:wp_chat_app:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"wp-whatsapp-chat": [
|
||||
"cpe:2.3:a:quadlayers:wp_social_chat:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"wp-whois-domain": [
|
||||
"cpe:2.3:a:netattingo:wp-whois-domain:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"wp-widget-bundle": [
|
||||
"cpe:2.3:a:devnath_verma:widget_bundle:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"wp-woocommerce-quickbooks": [
|
||||
"cpe:2.3:a:crmperks:integration_for_woocommerce_and_quickbooks:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -18041,6 +18294,7 @@
|
||||
"cpe:2.3:a:wpstream:wpstream:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"wptools": [
|
||||
"cpe:2.3:a:billminozzi:wp_tools:*:*:*:*:*:wordpress:*:*",
|
||||
"cpe:2.3:a:wptools_project:wptools:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"wptouch": [
|
||||
@@ -18058,6 +18312,9 @@
|
||||
"wpvr": [
|
||||
"cpe:2.3:a:coderex:wp_vr:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"wpzoom-elementor-addons": [
|
||||
"cpe:2.3:a:wpzoom:wpzoom_elementor_addons:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"wpzoom-portfolio": [
|
||||
"cpe:2.3:a:wpzoom:wpzoom_portfolio:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -18165,6 +18422,9 @@
|
||||
"yith-desktop-notifications-for-woocommerce": [
|
||||
"cpe:2.3:a:yithemes:yith_desktop_notifications_for_woocommerce:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"yith-essential-kit-for-woocommerce-1": [
|
||||
"cpe:2.3:a:yithemes:yith_essential_kit_for_woocommerce:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"yith-maintenance-mode": [
|
||||
"cpe:2.3:a:yithemes:yith_maintenance_mode:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -18175,6 +18435,9 @@
|
||||
"yith-woocommerce-product-add-ons": [
|
||||
"cpe:2.3:a:yithemes:yith_woocommerce_product_add-ons:*:*:*:*:free:wordpress:*:*"
|
||||
],
|
||||
"ymc-smart-filter": [
|
||||
"cpe:2.3:a:ymc-22:filter_\\\u0026_grids:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"yookassa": [
|
||||
"cpe:2.3:a:yookassa:yukassa_for_woocommerce:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -18288,6 +18551,9 @@
|
||||
"zoho-forms": [
|
||||
"cpe:2.3:a:zohocorp:zoho_forms:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"zoho-marketinghub": [
|
||||
"cpe:2.3:a:zoho:zoho_marketing_automation:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"zoho-salesiq": [
|
||||
"cpe:2.3:a:zoho:salesiq:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -18341,6 +18607,9 @@
|
||||
"auberge": [
|
||||
"cpe:2.3:a:webmandesign:auberge_theme:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"author": [
|
||||
"cpe:2.3:a:sinatrateam:sinatra:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"big-store": [
|
||||
"cpe:2.3:a:themehunk:big_store:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -18356,6 +18625,9 @@
|
||||
"bonkers": [
|
||||
"cpe:2.3:a:colorlib:bonkers:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"book-landing-page": [
|
||||
"cpe:2.3:a:rarathemes:book_landing_page:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"brilliance": [
|
||||
"cpe:2.3:a:cpothemes:brilliance:*:*:*:*:*:wordpress:*:*",
|
||||
"cpe:2.3:a:wpchill:brilliance:*:*:*:*:*:wordpress:*:*"
|
||||
@@ -18372,12 +18644,18 @@
|
||||
"construction-lite": [
|
||||
"cpe:2.3:a:accesspressthemes:construction_lite:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"cozipress": [
|
||||
"cpe:2.3:a:burgersoftwares:cozipress:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"customizr": [
|
||||
"cpe:2.3:a:presscustomizr:customizr:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"darcie": [
|
||||
"cpe:2.3:a:catchthemes:darcie:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"digital-newspaper": [
|
||||
"cpe:2.3:a:blazethemes:digital_newspaper:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"digitally": [
|
||||
"cpe:2.3:a:omarfolgheraiter:digitally:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -18393,9 +18671,16 @@
|
||||
"enlighten": [
|
||||
"cpe:2.3:a:accesspressthemes:enlighten:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"esteem": [
|
||||
"cpe:2.3:a:themegrill:esteem:*:*:*:*:*:wordpress:*:*",
|
||||
"cpe:2.3:a:themegrill:esteem:*:*:*:*:free:wordpress:*:*"
|
||||
],
|
||||
"everest-news": [
|
||||
"cpe:2.3:a:everestthemes:everest_news:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"excellent": [
|
||||
"cpe:2.3:a:themefreesia:excellent:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"flashy": [
|
||||
"cpe:2.3:a:flashy_project:flashy:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -18412,12 +18697,18 @@
|
||||
"cpe:2.3:a:generatepress:generatepress:*:*:*:*:-:wordpress:*:*",
|
||||
"cpe:2.3:a:generatepress:generatepress:*:*:*:*:premium:wordpress:*:*"
|
||||
],
|
||||
"grey-opaque": [
|
||||
"cpe:2.3:a:grey_opaque_project:grey_opaque:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"hueman": [
|
||||
"cpe:2.3:a:presscustomizr:hueman:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"illdy": [
|
||||
"cpe:2.3:a:colorlib:illdy:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"interface": [
|
||||
"cpe:2.3:a:themehorse:interface:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"kata": [
|
||||
"cpe:2.3:a:climaxthemes:kata:*:*:*:*:*:wordpress:*:*",
|
||||
"cpe:2.3:a:climaxthemes:kata_apps:*:*:*:*:*:wordpress:*:*",
|
||||
@@ -18438,6 +18729,9 @@
|
||||
"morning-coffee": [
|
||||
"cpe:2.3:a:adazing:morning_coffee:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"mosaic": [
|
||||
"cpe:2.3:a:wildweblab:mosaic:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"newsmag": [
|
||||
"cpe:2.3:a:machothemes:newsmag:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -18465,12 +18759,18 @@
|
||||
"responsive": [
|
||||
"cpe:2.3:a:cyberchimps:responsive:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"rife-free": [
|
||||
"cpe:2.3:a:apollo13themes:rife_free:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"royal-elementor-kit": [
|
||||
"cpe:2.3:a:royal-elementor-addons:royal_elementor_kit:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"shapely": [
|
||||
"cpe:2.3:a:colorlib:shapely:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"sinatra": [
|
||||
"cpe:2.3:a:sinatrateam:sinatra:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"sparkling": [
|
||||
"cpe:2.3:a:colorlib:sparklinkg:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
|
||||
@@ -127,6 +127,7 @@ func FromDictionaryFind(p pkg.Package) ([]cpe.CPE, bool) {
|
||||
return []cpe.CPE{}, false
|
||||
}
|
||||
|
||||
sort.Sort(cpe.BySourceThenSpecificity(parsedCPEs))
|
||||
return parsedCPEs, true
|
||||
}
|
||||
|
||||
@@ -163,12 +164,12 @@ func FromPackageAttributes(p pkg.Package) []cpe.CPE {
|
||||
// filter out any known combinations that don't accurately represent this package
|
||||
cpes = filter(cpes, p, cpeFilters...)
|
||||
|
||||
sort.Sort(cpe.BySpecificity(cpes))
|
||||
var result []cpe.CPE
|
||||
for _, c := range cpes {
|
||||
result = append(result, cpe.CPE{Attributes: c, Source: cpe.GeneratedSource})
|
||||
}
|
||||
|
||||
sort.Sort(cpe.BySourceThenSpecificity(result))
|
||||
return result
|
||||
}
|
||||
|
||||
|
||||
@@ -203,6 +203,8 @@ func TestGeneratePackageCPEs(t *testing.T) {
|
||||
"cpe:2.3:a:nexus:nexus:3.2:*:*:*:*:*:*:*",
|
||||
"cpe:2.3:a:sonatype:name:3.2:*:*:*:*:*:*:*",
|
||||
"cpe:2.3:a:sonatype:nexus:3.2:*:*:*:*:*:*:*",
|
||||
"cpe:2.3:a:org.sonatype.nexus:name:3.2:*:*:*:*:*:*:*",
|
||||
"cpe:2.3:a:org.sonatype.nexus:nexus:3.2:*:*:*:*:*:*:*",
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -371,6 +373,7 @@ func TestGeneratePackageCPEs(t *testing.T) {
|
||||
"cpe:2.3:a:name:name:3.2:*:*:*:*:*:*:*",
|
||||
"cpe:2.3:a:jenkins:name:3.2:*:*:*:*:*:*:*",
|
||||
"cpe:2.3:a:cloudbees:name:3.2:*:*:*:*:*:*:*",
|
||||
"cpe:2.3:a:com.cloudbees.jenkins.plugins:name:3.2:*:*:*:*:*:*:*",
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -394,6 +397,8 @@ func TestGeneratePackageCPEs(t *testing.T) {
|
||||
"cpe:2.3:a:something:something:3.2:*:*:*:*:*:*:*",
|
||||
"cpe:2.3:a:jenkins:name:3.2:*:*:*:*:*:*:*",
|
||||
"cpe:2.3:a:jenkins:something:3.2:*:*:*:*:*:*:*",
|
||||
"cpe:2.3:a:io.jenkins.plugins.name.something:name:3.2:*:*:*:*:*:*:*",
|
||||
"cpe:2.3:a:io.jenkins.plugins.name.something:something:3.2:*:*:*:*:*:*:*",
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -413,6 +418,7 @@ func TestGeneratePackageCPEs(t *testing.T) {
|
||||
expected: []string{
|
||||
"cpe:2.3:a:name:name:3.2:*:*:*:*:*:*:*",
|
||||
"cpe:2.3:a:jenkins:name:3.2:*:*:*:*:*:*:*",
|
||||
"cpe:2.3:a:io.jenkins.plugins:name:3.2:*:*:*:*:*:*:*",
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -434,6 +440,7 @@ func TestGeneratePackageCPEs(t *testing.T) {
|
||||
"cpe:2.3:a:jenkins-ci:name:3.2:*:*:*:*:*:*:*",
|
||||
"cpe:2.3:a:jenkins:name:3.2:*:*:*:*:*:*:*",
|
||||
"cpe:2.3:a:jenkins_ci:name:3.2:*:*:*:*:*:*:*",
|
||||
"cpe:2.3:a:io.jenkins-ci.plugins:name:3.2:*:*:*:*:*:*:*",
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -455,6 +462,7 @@ func TestGeneratePackageCPEs(t *testing.T) {
|
||||
"cpe:2.3:a:jenkins-ci:name:3.2:*:*:*:*:*:*:*",
|
||||
"cpe:2.3:a:jenkins:name:3.2:*:*:*:*:*:*:*",
|
||||
"cpe:2.3:a:jenkins_ci:name:3.2:*:*:*:*:*:*:*",
|
||||
"cpe:2.3:a:org.jenkins-ci.plugins:name:3.2:*:*:*:*:*:*:*",
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -489,6 +497,9 @@ func TestGeneratePackageCPEs(t *testing.T) {
|
||||
"cpe:2.3:a:jira_client_core:jira-client-core:3.2:*:*:*:*:*:*:*",
|
||||
"cpe:2.3:a:jira_client_core:jira:3.2:*:*:*:*:*:*:*",
|
||||
"cpe:2.3:a:jira_client_core:jira_client_core:3.2:*:*:*:*:*:*:*",
|
||||
"cpe:2.3:a:org.atlassian.jira:jira:3.2:*:*:*:*:*:*:*",
|
||||
"cpe:2.3:a:org.atlassian.jira:jira_client_core:3.2:*:*:*:*:*:*:*",
|
||||
"cpe:2.3:a:org.atlassian.jira:jira-client-core:3.2:*:*:*:*:*:*:*",
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -521,6 +532,8 @@ func TestGeneratePackageCPEs(t *testing.T) {
|
||||
"cpe:2.3:a:jenkins:cloudbees_installation_manager:2.89.0.33:*:*:*:*:*:*:*",
|
||||
"cpe:2.3:a:modules:cloudbees-installation-manager:2.89.0.33:*:*:*:*:*:*:*",
|
||||
"cpe:2.3:a:modules:cloudbees_installation_manager:2.89.0.33:*:*:*:*:*:*:*",
|
||||
"cpe:2.3:a:com.cloudbees.jenkins.modules:cloudbees_installation_manager:2.89.0.33:*:*:*:*:*:*:*",
|
||||
"cpe:2.3:a:com.cloudbees.jenkins.modules:cloudbees-installation-manager:2.89.0.33:*:*:*:*:*:*:*",
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -594,6 +607,7 @@ func TestGeneratePackageCPEs(t *testing.T) {
|
||||
"cpe:2.3:a:jenkins:handlebars:3.0.8:*:*:*:*:*:*:*",
|
||||
"cpe:2.3:a:jenkins_ci:handlebars:3.0.8:*:*:*:*:*:*:*",
|
||||
"cpe:2.3:a:ui:handlebars:3.0.8:*:*:*:*:*:*:*",
|
||||
"cpe:2.3:a:org.jenkins-ci.ui:handlebars:3.0.8:*:*:*:*:*:*:*",
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -631,6 +645,8 @@ func TestGeneratePackageCPEs(t *testing.T) {
|
||||
"cpe:2.3:a:jenkins:active_directory:2.25.1:*:*:*:*:*:*:*", // important!
|
||||
"cpe:2.3:a:jenkins_ci:active-directory:2.25.1:*:*:*:*:*:*:*",
|
||||
"cpe:2.3:a:jenkins_ci:active_directory:2.25.1:*:*:*:*:*:*:*",
|
||||
"cpe:2.3:a:org.jenkins-ci.plugins:active-directory:2.25.1:*:*:*:*:*:*:*",
|
||||
"cpe:2.3:a:org.jenkins-ci.plugins:active_directory:2.25.1:*:*:*:*:*:*:*",
|
||||
},
|
||||
},
|
||||
{
|
||||
|
||||
@@ -98,6 +98,13 @@ func vendorsFromJavaManifestNames(p pkg.Package) fieldCandidateSet {
|
||||
func vendorsFromGroupIDs(groupIDs []string) fieldCandidateSet {
|
||||
vendors := newFieldCandidateSet()
|
||||
for _, groupID := range groupIDs {
|
||||
// always include the groupId as a vendor -- the Grype database may include alternate matches with these
|
||||
vendors.add(fieldCandidate{
|
||||
value: groupID,
|
||||
disallowSubSelections: true,
|
||||
disallowDelimiterVariations: true,
|
||||
})
|
||||
|
||||
for i, field := range strings.Split(groupID, ".") {
|
||||
field = strings.TrimSpace(field)
|
||||
|
||||
|
||||
@@ -139,7 +139,7 @@ func Test_vendorsFromGroupIDs(t *testing.T) {
|
||||
}
|
||||
for _, test := range tests {
|
||||
t.Run(test.groupID, func(t *testing.T) {
|
||||
assert.ElementsMatch(t, test.expected, vendorsFromGroupIDs([]string{test.groupID}).values(), "different vendors")
|
||||
assert.ElementsMatch(t, append(test.expected, test.groupID), vendorsFromGroupIDs([]string{test.groupID}).values(), "different vendors")
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,8 +6,11 @@ import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path"
|
||||
"slices"
|
||||
"strings"
|
||||
|
||||
"golang.org/x/exp/maps"
|
||||
|
||||
intFile "github.com/anchore/syft/internal/file"
|
||||
"github.com/anchore/syft/internal/licenses"
|
||||
"github.com/anchore/syft/internal/log"
|
||||
@@ -298,7 +301,10 @@ func (j *archiveParser) guessMainPackageNameAndVersionFromPomInfo(ctx context.Co
|
||||
properties, _ := pomPropertiesByParentPath(j.archivePath, j.location, pomPropertyMatches)
|
||||
projects, _ := pomProjectByParentPath(j.archivePath, j.location, pomMatches)
|
||||
|
||||
for parentPath, propertiesObj := range properties {
|
||||
parentPaths := maps.Keys(properties)
|
||||
slices.Sort(parentPaths)
|
||||
for _, parentPath := range parentPaths {
|
||||
propertiesObj := properties[parentPath]
|
||||
if artifactIDMatchesFilename(propertiesObj.ArtifactID, j.fileInfo.name) {
|
||||
pomPropertiesObject = propertiesObj
|
||||
if proj, exists := projects[parentPath]; exists {
|
||||
|
||||
@@ -1386,6 +1386,44 @@ func Test_parseJavaArchive_regressions(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func Test_deterministicMatchingPomProperties(t *testing.T) {
|
||||
tests := []struct {
|
||||
fixture string
|
||||
expectedName string
|
||||
expectedVersion string
|
||||
}{
|
||||
{
|
||||
fixture: "multiple-matching-2.11.5",
|
||||
expectedName: "multiple-matching-1",
|
||||
expectedVersion: "2.11.5",
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run(test.fixture, func(t *testing.T) {
|
||||
fixturePath := generateJavaMetadataJarFixture(t, test.fixture)
|
||||
|
||||
for i := 0; i < 5; i++ {
|
||||
func() {
|
||||
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})
|
||||
defer cleanupFn()
|
||||
require.NoError(t, err)
|
||||
|
||||
name, version, _ := parser.guessMainPackageNameAndVersionFromPomInfo(context.TODO())
|
||||
require.Equal(t, test.expectedName, name)
|
||||
require.Equal(t, test.expectedVersion, version)
|
||||
}()
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func assignParent(parent *pkg.Package, childPackages ...pkg.Package) {
|
||||
for i, jp := range childPackages {
|
||||
if v, ok := jp.Metadata.(pkg.JavaArchive); ok {
|
||||
|
||||
@@ -6,6 +6,7 @@ SBT_JACKSON_CORE = com.fasterxml.jackson.core.jackson-core-2.15.2
|
||||
OPENSAML_CORE = opensaml-core-3.4.6
|
||||
API_ALL_SOURCES = api-all-2.0.0-sources
|
||||
SPRING_INSTRUMENTATION = spring-instrumentation-4.3.0-1.0
|
||||
MULTIPLE_MATCHING = multiple-matching-2.11.5
|
||||
|
||||
$(CACHE_DIR):
|
||||
mkdir -p $(CACHE_DIR)
|
||||
@@ -24,3 +25,6 @@ $(CACHE_DIR)/$(API_ALL_SOURCES).jar: $(CACHE_DIR)
|
||||
|
||||
$(CACHE_DIR)/$(SPRING_INSTRUMENTATION).jar: $(CACHE_DIR)
|
||||
cd $(SPRING_INSTRUMENTATION) && zip -r $(CACHE_PATH)/$(SPRING_INSTRUMENTATION).jar .
|
||||
|
||||
$(CACHE_DIR)/$(MULTIPLE_MATCHING).jar: $(CACHE_DIR)
|
||||
cd $(MULTIPLE_MATCHING) && zip -r $(CACHE_PATH)/$(MULTIPLE_MATCHING).jar .
|
||||
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
Manifest-Version: 1.0
|
||||
Created-By: Multi
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
version=2.11.5
|
||||
groupId=org.multiple
|
||||
artifactId=multiple-matching-1
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>org.multiple</groupId>
|
||||
<artifactId>multiple-matching-1</artifactId>
|
||||
<version>2.11.5</version>
|
||||
</project>
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
version=2.11.5
|
||||
groupId=org.multiple
|
||||
artifactId=multiple-matching-2
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>org.multiple</groupId>
|
||||
<artifactId>multiple-matching-2</artifactId>
|
||||
<version>2.11.5</version>
|
||||
</project>
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
version=2.11.5
|
||||
groupId=org.multiple
|
||||
artifactId=multiple-matching-3
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>org.multiple</groupId>
|
||||
<artifactId>multiple-matching-3</artifactId>
|
||||
<version>2.11.5</version>
|
||||
</project>
|
||||
@@ -119,9 +119,9 @@ func Test_PackageCataloger(t *testing.T) {
|
||||
"test-fixtures/dist-info/direct_url.json",
|
||||
},
|
||||
expectedPackage: pkg.Package{
|
||||
Name: "Pygments",
|
||||
Name: "pygments",
|
||||
Version: "2.6.1",
|
||||
PURL: "pkg:pypi/Pygments@2.6.1?vcs_url=git%2Bhttps://github.com/python-test/test.git%40aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
|
||||
PURL: "pkg:pypi/pygments@2.6.1?vcs_url=git%2Bhttps://github.com/python-test/test.git%40aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
|
||||
Type: pkg.PythonPkg,
|
||||
Language: pkg.Python,
|
||||
Licenses: pkg.NewLicenseSet(
|
||||
@@ -161,9 +161,9 @@ func Test_PackageCataloger(t *testing.T) {
|
||||
"test-fixtures/casesensitive/DIST-INFO/direct_url.json",
|
||||
},
|
||||
expectedPackage: pkg.Package{
|
||||
Name: "Pygments",
|
||||
Name: "pygments",
|
||||
Version: "2.6.1",
|
||||
PURL: "pkg:pypi/Pygments@2.6.1?vcs_url=git%2Bhttps://github.com/python-test/test.git%40aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
|
||||
PURL: "pkg:pypi/pygments@2.6.1?vcs_url=git%2Bhttps://github.com/python-test/test.git%40aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
|
||||
Type: pkg.PythonPkg,
|
||||
Language: pkg.Python,
|
||||
Licenses: pkg.NewLicenseSet(
|
||||
@@ -199,9 +199,9 @@ func Test_PackageCataloger(t *testing.T) {
|
||||
"test-fixtures/malformed-record/dist-info/RECORD",
|
||||
},
|
||||
expectedPackage: pkg.Package{
|
||||
Name: "Pygments",
|
||||
Name: "pygments",
|
||||
Version: "2.6.1",
|
||||
PURL: "pkg:pypi/Pygments@2.6.1",
|
||||
PURL: "pkg:pypi/pygments@2.6.1",
|
||||
Type: pkg.PythonPkg,
|
||||
Language: pkg.Python,
|
||||
Licenses: pkg.NewLicenseSet(
|
||||
@@ -231,9 +231,9 @@ func Test_PackageCataloger(t *testing.T) {
|
||||
name: "partial dist-info directory",
|
||||
fixtures: []string{"test-fixtures/partial.dist-info/METADATA"},
|
||||
expectedPackage: pkg.Package{
|
||||
Name: "Pygments",
|
||||
Name: "pygments",
|
||||
Version: "2.6.1",
|
||||
PURL: "pkg:pypi/Pygments@2.6.1",
|
||||
PURL: "pkg:pypi/pygments@2.6.1",
|
||||
Type: pkg.PythonPkg,
|
||||
Language: pkg.Python,
|
||||
Licenses: pkg.NewLicenseSet(
|
||||
|
||||
@@ -167,7 +167,7 @@ func wheelEggRelationships(ctx context.Context, resolver file.Resolver, pkgs []p
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("failed to resolve relationships for global site package %q: %w", globalSitePackage, err)
|
||||
}
|
||||
relationshipIndex.AddAll(siteRels...)
|
||||
relationshipIndex.Add(siteRels...)
|
||||
}
|
||||
|
||||
// create relationships between packages within each virtual env site package directory (that doesn't link to a global site-packages directory)
|
||||
@@ -180,7 +180,7 @@ func wheelEggRelationships(ctx context.Context, resolver file.Resolver, pkgs []p
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("failed to resolve relationships for virtualenv site package %q: %w", venv.SitePackagesPath, err)
|
||||
}
|
||||
relationshipIndex.AddAll(siteRels...)
|
||||
relationshipIndex.Add(siteRels...)
|
||||
}
|
||||
|
||||
// create relationships between packages within each virtual env site package directory (that links to a global site package directory)
|
||||
@@ -197,10 +197,10 @@ func wheelEggRelationships(ctx context.Context, resolver file.Resolver, pkgs []p
|
||||
return nil, nil, fmt.Errorf("failed to resolve relationships for virtualenv + global site package path %q + %q: %w", venv.SitePackagesPath, globalSitePackage, err)
|
||||
}
|
||||
|
||||
relationshipIndex.AddAll(siteRels...)
|
||||
relationshipIndex.Add(siteRels...)
|
||||
}
|
||||
|
||||
return pkgs, relationshipIndex.AllUniqueRelationships(), err
|
||||
return pkgs, relationshipIndex.All(), err
|
||||
}
|
||||
|
||||
func collectPackages(pkgsBySitePackageAndName map[string]map[string]pkg.Package, sites []string) []pkg.Package {
|
||||
|
||||
@@ -2,6 +2,8 @@ package python
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"github.com/anchore/packageurl-go"
|
||||
"github.com/anchore/syft/internal/licenses"
|
||||
@@ -10,7 +12,16 @@ import (
|
||||
"github.com/anchore/syft/syft/pkg"
|
||||
)
|
||||
|
||||
func normalize(name string) string {
|
||||
// https://packaging.python.org/en/latest/specifications/name-normalization/
|
||||
re := regexp.MustCompile(`[-_.]+`)
|
||||
normalized := re.ReplaceAllString(name, "-")
|
||||
return strings.ToLower(normalized)
|
||||
}
|
||||
|
||||
func newPackageForIndex(name, version string, locations ...file.Location) pkg.Package {
|
||||
name = normalize(name)
|
||||
|
||||
p := pkg.Package{
|
||||
Name: name,
|
||||
Version: version,
|
||||
@@ -26,6 +37,8 @@ func newPackageForIndex(name, version string, locations ...file.Location) pkg.Pa
|
||||
}
|
||||
|
||||
func newPackageForIndexWithMetadata(name, version string, metadata interface{}, locations ...file.Location) pkg.Package {
|
||||
name = normalize(name)
|
||||
|
||||
p := pkg.Package{
|
||||
Name: name,
|
||||
Version: version,
|
||||
@@ -42,6 +55,8 @@ func newPackageForIndexWithMetadata(name, version string, metadata interface{},
|
||||
}
|
||||
|
||||
func newPackageForRequirementsWithMetadata(name, version string, metadata pkg.PythonRequirementsEntry, locations ...file.Location) pkg.Package {
|
||||
name = normalize(name)
|
||||
|
||||
p := pkg.Package{
|
||||
Name: name,
|
||||
Version: version,
|
||||
@@ -87,10 +102,12 @@ func newPackageForPackage(resolver file.Resolver, m parsedData, sources ...file.
|
||||
}
|
||||
}
|
||||
|
||||
name := normalize(m.Name)
|
||||
|
||||
p := pkg.Package{
|
||||
Name: m.Name,
|
||||
Name: name,
|
||||
Version: m.Version,
|
||||
PURL: packageURL(m.Name, m.Version, &m.PythonPackage),
|
||||
PURL: packageURL(name, m.Version, &m.PythonPackage),
|
||||
Locations: file.NewLocationSet(sources...),
|
||||
Licenses: licenseSet,
|
||||
Language: pkg.Python,
|
||||
|
||||
@@ -44,3 +44,21 @@ func Test_packageURL(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func Test_normalization(t *testing.T) {
|
||||
normalForm := "friendly-bard"
|
||||
tests := []string{
|
||||
normalForm,
|
||||
"Friendly-Bard",
|
||||
"FRIENDLY-BARD",
|
||||
"friendly.bard",
|
||||
"friendly_bard",
|
||||
"friendly--bard",
|
||||
"FrIeNdLy-._.-bArD",
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt, func(t *testing.T) {
|
||||
assert.Equal(t, normalForm, normalize(tt))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@ const (
|
||||
// --hash=sha256:e9535b8c84dc9571a48999094fda7f33e63c3f1b74f3e5f3ac0105a58405bb65 # some comment
|
||||
|
||||
// namePattern matches: requests[security]
|
||||
namePattern = `(?P<name>\w[\w\[\],\s-_]+)`
|
||||
namePattern = `(?P<name>\w[\w\[\],\s-_\.]+)`
|
||||
|
||||
// versionConstraintPattern matches: == 2.8.*
|
||||
versionConstraintPattern = `(?P<versionConstraint>([^\S\r\n]*[~=>!<]+\s*[0-9a-zA-Z.*]+[^\S\r\n]*,?)+)?(@[^\S\r\n]*(?P<url>[^;]*))?`
|
||||
|
||||
@@ -41,9 +41,9 @@ func TestParseRequirementsTxt(t *testing.T) {
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "SomeProject",
|
||||
Name: "someproject",
|
||||
Version: "5.4",
|
||||
PURL: "pkg:pypi/SomeProject@5.4",
|
||||
PURL: "pkg:pypi/someproject@5.4",
|
||||
Locations: locations,
|
||||
Language: pkg.Python,
|
||||
Type: pkg.PythonPkg,
|
||||
@@ -53,6 +53,18 @@ func TestParseRequirementsTxt(t *testing.T) {
|
||||
Markers: "python_version < '3.8'",
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "dots-allowed",
|
||||
Version: "1.0.0",
|
||||
PURL: "pkg:pypi/dots-allowed@1.0.0",
|
||||
Locations: locations,
|
||||
Language: pkg.Python,
|
||||
Type: pkg.PythonPkg,
|
||||
Metadata: pkg.PythonRequirementsEntry{
|
||||
Name: "dots-._allowed",
|
||||
VersionConstraint: "== 1.0.0",
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "argh",
|
||||
Version: "0.26.2",
|
||||
@@ -91,9 +103,9 @@ func TestParseRequirementsTxt(t *testing.T) {
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "GithubSampleProject",
|
||||
Name: "githubsampleproject",
|
||||
Version: "3.7.1",
|
||||
PURL: "pkg:pypi/GithubSampleProject@3.7.1",
|
||||
PURL: "pkg:pypi/githubsampleproject@3.7.1",
|
||||
Locations: locations,
|
||||
Language: pkg.Python,
|
||||
Type: pkg.PythonPkg,
|
||||
@@ -103,6 +115,18 @@ func TestParseRequirementsTxt(t *testing.T) {
|
||||
URL: "git+https://github.com/owner/repo@releases/tag/v3.7.1",
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "friendly-bard",
|
||||
Version: "1.0.0",
|
||||
PURL: "pkg:pypi/friendly-bard@1.0.0",
|
||||
Locations: locations,
|
||||
Language: pkg.Python,
|
||||
Type: pkg.PythonPkg,
|
||||
Metadata: pkg.PythonRequirementsEntry{
|
||||
Name: "FrIeNdLy-_-bArD",
|
||||
VersionConstraint: "== 1.0.0",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
var testCases = []struct {
|
||||
@@ -128,9 +152,9 @@ func TestParseRequirementsTxt(t *testing.T) {
|
||||
},
|
||||
expectedPkgs: append([]pkg.Package{
|
||||
{
|
||||
Name: "Mopidy-Dirble",
|
||||
Name: "mopidy-dirble",
|
||||
Version: "1.1",
|
||||
PURL: "pkg:pypi/Mopidy-Dirble@1.1",
|
||||
PURL: "pkg:pypi/mopidy-dirble@1.1",
|
||||
Locations: locations,
|
||||
Language: pkg.Python,
|
||||
Type: pkg.PythonPkg,
|
||||
|
||||
@@ -8,6 +8,7 @@ bar >= 1.0.0, <= 2.0.0, \
|
||||
-r other-requirements.txt
|
||||
--requirements super-secretrequirements.txt
|
||||
SomeProject ==5.4 ; python_version < '3.8'
|
||||
dots-._allowed == 1.0.0
|
||||
coverage != 3.5 # Version Exclusion. Anything except version 3.5
|
||||
numpyNew; sys_platform == 'win32'
|
||||
numpy >= 3.4.1; sys_platform == 'win32'
|
||||
@@ -22,3 +23,4 @@ argh==0.26.3 --hash=sha256:a9b3aaa1904eeb78e32394cd46c6f37ac0fb4af6dc488daa58971
|
||||
celery[redis, pytest] == 4.4.7 # should remove [redis, pytest]
|
||||
requests[security] == 2.8.* ; python_version < "2.7" and sys_platform == "linux"
|
||||
GithubSampleProject == 3.7.1 @ git+https://github.com/owner/repo@releases/tag/v3.7.1
|
||||
FrIeNdLy-_-bArD == 1.0.0
|
||||
|
||||
@@ -8,6 +8,7 @@ import (
|
||||
rpmdb "github.com/knqyf263/go-rpmdb/pkg"
|
||||
"github.com/sassoftware/go-rpmutils"
|
||||
|
||||
"github.com/anchore/syft/internal/log"
|
||||
"github.com/anchore/syft/syft/artifact"
|
||||
"github.com/anchore/syft/syft/file"
|
||||
"github.com/anchore/syft/syft/pkg"
|
||||
@@ -26,12 +27,22 @@ func parseRpmArchive(_ context.Context, _ file.Resolver, _ *generic.Environment,
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
licenses, _ := rpm.Header.GetStrings(rpmutils.LICENSE)
|
||||
sourceRpm, _ := rpm.Header.GetString(rpmutils.SOURCERPM)
|
||||
vendor, _ := rpm.Header.GetString(rpmutils.VENDOR)
|
||||
digestAlgorithm := getDigestAlgorithm(rpm.Header)
|
||||
size, _ := rpm.Header.InstalledSize()
|
||||
files, _ := rpm.Header.GetFiles()
|
||||
licenses, err := rpm.Header.GetStrings(rpmutils.LICENSE)
|
||||
logRpmArchiveErr(reader.Location, "license", err)
|
||||
|
||||
sourceRpm, err := rpm.Header.GetString(rpmutils.SOURCERPM)
|
||||
logRpmArchiveErr(reader.Location, "sourcerpm", err)
|
||||
|
||||
vendor, err := rpm.Header.GetString(rpmutils.VENDOR)
|
||||
logRpmArchiveErr(reader.Location, "vendor", err)
|
||||
|
||||
digestAlgorithm := getDigestAlgorithm(reader.Location, rpm.Header)
|
||||
|
||||
size, err := rpm.Header.InstalledSize()
|
||||
logRpmArchiveErr(reader.Location, "size", err)
|
||||
|
||||
files, err := rpm.Header.GetFiles()
|
||||
logRpmArchiveErr(reader.Location, "files", err)
|
||||
|
||||
metadata := pkg.RpmArchive{
|
||||
Name: nevra.Name,
|
||||
@@ -48,12 +59,16 @@ func parseRpmArchive(_ context.Context, _ file.Resolver, _ *generic.Environment,
|
||||
return []pkg.Package{newArchivePackage(reader.Location, metadata, licenses)}, nil, nil
|
||||
}
|
||||
|
||||
func getDigestAlgorithm(header *rpmutils.RpmHeader) string {
|
||||
digestAlgorithm, _ := header.GetString(rpmutils.FILEDIGESTALGO)
|
||||
func getDigestAlgorithm(location file.Location, header *rpmutils.RpmHeader) string {
|
||||
digestAlgorithm, err := header.GetString(rpmutils.FILEDIGESTALGO)
|
||||
logRpmArchiveErr(location, "file digest algo", err)
|
||||
|
||||
if digestAlgorithm != "" {
|
||||
return digestAlgorithm
|
||||
}
|
||||
digestAlgorithms, _ := header.GetUint32s(rpmutils.FILEDIGESTALGO)
|
||||
digestAlgorithms, err := header.GetUint32s(rpmutils.FILEDIGESTALGO)
|
||||
logRpmArchiveErr(location, "file digest algo 32-bit", err)
|
||||
|
||||
if len(digestAlgorithms) > 0 {
|
||||
digestAlgo := int(digestAlgorithms[0])
|
||||
return rpmutils.GetFileAlgoName(digestAlgo)
|
||||
@@ -91,3 +106,9 @@ func parseEpoch(epoch string) *int {
|
||||
}
|
||||
return &i
|
||||
}
|
||||
|
||||
func logRpmArchiveErr(location file.Location, operation string, err error) {
|
||||
if err != nil {
|
||||
log.Debugf("ERROR in parse_rpm_archive %s file: %s: %v", operation, location.RealPath, err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -121,7 +121,7 @@ func pinsForVersion(data map[string]interface{}, version float64) ([]packagePin,
|
||||
pin.State.Version,
|
||||
})
|
||||
}
|
||||
case 2:
|
||||
case 2, 3:
|
||||
t := packageResolvedV2{}
|
||||
jsonString, err := json.Marshal(data)
|
||||
if err != nil {
|
||||
|
||||
@@ -80,6 +80,40 @@ func TestParsePackageResolved(t *testing.T) {
|
||||
pkgtest.TestFileParser(t, fixture, parsePackageResolved, expectedPkgs, expectedRelationships)
|
||||
}
|
||||
|
||||
func TestParsePackageResolvedV3(t *testing.T) {
|
||||
fixture := "test-fixtures/PackageV3.resolved"
|
||||
locations := file.NewLocationSet(file.NewLocation(fixture))
|
||||
expectedPkgs := []pkg.Package{
|
||||
{
|
||||
Name: "swift-mmio",
|
||||
Version: "",
|
||||
PURL: "pkg:swift/github.com/apple/swift-mmio/swift-mmio",
|
||||
Locations: locations,
|
||||
Language: pkg.Swift,
|
||||
Type: pkg.SwiftPkg,
|
||||
Metadata: pkg.SwiftPackageManagerResolvedEntry{
|
||||
Revision: "80c109b87511041338a4d8d88064088c8dfc079b",
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "swift-syntax",
|
||||
Version: "509.1.1",
|
||||
PURL: "pkg:swift/github.com/apple/swift-syntax.git/swift-syntax@509.1.1",
|
||||
Locations: locations,
|
||||
Language: pkg.Swift,
|
||||
Type: pkg.SwiftPkg,
|
||||
Metadata: pkg.SwiftPackageManagerResolvedEntry{
|
||||
Revision: "64889f0c732f210a935a0ad7cda38f77f876262d",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
// TODO: no relationships are under test yet
|
||||
var expectedRelationships []artifact.Relationship
|
||||
|
||||
pkgtest.TestFileParser(t, fixture, parsePackageResolved, expectedPkgs, expectedRelationships)
|
||||
}
|
||||
|
||||
func TestParsePackageResolved_empty(t *testing.T) {
|
||||
// regression for https://github.com/anchore/syft/issues/2225
|
||||
fixture := "test-fixtures/empty-packages.resolved"
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
{
|
||||
"originHash" : "ea83017c944c7850b8f60207e6143eb17cb6b5e6b734b3fa08787a5d920dba7b",
|
||||
"pins" : [
|
||||
{
|
||||
"identity" : "swift-mmio",
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/apple/swift-mmio",
|
||||
"state" : {
|
||||
"branch" : "swift-embedded-examples",
|
||||
"revision" : "80c109b87511041338a4d8d88064088c8dfc079b"
|
||||
}
|
||||
},
|
||||
{
|
||||
"identity" : "swift-syntax",
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/apple/swift-syntax.git",
|
||||
"state" : {
|
||||
"revision" : "64889f0c732f210a935a0ad7cda38f77f876262d",
|
||||
"version" : "509.1.1"
|
||||
}
|
||||
}
|
||||
],
|
||||
"version" : 3
|
||||
}
|
||||
@@ -35,6 +35,8 @@ type Descriptor struct {
|
||||
Configuration interface{}
|
||||
}
|
||||
|
||||
// RelationshipsSorted returns a sorted slice of all relationships
|
||||
// Deprecated -- use relationship.Index
|
||||
func (s SBOM) RelationshipsSorted() []artifact.Relationship {
|
||||
relationships := s.Relationships
|
||||
sort.SliceStable(relationships, func(i, j int) bool {
|
||||
@@ -70,6 +72,7 @@ func (s SBOM) AllCoordinates() []file.Coordinates {
|
||||
|
||||
// RelationshipsForPackage returns all relationships for the provided types.
|
||||
// If no types are provided, all relationships for the package are returned.
|
||||
// Deprecated -- use relationship.Index
|
||||
func (s SBOM) RelationshipsForPackage(p pkg.Package, rt ...artifact.RelationshipType) []artifact.Relationship {
|
||||
if len(rt) == 0 {
|
||||
rt = artifact.AllRelationshipTypes()
|
||||
@@ -103,6 +106,7 @@ func (s SBOM) RelationshipsForPackage(p pkg.Package, rt ...artifact.Relationship
|
||||
|
||||
// CoordinatesForPackage returns all coordinates for the provided package for provided relationship types
|
||||
// If no types are provided, all relationship types are considered.
|
||||
// Deprecated -- use relationship.Index
|
||||
func (s SBOM) CoordinatesForPackage(p pkg.Package, rt ...artifact.RelationshipType) []file.Coordinates {
|
||||
var coordinates []file.Coordinates
|
||||
for _, relationship := range s.RelationshipsForPackage(p, rt...) {
|
||||
|
||||
Reference in New Issue
Block a user