mirror of
https://github.com/anchore/syft.git
synced 2026-10-25 03:22:22 +01:00
Compare commits
+5
-5
@@ -26,7 +26,7 @@ tools:
|
||||
# used for linting
|
||||
- name: golangci-lint
|
||||
version:
|
||||
want: v2.2.2
|
||||
want: v2.3.1
|
||||
method: github-release
|
||||
with:
|
||||
repo: golangci/golangci-lint
|
||||
@@ -58,7 +58,7 @@ tools:
|
||||
# used to release all artifacts
|
||||
- name: goreleaser
|
||||
version:
|
||||
want: v2.11.0
|
||||
want: v2.11.2
|
||||
method: github-release
|
||||
with:
|
||||
repo: goreleaser/goreleaser
|
||||
@@ -90,7 +90,7 @@ tools:
|
||||
# used for running all local and CI tasks
|
||||
- name: task
|
||||
version:
|
||||
want: v3.44.0
|
||||
want: v3.44.1
|
||||
method: github-release
|
||||
with:
|
||||
repo: go-task/task
|
||||
@@ -98,7 +98,7 @@ tools:
|
||||
# used for triggering a release
|
||||
- name: gh
|
||||
version:
|
||||
want: v2.76.0
|
||||
want: v2.76.2
|
||||
method: github-release
|
||||
with:
|
||||
repo: cli/cli
|
||||
@@ -114,7 +114,7 @@ tools:
|
||||
# used to upload test fixture cache
|
||||
- name: yq
|
||||
version:
|
||||
want: v4.46.1
|
||||
want: v4.47.1
|
||||
method: github-release
|
||||
with:
|
||||
repo: mikefarah/yq
|
||||
|
||||
@@ -37,7 +37,7 @@ runs:
|
||||
- name: Restore tool cache
|
||||
if: inputs.tools == 'true'
|
||||
id: tool-cache
|
||||
uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3
|
||||
uses: actions/cache@0400d5f644dc74513175e3cd8d07132dd4860809 # v4.2.4
|
||||
with:
|
||||
path: ${{ github.workspace }}/.tool
|
||||
key: ${{ inputs.cache-key-prefix }}-${{ runner.os }}-tool-${{ hashFiles('.binny.yaml') }}
|
||||
@@ -63,7 +63,7 @@ runs:
|
||||
|
||||
- name: Restore ORAS cache from github actions
|
||||
if: inputs.download-test-fixture-cache == 'true'
|
||||
uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3
|
||||
uses: actions/cache@0400d5f644dc74513175e3cd8d07132dd4860809 # v4.2.4
|
||||
with:
|
||||
path: ${{ github.workspace }}/.tmp/oras-cache
|
||||
key: ${{ inputs.cache-key-prefix }}-oras-cache
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
set -ue
|
||||
|
||||
BIN="syft"
|
||||
VERSION_FILE="VERSION"
|
||||
VERSION=$1
|
||||
|
||||
# the source of truth as to whether we want to notify users of an update is if the release just created is NOT
|
||||
# flagged as a pre-release on github
|
||||
if [[ "$(curl -SsL https://api.github.com/repos/anchore/${BIN}/releases/tags/${VERSION} | jq .prerelease)" == "true" ]] ; then
|
||||
echo "skipping publishing a version file (this is a pre-release: ${VERSION})"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo "creating and publishing version file (${VERSION})"
|
||||
|
||||
# create a version file for version-update checks
|
||||
echo "${VERSION}" | tee "${VERSION_FILE}"
|
||||
|
||||
# upload the version file that supports the application version update check
|
||||
export AWS_DEFAULT_REGION=us-west-2
|
||||
aws s3 cp "${VERSION_FILE}" s3://toolbox-data.anchore.io/${BIN}/releases/latest/VERSION
|
||||
@@ -47,7 +47,7 @@ jobs:
|
||||
|
||||
# Initializes the CodeQL tools for scanning.
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@181d5eefc20863364f96762470ba6f862bdef56b #v3.29.2
|
||||
uses: github/codeql-action/init@76621b61decf072c1cee8dd1ce2d2a82d33c17ed #v3.29.5
|
||||
with:
|
||||
languages: ${{ matrix.language }}
|
||||
# If you wish to specify custom queries, you can do so here or in a config file.
|
||||
@@ -58,7 +58,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@181d5eefc20863364f96762470ba6f862bdef56b #v3.29.2
|
||||
uses: github/codeql-action/autobuild@76621b61decf072c1cee8dd1ce2d2a82d33c17ed #v3.29.5
|
||||
|
||||
# ℹ️ Command-line programs to run using the OS shell.
|
||||
# 📚 https://git.io/JvXDl
|
||||
@@ -72,4 +72,4 @@ jobs:
|
||||
# make release
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@181d5eefc20863364f96762470ba6f862bdef56b #v3.29.2
|
||||
uses: github/codeql-action/analyze@76621b61decf072c1cee8dd1ce2d2a82d33c17ed #v3.29.5
|
||||
|
||||
@@ -1,40 +0,0 @@
|
||||
name: "Release: version file"
|
||||
|
||||
on:
|
||||
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
version:
|
||||
description: release version to update the version file with (prefixed with v)
|
||||
required: true
|
||||
|
||||
workflow_call:
|
||||
inputs:
|
||||
version:
|
||||
type: string
|
||||
description: release version to update the version file with (prefixed with v)
|
||||
required: true
|
||||
secrets:
|
||||
TOOLBOX_AWS_ACCESS_KEY_ID:
|
||||
required: true
|
||||
TOOLBOX_AWS_SECRET_ACCESS_KEY:
|
||||
required: true
|
||||
|
||||
jobs:
|
||||
|
||||
release:
|
||||
runs-on: ubuntu-24.04
|
||||
permissions:
|
||||
contents: read
|
||||
steps:
|
||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 #v4.2.2
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- name: Update version file
|
||||
run: make ci-release-version-file
|
||||
env:
|
||||
RELEASE_VERSION: ${{ github.event.inputs.version }}
|
||||
# for updating the VERSION file in S3...
|
||||
AWS_ACCESS_KEY_ID: ${{ secrets.TOOLBOX_AWS_ACCESS_KEY_ID }}
|
||||
AWS_SECRET_ACCESS_KEY: ${{ secrets.TOOLBOX_AWS_SECRET_ACCESS_KEY }}
|
||||
@@ -125,13 +125,13 @@ jobs:
|
||||
uses: ./.github/actions/bootstrap
|
||||
|
||||
- name: Login to Docker Hub
|
||||
uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 #v3.4.0
|
||||
uses: docker/login-action@184bdaa0721073962dff0199f1fb9940f07167d1 #v3.5.0
|
||||
with:
|
||||
username: ${{ secrets.ANCHOREOSSWRITE_DH_USERNAME }}
|
||||
password: ${{ secrets.ANCHOREOSSWRITE_DH_PAT }}
|
||||
|
||||
- name: Login to GitHub Container Registry
|
||||
uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 #v3.4.0
|
||||
uses: docker/login-action@184bdaa0721073962dff0199f1fb9940f07167d1 #v3.5.0
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.actor }}
|
||||
@@ -161,7 +161,7 @@ jobs:
|
||||
# for updating brew formula in anchore/homebrew-syft
|
||||
GITHUB_BREW_TOKEN: ${{ secrets.ANCHOREOPS_GITHUB_OSS_WRITE_TOKEN }}
|
||||
|
||||
- uses: anchore/sbom-action@cee1b8e05ae5b2593a75e197229729eabaa9f8ec #v0.20.2
|
||||
- uses: anchore/sbom-action@7b36ad622f042cab6f59a75c2ac24ccb256e9b45 #v0.20.4
|
||||
continue-on-error: true
|
||||
with:
|
||||
file: go.mod
|
||||
@@ -177,11 +177,17 @@ jobs:
|
||||
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_TOOLBOX_WEBHOOK_URL }}
|
||||
if: ${{ success() }}
|
||||
|
||||
release-version-file:
|
||||
release-install-script:
|
||||
needs: [release]
|
||||
uses: ./.github/workflows/release-version-file.yaml
|
||||
if: ${{ needs.release.result == 'success' }}
|
||||
uses: "anchore/workflows/.github/workflows/release-install-script.yaml@main"
|
||||
with:
|
||||
version: ${{ github.event.inputs.version }}
|
||||
tag: ${{ github.event.inputs.version }}
|
||||
secrets:
|
||||
TOOLBOX_AWS_ACCESS_KEY_ID: ${{ secrets.TOOLBOX_AWS_ACCESS_KEY_ID }}
|
||||
TOOLBOX_AWS_SECRET_ACCESS_KEY: ${{ secrets.TOOLBOX_AWS_SECRET_ACCESS_KEY }}
|
||||
# needed for r2...
|
||||
R2_INSTALL_ACCESS_KEY_ID: ${{ secrets.OSS_R2_INSTALL_ACCESS_KEY_ID }}
|
||||
R2_INSTALL_SECRET_ACCESS_KEY: ${{ secrets.OSS_R2_INSTALL_SECRET_ACCESS_KEY }}
|
||||
R2_ENDPOINT: ${{ secrets.TOOLBOX_CLOUDFLARE_R2_ENDPOINT }}
|
||||
# needed for s3...
|
||||
S3_INSTALL_AWS_ACCESS_KEY_ID: ${{ secrets.TOOLBOX_AWS_ACCESS_KEY_ID }}
|
||||
S3_INSTALL_AWS_SECRET_ACCESS_KEY: ${{ secrets.TOOLBOX_AWS_SECRET_ACCESS_KEY }}
|
||||
|
||||
@@ -90,7 +90,7 @@ jobs:
|
||||
# why not use actions/upload-artifact? It is very slow (3 minutes to upload ~600MB of data, vs 10 seconds with this approach).
|
||||
# see https://github.com/actions/upload-artifact/issues/199 for more info
|
||||
- name: Upload snapshot artifacts
|
||||
uses: actions/cache/save@5a3ec84eff668545956fd18022155c47e93e2684 #v4.2.3
|
||||
uses: actions/cache/save@0400d5f644dc74513175e3cd8d07132dd4860809 #v4.2.4
|
||||
with:
|
||||
# we need to preserve the snapshot data itself as well as the task data that confirms if the
|
||||
# snapshot build is stale or not. Otherwise the downstream jobs will attempt to rebuild the snapshot
|
||||
@@ -118,7 +118,7 @@ jobs:
|
||||
|
||||
- name: Download snapshot build
|
||||
id: snapshot-cache
|
||||
uses: actions/cache/restore@5a3ec84eff668545956fd18022155c47e93e2684 #v4.2.3
|
||||
uses: actions/cache/restore@0400d5f644dc74513175e3cd8d07132dd4860809 #v4.2.4
|
||||
with:
|
||||
path: |
|
||||
snapshot
|
||||
@@ -175,7 +175,7 @@ jobs:
|
||||
|
||||
- name: Download snapshot build
|
||||
id: snapshot-cache
|
||||
uses: actions/cache/restore@5a3ec84eff668545956fd18022155c47e93e2684 #v4.2.3
|
||||
uses: actions/cache/restore@0400d5f644dc74513175e3cd8d07132dd4860809 #v4.2.4
|
||||
with:
|
||||
path: |
|
||||
snapshot
|
||||
@@ -225,7 +225,7 @@ jobs:
|
||||
|
||||
- name: Download snapshot build
|
||||
id: snapshot-cache
|
||||
uses: actions/cache/restore@5a3ec84eff668545956fd18022155c47e93e2684 #v4.2.3
|
||||
uses: actions/cache/restore@0400d5f644dc74513175e3cd8d07132dd4860809 #v4.2.4
|
||||
with:
|
||||
path: |
|
||||
snapshot
|
||||
@@ -262,7 +262,7 @@ jobs:
|
||||
|
||||
- name: Download snapshot build
|
||||
id: snapshot-cache
|
||||
uses: actions/cache/restore@5a3ec84eff668545956fd18022155c47e93e2684 #v4.2.3
|
||||
uses: actions/cache/restore@0400d5f644dc74513175e3cd8d07132dd4860809 #v4.2.4
|
||||
with:
|
||||
path: |
|
||||
snapshot
|
||||
|
||||
@@ -12,7 +12,7 @@ TASK = $(TOOL_DIR)/task
|
||||
# note: we need to assume that binny and task have not already been installed
|
||||
$(BINNY):
|
||||
@mkdir -p $(TOOL_DIR)
|
||||
@curl -sSfL https://raw.githubusercontent.com/$(OWNER)/binny/main/install.sh | sh -s -- -b $(TOOL_DIR)
|
||||
@curl -sSfL https://get.anchore.io/binny | sh -s -- -b $(TOOL_DIR)
|
||||
|
||||
# note: we need to assume that binny and task have not already been installed
|
||||
.PHONY: task
|
||||
|
||||
@@ -38,7 +38,7 @@ Syft binaries are provided for Linux, macOS and Windows.
|
||||
|
||||
### Recommended
|
||||
> ```bash
|
||||
> curl -sSfL https://raw.githubusercontent.com/anchore/syft/main/install.sh | sh -s -- -b /usr/local/bin
|
||||
> curl -sSfL https://get.anchore.io/syft | sudo sh -s -- -b /usr/local/bin
|
||||
> ```
|
||||
|
||||
Install script options:
|
||||
|
||||
+1
-11
@@ -91,7 +91,7 @@ tasks:
|
||||
- "{{ .TOOL_DIR }}/binny"
|
||||
status:
|
||||
- "test -f {{ .TOOL_DIR }}/binny"
|
||||
cmd: "curl -sSfL https://raw.githubusercontent.com/anchore/binny/main/install.sh | sh -s -- -b .tool"
|
||||
cmd: "curl -sSfL https://get.anchore.io/binny | sh -s -- -b .tool"
|
||||
silent: true
|
||||
|
||||
tools:
|
||||
@@ -604,16 +604,6 @@ tasks:
|
||||
silent: true
|
||||
- "{{ .RELEASE_CMD }}"
|
||||
|
||||
ci-release-version-file:
|
||||
# desc: "[CI only] Update the version file"
|
||||
deps: [tools]
|
||||
cmds:
|
||||
- task: ci-check
|
||||
- ".github/scripts/update-version-file.sh {{ .RELEASE_VERSION }}"
|
||||
requires:
|
||||
vars:
|
||||
- RELEASE_VERSION
|
||||
|
||||
|
||||
## Cleanup targets #################################
|
||||
|
||||
|
||||
@@ -24,12 +24,12 @@ 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.20250220190351-d62adb6e1115
|
||||
github.com/anchore/stereoscope v0.1.7-0.20250716200927-94c6f92877d4
|
||||
github.com/anchore/stereoscope v0.1.8
|
||||
github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be
|
||||
github.com/aquasecurity/go-pep440-version v0.0.1
|
||||
github.com/bitnami/go-version v0.0.0-20250131085805-b1f57a8634ef
|
||||
github.com/blakesmith/ar v0.0.0-20190502131153-809d4375e1fb
|
||||
github.com/bmatcuk/doublestar/v4 v4.9.0
|
||||
github.com/bmatcuk/doublestar/v4 v4.9.1
|
||||
github.com/charmbracelet/bubbles v0.21.0
|
||||
github.com/charmbracelet/bubbletea v1.3.6
|
||||
github.com/charmbracelet/lipgloss v1.1.0
|
||||
@@ -41,7 +41,7 @@ require (
|
||||
github.com/elliotchance/phpserialize v1.4.0
|
||||
github.com/facebookincubator/nvdtools v0.1.5
|
||||
github.com/github/go-spdx/v2 v2.3.3
|
||||
github.com/gkampitakis/go-snaps v0.5.13
|
||||
github.com/gkampitakis/go-snaps v0.5.14
|
||||
github.com/go-git/go-billy/v5 v5.6.2
|
||||
github.com/go-git/go-git/v5 v5.16.2
|
||||
github.com/go-test/deep v1.1.1
|
||||
@@ -58,14 +58,14 @@ require (
|
||||
github.com/hashicorp/hcl/v2 v2.24.0
|
||||
github.com/iancoleman/strcase v0.3.0
|
||||
github.com/invopop/jsonschema v0.7.0
|
||||
github.com/jedib0t/go-pretty/v6 v6.6.7
|
||||
github.com/jedib0t/go-pretty/v6 v6.6.8
|
||||
github.com/jinzhu/copier v0.4.0
|
||||
github.com/kastenhq/goversion v0.0.0-20230811215019-93b2f8823953
|
||||
github.com/magiconair/properties v1.8.10
|
||||
github.com/mholt/archives v0.1.3
|
||||
github.com/moby/sys/mountinfo v0.7.2
|
||||
github.com/nix-community/go-nix v0.0.0-20250101154619-4bdde671e0a1
|
||||
github.com/olekukonko/tablewriter v1.0.8
|
||||
github.com/olekukonko/tablewriter v1.0.9
|
||||
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
|
||||
@@ -88,11 +88,11 @@ 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/exp v0.0.0-20250408133849-7e4ce0ab07d0
|
||||
golang.org/x/mod v0.26.0
|
||||
golang.org/x/net v0.42.0
|
||||
golang.org/x/exp v0.0.0-20250620022241-b7579e27df2b
|
||||
golang.org/x/mod v0.27.0
|
||||
golang.org/x/net v0.43.0
|
||||
gopkg.in/yaml.v3 v3.0.1
|
||||
modernc.org/sqlite v1.38.0
|
||||
modernc.org/sqlite v1.38.2
|
||||
)
|
||||
|
||||
require (
|
||||
@@ -145,9 +145,9 @@ require (
|
||||
github.com/containerd/typeurl/v2 v2.2.0 // indirect
|
||||
github.com/cyphar/filepath-securejoin v0.4.1 // indirect
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
|
||||
github.com/docker/cli v28.3.0+incompatible // indirect
|
||||
github.com/docker/cli v28.3.2+incompatible // indirect
|
||||
github.com/docker/distribution v2.8.3+incompatible // indirect
|
||||
github.com/docker/docker v28.2.2+incompatible // indirect
|
||||
github.com/docker/docker v28.3.3+incompatible // indirect
|
||||
github.com/docker/docker-credential-helpers v0.9.3 // indirect
|
||||
github.com/docker/go-connections v0.5.0 // indirect
|
||||
github.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c // indirect
|
||||
@@ -215,8 +215,8 @@ require (
|
||||
github.com/ncruces/go-strftime v0.1.9 // indirect
|
||||
github.com/nwaples/rardecode v1.1.3 // indirect
|
||||
github.com/nwaples/rardecode/v2 v2.1.0 // indirect
|
||||
github.com/olekukonko/errors v0.0.0-20250405072817-4e6d85265da6 // indirect
|
||||
github.com/olekukonko/ll v0.0.8 // indirect
|
||||
github.com/olekukonko/errors v1.1.0 // indirect
|
||||
github.com/olekukonko/ll v0.0.9 // indirect
|
||||
github.com/opencontainers/image-spec v1.1.1 // indirect
|
||||
github.com/opencontainers/runtime-spec v1.1.0 // indirect
|
||||
github.com/opencontainers/selinux v1.11.0 // indirect
|
||||
@@ -268,14 +268,14 @@ require (
|
||||
go.uber.org/atomic v1.9.0 // indirect
|
||||
go.uber.org/multierr v1.9.0 // indirect
|
||||
go4.org v0.0.0-20230225012048-214862532bf5 // indirect
|
||||
golang.org/x/crypto v0.40.0 // indirect
|
||||
golang.org/x/crypto v0.41.0 // indirect
|
||||
golang.org/x/oauth2 v0.30.0 // indirect
|
||||
golang.org/x/sync v0.16.0 // indirect
|
||||
golang.org/x/sys v0.34.0 // indirect
|
||||
golang.org/x/term v0.33.0 // indirect
|
||||
golang.org/x/text v0.27.0 // indirect
|
||||
golang.org/x/sys v0.35.0 // indirect
|
||||
golang.org/x/term v0.34.0 // indirect
|
||||
golang.org/x/text v0.28.0 // indirect
|
||||
golang.org/x/time v0.7.0 // indirect
|
||||
golang.org/x/tools v0.34.0 // indirect
|
||||
golang.org/x/tools v0.35.0 // indirect
|
||||
golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 // indirect
|
||||
google.golang.org/api v0.203.0 // indirect
|
||||
google.golang.org/genproto v0.0.0-20241118233622-e639e219e697 // indirect
|
||||
@@ -284,7 +284,7 @@ require (
|
||||
google.golang.org/grpc v1.67.3 // indirect
|
||||
google.golang.org/protobuf v1.36.4 // indirect
|
||||
gopkg.in/warnings.v0 v0.1.2 // indirect
|
||||
modernc.org/libc v1.65.10 // indirect
|
||||
modernc.org/libc v1.66.3 // indirect
|
||||
modernc.org/mathutil v1.7.1 // indirect
|
||||
modernc.org/memory v1.11.0 // indirect
|
||||
)
|
||||
|
||||
@@ -694,8 +694,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.20250220190351-d62adb6e1115 h1:ZyRCmiEjnoGJZ1+Ah0ZZ/mKKqNhGcUZBl0s7PTTDzvY=
|
||||
github.com/anchore/packageurl-go v0.1.1-0.20250220190351-d62adb6e1115/go.mod h1:KoYIv7tdP5+CC9VGkeZV4/vGCKsY55VvoG+5dadg4YI=
|
||||
github.com/anchore/stereoscope v0.1.7-0.20250716200927-94c6f92877d4 h1:5UGwBBUAK8i06gDA5JD74vT3qcz4lR7BfLXudpD5y8w=
|
||||
github.com/anchore/stereoscope v0.1.7-0.20250716200927-94c6f92877d4/go.mod h1:ejAlYkAb/cRvSMlxQlrG2dMruqQpcJAh4w2Fu02FEYQ=
|
||||
github.com/anchore/stereoscope v0.1.8 h1:K1NRFUqGy6z/jp4ADHNXZWbZ+xd6fPr0Kn4gYp1zm1c=
|
||||
github.com/anchore/stereoscope v0.1.8/go.mod h1:VA9zyFcUzN7GIFsXfe8lj3Z6Ocs4CP5QZqbmFc1I7ag=
|
||||
github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8=
|
||||
github.com/andybalholm/brotli v1.0.4/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig=
|
||||
github.com/andybalholm/brotli v1.1.2-0.20250424173009-453214e765f3 h1:8PmGpDEZl9yDpcdEr6Odf23feCxK3LNUNMxjXg41pZQ=
|
||||
@@ -739,8 +739,8 @@ github.com/bitnami/go-version v0.0.0-20250131085805-b1f57a8634ef h1:TSFnfbbu2oAO
|
||||
github.com/bitnami/go-version v0.0.0-20250131085805-b1f57a8634ef/go.mod h1:9iglf1GG4oNRJ39bZ5AZrjgAFD2RwQbXw6Qf7Cs47wo=
|
||||
github.com/blakesmith/ar v0.0.0-20190502131153-809d4375e1fb h1:m935MPodAbYS46DG4pJSv7WO+VECIWUQ7OJYSoTrMh4=
|
||||
github.com/blakesmith/ar v0.0.0-20190502131153-809d4375e1fb/go.mod h1:PkYb9DJNAwrSvRx5DYA+gUcOIgTGVMNkfSCbZM8cWpI=
|
||||
github.com/bmatcuk/doublestar/v4 v4.9.0 h1:DBvuZxjdKkRP/dr4GVV4w2fnmrk5Hxc90T51LZjv0JA=
|
||||
github.com/bmatcuk/doublestar/v4 v4.9.0/go.mod h1:xBQ8jztBU6kakFMg+8WGxn0c6z1fTSPVIjEY1Wr7jzc=
|
||||
github.com/bmatcuk/doublestar/v4 v4.9.1 h1:X8jg9rRZmJd4yRy7ZeNDRnM+T3ZfHv15JiBJ/avrEXE=
|
||||
github.com/bmatcuk/doublestar/v4 v4.9.1/go.mod h1:xBQ8jztBU6kakFMg+8WGxn0c6z1fTSPVIjEY1Wr7jzc=
|
||||
github.com/bodgit/plumbing v1.3.0 h1:pf9Itz1JOQgn7vEOE7v7nlEfBykYqvUYioC61TwWCFU=
|
||||
github.com/bodgit/plumbing v1.3.0/go.mod h1:JOTb4XiRu5xfnmdnDJo6GmSbSbtSyufrsyZFByMtKEs=
|
||||
github.com/bodgit/sevenzip v1.6.0 h1:a4R0Wu6/P1o1pP/3VV++aEOcyeBxeO/xE2Y9NSTrr6A=
|
||||
@@ -857,12 +857,12 @@ github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5Qvfr
|
||||
github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E=
|
||||
github.com/djherbis/times v1.6.0 h1:w2ctJ92J8fBvWPxugmXIv7Nz7Q3iDMKNx9v5ocVH20c=
|
||||
github.com/djherbis/times v1.6.0/go.mod h1:gOHeRAz2h+VJNZ5Gmc/o7iD9k4wW7NMVqieYCY99oc0=
|
||||
github.com/docker/cli v28.3.0+incompatible h1:s+ttruVLhB5ayeuf2BciwDVxYdKi+RoUlxmwNHV3Vfo=
|
||||
github.com/docker/cli v28.3.0+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
|
||||
github.com/docker/cli v28.3.2+incompatible h1:mOt9fcLE7zaACbxW1GeS65RI67wIJrTnqS3hP2huFsY=
|
||||
github.com/docker/cli v28.3.2+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 v28.2.2+incompatible h1:CjwRSksz8Yo4+RmQ339Dp/D2tGO5JxwYeqtMOEe0LDw=
|
||||
github.com/docker/docker v28.2.2+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
|
||||
github.com/docker/docker v28.3.3+incompatible h1:Dypm25kh4rmk49v1eiVbsAtpAsYURjYkaKubwuBdxEI=
|
||||
github.com/docker/docker v28.3.3+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
|
||||
github.com/docker/docker-credential-helpers v0.9.3 h1:gAm/VtF9wgqJMoxzT3Gj5p4AqIjCBS4wrsOh9yRqcz8=
|
||||
github.com/docker/docker-credential-helpers v0.9.3/go.mod h1:x+4Gbw9aGmChi3qTLZj8Dfn0TD20M/fuWy0E5+WDeCo=
|
||||
github.com/docker/go-connections v0.5.0 h1:USnMq7hx7gwdVZq1L49hLXaFtUdTADjXGp+uj1Br63c=
|
||||
@@ -936,8 +936,8 @@ github.com/gkampitakis/ciinfo v0.3.2 h1:JcuOPk8ZU7nZQjdUhctuhQofk7BGHuIy0c9Ez8BN
|
||||
github.com/gkampitakis/ciinfo v0.3.2/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.13 h1:Hhjmvv1WboSCxkR9iU2mj5PQ8tsz/y8ECGrIbjjPF8Q=
|
||||
github.com/gkampitakis/go-snaps v0.5.13/go.mod h1:HNpx/9GoKisdhw9AFOBT1N7DBs9DiHo/hGheFGBZ+mc=
|
||||
github.com/gkampitakis/go-snaps v0.5.14 h1:3fAqdB6BCPKHDMHAKRwtPUwYexKtGrNuw8HX/T/4neo=
|
||||
github.com/gkampitakis/go-snaps v0.5.14/go.mod h1:HNpx/9GoKisdhw9AFOBT1N7DBs9DiHo/hGheFGBZ+mc=
|
||||
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.8 h1:a4YXD1V7xMF9g5nTkdfnja3Sxy1PVDCj1Zg4Wb8vY6c=
|
||||
@@ -1187,8 +1187,8 @@ github.com/invopop/jsonschema v0.7.0 h1:2vgQcBz1n256N+FpX3Jq7Y17AjYt46Ig3zIWyy77
|
||||
github.com/invopop/jsonschema v0.7.0/go.mod h1:O9uiLokuu0+MGFlyiaqtWxwqJm41/+8Nj0lD7A36YH0=
|
||||
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A=
|
||||
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo=
|
||||
github.com/jedib0t/go-pretty/v6 v6.6.7 h1:m+LbHpm0aIAPLzLbMfn8dc3Ht8MW7lsSO4MPItz/Uuo=
|
||||
github.com/jedib0t/go-pretty/v6 v6.6.7/go.mod h1:YwC5CE4fJ1HFUDeivSV1r//AmANFHyqczZk+U6BDALU=
|
||||
github.com/jedib0t/go-pretty/v6 v6.6.8 h1:JnnzQeRz2bACBobIaa/r+nqjvws4yEhcmaZ4n1QzsEc=
|
||||
github.com/jedib0t/go-pretty/v6 v6.6.8/go.mod h1:YwC5CE4fJ1HFUDeivSV1r//AmANFHyqczZk+U6BDALU=
|
||||
github.com/jinzhu/copier v0.4.0 h1:w3ciUoD19shMCRargcpm0cm91ytaBhDvuRpz1ODO/U8=
|
||||
github.com/jinzhu/copier v0.4.0/go.mod h1:DfbEm0FYsaqBcKcFuvmOZb218JkPGtvSHsKg8S8hyyg=
|
||||
github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg=
|
||||
@@ -1346,12 +1346,12 @@ github.com/nwaples/rardecode v1.1.3 h1:cWCaZwfM5H7nAD6PyEdcVnczzV8i/JtotnyW/dD9l
|
||||
github.com/nwaples/rardecode v1.1.3/go.mod h1:5DzqNKiOdpKKBH87u8VlvAnPZMXcGRhxWkRpHbbfGS0=
|
||||
github.com/nwaples/rardecode/v2 v2.1.0 h1:JQl9ZoBPDy+nIZGb1mx8+anfHp/LV3NE2MjMiv0ct/U=
|
||||
github.com/nwaples/rardecode/v2 v2.1.0/go.mod h1:7uz379lSxPe6j9nvzxUZ+n7mnJNgjsRNb6IbvGVHRmw=
|
||||
github.com/olekukonko/errors v0.0.0-20250405072817-4e6d85265da6 h1:r3FaAI0NZK3hSmtTDrBVREhKULp8oUeqLT5Eyl2mSPo=
|
||||
github.com/olekukonko/errors v0.0.0-20250405072817-4e6d85265da6/go.mod h1:ppzxA5jBKcO1vIpCXQ9ZqgDh8iwODz6OXIGKU8r5m4Y=
|
||||
github.com/olekukonko/ll v0.0.8 h1:sbGZ1Fx4QxJXEqL/6IG8GEFnYojUSQ45dJVwN2FH2fc=
|
||||
github.com/olekukonko/ll v0.0.8/go.mod h1:En+sEW0JNETl26+K8eZ6/W4UQ7CYSrrgg/EdIYT2H8g=
|
||||
github.com/olekukonko/tablewriter v1.0.8 h1:f6wJzHg4QUtJdvrVPKco4QTrAylgaU0+b9br/lJxEiQ=
|
||||
github.com/olekukonko/tablewriter v1.0.8/go.mod h1:H428M+HzoUXC6JU2Abj9IT9ooRmdq9CxuDmKMtrOCMs=
|
||||
github.com/olekukonko/errors v1.1.0 h1:RNuGIh15QdDenh+hNvKrJkmxxjV4hcS50Db478Ou5sM=
|
||||
github.com/olekukonko/errors v1.1.0/go.mod h1:ppzxA5jBKcO1vIpCXQ9ZqgDh8iwODz6OXIGKU8r5m4Y=
|
||||
github.com/olekukonko/ll v0.0.9 h1:Y+1YqDfVkqMWuEQMclsF9HUR5+a82+dxJuL1HHSRpxI=
|
||||
github.com/olekukonko/ll v0.0.9/go.mod h1:En+sEW0JNETl26+K8eZ6/W4UQ7CYSrrgg/EdIYT2H8g=
|
||||
github.com/olekukonko/tablewriter v1.0.9 h1:XGwRsYLC2bY7bNd93Dk51bcPZksWZmLYuaTHR0FqfL8=
|
||||
github.com/olekukonko/tablewriter v1.0.9/go.mod h1:5c+EBPeSqvXnLLgkm9isDdzR3wjfBkHR9Nhfp3NWrzo=
|
||||
github.com/onsi/gomega v1.34.1 h1:EUMJIKUjM8sKjYbtxQI9A4z2o+rruxnzNvpknOXie6k=
|
||||
github.com/onsi/gomega v1.34.1/go.mod h1:kU1QgUvBDLXBJq618Xvm2LUX6rSAfRaFRTcdOeDLwwY=
|
||||
github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=
|
||||
@@ -1643,8 +1643,8 @@ golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliY
|
||||
golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
|
||||
golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8=
|
||||
golang.org/x/crypto v0.32.0/go.mod h1:ZnnJkOaASj8g0AjIduWNlq2NRxL0PlBrbKVyZ6V/Ugc=
|
||||
golang.org/x/crypto v0.40.0 h1:r4x+VvoG5Fm+eJcxMaY8CQM7Lb0l1lsmjGBQ6s8BfKM=
|
||||
golang.org/x/crypto v0.40.0/go.mod h1:Qr1vMER5WyS2dfPHAlsOj01wgLbsyWtFn/aY+5+ZdxY=
|
||||
golang.org/x/crypto v0.41.0 h1:WKYxWedPGCTVVl5+WHSSrOBT0O8lx32+zxmHxijgXp4=
|
||||
golang.org/x/crypto v0.41.0/go.mod h1:pO5AFd7FA68rFak7rOAGVuygIISepHftHnr8dr6+sUc=
|
||||
golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
@@ -1660,8 +1660,8 @@ golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u0
|
||||
golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
|
||||
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
|
||||
golang.org/x/exp v0.0.0-20220827204233-334a2380cb91/go.mod h1:cyybsKvd6eL0RnXn6p/Grxp8F5bW7iYuBgsNCOHpMYE=
|
||||
golang.org/x/exp v0.0.0-20250408133849-7e4ce0ab07d0 h1:R84qjqJb5nVJMxqWYb3np9L5ZsaDtB+a39EqjV0JSUM=
|
||||
golang.org/x/exp v0.0.0-20250408133849-7e4ce0ab07d0/go.mod h1:S9Xr4PYopiDyqSyp5NjCrhFrqg6A5zA2E/iPHPhqnS8=
|
||||
golang.org/x/exp v0.0.0-20250620022241-b7579e27df2b h1:M2rDM6z3Fhozi9O7NWsxAkg/yqS/lQJ6PmkyIV3YP+o=
|
||||
golang.org/x/exp v0.0.0-20250620022241-b7579e27df2b/go.mod h1:3//PLf8L/X+8b4vuAfHzxeRUl04Adcb341+IGKfnqS8=
|
||||
golang.org/x/image v0.0.0-20180708004352-c73c2afc3b81/go.mod h1:ux5Hcp/YLpHSI86hEcLt0YII63i6oz57MZXIpbrjZUs=
|
||||
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
|
||||
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
||||
@@ -1707,8 +1707,8 @@ golang.org/x/mod v0.9.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||
golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||
golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
|
||||
golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
|
||||
golang.org/x/mod v0.26.0 h1:EGMPT//Ezu+ylkCijjPc+f4Aih7sZvaAr+O3EHBxvZg=
|
||||
golang.org/x/mod v0.26.0/go.mod h1:/j6NAhSk8iQ723BGAUyoAcn7SlD7s15Dp9Nd/SfeaFQ=
|
||||
golang.org/x/mod v0.27.0 h1:kb+q2PyFnEADO2IEF935ehFUXlWiNjJWtRNgBLSfbxQ=
|
||||
golang.org/x/mod v0.27.0/go.mod h1:rWI627Fq0DEoudcK+MBkNkCe0EetEaDSwJJkCcjpazc=
|
||||
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=
|
||||
@@ -1777,8 +1777,8 @@ golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk=
|
||||
golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
|
||||
golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM=
|
||||
golang.org/x/net v0.34.0/go.mod h1:di0qlW3YNM5oh6GqDGQr92MyTozJPmybPK4Ev/Gm31k=
|
||||
golang.org/x/net v0.42.0 h1:jzkYrhi3YQWD6MLBJcsklgQsoAcw89EcZbJw8Z614hs=
|
||||
golang.org/x/net v0.42.0/go.mod h1:FF1RA5d3u7nAYA4z2TkclSCKh68eSXtiFwcWQpPXdt8=
|
||||
golang.org/x/net v0.43.0 h1:lat02VYK2j4aLzMzecihNvTlJNQUq316m2Mr9rnM6YE=
|
||||
golang.org/x/net v0.43.0/go.mod h1:vhO1fvI4dGsIjh73sWfUVjj3N7CA9WkKJNQm2svM6Jg=
|
||||
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=
|
||||
@@ -1936,8 +1936,8 @@ golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.34.0 h1:H5Y5sJ2L2JRdyv7ROF1he/lPdvFsd0mJHFw2ThKHxLA=
|
||||
golang.org/x/sys v0.34.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
|
||||
golang.org/x/sys v0.35.0 h1:vz1N37gP5bs89s7He8XuIYXpyY0+QlsKmzipCbUtyxI=
|
||||
golang.org/x/sys v0.35.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
|
||||
golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2/go.mod h1:TeRTkGYfJXctD9OcfyVLyj2J3IxLnKwHJR8f4D8a3YE=
|
||||
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=
|
||||
@@ -1952,8 +1952,8 @@ golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU=
|
||||
golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk=
|
||||
golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY=
|
||||
golang.org/x/term v0.28.0/go.mod h1:Sw/lC2IAUZ92udQNf3WodGtn4k/XoLyZoh8v/8uiwek=
|
||||
golang.org/x/term v0.33.0 h1:NuFncQrRcaRvVmgRkvM3j/F00gWIAlcmlB8ACEKmGIg=
|
||||
golang.org/x/term v0.33.0/go.mod h1:s18+ql9tYWp1IfpV9DmCtQDDSRBUjKaw9M1eAv5UeF0=
|
||||
golang.org/x/term v0.34.0 h1:O/2T7POpk0ZZ7MAzMeWFSg6S5IpWd/RXDlM9hgM3DR4=
|
||||
golang.org/x/term v0.34.0/go.mod h1:5jC53AEywhIVebHgPVeg0mj8OD3VO9OzclacVrqpaAw=
|
||||
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=
|
||||
@@ -1974,8 +1974,8 @@ golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
|
||||
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||
golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||
golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=
|
||||
golang.org/x/text v0.27.0 h1:4fGWRpyh641NLlecmyl4LOe6yDdfaYNrGb2zdfo4JV4=
|
||||
golang.org/x/text v0.27.0/go.mod h1:1D28KMCvyooCX9hBiosv5Tz/+YLxj0j7XhWjpSUF7CU=
|
||||
golang.org/x/text v0.28.0 h1:rhazDwis8INMIwQ4tpjLDzUhx6RlXqZNPEM0huQojng=
|
||||
golang.org/x/text v0.28.0/go.mod h1:U8nCwOR8jO/marOQ0QbDiOngZVEBB7MAiitBuMjXiNU=
|
||||
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
@@ -2050,8 +2050,8 @@ golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
|
||||
golang.org/x/tools v0.7.0/go.mod h1:4pg6aUX35JBAogB10C9AtvVL+qowtN4pT3CGSQex14s=
|
||||
golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58=
|
||||
golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk=
|
||||
golang.org/x/tools v0.34.0 h1:qIpSLOxeCYGg9TrcJokLBG4KFA6d795g0xkBkiESGlo=
|
||||
golang.org/x/tools v0.34.0/go.mod h1:pAP9OwEaY1CAW3HOmg3hLZC5Z0CCmzjAF2UQMSqNARg=
|
||||
golang.org/x/tools v0.35.0 h1:mBffYraMEf7aa0sB+NuKnuCy8qI/9Bughn8dC2Gu5r0=
|
||||
golang.org/x/tools v0.35.0/go.mod h1:NKdj5HkL/73byiZSJjqJgKn3ep7KjFkBOkR/Hps3VPw=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
@@ -2382,8 +2382,8 @@ lukechampine.com/uint128 v1.2.0/go.mod h1:c4eWIwlEGaxC/+H1VguhU4PHXNWDCDMUlWdIWl
|
||||
modernc.org/cc/v3 v3.36.0/go.mod h1:NFUHyPn4ekoC/JHeZFfZurN6ixxawE1BnVonP/oahEI=
|
||||
modernc.org/cc/v3 v3.36.2/go.mod h1:NFUHyPn4ekoC/JHeZFfZurN6ixxawE1BnVonP/oahEI=
|
||||
modernc.org/cc/v3 v3.36.3/go.mod h1:NFUHyPn4ekoC/JHeZFfZurN6ixxawE1BnVonP/oahEI=
|
||||
modernc.org/cc/v4 v4.26.1 h1:+X5NtzVBn0KgsBCBe+xkDC7twLb/jNVj9FPgiwSQO3s=
|
||||
modernc.org/cc/v4 v4.26.1/go.mod h1:uVtb5OGqUKpoLWhqwNQo/8LwvoiEBLvZXIQ/SmO6mL0=
|
||||
modernc.org/cc/v4 v4.26.2 h1:991HMkLjJzYBIfha6ECZdjrIYz2/1ayr+FL8GN+CNzM=
|
||||
modernc.org/cc/v4 v4.26.2/go.mod h1:uVtb5OGqUKpoLWhqwNQo/8LwvoiEBLvZXIQ/SmO6mL0=
|
||||
modernc.org/ccgo/v3 v3.0.0-20220428102840-41399a37e894/go.mod h1:eI31LL8EwEBKPpNpA4bU1/i+sKOwOrQy8D87zWUcRZc=
|
||||
modernc.org/ccgo/v3 v3.0.0-20220430103911-bc99d88307be/go.mod h1:bwdAnOoaIt8Ax9YdWGjxWsdkPcZyRPHqrOvJxaKAKGw=
|
||||
modernc.org/ccgo/v3 v3.16.4/go.mod h1:tGtX0gE9Jn7hdZFeU88slbTh1UtCYKusWOoCJuvkWsQ=
|
||||
@@ -2393,10 +2393,12 @@ modernc.org/ccgo/v3 v3.16.9/go.mod h1:zNMzC9A9xeNUepy6KuZBbugn3c0Mc9TeiJO4lgvkJD
|
||||
modernc.org/ccgo/v4 v4.28.0 h1:rjznn6WWehKq7dG4JtLRKxb52Ecv8OUGah8+Z/SfpNU=
|
||||
modernc.org/ccgo/v4 v4.28.0/go.mod h1:JygV3+9AV6SmPhDasu4JgquwU81XAKLd3OKTUDNOiKE=
|
||||
modernc.org/ccorpus v1.11.6/go.mod h1:2gEUTrWqdpH2pXsmTM1ZkjeSrUWDpjMu2T6m29L/ErQ=
|
||||
modernc.org/fileutil v1.3.3 h1:3qaU+7f7xxTUmvU1pJTZiDLAIoJVdUSSauJNHg9yXoA=
|
||||
modernc.org/fileutil v1.3.3/go.mod h1:HxmghZSZVAz/LXcMNwZPA/DRrQZEVP9VX0V4LQGQFOc=
|
||||
modernc.org/fileutil v1.3.8 h1:qtzNm7ED75pd1C7WgAGcK4edm4fvhtBsEiI/0NQ54YM=
|
||||
modernc.org/fileutil v1.3.8/go.mod h1:HxmghZSZVAz/LXcMNwZPA/DRrQZEVP9VX0V4LQGQFOc=
|
||||
modernc.org/gc/v2 v2.6.5 h1:nyqdV8q46KvTpZlsw66kWqwXRHdjIlJOhG6kxiV/9xI=
|
||||
modernc.org/gc/v2 v2.6.5/go.mod h1:YgIahr1ypgfe7chRuJi2gD7DBQiKSLMPgBQe9oIiito=
|
||||
modernc.org/goabi0 v0.2.0 h1:HvEowk7LxcPd0eq6mVOAEMai46V+i7Jrj13t4AzuNks=
|
||||
modernc.org/goabi0 v0.2.0/go.mod h1:CEFRnnJhKvWT1c1JTI3Avm+tgOWbkOu5oPA8eH8LnMI=
|
||||
modernc.org/httpfs v1.0.6/go.mod h1:7dosgurJGp0sPaRanU53W4xZYKh14wfzX420oZADeHM=
|
||||
modernc.org/libc v0.0.0-20220428101251-2d5f3daf273b/go.mod h1:p7Mg4+koNjc8jkqwcoFBJx7tXkpj00G77X7A72jXPXA=
|
||||
modernc.org/libc v1.16.0/go.mod h1:N4LD6DBE9cf+Dzf9buBlzVJndKr/iJHG97vGLHYnb5A=
|
||||
@@ -2405,8 +2407,8 @@ modernc.org/libc v1.16.17/go.mod h1:hYIV5VZczAmGZAnG15Vdngn5HSF5cSkbvfz2B7GRuVU=
|
||||
modernc.org/libc v1.16.19/go.mod h1:p7Mg4+koNjc8jkqwcoFBJx7tXkpj00G77X7A72jXPXA=
|
||||
modernc.org/libc v1.17.0/go.mod h1:XsgLldpP4aWlPlsjqKRdHPqCxCjISdHfM/yeWC5GyW0=
|
||||
modernc.org/libc v1.17.1/go.mod h1:FZ23b+8LjxZs7XtFMbSzL/EhPxNbfZbErxEHc7cbD9s=
|
||||
modernc.org/libc v1.65.10 h1:ZwEk8+jhW7qBjHIT+wd0d9VjitRyQef9BnzlzGwMODc=
|
||||
modernc.org/libc v1.65.10/go.mod h1:StFvYpx7i/mXtBAfVOjaU0PWZOvIRoZSgXhrwXzr8Po=
|
||||
modernc.org/libc v1.66.3 h1:cfCbjTUcdsKyyZZfEUKfoHcP3S0Wkvz3jgSzByEWVCQ=
|
||||
modernc.org/libc v1.66.3/go.mod h1:XD9zO8kt59cANKvHPXpx7yS2ELPheAey0vjIuZOhOU8=
|
||||
modernc.org/mathutil v1.2.2/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E=
|
||||
modernc.org/mathutil v1.4.1/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E=
|
||||
modernc.org/mathutil v1.5.0/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E=
|
||||
@@ -2424,8 +2426,8 @@ modernc.org/opt v0.1.4/go.mod h1:03fq9lsNfvkYSfxrfUhZCWPk1lm4cq4N+Bh//bEtgns=
|
||||
modernc.org/sortutil v1.2.1 h1:+xyoGf15mM3NMlPDnFqrteY07klSFxLElE2PVuWIJ7w=
|
||||
modernc.org/sortutil v1.2.1/go.mod h1:7ZI3a3REbai7gzCLcotuw9AC4VZVpYMjDzETGsSMqJE=
|
||||
modernc.org/sqlite v1.18.1/go.mod h1:6ho+Gow7oX5V+OiOQ6Tr4xeqbx13UZ6t+Fw9IRUG4d4=
|
||||
modernc.org/sqlite v1.38.0 h1:+4OrfPQ8pxHKuWG4md1JpR/EYAh3Md7TdejuuzE7EUI=
|
||||
modernc.org/sqlite v1.38.0/go.mod h1:1Bj+yES4SVvBZ4cBOpVZ6QgesMCKpJZDq0nxYzOpmNE=
|
||||
modernc.org/sqlite v1.38.2 h1:Aclu7+tgjgcQVShZqim41Bbw9Cho0y/7WzYptXqkEek=
|
||||
modernc.org/sqlite v1.38.2/go.mod h1:cPTJYSlgg3Sfg046yBShXENNtPrWrDX8bsbAQBzgQ5E=
|
||||
modernc.org/strutil v1.1.1/go.mod h1:DE+MQQ/hjKBZS2zNInV5hhcipt5rLPWkmpbGeW5mmdw=
|
||||
modernc.org/strutil v1.1.3/go.mod h1:MEHNA7PdEnEwLvspRMtWTNnp2nnyvMfkimT1NKNAGbw=
|
||||
modernc.org/strutil v1.2.1 h1:UneZBkQA+DX2Rp35KcM69cSsNES9ly8mQWD71HKlOA0=
|
||||
|
||||
+7
-2
@@ -6,7 +6,8 @@ PROJECT_NAME=syft
|
||||
OWNER=anchore
|
||||
REPO="${PROJECT_NAME}"
|
||||
GITHUB_DOWNLOAD_PREFIX=https://github.com/${OWNER}/${REPO}/releases/download
|
||||
INSTALL_SH_BASE_URL=https://raw.githubusercontent.com/${OWNER}/${PROJECT_NAME}
|
||||
INSTALL_SH_BASE_URL=https://get.anchore.io/${PROJECT_NAME}
|
||||
LEGACY_INSTALL_SH_BASE_URL=https://raw.githubusercontent.com/${OWNER}/${PROJECT_NAME}
|
||||
PROGRAM_ARGS=$@
|
||||
|
||||
# signature verification options
|
||||
@@ -836,7 +837,11 @@ EOF
|
||||
if [ "${DOWNLOAD_TAG_INSTALL_SCRIPT}" = "true" ]; then
|
||||
export DOWNLOAD_TAG_INSTALL_SCRIPT=false
|
||||
log_info "fetching release script for tag='${tag}'"
|
||||
http_copy "${INSTALL_SH_BASE_URL}/${tag}/install.sh" "" | sh -s -- ${PROGRAM_ARGS}
|
||||
if ! install_script=$(http_copy "${INSTALL_SH_BASE_URL}/${tag}/install.sh" ""); then
|
||||
log_warn "failed to fetch from ${INSTALL_SH_BASE_URL}, trying fallback URL"
|
||||
install_script=$(http_copy "${LEGACY_INSTALL_SH_BASE_URL}/${tag}/install.sh" "")
|
||||
fi
|
||||
echo "${install_script}" | sh -s -- ${PROGRAM_ARGS}
|
||||
exit $?
|
||||
fi
|
||||
|
||||
|
||||
@@ -41,11 +41,11 @@ func MatchNamedCaptureGroups(regEx *regexp.Regexp, content string) map[string]st
|
||||
// 1.5x the reader chunk size (1MB * 1.5).
|
||||
func MatchNamedCaptureGroupsFromReader(re *regexp.Regexp, r io.Reader) (map[string]string, error) {
|
||||
results := make(map[string]string)
|
||||
_, err := processReaderInChunks(r, readerChunkSize, matchNamedCaptureGroupsHandler(re, results))
|
||||
matches, err := processReaderInChunks(r, readerChunkSize, matchNamedCaptureGroupsHandler(re, results))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(results) == 0 {
|
||||
if !matches {
|
||||
return nil, nil
|
||||
}
|
||||
return results, nil
|
||||
|
||||
@@ -12,6 +12,7 @@ type CompletionTester struct {
|
||||
}
|
||||
|
||||
func NewCompletionTester(t testing.TB, ignore ...any) *CompletionTester {
|
||||
t.Helper()
|
||||
tester := &CompletionTester{
|
||||
valid: AllTypes(),
|
||||
ignore: ignore,
|
||||
@@ -23,6 +24,14 @@ func NewCompletionTester(t testing.TB, ignore ...any) *CompletionTester {
|
||||
return tester
|
||||
}
|
||||
|
||||
func (tr *CompletionTester) Ignore(is ...any) {
|
||||
tr.ignore = append(tr.ignore, keepNonNil(is...)...)
|
||||
}
|
||||
|
||||
func (tr *CompletionTester) Expect(is ...any) {
|
||||
tr.valid = append(tr.valid, keepNonNil(is...)...)
|
||||
}
|
||||
|
||||
func (tr *CompletionTester) Tested(t testing.TB, m any) {
|
||||
t.Helper()
|
||||
|
||||
@@ -33,6 +42,13 @@ func (tr *CompletionTester) Tested(t testing.TB, m any) {
|
||||
t.Fatal("no valid metadata types to test against")
|
||||
}
|
||||
ty := reflect.TypeOf(m)
|
||||
|
||||
for _, v := range tr.ignore {
|
||||
if reflect.TypeOf(v) == ty {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
for _, v := range tr.valid {
|
||||
if reflect.TypeOf(v) == ty {
|
||||
tr.saw = append(tr.saw, m)
|
||||
@@ -67,3 +83,13 @@ validations:
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func keepNonNil(is ...any) []any {
|
||||
var result []any
|
||||
for _, i := range is {
|
||||
if i != nil {
|
||||
result = append(result, i)
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
@@ -12,6 +12,7 @@ type CompletionTester struct {
|
||||
}
|
||||
|
||||
func NewCompletionTester(t testing.TB, ignore ...any) *CompletionTester {
|
||||
t.Helper()
|
||||
tester := &CompletionTester{
|
||||
valid: AllTypes(),
|
||||
ignore: ignore,
|
||||
@@ -23,6 +24,14 @@ func NewCompletionTester(t testing.TB, ignore ...any) *CompletionTester {
|
||||
return tester
|
||||
}
|
||||
|
||||
func (tr *CompletionTester) Ignore(is ...any) {
|
||||
tr.ignore = append(tr.ignore, keepNonNil(is...)...)
|
||||
}
|
||||
|
||||
func (tr *CompletionTester) Expect(is ...any) {
|
||||
tr.valid = append(tr.valid, keepNonNil(is...)...)
|
||||
}
|
||||
|
||||
func (tr *CompletionTester) Tested(t testing.TB, m any) {
|
||||
t.Helper()
|
||||
|
||||
@@ -33,6 +42,13 @@ func (tr *CompletionTester) Tested(t testing.TB, m any) {
|
||||
t.Fatal("no valid metadata types to test against")
|
||||
}
|
||||
ty := reflect.TypeOf(m)
|
||||
|
||||
for _, v := range tr.ignore {
|
||||
if reflect.TypeOf(v) == ty {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
for _, v := range tr.valid {
|
||||
if reflect.TypeOf(v) == ty {
|
||||
tr.saw = append(tr.saw, m)
|
||||
@@ -67,3 +83,13 @@ validations:
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func keepNonNil(is ...any) []any {
|
||||
var result []any
|
||||
for _, i := range is {
|
||||
if i != nil {
|
||||
result = append(result, i)
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
@@ -75,6 +75,12 @@ func (c cataloger) Catalog(_ context.Context, resolver file.Resolver) ([]pkg.Pac
|
||||
newPackages:
|
||||
for i := range newPkgs {
|
||||
newPkg := &newPkgs[i]
|
||||
purlType := pkg.TypeFromPURL(newPkg.PURL)
|
||||
// for certain results, such as hashicorp vault we are returning a golang PURL, so we can use Golang package type,
|
||||
// despite not having the known metadata, this should result in downstream grype matching to use the golang matcher
|
||||
if purlType != pkg.UnknownPkg {
|
||||
newPkg.Type = purlType
|
||||
}
|
||||
for j := range packages {
|
||||
p := &packages[j]
|
||||
// consolidate identical packages found in different locations or by different classifiers
|
||||
@@ -92,6 +98,9 @@ func (c cataloger) Catalog(_ context.Context, resolver file.Resolver) ([]pkg.Pac
|
||||
|
||||
// mergePackages merges information from the extra package into the target package
|
||||
func mergePackages(target *pkg.Package, extra *pkg.Package) {
|
||||
if extra.Type != pkg.BinaryPkg && target.Type == pkg.BinaryPkg {
|
||||
target.Type = extra.Type
|
||||
}
|
||||
// add the locations
|
||||
target.Locations.Add(extra.Locations.ToSlice()...)
|
||||
// update the metadata to indicate which classifiers were used
|
||||
|
||||
@@ -697,21 +697,21 @@ func Test_Cataloger_PositiveCases(t *testing.T) {
|
||||
{
|
||||
logicalFixture: "java-jre-openjdk/1.8.0_352-b08/linux-amd64",
|
||||
expected: pkg.Package{
|
||||
Name: "java/jre",
|
||||
Name: "openjdk",
|
||||
Version: "1.8.0_352-b08",
|
||||
Type: "binary",
|
||||
PURL: "pkg:generic/java/jre@1.8.0_352-b08",
|
||||
PURL: "pkg:generic/oracle/openjdk@1.8.0_352-b08",
|
||||
Locations: locations("java"),
|
||||
Metadata: metadata("java-binary-openjdk", "java"),
|
||||
Metadata: metadata("java-binary-openjdk-with-update", "java"),
|
||||
},
|
||||
},
|
||||
{
|
||||
logicalFixture: "java-jre-openjdk/11.0.17/linux-amd64",
|
||||
expected: pkg.Package{
|
||||
Name: "java/jre",
|
||||
Name: "openjdk",
|
||||
Version: "11.0.17+8-LTS",
|
||||
Type: "binary",
|
||||
PURL: "pkg:generic/java/jre@11.0.17%2B8-LTS",
|
||||
PURL: "pkg:generic/oracle/openjdk@11.0.17%2B8-LTS",
|
||||
Locations: locations("java"),
|
||||
Metadata: metadata("java-binary-openjdk", "java"),
|
||||
},
|
||||
@@ -719,10 +719,10 @@ func Test_Cataloger_PositiveCases(t *testing.T) {
|
||||
{
|
||||
logicalFixture: "java-jre-openjdk-eclipse/11.0.22/linux-amd64",
|
||||
expected: pkg.Package{
|
||||
Name: "java/jre",
|
||||
Name: "openjdk",
|
||||
Version: "11.0.22+7",
|
||||
Type: "binary",
|
||||
PURL: "pkg:generic/java/jre@11.0.22%2B7",
|
||||
PURL: "pkg:generic/oracle/openjdk@11.0.22%2B7",
|
||||
Locations: locations("java"),
|
||||
Metadata: metadata("java-binary-openjdk", "java"),
|
||||
},
|
||||
@@ -730,10 +730,10 @@ func Test_Cataloger_PositiveCases(t *testing.T) {
|
||||
{
|
||||
logicalFixture: "java-jre-openjdk-arm64-eclipse/11.0.22/linux-arm64",
|
||||
expected: pkg.Package{
|
||||
Name: "java/jre",
|
||||
Name: "openjdk",
|
||||
Version: "11.0.22+7",
|
||||
Type: "binary",
|
||||
PURL: "pkg:generic/java/jre@11.0.22%2B7",
|
||||
PURL: "pkg:generic/oracle/openjdk@11.0.22%2B7",
|
||||
Locations: locations("java"),
|
||||
Metadata: metadata("java-binary-openjdk", "java"),
|
||||
},
|
||||
@@ -741,10 +741,10 @@ func Test_Cataloger_PositiveCases(t *testing.T) {
|
||||
{
|
||||
logicalFixture: "java-graal-openjdk/17.0.3+7-jvmci-22.1-b06/linux-amd64",
|
||||
expected: pkg.Package{
|
||||
Name: "java/graalvm",
|
||||
Name: "graalvm",
|
||||
Version: "17.0.3+7-jvmci-22.1-b06",
|
||||
Type: "binary",
|
||||
PURL: "pkg:generic/java/graalvm@17.0.3%2B7-jvmci-22.1-b06",
|
||||
PURL: "pkg:generic/oracle/graalvm@17.0.3%2B7-jvmci-22.1-b06",
|
||||
Locations: locations("java"),
|
||||
Metadata: metadata("java-binary-graalvm", "java"),
|
||||
},
|
||||
@@ -754,10 +754,10 @@ func Test_Cataloger_PositiveCases(t *testing.T) {
|
||||
// note: cannot find the original binary, using a custom snippet based on the original snippet in the repo
|
||||
logicalFixture: "java-jre-oracle/19.0.1/linux-amd64",
|
||||
expected: pkg.Package{
|
||||
Name: "java/jre",
|
||||
Name: "jre",
|
||||
Version: "19.0.1+10-21",
|
||||
Type: "binary",
|
||||
PURL: "pkg:generic/java/jre@19.0.1%2B10-21",
|
||||
PURL: "pkg:generic/oracle/jre@19.0.1%2B10-21",
|
||||
Locations: locations("java"),
|
||||
Metadata: metadata("java-binary-oracle", "java"),
|
||||
},
|
||||
@@ -767,10 +767,10 @@ func Test_Cataloger_PositiveCases(t *testing.T) {
|
||||
// note: cannot find the original binary, using a custom snippet based on the original snippet in the repo
|
||||
logicalFixture: "java-jre-oracle/19.0.1/darwin",
|
||||
expected: pkg.Package{
|
||||
Name: "java/jre",
|
||||
Name: "jre",
|
||||
Version: "19.0.1+10-21",
|
||||
Type: "binary",
|
||||
PURL: "pkg:generic/java/jre@19.0.1%2B10-21",
|
||||
PURL: "pkg:generic/oracle/jre@19.0.1%2B10-21",
|
||||
Locations: locations("java"),
|
||||
Metadata: metadata("java-binary-oracle", "java"),
|
||||
},
|
||||
@@ -778,23 +778,45 @@ func Test_Cataloger_PositiveCases(t *testing.T) {
|
||||
{
|
||||
logicalFixture: "java-jre-ibm/1.8.0_391/linux-amd64",
|
||||
expected: pkg.Package{
|
||||
Name: "java/jre",
|
||||
Name: "java",
|
||||
Version: "1.8.0-foreman_2023_10_12_13_27-b00",
|
||||
Type: "binary",
|
||||
PURL: "pkg:generic/java/jre@1.8.0-foreman_2023_10_12_13_27-b00",
|
||||
PURL: "pkg:generic/ibm/java@1.8.0-foreman_2023_10_12_13_27-b00",
|
||||
Locations: locations("java"),
|
||||
Metadata: metadata("java-binary-ibm", "java"),
|
||||
},
|
||||
},
|
||||
{
|
||||
logicalFixture: "java-ibm-8-jre/1.8.0_451/linux-amd64",
|
||||
expected: pkg.Package{
|
||||
Name: "java",
|
||||
Version: "1.8.0-_2025_04_14_02_37-b00",
|
||||
Type: "binary",
|
||||
PURL: "pkg:generic/ibm/java@1.8.0-_2025_04_14_02_37-b00",
|
||||
Locations: locations("java"),
|
||||
Metadata: metadata("java-binary-ibm", "java"),
|
||||
},
|
||||
},
|
||||
{
|
||||
logicalFixture: "java-ibm-8-sdk-alpine/1.8.0_321/linux-amd64",
|
||||
expected: pkg.Package{
|
||||
Name: "java_sdk",
|
||||
Version: "1.8.0-foreman_2022_01_20_09_33-b00",
|
||||
Type: "binary",
|
||||
PURL: "pkg:generic/ibm/java_sdk@1.8.0-foreman_2022_01_20_09_33-b00",
|
||||
Locations: locations("jdb"),
|
||||
Metadata: metadata("java-sdk-binary-ibm", "jdb"),
|
||||
},
|
||||
},
|
||||
{
|
||||
logicalFixture: "java-jdk-openjdk/21.0.2+13-LTS/linux-amd64",
|
||||
expected: pkg.Package{
|
||||
Name: "java/jdk",
|
||||
Name: "openjdk",
|
||||
Version: "21.0.2+13-LTS",
|
||||
Type: "binary",
|
||||
PURL: "pkg:generic/java/jdk@21.0.2%2B13-LTS",
|
||||
PURL: "pkg:generic/oracle/openjdk@21.0.2%2B13-LTS",
|
||||
Locations: locations("jdb"),
|
||||
Metadata: metadata("java-binary-jdk", "java"),
|
||||
Metadata: metadata("java-binary-openjdk-fallthrough", "jdb"),
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -985,6 +1007,28 @@ func Test_Cataloger_PositiveCases(t *testing.T) {
|
||||
Metadata: metadata("consul-binary"),
|
||||
},
|
||||
},
|
||||
{
|
||||
logicalFixture: "vault/1.20.2/linux-amd64",
|
||||
expected: pkg.Package{
|
||||
Name: "github.com/hashicorp/vault",
|
||||
Version: "1.20.2",
|
||||
Type: "golang",
|
||||
PURL: "pkg:golang/github.com/hashicorp/vault@1.20.2",
|
||||
Locations: locations("vault"),
|
||||
Metadata: metadata("hashicorp-vault-binary"),
|
||||
},
|
||||
},
|
||||
{
|
||||
logicalFixture: "vault/1.19.4/linux-arm64",
|
||||
expected: pkg.Package{
|
||||
Name: "github.com/hashicorp/vault",
|
||||
Version: "1.19.4",
|
||||
Type: "golang",
|
||||
PURL: "pkg:golang/github.com/hashicorp/vault@1.19.4",
|
||||
Locations: locations("vault"),
|
||||
Metadata: metadata("hashicorp-vault-binary"),
|
||||
},
|
||||
},
|
||||
{
|
||||
logicalFixture: "erlang/25.3.2.6/linux-amd64",
|
||||
expected: pkg.Package{
|
||||
@@ -1463,8 +1507,8 @@ func Test_Cataloger_CustomClassifiers(t *testing.T) {
|
||||
Class: "foo-binary",
|
||||
FileGlob: "**/foo",
|
||||
EvidenceMatcher: binutils.FileContentsVersionMatcher(
|
||||
`(?m)foobar\s(?P<version>[0-9]+\.[0-9]+\.[0-9]+)`,
|
||||
catalogerName,
|
||||
`(?m)foobar\s(?P<version>[0-9]+\.[0-9]+\.[0-9]+)`,
|
||||
),
|
||||
Package: "foo",
|
||||
PURL: mustPURL("pkg:generic/foo@version"),
|
||||
@@ -1521,7 +1565,7 @@ func Test_Cataloger_CustomClassifiers(t *testing.T) {
|
||||
binutils.Classifier{
|
||||
Class: "foo-binary",
|
||||
FileGlob: "**/foo",
|
||||
EvidenceMatcher: binutils.FileContentsVersionMatcher(`(?m)not there`, catalogerName),
|
||||
EvidenceMatcher: binutils.FileContentsVersionMatcher(catalogerName, `(?m)not there`),
|
||||
Package: "foo",
|
||||
PURL: mustPURL("pkg:generic/foo@version"),
|
||||
CPEs: singleCPE("cpe:2.3:a:foo:foo:*:*:*:*:*:*:*:*"),
|
||||
@@ -1739,7 +1783,7 @@ func TestCatalogerConfig_MarshalJSON(t *testing.T) {
|
||||
{
|
||||
Class: "class",
|
||||
FileGlob: "glob",
|
||||
EvidenceMatcher: binutils.FileContentsVersionMatcher(".thing", catalogerName),
|
||||
EvidenceMatcher: binutils.FileContentsVersionMatcher(catalogerName, ".thing"),
|
||||
Package: "pkg",
|
||||
PURL: packageurl.PackageURL{
|
||||
Type: "type",
|
||||
|
||||
@@ -28,11 +28,11 @@ func DefaultClassifiers() []binutils.Classifier {
|
||||
// ruby 2.7.7p221 (2022-11-24 revision 168ec2b1e5) [x86_64-linux]
|
||||
`(?m)ruby (?P<version>[0-9]+\.[0-9]+\.[0-9]+((p|preview|rc|dev)[0-9]*)?) `)
|
||||
|
||||
return []binutils.Classifier{
|
||||
classifiers := []binutils.Classifier{
|
||||
{
|
||||
Class: "python-binary",
|
||||
FileGlob: "**/python*",
|
||||
EvidenceMatcher: binutils.EvidenceMatchers(
|
||||
EvidenceMatcher: binutils.MatchAny(
|
||||
// try to find version information from libpython shared libraries
|
||||
binutils.SharedLibraryLookup(
|
||||
`^libpython[0-9]+(?:\.[0-9]+)+[a-z]?\.so.*$`,
|
||||
@@ -98,7 +98,7 @@ func DefaultClassifiers() []binutils.Classifier {
|
||||
{
|
||||
Class: "redis-binary",
|
||||
FileGlob: "**/redis-server",
|
||||
EvidenceMatcher: binutils.EvidenceMatchers(
|
||||
EvidenceMatcher: binutils.MatchAny(
|
||||
// matches most recent versions of redis (~v7), e.g. "7.0.14buildkitsandbox-1702957741000000000"
|
||||
m.FileContentsVersionMatcher(`[^\d](?P<version>\d+.\d+\.\d+)buildkitsandbox-\d+`),
|
||||
// matches against older versions of redis (~v3 - v6), e.g. "4.0.11841ce7054bd9-1542359302000000000"
|
||||
@@ -113,73 +113,10 @@ func DefaultClassifiers() []binutils.Classifier {
|
||||
cpe.Must("cpe:2.3:a:redis:redis:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
|
||||
},
|
||||
},
|
||||
{
|
||||
Class: "java-binary-openjdk",
|
||||
FileGlob: "**/java",
|
||||
EvidenceMatcher: binutils.MatchExcluding(
|
||||
binutils.EvidenceMatchers(
|
||||
m.FileContentsVersionMatcher(
|
||||
// [NUL]openjdk[NUL]java[NUL]0.0[NUL]11.0.17+8-LTS[NUL]
|
||||
// [NUL]openjdk[NUL]java[NUL]1.8[NUL]1.8.0_352-b08[NUL]
|
||||
`(?m)\x00openjdk\x00java\x00(?P<release>[0-9]+[.0-9]*)\x00(?P<version>[0-9]+[^\x00]+)\x00`),
|
||||
m.FileContentsVersionMatcher(
|
||||
// arm64 versions: [NUL]0.0[NUL][NUL][NUL][NUL][NUL]11.0.22+7[NUL][NUL][NUL][NUL][NUL][NUL][NUL]openjdk[NUL]java[NUL]
|
||||
`(?m)\x00(?P<release>[0-9]+[.0-9]*)\x00+(?P<version>[0-9]+[^\x00]+)\x00+openjdk\x00java`),
|
||||
),
|
||||
// don't match graalvm
|
||||
"-jvmci-",
|
||||
),
|
||||
Package: "java/jre",
|
||||
PURL: mustPURL("pkg:generic/java/jre@version"),
|
||||
// TODO the updates might need to be part of the CPE Attributes, like: 1.8.0:update152
|
||||
CPEs: singleCPE("cpe:2.3:a:oracle:openjdk:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
|
||||
},
|
||||
{
|
||||
Class: "java-binary-ibm",
|
||||
FileGlob: "**/java",
|
||||
EvidenceMatcher: m.FileContentsVersionMatcher(
|
||||
// [NUL]java[NUL]1.8[NUL][NUL][NUL][NUL]1.8.0-foreman_2022_09_22_15_30-b00[NUL]
|
||||
`(?m)\x00java\x00(?P<release>[0-9]+[.0-9]+)\x00{4}(?P<version>[0-9]+[-._a-zA-Z0-9]+)\x00`),
|
||||
Package: "java/jre",
|
||||
PURL: mustPURL("pkg:generic/java/jre@version"),
|
||||
CPEs: singleCPE("cpe:2.3:a:ibm:java:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
|
||||
},
|
||||
{
|
||||
Class: "java-binary-oracle",
|
||||
FileGlob: "**/java",
|
||||
EvidenceMatcher: binutils.MatchExcluding(
|
||||
m.FileContentsVersionMatcher(
|
||||
// [NUL]19.0.1+10-21[NUL]
|
||||
`(?m)\x00(?P<version>[0-9]+[.0-9]+[+][-0-9]+)\x00`),
|
||||
// don't match openjdk
|
||||
`\x00openjdk\x00`,
|
||||
),
|
||||
Package: "java/jre",
|
||||
PURL: mustPURL("pkg:generic/java/jre@version"),
|
||||
CPEs: singleCPE("cpe:2.3:a:oracle:jre:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
|
||||
},
|
||||
{
|
||||
Class: "java-binary-graalvm",
|
||||
FileGlob: "**/java",
|
||||
EvidenceMatcher: m.FileContentsVersionMatcher(
|
||||
`(?m)\x00(?P<version>[0-9]+[.0-9]+[.0-9]+\+[0-9]+-jvmci-[0-9]+[.0-9]+-b[0-9]+)\x00`),
|
||||
Package: "java/graalvm",
|
||||
PURL: mustPURL("pkg:generic/java/graalvm@version"),
|
||||
CPEs: singleCPE("cpe:2.3:a:oracle:graalvm:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
|
||||
},
|
||||
{
|
||||
Class: "java-binary-jdk",
|
||||
FileGlob: "**/jdb",
|
||||
EvidenceMatcher: m.FileContentsVersionMatcher(
|
||||
`(?m)\x00(?P<version>[0-9]+\.[0-9]+\.[0-9]+(\+[0-9]+)?([-._a-zA-Z0-9]+)?)\x00`),
|
||||
Package: "java/jdk",
|
||||
PURL: mustPURL("pkg:generic/java/jdk@version"),
|
||||
CPEs: singleCPE("cpe:2.3:a:oracle:jdk:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
|
||||
},
|
||||
{
|
||||
Class: "nodejs-binary",
|
||||
FileGlob: "**/node",
|
||||
EvidenceMatcher: binutils.EvidenceMatchers(
|
||||
EvidenceMatcher: binutils.MatchAny(
|
||||
// [NUL]node v0.10.48[NUL]
|
||||
// [NUL]v0.12.18[NUL]
|
||||
// [NUL]v4.9.1[NUL]
|
||||
@@ -221,7 +158,7 @@ func DefaultClassifiers() []binutils.Classifier {
|
||||
{
|
||||
Class: "haproxy-binary",
|
||||
FileGlob: "**/haproxy",
|
||||
EvidenceMatcher: binutils.EvidenceMatchers(
|
||||
EvidenceMatcher: binutils.MatchAny(
|
||||
m.FileContentsVersionMatcher(`(?m)version (?P<version>[0-9]+\.[0-9]+(\.|-dev|-rc)[0-9]+)(-[a-z0-9]{7})?, released 20`),
|
||||
m.FileContentsVersionMatcher(`(?m)HA-Proxy version (?P<version>[0-9]+\.[0-9]+(\.|-dev)[0-9]+)`),
|
||||
m.FileContentsVersionMatcher(`(?m)(?P<version>[0-9]+\.[0-9]+(\.|-dev)[0-9]+)-[0-9a-zA-Z]{7}.+HAProxy version`),
|
||||
@@ -303,7 +240,7 @@ func DefaultClassifiers() []binutils.Classifier {
|
||||
{
|
||||
Class: "mysql-binary",
|
||||
FileGlob: "**/mysql",
|
||||
EvidenceMatcher: binutils.EvidenceMatchers(
|
||||
EvidenceMatcher: binutils.MatchAny(
|
||||
// shutdown[NUL]8.0.37[NUL][NUL][NUL][NUL][NUL]mysql_real_esc
|
||||
m.FileContentsVersionMatcher(`\x00(?P<version>[0-9]+(\.[0-9]+)?(\.[0-9]+)?(alpha[0-9]|beta[0-9]|rc[0-9])?)\x00+mysql`),
|
||||
// /export/home/pb2/build/sb_0-26781090-1516292385.58/release/mysql-8.0.4-rc/mysys_ssl/my_default.cc
|
||||
@@ -380,7 +317,7 @@ func DefaultClassifiers() []binutils.Classifier {
|
||||
{
|
||||
Class: "ruby-binary",
|
||||
FileGlob: "**/ruby",
|
||||
EvidenceMatcher: binutils.EvidenceMatchers(
|
||||
EvidenceMatcher: binutils.MatchAny(
|
||||
rubyMatcher,
|
||||
binutils.SharedLibraryLookup(
|
||||
// try to find version information from libruby shared libraries
|
||||
@@ -394,7 +331,7 @@ func DefaultClassifiers() []binutils.Classifier {
|
||||
{
|
||||
Class: "erlang-binary",
|
||||
FileGlob: "**/erlexec",
|
||||
EvidenceMatcher: binutils.EvidenceMatchers(
|
||||
EvidenceMatcher: binutils.MatchAny(
|
||||
m.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/`,
|
||||
@@ -411,7 +348,7 @@ func DefaultClassifiers() []binutils.Classifier {
|
||||
{
|
||||
Class: "erlang-alpine-binary",
|
||||
FileGlob: "**/beam.smp",
|
||||
EvidenceMatcher: binutils.EvidenceMatchers(
|
||||
EvidenceMatcher: binutils.MatchAny(
|
||||
m.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/`,
|
||||
@@ -432,7 +369,7 @@ func DefaultClassifiers() []binutils.Classifier {
|
||||
{
|
||||
Class: "erlang-library",
|
||||
FileGlob: "**/liberts_internal.a",
|
||||
EvidenceMatcher: binutils.EvidenceMatchers(
|
||||
EvidenceMatcher: binutils.MatchAny(
|
||||
m.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/`,
|
||||
@@ -511,6 +448,16 @@ func DefaultClassifiers() []binutils.Classifier {
|
||||
PURL: mustPURL("pkg:golang/github.com/hashicorp/consul@version"),
|
||||
CPEs: singleCPE("cpe:2.3:a:hashicorp:consul:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
|
||||
},
|
||||
{
|
||||
Class: "hashicorp-vault-binary",
|
||||
FileGlob: "**/vault",
|
||||
EvidenceMatcher: m.FileContentsVersionMatcher(
|
||||
// revoke1.18.0
|
||||
`(?m)revoke(?P<version>[0-9]+\.[0-9]+\.[0-9]+)`),
|
||||
Package: "github.com/hashicorp/vault",
|
||||
PURL: mustPURL("pkg:golang/github.com/hashicorp/vault@version"),
|
||||
CPEs: singleCPE("cpe:2.3:a:hashicorp:vault:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
|
||||
},
|
||||
{
|
||||
Class: "nginx-binary",
|
||||
FileGlob: "**/nginx",
|
||||
@@ -681,6 +628,8 @@ func DefaultClassifiers() []binutils.Classifier {
|
||||
CPEs: singleCPE("cpe:2.3:a:google:chrome:*:*:*:*:*:*:*:*"),
|
||||
},
|
||||
}
|
||||
|
||||
return append(classifiers, defaultJavaClassifiers()...)
|
||||
}
|
||||
|
||||
// singleCPE returns a []cpe.CPE with Source: Generated based on the cpe string or panics if the
|
||||
|
||||
@@ -0,0 +1,196 @@
|
||||
package binary
|
||||
|
||||
import (
|
||||
"github.com/anchore/syft/syft/cpe"
|
||||
"github.com/anchore/syft/syft/pkg/cataloger/internal/binutils"
|
||||
)
|
||||
|
||||
//nolint:funlen
|
||||
func defaultJavaClassifiers() []binutils.Classifier {
|
||||
m := binutils.ContextualEvidenceMatchers{CatalogerName: catalogerName}
|
||||
|
||||
return []binutils.Classifier{
|
||||
{
|
||||
Class: "java-binary",
|
||||
FileGlob: "**/java",
|
||||
EvidenceMatcher: binutils.BranchingEvidenceMatcher([]binutils.Classifier{
|
||||
{
|
||||
Class: "java-binary-graalvm",
|
||||
EvidenceMatcher: m.FileContentsVersionMatcher(
|
||||
`(?m)\x00(?P<version>[0-9]+[.0-9]+[.0-9]+\+[0-9]+-jvmci-[0-9]+[.0-9]+-b[0-9]+)\x00`),
|
||||
Package: "graalvm",
|
||||
PURL: mustPURL("pkg:generic/oracle/graalvm@version"),
|
||||
CPEs: singleCPE("cpe:2.3:a:oracle:graalvm:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
|
||||
},
|
||||
{
|
||||
Class: "java-binary-openjdk-zulu",
|
||||
EvidenceMatcher: binutils.MatchAll(
|
||||
binutils.MatchPath(`**/*zulu*/**`),
|
||||
binutils.MatchAny(
|
||||
m.FileContentsVersionMatcher(
|
||||
// [NUL]openjdk[NUL]java[NUL]0.0[NUL]11.0.17+8-LTS[NUL]
|
||||
`(?m)\x00java\x00(?P<release>[0-9]+[.0-9]*)\x00(?P<version>[0-9]+[^\x00]+)\x00`),
|
||||
m.FileContentsVersionMatcher(
|
||||
// arm64 versions: [NUL]0.0[NUL][NUL][NUL][NUL][NUL]11.0.22+7[NUL][NUL][NUL][NUL][NUL][NUL][NUL]openjdk[NUL]java[NUL]
|
||||
`(?m)\x00(?P<release>[0-9]+[.0-9]*)\x00+(?P<version>[0-9]+[^\x00]+)\x00+(openjdk|java)`),
|
||||
),
|
||||
),
|
||||
Package: "zulu",
|
||||
PURL: mustPURL("pkg:generic/azul/zulu@version"),
|
||||
CPEs: singleCPE("cpe:2.3:a:azul:zulu:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
|
||||
},
|
||||
{
|
||||
Class: "java-binary-openjdk-with-update",
|
||||
EvidenceMatcher: binutils.MatchAny(
|
||||
m.FileContentsVersionMatcher(
|
||||
`openjdk`,
|
||||
// [NUL]openjdk[NUL]java[NUL]1.8[NUL]1.8.0_352-b08[NUL]
|
||||
`(?m)java\x00(?P<release>[0-9]+[.0-9]*)\x00(?P<version>(?<primary>[0-9]+[^\x00]+)_(?<update>[^\x00]+)-[^\x00]+)\x00`),
|
||||
m.FileContentsVersionMatcher(
|
||||
`openjdk`,
|
||||
// arm64 versions: [NUL]0.0[NUL][NUL][NUL][NUL][NUL]1.8.0_352-b08[NUL][NUL][NUL][NUL][NUL][NUL][NUL]openjdk[NUL]java[NUL]
|
||||
`(?m)\x00(?P<release>[0-9]+[.0-9]*)\x00+(?P<version>(?<primary>[0-9]+[^\x00]+)_(?<update>[^\x00]+)-[^\x00]+)\x00+openjdk\x00java`),
|
||||
),
|
||||
Package: "openjdk",
|
||||
PURL: mustPURL("pkg:generic/oracle/openjdk@version"),
|
||||
CPEs: singleCPE("cpe:2.3:a:oracle:openjdk:{{.primary}}:update{{.update}}:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
|
||||
},
|
||||
{
|
||||
Class: "java-binary-openjdk",
|
||||
EvidenceMatcher: binutils.MatchAny(
|
||||
m.FileContentsVersionMatcher(
|
||||
// [NUL]openjdk[NUL]java[NUL]0.0[NUL]11.0.17+8-LTS[NUL]
|
||||
`(?m)\x00openjdk\x00java\x00(?P<release>[0-9]+[.0-9]*)\x00(?P<version>[0-9]+[^\x00]+)\x00`),
|
||||
m.FileContentsVersionMatcher(
|
||||
// arm64 versions: [NUL]0.0[NUL][NUL][NUL][NUL][NUL]11.0.22+7[NUL][NUL][NUL][NUL][NUL][NUL][NUL]openjdk[NUL]java[NUL]
|
||||
`(?m)\x00(?P<release>[0-9]+[.0-9]*)\x00+(?P<version>[0-9]+[^\x00]+)\x00+openjdk\x00java`),
|
||||
),
|
||||
Package: "openjdk",
|
||||
PURL: mustPURL("pkg:generic/oracle/openjdk@version"),
|
||||
CPEs: singleCPE("cpe:2.3:a:oracle:openjdk:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
|
||||
},
|
||||
{
|
||||
Class: "java-binary-ibm",
|
||||
EvidenceMatcher: binutils.MatchAll(
|
||||
binutils.MatchAny(
|
||||
binutils.MatchPath("**/ibm/**"),
|
||||
binutils.SharedLibraryLookup(
|
||||
`^libjli\.so$`,
|
||||
m.FileContentsVersionMatcher("IBM_JAVA")),
|
||||
),
|
||||
m.FileContentsVersionMatcher(
|
||||
// [NUL]java[NUL]1.8[NUL][NUL][NUL]1.8.0-foreman_2022_01_20_09_33-b00[NUL]
|
||||
`(?m)\x00java\x00+(?P<release>[0-9]+[.0-9]+)\x00+(?P<version>[0-9]+[-._a-zA-Z0-9]+)\x00`),
|
||||
),
|
||||
Package: "java",
|
||||
PURL: mustPURL("pkg:generic/ibm/java@version"),
|
||||
CPEs: singleCPE("cpe:2.3:a:ibm:java:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
|
||||
},
|
||||
{
|
||||
Class: "java-binary-openjdk-fallthrough",
|
||||
EvidenceMatcher: m.FileContentsVersionMatcher(
|
||||
"openjdk",
|
||||
// [NUL]19.0.1+10-21[NUL]
|
||||
`(?m)\x00(?P<version>[0-9]+[.0-9]+[+][-0-9]+)\x00`,
|
||||
),
|
||||
Package: "jre",
|
||||
PURL: mustPURL("pkg:generic/oracle/jre@version"),
|
||||
CPEs: singleCPE("cpe:2.3:a:oracle:jre:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
|
||||
},
|
||||
{
|
||||
Class: "java-binary-oracle",
|
||||
EvidenceMatcher: m.FileContentsVersionMatcher(
|
||||
// [NUL]19.0.1+10-21[NUL]
|
||||
// java[NUL]1.8[NUL]1.8.0_451-b10
|
||||
`(?m)\x00(?P<version>[0-9]+\.[0-9]+\.[-._+a-zA-Z0-9]+)\x00`,
|
||||
),
|
||||
Package: "jre",
|
||||
PURL: mustPURL("pkg:generic/oracle/jre@version"),
|
||||
CPEs: singleCPE("cpe:2.3:a:oracle:jre:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
|
||||
},
|
||||
}...),
|
||||
},
|
||||
{
|
||||
Class: "java-jdb-binary",
|
||||
FileGlob: "**/jdb",
|
||||
EvidenceMatcher: binutils.BranchingEvidenceMatcher([]binutils.Classifier{
|
||||
{
|
||||
Class: "java-binary-graalvm",
|
||||
EvidenceMatcher: m.FileContentsVersionMatcher(
|
||||
`(?m)\x00(?P<version>[0-9]+[.0-9]+[.0-9]+\+[0-9]+-jvmci-[0-9]+[.0-9]+-b[0-9]+)\x00`),
|
||||
Package: "graalvm",
|
||||
PURL: mustPURL("pkg:generic/oracle/graalvm@version"),
|
||||
CPEs: singleCPE("cpe:2.3:a:oracle:graalvm_for_jdk:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
|
||||
},
|
||||
{
|
||||
Class: "java-jdb-binary-openjdk",
|
||||
EvidenceMatcher: binutils.MatchAll(
|
||||
m.FileContentsVersionMatcher(
|
||||
// [NUL]openjdk[NUL]java[NUL]0.0[NUL]11.0.17+8-LTS[NUL]
|
||||
// [NUL]openjdk[NUL]java[NUL]1.8[NUL]1.8.0_352-b08[NUL]
|
||||
`(?m)\x00openjdk\x00java\x00(?P<release>[0-9]+[.0-9]*)\x00(?P<version>[0-9]+[^\x00]+)\x00`),
|
||||
m.FileContentsVersionMatcher(
|
||||
// arm64 versions: [NUL]0.0[NUL][NUL][NUL][NUL][NUL]11.0.22+7[NUL][NUL][NUL][NUL][NUL][NUL][NUL]openjdk[NUL]java[NUL]
|
||||
`(?m)\x00(?P<release>[0-9]+[.0-9]*)\x00+(?P<version>[0-9]+[^\x00]+)\x00+openjdk\x00java`),
|
||||
),
|
||||
Package: "openjdk",
|
||||
PURL: mustPURL("pkg:generic/oracle/openjdk@version"),
|
||||
CPEs: singleCPE("cpe:2.3:a:oracle:openjdk:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
|
||||
},
|
||||
{
|
||||
Class: "jdb-binary-openjdk-zulu",
|
||||
EvidenceMatcher: binutils.MatchAll(
|
||||
binutils.MatchPath("**/*zulu*/**"),
|
||||
binutils.MatchAny(
|
||||
m.FileContentsVersionMatcher(
|
||||
// [NUL]openjdk[NUL]java[NUL]0.0[NUL]11.0.17+8-LTS[NUL]
|
||||
`(?m)\x00openjdk\x00java\x00(?P<release>[0-9]+[.0-9]*)\x00(?P<version>[0-9]+[^\x00]+)\x00`),
|
||||
m.FileContentsVersionMatcher(
|
||||
// arm64 versions: [NUL]0.0[NUL][NUL][NUL][NUL][NUL]11.0.22+7[NUL][NUL][NUL][NUL][NUL][NUL][NUL]openjdk[NUL]java[NUL]
|
||||
`(?m)\x00(?P<release>[0-9]+[.0-9]*)\x00+(?P<version>[0-9]+[^\x00]+)\x00+openjdk\x00java`),
|
||||
),
|
||||
),
|
||||
Package: "zulu",
|
||||
PURL: mustPURL("pkg:generic/azul/zulu@version"),
|
||||
CPEs: singleCPE("cpe:2.3:a:azul:zulu:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
|
||||
},
|
||||
{
|
||||
Class: "java-sdk-binary-ibm",
|
||||
EvidenceMatcher: binutils.MatchAll(
|
||||
binutils.MatchAny(
|
||||
binutils.MatchPath("**/ibm/**"),
|
||||
binutils.SharedLibraryLookup(
|
||||
`^libjli\.so$`,
|
||||
m.FileContentsVersionMatcher("IBM_JAVA")),
|
||||
),
|
||||
m.FileContentsVersionMatcher(
|
||||
// [NUL]java[NUL]./lib/tools.jar./lib/sa-jdi.jar./classes.-J-ms8m[NUL][NUL]1.8[NUL][NUL][NUL]1.8.0-foreman_2022_01_20_09_33-b00[NUL]
|
||||
`(?m)\x00java\x00.+?\x00(?P<version>[0-9]+[-._a-zA-Z0-9]+)\x00`),
|
||||
),
|
||||
Package: "java_sdk",
|
||||
PURL: mustPURL("pkg:generic/ibm/java_sdk@version"),
|
||||
CPEs: singleCPE("cpe:2.3:a:ibm:java_sdk:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
|
||||
},
|
||||
{
|
||||
Class: "java-binary-openjdk-fallthrough",
|
||||
EvidenceMatcher: binutils.MatchAll(
|
||||
m.FileContentsVersionMatcher(
|
||||
"openjdk",
|
||||
`(?m)\x00(?P<version>[0-9]+\.[0-9]+\.[0-9]+(\+[0-9]+)?([-._a-zA-Z0-9]+)?)\x00`),
|
||||
),
|
||||
Package: "openjdk",
|
||||
PURL: mustPURL("pkg:generic/oracle/openjdk@version"),
|
||||
CPEs: singleCPE("cpe:2.3:a:oracle:openjdk:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
|
||||
},
|
||||
{
|
||||
Class: "java-binary-jdk",
|
||||
EvidenceMatcher: m.FileContentsVersionMatcher(
|
||||
`(?m)\x00(?P<version>[0-9]+\.[0-9]+\.[0-9]+(\+[0-9]+)?([-._a-zA-Z0-9]+)?)\x00`),
|
||||
Package: "jdk",
|
||||
PURL: mustPURL("pkg:generic/oracle/jdk@version"),
|
||||
CPEs: singleCPE("cpe:2.3:a:oracle:jdk:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
|
||||
},
|
||||
}...),
|
||||
},
|
||||
}
|
||||
}
|
||||
@@ -14,5 +14,5 @@ type EvidenceMatcher = binutils.EvidenceMatcher
|
||||
func FileContentsVersionMatcher(
|
||||
pattern string,
|
||||
) EvidenceMatcher {
|
||||
return binutils.FileContentsVersionMatcher(pattern, catalogerName)
|
||||
return binutils.FileContentsVersionMatcher(catalogerName, pattern)
|
||||
}
|
||||
|
||||
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
+11
@@ -0,0 +1,11 @@
|
||||
name: vault
|
||||
offset: 191891817
|
||||
length: 420
|
||||
snippetSha256: fd8eb7979e1e7bbc254f2f7a26f6a70ecb479cc4f50c804f3b0789bc0e229097
|
||||
fileSha256: a4754a343e619adef87a1d7e1368a0709ba29802fefbe8d70105c11085becd43
|
||||
|
||||
### byte snippet to follow ###
|
||||
ctstreamPragma</a>.
|
||||
:httpssocks Locked%s.logCT_LOGLOCAL0@level[INFO][WARN]env:///v1/%sDELETEcreateErrorserrorsclient/data/lookupactualAcceptregionawskmsocikmspkcs11%s%s%scloud:%s.%s:revoke1.19.4)(nil))(%#v) {...}frenchCommonArabicBrahmiCarianChakmaCopticGothicHangulHatranHebrewKaithiKhojkiLepchaLycianLydianRejangSyriacTai_LeTangsaTangutTeluguThaanaWanchoYezidiHyphen\u%04x\U%08xgetentpasswd390625%s
|
||||
%s
|
||||
%q: %wnumber\uff
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
name: vault
|
||||
offset: 213670425
|
||||
length: 220
|
||||
snippetSha256: d9b23916d00e8085a4066974641ef77962f2e0aae6f4244688d2c4fe4286c92b
|
||||
fileSha256: fb484f1b458e5d2fd28270b406a8b26b28d040dddcaa1d099aa9ee4ac927b730
|
||||
|
||||
### byte snippet to follow ###
|
||||
ctstreamPragma</a>.
|
||||
:httpssocks Locked%s.logCT_LOGLOCAL0@level[INFO][WARN]env:///v1/%sDELETEcreateErrorserrorsclient/data/lookupactualAcceptregionawskmsocikmspkcs11%s%s%scloud:%s.%s:revoke1.20.2)(nil))(%#v) {...}frenchCo
|
||||
@@ -194,6 +194,25 @@ from-images:
|
||||
platform: linux/amd64
|
||||
paths:
|
||||
- /opt/ibm/java/jre/bin/java
|
||||
- /opt/ibm/java/jre/lib/amd64/jli/libjli.so
|
||||
|
||||
- name: java-ibm-8-jre
|
||||
version: 1.8.0_451
|
||||
images:
|
||||
- ref: ibmjava:8-jre@sha256:3588cd1cc9b8646fe03b3b15210e69b1b520f1321f8518b69c0e7013d702fd23
|
||||
platform: linux/amd64
|
||||
paths:
|
||||
- /opt/ibm/java/jre/bin/java
|
||||
- /opt/ibm/java/jre/lib/amd64/jli/libjli.so
|
||||
|
||||
- name: java-ibm-8-sdk-alpine
|
||||
version: 1.8.0_321
|
||||
images:
|
||||
- ref: ibmjava:8-sdk-alpine@sha256:4f8ad2029e78f7b91721745a77fc6011a7c0e09b9edeffb6b20b6ec34a6e63cd
|
||||
platform: linux/amd64
|
||||
paths:
|
||||
- /opt/ibm/java/bin/jdb
|
||||
- /opt/ibm/java/lib/amd64/jli/libjli.so
|
||||
|
||||
- version: 10.6.15
|
||||
images:
|
||||
@@ -320,6 +339,23 @@ from-images:
|
||||
paths:
|
||||
- /usr/local/bin/node
|
||||
|
||||
- name: java-jdk-oracle
|
||||
version: 1.8.0_451-b10
|
||||
images:
|
||||
- ref: container-registry.oracle.com/java/jdk:8u451-oraclelinux8@sha256:f9c980e52853bd0a8815ad908c9a4025ed68cb52f31f3b8cd0cd442ee367bfd1
|
||||
platform: linux/amd64
|
||||
paths:
|
||||
- /usr/java/jdk-8/bin/java
|
||||
- /usr/java/jdk-8/bin/jdb
|
||||
|
||||
- name: java-jre-oracle-sdk
|
||||
version: 1.8.0_451-b10
|
||||
images:
|
||||
- ref: container-registry.oracle.com/java/serverjre:1.8.0_451@sha256:fe78fe3efd292dceb5685882ce1b13eb78492f383ccfd52a1b88a4f755b9d996
|
||||
platform: linux/amd64
|
||||
paths:
|
||||
- /usr/java/jdk-8/bin/java
|
||||
|
||||
- name: java-jre-openjdk
|
||||
version: 1.8.0_352-b08
|
||||
images:
|
||||
@@ -688,6 +724,20 @@ from-images:
|
||||
paths:
|
||||
- /bin/consul
|
||||
|
||||
- version: 1.20.2
|
||||
images:
|
||||
- ref: hashicorp/vault@sha256:5cd2003247e0a574a66c66aee1916b1e9e7f99640298f2e61271a8842d2d2a19
|
||||
platform: linux/amd64
|
||||
paths:
|
||||
- /bin/vault
|
||||
|
||||
- version: 1.19.4
|
||||
images:
|
||||
- ref: hashicorp/vault@sha256:b5f675b0bf681568cd7354c697fe4ce953024312d6d23ee7216deda60c192bad
|
||||
platform: linux/arm64
|
||||
paths:
|
||||
- /bin/vault
|
||||
|
||||
- version: 3.0.2
|
||||
images:
|
||||
- ref: fluent/fluent-bit:3.0.2-amd64@sha256:7e6fe8efd51dda0739e355f58bf5e3b1623cbf2d4a23c06c7a365d9553e2d242
|
||||
|
||||
@@ -133,6 +133,7 @@ func addLicenses(ctx context.Context, resolver file.Resolver, dbLocation file.Lo
|
||||
if len(licenseStrs) == 0 {
|
||||
sr, sl := fetchCopyrightContents(resolver, dbLocation, metadata)
|
||||
if sr != nil && sl != nil {
|
||||
defer internal.CloseAndLogError(sr, sl.AccessPath)
|
||||
p.Licenses.Add(pkg.NewLicensesFromReadCloserWithContext(ctx, file.NewLocationReadCloser(*sl, sr))...)
|
||||
}
|
||||
}
|
||||
@@ -292,11 +293,10 @@ func fetchCopyrightContents(resolver file.Resolver, dbLocation file.Location, m
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
reader, err := resolver.FileContentsByLocation(*location)
|
||||
reader, err := resolver.FileContentsByLocation(*location) //nolint:gocritic // since we're returning the reader, it's up to the caller to close it
|
||||
if err != nil {
|
||||
log.Tracef("failed to fetch deb copyright contents (package=%s): %s", m.Package, err)
|
||||
}
|
||||
defer internal.CloseAndLogError(reader, location.RealPath)
|
||||
|
||||
l := location.WithAnnotation(pkg.EvidenceAnnotationKey, pkg.SupportingEvidenceAnnotation)
|
||||
|
||||
|
||||
@@ -98,7 +98,6 @@ func findLibmanJSON(resolver file.Resolver, depsJSON file.Location) (*libmanJSON
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
internal.CloseAndLogError(reader, loc.RealPath)
|
||||
|
||||
lj, err := newLibmanJSON(file.NewLocationReadCloser(*loc, reader))
|
||||
if err != nil {
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
package binutils
|
||||
|
||||
import (
|
||||
"io"
|
||||
|
||||
"github.com/anchore/syft/internal"
|
||||
"github.com/anchore/syft/syft/internal/unionreader"
|
||||
"github.com/anchore/syft/syft/pkg"
|
||||
)
|
||||
|
||||
// BranchingEvidenceMatcher loads the contents of the reader into memory, assuming that all
|
||||
// classifier matchers are going to be reading the same file, e.g. a "java" binary, continuing to
|
||||
// try classifier EvidenceMatcher until the first set of packages is found
|
||||
func BranchingEvidenceMatcher(classifiers ...Classifier) EvidenceMatcher {
|
||||
return func(_ Classifier, context MatcherContext) ([]pkg.Package, error) {
|
||||
// we are scanning the same contents multiple times, so read it into memory for a reader that can reset
|
||||
rdr, err := getReader(context)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer internal.CloseAndLogError(rdr, context.Location.RealPath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, c := range classifiers {
|
||||
pkgs, err := c.EvidenceMatcher(c, MatcherContext{
|
||||
Resolver: context.Resolver,
|
||||
Location: context.Location,
|
||||
GetReader: func(_ MatcherContext) (unionreader.UnionReader, error) {
|
||||
_, err := rdr.Seek(0, io.SeekStart)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return rdr, nil
|
||||
},
|
||||
})
|
||||
if len(pkgs) > 0 || err != nil {
|
||||
return pkgs, err
|
||||
}
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
package binutils
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/anchore/syft/syft/file"
|
||||
"github.com/anchore/syft/syft/internal/unionreader"
|
||||
)
|
||||
|
||||
func Test_BranchingMatcher(t *testing.T) {
|
||||
matchingTest := FileContentsVersionMatcher("", `my-verison:(?<version>\d+\.\d+)`)
|
||||
notMatchingTest := MatchPath("**/not-version*")
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
matcher EvidenceMatcher
|
||||
expectedPackageNames []string
|
||||
}{
|
||||
{
|
||||
name: "not matching",
|
||||
matcher: BranchingEvidenceMatcher(
|
||||
Classifier{
|
||||
EvidenceMatcher: MatchAll(
|
||||
notMatchingTest,
|
||||
matchingTest,
|
||||
),
|
||||
Package: "a-pkg",
|
||||
},
|
||||
),
|
||||
expectedPackageNames: nil,
|
||||
},
|
||||
{
|
||||
name: "both match",
|
||||
matcher: BranchingEvidenceMatcher(
|
||||
Classifier{
|
||||
EvidenceMatcher: matchingTest,
|
||||
Package: "a-pkg",
|
||||
},
|
||||
Classifier{
|
||||
EvidenceMatcher: matchingTest,
|
||||
Package: "b-pkg",
|
||||
},
|
||||
),
|
||||
expectedPackageNames: []string{"a-pkg"},
|
||||
},
|
||||
{
|
||||
name: "first-does-not-match",
|
||||
matcher: BranchingEvidenceMatcher(
|
||||
Classifier{
|
||||
EvidenceMatcher: MatchAll(
|
||||
notMatchingTest,
|
||||
matchingTest,
|
||||
),
|
||||
Package: "b-pkg",
|
||||
},
|
||||
Classifier{
|
||||
EvidenceMatcher: matchingTest,
|
||||
Package: "c-pkg",
|
||||
},
|
||||
),
|
||||
expectedPackageNames: []string{"c-pkg"},
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
resolver := file.NewMockResolverForPaths("test-fixtures/version.txt", "test-fixtures/version-parts.txt")
|
||||
locs, err := resolver.FilesByGlob("**/version.txt")
|
||||
require.NoError(t, err)
|
||||
require.Len(t, locs, 1)
|
||||
loc := locs[0]
|
||||
rdr, err := resolver.FileContentsByLocation(loc)
|
||||
require.NoError(t, err)
|
||||
urdr, err := unionreader.GetUnionReader(rdr)
|
||||
require.NoError(t, err)
|
||||
pkgs, err := test.matcher(Classifier{
|
||||
Package: "a-pkg",
|
||||
}, MatcherContext{
|
||||
Resolver: resolver,
|
||||
Location: loc,
|
||||
GetReader: func(resolver MatcherContext) (unionreader.UnionReader, error) {
|
||||
return urdr, nil
|
||||
},
|
||||
})
|
||||
require.NoError(t, err)
|
||||
var got []string
|
||||
for i := range pkgs {
|
||||
got = append(got, pkgs[i].Name)
|
||||
}
|
||||
require.EqualValues(t, test.expectedPackageNames, got)
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -8,11 +8,14 @@ import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"maps"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
"text/template"
|
||||
|
||||
"github.com/bmatcuk/doublestar/v4"
|
||||
|
||||
"github.com/anchore/packageurl-go"
|
||||
"github.com/anchore/syft/internal"
|
||||
"github.com/anchore/syft/internal/log"
|
||||
@@ -71,7 +74,8 @@ func (cfg Classifier) MarshalJSON() ([]byte, error) {
|
||||
return json.Marshal(m)
|
||||
}
|
||||
|
||||
// EvidenceMatcher is a function called to catalog Packages that match some sort of evidence
|
||||
// EvidenceMatcher is a function called to identify based on some sort of evidence in the filesystem contents.
|
||||
// A non-nil return value indicates a successful match, regardless of packages being returned.
|
||||
type EvidenceMatcher func(classifier Classifier, context MatcherContext) ([]pkg.Package, error)
|
||||
|
||||
type MatcherContext struct {
|
||||
@@ -80,13 +84,16 @@ type MatcherContext struct {
|
||||
GetReader func(resolver MatcherContext) (unionreader.UnionReader, error)
|
||||
}
|
||||
|
||||
func EvidenceMatchers(matchers ...EvidenceMatcher) EvidenceMatcher {
|
||||
// MatchAny returns a combined evidence matcher that returns results from the first
|
||||
// matcher that returns results
|
||||
func MatchAny(matchers ...EvidenceMatcher) EvidenceMatcher {
|
||||
return func(classifier Classifier, context MatcherContext) ([]pkg.Package, error) {
|
||||
for _, matcher := range matchers {
|
||||
match, err := matcher(classifier, context)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// only return when results
|
||||
if match != nil {
|
||||
return match, nil
|
||||
}
|
||||
@@ -95,6 +102,23 @@ func EvidenceMatchers(matchers ...EvidenceMatcher) EvidenceMatcher {
|
||||
}
|
||||
}
|
||||
|
||||
// MatchAll executes all matchers until one returns nil results, only returning the final results
|
||||
func MatchAll(matchers ...EvidenceMatcher) EvidenceMatcher {
|
||||
return func(classifier Classifier, context MatcherContext) ([]pkg.Package, error) {
|
||||
var out []pkg.Package
|
||||
for _, matcher := range matchers {
|
||||
match, err := matcher(classifier, context)
|
||||
if match == nil || err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(match) > 0 {
|
||||
out = match
|
||||
}
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
}
|
||||
|
||||
type ContextualEvidenceMatchers struct {
|
||||
CatalogerName string
|
||||
}
|
||||
@@ -103,8 +127,8 @@ func (c ContextualEvidenceMatchers) FileNameTemplateVersionMatcher(fileNamePatte
|
||||
return FileNameTemplateVersionMatcher(fileNamePattern, contentTemplate, c.CatalogerName)
|
||||
}
|
||||
|
||||
func (c ContextualEvidenceMatchers) FileContentsVersionMatcher(pattern string) EvidenceMatcher {
|
||||
return FileContentsVersionMatcher(pattern, c.CatalogerName)
|
||||
func (c ContextualEvidenceMatchers) FileContentsVersionMatcher(patterns ...string) EvidenceMatcher {
|
||||
return FileContentsVersionMatcher(c.CatalogerName, patterns...)
|
||||
}
|
||||
|
||||
func FileNameTemplateVersionMatcher(fileNamePattern, contentTemplate, catalogerName string) EvidenceMatcher {
|
||||
@@ -156,17 +180,36 @@ func FileNameTemplateVersionMatcher(fileNamePattern, contentTemplate, catalogerN
|
||||
}
|
||||
}
|
||||
|
||||
func FileContentsVersionMatcher(pattern, catalogerName string) EvidenceMatcher {
|
||||
pat := regexp.MustCompile(pattern)
|
||||
// FileContentsVersionMatcher will match all provided patterns, extracting named capture groups from each pattern, overwriting earlier results
|
||||
func FileContentsVersionMatcher(catalogerName string, patterns ...string) EvidenceMatcher {
|
||||
if len(patterns) == 0 {
|
||||
panic("must specify at least one pattern")
|
||||
}
|
||||
var pats []*regexp.Regexp
|
||||
for _, pattern := range patterns {
|
||||
pats = append(pats, regexp.MustCompile(pattern))
|
||||
}
|
||||
return func(classifier Classifier, context MatcherContext) ([]pkg.Package, error) {
|
||||
contents, err := getReader(context)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unable to get read contents for file: %w", err)
|
||||
}
|
||||
var matchMetadata map[string]string
|
||||
|
||||
matchMetadata, err := internal.MatchNamedCaptureGroupsFromReader(pat, contents)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unable to match version: %w", err)
|
||||
for _, pat := range pats {
|
||||
contents, err := getReader(context)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unable to get read contents for file: %w", err)
|
||||
}
|
||||
|
||||
match, err := internal.MatchNamedCaptureGroupsFromReader(pat, contents)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unable to match version: %w", err)
|
||||
}
|
||||
if match == nil {
|
||||
return nil, nil
|
||||
}
|
||||
if matchMetadata == nil {
|
||||
matchMetadata = match
|
||||
} else {
|
||||
maps.Copy(matchMetadata, match)
|
||||
}
|
||||
}
|
||||
|
||||
// Convert {major: 1, minor: 2, patch: 3} to "1.2.3"
|
||||
@@ -187,6 +230,10 @@ func FileContentsVersionMatcher(pattern, catalogerName string) EvidenceMatcher {
|
||||
|
||||
p := NewClassifierPackage(classifier, context.Location, matchMetadata, catalogerName)
|
||||
if p == nil {
|
||||
if matchMetadata != nil {
|
||||
// if we had a successful metadata match, but no packages, return a successful match result
|
||||
return []pkg.Package{}, nil
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
@@ -194,29 +241,6 @@ func FileContentsVersionMatcher(pattern, catalogerName string) EvidenceMatcher {
|
||||
}
|
||||
}
|
||||
|
||||
// MatchExcluding tests the provided regular expressions against the file, and if matched, DOES NOT return
|
||||
// anything that the matcher would otherwise return
|
||||
func MatchExcluding(matcher EvidenceMatcher, contentPatternsToExclude ...string) EvidenceMatcher {
|
||||
var nonMatchPatterns []*regexp.Regexp
|
||||
for _, p := range contentPatternsToExclude {
|
||||
nonMatchPatterns = append(nonMatchPatterns, regexp.MustCompile(p))
|
||||
}
|
||||
return func(classifier Classifier, context MatcherContext) ([]pkg.Package, error) {
|
||||
contents, err := getReader(context)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unable to get read contents for file: %w", err)
|
||||
}
|
||||
matches, err := internal.MatchAnyFromReader(contents, nonMatchPatterns...)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unable to match content: %w", err)
|
||||
}
|
||||
if matches {
|
||||
return nil, nil
|
||||
}
|
||||
return matcher(classifier, context)
|
||||
}
|
||||
}
|
||||
|
||||
func SharedLibraryLookup(sharedLibraryPattern string, sharedLibraryMatcher EvidenceMatcher) EvidenceMatcher {
|
||||
pat := regexp.MustCompile(sharedLibraryPattern)
|
||||
return func(classifier Classifier, context MatcherContext) (packages []pkg.Package, _ error) {
|
||||
@@ -234,16 +258,19 @@ func SharedLibraryLookup(sharedLibraryPattern string, sharedLibraryMatcher Evide
|
||||
return nil, err
|
||||
}
|
||||
for _, libraryLocation := range locations {
|
||||
// create a new resolver without the cached context lookup -- this is decidedly a different file
|
||||
newResolver := MatcherContext{
|
||||
Resolver: context.Resolver,
|
||||
Location: libraryLocation,
|
||||
GetReader: context.GetReader,
|
||||
Resolver: context.Resolver,
|
||||
Location: libraryLocation,
|
||||
}
|
||||
newResolver.Location = libraryLocation
|
||||
pkgs, err := sharedLibraryMatcher(classifier, newResolver)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// not a successful match
|
||||
if pkgs == nil {
|
||||
continue
|
||||
}
|
||||
for _, p := range pkgs {
|
||||
// set the source binary as the first location
|
||||
locationSet := file.NewLocationSet(context.Location)
|
||||
@@ -260,12 +287,28 @@ func SharedLibraryLookup(sharedLibraryPattern string, sharedLibraryMatcher Evide
|
||||
}
|
||||
packages = append(packages, p)
|
||||
}
|
||||
// return non-nil package results as a successful match indication if the evidence matcher returned a successful match indication
|
||||
if packages == nil {
|
||||
packages = pkgs
|
||||
}
|
||||
}
|
||||
}
|
||||
return packages, nil
|
||||
}
|
||||
}
|
||||
|
||||
func MatchPath(path string) EvidenceMatcher {
|
||||
if !doublestar.ValidatePattern(path) {
|
||||
panic("invalid pattern")
|
||||
}
|
||||
return func(_ Classifier, context MatcherContext) ([]pkg.Package, error) {
|
||||
if doublestar.MatchUnvalidated(path, context.Location.RealPath) {
|
||||
return []pkg.Package{}, nil // return non-nil
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
}
|
||||
|
||||
func getReader(context MatcherContext) (unionreader.UnionReader, error) {
|
||||
if context.GetReader != nil {
|
||||
return context.GetReader(context)
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
package binutils
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"reflect"
|
||||
"text/template"
|
||||
|
||||
"github.com/anchore/packageurl-go"
|
||||
"github.com/anchore/syft/internal/log"
|
||||
"github.com/anchore/syft/syft/cpe"
|
||||
"github.com/anchore/syft/syft/file"
|
||||
"github.com/anchore/syft/syft/pkg"
|
||||
@@ -21,8 +24,8 @@ func NewClassifierPackage(classifier Classifier, location file.Location, matchMe
|
||||
|
||||
var cpes []cpe.CPE
|
||||
for _, c := range classifier.CPEs {
|
||||
c.Attributes.Version = version
|
||||
c.Attributes.Update = update
|
||||
c.Attributes.Version = templatedUpdate(c.Attributes.Version, matchMetadata, version)
|
||||
c.Attributes.Update = templatedUpdate(c.Attributes.Update, matchMetadata, update)
|
||||
cpes = append(cpes, c)
|
||||
}
|
||||
|
||||
@@ -55,3 +58,28 @@ func NewClassifierPackage(classifier Classifier, location file.Location, matchMe
|
||||
|
||||
return &p
|
||||
}
|
||||
|
||||
func templatedUpdate(providedValue string, matchMetadata map[string]string, defaultValue string) string {
|
||||
// if no template provided, just use the value directly
|
||||
if providedValue == "" {
|
||||
return defaultValue
|
||||
}
|
||||
// support templated updates
|
||||
t, err := template.New("").Option("missingkey=zero").Parse(providedValue)
|
||||
if err != nil {
|
||||
log.Debugf("unable to parse classifier template=%q : %w", providedValue, err)
|
||||
} else {
|
||||
update := bytes.Buffer{}
|
||||
err = t.Execute(&update, matchMetadata)
|
||||
if err != nil {
|
||||
log.Debugf("unable to render template: %w", err)
|
||||
} else {
|
||||
// only use the template result if it's non-empty
|
||||
providedValue = update.String()
|
||||
if providedValue != "" {
|
||||
return providedValue
|
||||
}
|
||||
}
|
||||
}
|
||||
return defaultValue
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@ func Test_ClassifierCPEs(t *testing.T) {
|
||||
classifier: Classifier{
|
||||
Package: "some-app",
|
||||
FileGlob: "**/version.txt",
|
||||
EvidenceMatcher: FileContentsVersionMatcher(`(?m)my-verison:(?P<version>[0-9.]+)`, "cataloger-name"),
|
||||
EvidenceMatcher: FileContentsVersionMatcher("cataloger-name", `(?m)my-verison:(?P<version>[0-9.]+)`),
|
||||
CPEs: []cpe.CPE{},
|
||||
},
|
||||
cpes: nil,
|
||||
@@ -38,7 +38,7 @@ func Test_ClassifierCPEs(t *testing.T) {
|
||||
classifier: Classifier{
|
||||
Package: "some-app",
|
||||
FileGlob: "**/version.txt",
|
||||
EvidenceMatcher: FileContentsVersionMatcher(`(?m)my-verison:(?P<version>[0-9.]+)`, "cataloger-name"),
|
||||
EvidenceMatcher: FileContentsVersionMatcher("cataloger-name", `(?m)my-verison:(?P<version>[0-9.]+)`),
|
||||
CPEs: []cpe.CPE{
|
||||
cpe.Must("cpe:2.3:a:some:app:*:*:*:*:*:*:*:*", cpe.GeneratedSource),
|
||||
},
|
||||
@@ -53,7 +53,7 @@ func Test_ClassifierCPEs(t *testing.T) {
|
||||
classifier: Classifier{
|
||||
Package: "some-app",
|
||||
FileGlob: "**/version.txt",
|
||||
EvidenceMatcher: FileContentsVersionMatcher(`(?m)my-verison:(?P<version>[0-9.]+)`, "cataloger-name"),
|
||||
EvidenceMatcher: FileContentsVersionMatcher("cataloger-name", `(?m)my-verison:(?P<version>[0-9.]+)`),
|
||||
CPEs: []cpe.CPE{
|
||||
cpe.Must("cpe:2.3:a:some:app:*:*:*:*:*:*:*:*", cpe.GeneratedSource),
|
||||
cpe.Must("cpe:2.3:a:some:apps:*:*:*:*:*:*:*:*", cpe.GeneratedSource),
|
||||
@@ -70,7 +70,7 @@ func Test_ClassifierCPEs(t *testing.T) {
|
||||
classifier: Classifier{
|
||||
Package: "some-app",
|
||||
FileGlob: "**/version-parts.txt",
|
||||
EvidenceMatcher: FileContentsVersionMatcher(`(?m)\x00(?P<major>[0-9.]+)\x00(?P<minor>[0-9.]+)\x00(?P<patch>[0-9.]+)\x00`, "cataloger-name"),
|
||||
EvidenceMatcher: FileContentsVersionMatcher("cataloger-name", `(?m)\x00(?P<major>[0-9.]+)\x00(?P<minor>[0-9.]+)\x00(?P<patch>[0-9.]+)\x00`),
|
||||
CPEs: []cpe.CPE{},
|
||||
},
|
||||
cpes: nil,
|
||||
@@ -113,7 +113,7 @@ func TestClassifier_MarshalJSON(t *testing.T) {
|
||||
classifier: Classifier{
|
||||
Class: "class",
|
||||
FileGlob: "glob",
|
||||
EvidenceMatcher: FileContentsVersionMatcher(".thing", "cataloger-name"),
|
||||
EvidenceMatcher: FileContentsVersionMatcher("cataloger-name", ".thing"),
|
||||
Package: "pkg",
|
||||
PURL: packageurl.PackageURL{
|
||||
Type: "type",
|
||||
@@ -168,7 +168,7 @@ func TestFileContentsVersionMatcher(t *testing.T) {
|
||||
mockGetContent := func(context MatcherContext) (unionreader.UnionReader, error) {
|
||||
return unionreader.GetUnionReader(io.NopCloser(bytes.NewBufferString(tt.data)))
|
||||
}
|
||||
fn := FileContentsVersionMatcher(tt.pattern, "cataloger-name")
|
||||
fn := FileContentsVersionMatcher("cataloger-name", tt.pattern)
|
||||
p, err := fn(Classifier{}, MatcherContext{
|
||||
GetReader: mockGetContent,
|
||||
})
|
||||
|
||||
@@ -61,6 +61,9 @@
|
||||
"github.com/gofiber/template/django/v3": [
|
||||
"cpe:2.3:a:gofiber:django:*:*:*:*:*:go:*:*"
|
||||
],
|
||||
"github.com/google/nftables": [
|
||||
"cpe:2.3:a:google:nftables:*:*:*:*:*:go:*:*"
|
||||
],
|
||||
"github.com/gookit/goutil": [
|
||||
"cpe:2.3:a:go_util_project:go_util:*:*:*:*:*:go:*:*"
|
||||
],
|
||||
@@ -161,6 +164,9 @@
|
||||
]
|
||||
},
|
||||
"jenkins_plugins": {
|
||||
"ApicaLoadtest": [
|
||||
"cpe:2.3:a:jenkins:apica_loadtest:*:*:*:*:*:jenkins:*:*"
|
||||
],
|
||||
"DotCi": [
|
||||
"cpe:2.3:a:jenkins:dotci:*:*:*:*:*:jenkins:*:*"
|
||||
],
|
||||
@@ -1339,6 +1345,9 @@
|
||||
"nomad": [
|
||||
"cpe:2.3:a:jenkins:nomad:*:*:*:*:*:jenkins:*:*"
|
||||
],
|
||||
"nouvola-divecloud": [
|
||||
"cpe:2.3:a:jenkins:nouvola_divecloud:*:*:*:*:*:jenkins:*:*"
|
||||
],
|
||||
"nuget": [
|
||||
"cpe:2.3:a:jenkins:nuget:*:*:*:*:*:jenkins:*:*"
|
||||
],
|
||||
@@ -1919,6 +1928,9 @@
|
||||
"usemango-runner": [
|
||||
"cpe:2.3:a:jenkins:usemango_runner:*:*:*:*:*:jenkins:*:*"
|
||||
],
|
||||
"vaddy-plugin": [
|
||||
"cpe:2.3:a:jenkins:vaddy:*:*:*:*:*:jenkins:*:*"
|
||||
],
|
||||
"valgrind": [
|
||||
"cpe:2.3:a:jenkins:valgrind:*:*:*:*:*:jenkins:*:*"
|
||||
],
|
||||
@@ -2348,6 +2360,9 @@
|
||||
"@zxcvbn-ts/core": [
|
||||
"cpe:2.3:a:zxcvbn-ts_project:zxcvbn-ts:*:*:*:*:*:node.js:*:*"
|
||||
],
|
||||
"ContentTools": [
|
||||
"cpe:2.3:a:getme:contenttools:*:*:*:*:*:node.js:*:*"
|
||||
],
|
||||
"Proto": [
|
||||
"cpe:2.3:a:proto_project:proto:*:*:*:*:*:node.js:*:*"
|
||||
],
|
||||
@@ -5552,6 +5567,9 @@
|
||||
"mustache/mustache": [
|
||||
"cpe:2.3:a:mustache_project:mustache:*:*:*:*:*:php:*:*"
|
||||
],
|
||||
"nitsan/ns-backup": [
|
||||
"cpe:2.3:a:nitsantech:ns-backup:*:*:*:*:*:typo3:*:*"
|
||||
],
|
||||
"phpfastcache/phpfastcache": [
|
||||
"cpe:2.3:a:phpfastcache:phpfastcache:*:*:*:*:*:*:*:*"
|
||||
],
|
||||
@@ -8292,6 +8310,9 @@
|
||||
"awsm-team": [
|
||||
"cpe:2.3:a:awsm:awsm_team:*:*:*:*:free:wordpress:*:*"
|
||||
],
|
||||
"axle-demo-importer": [
|
||||
"cpe:2.3:a:axlethemes:axle_demo_importer:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"ays-chatgpt-assistant": [
|
||||
"cpe:2.3:a:ays-pro:chatgpt_assistant:*:*:*:*:free:wordpress:*:*"
|
||||
],
|
||||
@@ -8776,6 +8797,9 @@
|
||||
"cpe:2.3:a:brizy:brizy:*:*:*:*:free:wordpress:*:*",
|
||||
"cpe:2.3:a:brizy:brizy:*:*:*:*:pro:wordpress:*:*"
|
||||
],
|
||||
"broadstreet": [
|
||||
"cpe:2.3:a:broadstreetads:broadstreet:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"broken-link-checker": [
|
||||
"cpe:2.3:a:managewp:broken_link_checker:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -10535,6 +10559,9 @@
|
||||
"drawblog": [
|
||||
"cpe:2.3:a:drawblog_project:drawblog:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"drive-folder-embeder": [
|
||||
"cpe:2.3:a:azumbro:drive_folder_embedder:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"droit-dark-mode": [
|
||||
"cpe:2.3:a:droitthemes:droit_dark_mode:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -11042,6 +11069,7 @@
|
||||
"cpe:2.3:a:inisev:enhanced_text_widget:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"enhanced-tooltipglossary": [
|
||||
"cpe:2.3:a:cminds:cm_tooltip_glossary:*:*:*:*:*:wordpress:*:*",
|
||||
"cpe:2.3:a:cminds:tooltip_glossary:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"enqueue-anything": [
|
||||
@@ -11803,6 +11831,9 @@
|
||||
"frontier-post": [
|
||||
"cpe:2.3:a:wpfrontier:frontier_post:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"fs-product-inquiry": [
|
||||
"cpe:2.3:a:fudugo:fs_product_inquiry:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"fs-shopping-cart": [
|
||||
"cpe:2.3:a:firestormplugins:fs-shopping-cart:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -11833,6 +11864,9 @@
|
||||
"furikake": [
|
||||
"cpe:2.3:a:furikake_project:furikake:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"fusedesk": [
|
||||
"cpe:2.3:a:jeremyshapiro:fusedesk:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"fusion-builder": [
|
||||
"cpe:2.3:a:theme-fusion:avada:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -12061,6 +12095,9 @@
|
||||
"glossary-by-codeat": [
|
||||
"cpe:2.3:a:codeat:glossary:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"glossy": [
|
||||
"cpe:2.3:a:croberts:glossy:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"gm-woocommerce-quote-popup": [
|
||||
"cpe:2.3:a:gravitymaster:product_enquiry_for_woocommerce:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -12285,6 +12322,9 @@
|
||||
"gtbabel": [
|
||||
"cpe:2.3:a:gtbabel:gtbabel:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"gtg-advanced-blocks": [
|
||||
"cpe:2.3:a:gutengeek:free_gutenberg_blocks:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"gtm-server-side": [
|
||||
"cpe:2.3:a:stape:gtm_server_side:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -12459,6 +12499,9 @@
|
||||
"homepage-product-organizer-for-woocommerce": [
|
||||
"cpe:2.3:a:homepage_product_organizer_for_woocommerce_project:homepage_product_organizer_for_woocommerce:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"homerunner-smartcheckout": [
|
||||
"cpe:2.3:a:coolrunner:homerunner:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"honeypot": [
|
||||
"cpe:2.3:a:dineshkarki:wp_armour:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -12783,6 +12826,9 @@
|
||||
"indeed-job-importer": [
|
||||
"cpe:2.3:a:indeed-job-importer_project:indeed-job-importer:*:*:*:*:*:*:*:*"
|
||||
],
|
||||
"index-wp-mysql-for-speed": [
|
||||
"cpe:2.3:a:plumislandmedia:index_wp_mysql_for_speed:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"indieblocks": [
|
||||
"cpe:2.3:a:janboddez:indieblocks:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -13099,6 +13145,9 @@
|
||||
"cpe:2.3:a:joomsky:js_help_desk:*:*:*:*:*:wordpress:*:*",
|
||||
"cpe:2.3:a:wiselyhub:js_help_desk:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"js_composer": [
|
||||
"cpe:2.3:a:wpbakery:page_builder:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"jsmol2wp": [
|
||||
"cpe:2.3:a:jsmol2wp_project:jsmol2wp:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -13942,7 +13991,8 @@
|
||||
"cpe:2.3:a:mekshq:meks_flexible_shortcodes:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"meks-smart-author-widget": [
|
||||
"cpe:2.3:a:mekshq:meks_smart_author_widget:*:*:*:*:*:wordpress:*:*"
|
||||
"cpe:2.3:a:mekshq:meks_smart_author_widget:*:*:*:*:*:wordpress:*:*",
|
||||
"cpe:2.3:a:mekshq:smart_author_widget:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"meks-smart-social-widget": [
|
||||
"cpe:2.3:a:mekshq:meks_smart_social_widget:*:*:*:*:*:wordpress:*:*"
|
||||
@@ -14569,6 +14619,9 @@
|
||||
"note-press": [
|
||||
"cpe:2.3:a:datainterlock:note_press:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"notice-faq": [
|
||||
"cpe:2.3:a:notice:notice_faq:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"notices": [
|
||||
"cpe:2.3:a:notices_project:notices:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -15159,6 +15212,9 @@
|
||||
"plausible-analytics": [
|
||||
"cpe:2.3:a:plausible:plausible_analytics:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"play-ht": [
|
||||
"cpe:2.3:a:hammadh:play.ht:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"player": [
|
||||
"cpe:2.3:a:web-dorado:spidervplayer:*:*:*:*:*:wordpress:*:*",
|
||||
"cpe:2.3:a:web-dorado:web-dorado_spider_video_player:*:*:*:*:*:wordpress:*:*"
|
||||
@@ -15421,6 +15477,9 @@
|
||||
"posts-reminder": [
|
||||
"cpe:2.3:a:lucasgarcia:posts_reminder:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"posts-table-filterable": [
|
||||
"cpe:2.3:a:pluginus:tableon_-_wordpress_posts_table_filterable:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"posttabs": [
|
||||
"cpe:2.3:a:posttabs_project:posttabs:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -15816,6 +15875,9 @@
|
||||
"randomtext": [
|
||||
"cpe:2.3:a:random_text_project:random_text:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"rapid-cache": [
|
||||
"cpe:2.3:a:megaoptim:rapid_cache:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"rara-one-click-demo-import": [
|
||||
"cpe:2.3:a:rarathemes:rara_one_click_demo_import:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -15902,6 +15964,9 @@
|
||||
"recall-products": [
|
||||
"cpe:2.3:a:recall-products_project:recall-products:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"recaptcha-jetpack": [
|
||||
"cpe:2.3:a:bozdoz:recaptcha_jetpack:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"recent-backups": [
|
||||
"cpe:2.3:a:recent-backups_project:recent-backups:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -18050,6 +18115,9 @@
|
||||
"tourfic": [
|
||||
"cpe:2.3:a:themefic:tourfic:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"tourmaster": [
|
||||
"cpe:2.3:a:goodlayers:tour_master:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"tournamatch": [
|
||||
"cpe:2.3:a:tournamatch:tournamatch:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -19488,6 +19556,9 @@
|
||||
"wp-backgrounds-lite": [
|
||||
"cpe:2.3:a:inoplugs:wp-backgrounds_lite:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"wp-backitup": [
|
||||
"cpe:2.3:a:wpbackitup:backup_and_restore_wordpress:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"wp-baidu-submit": [
|
||||
"cpe:2.3:a:wp_baidu_submit_project:wp_baidu_submit:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -19781,6 +19852,9 @@
|
||||
"wp-easy-contact": [
|
||||
"cpe:2.3:a:emarketdesign:wp_easy_contact:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"wp-easy-gallery": [
|
||||
"cpe:2.3:a:plugingarden:wp_easy_gallery:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"wp-easy-pay": [
|
||||
"cpe:2.3:a:wpeasypay:wp_easypay:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -20180,6 +20254,9 @@
|
||||
"wp-marketing-automations": [
|
||||
"cpe:2.3:a:funnelkit:funnelkit_automations:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"wp-masonry-infinite-scroll": [
|
||||
"cpe:2.3:a:wporbit:wp_masonry_\\\u0026_infinite_scroll:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"wp-media-cleaner": [
|
||||
"cpe:2.3:a:wp_media_cleaner_project:wp_media_cleaner:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -20756,6 +20833,9 @@
|
||||
"wp-users-exporter": [
|
||||
"cpe:2.3:a:wp-users-exporter_project:wp-users-exporter:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"wp-users-masquerade": [
|
||||
"cpe:2.3:a:lagunaisw:wp_users_masquerade:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"wp-vertical-image-slider": [
|
||||
"cpe:2.3:a:i13websolution:wordpress_vertical_image_slider:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -21631,6 +21711,9 @@
|
||||
"posterity": [
|
||||
"cpe:2.3:a:sktthemes:posterity:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"pressmart": [
|
||||
"cpe:2.3:a:presslayouts:pressmart:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"regina-lite": [
|
||||
"cpe:2.3:a:machothemes:regina_lite:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
|
||||
@@ -1,15 +1,18 @@
|
||||
package java
|
||||
|
||||
import (
|
||||
"cmp"
|
||||
"context"
|
||||
"crypto"
|
||||
"fmt"
|
||||
"io"
|
||||
"iter"
|
||||
"os"
|
||||
"path"
|
||||
"slices"
|
||||
"strings"
|
||||
|
||||
"github.com/scylladb/go-set/strset"
|
||||
"golang.org/x/exp/maps"
|
||||
|
||||
"github.com/anchore/syft/internal"
|
||||
@@ -391,20 +394,32 @@ func (j *archiveParser) discoverMainPackageFromPomInfo(ctx context.Context) (gro
|
||||
projects, _ := pomProjectByParentPath(j.archivePath, j.location, j.fileManifest.GlobMatch(false, pomXMLGlob))
|
||||
|
||||
// map of all the artifacts in the pom properties, in order to chek exact match with the filename
|
||||
artifactsMap := make(map[string]bool)
|
||||
artifactsMap := strset.New()
|
||||
for _, propertiesObj := range properties {
|
||||
artifactsMap[propertiesObj.ArtifactID] = true
|
||||
artifactsMap.Add(propertiesObj.ArtifactID)
|
||||
}
|
||||
|
||||
parentPaths := maps.Keys(properties)
|
||||
slices.Sort(parentPaths)
|
||||
for _, parentPath := range parentPaths {
|
||||
propertiesObj := properties[parentPath]
|
||||
for parentPath, propertiesObj := range sortedIter(properties) {
|
||||
// the logic for selecting the best name is as follows:
|
||||
// if we find an artifact id AND group id which are both contained in the filename
|
||||
// OR if we have an artifact id that exactly matches the filename, prefer this
|
||||
// OTHERWISE track the first matching pom properties with a pom.xml
|
||||
// FINALLY return the first matching pom properties
|
||||
if artifactIDMatchesFilename(propertiesObj.ArtifactID, j.fileInfo.name, artifactsMap) {
|
||||
pomProperties = propertiesObj
|
||||
if pomProperties.ArtifactID == "" { // keep the first match, or overwrite if we find more specific entries
|
||||
pomProperties = propertiesObj
|
||||
}
|
||||
if proj, exists := projects[parentPath]; exists {
|
||||
parsedPom = proj
|
||||
break
|
||||
if parsedPom == nil { // keep the first matching artifact if we don't find an exact match or groupid + artfiact id match
|
||||
pomProperties = propertiesObj // set this, as it may not be the first entry found
|
||||
parsedPom = proj
|
||||
}
|
||||
// if artifact ID is the entire filename or BOTH artifactID and groupID are contained in the artifact, prefer this match
|
||||
if strings.Contains(j.fileInfo.name, propertiesObj.GroupID) || j.fileInfo.name == propertiesObj.ArtifactID {
|
||||
pomProperties = propertiesObj // this is an exact match, use it
|
||||
parsedPom = proj
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -429,12 +444,13 @@ func (j *archiveParser) discoverMainPackageFromPomInfo(ctx context.Context) (gro
|
||||
return group, name, version, parsedPom
|
||||
}
|
||||
|
||||
func artifactIDMatchesFilename(artifactID, fileName string, artifactsMap map[string]bool) bool {
|
||||
// artifactIDMatchesFilename returns true if one starts with the other
|
||||
func artifactIDMatchesFilename(artifactID, fileName string, artifactsMap *strset.Set) bool {
|
||||
if artifactID == "" || fileName == "" {
|
||||
return false
|
||||
}
|
||||
// Ensure true is returned when filename matches the artifact ID, prevent random retrieval by checking prefix and suffix
|
||||
if _, exists := artifactsMap[fileName]; exists {
|
||||
if artifactsMap.Has(fileName) {
|
||||
return artifactID == fileName
|
||||
}
|
||||
// Use fallback check with suffix and prefix if no POM properties file matches the exact artifact name
|
||||
@@ -464,7 +480,7 @@ func (j *archiveParser) discoverPkgsFromAllMavenFiles(ctx context.Context, paren
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for parentPath, propertiesObj := range properties {
|
||||
for parentPath, propertiesObj := range sortedIter(properties) {
|
||||
var parsedPom *parsedPomProject
|
||||
if proj, exists := projects[parentPath]; exists {
|
||||
parsedPom = proj
|
||||
@@ -546,7 +562,7 @@ func discoverPkgsFromOpeners(ctx context.Context, location file.Location, opener
|
||||
var pkgs []pkg.Package
|
||||
var relationships []artifact.Relationship
|
||||
|
||||
for pathWithinArchive, archiveOpener := range openers {
|
||||
for pathWithinArchive, archiveOpener := range sortedIter(openers) {
|
||||
nestedPkgs, nestedRelationships, err := discoverPkgsFromOpener(ctx, location, pathWithinArchive, archiveOpener, cfg, parentPkg)
|
||||
if err != nil {
|
||||
log.WithFields("location", location.Path(), "error", err).Debug("unable to discover java packages from opener")
|
||||
@@ -604,7 +620,7 @@ func pomPropertiesByParentPath(archivePath string, location file.Location, extra
|
||||
}
|
||||
|
||||
propertiesByParentPath := make(map[string]pkg.JavaPomProperties)
|
||||
for filePath, fileContents := range contentsOfMavenPropertiesFiles {
|
||||
for filePath, fileContents := range sortedIter(contentsOfMavenPropertiesFiles) {
|
||||
pomProperties, err := parsePomProperties(filePath, strings.NewReader(fileContents))
|
||||
if err != nil {
|
||||
log.WithFields("contents-path", filePath, "location", location.Path(), "error", err).Debug("failed to parse pom.properties")
|
||||
@@ -633,7 +649,7 @@ func pomProjectByParentPath(archivePath string, location file.Location, extractP
|
||||
}
|
||||
|
||||
projectByParentPath := make(map[string]*parsedPomProject)
|
||||
for filePath, fileContents := range contentsOfMavenProjectFiles {
|
||||
for filePath, fileContents := range sortedIter(contentsOfMavenProjectFiles) {
|
||||
// TODO: when we support locations of paths within archives we should start passing the specific pom.xml location object instead of the top jar
|
||||
pom, err := maven.ParsePomXML(strings.NewReader(fileContents))
|
||||
if err != nil {
|
||||
@@ -784,3 +800,15 @@ func updateParentPackage(p pkg.Package, parentPkg *pkg.Package) {
|
||||
parentPkg.Metadata = parentMetadata
|
||||
}
|
||||
}
|
||||
|
||||
func sortedIter[K cmp.Ordered, V any](values map[K]V) iter.Seq2[K, V] {
|
||||
return func(yield func(K, V) bool) {
|
||||
keys := maps.Keys(values)
|
||||
slices.Sort(keys)
|
||||
for _, key := range keys {
|
||||
if !yield(key, values[key]) {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1086,7 +1086,7 @@ func Test_artifactIDMatchesFilename(t *testing.T) {
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
assert.Equal(t, tt.want, artifactIDMatchesFilename(tt.artifactID, tt.fileName, nil))
|
||||
assert.Equal(t, tt.want, artifactIDMatchesFilename(tt.artifactID, tt.fileName, strset.New()))
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -1382,6 +1382,10 @@ func Test_deterministicMatchingPomProperties(t *testing.T) {
|
||||
fixture: "multiple-matching-2.11.5",
|
||||
expected: maven.NewID("org.multiple", "multiple-matching-1", "2.11.5"),
|
||||
},
|
||||
{
|
||||
fixture: "org.multiple-thename",
|
||||
expected: maven.NewID("org.multiple", "thename", "10.11.12"),
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
|
||||
@@ -11,7 +11,7 @@ import (
|
||||
"path"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/anchore/syft/syft/artifact"
|
||||
"github.com/anchore/syft/syft/cpe"
|
||||
@@ -36,16 +36,16 @@ func TestParseNativeImage(t *testing.T) {
|
||||
for _, test := range tests {
|
||||
t.Run(test.fixture, func(t *testing.T) {
|
||||
f, err := os.Open("test-fixtures/java-builds/packages/" + test.fixture)
|
||||
assert.NoError(t, err)
|
||||
require.NoError(t, err)
|
||||
readerCloser := io.NopCloser(f)
|
||||
reader, err := unionreader.GetUnionReader(readerCloser)
|
||||
assert.NoError(t, err)
|
||||
require.NoError(t, err)
|
||||
parsed := false
|
||||
readers, err := unionreader.GetReaders(reader)
|
||||
assert.NoError(t, err)
|
||||
require.NoError(t, err)
|
||||
for _, r := range readers {
|
||||
ni, err := test.newFn(test.fixture, r)
|
||||
assert.NoError(t, err)
|
||||
require.NoError(t, err)
|
||||
_, _, err = ni.fetchPkgs()
|
||||
if err == nil {
|
||||
t.Fatalf("should have failed to extract SBOM.")
|
||||
@@ -228,11 +228,11 @@ func buildPackageMap(packages []pkg.Package) map[string]pkg.Package {
|
||||
}
|
||||
|
||||
func verifyPackageFields(t *testing.T, expected, actual pkg.Package) {
|
||||
assert.Equal(t, expected.Name, actual.Name)
|
||||
assert.Equal(t, expected.Version, actual.Version)
|
||||
assert.Equal(t, expected.FoundBy, actual.FoundBy)
|
||||
assert.Equal(t, expected.PURL, actual.PURL)
|
||||
assert.ElementsMatch(t, expected.CPEs, actual.CPEs)
|
||||
require.Equal(t, expected.Name, actual.Name)
|
||||
require.Equal(t, expected.Version, actual.Version)
|
||||
require.Equal(t, expected.FoundBy, actual.FoundBy)
|
||||
require.Equal(t, expected.PURL, actual.PURL)
|
||||
require.ElementsMatch(t, expected.CPEs, actual.CPEs)
|
||||
}
|
||||
|
||||
func verifyRelationships(t *testing.T, expected, actual []artifact.Relationship) {
|
||||
@@ -260,8 +260,8 @@ func buildRelationshipMap(relationships []artifact.Relationship) map[string][]ar
|
||||
}
|
||||
|
||||
func verifyRelationshipFields(t *testing.T, expected, actual []artifact.Relationship) {
|
||||
assert.Equal(t, len(expected), len(actual))
|
||||
require.Equal(t, len(expected), len(actual))
|
||||
for i := range expected {
|
||||
assert.Equal(t, expected[i].Type, actual[i].Type)
|
||||
require.Equal(t, expected[i].Type, actual[i].Type)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -91,7 +91,7 @@ func parseJVMRelease(_ context.Context, resolver file.Resolver, _ *generic.Envir
|
||||
// the reason we use the reference to get the real path is in cases where the file cataloger is involved
|
||||
// (thus the real path is not available except for in the original file reference). This is important
|
||||
// since the path is critical for distinguishing between different JVM vendors.
|
||||
vendor, product := jvmPrimaryVendorProduct(ri.Implementor, string(reader.Reference().RealPath), ri.ImageType, hasJdk)
|
||||
vendor, product := jvmPrimaryVendorProduct(ri, string(reader.Reference().RealPath), hasJdk)
|
||||
|
||||
p := pkg.Package{
|
||||
Name: product,
|
||||
@@ -163,11 +163,11 @@ func jvmPurl(ri pkg.JavaVMRelease, version, vendor, product string) string {
|
||||
return pURL.ToString()
|
||||
}
|
||||
|
||||
func jvmPrimaryVendorProduct(implementor, path, imageType string, hasJdk bool) (string, string) {
|
||||
implementor = strings.ReplaceAll(strings.ToLower(implementor), " ", "")
|
||||
func jvmPrimaryVendorProduct(ri *pkg.JavaVMRelease, path string, hasJdk bool) (string, string) {
|
||||
implementor := strings.ReplaceAll(strings.ToLower(ri.Implementor), " ", "")
|
||||
|
||||
pickProduct := func() string {
|
||||
if hasJdk || jvmProjectByType(imageType) == jdk {
|
||||
if hasJdk || jvmProjectByType(ri.ImageType) == jdk {
|
||||
return jdk
|
||||
}
|
||||
return jre
|
||||
@@ -180,7 +180,13 @@ func jvmPrimaryVendorProduct(implementor, path, imageType string, hasJdk bool) (
|
||||
case strings.Contains(implementor, "sun"):
|
||||
return "sun", pickProduct()
|
||||
|
||||
case strings.Contains(implementor, "oracle") || strings.Contains(path, "oracle"):
|
||||
case strings.Contains(implementor, "ibm") || strings.Contains(path, "/ibm"):
|
||||
if hasJdk {
|
||||
return "ibm", "java_sdk"
|
||||
}
|
||||
return "ibm", "java"
|
||||
|
||||
case strings.Contains(implementor, "oracle") || strings.Contains(path, "oracle") || strings.Contains(ri.BuildType, "commercial"):
|
||||
return oracleVendor, pickProduct()
|
||||
}
|
||||
return oracleVendor, openJdkProduct
|
||||
|
||||
@@ -307,6 +307,7 @@ func TestJvmPrimaryVendorProduct(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
implementor string
|
||||
buildType string
|
||||
path string
|
||||
imageType string
|
||||
hasJdk bool
|
||||
@@ -340,6 +341,25 @@ func TestJvmPrimaryVendorProduct(t *testing.T) {
|
||||
expectedVendor: "oracle",
|
||||
expectedProduct: "jre",
|
||||
},
|
||||
{
|
||||
name: "Oracle commercial build type with JRE",
|
||||
implementor: "",
|
||||
buildType: "commercial",
|
||||
path: "/usr/lib/jvm/jdk8/release",
|
||||
imageType: "JRE",
|
||||
hasJdk: false,
|
||||
expectedVendor: "oracle",
|
||||
expectedProduct: "jre",
|
||||
},
|
||||
{
|
||||
name: "Oracle commercial build type with JDK",
|
||||
implementor: "",
|
||||
buildType: "commercial",
|
||||
path: "/usr/lib/jvm/jdk8/release",
|
||||
hasJdk: true,
|
||||
expectedVendor: "oracle",
|
||||
expectedProduct: "jdk",
|
||||
},
|
||||
{
|
||||
name: "Oracle vendor with JDK in path",
|
||||
implementor: "",
|
||||
@@ -367,11 +387,29 @@ func TestJvmPrimaryVendorProduct(t *testing.T) {
|
||||
expectedVendor: "oracle", // corretto upstream is oracle openjdk
|
||||
expectedProduct: "openjdk",
|
||||
},
|
||||
{
|
||||
name: "IBM JRE",
|
||||
path: "/opt/ibm/java/release",
|
||||
expectedVendor: "ibm",
|
||||
expectedProduct: "java",
|
||||
},
|
||||
{
|
||||
name: "IBM JDK",
|
||||
path: "/opt/ibm/java/release",
|
||||
hasJdk: true,
|
||||
expectedVendor: "ibm",
|
||||
expectedProduct: "java_sdk",
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
vendor, product := jvmPrimaryVendorProduct(tt.implementor, tt.path, tt.imageType, tt.hasJdk)
|
||||
ri := pkg.JavaVMRelease{
|
||||
Implementor: tt.implementor,
|
||||
BuildType: tt.buildType,
|
||||
ImageType: tt.imageType,
|
||||
}
|
||||
vendor, product := jvmPrimaryVendorProduct(&ri, tt.path, tt.hasJdk)
|
||||
assert.Equal(t, tt.expectedVendor, vendor)
|
||||
assert.Equal(t, tt.expectedProduct, product)
|
||||
})
|
||||
|
||||
@@ -12,6 +12,7 @@ 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
|
||||
ORG_MULTIPLE_THENAME = org.multiple-thename
|
||||
|
||||
|
||||
.DEFAULT_GOAL := fixtures
|
||||
@@ -48,7 +49,11 @@ $(CACHE_DIR)/$(MULTIPLE_MATCHING).jar:
|
||||
mkdir -p $(CACHE_DIR)
|
||||
cd $(MULTIPLE_MATCHING) && zip -r $(CACHE_PATH)/$(MULTIPLE_MATCHING).jar .
|
||||
|
||||
# Jenkins plugins typically do not have the version included in the archive name,
|
||||
$(CACHE_DIR)/$(ORG_MULTIPLE_THENAME).jar:
|
||||
mkdir -p $(CACHE_DIR)
|
||||
cd $(ORG_MULTIPLE_THENAME) && zip -r $(CACHE_PATH)/$(ORG_MULTIPLE_THENAME).jar .
|
||||
|
||||
# Jenkins plugins typically do not have the version included in the archive name,
|
||||
# so it is important to not include it in the generated test fixture
|
||||
$(CACHE_DIR)/gradle.hpi:
|
||||
mkdir -p $(CACHE_DIR)
|
||||
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
Manifest-Version: 1.0
|
||||
Created-By: Multi
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
version=10.11.12
|
||||
groupId=com.multiple
|
||||
artifactId=thename
|
||||
+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>com.multiple</groupId>
|
||||
<artifactId>thename</artifactId>
|
||||
<version>10.11.12</version>
|
||||
</project>
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
version=10.11.12
|
||||
groupId=org.multiple
|
||||
artifactId=thename
|
||||
+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>thename</artifactId>
|
||||
<version>10.11.12</version>
|
||||
</project>
|
||||
@@ -219,7 +219,7 @@ func (p interpreterCataloger) getClassifier(realPath string) (string, *binutils.
|
||||
|
||||
return name, &binutils.Classifier{
|
||||
Class: fmt.Sprintf("php-ext-%s-binary", name),
|
||||
EvidenceMatcher: binutils.FileContentsVersionMatcher(match, p.name),
|
||||
EvidenceMatcher: binutils.FileContentsVersionMatcher(p.name, match),
|
||||
Package: name,
|
||||
PURL: packageurl.PackageURL{
|
||||
Type: packageurl.TypeGeneric,
|
||||
|
||||
@@ -4,14 +4,27 @@ import (
|
||||
"testing"
|
||||
|
||||
"github.com/anchore/syft/syft/internal/packagemetadata"
|
||||
"github.com/anchore/syft/syft/internal/sourcemetadata"
|
||||
)
|
||||
|
||||
type PackageMetadataCompletionTester struct {
|
||||
*packagemetadata.CompletionTester
|
||||
}
|
||||
|
||||
type SourceMetadataCompletionTester struct {
|
||||
*sourcemetadata.CompletionTester
|
||||
}
|
||||
|
||||
func NewPackageMetadataCompletionTester(t testing.TB, ignore ...any) *PackageMetadataCompletionTester {
|
||||
t.Helper()
|
||||
return &PackageMetadataCompletionTester{
|
||||
CompletionTester: packagemetadata.NewCompletionTester(t, ignore...),
|
||||
}
|
||||
}
|
||||
|
||||
func NewSourceMetadataCompletionTester(t testing.TB, ignore ...any) *SourceMetadataCompletionTester {
|
||||
t.Helper()
|
||||
return &SourceMetadataCompletionTester{
|
||||
CompletionTester: sourcemetadata.NewCompletionTester(t, ignore...),
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user