mirror of
https://github.com/anchore/syft.git
synced 2026-10-12 14:17:20 +02:00
Compare commits
28
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
dfde0974b0 | ||
|
|
9f047fdf11 | ||
|
|
07ae2ca08d | ||
|
|
36969bdeff | ||
|
|
dfb6011083 | ||
|
|
997a486e22 | ||
|
|
4f64fbc004 | ||
|
|
87d6a288d7 | ||
|
|
20987d30d0 | ||
|
|
e2007d9bf2 | ||
|
|
4f0e32ab51 | ||
|
|
605391114c | ||
|
|
1caf243d29 | ||
|
|
48e91312e8 | ||
|
|
d81df67493 | ||
|
|
47cda2b5ef | ||
|
|
ae711963d1 | ||
|
|
f878197150 | ||
|
|
514efb03e0 | ||
|
|
1e4f424f09 | ||
|
|
b5f0877967 | ||
|
|
8cb78ce40c | ||
|
|
3b046b3787 | ||
|
|
05cc8ee5f4 | ||
|
|
3562dab445 | ||
|
|
014a4c9c59 | ||
|
|
3cb838eacf | ||
|
|
758324b3e8 |
@@ -35,7 +35,7 @@ runs:
|
||||
- name: Restore tool cache
|
||||
if: inputs.tools == 'true'
|
||||
id: tool-cache
|
||||
uses: actions/cache@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5.0.4
|
||||
uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
|
||||
with:
|
||||
path: ${{ github.workspace }}/.tool
|
||||
key: ${{ inputs.cache-key-prefix }}-${{ runner.os }}-tool-${{ hashFiles('.binny.yaml') }}
|
||||
@@ -60,7 +60,7 @@ runs:
|
||||
DEBIAN_FRONTEND=noninteractive sudo apt update && sudo -E apt install -y "${packages[@]}"
|
||||
- name: Restore ORAS cache from github actions
|
||||
if: inputs.download-test-fixture-cache == 'true'
|
||||
uses: actions/cache@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5.0.4
|
||||
uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
|
||||
with:
|
||||
path: ${{ github.workspace }}/.tmp/oras-cache
|
||||
key: ${{ inputs.cache-key-prefix }}-oras-cache
|
||||
|
||||
@@ -1,6 +1,3 @@
|
||||
# CodeQL scans for security vulnerabilities and coding errors across all
|
||||
# languages in this repo. Results appear in the "Security" tab under
|
||||
# "Code scanning alerts" and are enforced by branch protection rules.
|
||||
name: "CodeQL"
|
||||
|
||||
on:
|
||||
@@ -8,74 +5,17 @@ on:
|
||||
branches: [ "main" ]
|
||||
pull_request:
|
||||
branches: [ "main" ]
|
||||
# Weekly scheduled scan catches newly disclosed vulnerabilities in
|
||||
# existing code, not just changes introduced by PRs.
|
||||
schedule:
|
||||
- cron: '38 11 * * 3'
|
||||
|
||||
permissions: {}
|
||||
|
||||
jobs:
|
||||
analyze:
|
||||
name: Analyze (${{ matrix.language }})
|
||||
runs-on: ubuntu-latest
|
||||
name: Analyze
|
||||
uses: anchore/workflows/.github/workflows/codeql.yaml@e8cee3a5916cebb68cda68b54c180f43394c1910 # v0.5.0
|
||||
permissions:
|
||||
# Required to upload SARIF results to the "Security" tab.
|
||||
security-events: write
|
||||
# Required to fetch internal or private CodeQL packs.
|
||||
packages: read
|
||||
# Only required for workflows in private repositories.
|
||||
actions: read
|
||||
contents: read
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
# GitHub Actions workflow linting — no build needed.
|
||||
- language: actions
|
||||
build-mode: none
|
||||
|
||||
# Go uses "manual" build mode so we control exactly what gets
|
||||
# compiled. The default "autobuild" finds the Makefile and runs
|
||||
# the full CI pipeline (lint, test, snapshot release, etc.),
|
||||
# which is far more work than CodeQL needs. All it requires is
|
||||
# compiled Go source so it can build a type-resolved code graph
|
||||
# for analysis.
|
||||
- language: go
|
||||
build-mode: manual
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
# Pin the Go toolchain to whatever go.mod declares so CodeQL
|
||||
# analyzes with the same version the project actually uses.
|
||||
# Only runs for the Go matrix entry.
|
||||
- name: Setup Go
|
||||
if: matrix.language == 'go'
|
||||
uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0
|
||||
with:
|
||||
go-version-file: go.mod
|
||||
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@c10b8064de6f491fea524254123dbe5e09572f13 # v4.35.1
|
||||
with:
|
||||
languages: ${{ matrix.language }}
|
||||
build-mode: ${{ matrix.build-mode }}
|
||||
|
||||
# Minimal build for Go: compile all packages so CodeQL gets a full
|
||||
# type-resolved code graph for analysis.
|
||||
- name: Build (Go)
|
||||
if: matrix.build-mode == 'manual'
|
||||
shell: bash
|
||||
run: go build ./...
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@c10b8064de6f491fea524254123dbe5e09572f13 # v4.35.1
|
||||
with:
|
||||
# The category tag lets GitHub associate SARIF results with the
|
||||
# correct language when branch protection checks for required
|
||||
# code scanning results.
|
||||
category: "/language:${{matrix.language}}"
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
name: Dependabot Automation
|
||||
on:
|
||||
pull_request:
|
||||
|
||||
permissions:
|
||||
pull-requests: write
|
||||
|
||||
jobs:
|
||||
run:
|
||||
uses: anchore/workflows/.github/workflows/dependabot-automation.yaml@main
|
||||
@@ -1,64 +0,0 @@
|
||||
# Note: this workflow has been disabled manually in the UI and will be replaced in short order
|
||||
|
||||
name: "Detect schema changes"
|
||||
|
||||
on:
|
||||
# IMPORTANT! This workflow is triggered by the `pull_request_target` event
|
||||
# which means that forked PRs will run with access secrets from the repo
|
||||
# it's forked from (the "target" repo).
|
||||
#
|
||||
# For this reason we only NEVER checkout the code from the pull request
|
||||
# (e.g. "ref: ${{ github.event.pull_request.head.sha }}") to prevent
|
||||
# accidentally running potentially untrusted code.
|
||||
#
|
||||
# By default the checkout will be:
|
||||
# - GITHUB_SHA: Last commit on the PR base branch
|
||||
# - GITHUB_REF: PR base branch
|
||||
#
|
||||
# ...unlike a typical PR where:
|
||||
# - GITHUB_SHA: Last merge commit on the GITHUB_REF branch
|
||||
# - GITHUB_REF: PR merge branch refs/pull/:prNumber/merge
|
||||
pull_request_target:
|
||||
|
||||
env:
|
||||
# note: this is used within hashFiles() so must be within the GITHUB_WORKSPACE path (or will silently fail)
|
||||
CI_COMMENT_FILE: .tmp/labeler-comment.txt
|
||||
# needs to be any string to uniquely identify the comment on a PR across multiple runs
|
||||
COMMENT_HEADER: "label-commentary"
|
||||
|
||||
jobs:
|
||||
label:
|
||||
name: "Label changes"
|
||||
runs-on: ubuntu-22.04
|
||||
permissions:
|
||||
contents: read
|
||||
pull-requests: write
|
||||
issues: write
|
||||
steps:
|
||||
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd #v6.0.2
|
||||
with:
|
||||
persist-credentials: false
|
||||
repository: anchore/syft # IMPORTANT! An additional protection that this is checking out code from the expected repository
|
||||
ref: main # IMPORTANT! It is CRITICAL that this only ever considers the code from main and NEVER EVER from a fork.
|
||||
|
||||
- run: python .github/scripts/labeler.py
|
||||
env:
|
||||
# note: this token has write access to the repo
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
GITHUB_PR_NUMBER: ${{ github.event.number }}
|
||||
|
||||
- name: Delete existing comment
|
||||
if: ${{ hashFiles( env.CI_COMMENT_FILE ) == '' }}
|
||||
uses: marocchino/sticky-pull-request-comment@d4d6b0936434b21bc8345ad45a440c5f7d2c40ff #v3.0.3
|
||||
with:
|
||||
header: ${{ env.COMMENT_HEADER }}
|
||||
hide: true
|
||||
hide_classify: "OUTDATED"
|
||||
|
||||
- name: Add comment
|
||||
if: ${{ hashFiles( env.CI_COMMENT_FILE ) != '' }}
|
||||
uses: marocchino/sticky-pull-request-comment@d4d6b0936434b21bc8345ad45a440c5f7d2c40ff #v3.0.3
|
||||
with:
|
||||
header: ${{ env.COMMENT_HEADER }}
|
||||
path: ${{ env.CI_COMMENT_FILE }}
|
||||
@@ -1,18 +0,0 @@
|
||||
name: Add to OSS board
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
on:
|
||||
issues:
|
||||
types:
|
||||
- opened
|
||||
- reopened
|
||||
- transferred
|
||||
- labeled
|
||||
|
||||
jobs:
|
||||
run:
|
||||
uses: "anchore/workflows/.github/workflows/oss-project-board-add.yaml@main"
|
||||
secrets:
|
||||
token: ${{ secrets.OSS_PROJECT_GH_TOKEN }}
|
||||
+23
-108
@@ -1,7 +1,11 @@
|
||||
name: "Release"
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
permissions: {}
|
||||
|
||||
# there should never be two releases in progress at the same time
|
||||
concurrency:
|
||||
group: release
|
||||
cancel-in-progress: false
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
@@ -19,115 +23,26 @@ on:
|
||||
- "install-script-only"
|
||||
|
||||
jobs:
|
||||
quality-gate:
|
||||
environment: release
|
||||
|
||||
version-available:
|
||||
if: ${{ github.event.inputs.phase == 'all' }}
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd #v6.0.2
|
||||
with:
|
||||
persist-credentials: false
|
||||
uses: anchore/workflows/.github/workflows/check-version-available.yaml@8b2b1caf40e03933c6807e03b99e883e2ceb5ac8 # v0.4.0
|
||||
with:
|
||||
version: ${{ github.event.inputs.version }}
|
||||
|
||||
- name: Bootstrap environment
|
||||
uses: ./.github/actions/bootstrap
|
||||
|
||||
- name: Validate Apple notarization credentials
|
||||
run: .tool/quill submission list
|
||||
env:
|
||||
QUILL_NOTARY_ISSUER: ${{ secrets.APPLE_NOTARY_ISSUER }}
|
||||
QUILL_NOTARY_KEY_ID: ${{ secrets.APPLE_NOTARY_KEY_ID }}
|
||||
QUILL_NOTARY_KEY: ${{ secrets.APPLE_NOTARY_KEY }}
|
||||
|
||||
- name: Check if running on main
|
||||
if: github.ref != 'refs/heads/main'
|
||||
# we are using the following flag when running `cosign blob-verify` for checksum signature verification:
|
||||
# --certificate-identity-regexp "https://github.com/anchore/.github/workflows/release.yaml@refs/heads/main"
|
||||
# if we are not on the main branch, the signature will not be verifiable since the suffix requires the main branch
|
||||
# at the time of when the OIDC token was issued on the Github Actions runner.
|
||||
run: echo "This can only be run on the main branch otherwise releases produced will not be verifiable with cosign" && exit 1
|
||||
|
||||
- name: Check if tag already exists
|
||||
# note: this will fail if the tag already exists
|
||||
run: |
|
||||
[[ "$VERSION" == v* ]] || (echo "version '$VERSION' does not have a 'v' prefix" && exit 1)
|
||||
git tag "$VERSION"
|
||||
env:
|
||||
VERSION: ${{ github.event.inputs.version }}
|
||||
|
||||
- name: Check static analysis results
|
||||
uses: fountainhead/action-wait-for-check@5a908a24814494009c4bb27c242ea38c93c593be # v1.2.0
|
||||
id: static-analysis
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
# This check name is defined as the github action job name (in .github/workflows/testing.yaml)
|
||||
checkName: "Static analysis"
|
||||
ref: ${{ github.event.pull_request.head.sha || github.sha }}
|
||||
|
||||
- name: Check unit test results
|
||||
uses: fountainhead/action-wait-for-check@5a908a24814494009c4bb27c242ea38c93c593be # v1.2.0
|
||||
id: unit
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
# This check name is defined as the github action job name (in .github/workflows/testing.yaml)
|
||||
checkName: "Unit tests"
|
||||
ref: ${{ github.event.pull_request.head.sha || github.sha }}
|
||||
|
||||
- name: Check integration test results
|
||||
uses: fountainhead/action-wait-for-check@5a908a24814494009c4bb27c242ea38c93c593be # v1.2.0
|
||||
id: integration
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
# This check name is defined as the github action job name (in .github/workflows/testing.yaml)
|
||||
checkName: "Integration tests"
|
||||
ref: ${{ github.event.pull_request.head.sha || github.sha }}
|
||||
|
||||
- name: Check acceptance test results (linux)
|
||||
uses: fountainhead/action-wait-for-check@5a908a24814494009c4bb27c242ea38c93c593be # v1.2.0
|
||||
id: acceptance-linux
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
# This check name is defined as the github action job name (in .github/workflows/testing.yaml)
|
||||
checkName: "Acceptance tests (Linux)"
|
||||
ref: ${{ github.event.pull_request.head.sha || github.sha }}
|
||||
|
||||
- name: Check acceptance test results (mac)
|
||||
uses: fountainhead/action-wait-for-check@5a908a24814494009c4bb27c242ea38c93c593be # v1.2.0
|
||||
id: acceptance-mac
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
# This check name is defined as the github action job name (in .github/workflows/testing.yaml)
|
||||
checkName: "Acceptance tests (Mac)"
|
||||
ref: ${{ github.event.pull_request.head.sha || github.sha }}
|
||||
|
||||
- name: Check cli test results (linux)
|
||||
uses: fountainhead/action-wait-for-check@5a908a24814494009c4bb27c242ea38c93c593be # v1.2.0
|
||||
id: cli-linux
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
# This check name is defined as the github action job name (in .github/workflows/testing.yaml)
|
||||
checkName: "CLI tests (Linux)"
|
||||
ref: ${{ github.event.pull_request.head.sha || github.sha }}
|
||||
|
||||
- name: Quality gate
|
||||
if: steps.static-analysis.outputs.conclusion != 'success' || steps.unit.outputs.conclusion != 'success' || steps.integration.outputs.conclusion != 'success' || steps.cli-linux.outputs.conclusion != 'success' || steps.acceptance-linux.outputs.conclusion != 'success' || steps.acceptance-mac.outputs.conclusion != 'success'
|
||||
env:
|
||||
STATIC_ANALYSIS_STATUS: ${{ steps.static-analysis.conclusion }}
|
||||
UNIT_TEST_STATUS: ${{ steps.unit.outputs.conclusion }}
|
||||
INTEGRATION_TEST_STATUS: ${{ steps.integration.outputs.conclusion }}
|
||||
ACCEPTANCE_LINUX_STATUS: ${{ steps.acceptance-linux.outputs.conclusion }}
|
||||
ACCEPTANCE_MAC_STATUS: ${{ steps.acceptance-mac.outputs.conclusion }}
|
||||
CLI_LINUX_STATUS: ${{ steps.cli-linux.outputs.conclusion }}
|
||||
run: |
|
||||
echo "Static Analysis Status: $STATIC_ANALYSIS_STATUS"
|
||||
echo "Unit Test Status: $UNIT_TEST_STATUS"
|
||||
echo "Integration Test Status: $INTEGRATION_TEST_STATUS"
|
||||
echo "Acceptance Test (Linux) Status: $ACCEPTANCE_LINUX_STATUS"
|
||||
echo "Acceptance Test (Mac) Status: $ACCEPTANCE_MAC_STATUS"
|
||||
echo "CLI Test (Linux) Status: $CLI_LINUX_STATUS"
|
||||
false
|
||||
check-gate:
|
||||
if: ${{ github.event.inputs.phase == 'all' }}
|
||||
permissions:
|
||||
checks: read # required for getting the status of specific check names
|
||||
uses: anchore/workflows/.github/workflows/check-gate.yaml@8b2b1caf40e03933c6807e03b99e883e2ceb5ac8 # v0.4.0
|
||||
with:
|
||||
# these are checks that should be run on pull-request and merges to main.
|
||||
# we do NOT want to kick off a release if these have not been verified on main.
|
||||
# Please see the validations.yaml workflow for the names that should be used here.
|
||||
checks: '["Acceptance tests (Linux)", "Acceptance tests (Mac)", "Build snapshot artifacts", "CLI tests (Linux)", "Integration tests", "Static analysis", "Unit tests"]'
|
||||
|
||||
release:
|
||||
needs: [ quality-gate ]
|
||||
needs: [ check-gate, version-available ]
|
||||
if: ${{ github.event.inputs.phase == 'all' }}
|
||||
# runs-on.com: compute instances for parallel builds
|
||||
# spot disabled: reliability for build workflows (used for releases too)
|
||||
@@ -193,7 +108,7 @@ jobs:
|
||||
artifact-name: sbom.spdx.json
|
||||
|
||||
- name: Notify Slack of new release
|
||||
uses: slackapi/slack-github-action@af78098f536edbc4de71162a307590698245be95 #v3.0.1
|
||||
uses: slackapi/slack-github-action@45a88b9581bfab2566dc881e2cd66d334e621e2c #v3.0.3
|
||||
continue-on-error: true
|
||||
with:
|
||||
webhook: ${{ secrets.SLACK_TOOLBOX_WEBHOOK_URL }}
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
name: "Manage Awaiting Response Label"
|
||||
|
||||
on:
|
||||
issue_comment:
|
||||
types: [created]
|
||||
|
||||
jobs:
|
||||
run:
|
||||
permissions:
|
||||
contents: read
|
||||
issues: write
|
||||
pull-requests: write
|
||||
uses: "anchore/workflows/.github/workflows/remove-awaiting-response-label.yaml@main"
|
||||
secrets:
|
||||
token: ${{ secrets.OSS_PROJECT_GH_TOKEN }}
|
||||
@@ -10,8 +10,7 @@ on:
|
||||
- '.github/workflows/**'
|
||||
- '.github/actions/**'
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
permissions: {}
|
||||
|
||||
jobs:
|
||||
zizmor:
|
||||
@@ -26,7 +25,7 @@ jobs:
|
||||
persist-credentials: false
|
||||
|
||||
- name: "Run zizmor"
|
||||
uses: zizmorcore/zizmor-action@71321a20a9ded102f6e9ce5718a2fcec2c4f70d8 # v0.5.2
|
||||
uses: zizmorcore/zizmor-action@b1d7e1fb5de872772f31590499237e7cce841e8e # v0.5.3
|
||||
with:
|
||||
# there is a pass/fail gate as a repo ruleset (if there is no ruleset configured then the action will pass by default)
|
||||
advanced-security: true
|
||||
|
||||
@@ -13,8 +13,7 @@ on:
|
||||
branches:
|
||||
- main
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
permissions: {}
|
||||
|
||||
jobs:
|
||||
Static-Analysis:
|
||||
@@ -25,6 +24,8 @@ jobs:
|
||||
# s3-cache: faster actions cache
|
||||
# tmpfs: faster io-intensive workflows
|
||||
runs-on: &test-runner "runs-on=${{ github.run_id }}/cpu=4+8/ram=32+128/family=r5+r6+r7+r8+m4+m5+m6+m7+m8/spot=price-capacity-optimized/extras=s3-cache+tmpfs"
|
||||
permissions:
|
||||
contents: read
|
||||
steps:
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd #v6.0.2
|
||||
with:
|
||||
@@ -45,6 +46,8 @@ jobs:
|
||||
# Note: changing this job name requires making the same update in the .github/workflows/release.yaml pipeline
|
||||
name: "Unit tests"
|
||||
runs-on: *test-runner
|
||||
permissions:
|
||||
contents: read
|
||||
steps:
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd #v6.0.2
|
||||
with:
|
||||
@@ -65,6 +68,8 @@ jobs:
|
||||
# Note: changing this job name requires making the same update in the .github/workflows/release.yaml pipeline
|
||||
name: "Integration tests"
|
||||
runs-on: *test-runner
|
||||
permissions:
|
||||
contents: read
|
||||
steps:
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd #v6.0.2
|
||||
with:
|
||||
@@ -89,6 +94,8 @@ jobs:
|
||||
# s3-cache: faster actions cache
|
||||
# tmpfs: faster io-intensive workflows
|
||||
runs-on: "runs-on=${{ github.run_id }}/cpu=16+32/ram=32+128/family=c5+c6+c7+c8/spot=false/extras=s3-cache+tmpfs"
|
||||
permissions:
|
||||
contents: read
|
||||
steps:
|
||||
# required for magic-cache from runs-on to function with artifact upload/download (see https://runs-on.com/caching/magic-cache/#actionsupload-artifact-compatibility)
|
||||
- uses: runs-on/action@742bf56072eb4845a0f94b3394673e4903c90ff0 # v2.1.0
|
||||
@@ -120,6 +127,8 @@ jobs:
|
||||
name: "Acceptance tests (Linux)"
|
||||
needs: [Build-Snapshot-Artifacts]
|
||||
runs-on: *test-runner
|
||||
permissions:
|
||||
contents: read
|
||||
steps:
|
||||
# required for magic-cache from runs-on to function with artifact upload/download (see https://runs-on.com/caching/magic-cache/#actionsupload-artifact-compatibility)
|
||||
- uses: runs-on/action@742bf56072eb4845a0f94b3394673e4903c90ff0 # v2.1.0
|
||||
@@ -162,6 +171,8 @@ jobs:
|
||||
needs: [Build-Snapshot-Artifacts]
|
||||
# note: macos runners aren't supported yet for runs-on managed runners.
|
||||
runs-on: macos-latest
|
||||
permissions:
|
||||
contents: read
|
||||
steps:
|
||||
- name: Install Cosign
|
||||
uses: sigstore/cosign-installer@cad07c2e89fa2edd6e2d7bab4c1aa38e53f76003 # v4.1.1
|
||||
@@ -197,6 +208,8 @@ jobs:
|
||||
name: "CLI tests (Linux)"
|
||||
needs: [Build-Snapshot-Artifacts]
|
||||
runs-on: *test-runner
|
||||
permissions:
|
||||
contents: read
|
||||
steps:
|
||||
# required for magic-cache from runs-on to function with artifact upload/download (see https://runs-on.com/caching/magic-cache/#actionsupload-artifact-compatibility)
|
||||
- uses: runs-on/action@742bf56072eb4845a0f94b3394673e4903c90ff0 # v2.1.0
|
||||
|
||||
+55
-1
@@ -14,7 +14,7 @@ builds:
|
||||
dir: ./cmd/syft
|
||||
binary: syft
|
||||
goos: [linux]
|
||||
goarch: [amd64, arm64, ppc64le, s390x]
|
||||
goarch: [amd64, arm64, ppc64le, riscv64, s390x]
|
||||
mod_timestamp: &build-timestamp '{{ .CommitTimestamp }}'
|
||||
ldflags: &build-ldflags |
|
||||
-w
|
||||
@@ -114,6 +114,20 @@ dockers:
|
||||
- "--build-arg=VCS_REF={{.FullCommit}}"
|
||||
- "--build-arg=VCS_URL={{.GitURL}}"
|
||||
|
||||
- image_templates:
|
||||
- anchore/syft:{{.Tag}}-riscv64
|
||||
- ghcr.io/anchore/syft:{{.Tag}}-riscv64
|
||||
goarch: riscv64
|
||||
dockerfile: Dockerfile
|
||||
use: buildx
|
||||
build_flag_templates:
|
||||
- "--platform=linux/riscv64"
|
||||
- "--build-arg=DEBIAN_VERSION=13"
|
||||
- "--build-arg=BUILD_DATE={{.Date}}"
|
||||
- "--build-arg=BUILD_VERSION={{.Version}}"
|
||||
- "--build-arg=VCS_REF={{.FullCommit}}"
|
||||
- "--build-arg=VCS_URL={{.GitURL}}"
|
||||
|
||||
- image_templates:
|
||||
- anchore/syft:{{.Tag}}-s390x
|
||||
- ghcr.io/anchore/syft:{{.Tag}}-s390x
|
||||
@@ -167,6 +181,20 @@ dockers:
|
||||
- "--build-arg=VCS_REF={{.FullCommit}}"
|
||||
- "--build-arg=VCS_URL={{.GitURL}}"
|
||||
|
||||
- image_templates:
|
||||
- anchore/syft:{{.Tag}}-nonroot-riscv64
|
||||
- ghcr.io/anchore/syft:{{.Tag}}-nonroot-riscv64
|
||||
goarch: riscv64
|
||||
dockerfile: Dockerfile.nonroot
|
||||
use: buildx
|
||||
build_flag_templates:
|
||||
- "--platform=linux/riscv64"
|
||||
- "--build-arg=DEBIAN_VERSION=13"
|
||||
- "--build-arg=BUILD_DATE={{.Date}}"
|
||||
- "--build-arg=BUILD_VERSION={{.Version}}"
|
||||
- "--build-arg=VCS_REF={{.FullCommit}}"
|
||||
- "--build-arg=VCS_URL={{.GitURL}}"
|
||||
|
||||
- image_templates:
|
||||
- anchore/syft:{{.Tag}}-nonroot-s390x
|
||||
- ghcr.io/anchore/syft:{{.Tag}}-nonroot-s390x
|
||||
@@ -220,6 +248,20 @@ dockers:
|
||||
- "--build-arg=VCS_REF={{.FullCommit}}"
|
||||
- "--build-arg=VCS_URL={{.GitURL}}"
|
||||
|
||||
- image_templates:
|
||||
- anchore/syft:{{.Tag}}-debug-riscv64
|
||||
- ghcr.io/anchore/syft:{{.Tag}}-debug-riscv64
|
||||
goarch: riscv64
|
||||
dockerfile: Dockerfile.debug
|
||||
use: buildx
|
||||
build_flag_templates:
|
||||
- "--platform=linux/riscv64"
|
||||
- "--build-arg=DEBIAN_VERSION=13"
|
||||
- "--build-arg=BUILD_DATE={{.Date}}"
|
||||
- "--build-arg=BUILD_VERSION={{.Version}}"
|
||||
- "--build-arg=VCS_REF={{.FullCommit}}"
|
||||
- "--build-arg=VCS_URL={{.GitURL}}"
|
||||
|
||||
- image_templates:
|
||||
- anchore/syft:{{.Tag}}-debug-s390x
|
||||
- ghcr.io/anchore/syft:{{.Tag}}-debug-s390x
|
||||
@@ -239,6 +281,7 @@ docker_manifests:
|
||||
- anchore/syft:{{.Tag}}-amd64
|
||||
- anchore/syft:{{.Tag}}-arm64v8
|
||||
- anchore/syft:{{.Tag}}-ppc64le
|
||||
- anchore/syft:{{.Tag}}-riscv64
|
||||
- anchore/syft:{{.Tag}}-s390x
|
||||
|
||||
- name_template: ghcr.io/anchore/syft:latest
|
||||
@@ -246,6 +289,7 @@ docker_manifests:
|
||||
- ghcr.io/anchore/syft:{{.Tag}}-amd64
|
||||
- ghcr.io/anchore/syft:{{.Tag}}-arm64v8
|
||||
- ghcr.io/anchore/syft:{{.Tag}}-ppc64le
|
||||
- ghcr.io/anchore/syft:{{.Tag}}-riscv64
|
||||
- ghcr.io/anchore/syft:{{.Tag}}-s390x
|
||||
|
||||
- name_template: anchore/syft:{{.Tag}}
|
||||
@@ -253,6 +297,7 @@ docker_manifests:
|
||||
- anchore/syft:{{.Tag}}-amd64
|
||||
- anchore/syft:{{.Tag}}-arm64v8
|
||||
- anchore/syft:{{.Tag}}-ppc64le
|
||||
- anchore/syft:{{.Tag}}-riscv64
|
||||
- anchore/syft:{{.Tag}}-s390x
|
||||
|
||||
- name_template: ghcr.io/anchore/syft:{{.Tag}}
|
||||
@@ -260,6 +305,7 @@ docker_manifests:
|
||||
- ghcr.io/anchore/syft:{{.Tag}}-amd64
|
||||
- ghcr.io/anchore/syft:{{.Tag}}-arm64v8
|
||||
- ghcr.io/anchore/syft:{{.Tag}}-ppc64le
|
||||
- ghcr.io/anchore/syft:{{.Tag}}-riscv64
|
||||
- ghcr.io/anchore/syft:{{.Tag}}-s390x
|
||||
|
||||
# nonroot images...
|
||||
@@ -268,6 +314,7 @@ docker_manifests:
|
||||
- anchore/syft:{{.Tag}}-nonroot-amd64
|
||||
- anchore/syft:{{.Tag}}-nonroot-arm64v8
|
||||
- anchore/syft:{{.Tag}}-nonroot-ppc64le
|
||||
- anchore/syft:{{.Tag}}-nonroot-riscv64
|
||||
- anchore/syft:{{.Tag}}-nonroot-s390x
|
||||
|
||||
- name_template: ghcr.io/anchore/syft:nonroot
|
||||
@@ -275,6 +322,7 @@ docker_manifests:
|
||||
- ghcr.io/anchore/syft:{{.Tag}}-nonroot-amd64
|
||||
- ghcr.io/anchore/syft:{{.Tag}}-nonroot-arm64v8
|
||||
- ghcr.io/anchore/syft:{{.Tag}}-nonroot-ppc64le
|
||||
- ghcr.io/anchore/syft:{{.Tag}}-nonroot-riscv64
|
||||
- ghcr.io/anchore/syft:{{.Tag}}-nonroot-s390x
|
||||
|
||||
- name_template: anchore/syft:{{.Tag}}-nonroot
|
||||
@@ -282,6 +330,7 @@ docker_manifests:
|
||||
- anchore/syft:{{.Tag}}-nonroot-amd64
|
||||
- anchore/syft:{{.Tag}}-nonroot-arm64v8
|
||||
- anchore/syft:{{.Tag}}-nonroot-ppc64le
|
||||
- anchore/syft:{{.Tag}}-nonroot-riscv64
|
||||
- anchore/syft:{{.Tag}}-nonroot-s390x
|
||||
|
||||
- name_template: ghcr.io/anchore/syft:{{.Tag}}-nonroot
|
||||
@@ -289,6 +338,7 @@ docker_manifests:
|
||||
- ghcr.io/anchore/syft:{{.Tag}}-nonroot-amd64
|
||||
- ghcr.io/anchore/syft:{{.Tag}}-nonroot-arm64v8
|
||||
- ghcr.io/anchore/syft:{{.Tag}}-nonroot-ppc64le
|
||||
- ghcr.io/anchore/syft:{{.Tag}}-nonroot-riscv64
|
||||
- ghcr.io/anchore/syft:{{.Tag}}-nonroot-s390x
|
||||
|
||||
# debug images...
|
||||
@@ -297,6 +347,7 @@ docker_manifests:
|
||||
- anchore/syft:{{.Tag}}-debug-amd64
|
||||
- anchore/syft:{{.Tag}}-debug-arm64v8
|
||||
- anchore/syft:{{.Tag}}-debug-ppc64le
|
||||
- anchore/syft:{{.Tag}}-debug-riscv64
|
||||
- anchore/syft:{{.Tag}}-debug-s390x
|
||||
|
||||
- name_template: ghcr.io/anchore/syft:debug
|
||||
@@ -304,6 +355,7 @@ docker_manifests:
|
||||
- ghcr.io/anchore/syft:{{.Tag}}-debug-amd64
|
||||
- ghcr.io/anchore/syft:{{.Tag}}-debug-arm64v8
|
||||
- ghcr.io/anchore/syft:{{.Tag}}-debug-ppc64le
|
||||
- ghcr.io/anchore/syft:{{.Tag}}-debug-riscv64
|
||||
- ghcr.io/anchore/syft:{{.Tag}}-debug-s390x
|
||||
|
||||
- name_template: anchore/syft:{{.Tag}}-debug
|
||||
@@ -311,6 +363,7 @@ docker_manifests:
|
||||
- anchore/syft:{{.Tag}}-debug-amd64
|
||||
- anchore/syft:{{.Tag}}-debug-arm64v8
|
||||
- anchore/syft:{{.Tag}}-debug-ppc64le
|
||||
- anchore/syft:{{.Tag}}-debug-riscv64
|
||||
- anchore/syft:{{.Tag}}-debug-s390x
|
||||
|
||||
- name_template: ghcr.io/anchore/syft:{{.Tag}}-debug
|
||||
@@ -318,6 +371,7 @@ docker_manifests:
|
||||
- ghcr.io/anchore/syft:{{.Tag}}-debug-amd64
|
||||
- ghcr.io/anchore/syft:{{.Tag}}-debug-arm64v8
|
||||
- ghcr.io/anchore/syft:{{.Tag}}-debug-ppc64le
|
||||
- ghcr.io/anchore/syft:{{.Tag}}-debug-riscv64
|
||||
- ghcr.io/anchore/syft:{{.Tag}}-debug-s390x
|
||||
|
||||
sboms:
|
||||
|
||||
+2
-1
@@ -1,4 +1,5 @@
|
||||
FROM gcr.io/distroless/static-debian12:latest AS build
|
||||
ARG DEBIAN_VERSION=12
|
||||
FROM gcr.io/distroless/static-debian${DEBIAN_VERSION}:latest AS build
|
||||
|
||||
FROM scratch
|
||||
# needed for version check HTTPS request
|
||||
|
||||
+2
-1
@@ -1,4 +1,5 @@
|
||||
FROM gcr.io/distroless/static-debian12:debug-nonroot
|
||||
ARG DEBIAN_VERSION=12
|
||||
FROM gcr.io/distroless/static-debian${DEBIAN_VERSION}:debug-nonroot
|
||||
|
||||
# create the /tmp dir, which is needed for image content cache
|
||||
WORKDIR /tmp
|
||||
|
||||
+2
-1
@@ -1,4 +1,5 @@
|
||||
FROM gcr.io/distroless/static-debian12:nonroot
|
||||
ARG DEBIAN_VERSION=12
|
||||
FROM gcr.io/distroless/static-debian${DEBIAN_VERSION}:nonroot
|
||||
|
||||
# create the /tmp dir, which is needed for image content cache
|
||||
WORKDIR /tmp
|
||||
|
||||
@@ -9,6 +9,7 @@ require (
|
||||
github.com/Masterminds/sprig/v3 v3.3.0
|
||||
github.com/OneOfOne/xxhash v1.2.8
|
||||
github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d
|
||||
github.com/acobaugh/osrelease v0.1.0
|
||||
github.com/adrg/xdg v0.5.3
|
||||
github.com/anchore/bubbly v0.2.0
|
||||
github.com/anchore/clio v0.1.0
|
||||
@@ -22,10 +23,12 @@ require (
|
||||
github.com/anchore/go-version v1.2.2-0.20200701162849-18adb9c92b9b
|
||||
github.com/anchore/packageurl-go v0.2.0
|
||||
github.com/anchore/stereoscope v0.1.23
|
||||
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.10.0
|
||||
github.com/cespare/xxhash/v2 v2.3.0
|
||||
github.com/charmbracelet/bubbles v1.0.0
|
||||
github.com/charmbracelet/bubbletea v1.3.10
|
||||
github.com/charmbracelet/lipgloss v1.1.0
|
||||
@@ -38,16 +41,18 @@ require (
|
||||
github.com/facebookincubator/nvdtools v0.1.5
|
||||
github.com/github/go-spdx/v2 v2.4.0
|
||||
github.com/gkampitakis/go-snaps v0.5.21
|
||||
github.com/go-git/go-billy/v5 v5.8.0
|
||||
github.com/go-git/go-git/v5 v5.18.0
|
||||
github.com/go-git/go-billy/v5 v5.9.0
|
||||
github.com/go-git/go-git/v5 v5.19.0
|
||||
github.com/go-test/deep v1.1.1
|
||||
github.com/go-viper/mapstructure/v2 v2.5.0
|
||||
github.com/goccy/go-yaml v1.19.2
|
||||
github.com/gohugoio/hashstructure v0.6.0
|
||||
github.com/google/go-cmp v0.7.0
|
||||
github.com/google/go-containerregistry v0.21.5
|
||||
github.com/google/licensecheck v0.3.1
|
||||
github.com/google/uuid v1.6.0
|
||||
github.com/gookit/color v1.6.0
|
||||
github.com/gpustack/gguf-parser-go v0.24.0
|
||||
github.com/hashicorp/go-cleanhttp v0.5.2
|
||||
github.com/hashicorp/go-getter v1.8.6
|
||||
github.com/hashicorp/go-multierror v1.1.1
|
||||
@@ -57,6 +62,7 @@ require (
|
||||
github.com/jedib0t/go-pretty/v6 v6.7.8
|
||||
github.com/jinzhu/copier v0.4.0
|
||||
github.com/kastenhq/goversion v0.0.0-20230811215019-93b2f8823953
|
||||
github.com/klauspost/compress v1.18.5
|
||||
github.com/magiconair/properties v1.8.10
|
||||
github.com/mholt/archives v0.1.5
|
||||
github.com/moby/sys/mountinfo v0.7.2
|
||||
@@ -77,209 +83,52 @@ require (
|
||||
github.com/spf13/afero v1.15.0
|
||||
github.com/spf13/cobra v1.10.2
|
||||
github.com/stretchr/testify v1.11.1
|
||||
github.com/ulikunitz/xz v0.5.15
|
||||
github.com/vbatts/go-mtree v0.7.0
|
||||
github.com/vifraa/gopom v1.0.0
|
||||
github.com/wagoodman/go-partybus v0.0.0-20230516145632-8ccac152c651
|
||||
github.com/wagoodman/go-progress v0.0.0-20260303201901-10176f79b2c0
|
||||
github.com/wk8/go-ordered-map/v2 v2.1.8
|
||||
github.com/xeipuuv/gojsonschema v1.2.0
|
||||
github.com/zyedidia/generic v1.2.2-0.20230320175451-4410d2372cb1
|
||||
go.uber.org/goleak v1.3.0
|
||||
go.yaml.in/yaml/v3 v3.0.4
|
||||
golang.org/x/exp v0.0.0-20251023183803-a4bb9ffd2546
|
||||
golang.org/x/exp v0.0.0-20260410095643-746e56fc9e2f
|
||||
golang.org/x/mod v0.35.0
|
||||
golang.org/x/net v0.53.0
|
||||
golang.org/x/time v0.15.0
|
||||
golang.org/x/tools v0.44.0
|
||||
gopkg.in/yaml.v3 v3.0.1
|
||||
modernc.org/sqlite v1.46.2
|
||||
)
|
||||
|
||||
require (
|
||||
cel.dev/expr v0.25.1 // indirect
|
||||
cloud.google.com/go v0.123.0 // indirect
|
||||
cloud.google.com/go/auth v0.18.2 // indirect
|
||||
cloud.google.com/go/auth/oauth2adapt v0.2.8 // indirect
|
||||
cloud.google.com/go/compute/metadata v0.9.0 // indirect
|
||||
cloud.google.com/go/iam v1.5.3 // indirect
|
||||
cloud.google.com/go/monitoring v1.24.3 // indirect
|
||||
cloud.google.com/go/storage v1.61.3 // indirect
|
||||
cyphar.com/go-pathrs v0.2.1 // indirect
|
||||
dario.cat/mergo v1.0.2 // indirect
|
||||
github.com/DataDog/zstd v1.5.5 // indirect
|
||||
github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.30.0 // indirect
|
||||
github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.55.0 // indirect
|
||||
github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.55.0 // indirect
|
||||
github.com/Masterminds/goutils v1.1.1 // indirect
|
||||
github.com/Microsoft/go-winio v0.6.2 // indirect
|
||||
github.com/Microsoft/hcsshim v0.14.0-rc.1 // indirect
|
||||
github.com/ProtonMail/go-crypto v1.4.0 // indirect
|
||||
github.com/STARRY-S/zip v0.2.3 // indirect
|
||||
github.com/agext/levenshtein v1.2.1 // indirect; indirectt
|
||||
github.com/agext/levenshtein v1.2.1 // indirect
|
||||
github.com/anchore/go-lzo v0.1.0 // indirect
|
||||
github.com/anchore/go-struct-converter v0.1.0 // indirect
|
||||
github.com/andybalholm/brotli v1.2.0 // indirect
|
||||
github.com/apparentlymart/go-textseg/v15 v15.0.0 // indirect
|
||||
github.com/aquasecurity/go-version v0.0.1 // indirect
|
||||
github.com/atotto/clipboard v0.1.4 // indirect
|
||||
github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect
|
||||
github.com/becheran/wildmatch-go v1.0.0 // indirect
|
||||
github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d // indirect
|
||||
github.com/bodgit/plumbing v1.3.0 // indirect
|
||||
github.com/bodgit/sevenzip v1.6.1 // indirect
|
||||
github.com/bodgit/windows v1.0.1 // indirect
|
||||
github.com/charmbracelet/colorprofile v0.4.1 // indirect
|
||||
github.com/charmbracelet/harmonica v0.2.0 // indirect
|
||||
github.com/charmbracelet/x/ansi v0.11.6 // indirect
|
||||
github.com/charmbracelet/x/cellbuf v0.0.15 // indirect
|
||||
github.com/charmbracelet/x/term v0.2.2 // indirect
|
||||
github.com/cloudflare/circl v1.6.3 // indirect
|
||||
github.com/containerd/containerd/api v1.10.0 // indirect
|
||||
github.com/containerd/continuity v0.4.5 // indirect
|
||||
github.com/containerd/errdefs v1.0.0 // indirect
|
||||
github.com/containerd/errdefs/pkg v0.3.0 // indirect
|
||||
github.com/containerd/fifo v1.1.0 // indirect
|
||||
github.com/containerd/log v0.1.0 // indirect
|
||||
github.com/containerd/platforms v1.0.0-rc.4 // indirect
|
||||
github.com/containerd/stargz-snapshotter/estargz v0.18.2 // indirect
|
||||
github.com/containerd/ttrpc v1.2.7 // indirect
|
||||
github.com/containerd/typeurl/v2 v2.2.3 // indirect
|
||||
github.com/cyphar/filepath-securejoin v0.6.0 // indirect
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
|
||||
github.com/docker/cli v29.4.0+incompatible // indirect
|
||||
github.com/docker/docker-credential-helpers v0.9.5 // indirect
|
||||
github.com/docker/go-connections v0.6.0 // indirect
|
||||
github.com/docker/go-units v0.5.0 // indirect
|
||||
github.com/dsnet/compress v0.0.2-0.20230904184137-39efe44ab707 // indirect
|
||||
github.com/emirpasic/gods v1.18.1 // indirect
|
||||
github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f // indirect
|
||||
github.com/fatih/color v1.18.0 // indirect
|
||||
github.com/felixge/fgprof v0.9.5 // indirect
|
||||
github.com/felixge/httpsnoop v1.0.4 // indirect
|
||||
github.com/fsnotify/fsnotify v1.9.0 // indirect
|
||||
github.com/gabriel-vasile/mimetype v1.4.13 // indirect
|
||||
github.com/gkampitakis/ciinfo v0.3.2 // indirect
|
||||
github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect
|
||||
github.com/go-logr/logr v1.4.3 // indirect
|
||||
github.com/go-logr/stdr v1.2.2 // indirect
|
||||
github.com/go-restruct/restruct v1.2.0-alpha // indirect
|
||||
github.com/goccy/go-yaml v1.19.2
|
||||
github.com/gogo/protobuf v1.3.2 // indirect
|
||||
github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 // indirect
|
||||
github.com/google/pprof v0.0.0-20250317173921-a4b03ec1a45e // indirect
|
||||
github.com/google/s2a-go v0.1.9 // indirect
|
||||
github.com/googleapis/enterprise-certificate-proxy v0.3.14 // indirect
|
||||
github.com/googleapis/gax-go/v2 v2.17.0 // indirect
|
||||
github.com/hashicorp/errwrap v1.1.0 // indirect
|
||||
github.com/hashicorp/go-version v1.8.0 // indirect
|
||||
github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect
|
||||
github.com/huandu/xstrings v1.5.0 // indirect
|
||||
github.com/inconshreveable/mousetrap v1.1.0 // indirect
|
||||
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect
|
||||
github.com/kevinburke/ssh_config v1.2.0 // indirect
|
||||
github.com/klauspost/compress v1.18.5 // indirect
|
||||
github.com/klauspost/pgzip v1.2.6 // indirect
|
||||
github.com/kr/pretty v0.3.1 // indirect
|
||||
github.com/kr/text v0.2.0 // indirect
|
||||
github.com/lucasb-eyer/go-colorful v1.3.0 // indirect
|
||||
github.com/maruel/natural v1.1.1 // indirect
|
||||
github.com/mattn/go-colorable v0.1.14 // indirect
|
||||
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||
github.com/mattn/go-localereader v0.0.2-0.20220822084749-2491eb6c1c75 // indirect
|
||||
github.com/mattn/go-runewidth v0.0.19 // indirect
|
||||
github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d // indirect
|
||||
github.com/mikelolasagasti/xz v1.0.1 // indirect
|
||||
github.com/minio/minlz v1.0.1 // indirect
|
||||
github.com/mitchellh/copystructure v1.2.0 // indirect
|
||||
github.com/mitchellh/go-homedir v1.1.0 // indirect
|
||||
github.com/mitchellh/go-wordwrap v1.0.1 // indirect
|
||||
github.com/mitchellh/reflectwalk v1.0.2 // indirect
|
||||
github.com/moby/docker-image-spec v1.3.1 // indirect
|
||||
github.com/moby/locker v1.0.1 // indirect
|
||||
github.com/moby/sys/sequential v0.6.0 // indirect
|
||||
github.com/moby/sys/signal v0.7.1 // indirect
|
||||
github.com/moby/sys/user v0.4.0 // indirect
|
||||
github.com/moby/sys/userns v0.1.0 // indirect
|
||||
github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 // indirect
|
||||
github.com/muesli/cancelreader v0.2.2 // indirect
|
||||
github.com/muesli/termenv v0.16.0 // indirect
|
||||
github.com/ncruces/go-strftime v1.0.0 // indirect
|
||||
github.com/opencontainers/image-spec v1.1.1 // indirect
|
||||
github.com/opencontainers/runtime-spec v1.3.0 // indirect
|
||||
github.com/opencontainers/selinux v1.13.1 // indirect
|
||||
github.com/pborman/indent v1.2.1 // indirect
|
||||
github.com/pelletier/go-toml/v2 v2.2.4 // indirect
|
||||
github.com/pierrec/lz4/v4 v4.1.22 // indirect
|
||||
github.com/pjbgf/sha1cd v0.3.2 // indirect
|
||||
github.com/pkg/errors v0.9.1 // indirect
|
||||
github.com/pkg/profile v1.7.0 // indirect
|
||||
github.com/pkg/xattr v0.4.9 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
|
||||
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect
|
||||
github.com/rivo/uniseg v0.4.7 // indirect
|
||||
github.com/rogpeppe/go-internal v1.14.1 // indirect
|
||||
github.com/sagikazarmark/locafero v0.11.0 // indirect
|
||||
github.com/sahilm/fuzzy v0.1.1 // indirect
|
||||
github.com/shopspring/decimal v1.4.0 // indirect
|
||||
github.com/sirupsen/logrus v1.9.4 // indirect
|
||||
github.com/skeema/knownhosts v1.3.1 // indirect
|
||||
github.com/sorairolake/lzip-go v0.3.8 // indirect
|
||||
github.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8 // indirect
|
||||
github.com/spf13/cast v1.10.0 // indirect
|
||||
github.com/spf13/pflag v1.0.10 // indirect
|
||||
github.com/spf13/viper v1.21.0 // indirect
|
||||
github.com/stretchr/objx v0.5.2 // indirect
|
||||
github.com/subosito/gotenv v1.6.0 // indirect
|
||||
github.com/sylabs/sif/v2 v2.24.0 // indirect
|
||||
github.com/sylabs/squashfs v1.0.6 // indirect
|
||||
github.com/therootcompany/xz v1.0.1 // indirect
|
||||
github.com/tidwall/gjson v1.18.0 // indirect
|
||||
github.com/tidwall/match v1.1.1 // indirect
|
||||
github.com/tidwall/pretty v1.2.1 // indirect
|
||||
github.com/tidwall/sjson v1.2.5 // indirect
|
||||
github.com/ulikunitz/xz v0.5.15
|
||||
github.com/vbatts/tar-split v0.12.2 // indirect
|
||||
github.com/xanzy/ssh-agent v0.3.3 // indirect
|
||||
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect
|
||||
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect
|
||||
github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8 // indirect
|
||||
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect
|
||||
github.com/zclconf/go-cty v1.16.3 // indirect
|
||||
go.opencensus.io v0.24.0 // indirect
|
||||
go.opentelemetry.io/auto/sdk v1.2.1 // indirect
|
||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.63.0 // indirect
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0 // indirect
|
||||
go.opentelemetry.io/otel v1.43.0 // indirect
|
||||
go.opentelemetry.io/otel/metric v1.43.0 // indirect
|
||||
go.opentelemetry.io/otel/trace v1.43.0 // indirect
|
||||
go4.org v0.0.0-20230225012048-214862532bf5 // indirect
|
||||
golang.org/x/crypto v0.50.0 // indirect
|
||||
golang.org/x/oauth2 v0.36.0 // indirect
|
||||
golang.org/x/sync v0.20.0 // indirect
|
||||
golang.org/x/sys v0.43.0 // indirect
|
||||
golang.org/x/term v0.42.0 // indirect
|
||||
golang.org/x/text v0.36.0 // indirect
|
||||
golang.org/x/time v0.15.0
|
||||
golang.org/x/tools v0.44.0
|
||||
golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 // indirect
|
||||
google.golang.org/api v0.271.0 // indirect
|
||||
google.golang.org/genproto v0.0.0-20260128011058-8636f8732409 // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20260203192932-546029d2fa20 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20260226221140-a57be14db171 // indirect
|
||||
google.golang.org/grpc v1.79.3 // indirect
|
||||
google.golang.org/protobuf v1.36.11 // indirect
|
||||
gopkg.in/warnings.v0 v0.1.2 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1
|
||||
modernc.org/libc v1.70.0 // indirect
|
||||
modernc.org/mathutil v1.7.1 // indirect
|
||||
modernc.org/memory v1.11.0 // indirect
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/acobaugh/osrelease v0.1.0
|
||||
github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be
|
||||
github.com/cespare/xxhash/v2 v2.3.0
|
||||
github.com/gpustack/gguf-parser-go v0.24.0
|
||||
github.com/wk8/go-ordered-map/v2 v2.1.8
|
||||
)
|
||||
|
||||
require (
|
||||
cel.dev/expr v0.25.1 // indirect
|
||||
cloud.google.com/go/monitoring v1.24.3 // indirect
|
||||
cyphar.com/go-pathrs v0.2.1 // indirect
|
||||
github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.30.0 // indirect
|
||||
github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.55.0 // indirect
|
||||
github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.55.0 // indirect
|
||||
github.com/aws/aws-sdk-go-v2 v1.41.5 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.7.8 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/config v1.32.12 // indirect
|
||||
@@ -299,36 +148,182 @@ require (
|
||||
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.17 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/sts v1.41.9 // indirect
|
||||
github.com/aws/smithy-go v1.24.2 // indirect
|
||||
github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect
|
||||
github.com/bahlo/generic-list-go v0.2.0 // indirect
|
||||
github.com/becheran/wildmatch-go v1.0.0 // indirect
|
||||
github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d // indirect
|
||||
github.com/bodgit/plumbing v1.3.0 // indirect
|
||||
github.com/bodgit/sevenzip v1.6.1 // indirect
|
||||
github.com/bodgit/windows v1.0.1 // indirect
|
||||
github.com/buger/jsonparser v1.1.2 // indirect
|
||||
github.com/charmbracelet/colorprofile v0.4.1 // indirect
|
||||
github.com/charmbracelet/harmonica v0.2.0 // indirect
|
||||
github.com/charmbracelet/x/ansi v0.11.6 // indirect
|
||||
github.com/charmbracelet/x/cellbuf v0.0.15 // indirect
|
||||
github.com/charmbracelet/x/term v0.2.2 // indirect
|
||||
github.com/clipperhouse/displaywidth v0.10.0 // indirect
|
||||
github.com/clipperhouse/uax29/v2 v2.6.0 // indirect
|
||||
github.com/cloudflare/circl v1.6.3 // indirect
|
||||
github.com/cncf/xds/go v0.0.0-20251210132809-ee656c7534f5 // indirect
|
||||
github.com/containerd/cgroups/v3 v3.1.2 // indirect
|
||||
github.com/containerd/containerd/api v1.10.0 // indirect
|
||||
github.com/containerd/containerd/v2 v2.2.2 // indirect
|
||||
github.com/containerd/continuity v0.4.5 // indirect
|
||||
github.com/containerd/errdefs v1.0.0 // indirect
|
||||
github.com/containerd/errdefs/pkg v0.3.0 // indirect
|
||||
github.com/containerd/fifo v1.1.0 // indirect
|
||||
github.com/containerd/log v0.1.0 // indirect
|
||||
github.com/containerd/platforms v1.0.0-rc.4 // indirect
|
||||
github.com/containerd/plugin v1.0.0 // indirect
|
||||
github.com/containerd/stargz-snapshotter/estargz v0.18.2 // indirect
|
||||
github.com/containerd/ttrpc v1.2.7 // indirect
|
||||
github.com/containerd/typeurl/v2 v2.2.3 // indirect
|
||||
github.com/cyphar/filepath-securejoin v0.6.1 // indirect
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
|
||||
github.com/docker/cli v29.4.0+incompatible // indirect
|
||||
github.com/docker/docker-credential-helpers v0.9.5 // indirect
|
||||
github.com/docker/go-connections v0.6.0 // indirect
|
||||
github.com/docker/go-units v0.5.0 // indirect
|
||||
github.com/dsnet/compress v0.0.2-0.20230904184137-39efe44ab707 // indirect
|
||||
github.com/emirpasic/gods v1.18.1 // indirect
|
||||
github.com/envoyproxy/go-control-plane/envoy v1.36.0 // indirect
|
||||
github.com/envoyproxy/protoc-gen-validate v1.3.0 // indirect
|
||||
github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f // indirect
|
||||
github.com/fatih/color v1.18.0 // indirect
|
||||
github.com/felixge/fgprof v0.9.5 // indirect
|
||||
github.com/felixge/httpsnoop v1.0.4 // indirect
|
||||
github.com/fsnotify/fsnotify v1.9.0 // indirect
|
||||
github.com/gabriel-vasile/mimetype v1.4.13 // indirect
|
||||
github.com/gkampitakis/ciinfo v0.3.2 // indirect
|
||||
github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect
|
||||
github.com/go-jose/go-jose/v4 v4.1.4 // indirect
|
||||
github.com/go-logr/logr v1.4.3 // indirect
|
||||
github.com/go-logr/stdr v1.2.2 // indirect
|
||||
github.com/go-restruct/restruct v1.2.0-alpha // indirect
|
||||
github.com/gogo/protobuf v1.3.2 // indirect
|
||||
github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 // indirect
|
||||
github.com/google/pprof v0.0.0-20250317173921-a4b03ec1a45e // indirect
|
||||
github.com/google/s2a-go v0.1.9 // indirect
|
||||
github.com/googleapis/enterprise-certificate-proxy v0.3.14 // indirect
|
||||
github.com/googleapis/gax-go/v2 v2.17.0 // indirect
|
||||
github.com/hashicorp/aws-sdk-go-base/v2 v2.0.0-beta.72 // indirect
|
||||
github.com/hashicorp/errwrap v1.1.0 // indirect
|
||||
github.com/hashicorp/go-version v1.8.0 // indirect
|
||||
github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect
|
||||
github.com/henvic/httpretty v0.1.4 // indirect
|
||||
github.com/huandu/xstrings v1.5.0 // indirect
|
||||
github.com/inconshreveable/mousetrap v1.1.0 // indirect
|
||||
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect
|
||||
github.com/json-iterator/go v1.1.12 // indirect
|
||||
github.com/kevinburke/ssh_config v1.2.0 // indirect
|
||||
github.com/klauspost/cpuid/v2 v2.3.0 // indirect
|
||||
github.com/klauspost/pgzip v1.2.6 // indirect
|
||||
github.com/kr/pretty v0.3.1 // indirect
|
||||
github.com/kr/text v0.2.0 // indirect
|
||||
github.com/lucasb-eyer/go-colorful v1.3.0 // indirect
|
||||
github.com/mailru/easyjson v0.7.7 // indirect
|
||||
github.com/maruel/natural v1.1.1 // indirect
|
||||
github.com/mattn/go-colorable v0.1.14 // indirect
|
||||
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||
github.com/mattn/go-localereader v0.0.2-0.20220822084749-2491eb6c1c75 // indirect
|
||||
github.com/mattn/go-runewidth v0.0.19 // indirect
|
||||
github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d // indirect
|
||||
github.com/mikelolasagasti/xz v1.0.1 // indirect
|
||||
github.com/minio/minlz v1.0.1 // indirect
|
||||
github.com/mitchellh/copystructure v1.2.0 // indirect
|
||||
github.com/mitchellh/go-homedir v1.1.0 // indirect
|
||||
github.com/mitchellh/go-wordwrap v1.0.1 // indirect
|
||||
github.com/mitchellh/reflectwalk v1.0.2 // indirect
|
||||
github.com/moby/docker-image-spec v1.3.1 // indirect
|
||||
github.com/moby/locker v1.0.1 // indirect
|
||||
github.com/moby/moby/api v1.54.1 // indirect
|
||||
github.com/moby/moby/client v0.4.0 // indirect
|
||||
github.com/moby/sys/sequential v0.6.0 // indirect
|
||||
github.com/moby/sys/signal v0.7.1 // indirect
|
||||
github.com/moby/sys/user v0.4.0 // indirect
|
||||
github.com/moby/sys/userns v0.1.0 // indirect
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||
github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect
|
||||
github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 // indirect
|
||||
github.com/muesli/cancelreader v0.2.2 // indirect
|
||||
github.com/muesli/termenv v0.16.0 // indirect
|
||||
github.com/ncruces/go-strftime v1.0.0 // indirect
|
||||
github.com/nwaples/rardecode/v2 v2.2.0 // indirect
|
||||
github.com/olekukonko/cat v0.0.0-20250911104152-50322a0618f6 // indirect
|
||||
github.com/olekukonko/errors v1.2.0 // indirect
|
||||
github.com/olekukonko/ll v0.1.6 // indirect
|
||||
github.com/opencontainers/image-spec v1.1.1 // indirect
|
||||
github.com/opencontainers/runtime-spec v1.3.0 // indirect
|
||||
github.com/opencontainers/selinux v1.13.1 // indirect
|
||||
github.com/pborman/indent v1.2.1 // indirect
|
||||
github.com/pelletier/go-toml/v2 v2.2.4 // indirect
|
||||
github.com/pierrec/lz4/v4 v4.1.22 // indirect
|
||||
github.com/pjbgf/sha1cd v0.6.0 // indirect
|
||||
github.com/pkg/errors v0.9.1 // indirect
|
||||
github.com/pkg/profile v1.7.0 // indirect
|
||||
github.com/pkg/xattr v0.4.9 // indirect
|
||||
github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
|
||||
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect
|
||||
github.com/rivo/uniseg v0.4.7 // indirect
|
||||
github.com/rogpeppe/go-internal v1.14.1 // indirect
|
||||
github.com/sagikazarmark/locafero v0.11.0 // indirect
|
||||
github.com/sahilm/fuzzy v0.1.1 // indirect
|
||||
github.com/shopspring/decimal v1.4.0 // indirect
|
||||
github.com/sirupsen/logrus v1.9.4 // indirect
|
||||
github.com/skeema/knownhosts v1.3.1 // indirect
|
||||
github.com/smallnest/ringbuffer v0.0.0-20241116012123-461381446e3d // indirect
|
||||
github.com/sorairolake/lzip-go v0.3.8 // indirect
|
||||
github.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8 // indirect
|
||||
github.com/spf13/cast v1.10.0 // indirect
|
||||
github.com/spf13/pflag v1.0.10 // indirect
|
||||
github.com/spf13/viper v1.21.0 // indirect
|
||||
github.com/spiffe/go-spiffe/v2 v2.6.0 // indirect
|
||||
github.com/stretchr/objx v0.5.2 // indirect
|
||||
github.com/subosito/gotenv v1.6.0 // indirect
|
||||
github.com/sylabs/sif/v2 v2.24.0 // indirect
|
||||
github.com/sylabs/squashfs v1.0.6 // indirect
|
||||
github.com/therootcompany/xz v1.0.1 // indirect
|
||||
github.com/tidwall/gjson v1.18.0 // indirect
|
||||
github.com/tidwall/match v1.1.1 // indirect
|
||||
github.com/tidwall/pretty v1.2.1 // indirect
|
||||
github.com/tidwall/sjson v1.2.5 // indirect
|
||||
github.com/vbatts/tar-split v0.12.2 // indirect
|
||||
github.com/xanzy/ssh-agent v0.3.3 // indirect
|
||||
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect
|
||||
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect
|
||||
github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8 // indirect
|
||||
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect
|
||||
github.com/zclconf/go-cty v1.16.3 // indirect
|
||||
go.opencensus.io v0.24.0 // indirect
|
||||
go.opentelemetry.io/auto/sdk v1.2.1 // indirect
|
||||
go.opentelemetry.io/contrib/detectors/gcp v1.39.0 // indirect
|
||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.63.0 // indirect
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0 // indirect
|
||||
go.opentelemetry.io/otel v1.43.0 // indirect
|
||||
go.opentelemetry.io/otel/metric v1.43.0 // indirect
|
||||
go.opentelemetry.io/otel/sdk v1.43.0 // indirect
|
||||
go.opentelemetry.io/otel/sdk/metric v1.43.0 // indirect
|
||||
go.opentelemetry.io/otel/trace v1.43.0 // indirect
|
||||
go4.org v0.0.0-20230225012048-214862532bf5 // indirect
|
||||
golang.org/x/crypto v0.50.0 // indirect
|
||||
golang.org/x/oauth2 v0.36.0 // indirect
|
||||
golang.org/x/sync v0.20.0 // indirect
|
||||
golang.org/x/sys v0.43.0 // indirect
|
||||
golang.org/x/term v0.42.0 // indirect
|
||||
golang.org/x/text v0.36.0 // indirect
|
||||
golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 // indirect
|
||||
gonum.org/v1/gonum v0.16.0 // indirect
|
||||
google.golang.org/api v0.271.0 // indirect
|
||||
google.golang.org/genproto v0.0.0-20260128011058-8636f8732409 // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20260203192932-546029d2fa20 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20260226221140-a57be14db171 // indirect
|
||||
google.golang.org/grpc v1.79.3 // indirect
|
||||
google.golang.org/protobuf v1.36.11 // indirect
|
||||
gopkg.in/warnings.v0 v0.1.2 // indirect
|
||||
modernc.org/libc v1.70.0 // indirect
|
||||
modernc.org/mathutil v1.7.1 // indirect
|
||||
modernc.org/memory v1.11.0 // indirect
|
||||
)
|
||||
|
||||
retract (
|
||||
|
||||
@@ -325,8 +325,8 @@ github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSV
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.1/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=
|
||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
github.com/cyphar/filepath-securejoin v0.6.0 h1:BtGB77njd6SVO6VztOHfPxKitJvd/VPT+OFBFMOi1Is=
|
||||
github.com/cyphar/filepath-securejoin v0.6.0/go.mod h1:A8hd4EnAeyujCJRrICiOWqjS1AX0a9kM5XL+NwKoYSc=
|
||||
github.com/cyphar/filepath-securejoin v0.6.1 h1:5CeZ1jPXEiYt3+Z6zqprSAgSWiggmpVyciv8syjIpVE=
|
||||
github.com/cyphar/filepath-securejoin v0.6.1/go.mod h1:A8hd4EnAeyujCJRrICiOWqjS1AX0a9kM5XL+NwKoYSc=
|
||||
github.com/dave/jennifer v1.7.1 h1:B4jJJDHelWcDhlRQxWeo0Npa/pYKBLrirAQoTN45txo=
|
||||
github.com/dave/jennifer v1.7.1/go.mod h1:nXbxhEmQfOZhWml3D1cDK5M1FLnMSozpbFN/m3RmGZc=
|
||||
github.com/davecgh/go-spew v0.0.0-20161028175848-04cdfd42973b/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
@@ -420,12 +420,12 @@ github.com/gliderlabs/ssh v0.3.8 h1:a4YXD1V7xMF9g5nTkdfnja3Sxy1PVDCj1Zg4Wb8vY6c=
|
||||
github.com/gliderlabs/ssh v0.3.8/go.mod h1:xYoytBv1sV0aL3CavoDuJIQNURXkkfPA/wxQ1pL1fAU=
|
||||
github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 h1:+zs/tPmkDkHx3U66DAb0lQFJrpS6731Oaa12ikc+DiI=
|
||||
github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376/go.mod h1:an3vInlBmSxCcxctByoQdvwPiA7DTK7jaaFDBTtu0ic=
|
||||
github.com/go-git/go-billy/v5 v5.8.0 h1:I8hjc3LbBlXTtVuFNJuwYuMiHvQJDq1AT6u4DwDzZG0=
|
||||
github.com/go-git/go-billy/v5 v5.8.0/go.mod h1:RpvI/rw4Vr5QA+Z60c6d6LXH0rYJo0uD5SqfmrrheCY=
|
||||
github.com/go-git/go-billy/v5 v5.9.0 h1:jItGXszUDRtR/AlferWPTMN4j38BQ88XnXKbilmmBPA=
|
||||
github.com/go-git/go-billy/v5 v5.9.0/go.mod h1:jCnQMLj9eUgGU7+ludSTYoZL/GGmii14RxKFj7ROgHw=
|
||||
github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399 h1:eMje31YglSBqCdIqdhKBW8lokaMrL3uTkpGYlE2OOT4=
|
||||
github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399/go.mod h1:1OCfN199q1Jm3HZlxleg+Dw/mwps2Wbk9frAWm+4FII=
|
||||
github.com/go-git/go-git/v5 v5.18.0 h1:O831KI+0PR51hM2kep6T8k+w0/LIAD490gvqMCvL5hM=
|
||||
github.com/go-git/go-git/v5 v5.18.0/go.mod h1:pW/VmeqkanRFqR6AljLcs7EA7FbZaN5MQqO7oZADXpo=
|
||||
github.com/go-git/go-git/v5 v5.19.0 h1:+WkVUQZSy/F1Gb13udrMKjIM2PrzsNfDKFSfo5tkMtc=
|
||||
github.com/go-git/go-git/v5 v5.19.0/go.mod h1:Pb1v0c7/g8aGQJwx9Us09W85yGoyvSwuhEGMH7zjDKQ=
|
||||
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
|
||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
||||
@@ -649,6 +649,8 @@ github.com/klauspost/compress v1.4.1/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0
|
||||
github.com/klauspost/compress v1.18.5 h1:/h1gH5Ce+VWNLSWqPzOVn6XBO+vJbCNGvjoaGBFW2IE=
|
||||
github.com/klauspost/compress v1.18.5/go.mod h1:cwPg85FWrGar70rWktvGQj8/hthj3wpl0PGDogxkrSQ=
|
||||
github.com/klauspost/cpuid v1.2.0/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
|
||||
github.com/klauspost/cpuid/v2 v2.3.0 h1:S4CRMLnYUhGeDFDqkGriYKdfoFlDnMtqTiI/sFzhA9Y=
|
||||
github.com/klauspost/cpuid/v2 v2.3.0/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0=
|
||||
github.com/klauspost/pgzip v1.2.6 h1:8RXeL5crjEUFnR2/Sn6GJNWtSQ3Dk8pq4CL3jvdDyjU=
|
||||
github.com/klauspost/pgzip v1.2.6/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
@@ -790,8 +792,8 @@ github.com/pelletier/go-toml/v2 v2.2.4 h1:mye9XuhQ6gvn5h28+VilKrrPoQVanw5PMw/TB0
|
||||
github.com/pelletier/go-toml/v2 v2.2.4/go.mod h1:2gIqNv+qfxSVS7cM2xJQKtLSTLUE9V8t9Stt+h56mCY=
|
||||
github.com/pierrec/lz4/v4 v4.1.22 h1:cKFw6uJDK+/gfw5BcDL0JL5aBsAFdsIT18eRtLj7VIU=
|
||||
github.com/pierrec/lz4/v4 v4.1.22/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4=
|
||||
github.com/pjbgf/sha1cd v0.3.2 h1:a9wb0bp1oC2TGwStyn0Umc/IGKQnEgF0vVaZ8QF8eo4=
|
||||
github.com/pjbgf/sha1cd v0.3.2/go.mod h1:zQWigSxVmsHEZow5qaLtPYxpcKMMQpa09ixqBxuCS6A=
|
||||
github.com/pjbgf/sha1cd v0.6.0 h1:3WJ8Wz8gvDz29quX1OcEmkAlUg9diU4GxJHqs0/XiwU=
|
||||
github.com/pjbgf/sha1cd v0.6.0/go.mod h1:lhpGlyHLpQZoxMv8HcgXvZEhcGs0PG/vsZnEJ7H0iCM=
|
||||
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
|
||||
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
@@ -1048,8 +1050,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0
|
||||
golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
|
||||
golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
|
||||
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
|
||||
golang.org/x/exp v0.0.0-20251023183803-a4bb9ffd2546 h1:mgKeJMpvi0yx/sU5GsxQ7p6s2wtOnGAHZWCHUM4KGzY=
|
||||
golang.org/x/exp v0.0.0-20251023183803-a4bb9ffd2546/go.mod h1:j/pmGrbnkbPtQfxEe5D0VQhZC6qKbfKifgD0oM7sR70=
|
||||
golang.org/x/exp v0.0.0-20260410095643-746e56fc9e2f h1:W3F4c+6OLc6H2lb//N1q4WpJkhzJCK5J6kUi1NTVXfM=
|
||||
golang.org/x/exp v0.0.0-20260410095643-746e56fc9e2f/go.mod h1:J1xhfL/vlindoeF/aINzNzt2Bket5bjo9sdOYzOsU80=
|
||||
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
|
||||
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
|
||||
@@ -154,6 +154,7 @@ uname_arch_check() (
|
||||
mipsle) return 0 ;;
|
||||
mips64) return 0 ;;
|
||||
mips64le) return 0 ;;
|
||||
riscv64) return 0 ;;
|
||||
s390x) return 0 ;;
|
||||
amd64p32) return 0 ;;
|
||||
esac
|
||||
|
||||
@@ -96,6 +96,20 @@ var binaryClassifierOverrides = map[string][]binaryClassifierOverride{
|
||||
CPEs: singleCPE("cpe:2.3:a:oracle:jdk:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
|
||||
},
|
||||
},
|
||||
"openssl-binary": {
|
||||
{
|
||||
Class: "openssl-binary-aws-lc",
|
||||
Package: "aws-lc",
|
||||
PURL: mustPURL("pkg:generic/aws-lc@version"),
|
||||
CPEs: singleCPE("cpe:2.3:a:amazon:aws_libcrypto:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
|
||||
},
|
||||
{
|
||||
Class: "openssl-binary",
|
||||
Package: "openssl",
|
||||
PURL: mustPURL("pkg:generic/openssl@version"),
|
||||
CPEs: singleCPE("cpe:2.3:a:openssl:openssl:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
func mustPURL(purl string) string {
|
||||
|
||||
+13
-1
@@ -12,8 +12,20 @@ const perFileReadLimit = 2 * GB
|
||||
// protect against decompression bomb attacks.
|
||||
func safeCopy(writer io.Writer, reader io.Reader) error {
|
||||
numBytes, err := io.Copy(writer, io.LimitReader(reader, perFileReadLimit))
|
||||
if numBytes >= perFileReadLimit || errors.Is(err, io.EOF) {
|
||||
if numBytes >= perFileReadLimit {
|
||||
return fmt.Errorf("zip read limit hit (potential decompression bomb attack)")
|
||||
}
|
||||
// Propagate decompression / read errors up to the caller. io.Copy
|
||||
// on the happy path returns (n, nil); the only way err is non-nil
|
||||
// here is that the underlying reader surfaced a real failure
|
||||
// ("flate: corrupt input before offset X" on a mangled ZIP entry,
|
||||
// a network-backed reader erroring mid-stream, etc.). The previous
|
||||
// implementation dropped that error and the caller stored a
|
||||
// partial / empty buffer as a "successful" extract, which silently
|
||||
// downgraded Java cataloger output and caused SBOM scanners to
|
||||
// miss known CVEs (#4806).
|
||||
if err != nil && !errors.Is(err, io.EOF) {
|
||||
return fmt.Errorf("failed to read archive entry: %w", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -0,0 +1,64 @@
|
||||
package file
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"io"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
// errReader returns a deterministic non-EOF error after emitting some
|
||||
// bytes, mimicking what compress/flate does when it hits a corrupt
|
||||
// stream mid-entry.
|
||||
type errReader struct {
|
||||
data []byte
|
||||
err error
|
||||
off int
|
||||
}
|
||||
|
||||
func (r *errReader) Read(p []byte) (int, error) {
|
||||
if r.off >= len(r.data) {
|
||||
return 0, r.err
|
||||
}
|
||||
n := copy(p, r.data[r.off:])
|
||||
r.off += n
|
||||
return n, nil
|
||||
}
|
||||
|
||||
func TestSafeCopy(t *testing.T) {
|
||||
t.Run("clean copy returns nil", func(t *testing.T) {
|
||||
var buf bytes.Buffer
|
||||
if err := safeCopy(&buf, strings.NewReader("hello")); err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
if got := buf.String(); got != "hello" {
|
||||
t.Fatalf("unexpected buffer contents: %q", got)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("propagates decompression error", func(t *testing.T) {
|
||||
// #4806: safeCopy used to drop non-EOF errors, so the caller
|
||||
// would persist a partial buffer as a successful extract and
|
||||
// downstream catalogers silently read empty manifests.
|
||||
sentinel := errors.New("flate: corrupt input before offset 42")
|
||||
var buf bytes.Buffer
|
||||
err := safeCopy(&buf, &errReader{data: []byte("partial"), err: sentinel})
|
||||
if err == nil {
|
||||
t.Fatalf("expected error to be returned, got nil")
|
||||
}
|
||||
if !errors.Is(err, sentinel) {
|
||||
t.Fatalf("error does not wrap sentinel: %v", err)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("EOF is not treated as an error", func(t *testing.T) {
|
||||
// The old code had a dead io.EOF branch that labelled clean
|
||||
// reads as decompression bombs; keep the happy path clean.
|
||||
var buf bytes.Buffer
|
||||
err := safeCopy(&buf, io.LimitReader(strings.NewReader("abc"), 3))
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error on clean copy: %v", err)
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -5132,6 +5132,7 @@
|
||||
"armv9-a",
|
||||
"armv9-m",
|
||||
"s390x",
|
||||
"riscv64",
|
||||
"ppc64",
|
||||
"ppc64le",
|
||||
"other",
|
||||
|
||||
@@ -6471,6 +6471,7 @@ limitations under the License.
|
||||
<xs:enumeration value="armv9-a"/>
|
||||
<xs:enumeration value="armv9-m"/>
|
||||
<xs:enumeration value="s390x"/>
|
||||
<xs:enumeration value="riscv64"/>
|
||||
<xs:enumeration value="ppc64"/>
|
||||
<xs:enumeration value="ppc64le"/>
|
||||
<xs:enumeration value="other"/>
|
||||
|
||||
@@ -427,6 +427,17 @@ catalogers:
|
||||
criteria:
|
||||
- '**/openssl'
|
||||
packages:
|
||||
- class: openssl-binary
|
||||
name: ""
|
||||
purl: pkg:/
|
||||
cpes: []
|
||||
type: BinaryPkg
|
||||
- class: openssl-binary-aws-lc
|
||||
name: aws-lc
|
||||
purl: pkg:generic/aws-lc
|
||||
cpes:
|
||||
- cpe:2.3:a:amazon:aws_libcrypto:*:*:*:*:*:*:*:*
|
||||
type: BinaryPkg
|
||||
- class: openssl-binary
|
||||
name: openssl
|
||||
purl: pkg:generic/openssl
|
||||
@@ -684,6 +695,16 @@ catalogers:
|
||||
cpes:
|
||||
- cpe:2.3:a:mongodb:mongodb:*:*:*:*:*:*:*:*
|
||||
type: BinaryPkg
|
||||
- method: glob
|
||||
criteria:
|
||||
- '**/nginx-ingress-controller'
|
||||
packages:
|
||||
- class: ingress-nginx-binary
|
||||
name: nginx-ingress-controller
|
||||
purl: pkg:generic/nginx-ingress-controller
|
||||
cpes:
|
||||
- cpe:2.3:a:kubernetes:ingress-nginx:*:*:*:*:*:*:*:*
|
||||
type: BinaryPkg
|
||||
- method: glob
|
||||
criteria:
|
||||
- '**/java'
|
||||
|
||||
@@ -1485,6 +1485,17 @@ func Test_Cataloger_PositiveCases(t *testing.T) {
|
||||
Metadata: metadata("openssl-binary"),
|
||||
},
|
||||
},
|
||||
{
|
||||
logicalFixture: "aws-lc/1.69.0/linux-amd64",
|
||||
expected: pkg.Package{
|
||||
Name: "aws-lc",
|
||||
Version: "1.69.0",
|
||||
Type: "binary",
|
||||
PURL: "pkg:generic/aws-lc@1.69.0",
|
||||
Locations: locations("openssl"),
|
||||
Metadata: metadata("openssl-binary-aws-lc"),
|
||||
},
|
||||
},
|
||||
{
|
||||
logicalFixture: "openldap/2.6.10/linux-amd64",
|
||||
expected: pkg.Package{
|
||||
@@ -1754,6 +1765,25 @@ func Test_Cataloger_PositiveCases(t *testing.T) {
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
// release-candidate elixir image — pre-fix the matchers stripped the
|
||||
// "-rc.1" suffix from the elixir-library result and missed the
|
||||
// elixir-binary entirely (#4819).
|
||||
logicalFixture: "elixir/1.12.0-rc.1/linux-amd64",
|
||||
expected: pkg.Package{
|
||||
Name: "elixir",
|
||||
Version: "1.12.0-rc.1",
|
||||
Type: "binary",
|
||||
PURL: "pkg:generic/elixir@1.12.0-rc.1",
|
||||
Locations: locations("elixir", "lib/elixir/ebin/elixir.app"),
|
||||
Metadata: pkg.BinarySignature{
|
||||
Matches: []pkg.ClassifierMatch{
|
||||
match("elixir-binary", "elixir"),
|
||||
match("elixir-library", "lib/elixir/ebin/elixir.app"),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
logicalFixture: "istio_pilot-discovery/1.29.0-alpha.0/linux-amd64",
|
||||
expected: pkg.Package{
|
||||
@@ -2227,6 +2257,105 @@ func Test_Cataloger_PositiveCases(t *testing.T) {
|
||||
Metadata: metadata("envoy-binary"),
|
||||
},
|
||||
},
|
||||
{
|
||||
logicalFixture: "nginx-ingress-controller/1.15.1/linux-amd64",
|
||||
expected: pkg.Package{
|
||||
Name: "nginx-ingress-controller",
|
||||
Version: "1.15.1",
|
||||
Type: "binary",
|
||||
PURL: "pkg:generic/nginx-ingress-controller@1.15.1",
|
||||
Locations: locations("nginx-ingress-controller"),
|
||||
Metadata: metadata("ingress-nginx-binary"),
|
||||
},
|
||||
},
|
||||
{
|
||||
logicalFixture: "nginx-ingress-controller/1.11.8/linux-amd64",
|
||||
expected: pkg.Package{
|
||||
Name: "nginx-ingress-controller",
|
||||
Version: "1.11.8",
|
||||
Type: "binary",
|
||||
PURL: "pkg:generic/nginx-ingress-controller@1.11.8",
|
||||
Locations: locations("nginx-ingress-controller"),
|
||||
Metadata: metadata("ingress-nginx-binary"),
|
||||
},
|
||||
},
|
||||
{
|
||||
logicalFixture: "nginx-ingress-controller/1.9.6/linux-amd64",
|
||||
expected: pkg.Package{
|
||||
Name: "nginx-ingress-controller",
|
||||
Version: "1.9.6",
|
||||
Type: "binary",
|
||||
PURL: "pkg:generic/nginx-ingress-controller@1.9.6",
|
||||
Locations: locations("nginx-ingress-controller"),
|
||||
Metadata: metadata("ingress-nginx-binary"),
|
||||
},
|
||||
},
|
||||
{
|
||||
logicalFixture: "nginx-ingress-controller/1.7.1/linux-amd64",
|
||||
expected: pkg.Package{
|
||||
Name: "nginx-ingress-controller",
|
||||
Version: "1.7.1",
|
||||
Type: "binary",
|
||||
PURL: "pkg:generic/nginx-ingress-controller@1.7.1",
|
||||
Locations: locations("nginx-ingress-controller"),
|
||||
Metadata: metadata("ingress-nginx-binary"),
|
||||
},
|
||||
},
|
||||
{
|
||||
logicalFixture: "nginx-ingress-controller/1.12.0-beta.0/linux-amd64",
|
||||
expected: pkg.Package{
|
||||
Name: "nginx-ingress-controller",
|
||||
Version: "1.12.0-beta.0",
|
||||
Type: "binary",
|
||||
PURL: "pkg:generic/nginx-ingress-controller@1.12.0-beta.0",
|
||||
Locations: locations("nginx-ingress-controller"),
|
||||
Metadata: metadata("ingress-nginx-binary"),
|
||||
},
|
||||
},
|
||||
{
|
||||
logicalFixture: "nginx-ingress-controller/1.2.0-beta.1/linux-amd64",
|
||||
expected: pkg.Package{
|
||||
Name: "nginx-ingress-controller",
|
||||
Version: "1.2.0-beta.1",
|
||||
Type: "binary",
|
||||
PURL: "pkg:generic/nginx-ingress-controller@1.2.0-beta.1",
|
||||
Locations: locations("nginx-ingress-controller"),
|
||||
Metadata: metadata("ingress-nginx-binary"),
|
||||
},
|
||||
},
|
||||
{
|
||||
logicalFixture: "nginx-ingress-controller/1.0.0-alpha.2/linux-amd64",
|
||||
expected: pkg.Package{
|
||||
Name: "nginx-ingress-controller",
|
||||
Version: "1.0.0-alpha.2",
|
||||
Type: "binary",
|
||||
PURL: "pkg:generic/nginx-ingress-controller@1.0.0-alpha.2",
|
||||
Locations: locations("nginx-ingress-controller"),
|
||||
Metadata: metadata("ingress-nginx-binary"),
|
||||
},
|
||||
},
|
||||
{
|
||||
logicalFixture: "nginx-ingress-controller/0.34.0/linux-amd64",
|
||||
expected: pkg.Package{
|
||||
Name: "nginx-ingress-controller",
|
||||
Version: "0.34.0",
|
||||
Type: "binary",
|
||||
PURL: "pkg:generic/nginx-ingress-controller@0.34.0",
|
||||
Locations: locations("nginx-ingress-controller"),
|
||||
Metadata: metadata("ingress-nginx-binary"),
|
||||
},
|
||||
},
|
||||
{
|
||||
logicalFixture: "nginx-ingress-controller/0.33.0/linux-amd64",
|
||||
expected: pkg.Package{
|
||||
Name: "nginx-ingress-controller",
|
||||
Version: "0.33.0",
|
||||
Type: "binary",
|
||||
PURL: "pkg:generic/nginx-ingress-controller@0.33.0",
|
||||
Locations: locations("nginx-ingress-controller"),
|
||||
Metadata: metadata("ingress-nginx-binary"),
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
|
||||
@@ -106,13 +106,19 @@ func DefaultClassifiers() []binutils.Classifier {
|
||||
{
|
||||
Class: "redis-binary",
|
||||
FileGlob: "**/redis-server",
|
||||
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"
|
||||
m.FileContentsVersionMatcher(`[^\d](?P<version>[0-9]+\.[0-9]+\.[0-9]+)\w{12}-\d+`),
|
||||
// matches against older versions of redis (~v2), e.g. "Server started, Redis version 2.8.23"
|
||||
m.FileContentsVersionMatcher(`Redis version (?P<version>[0-9]+\.[0-9]+\.[0-9]+)`),
|
||||
EvidenceMatcher: binutils.MatchAll(
|
||||
// Negative Matchers to exclude valkey-server
|
||||
binutils.MatchNone(
|
||||
binutils.MatchPath("**/valkey-server"),
|
||||
),
|
||||
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"
|
||||
m.FileContentsVersionMatcher(`[^\d](?P<version>[0-9]+\.[0-9]+\.[0-9]+)\w{12}-\d+`),
|
||||
// matches against older versions of redis (~v2), e.g. "Server started, Redis version 2.8.23"
|
||||
m.FileContentsVersionMatcher(`Redis version (?P<version>[0-9]+\.[0-9]+\.[0-9]+)`),
|
||||
),
|
||||
),
|
||||
Package: "redis",
|
||||
PURL: mustPURL("pkg:generic/redis@version"),
|
||||
@@ -558,14 +564,29 @@ func DefaultClassifiers() []binutils.Classifier {
|
||||
{
|
||||
Class: "openssl-binary",
|
||||
FileGlob: "**/openssl",
|
||||
EvidenceMatcher: m.FileContentsVersionMatcher(
|
||||
// [NUL]OpenSSL 3.1.4'
|
||||
// [NUL]OpenSSL 1.1.1w'
|
||||
`\x00OpenSSL (?P<version>[0-9]+\.[0-9]+\.[0-9]+([a-z]+|-alpha[0-9]|-beta[0-9]|-rc[0-9])?)`,
|
||||
),
|
||||
Package: "openssl",
|
||||
PURL: mustPURL("pkg:generic/openssl@version"),
|
||||
CPEs: singleCPE("cpe:2.3:a:openssl:openssl:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
|
||||
EvidenceMatcher: binutils.BranchingEvidenceMatcher([]binutils.Classifier{
|
||||
{
|
||||
Class: "openssl-binary-aws-lc",
|
||||
EvidenceMatcher: m.FileContentsVersionMatcher(
|
||||
// [NUL]OpenSSL 1.1.1 (compatible; AWS-LC 1.69.0)[NUL]
|
||||
`AWS-LC (?P<version>[0-9]+\.[0-9]+\.[0-9]+)\)\x00`,
|
||||
),
|
||||
Package: "aws-lc",
|
||||
PURL: mustPURL("pkg:generic/aws-lc@version"),
|
||||
CPEs: singleCPE("cpe:2.3:a:amazon:aws_libcrypto:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
|
||||
},
|
||||
{
|
||||
Class: "openssl-binary",
|
||||
EvidenceMatcher: m.FileContentsVersionMatcher(
|
||||
// [NUL]OpenSSL 3.1.4'
|
||||
// [NUL]OpenSSL 1.1.1w'
|
||||
`\x00OpenSSL (?P<version>[0-9]+\.[0-9]+\.[0-9]+([a-z]+|-alpha[0-9]|-beta[0-9]|-rc[0-9])?)`,
|
||||
),
|
||||
Package: "openssl",
|
||||
PURL: mustPURL("pkg:generic/openssl@version"),
|
||||
CPEs: singleCPE("cpe:2.3:a:openssl:openssl:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
|
||||
},
|
||||
}...),
|
||||
},
|
||||
{
|
||||
Class: "openldap-search-binary",
|
||||
@@ -762,7 +783,9 @@ func DefaultClassifiers() []binutils.Classifier {
|
||||
Class: "elixir-binary",
|
||||
FileGlob: "**/elixir",
|
||||
EvidenceMatcher: m.FileContentsVersionMatcher(
|
||||
`(?m)ELIXIR_VERSION=(?P<version>[0-9]+\.[0-9]+\.[0-9]+)`),
|
||||
// Capture optional pre-release suffix (-rc.1, -alpha.0, -beta.2,
|
||||
// etc.) so release-candidate elixir images (#4819) match.
|
||||
`(?m)ELIXIR_VERSION=(?P<version>[0-9]+\.[0-9]+\.[0-9]+(?:-[a-z0-9]+(?:\.[0-9]+)?)?)`),
|
||||
Package: "elixir",
|
||||
PURL: mustPURL("pkg:generic/elixir@version"),
|
||||
CPEs: []cpe.CPE{
|
||||
@@ -773,7 +796,8 @@ func DefaultClassifiers() []binutils.Classifier {
|
||||
Class: "elixir-library",
|
||||
FileGlob: "**/elixir/ebin/elixir.app",
|
||||
EvidenceMatcher: m.FileContentsVersionMatcher(
|
||||
`(?m)\{vsn,"(?P<version>[0-9]+\.[0-9]+\.[0-9]+(-[a-z0-9]+)?)"\}`),
|
||||
// Same pre-release extension as elixir-binary above.
|
||||
`(?m)\{vsn,"(?P<version>[0-9]+\.[0-9]+\.[0-9]+(?:-[a-z0-9]+(?:\.[0-9]+)?)?)"\}`),
|
||||
Package: "elixir",
|
||||
PURL: mustPURL("pkg:generic/elixir@version"),
|
||||
CPEs: singleCPE("cpe:2.3:a:elixir-lang:elixir:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
|
||||
@@ -905,6 +929,29 @@ func DefaultClassifiers() []binutils.Classifier {
|
||||
PURL: mustPURL("pkg:generic/mongodb@version"),
|
||||
CPEs: singleCPE("cpe:2.3:a:mongodb:mongodb:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
|
||||
},
|
||||
{
|
||||
Class: "ingress-nginx-binary",
|
||||
FileGlob: "**/nginx-ingress-controller",
|
||||
EvidenceMatcher: binutils.MatchAny(
|
||||
// [NUL][NUL]v1.15.1[NUL][NUL]@e[ETX][NUL][NUL][NUL][NUL]go1.26.1[NUL][NUL][NUL]
|
||||
// �v1.15.1[NUL][NUL]�z[ETX][NUL][NUL][NUL][NUL]go1.24.4[NUL][NUL][NUL]
|
||||
m.FileContentsVersionMatcher(`v(?P<version>[0-9]+\.[0-9]+\.[0-9]+)\x00+.{0,50}go[0-9]+\.[0-9]+(\-(alpha|beta)\.[0-9])?\.[0-9]+\x00+`),
|
||||
// �Lv1.9.6[NUL][NUL]$a�c[SOH][NUL][NUL][NUL]
|
||||
// [NUL][NUL]v0.34.0[NUL]......�$a�...[NUL]
|
||||
m.FileContentsVersionMatcher(`v(?P<version>[0-9]+\.[0-9]+\.[0-9]+(\-(alpha|beta)\.[0-9])?)\x00+.{0,800}\$a.{0,10}\x00+`),
|
||||
// [NUL][NUL]v1.7.1[NUL][NUL][NUL]...S=v<y5...
|
||||
// [NUL]0.33.0[NUL][NUL]...[NUL][NUL]...S=v<y5
|
||||
m.FileContentsVersionMatcher(`\x00+v?(?P<version>[0-9]+\.[0-9]+\.[0-9]+(\-(alpha|beta)\.[0-9])?)\x00+.{0,100}S=v<y5`),
|
||||
// [NUL][NUL]go1.22.8[NUL][NUL][NUL][NUL][NUL][NUL][NUL][NUL][NUL]v1.12.0-beta.0[NUL][NUL]
|
||||
m.FileContentsVersionMatcher(`\x00+go[0-9]+\.[0-9]+\.[0-9]+\x00+v(?P<version>[0-9]+\.[0-9]+\.[0-9]+(\-(alpha|beta)\.[0-9])?)\x00+`),
|
||||
// [NUL][NUL]v1.2.0-beta.1[NUL][NUL]
|
||||
// [NUL][NUL]v1.0.0-alpha.2[NUL][NUL]
|
||||
m.FileContentsVersionMatcher(`\x00+v(?P<version>[0-9]+\.[0-9]+\.[0-9]+\-(alpha|beta)\.[0-9])\x00+`),
|
||||
),
|
||||
Package: "nginx-ingress-controller",
|
||||
PURL: mustPURL("pkg:generic/nginx-ingress-controller@version"),
|
||||
CPEs: singleCPE("cpe:2.3:a:kubernetes:ingress-nginx:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
|
||||
},
|
||||
}
|
||||
|
||||
return append(classifiers, defaultJavaClassifiers()...)
|
||||
|
||||
BIN
Binary file not shown.
Vendored
+20
@@ -0,0 +1,20 @@
|
||||
#!/bin/sh
|
||||
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
# SPDX-FileCopyrightText: 2021 The Elixir Team
|
||||
# SPDX-FileCopyrightText: 2012 Plataformatec
|
||||
|
||||
set -e
|
||||
|
||||
ELIXIR_VERSION=1.12.0-rc.1
|
||||
|
||||
if [ $# -eq 0 ] || { [ $# -eq 1 ] && { [ "$1" = "--help" ] || [ "$1" = "-h" ]; }; }; then
|
||||
cat <<USAGE >&2
|
||||
Usage: $(basename "$0") [options] [.exs file] [data]
|
||||
|
||||
## General options
|
||||
|
||||
-e "COMMAND" Evaluates the given command (*)
|
||||
-h, --help Prints this message (standalone)
|
||||
-r "FILE" Requires the given files/patterns (*)
|
||||
-S SCRIPT Finds and executes the given script in \$PATH
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
{application,elixir,
|
||||
[{description,"elixir"},
|
||||
{vsn,"1.12.0-rc.1"},
|
||||
{modules,
|
||||
['Elixir.Access','Elixir.Agent.Server','Elixir.Agent',
|
||||
'Elixir.Application','Elixir.ArgumentError',
|
||||
elixir_overridable,elixir_parser,elixir_quote,elixir_rewrite,
|
||||
elixir_sup,elixir_tokenizer,elixir_utils,iex]},
|
||||
{registered,[elixir_sup,elixir_config,elixir_code_server]},
|
||||
{applications,[kernel,stdlib,compiler]},
|
||||
{mod,{elixir,[]}},
|
||||
{env,
|
||||
[{ansi_syntax_colors,
|
||||
[{atom,cyan},
|
||||
{binary,default_color},
|
||||
{operator,default_color}]},
|
||||
{check_endianness,true},
|
||||
{dbg_callback,{'Elixir.Macro',dbg,[]}},
|
||||
{time_zone_database,'Elixir.Calendar.UTCOnlyTimeZoneDatabase'}]}]}.
|
||||
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.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
+83
-2
@@ -625,12 +625,14 @@ from-images:
|
||||
paths:
|
||||
- /usr/local/bin/redis-server
|
||||
|
||||
- version: 9.0.0
|
||||
- name: valkey-server
|
||||
version: 9.0.0
|
||||
images:
|
||||
- ref: valkey/valkey:9.0.0@sha256:42ea97850708540d4e05f6241cfbd241c1ba502e64d9a42efb2c2e277a8ca9d6
|
||||
platform: linux/amd64
|
||||
paths:
|
||||
- /usr/local/bin/valkey-server
|
||||
- /usr/local/bin/redis-server
|
||||
|
||||
- version: 2.9.0
|
||||
images:
|
||||
@@ -917,11 +919,19 @@ from-images:
|
||||
- name: openssl
|
||||
version: 1.1.1w
|
||||
images:
|
||||
- ref: openresty/openresty:1.25.3.1-2-alpine@sha256:b1cb45b1556801b8cb1bc29ea78faf2eaf67926a37b052dd070866e44d7df07a
|
||||
- ref: openresty/openresty:1.25.3.1-2-alpine@sha256:6c24f25318e5ecf0c981bec584842af329552a538fe48a24ec25387374c652b2
|
||||
platform: linux/arm64
|
||||
paths:
|
||||
- /usr/local/openresty/openssl/bin/openssl
|
||||
|
||||
- name: aws-lc
|
||||
version: 1.69.0
|
||||
images:
|
||||
- ref: haproxytech/haproxy-alpine:3.3.8@sha256:ba237771cc7e734b4449829b09d107012c8d7578d77487b8453207e7ca851996
|
||||
platform: linux/amd64
|
||||
paths:
|
||||
- /opt/aws-lc/bin/openssl
|
||||
|
||||
- name: openldap
|
||||
version: 2.6.10
|
||||
images:
|
||||
@@ -1379,3 +1389,74 @@ from-images:
|
||||
platform: linux/amd64
|
||||
paths:
|
||||
- /usr/local/bin/envoy
|
||||
|
||||
- version: 1.15.1
|
||||
images:
|
||||
- ref: registry.k8s.io/ingress-nginx/controller:v1.15.1@sha256:594ceea76b01c592858f803f9ff4d2cb40542cae2060410b2c95f75907d659e1
|
||||
platform: linux/amd64
|
||||
paths:
|
||||
- /nginx-ingress-controller
|
||||
|
||||
- version: 1.11.8
|
||||
images:
|
||||
- ref: registry.k8s.io/ingress-nginx/controller:v1.11.8@sha256:695d79381ee6af00c7f5c9fd434f50851d7d32838ad5b2c507e416cf2084fc79
|
||||
platform: linux/amd64
|
||||
paths:
|
||||
- /nginx-ingress-controller
|
||||
|
||||
- version: 1.9.6
|
||||
images:
|
||||
- ref: registry.k8s.io/ingress-nginx/controller:v1.9.6@sha256:1405cc613bd95b2c6edd8b2a152510ae91c7e62aea4698500d23b2145960ab9c
|
||||
platform: linux/amd64
|
||||
paths:
|
||||
- /nginx-ingress-controller
|
||||
|
||||
- version: 1.8.4
|
||||
images:
|
||||
- ref: registry.k8s.io/ingress-nginx/controller:v1.8.4@sha256:8d8ddf32b83ca3e74bd5f66369fa60d85353e18ff55fa7691b321aa4716f5ba9
|
||||
platform: linux/amd64
|
||||
paths:
|
||||
- /nginx-ingress-controller
|
||||
|
||||
- version: 1.7.1
|
||||
images:
|
||||
- ref: registry.k8s.io/ingress-nginx/controller:v1.7.1@sha256:7244b95ea47bddcb8267c1e625fb163fc183ef55448855e3ac52a7b260a60407
|
||||
platform: linux/amd64
|
||||
paths:
|
||||
- /nginx-ingress-controller
|
||||
|
||||
- version: 1.12.0-beta.0
|
||||
images:
|
||||
- ref: registry.k8s.io/ingress-nginx/controller:v1.12.0-beta.0@sha256:9724476b928967173d501040631b23ba07f47073999e80e34b120e8db5f234d5
|
||||
platform: linux/amd64
|
||||
paths:
|
||||
- /nginx-ingress-controller
|
||||
|
||||
- version: 1.2.0-beta.1
|
||||
images:
|
||||
- ref: k8s.gcr.io/ingress-nginx/controller:v1.2.0-beta.1@sha256:7059739637c30865f74cae403fffa55c2cb6d9779cd15654480dd0e4f850d536
|
||||
platform: linux/amd64
|
||||
paths:
|
||||
- /nginx-ingress-controller
|
||||
|
||||
- version: 1.0.0-alpha.2
|
||||
images:
|
||||
- ref: k8s.gcr.io/ingress-nginx/controller:v1.0.0-alpha.2@sha256:04a0ad3a1279c2a58898e789eed767eafa138ee1e5b9b23a988c6e8485cf958d
|
||||
platform: linux/amd64
|
||||
paths:
|
||||
- /nginx-ingress-controller
|
||||
|
||||
- version: 0.34.0
|
||||
images:
|
||||
- ref: k8s.gcr.io/ingress-nginx/controller:v0.34.0@sha256:5e0dcdc3ddb076f9ad988c624b8c459b53235ace26b9b18c192dedd3a038173c
|
||||
platform: linux/amd64
|
||||
paths:
|
||||
- /nginx-ingress-controller
|
||||
|
||||
- version: 0.33.0
|
||||
images:
|
||||
- ref: quay.io/kubernetes-ingress-controller/nginx-ingress-controller:0.33.0@sha256:ad8a1e9e44b4deb6ded8d677e9f0014178294e579d0710a48bca1e05838f2473
|
||||
platform: linux/amd64
|
||||
paths:
|
||||
- /nginx-ingress-controller
|
||||
|
||||
|
||||
@@ -18,71 +18,60 @@ var (
|
||||
licensePattern = regexp.MustCompile(`^License: (?P<license>\S*)`)
|
||||
commonLicensePathPattern = regexp.MustCompile(`/usr/share/common-licenses/(?P<license>[0-9A-Za-z_.\-]+)`)
|
||||
licenseAgreementHeadingPattern = regexp.MustCompile(`(?i)^\s*(?P<license>LICENSE AGREEMENT(?: FOR .+?)?)\s*$`)
|
||||
formatHeaderPattern = regexp.MustCompile(`^Format:\s*https?://www\.debian\.org/doc/packaging-manuals/copyright-format/`)
|
||||
)
|
||||
|
||||
// heading-detection states. Replaces licenseFirstSentenceAfterHeadingPattern,
|
||||
// which only matched at the start of the file: a non-empty heading, a line
|
||||
// of dashes, blank lines, then text up to the first period.
|
||||
const (
|
||||
expectHeading = iota
|
||||
expectDashes
|
||||
skipBlanks
|
||||
captureLicense
|
||||
headingDone // matched or impossible — stop checking
|
||||
)
|
||||
|
||||
func parseLicensesFromCopyright(reader io.Reader) []string {
|
||||
findings := strset.New()
|
||||
scanner := bufio.NewScanner(reader)
|
||||
|
||||
// State machine replacing licenseFirstSentenceAfterHeadingPattern.
|
||||
// That regex only matched at the start of the file: a non-empty heading,
|
||||
// a line of dashes, blank lines, then text up to the first period.
|
||||
const (
|
||||
expectHeading = iota
|
||||
expectDashes
|
||||
skipBlanks
|
||||
captureLicense
|
||||
headingDone // matched or impossible — stop checking
|
||||
)
|
||||
// per the DEP-5 spec, machine-readable copyright files MUST have a
|
||||
// Format field whose value is a URI for the specification. Only files
|
||||
// with this header should be parsed as machine-readable.
|
||||
// See: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
|
||||
formatVerified := false
|
||||
headingState := expectHeading
|
||||
var licenseText strings.Builder
|
||||
|
||||
for scanner.Scan() {
|
||||
line := scanner.Text()
|
||||
|
||||
// per-line regex checks (applied to every line)
|
||||
if value := findLicenseClause(licensePattern, line); value != "" {
|
||||
findings.Add(value)
|
||||
}
|
||||
if value := findLicenseClause(commonLicensePathPattern, line); value != "" {
|
||||
findings.Add(value)
|
||||
}
|
||||
if value := findLicenseClause(licenseAgreementHeadingPattern, line); value != "" {
|
||||
findings.Add(value)
|
||||
if !formatVerified {
|
||||
if strings.TrimSpace(line) == "" {
|
||||
continue
|
||||
}
|
||||
if !formatHeaderPattern.MatchString(line) {
|
||||
return nil
|
||||
}
|
||||
formatVerified = true
|
||||
}
|
||||
|
||||
// multi-line heading detection (only at start of file)
|
||||
switch headingState {
|
||||
case expectHeading:
|
||||
if strings.TrimSpace(line) != "" {
|
||||
headingState = expectDashes
|
||||
} else {
|
||||
headingState = headingDone
|
||||
}
|
||||
case expectDashes:
|
||||
trimmed := strings.TrimSpace(line)
|
||||
if len(trimmed) > 0 && strings.Trim(trimmed, "-") == "" {
|
||||
headingState = skipBlanks
|
||||
} else {
|
||||
headingState = headingDone
|
||||
}
|
||||
case skipBlanks:
|
||||
if strings.TrimSpace(line) != "" {
|
||||
headingState = captureLicense
|
||||
licenseText.WriteString(line)
|
||||
if value := extractUpToFirstPeriod(licenseText.String()); value != "" {
|
||||
findings.Add(value)
|
||||
headingState = headingDone
|
||||
}
|
||||
}
|
||||
case captureLicense:
|
||||
licenseText.WriteString(" ")
|
||||
licenseText.WriteString(line)
|
||||
if value := extractUpToFirstPeriod(licenseText.String()); value != "" {
|
||||
for _, p := range []*regexp.Regexp{licensePattern, commonLicensePathPattern, licenseAgreementHeadingPattern} {
|
||||
if value := findLicenseClause(p, line); value != "" {
|
||||
findings.Add(value)
|
||||
headingState = headingDone
|
||||
}
|
||||
}
|
||||
|
||||
var found string
|
||||
headingState, found = advanceHeadingState(headingState, line, &licenseText)
|
||||
if found != "" {
|
||||
findings.Add(found)
|
||||
}
|
||||
}
|
||||
|
||||
if !formatVerified {
|
||||
return nil
|
||||
}
|
||||
|
||||
results := findings.List()
|
||||
@@ -91,6 +80,40 @@ func parseLicensesFromCopyright(reader io.Reader) []string {
|
||||
return results
|
||||
}
|
||||
|
||||
func advanceHeadingState(state int, line string, licenseText *strings.Builder) (int, string) {
|
||||
switch state {
|
||||
case expectHeading:
|
||||
if strings.TrimSpace(line) != "" {
|
||||
return expectDashes, ""
|
||||
}
|
||||
return headingDone, ""
|
||||
case expectDashes:
|
||||
trimmed := strings.TrimSpace(line)
|
||||
if len(trimmed) > 0 && strings.Trim(trimmed, "-") == "" {
|
||||
return skipBlanks, ""
|
||||
}
|
||||
return headingDone, ""
|
||||
case skipBlanks:
|
||||
if strings.TrimSpace(line) == "" {
|
||||
return state, ""
|
||||
}
|
||||
licenseText.WriteString(line)
|
||||
if value := extractUpToFirstPeriod(licenseText.String()); value != "" {
|
||||
return headingDone, value
|
||||
}
|
||||
return captureLicense, ""
|
||||
case captureLicense:
|
||||
licenseText.WriteString(" ")
|
||||
licenseText.WriteString(line)
|
||||
if value := extractUpToFirstPeriod(licenseText.String()); value != "" {
|
||||
return headingDone, value
|
||||
}
|
||||
return state, ""
|
||||
case headingDone:
|
||||
}
|
||||
return state, ""
|
||||
}
|
||||
|
||||
// extractUpToFirstPeriod returns the license text up to the first period,
|
||||
// processed through ensureIsSingleLicense, or "" if no period found yet.
|
||||
func extractUpToFirstPeriod(s string) string {
|
||||
|
||||
@@ -2,6 +2,7 @@ package debian
|
||||
|
||||
import (
|
||||
"os"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/google/go-cmp/cmp"
|
||||
@@ -14,13 +15,14 @@ func TestParseLicensesFromCopyright(t *testing.T) {
|
||||
expected []string
|
||||
}{
|
||||
{
|
||||
fixture: "testdata/copyright/libc6",
|
||||
// note: there are other licenses in this file that are not matched --we don't do full text license identification yet
|
||||
expected: []string{"GPL-2", "LGPL-2.1"},
|
||||
// no Format header; not machine-readable, returns nil
|
||||
fixture: "testdata/copyright/libc6",
|
||||
expected: nil,
|
||||
},
|
||||
{
|
||||
// no Format header; not machine-readable, returns nil
|
||||
fixture: "testdata/copyright/trilicense",
|
||||
expected: []string{"GPL-2", "LGPL-2.1", "MPL-1.1"},
|
||||
expected: nil,
|
||||
},
|
||||
{
|
||||
fixture: "testdata/copyright/liblzma5",
|
||||
@@ -31,21 +33,25 @@ func TestParseLicensesFromCopyright(t *testing.T) {
|
||||
expected: []string{"GPL-1", "GPL-2", "LGPL-2.1"},
|
||||
},
|
||||
{
|
||||
fixture: "testdata/copyright/python",
|
||||
// note: this should not capture #, Permission, This, see ... however it's not clear how to fix this (this is probably good enough)
|
||||
expected: []string{"#", "Apache", "Apache-2", "Apache-2.0", "Expat", "GPL-2", "ISC", "LGPL-2.1+", "PSF-2", "Permission", "Python", "This", "see"},
|
||||
// no Format header; not machine-readable, returns nil
|
||||
// previously this captured nonsensical values like "#", "Permission", "This", "see"
|
||||
fixture: "testdata/copyright/python",
|
||||
expected: nil,
|
||||
},
|
||||
{
|
||||
// no Format header; not machine-readable, returns nil
|
||||
fixture: "testdata/copyright/cuda",
|
||||
expected: []string{"NVIDIA Software License Agreement and CUDA Supplement to Software License Agreement"},
|
||||
expected: nil,
|
||||
},
|
||||
{
|
||||
// no Format header; not machine-readable, returns nil
|
||||
fixture: "testdata/copyright/dev-kit",
|
||||
expected: []string{"LICENSE AGREEMENT FOR NVIDIA SOFTWARE DEVELOPMENT KITS"},
|
||||
expected: nil,
|
||||
},
|
||||
{
|
||||
// no Format header; not machine-readable, returns nil
|
||||
fixture: "testdata/copyright/microsoft",
|
||||
expected: []string{"LICENSE AGREEMENT FOR MICROSOFT PRODUCTS"},
|
||||
expected: nil,
|
||||
},
|
||||
}
|
||||
|
||||
@@ -63,3 +69,71 @@ func TestParseLicensesFromCopyright(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestParseLicensesFromCopyright_FormatHeader(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
content string
|
||||
machineReadable bool
|
||||
}{
|
||||
{
|
||||
name: "valid http Format header",
|
||||
content: "Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/\n",
|
||||
machineReadable: true,
|
||||
},
|
||||
{
|
||||
name: "valid https Format header",
|
||||
content: "Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/\n",
|
||||
machineReadable: true,
|
||||
},
|
||||
{
|
||||
name: "blank lines before Format header",
|
||||
content: "\n\nFormat: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/\n",
|
||||
machineReadable: true,
|
||||
},
|
||||
{
|
||||
name: "no Format header",
|
||||
content: "This is the Debian prepackaged version of foo.\n",
|
||||
machineReadable: false,
|
||||
},
|
||||
{
|
||||
name: "Format header is not first non-blank line",
|
||||
content: "Some-Field: value\nFormat: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/\n",
|
||||
machineReadable: false,
|
||||
},
|
||||
{
|
||||
name: "empty content",
|
||||
content: "",
|
||||
machineReadable: false,
|
||||
},
|
||||
{
|
||||
name: "only blank lines",
|
||||
content: "\n\n\n",
|
||||
machineReadable: false,
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
actual := parseLicensesFromCopyright(strings.NewReader(test.content))
|
||||
// parseLicensesFromCopyright returns nil for non-machine-readable
|
||||
// files and a (possibly empty) slice otherwise.
|
||||
if test.machineReadable {
|
||||
require.NotNil(t, actual)
|
||||
} else {
|
||||
require.Nil(t, actual)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestParseLicensesFromCopyrightInline(t *testing.T) {
|
||||
// verify that a file with License: fields but no Format header returns nil
|
||||
content := `License: GPL-2
|
||||
License: LGPL-2.1
|
||||
`
|
||||
actual := parseLicensesFromCopyright(strings.NewReader(content))
|
||||
if actual != nil {
|
||||
t.Errorf("expected nil for non-machine-readable file, got %v", actual)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -319,174 +319,174 @@ func TestCataloger(t *testing.T) {
|
||||
net8AppExpectedBinarySelfContainedPkgs = append(net8AppExpectedBinarySelfContainedPkgs,
|
||||
// include the runtime...
|
||||
".NET Runtime @ 8,0,1425,11118 (/app/coreclr.dll)",
|
||||
"Microsoft.CSharp @ 8.0.1425.11118 (/app/Microsoft.CSharp.dll)",
|
||||
"Microsoft.VisualBasic @ 8.0.1425.11118 (/app/Microsoft.VisualBasic.dll)",
|
||||
"Microsoft.CSharp @ 8.0.14 (/app/Microsoft.CSharp.dll)",
|
||||
"Microsoft.VisualBasic @ 8.0.14 (/app/Microsoft.VisualBasic.dll)",
|
||||
"Microsoft.VisualBasic.Core @ 13.0.1425.11118 (/app/Microsoft.VisualBasic.Core.dll)",
|
||||
"Microsoft.Win32.Primitives @ 8.0.1425.11118 (/app/Microsoft.Win32.Primitives.dll)",
|
||||
"Microsoft.Win32.Registry @ 8.0.1425.11118 (/app/Microsoft.Win32.Registry.dll)",
|
||||
"System @ 8.0.1425.11118 (/app/System.dll)",
|
||||
"System.AppContext @ 8.0.1425.11118 (/app/System.AppContext.dll)",
|
||||
"System.Buffers @ 8.0.1425.11118 (/app/System.Buffers.dll)",
|
||||
"System.Collections @ 8.0.1425.11118 (/app/System.Collections.dll)",
|
||||
"System.Collections.Concurrent @ 8.0.1425.11118 (/app/System.Collections.Concurrent.dll)",
|
||||
"System.Collections.Immutable @ 8.0.1425.11118 (/app/System.Collections.Immutable.dll)",
|
||||
"System.Collections.NonGeneric @ 8.0.1425.11118 (/app/System.Collections.NonGeneric.dll)",
|
||||
"System.Collections.Specialized @ 8.0.1425.11118 (/app/System.Collections.Specialized.dll)",
|
||||
"System.ComponentModel @ 8.0.1425.11118 (/app/System.ComponentModel.dll)",
|
||||
"System.ComponentModel.Annotations @ 8.0.1425.11118 (/app/System.ComponentModel.Annotations.dll)",
|
||||
"System.ComponentModel.DataAnnotations @ 8.0.1425.11118 (/app/System.ComponentModel.DataAnnotations.dll)",
|
||||
"System.ComponentModel.EventBasedAsync @ 8.0.1425.11118 (/app/System.ComponentModel.EventBasedAsync.dll)",
|
||||
"System.ComponentModel.Primitives @ 8.0.1425.11118 (/app/System.ComponentModel.Primitives.dll)",
|
||||
"System.ComponentModel.TypeConverter @ 8.0.1425.11118 (/app/System.ComponentModel.TypeConverter.dll)",
|
||||
"System.Configuration @ 8.0.1425.11118 (/app/System.Configuration.dll)",
|
||||
"System.Console @ 8.0.1425.11118 (/app/System.Console.dll)",
|
||||
"System.Core @ 8.0.1425.11118 (/app/System.Core.dll)",
|
||||
"System.Data @ 8.0.1425.11118 (/app/System.Data.dll)",
|
||||
"System.Data.Common @ 8.0.1425.11118 (/app/System.Data.Common.dll)",
|
||||
"System.Data.DataSetExtensions @ 8.0.1425.11118 (/app/System.Data.DataSetExtensions.dll)",
|
||||
"System.Diagnostics.Contracts @ 8.0.1425.11118 (/app/System.Diagnostics.Contracts.dll)",
|
||||
"System.Diagnostics.Debug @ 8.0.1425.11118 (/app/System.Diagnostics.Debug.dll)",
|
||||
"System.Diagnostics.DiagnosticSource @ 8.0.1425.11118 (/app/System.Diagnostics.DiagnosticSource.dll)",
|
||||
"System.Diagnostics.FileVersionInfo @ 8.0.1425.11118 (/app/System.Diagnostics.FileVersionInfo.dll)",
|
||||
"System.Diagnostics.Process @ 8.0.1425.11118 (/app/System.Diagnostics.Process.dll)",
|
||||
"System.Diagnostics.StackTrace @ 8.0.1425.11118 (/app/System.Diagnostics.StackTrace.dll)",
|
||||
"System.Diagnostics.TextWriterTraceListener @ 8.0.1425.11118 (/app/System.Diagnostics.TextWriterTraceListener.dll)",
|
||||
"System.Diagnostics.Tools @ 8.0.1425.11118 (/app/System.Diagnostics.Tools.dll)",
|
||||
"System.Diagnostics.TraceSource @ 8.0.1425.11118 (/app/System.Diagnostics.TraceSource.dll)",
|
||||
"System.Diagnostics.Tracing @ 8.0.1425.11118 (/app/System.Diagnostics.Tracing.dll)",
|
||||
"System.Drawing @ 8.0.1425.11118 (/app/System.Drawing.dll)",
|
||||
"System.Drawing.Primitives @ 8.0.1425.11118 (/app/System.Drawing.Primitives.dll)",
|
||||
"System.Dynamic.Runtime @ 8.0.1425.11118 (/app/System.Dynamic.Runtime.dll)",
|
||||
"System.Formats.Asn1 @ 8.0.1425.11118 (/app/System.Formats.Asn1.dll)",
|
||||
"System.Formats.Tar @ 8.0.1425.11118 (/app/System.Formats.Tar.dll)",
|
||||
"System.Globalization @ 8.0.1425.11118 (/app/System.Globalization.dll)",
|
||||
"System.Globalization.Calendars @ 8.0.1425.11118 (/app/System.Globalization.Calendars.dll)",
|
||||
"System.Globalization.Extensions @ 8.0.1425.11118 (/app/System.Globalization.Extensions.dll)",
|
||||
"System.IO @ 8.0.1425.11118 (/app/System.IO.dll)",
|
||||
"System.IO.Compression @ 8.0.1425.11118 (/app/System.IO.Compression.dll)",
|
||||
"System.IO.Compression.Brotli @ 8.0.1425.11118 (/app/System.IO.Compression.Brotli.dll)",
|
||||
"System.IO.Compression.FileSystem @ 8.0.1425.11118 (/app/System.IO.Compression.FileSystem.dll)",
|
||||
"System.IO.Compression.ZipFile @ 8.0.1425.11118 (/app/System.IO.Compression.ZipFile.dll)",
|
||||
"System.IO.FileSystem @ 8.0.1425.11118 (/app/System.IO.FileSystem.dll)",
|
||||
"System.IO.FileSystem.AccessControl @ 8.0.1425.11118 (/app/System.IO.FileSystem.AccessControl.dll)",
|
||||
"System.IO.FileSystem.DriveInfo @ 8.0.1425.11118 (/app/System.IO.FileSystem.DriveInfo.dll)",
|
||||
"System.IO.FileSystem.Primitives @ 8.0.1425.11118 (/app/System.IO.FileSystem.Primitives.dll)",
|
||||
"System.IO.FileSystem.Watcher @ 8.0.1425.11118 (/app/System.IO.FileSystem.Watcher.dll)",
|
||||
"System.IO.IsolatedStorage @ 8.0.1425.11118 (/app/System.IO.IsolatedStorage.dll)",
|
||||
"System.IO.MemoryMappedFiles @ 8.0.1425.11118 (/app/System.IO.MemoryMappedFiles.dll)",
|
||||
"System.IO.Pipes @ 8.0.1425.11118 (/app/System.IO.Pipes.dll)",
|
||||
"System.IO.Pipes.AccessControl @ 8.0.1425.11118 (/app/System.IO.Pipes.AccessControl.dll)",
|
||||
"System.IO.UnmanagedMemoryStream @ 8.0.1425.11118 (/app/System.IO.UnmanagedMemoryStream.dll)",
|
||||
"System.Linq @ 8.0.1425.11118 (/app/System.Linq.dll)",
|
||||
"System.Linq.Expressions @ 8.0.1425.11118 (/app/System.Linq.Expressions.dll)",
|
||||
"System.Linq.Parallel @ 8.0.1425.11118 (/app/System.Linq.Parallel.dll)",
|
||||
"System.Linq.Queryable @ 8.0.1425.11118 (/app/System.Linq.Queryable.dll)",
|
||||
"System.Memory @ 8.0.1425.11118 (/app/System.Memory.dll)",
|
||||
"System.Net @ 8.0.1425.11118 (/app/System.Net.dll)",
|
||||
"System.Net.Http @ 8.0.1425.11118 (/app/System.Net.Http.dll)",
|
||||
"System.Net.Http.Json @ 8.0.1425.11118 (/app/System.Net.Http.Json.dll)",
|
||||
"System.Net.HttpListener @ 8.0.1425.11118 (/app/System.Net.HttpListener.dll)",
|
||||
"System.Net.Mail @ 8.0.1425.11118 (/app/System.Net.Mail.dll)",
|
||||
"System.Net.NameResolution @ 8.0.1425.11118 (/app/System.Net.NameResolution.dll)",
|
||||
"System.Net.NetworkInformation @ 8.0.1425.11118 (/app/System.Net.NetworkInformation.dll)",
|
||||
"System.Net.Ping @ 8.0.1425.11118 (/app/System.Net.Ping.dll)",
|
||||
"System.Net.Primitives @ 8.0.1425.11118 (/app/System.Net.Primitives.dll)",
|
||||
"System.Net.Quic @ 8.0.1425.11118 (/app/System.Net.Quic.dll)",
|
||||
"System.Net.Requests @ 8.0.1425.11118 (/app/System.Net.Requests.dll)",
|
||||
"System.Net.Security @ 8.0.1425.11118 (/app/System.Net.Security.dll)",
|
||||
"System.Net.ServicePoint @ 8.0.1425.11118 (/app/System.Net.ServicePoint.dll)",
|
||||
"System.Net.Sockets @ 8.0.1425.11118 (/app/System.Net.Sockets.dll)",
|
||||
"System.Net.WebClient @ 8.0.1425.11118 (/app/System.Net.WebClient.dll)",
|
||||
"System.Net.WebHeaderCollection @ 8.0.1425.11118 (/app/System.Net.WebHeaderCollection.dll)",
|
||||
"System.Net.WebProxy @ 8.0.1425.11118 (/app/System.Net.WebProxy.dll)",
|
||||
"System.Net.WebSockets @ 8.0.1425.11118 (/app/System.Net.WebSockets.dll)",
|
||||
"System.Net.WebSockets.Client @ 8.0.1425.11118 (/app/System.Net.WebSockets.Client.dll)",
|
||||
"System.Numerics @ 8.0.1425.11118 (/app/System.Numerics.dll)",
|
||||
"System.Numerics.Vectors @ 8.0.1425.11118 (/app/System.Numerics.Vectors.dll)",
|
||||
"System.ObjectModel @ 8.0.1425.11118 (/app/System.ObjectModel.dll)",
|
||||
"System.Private.CoreLib @ 8.0.1425.11118 (/app/System.Private.CoreLib.dll)",
|
||||
"System.Private.DataContractSerialization @ 8.0.1425.11118 (/app/System.Private.DataContractSerialization.dll)",
|
||||
"System.Private.Uri @ 8.0.1425.11118 (/app/System.Private.Uri.dll)",
|
||||
"System.Private.Xml @ 8.0.1425.11118 (/app/System.Private.Xml.dll)",
|
||||
"System.Private.Xml.Linq @ 8.0.1425.11118 (/app/System.Private.Xml.Linq.dll)",
|
||||
"System.Reflection @ 8.0.1425.11118 (/app/System.Reflection.dll)",
|
||||
"System.Reflection.DispatchProxy @ 8.0.1425.11118 (/app/System.Reflection.DispatchProxy.dll)",
|
||||
"System.Reflection.Emit @ 8.0.1425.11118 (/app/System.Reflection.Emit.dll)",
|
||||
"System.Reflection.Emit.ILGeneration @ 8.0.1425.11118 (/app/System.Reflection.Emit.ILGeneration.dll)",
|
||||
"System.Reflection.Emit.Lightweight @ 8.0.1425.11118 (/app/System.Reflection.Emit.Lightweight.dll)",
|
||||
"System.Reflection.Extensions @ 8.0.1425.11118 (/app/System.Reflection.Extensions.dll)",
|
||||
"System.Reflection.Metadata @ 8.0.1425.11118 (/app/System.Reflection.Metadata.dll)",
|
||||
"System.Reflection.Primitives @ 8.0.1425.11118 (/app/System.Reflection.Primitives.dll)",
|
||||
"System.Reflection.TypeExtensions @ 8.0.1425.11118 (/app/System.Reflection.TypeExtensions.dll)",
|
||||
"System.Resources.Reader @ 8.0.1425.11118 (/app/System.Resources.Reader.dll)",
|
||||
"System.Resources.ResourceManager @ 8.0.1425.11118 (/app/System.Resources.ResourceManager.dll)",
|
||||
"System.Resources.Writer @ 8.0.1425.11118 (/app/System.Resources.Writer.dll)",
|
||||
"System.Runtime @ 8.0.1425.11118 (/app/System.Runtime.dll)",
|
||||
"System.Runtime.CompilerServices.Unsafe @ 8.0.1425.11118 (/app/System.Runtime.CompilerServices.Unsafe.dll)",
|
||||
"System.Runtime.CompilerServices.VisualC @ 8.0.1425.11118 (/app/System.Runtime.CompilerServices.VisualC.dll)",
|
||||
"System.Runtime.Extensions @ 8.0.1425.11118 (/app/System.Runtime.Extensions.dll)",
|
||||
"System.Runtime.Handles @ 8.0.1425.11118 (/app/System.Runtime.Handles.dll)",
|
||||
"System.Runtime.InteropServices @ 8.0.1425.11118 (/app/System.Runtime.InteropServices.dll)",
|
||||
"System.Runtime.InteropServices.JavaScript @ 8.0.1425.11118 (/app/System.Runtime.InteropServices.JavaScript.dll)",
|
||||
"System.Runtime.InteropServices.RuntimeInformation @ 8.0.1425.11118 (/app/System.Runtime.InteropServices.RuntimeInformation.dll)",
|
||||
"System.Runtime.Intrinsics @ 8.0.1425.11118 (/app/System.Runtime.Intrinsics.dll)",
|
||||
"System.Runtime.Loader @ 8.0.1425.11118 (/app/System.Runtime.Loader.dll)",
|
||||
"System.Runtime.Numerics @ 8.0.1425.11118 (/app/System.Runtime.Numerics.dll)",
|
||||
"System.Runtime.Serialization @ 8.0.1425.11118 (/app/System.Runtime.Serialization.dll)",
|
||||
"System.Runtime.Serialization.Formatters @ 8.0.1425.11118 (/app/System.Runtime.Serialization.Formatters.dll)",
|
||||
"System.Runtime.Serialization.Json @ 8.0.1425.11118 (/app/System.Runtime.Serialization.Json.dll)",
|
||||
"System.Runtime.Serialization.Primitives @ 8.0.1425.11118 (/app/System.Runtime.Serialization.Primitives.dll)",
|
||||
"System.Runtime.Serialization.Xml @ 8.0.1425.11118 (/app/System.Runtime.Serialization.Xml.dll)",
|
||||
"System.Security @ 8.0.1425.11118 (/app/System.Security.dll)",
|
||||
"System.Security.AccessControl @ 8.0.1425.11118 (/app/System.Security.AccessControl.dll)",
|
||||
"System.Security.Claims @ 8.0.1425.11118 (/app/System.Security.Claims.dll)",
|
||||
"System.Security.Cryptography @ 8.0.1425.11118 (/app/System.Security.Cryptography.dll)",
|
||||
"System.Security.Cryptography.Algorithms @ 8.0.1425.11118 (/app/System.Security.Cryptography.Algorithms.dll)",
|
||||
"System.Security.Cryptography.Cng @ 8.0.1425.11118 (/app/System.Security.Cryptography.Cng.dll)",
|
||||
"System.Security.Cryptography.Csp @ 8.0.1425.11118 (/app/System.Security.Cryptography.Csp.dll)",
|
||||
"System.Security.Cryptography.Encoding @ 8.0.1425.11118 (/app/System.Security.Cryptography.Encoding.dll)",
|
||||
"System.Security.Cryptography.OpenSsl @ 8.0.1425.11118 (/app/System.Security.Cryptography.OpenSsl.dll)",
|
||||
"System.Security.Cryptography.Primitives @ 8.0.1425.11118 (/app/System.Security.Cryptography.Primitives.dll)",
|
||||
"System.Security.Cryptography.X509Certificates @ 8.0.1425.11118 (/app/System.Security.Cryptography.X509Certificates.dll)",
|
||||
"System.Security.Principal @ 8.0.1425.11118 (/app/System.Security.Principal.dll)",
|
||||
"System.Security.Principal.Windows @ 8.0.1425.11118 (/app/System.Security.Principal.Windows.dll)",
|
||||
"System.Security.SecureString @ 8.0.1425.11118 (/app/System.Security.SecureString.dll)",
|
||||
"System.ServiceModel.Web @ 8.0.1425.11118 (/app/System.ServiceModel.Web.dll)",
|
||||
"System.ServiceProcess @ 8.0.1425.11118 (/app/System.ServiceProcess.dll)",
|
||||
"System.Text.Encoding @ 8.0.1425.11118 (/app/System.Text.Encoding.dll)",
|
||||
"System.Text.Encoding.CodePages @ 8.0.1425.11118 (/app/System.Text.Encoding.CodePages.dll)",
|
||||
"System.Text.Encoding.Extensions @ 8.0.1425.11118 (/app/System.Text.Encoding.Extensions.dll)",
|
||||
"System.Text.Encodings.Web @ 8.0.1425.11118 (/app/System.Text.Encodings.Web.dll)",
|
||||
"System.Text.Json @ 8.0.1425.11118 (/app/System.Text.Json.dll)",
|
||||
"System.Text.RegularExpressions @ 8.0.1425.11118 (/app/System.Text.RegularExpressions.dll)",
|
||||
"System.Threading @ 8.0.1425.11118 (/app/System.Threading.dll)",
|
||||
"System.Threading.Channels @ 8.0.1425.11118 (/app/System.Threading.Channels.dll)",
|
||||
"System.Threading.Overlapped @ 8.0.1425.11118 (/app/System.Threading.Overlapped.dll)",
|
||||
"System.Threading.Tasks @ 8.0.1425.11118 (/app/System.Threading.Tasks.dll)",
|
||||
"System.Threading.Tasks.Dataflow @ 8.0.1425.11118 (/app/System.Threading.Tasks.Dataflow.dll)",
|
||||
"System.Threading.Tasks.Extensions @ 8.0.1425.11118 (/app/System.Threading.Tasks.Extensions.dll)",
|
||||
"System.Threading.Tasks.Parallel @ 8.0.1425.11118 (/app/System.Threading.Tasks.Parallel.dll)",
|
||||
"System.Threading.Thread @ 8.0.1425.11118 (/app/System.Threading.Thread.dll)",
|
||||
"System.Threading.ThreadPool @ 8.0.1425.11118 (/app/System.Threading.ThreadPool.dll)",
|
||||
"System.Threading.Timer @ 8.0.1425.11118 (/app/System.Threading.Timer.dll)",
|
||||
"System.Transactions @ 8.0.1425.11118 (/app/System.Transactions.dll)",
|
||||
"System.Transactions.Local @ 8.0.1425.11118 (/app/System.Transactions.Local.dll)",
|
||||
"System.ValueTuple @ 8.0.1425.11118 (/app/System.ValueTuple.dll)",
|
||||
"System.Web @ 8.0.1425.11118 (/app/System.Web.dll)",
|
||||
"System.Web.HttpUtility @ 8.0.1425.11118 (/app/System.Web.HttpUtility.dll)",
|
||||
"System.Windows @ 8.0.1425.11118 (/app/System.Windows.dll)",
|
||||
"System.Xml @ 8.0.1425.11118 (/app/System.Xml.dll)",
|
||||
"System.Xml.Linq @ 8.0.1425.11118 (/app/System.Xml.Linq.dll)",
|
||||
"System.Xml.ReaderWriter @ 8.0.1425.11118 (/app/System.Xml.ReaderWriter.dll)",
|
||||
"System.Xml.Serialization @ 8.0.1425.11118 (/app/System.Xml.Serialization.dll)",
|
||||
"System.Xml.XDocument @ 8.0.1425.11118 (/app/System.Xml.XDocument.dll)",
|
||||
"System.Xml.XPath @ 8.0.1425.11118 (/app/System.Xml.XPath.dll)",
|
||||
"System.Xml.XPath.XDocument @ 8.0.1425.11118 (/app/System.Xml.XPath.XDocument.dll)",
|
||||
"System.Xml.XmlDocument @ 8.0.1425.11118 (/app/System.Xml.XmlDocument.dll)",
|
||||
"System.Xml.XmlSerializer @ 8.0.1425.11118 (/app/System.Xml.XmlSerializer.dll)",
|
||||
"WindowsBase @ 8.0.1425.11118 (/app/WindowsBase.dll)",
|
||||
"mscorlib @ 8.0.1425.11118 (/app/mscorlib.dll)",
|
||||
"netstandard @ 8.0.1425.11118 (/app/netstandard.dll)",
|
||||
"Microsoft.Win32.Primitives @ 8.0.14 (/app/Microsoft.Win32.Primitives.dll)",
|
||||
"Microsoft.Win32.Registry @ 8.0.14 (/app/Microsoft.Win32.Registry.dll)",
|
||||
"System @ 8.0.14 (/app/System.dll)",
|
||||
"System.AppContext @ 8.0.14 (/app/System.AppContext.dll)",
|
||||
"System.Buffers @ 8.0.14 (/app/System.Buffers.dll)",
|
||||
"System.Collections @ 8.0.14 (/app/System.Collections.dll)",
|
||||
"System.Collections.Concurrent @ 8.0.14 (/app/System.Collections.Concurrent.dll)",
|
||||
"System.Collections.Immutable @ 8.0.14 (/app/System.Collections.Immutable.dll)",
|
||||
"System.Collections.NonGeneric @ 8.0.14 (/app/System.Collections.NonGeneric.dll)",
|
||||
"System.Collections.Specialized @ 8.0.14 (/app/System.Collections.Specialized.dll)",
|
||||
"System.ComponentModel @ 8.0.14 (/app/System.ComponentModel.dll)",
|
||||
"System.ComponentModel.Annotations @ 8.0.14 (/app/System.ComponentModel.Annotations.dll)",
|
||||
"System.ComponentModel.DataAnnotations @ 8.0.14 (/app/System.ComponentModel.DataAnnotations.dll)",
|
||||
"System.ComponentModel.EventBasedAsync @ 8.0.14 (/app/System.ComponentModel.EventBasedAsync.dll)",
|
||||
"System.ComponentModel.Primitives @ 8.0.14 (/app/System.ComponentModel.Primitives.dll)",
|
||||
"System.ComponentModel.TypeConverter @ 8.0.14 (/app/System.ComponentModel.TypeConverter.dll)",
|
||||
"System.Configuration @ 8.0.14 (/app/System.Configuration.dll)",
|
||||
"System.Console @ 8.0.14 (/app/System.Console.dll)",
|
||||
"System.Core @ 8.0.14 (/app/System.Core.dll)",
|
||||
"System.Data @ 8.0.14 (/app/System.Data.dll)",
|
||||
"System.Data.Common @ 8.0.14 (/app/System.Data.Common.dll)",
|
||||
"System.Data.DataSetExtensions @ 8.0.14 (/app/System.Data.DataSetExtensions.dll)",
|
||||
"System.Diagnostics.Contracts @ 8.0.14 (/app/System.Diagnostics.Contracts.dll)",
|
||||
"System.Diagnostics.Debug @ 8.0.14 (/app/System.Diagnostics.Debug.dll)",
|
||||
"System.Diagnostics.DiagnosticSource @ 8.0.14 (/app/System.Diagnostics.DiagnosticSource.dll)",
|
||||
"System.Diagnostics.FileVersionInfo @ 8.0.14 (/app/System.Diagnostics.FileVersionInfo.dll)",
|
||||
"System.Diagnostics.Process @ 8.0.14 (/app/System.Diagnostics.Process.dll)",
|
||||
"System.Diagnostics.StackTrace @ 8.0.14 (/app/System.Diagnostics.StackTrace.dll)",
|
||||
"System.Diagnostics.TextWriterTraceListener @ 8.0.14 (/app/System.Diagnostics.TextWriterTraceListener.dll)",
|
||||
"System.Diagnostics.Tools @ 8.0.14 (/app/System.Diagnostics.Tools.dll)",
|
||||
"System.Diagnostics.TraceSource @ 8.0.14 (/app/System.Diagnostics.TraceSource.dll)",
|
||||
"System.Diagnostics.Tracing @ 8.0.14 (/app/System.Diagnostics.Tracing.dll)",
|
||||
"System.Drawing @ 8.0.14 (/app/System.Drawing.dll)",
|
||||
"System.Drawing.Primitives @ 8.0.14 (/app/System.Drawing.Primitives.dll)",
|
||||
"System.Dynamic.Runtime @ 8.0.14 (/app/System.Dynamic.Runtime.dll)",
|
||||
"System.Formats.Asn1 @ 8.0.14 (/app/System.Formats.Asn1.dll)",
|
||||
"System.Formats.Tar @ 8.0.14 (/app/System.Formats.Tar.dll)",
|
||||
"System.Globalization @ 8.0.14 (/app/System.Globalization.dll)",
|
||||
"System.Globalization.Calendars @ 8.0.14 (/app/System.Globalization.Calendars.dll)",
|
||||
"System.Globalization.Extensions @ 8.0.14 (/app/System.Globalization.Extensions.dll)",
|
||||
"System.IO @ 8.0.14 (/app/System.IO.dll)",
|
||||
"System.IO.Compression @ 8.0.14 (/app/System.IO.Compression.dll)",
|
||||
"System.IO.Compression.Brotli @ 8.0.14 (/app/System.IO.Compression.Brotli.dll)",
|
||||
"System.IO.Compression.FileSystem @ 8.0.14 (/app/System.IO.Compression.FileSystem.dll)",
|
||||
"System.IO.Compression.ZipFile @ 8.0.14 (/app/System.IO.Compression.ZipFile.dll)",
|
||||
"System.IO.FileSystem @ 8.0.14 (/app/System.IO.FileSystem.dll)",
|
||||
"System.IO.FileSystem.AccessControl @ 8.0.14 (/app/System.IO.FileSystem.AccessControl.dll)",
|
||||
"System.IO.FileSystem.DriveInfo @ 8.0.14 (/app/System.IO.FileSystem.DriveInfo.dll)",
|
||||
"System.IO.FileSystem.Primitives @ 8.0.14 (/app/System.IO.FileSystem.Primitives.dll)",
|
||||
"System.IO.FileSystem.Watcher @ 8.0.14 (/app/System.IO.FileSystem.Watcher.dll)",
|
||||
"System.IO.IsolatedStorage @ 8.0.14 (/app/System.IO.IsolatedStorage.dll)",
|
||||
"System.IO.MemoryMappedFiles @ 8.0.14 (/app/System.IO.MemoryMappedFiles.dll)",
|
||||
"System.IO.Pipes @ 8.0.14 (/app/System.IO.Pipes.dll)",
|
||||
"System.IO.Pipes.AccessControl @ 8.0.14 (/app/System.IO.Pipes.AccessControl.dll)",
|
||||
"System.IO.UnmanagedMemoryStream @ 8.0.14 (/app/System.IO.UnmanagedMemoryStream.dll)",
|
||||
"System.Linq @ 8.0.14 (/app/System.Linq.dll)",
|
||||
"System.Linq.Expressions @ 8.0.14 (/app/System.Linq.Expressions.dll)",
|
||||
"System.Linq.Parallel @ 8.0.14 (/app/System.Linq.Parallel.dll)",
|
||||
"System.Linq.Queryable @ 8.0.14 (/app/System.Linq.Queryable.dll)",
|
||||
"System.Memory @ 8.0.14 (/app/System.Memory.dll)",
|
||||
"System.Net @ 8.0.14 (/app/System.Net.dll)",
|
||||
"System.Net.Http @ 8.0.14 (/app/System.Net.Http.dll)",
|
||||
"System.Net.Http.Json @ 8.0.14 (/app/System.Net.Http.Json.dll)",
|
||||
"System.Net.HttpListener @ 8.0.14 (/app/System.Net.HttpListener.dll)",
|
||||
"System.Net.Mail @ 8.0.14 (/app/System.Net.Mail.dll)",
|
||||
"System.Net.NameResolution @ 8.0.14 (/app/System.Net.NameResolution.dll)",
|
||||
"System.Net.NetworkInformation @ 8.0.14 (/app/System.Net.NetworkInformation.dll)",
|
||||
"System.Net.Ping @ 8.0.14 (/app/System.Net.Ping.dll)",
|
||||
"System.Net.Primitives @ 8.0.14 (/app/System.Net.Primitives.dll)",
|
||||
"System.Net.Quic @ 8.0.14 (/app/System.Net.Quic.dll)",
|
||||
"System.Net.Requests @ 8.0.14 (/app/System.Net.Requests.dll)",
|
||||
"System.Net.Security @ 8.0.14 (/app/System.Net.Security.dll)",
|
||||
"System.Net.ServicePoint @ 8.0.14 (/app/System.Net.ServicePoint.dll)",
|
||||
"System.Net.Sockets @ 8.0.14 (/app/System.Net.Sockets.dll)",
|
||||
"System.Net.WebClient @ 8.0.14 (/app/System.Net.WebClient.dll)",
|
||||
"System.Net.WebHeaderCollection @ 8.0.14 (/app/System.Net.WebHeaderCollection.dll)",
|
||||
"System.Net.WebProxy @ 8.0.14 (/app/System.Net.WebProxy.dll)",
|
||||
"System.Net.WebSockets @ 8.0.14 (/app/System.Net.WebSockets.dll)",
|
||||
"System.Net.WebSockets.Client @ 8.0.14 (/app/System.Net.WebSockets.Client.dll)",
|
||||
"System.Numerics @ 8.0.14 (/app/System.Numerics.dll)",
|
||||
"System.Numerics.Vectors @ 8.0.14 (/app/System.Numerics.Vectors.dll)",
|
||||
"System.ObjectModel @ 8.0.14 (/app/System.ObjectModel.dll)",
|
||||
"System.Private.CoreLib @ 8.0.14 (/app/System.Private.CoreLib.dll)",
|
||||
"System.Private.DataContractSerialization @ 8.0.14 (/app/System.Private.DataContractSerialization.dll)",
|
||||
"System.Private.Uri @ 8.0.14 (/app/System.Private.Uri.dll)",
|
||||
"System.Private.Xml @ 8.0.14 (/app/System.Private.Xml.dll)",
|
||||
"System.Private.Xml.Linq @ 8.0.14 (/app/System.Private.Xml.Linq.dll)",
|
||||
"System.Reflection @ 8.0.14 (/app/System.Reflection.dll)",
|
||||
"System.Reflection.DispatchProxy @ 8.0.14 (/app/System.Reflection.DispatchProxy.dll)",
|
||||
"System.Reflection.Emit @ 8.0.14 (/app/System.Reflection.Emit.dll)",
|
||||
"System.Reflection.Emit.ILGeneration @ 8.0.14 (/app/System.Reflection.Emit.ILGeneration.dll)",
|
||||
"System.Reflection.Emit.Lightweight @ 8.0.14 (/app/System.Reflection.Emit.Lightweight.dll)",
|
||||
"System.Reflection.Extensions @ 8.0.14 (/app/System.Reflection.Extensions.dll)",
|
||||
"System.Reflection.Metadata @ 8.0.14 (/app/System.Reflection.Metadata.dll)",
|
||||
"System.Reflection.Primitives @ 8.0.14 (/app/System.Reflection.Primitives.dll)",
|
||||
"System.Reflection.TypeExtensions @ 8.0.14 (/app/System.Reflection.TypeExtensions.dll)",
|
||||
"System.Resources.Reader @ 8.0.14 (/app/System.Resources.Reader.dll)",
|
||||
"System.Resources.ResourceManager @ 8.0.14 (/app/System.Resources.ResourceManager.dll)",
|
||||
"System.Resources.Writer @ 8.0.14 (/app/System.Resources.Writer.dll)",
|
||||
"System.Runtime @ 8.0.14 (/app/System.Runtime.dll)",
|
||||
"System.Runtime.CompilerServices.Unsafe @ 8.0.14 (/app/System.Runtime.CompilerServices.Unsafe.dll)",
|
||||
"System.Runtime.CompilerServices.VisualC @ 8.0.14 (/app/System.Runtime.CompilerServices.VisualC.dll)",
|
||||
"System.Runtime.Extensions @ 8.0.14 (/app/System.Runtime.Extensions.dll)",
|
||||
"System.Runtime.Handles @ 8.0.14 (/app/System.Runtime.Handles.dll)",
|
||||
"System.Runtime.InteropServices @ 8.0.14 (/app/System.Runtime.InteropServices.dll)",
|
||||
"System.Runtime.InteropServices.JavaScript @ 8.0.14 (/app/System.Runtime.InteropServices.JavaScript.dll)",
|
||||
"System.Runtime.InteropServices.RuntimeInformation @ 8.0.14 (/app/System.Runtime.InteropServices.RuntimeInformation.dll)",
|
||||
"System.Runtime.Intrinsics @ 8.0.14 (/app/System.Runtime.Intrinsics.dll)",
|
||||
"System.Runtime.Loader @ 8.0.14 (/app/System.Runtime.Loader.dll)",
|
||||
"System.Runtime.Numerics @ 8.0.14 (/app/System.Runtime.Numerics.dll)",
|
||||
"System.Runtime.Serialization @ 8.0.14 (/app/System.Runtime.Serialization.dll)",
|
||||
"System.Runtime.Serialization.Formatters @ 8.0.14 (/app/System.Runtime.Serialization.Formatters.dll)",
|
||||
"System.Runtime.Serialization.Json @ 8.0.14 (/app/System.Runtime.Serialization.Json.dll)",
|
||||
"System.Runtime.Serialization.Primitives @ 8.0.14 (/app/System.Runtime.Serialization.Primitives.dll)",
|
||||
"System.Runtime.Serialization.Xml @ 8.0.14 (/app/System.Runtime.Serialization.Xml.dll)",
|
||||
"System.Security @ 8.0.14 (/app/System.Security.dll)",
|
||||
"System.Security.AccessControl @ 8.0.14 (/app/System.Security.AccessControl.dll)",
|
||||
"System.Security.Claims @ 8.0.14 (/app/System.Security.Claims.dll)",
|
||||
"System.Security.Cryptography @ 8.0.14 (/app/System.Security.Cryptography.dll)",
|
||||
"System.Security.Cryptography.Algorithms @ 8.0.14 (/app/System.Security.Cryptography.Algorithms.dll)",
|
||||
"System.Security.Cryptography.Cng @ 8.0.14 (/app/System.Security.Cryptography.Cng.dll)",
|
||||
"System.Security.Cryptography.Csp @ 8.0.14 (/app/System.Security.Cryptography.Csp.dll)",
|
||||
"System.Security.Cryptography.Encoding @ 8.0.14 (/app/System.Security.Cryptography.Encoding.dll)",
|
||||
"System.Security.Cryptography.OpenSsl @ 8.0.14 (/app/System.Security.Cryptography.OpenSsl.dll)",
|
||||
"System.Security.Cryptography.Primitives @ 8.0.14 (/app/System.Security.Cryptography.Primitives.dll)",
|
||||
"System.Security.Cryptography.X509Certificates @ 8.0.14 (/app/System.Security.Cryptography.X509Certificates.dll)",
|
||||
"System.Security.Principal @ 8.0.14 (/app/System.Security.Principal.dll)",
|
||||
"System.Security.Principal.Windows @ 8.0.14 (/app/System.Security.Principal.Windows.dll)",
|
||||
"System.Security.SecureString @ 8.0.14 (/app/System.Security.SecureString.dll)",
|
||||
"System.ServiceModel.Web @ 8.0.14 (/app/System.ServiceModel.Web.dll)",
|
||||
"System.ServiceProcess @ 8.0.14 (/app/System.ServiceProcess.dll)",
|
||||
"System.Text.Encoding @ 8.0.14 (/app/System.Text.Encoding.dll)",
|
||||
"System.Text.Encoding.CodePages @ 8.0.14 (/app/System.Text.Encoding.CodePages.dll)",
|
||||
"System.Text.Encoding.Extensions @ 8.0.14 (/app/System.Text.Encoding.Extensions.dll)",
|
||||
"System.Text.Encodings.Web @ 8.0.14 (/app/System.Text.Encodings.Web.dll)",
|
||||
"System.Text.Json @ 8.0.14 (/app/System.Text.Json.dll)",
|
||||
"System.Text.RegularExpressions @ 8.0.14 (/app/System.Text.RegularExpressions.dll)",
|
||||
"System.Threading @ 8.0.14 (/app/System.Threading.dll)",
|
||||
"System.Threading.Channels @ 8.0.14 (/app/System.Threading.Channels.dll)",
|
||||
"System.Threading.Overlapped @ 8.0.14 (/app/System.Threading.Overlapped.dll)",
|
||||
"System.Threading.Tasks @ 8.0.14 (/app/System.Threading.Tasks.dll)",
|
||||
"System.Threading.Tasks.Dataflow @ 8.0.14 (/app/System.Threading.Tasks.Dataflow.dll)",
|
||||
"System.Threading.Tasks.Extensions @ 8.0.14 (/app/System.Threading.Tasks.Extensions.dll)",
|
||||
"System.Threading.Tasks.Parallel @ 8.0.14 (/app/System.Threading.Tasks.Parallel.dll)",
|
||||
"System.Threading.Thread @ 8.0.14 (/app/System.Threading.Thread.dll)",
|
||||
"System.Threading.ThreadPool @ 8.0.14 (/app/System.Threading.ThreadPool.dll)",
|
||||
"System.Threading.Timer @ 8.0.14 (/app/System.Threading.Timer.dll)",
|
||||
"System.Transactions @ 8.0.14 (/app/System.Transactions.dll)",
|
||||
"System.Transactions.Local @ 8.0.14 (/app/System.Transactions.Local.dll)",
|
||||
"System.ValueTuple @ 8.0.14 (/app/System.ValueTuple.dll)",
|
||||
"System.Web @ 8.0.14 (/app/System.Web.dll)",
|
||||
"System.Web.HttpUtility @ 8.0.14 (/app/System.Web.HttpUtility.dll)",
|
||||
"System.Windows @ 8.0.14 (/app/System.Windows.dll)",
|
||||
"System.Xml @ 8.0.14 (/app/System.Xml.dll)",
|
||||
"System.Xml.Linq @ 8.0.14 (/app/System.Xml.Linq.dll)",
|
||||
"System.Xml.ReaderWriter @ 8.0.14 (/app/System.Xml.ReaderWriter.dll)",
|
||||
"System.Xml.Serialization @ 8.0.14 (/app/System.Xml.Serialization.dll)",
|
||||
"System.Xml.XDocument @ 8.0.14 (/app/System.Xml.XDocument.dll)",
|
||||
"System.Xml.XPath @ 8.0.14 (/app/System.Xml.XPath.dll)",
|
||||
"System.Xml.XPath.XDocument @ 8.0.14 (/app/System.Xml.XPath.XDocument.dll)",
|
||||
"System.Xml.XmlDocument @ 8.0.14 (/app/System.Xml.XmlDocument.dll)",
|
||||
"System.Xml.XmlSerializer @ 8.0.14 (/app/System.Xml.XmlSerializer.dll)",
|
||||
"WindowsBase @ 8.0.14 (/app/WindowsBase.dll)",
|
||||
"mscorlib @ 8.0.14 (/app/mscorlib.dll)",
|
||||
"netstandard @ 8.0.14 (/app/netstandard.dll)",
|
||||
)
|
||||
|
||||
assertAllDepEntriesInEmbeddedExecutable := func(t *testing.T, pkgs []pkg.Package, relationships []artifact.Relationship) {
|
||||
@@ -730,7 +730,10 @@ func TestCataloger(t *testing.T) {
|
||||
if len(p.CPEs) == 0 {
|
||||
continue
|
||||
}
|
||||
assert.Contains(t, p.Name, "Microsoft.NETCore.App")
|
||||
if runtimeFamilyFromName(p.Name) != netRuntimeFamily {
|
||||
continue
|
||||
}
|
||||
assert.Equal(t, runtimeCPEs(p.Name, p.Version), p.CPEs)
|
||||
return
|
||||
}
|
||||
t.Error("expected at least one runtime package with a CPE")
|
||||
@@ -1186,6 +1189,7 @@ func TestCataloger(t *testing.T) {
|
||||
"runtime.linux-x64.Microsoft.NETCore.DotNetHostPolicy @ 2.2.8 (/usr/share/dotnet/shared/Microsoft.NETCore.App/2.2.8/Microsoft.NETCore.App.deps.json)", // a compile target reference
|
||||
},
|
||||
expectedRels: []string{
|
||||
"Microsoft.NETCore.App @ 2.2.8 (/usr/share/dotnet/shared/Microsoft.NETCore.App/2.2.8/Microsoft.NETCore.App.deps.json) [dependency-of] helloworld @ 1.0.0 (/app/helloworld.deps.json)",
|
||||
"Microsoft.NETCore.DotNetHostPolicy @ 2.2.8 (/usr/share/dotnet/shared/Microsoft.NETCore.App/2.2.8/Microsoft.NETCore.App.deps.json) [dependency-of] Microsoft.NETCore.App @ 2.2.8 (/usr/share/dotnet/shared/Microsoft.NETCore.App/2.2.8/Microsoft.NETCore.App.deps.json)",
|
||||
"Serilog @ 2.10.0 (/app/helloworld.deps.json) [dependency-of] Serilog.Sinks.Console @ 4.0.1 (/app/helloworld.deps.json)",
|
||||
"Serilog @ 2.10.0 (/app/helloworld.deps.json) [dependency-of] helloworld @ 1.0.0 (/app/helloworld.deps.json)",
|
||||
|
||||
@@ -108,7 +108,7 @@ func (c depsBinaryCataloger) Catalog(_ context.Context, resolver file.Resolver)
|
||||
Name: "Microsoft.NETCore.App",
|
||||
Version: version,
|
||||
Type: pkg.DotnetPkg,
|
||||
CPEs: runtimeCPEs(version),
|
||||
CPEs: runtimeCPEs("Microsoft.NETCore.App", version),
|
||||
Locations: file.NewLocationSet(locs...),
|
||||
}
|
||||
pkgs = append(pkgs, rtp)
|
||||
|
||||
@@ -22,6 +22,14 @@ var (
|
||||
versionPunctuationRegex = regexp.MustCompile(`[.,]+`)
|
||||
)
|
||||
|
||||
type runtimeFamily string
|
||||
|
||||
const (
|
||||
unknownRuntimeFamily runtimeFamily = ""
|
||||
netRuntimeFamily runtimeFamily = "net"
|
||||
aspNetCoreRuntimeFamily runtimeFamily = "aspnet_core"
|
||||
)
|
||||
|
||||
// newDotnetDepsPackage creates a new Dotnet dependency package from a logicalDepsJSONPackage.
|
||||
// Note that the new logicalDepsJSONPackage now directly holds library and executable information.
|
||||
func newDotnetDepsPackage(lp logicalDepsJSONPackage, depsLocation file.Location) *pkg.Package {
|
||||
@@ -36,7 +44,7 @@ func newDotnetDepsPackage(lp logicalDepsJSONPackage, depsLocation file.Location)
|
||||
|
||||
var cpes []cpe.CPE
|
||||
if isRuntime(name) {
|
||||
cpes = runtimeCPEs(ver)
|
||||
cpes = runtimeCPEs(name, ver)
|
||||
}
|
||||
|
||||
p := &pkg.Package{
|
||||
@@ -56,52 +64,68 @@ func newDotnetDepsPackage(lp logicalDepsJSONPackage, depsLocation file.Location)
|
||||
}
|
||||
|
||||
func isRuntime(name string) bool {
|
||||
// found in a self-contained net8 app in the deps.json for the application
|
||||
selfContainedRuntimeDependency := strings.HasPrefix(name, "runtimepack.Microsoft.NETCore.App.Runtime")
|
||||
// found in net8 apps in the deps.json for the runtime
|
||||
explicitRuntimeDependency := strings.HasPrefix(name, "Microsoft.NETCore.App.Runtime")
|
||||
// found in net2 apps in the deps.json for the runtime
|
||||
producesARuntime := strings.HasPrefix(name, "runtime") && strings.HasSuffix(name, "Microsoft.NETCore.App")
|
||||
return selfContainedRuntimeDependency || explicitRuntimeDependency || producesARuntime
|
||||
return runtimeFamilyFromName(name) != unknownRuntimeFamily
|
||||
}
|
||||
|
||||
func runtimeCPEs(ver string) []cpe.CPE {
|
||||
// .NET Core Versions
|
||||
// 2016: .NET Core 1.0, cpe:2.3:a:microsoft:dotnet_core:1.0:*:*:*:*:*:*:*
|
||||
// 2016: .NET Core 1.1, cpe:2.3:a:microsoft:dotnet_core:1.1:*:*:*:*:*:*:*
|
||||
// 2017: .NET Core 2.0, cpe:2.3:a:microsoft:dotnet_core:2.0:*:*:*:*:*:*:*
|
||||
// 2018: .NET Core 2.1, cpe:2.3:a:microsoft:dotnet_core:2.1:*:*:*:*:*:*:*
|
||||
// 2018: .NET Core 2.2, cpe:2.3:a:microsoft:dotnet_core:2.2:*:*:*:*:*:*:*
|
||||
// 2019: .NET Core 3.0, cpe:2.3:a:microsoft:dotnet_core:3.0:*:*:*:*:*:*:*
|
||||
// 2019: .NET Core 3.1, cpe:2.3:a:microsoft:dotnet_core:3.1:*:*:*:*:*:*:*
|
||||
func runtimeFamilyFromName(name string) runtimeFamily {
|
||||
normalizedName := strings.ToLower(name)
|
||||
|
||||
// Unified .NET Versions
|
||||
// 2020: .NET 5.0, cpe:2.3:a:microsoft:dotnet:5.0:*:*:*:*:*:*:*
|
||||
// 2021: .NET 6.0, cpe:2.3:a:microsoft:dotnet:6.0:*:*:*:*:*:*:*
|
||||
// 2022: .NET 7.0, cpe:2.3:a:microsoft:dotnet:7.0:*:*:*:*:*:*:*
|
||||
// 2023: .NET 8.0, cpe:2.3:a:microsoft:dotnet:8.0:*:*:*:*:*:*:*
|
||||
// 2024: .NET 9.0, cpe:2.3:a:microsoft:dotnet:9.0:*:*:*:*:*:*:*
|
||||
// 2025 ...?
|
||||
// found in self-contained or framework-dependent apps in deps.json entries
|
||||
if strings.HasPrefix(normalizedName, "runtimepack.microsoft.aspnetcore.app.runtime") ||
|
||||
strings.HasPrefix(normalizedName, "microsoft.aspnetcore.app.runtime") ||
|
||||
normalizedName == "microsoft.aspnetcore.app" ||
|
||||
(strings.HasPrefix(normalizedName, "runtime") && strings.HasSuffix(normalizedName, "microsoft.aspnetcore.app")) {
|
||||
return aspNetCoreRuntimeFamily
|
||||
}
|
||||
|
||||
fields := strings.Split(ver, ".")
|
||||
majorVersion, err := strconv.Atoi(fields[0])
|
||||
if err != nil {
|
||||
log.WithFields("error", err).Tracef("failed to parse .NET major version from %q", ver)
|
||||
// found in self-contained, framework-dependent, and synthesized runtime packages
|
||||
if strings.HasPrefix(normalizedName, "runtimepack.microsoft.netcore.app.runtime") ||
|
||||
strings.HasPrefix(normalizedName, "microsoft.netcore.app.runtime") ||
|
||||
normalizedName == "microsoft.netcore.app" ||
|
||||
(strings.HasPrefix(normalizedName, "runtime") && strings.HasSuffix(normalizedName, "microsoft.netcore.app")) {
|
||||
return netRuntimeFamily
|
||||
}
|
||||
|
||||
return unknownRuntimeFamily
|
||||
}
|
||||
|
||||
func runtimeCPEs(name, ver string) []cpe.CPE {
|
||||
family := runtimeFamilyFromName(name)
|
||||
if family == unknownRuntimeFamily {
|
||||
return nil
|
||||
}
|
||||
|
||||
var minorVersion int
|
||||
if len(fields) > 1 {
|
||||
minorVersion, err = strconv.Atoi(fields[1])
|
||||
if err != nil {
|
||||
log.WithFields("error", err).Tracef("failed to parse .NET minor version from %q", ver)
|
||||
return nil
|
||||
}
|
||||
fields := strings.Split(ver, ".")
|
||||
if len(fields) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
productName := "dotnet"
|
||||
if majorVersion < 5 {
|
||||
productName = "dotnet_core"
|
||||
normalizedVersionFields := make([]string, 0, len(fields))
|
||||
majorVersion, err := strconv.Atoi(fields[0])
|
||||
if err != nil {
|
||||
log.WithFields("error", err).Tracef("failed to parse .NET runtime major version from %q", ver)
|
||||
return nil
|
||||
}
|
||||
normalizedVersionFields = append(normalizedVersionFields, strconv.Itoa(majorVersion))
|
||||
|
||||
for _, field := range fields[1:] {
|
||||
value, err := strconv.Atoi(field)
|
||||
if err != nil {
|
||||
log.WithFields("error", err).Tracef("failed to parse .NET runtime version component %q from %q", field, ver)
|
||||
return nil
|
||||
}
|
||||
normalizedVersionFields = append(normalizedVersionFields, strconv.Itoa(value))
|
||||
}
|
||||
|
||||
if len(normalizedVersionFields) == 1 {
|
||||
normalizedVersionFields = append(normalizedVersionFields, "0")
|
||||
}
|
||||
|
||||
productName := ".net"
|
||||
if family == aspNetCoreRuntimeFamily {
|
||||
productName = "asp.net_core"
|
||||
} else if majorVersion < 5 {
|
||||
productName = ".net_core"
|
||||
}
|
||||
|
||||
return []cpe.CPE{
|
||||
@@ -110,7 +134,7 @@ func runtimeCPEs(ver string) []cpe.CPE {
|
||||
Part: "a",
|
||||
Vendor: "microsoft",
|
||||
Product: productName,
|
||||
Version: fmt.Sprintf("%d.%d", majorVersion, minorVersion),
|
||||
Version: strings.Join(normalizedVersionFields, "."),
|
||||
},
|
||||
// we didn't find this in the underlying material, but this is the convention in NVD and we are certain this is a runtime package
|
||||
Source: cpe.DeclaredSource,
|
||||
@@ -323,6 +347,13 @@ func findVersionFromVersionResources(versionResources map[string]string) string
|
||||
productVersion := extractVersionFromResourcesValue(versionResources["ProductVersion"])
|
||||
fileVersion := extractVersionFromResourcesValue(versionResources["FileVersion"])
|
||||
|
||||
// ms file ver is a ci build stamp (major.minor.<buildfate>.<buildyime>) we'll match with fewer segments
|
||||
if isMicrosoftVersionResource(versionResources) {
|
||||
if v := preferShorterMajorMinorMatch(productVersion, fileVersion); v != "" {
|
||||
return v
|
||||
}
|
||||
}
|
||||
|
||||
semanticVersionCompareResult := keepGreaterSemanticVersion(productVersion, fileVersion)
|
||||
if semanticVersionCompareResult != "" {
|
||||
return semanticVersionCompareResult
|
||||
@@ -363,6 +394,33 @@ func extractVersionFromResourcesValue(version string) string {
|
||||
return out
|
||||
}
|
||||
|
||||
// preferShorterMajorMinorMatch returns productVersion when it shares major.minor
|
||||
// with fileversion and has fewer segments "" otherwise
|
||||
func preferShorterMajorMinorMatch(productVersion, fileVersion string) string {
|
||||
semanticProductVersion, err := version.NewVersion(productVersion)
|
||||
if err != nil || semanticProductVersion == nil {
|
||||
return ""
|
||||
}
|
||||
semanticFileVersion, err := version.NewVersion(fileVersion)
|
||||
if err != nil || semanticFileVersion == nil {
|
||||
return ""
|
||||
}
|
||||
productSegments := semanticProductVersion.Segments()
|
||||
fileSegments := semanticFileVersion.Segments()
|
||||
if len(productSegments) < 2 || len(fileSegments) < 2 {
|
||||
return ""
|
||||
}
|
||||
if productSegments[0] != fileSegments[0] || productSegments[1] != fileSegments[1] {
|
||||
return ""
|
||||
}
|
||||
if len(productSegments) >= len(fileSegments) {
|
||||
return ""
|
||||
}
|
||||
// 1.0.7+sha -> 1.0.7
|
||||
v, _, _ := strings.Cut(productVersion, "+")
|
||||
return v
|
||||
}
|
||||
|
||||
func keepGreaterSemanticVersion(productVersion string, fileVersion string) string {
|
||||
semanticProductVersion, err := version.NewVersion(productVersion)
|
||||
if err != nil || semanticProductVersion == nil {
|
||||
|
||||
@@ -46,6 +46,56 @@ func Test_getDepsJSONFilePrefix(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func Test_newDotnetDepsPackage_AssignsRuntimeCPEs(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
nameVersion string
|
||||
expected []cpe.CPE
|
||||
}{
|
||||
{
|
||||
name: ".NET runtime package",
|
||||
nameVersion: "runtimepack.Microsoft.NETCore.App.Runtime.win-x64/10.0.4",
|
||||
expected: []cpe.CPE{
|
||||
{
|
||||
Attributes: cpe.Attributes{
|
||||
Part: "a",
|
||||
Vendor: "microsoft",
|
||||
Product: ".net",
|
||||
Version: "10.0.4",
|
||||
},
|
||||
Source: cpe.DeclaredSource,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "ASP.NET Core runtime package",
|
||||
nameVersion: "runtimepack.Microsoft.AspNetCore.App.Runtime.win-x64/10.0.4",
|
||||
expected: []cpe.CPE{
|
||||
{
|
||||
Attributes: cpe.Attributes{
|
||||
Part: "a",
|
||||
Vendor: "microsoft",
|
||||
Product: "asp.net_core",
|
||||
Version: "10.0.4",
|
||||
},
|
||||
Source: cpe.DeclaredSource,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range tests {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
actual := newDotnetDepsPackage(
|
||||
logicalDepsJSONPackage{NameVersion: tc.nameVersion},
|
||||
file.NewLocation("/app/test.deps.json"),
|
||||
)
|
||||
|
||||
assert.Equal(t, tc.expected, actual.CPEs)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func Test_NewDotnetBinaryPackage(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
@@ -302,6 +352,24 @@ func Test_NewDotnetBinaryPackage(t *testing.T) {
|
||||
Version: "3.0.0.0",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Microsoft assembly with CI-stamped FileVersion prefers ProductVersion",
|
||||
versionResources: map[string]string{
|
||||
"CompanyName": "Microsoft Corporation",
|
||||
"ProductName": "Microsoft ASP.NET Core",
|
||||
"FileVersion": "10.0.726.21808",
|
||||
"ProductVersion": "10.0.7+b16286c2284fecf303dbc12a0bb152476d662e44",
|
||||
},
|
||||
expectedPackage: pkg.Package{
|
||||
Name: "Microsoft ASP.NET Core",
|
||||
Version: "10.0.7",
|
||||
Metadata: pkg.DotnetPortableExecutableEntry{
|
||||
CompanyName: "Microsoft Corporation",
|
||||
ProductName: "Microsoft ASP.NET Core",
|
||||
ProductVersion: "10.0.7+b16286c2284fecf303dbc12a0bb152476d662e44",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range tests {
|
||||
@@ -382,19 +450,21 @@ func Test_spaceNormalize(t *testing.T) {
|
||||
|
||||
func TestRuntimeCPEs(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
version string
|
||||
expected []cpe.CPE
|
||||
name string
|
||||
packageName string
|
||||
version string
|
||||
expected []cpe.CPE
|
||||
}{
|
||||
{
|
||||
name: ".NET Core 1.0",
|
||||
version: "1.0",
|
||||
name: ".NET Core 1.0",
|
||||
packageName: "Microsoft.NETCore.App",
|
||||
version: "1.0",
|
||||
expected: []cpe.CPE{
|
||||
{
|
||||
Attributes: cpe.Attributes{
|
||||
Part: "a",
|
||||
Vendor: "microsoft",
|
||||
Product: "dotnet_core",
|
||||
Product: ".net_core",
|
||||
Version: "1.0",
|
||||
},
|
||||
Source: cpe.DeclaredSource,
|
||||
@@ -402,14 +472,15 @@ func TestRuntimeCPEs(t *testing.T) {
|
||||
},
|
||||
},
|
||||
{
|
||||
name: ".NET Core 2.1",
|
||||
version: "2.1",
|
||||
name: ".NET Core 2.1",
|
||||
packageName: "Microsoft.NETCore.App",
|
||||
version: "2.1",
|
||||
expected: []cpe.CPE{
|
||||
{
|
||||
Attributes: cpe.Attributes{
|
||||
Part: "a",
|
||||
Vendor: "microsoft",
|
||||
Product: "dotnet_core",
|
||||
Product: ".net_core",
|
||||
Version: "2.1",
|
||||
},
|
||||
Source: cpe.DeclaredSource,
|
||||
@@ -417,14 +488,15 @@ func TestRuntimeCPEs(t *testing.T) {
|
||||
},
|
||||
},
|
||||
{
|
||||
name: ".NET Core 3.1",
|
||||
version: "3.1",
|
||||
name: ".NET Core 3.1",
|
||||
packageName: "Microsoft.NETCore.App",
|
||||
version: "3.1",
|
||||
expected: []cpe.CPE{
|
||||
{
|
||||
Attributes: cpe.Attributes{
|
||||
Part: "a",
|
||||
Vendor: "microsoft",
|
||||
Product: "dotnet_core",
|
||||
Product: ".net_core",
|
||||
Version: "3.1",
|
||||
},
|
||||
Source: cpe.DeclaredSource,
|
||||
@@ -432,14 +504,15 @@ func TestRuntimeCPEs(t *testing.T) {
|
||||
},
|
||||
},
|
||||
{
|
||||
name: ".NET Core 4.9 (hypothetical)",
|
||||
version: "4.9",
|
||||
name: ".NET Core 4.9 (hypothetical)",
|
||||
packageName: "Microsoft.NETCore.App",
|
||||
version: "4.9",
|
||||
expected: []cpe.CPE{
|
||||
{
|
||||
Attributes: cpe.Attributes{
|
||||
Part: "a",
|
||||
Vendor: "microsoft",
|
||||
Product: "dotnet_core",
|
||||
Product: ".net_core",
|
||||
Version: "4.9",
|
||||
},
|
||||
Source: cpe.DeclaredSource,
|
||||
@@ -447,14 +520,15 @@ func TestRuntimeCPEs(t *testing.T) {
|
||||
},
|
||||
},
|
||||
{
|
||||
name: ".NET 5.0",
|
||||
version: "5.0",
|
||||
name: ".NET 5.0",
|
||||
packageName: "Microsoft.NETCore.App",
|
||||
version: "5.0",
|
||||
expected: []cpe.CPE{
|
||||
{
|
||||
Attributes: cpe.Attributes{
|
||||
Part: "a",
|
||||
Vendor: "microsoft",
|
||||
Product: "dotnet",
|
||||
Product: ".net",
|
||||
Version: "5.0",
|
||||
},
|
||||
Source: cpe.DeclaredSource,
|
||||
@@ -462,14 +536,15 @@ func TestRuntimeCPEs(t *testing.T) {
|
||||
},
|
||||
},
|
||||
{
|
||||
name: ".NET 6.0",
|
||||
version: "6.0",
|
||||
name: ".NET 6.0",
|
||||
packageName: "Microsoft.NETCore.App",
|
||||
version: "6.0",
|
||||
expected: []cpe.CPE{
|
||||
{
|
||||
Attributes: cpe.Attributes{
|
||||
Part: "a",
|
||||
Vendor: "microsoft",
|
||||
Product: "dotnet",
|
||||
Product: ".net",
|
||||
Version: "6.0",
|
||||
},
|
||||
Source: cpe.DeclaredSource,
|
||||
@@ -477,14 +552,15 @@ func TestRuntimeCPEs(t *testing.T) {
|
||||
},
|
||||
},
|
||||
{
|
||||
name: ".NET 8.0",
|
||||
version: "8.0",
|
||||
name: ".NET 8.0",
|
||||
packageName: "Microsoft.NETCore.App",
|
||||
version: "8.0",
|
||||
expected: []cpe.CPE{
|
||||
{
|
||||
Attributes: cpe.Attributes{
|
||||
Part: "a",
|
||||
Vendor: "microsoft",
|
||||
Product: "dotnet",
|
||||
Product: ".net",
|
||||
Version: "8.0",
|
||||
},
|
||||
Source: cpe.DeclaredSource,
|
||||
@@ -492,14 +568,15 @@ func TestRuntimeCPEs(t *testing.T) {
|
||||
},
|
||||
},
|
||||
{
|
||||
name: ".NET 10.0 (future version)",
|
||||
version: "10.0",
|
||||
name: ".NET 10.0 (future version)",
|
||||
packageName: "Microsoft.NETCore.App",
|
||||
version: "10.0",
|
||||
expected: []cpe.CPE{
|
||||
{
|
||||
Attributes: cpe.Attributes{
|
||||
Part: "a",
|
||||
Vendor: "microsoft",
|
||||
Product: "dotnet",
|
||||
Product: ".net",
|
||||
Version: "10.0",
|
||||
},
|
||||
Source: cpe.DeclaredSource,
|
||||
@@ -507,14 +584,47 @@ func TestRuntimeCPEs(t *testing.T) {
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Patch version should not be included",
|
||||
version: "6.0.21",
|
||||
name: "Patch version should be preserved",
|
||||
packageName: "Microsoft.NETCore.App",
|
||||
version: "6.0.21",
|
||||
expected: []cpe.CPE{
|
||||
{
|
||||
Attributes: cpe.Attributes{
|
||||
Part: "a",
|
||||
Vendor: "microsoft",
|
||||
Product: "dotnet",
|
||||
Product: ".net",
|
||||
Version: "6.0.21",
|
||||
},
|
||||
Source: cpe.DeclaredSource,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "ASP.NET Core runtime",
|
||||
packageName: "runtimepack.Microsoft.AspNetCore.App.Runtime.win-x64",
|
||||
version: "9.0.10",
|
||||
expected: []cpe.CPE{
|
||||
{
|
||||
Attributes: cpe.Attributes{
|
||||
Part: "a",
|
||||
Vendor: "microsoft",
|
||||
Product: "asp.net_core",
|
||||
Version: "9.0.10",
|
||||
},
|
||||
Source: cpe.DeclaredSource,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Assumed minor version",
|
||||
packageName: "Microsoft.NETCore.App",
|
||||
version: "6",
|
||||
expected: []cpe.CPE{
|
||||
{
|
||||
Attributes: cpe.Attributes{
|
||||
Part: "a",
|
||||
Vendor: "microsoft",
|
||||
Product: ".net",
|
||||
Version: "6.0",
|
||||
},
|
||||
Source: cpe.DeclaredSource,
|
||||
@@ -522,39 +632,26 @@ func TestRuntimeCPEs(t *testing.T) {
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Assumed minor version",
|
||||
version: "6",
|
||||
expected: []cpe.CPE{
|
||||
{
|
||||
Attributes: cpe.Attributes{
|
||||
Part: "a",
|
||||
Vendor: "microsoft",
|
||||
Product: "dotnet",
|
||||
Version: "6.0",
|
||||
},
|
||||
Source: cpe.DeclaredSource,
|
||||
},
|
||||
},
|
||||
name: "Invalid version format",
|
||||
packageName: "Microsoft.NETCore.App",
|
||||
version: "invalid",
|
||||
expected: nil,
|
||||
},
|
||||
{
|
||||
name: "Invalid version format",
|
||||
version: "invalid",
|
||||
expected: nil,
|
||||
},
|
||||
{
|
||||
name: "Empty version",
|
||||
version: "",
|
||||
expected: nil,
|
||||
name: "Empty version",
|
||||
packageName: "Microsoft.NETCore.App",
|
||||
version: "",
|
||||
expected: nil,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range tests {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
result := runtimeCPEs(tc.version)
|
||||
result := runtimeCPEs(tc.packageName, tc.version)
|
||||
|
||||
if !reflect.DeepEqual(result, tc.expected) {
|
||||
t.Errorf("runtimeCPEs(%q) = %+v; want %+v",
|
||||
tc.version, result, tc.expected)
|
||||
t.Errorf("runtimeCPEs(%q, %q) = %+v; want %+v",
|
||||
tc.packageName, tc.version, result, tc.expected)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@@ -120,6 +120,20 @@ func MatchAll(matchers ...EvidenceMatcher) EvidenceMatcher {
|
||||
}
|
||||
}
|
||||
|
||||
// MatchNone succeeds only if the matcher returns no results.
|
||||
func MatchNone(matcher EvidenceMatcher) EvidenceMatcher {
|
||||
return func(classifier Classifier, context MatcherContext) ([]pkg.Package, error) {
|
||||
match, err := matcher(classifier, context)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if match != nil {
|
||||
return nil, nil
|
||||
}
|
||||
return []pkg.Package{}, nil
|
||||
}
|
||||
}
|
||||
|
||||
type ContextualEvidenceMatchers struct {
|
||||
CatalogerName string
|
||||
}
|
||||
|
||||
@@ -243,3 +243,40 @@ func Test_SupportingEvidenceMatcher(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestMatchNone(t *testing.T) {
|
||||
matchingMatcher := MatchPath("**")
|
||||
notMatchingMatcher := MatchPath("will-not-match")
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
matcher EvidenceMatcher
|
||||
expected bool // true if MatchNone should succeed (inner failed)
|
||||
}{
|
||||
{
|
||||
name: "inner matches, MatchNone fails",
|
||||
matcher: MatchNone(matchingMatcher),
|
||||
expected: false,
|
||||
},
|
||||
{
|
||||
name: "inner fails, MatchNone succeeds",
|
||||
matcher: MatchNone(notMatchingMatcher),
|
||||
expected: true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
pkgs, err := tt.matcher(Classifier{}, MatcherContext{
|
||||
Location: file.NewLocation("some/path"),
|
||||
})
|
||||
require.NoError(t, err)
|
||||
if tt.expected {
|
||||
assert.NotNil(t, pkgs)
|
||||
assert.Empty(t, pkgs)
|
||||
} else {
|
||||
assert.Nil(t, pkgs)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -76,6 +76,9 @@
|
||||
"github.com/go-git/go-git": [
|
||||
"cpe:2.3:a:go-git_project:go-git:*:*:*:*:*:go:*:*"
|
||||
],
|
||||
"github.com/go-jose/go-jose/v4#pkg-constants": [
|
||||
"cpe:2.3:a:go-jose_project:go-jose:*:*:*:*:*:*:*:*"
|
||||
],
|
||||
"github.com/go-resty/resty/v2": [
|
||||
"cpe:2.3:a:resty_project:resty:*:*:*:*:*:go:*:*"
|
||||
],
|
||||
@@ -151,6 +154,9 @@
|
||||
"github.com/rezmoss/axios4go": [
|
||||
"cpe:2.3:a:rezmoss:axios4go:*:*:*:*:*:go:*:*"
|
||||
],
|
||||
"github.com/russellhaering/goxmldsig": [
|
||||
"cpe:2.3:a:goxmldsig_project:goxmldsig:*:*:*:*:*:*:*:*"
|
||||
],
|
||||
"github.com/sap/cloud-security-client-go": [
|
||||
"cpe:2.3:a:sap:cloud-security-client-go:*:*:*:*:*:go:*:*"
|
||||
],
|
||||
@@ -160,6 +166,9 @@
|
||||
"github.com/sigstore/gitsign": [
|
||||
"cpe:2.3:a:sigstore:gitsign:*:*:*:*:*:go:*:*"
|
||||
],
|
||||
"github.com/sipeed/picoclaw": [
|
||||
"cpe:2.3:a:sipeed:picoclaw:*:*:*:*:*:go:*:*"
|
||||
],
|
||||
"github.com/sirupsen/logrus": [
|
||||
"cpe:2.3:a:turbopuffer:logrus:*:*:*:*:*:go:*:*"
|
||||
],
|
||||
@@ -169,12 +178,27 @@
|
||||
"github.com/stacklok/minder": [
|
||||
"cpe:2.3:a:lfprojects:minder:*:*:*:*:*:go:*:*"
|
||||
],
|
||||
"github.com/tomwright/dasel": [
|
||||
"cpe:2.3:a:tomwright:dasel:*:*:*:*:*:go:*:*"
|
||||
],
|
||||
"github.com/tomwright/dasel/v2": [
|
||||
"cpe:2.3:a:tomwright:dasel:*:*:*:*:*:go:*:*"
|
||||
],
|
||||
"github.com/tomwright/dasel/v3": [
|
||||
"cpe:2.3:a:tomwright:dasel:*:*:*:*:*:go:*:*"
|
||||
],
|
||||
"github.com/valyala/fasthttp": [
|
||||
"cpe:2.3:a:fasthttp_project:fasthttp:*:*:*:*:*:*:*:*"
|
||||
],
|
||||
"github.com/whilp/git-urls": [
|
||||
"cpe:2.3:a:git-urls_project:git-urls:*:*:*:*:*:go:*:*"
|
||||
],
|
||||
"github.com/yuin/goldmark": [
|
||||
"cpe:2.3:a:yuin:goldmark:*:*:*:*:*:go:*:*"
|
||||
],
|
||||
"go.opentelemetry.io/otel": [
|
||||
"cpe:2.3:a:opentelemetry:opentelemetry:*:*:*:*:*:go:*:*"
|
||||
],
|
||||
"golang.org/x/crypto": [
|
||||
"cpe:2.3:a:go:ssh:*:*:*:*:*:go:*:*"
|
||||
],
|
||||
@@ -2222,6 +2246,9 @@
|
||||
"626": [
|
||||
"cpe:2.3:a:626_project:626:*:*:*:*:*:node.js:*:*"
|
||||
],
|
||||
"@aborruso/ckan-mcp-server": [
|
||||
"cpe:2.3:a:ondata:ckan_mcp_server:*:*:*:*:*:node.js:*:*"
|
||||
],
|
||||
"@actions/artifact": [
|
||||
"cpe:2.3:a:github:actions\\/artifact:*:*:*:*:*:node.js:*:*"
|
||||
],
|
||||
@@ -2248,6 +2275,9 @@
|
||||
"@anthropic-ai/claude-code": [
|
||||
"cpe:2.3:a:anthropic:claude_code:*:*:*:*:*:node.js:*:*"
|
||||
],
|
||||
"@anthropic-ai/sdk": [
|
||||
"cpe:2.3:a:anthropic:claude_sdk_for_typescript:*:*:*:*:*:*:*:*"
|
||||
],
|
||||
"@apollo/gateway": [
|
||||
"cpe:2.3:a:apollographql:apollo_gateway:*:*:*:*:*:node.js:*:*"
|
||||
],
|
||||
@@ -2257,6 +2287,9 @@
|
||||
"@apollosproject/data-connector-rock": [
|
||||
"cpe:2.3:a:apollosapp:data-connector-rock:*:*:*:*:*:node.js:*:*"
|
||||
],
|
||||
"@appium/support": [
|
||||
"cpe:2.3:a:appium:appium\\/support:*:*:*:*:*:node.js:*:*"
|
||||
],
|
||||
"@astrojs/cloudflare": [
|
||||
"cpe:2.3:a:astro:\\@astrojs\\/cloudflare:*:*:*:*:*:node.js:*:*"
|
||||
],
|
||||
@@ -2284,12 +2317,21 @@
|
||||
"@backstage/backend-common": [
|
||||
"cpe:2.3:a:linuxfoundation:backstage_backend-common:*:*:*:*:*:node.js:*:*"
|
||||
],
|
||||
"@backstage/integration": [
|
||||
"cpe:2.3:a:linuxfoundation:backstage\\/integration:*:*:*:*:*:node.js:*:*"
|
||||
],
|
||||
"@backstage/plugin-auth-backend": [
|
||||
"cpe:2.3:a:linuxfoundation:auth_backend:*:*:*:*:*:node.js:*:*"
|
||||
],
|
||||
"@backstage/plugin-scaffolder-backend": [
|
||||
"cpe:2.3:a:linuxfoundation:backstage\\/plugin-scaffolder-backend:*:*:*:*:*:*:*:*"
|
||||
],
|
||||
"@backstage/plugin-techdocs": [
|
||||
"cpe:2.3:a:linuxfoundation:\\@backstage\\/plugin-techdocs:*:*:*:*:*:node.js:*:*"
|
||||
],
|
||||
"@backstage/plugin-techdocs-node": [
|
||||
"cpe:2.3:a:linuxfoundation:backstage_plugin-techdocs-node:*:*:*:*:*:*:*:*"
|
||||
],
|
||||
"@backstage/techdocs-common": [
|
||||
"cpe:2.3:a:linuxfoundation:\\@backstage\\/techdocs-common:*:*:*:*:*:node.js:*:*"
|
||||
],
|
||||
@@ -2350,6 +2392,9 @@
|
||||
"@evershop/evershop": [
|
||||
"cpe:2.3:a:evershop:evershop:*:*:*:*:*:node.js:*:*"
|
||||
],
|
||||
"@fastify/middie": [
|
||||
"cpe:2.3:a:openjsf:\\@fastify\\/middie:*:*:*:*:*:fastify:*:*"
|
||||
],
|
||||
"@fastly/js-compute": [
|
||||
"cpe:2.3:a:fastly:js-compute:*:*:*:*:*:node.js:*:*"
|
||||
],
|
||||
@@ -2365,6 +2410,12 @@
|
||||
"@flourish/sdk": [
|
||||
"cpe:2.3:a:canva:flourish_sdk:*:*:*:*:*:node.js:*:*"
|
||||
],
|
||||
"@frontmcp/adapters": [
|
||||
"cpe:2.3:a:agentfront:\\@frontmcp\\/adapters:*:*:*:*:*:node.js:*:*"
|
||||
],
|
||||
"@frontmcp/sdk": [
|
||||
"cpe:2.3:a:agentfront:\\@frontmcp\\/sdk:*:*:*:*:*:node.js:*:*"
|
||||
],
|
||||
"@github/paste-markdown": [
|
||||
"cpe:2.3:a:paste-markdown_project:paste-markdown:*:*:*:*:*:node.js:*:*"
|
||||
],
|
||||
@@ -2389,6 +2440,9 @@
|
||||
"@joeattardi/emoji-button": [
|
||||
"cpe:2.3:a:emoji_button_project:emoji_button:*:*:*:*:*:node.js:*:*"
|
||||
],
|
||||
"@keystone-6/core": [
|
||||
"cpe:2.3:a:keystonejs:keystone:*:*:*:*:*:node.js:*:*"
|
||||
],
|
||||
"@keystonejs/keystone": [
|
||||
"cpe:2.3:a:keystonejs:keystone:*:*:*:*:*:node.js:*:*"
|
||||
],
|
||||
@@ -2407,6 +2461,9 @@
|
||||
"@misskey-dev/summaly": [
|
||||
"cpe:2.3:a:misskey:summaly:*:*:*:*:*:node.js:*:*"
|
||||
],
|
||||
"@mobilenext/mobile-mcp": [
|
||||
"cpe:2.3:a:mobilenexthq:mobile_mcp:*:*:*:*:*:node.js:*:*"
|
||||
],
|
||||
"@nestjs/core": [
|
||||
"cpe:2.3:a:nestjs:nest:*:*:*:*:*:node.js:*:*"
|
||||
],
|
||||
@@ -2431,6 +2488,12 @@
|
||||
"@octokit/webhooks": [
|
||||
"cpe:2.3:a:octokit:webhooks:*:*:*:*:*:node.js:*:*"
|
||||
],
|
||||
"@openclaw/voice-call": [
|
||||
"cpe:2.3:a:openclaw:openclaw\\/voice-call:*:*:*:*:*:node.js:*:*"
|
||||
],
|
||||
"@opennextjs/cloudflare": [
|
||||
"cpe:2.3:a:opennextjs:opennext_for_cloudflare:*:*:*:*:*:node.js:*:*"
|
||||
],
|
||||
"@openzeppelin/contracts": [
|
||||
"cpe:2.3:a:openzeppelin:contracts:*:*:*:*:*:node.js:*:*"
|
||||
],
|
||||
@@ -2456,6 +2519,9 @@
|
||||
"@rkesters/gnuplot": [
|
||||
"cpe:2.3:a:gnuplot_project:gnuplot:*:*:*:*:*:node.js:*:*"
|
||||
],
|
||||
"@saltcorn/server": [
|
||||
"cpe:2.3:a:saltcorn:saltcorn:*:*:*:*:*:*:*:*"
|
||||
],
|
||||
"@sap/xssec": [
|
||||
"cpe:2.3:a:sap:\\@sap\\/xssec:*:*:*:*:*:node.js:*:*"
|
||||
],
|
||||
@@ -2749,6 +2815,9 @@
|
||||
"box2d-native": [
|
||||
"cpe:2.3:a:box2d-native_project:box2d-native:*:*:*:*:*:node.js:*:*"
|
||||
],
|
||||
"brace-expansion": [
|
||||
"cpe:2.3:a:juliangruber:brace-expansion:*:*:*:*:*:node.js:*:*"
|
||||
],
|
||||
"braces": [
|
||||
"cpe:2.3:a:braces_project:braces:*:*:*:*:*:node.js:*:*",
|
||||
"cpe:2.3:a:jonschlinkert:braces:*:*:*:*:*:node.js:*:*"
|
||||
@@ -2859,6 +2928,9 @@
|
||||
"class-transformer": [
|
||||
"cpe:2.3:a:class-transformer_project:class-transformer:*:*:*:*:*:node.js:*:*"
|
||||
],
|
||||
"clawdbot": [
|
||||
"cpe:2.3:a:openclaw:openclaw:*:*:*:*:*:node.js:*:*"
|
||||
],
|
||||
"cli": [
|
||||
"cpe:2.3:a:cli_project:cli:*:*:*:*:*:node.js:*:*"
|
||||
],
|
||||
@@ -3100,6 +3172,9 @@
|
||||
"defaults-deep": [
|
||||
"cpe:2.3:a:defaults-deep_project:defaults-deep:*:*:*:*:*:node.js:*:*"
|
||||
],
|
||||
"defu": [
|
||||
"cpe:2.3:a:unjs:defu:*:*:*:*:*:node.js:*:*"
|
||||
],
|
||||
"defuddle": [
|
||||
"cpe:2.3:a:kepano:defuddle:*:*:*:*:*:node.js:*:*"
|
||||
],
|
||||
@@ -3182,6 +3257,9 @@
|
||||
"dotty": [
|
||||
"cpe:2.3:a:dotty_project:dotty:*:*:*:*:*:*:*:*"
|
||||
],
|
||||
"drizzle-orm": [
|
||||
"cpe:2.3:a:drizzle:drizzle:*:*:*:*:*:node.js:*:*"
|
||||
],
|
||||
"droppy": [
|
||||
"cpe:2.3:a:droppy_project:droppy:*:*:*:*:*:node.js:*:*"
|
||||
],
|
||||
@@ -3216,7 +3294,8 @@
|
||||
"cpe:2.3:a:adonisjs:edge:*:*:*:*:*:node.js:*:*"
|
||||
],
|
||||
"effect": [
|
||||
"cpe:2.3:a:effect_project:effect:*:*:*:*:*:node.js:*:*"
|
||||
"cpe:2.3:a:effect_project:effect:*:*:*:*:*:node.js:*:*",
|
||||
"cpe:2.3:a:effectful:effect:*:*:*:*:*:node.js:*:*"
|
||||
],
|
||||
"egg-scripts": [
|
||||
"cpe:2.3:a:eggjs:egg-scripts:*:*:*:*:*:node.js:*:*"
|
||||
@@ -4069,6 +4148,9 @@
|
||||
"launchpad": [
|
||||
"cpe:2.3:a:bitovi:launchpad:*:*:*:*:*:node.js:*:*"
|
||||
],
|
||||
"leaflet": [
|
||||
"cpe:2.3:a:leafletjs:leaflet:*:*:*:*:*:node.js:*:*"
|
||||
],
|
||||
"less-openui5": [
|
||||
"cpe:2.3:a:less-openui5_project:less-openui5:*:*:*:*:*:node.js:*:*"
|
||||
],
|
||||
@@ -4147,6 +4229,18 @@
|
||||
"lodash": [
|
||||
"cpe:2.3:a:lodash:lodash:*:*:*:*:*:node.js:*:*"
|
||||
],
|
||||
"lodash-amd": [
|
||||
"cpe:2.3:a:lodash:lodash-amd:*:*:*:*:*:node.js:*:*"
|
||||
],
|
||||
"lodash-es": [
|
||||
"cpe:2.3:a:lodash:lodash-es:*:*:*:*:*:node.js:*:*"
|
||||
],
|
||||
"lodash.template": [
|
||||
"cpe:2.3:a:lodash:lodash.template:*:*:*:*:*:node.js:*:*"
|
||||
],
|
||||
"lodash.unset": [
|
||||
"cpe:2.3:a:lodash:lodash.unset:*:*:*:*:*:node.js:*:*"
|
||||
],
|
||||
"log4js": [
|
||||
"cpe:2.3:a:log4js_project:log4js:*:*:*:*:*:node.js:*:*"
|
||||
],
|
||||
@@ -4235,6 +4329,9 @@
|
||||
"materialize-css": [
|
||||
"cpe:2.3:a:materializecss:materialize:*:*:*:*:*:*:node.js:*"
|
||||
],
|
||||
"mathjs": [
|
||||
"cpe:2.3:a:mathjs:mathjs:*:*:*:*:*:node.js:*:*"
|
||||
],
|
||||
"matrix-appservice-bridge": [
|
||||
"cpe:2.3:a:matrix:matrix-appservice-bridge:*:*:*:*:*:node.js:*:*"
|
||||
],
|
||||
@@ -4377,6 +4474,9 @@
|
||||
"mpath": [
|
||||
"cpe:2.3:a:mpath_project:mpath:*:*:*:*:*:node.js:*:*"
|
||||
],
|
||||
"mppx": [
|
||||
"cpe:2.3:a:wevm:mppx:*:*:*:*:*:node.js:*:*"
|
||||
],
|
||||
"mqtt-packet": [
|
||||
"cpe:2.3:a:mqtt-packet_project:mqtt-packet:*:*:*:*:*:node.js:*:*"
|
||||
],
|
||||
@@ -4443,6 +4543,9 @@
|
||||
"nanoid": [
|
||||
"cpe:2.3:a:nanoid_project:nanoid:*:*:*:*:*:node.js:*:*"
|
||||
],
|
||||
"nanotar": [
|
||||
"cpe:2.3:a:unjs:nanotar:*:*:*:*:*:node.js:*:*"
|
||||
],
|
||||
"napi-postinstall": [
|
||||
"cpe:2.3:a:un-ts:napi-postinstall:*:*:*:*:*:node.js:*:*"
|
||||
],
|
||||
@@ -4739,6 +4842,9 @@
|
||||
"open-graph": [
|
||||
"cpe:2.3:a:open-graph_project:open-graph:*:*:*:*:*:node.js:*:*"
|
||||
],
|
||||
"openclaw": [
|
||||
"cpe:2.3:a:openclaw:openclaw:*:*:*:*:*:node.js:*:*"
|
||||
],
|
||||
"opencv": [
|
||||
"cpe:2.3:a:node-opencv_project:node-opencv:*:*:*:*:*:node.js:*:*"
|
||||
],
|
||||
@@ -4802,6 +4908,9 @@
|
||||
"parsejson": [
|
||||
"cpe:2.3:a:parsejson_project:parsejson:*:*:*:*:*:node.js:*:*"
|
||||
],
|
||||
"parsoid": [
|
||||
"cpe:2.3:a:wikimedia:parsoid:*:*:*:*:*:node.js:*:*"
|
||||
],
|
||||
"passport": [
|
||||
"cpe:2.3:a:passport_project:passport:*:*:*:*:*:node.js:*:*"
|
||||
],
|
||||
@@ -4817,6 +4926,9 @@
|
||||
"path-parse": [
|
||||
"cpe:2.3:a:path-parse_project:path-parse:*:*:*:*:*:node.js:*:*"
|
||||
],
|
||||
"path-to-regexp": [
|
||||
"cpe:2.3:a:pillarjs:path-to-regexp:*:*:*:*:*:node.js:*:*"
|
||||
],
|
||||
"pathval": [
|
||||
"cpe:2.3:a:chaijis:pathval:*:*:*:*:*:node.js:*:*"
|
||||
],
|
||||
@@ -5109,6 +5221,9 @@
|
||||
"robot-js": [
|
||||
"cpe:2.3:a:getrobot:robot-js:*:*:*:*:*:node.js:*:*"
|
||||
],
|
||||
"rollup": [
|
||||
"cpe:2.3:a:rollupjs:rollup:*:*:*:*:*:node.js:*:*"
|
||||
],
|
||||
"rollup-plugin-dev-server": [
|
||||
"cpe:2.3:a:rollup-plugin-dev-server_project:rollup-plugin-dev-server:*:*:*:*:*:node.js:*:*"
|
||||
],
|
||||
@@ -5130,6 +5245,9 @@
|
||||
"rtcmulticonnection-client": [
|
||||
"cpe:2.3:a:rtcmulticonnection-client_project:rtcmulticonnection-client:*:*:*:*:*:node.js:*:*"
|
||||
],
|
||||
"rwsdk": [
|
||||
"cpe:2.3:a:redwoodjs:redwoodsdk:*:*:*:*:*:*:*:*"
|
||||
],
|
||||
"s3-uploader": [
|
||||
"cpe:2.3:a:s3-uploader_project:s3-uploader:*:*:*:*:*:node.js:*:*"
|
||||
],
|
||||
@@ -5381,6 +5499,9 @@
|
||||
"sockjs": [
|
||||
"cpe:2.3:a:sockjs_project:sockjs:*:*:*:*:*:node.js:*:*"
|
||||
],
|
||||
"spin.js": [
|
||||
"cpe:2.3:a:spin.js:spin.js:*:*:*:*:*:node.js:*:*"
|
||||
],
|
||||
"split-html-to-chars": [
|
||||
"cpe:2.3:a:split-html-to-chars_project:split-html-to-chars:*:*:*:*:*:node.js:*:*"
|
||||
],
|
||||
@@ -5702,6 +5823,9 @@
|
||||
"utils-extend": [
|
||||
"cpe:2.3:a:utils-extend_project:utils-extend:*:*:*:*:*:node.js:*:*"
|
||||
],
|
||||
"uuid": [
|
||||
"cpe:2.3:a:uuidjs:uuid:*:*:*:*:*:node.js:*:*"
|
||||
],
|
||||
"uv-tj-demo": [
|
||||
"cpe:2.3:a:uv-tj-demo_project:uv-tj-demo:*:*:*:*:*:node.js:*:*"
|
||||
],
|
||||
@@ -5981,6 +6105,9 @@
|
||||
"Flask-Caching": [
|
||||
"cpe:2.3:a:flask-caching_project:flask-caching:*:*:*:*:*:flask:*:*"
|
||||
],
|
||||
"Flask-HTTPAuth": [
|
||||
"cpe:2.3:a:miguelgrinberg:flask-httpauth:*:*:*:*:*:python:*:*"
|
||||
],
|
||||
"Flask-Security-Too": [
|
||||
"cpe:2.3:a:flask-security-too_project:flask-security-too:*:*:*:*:*:*:*:*"
|
||||
],
|
||||
@@ -6020,6 +6147,9 @@
|
||||
"aiohttp-session": [
|
||||
"cpe:2.3:a:aio-libs:aiohttp_session:*:*:*:*:*:*:*:*"
|
||||
],
|
||||
"ajenti.plugin.core": [
|
||||
"cpe:2.3:a:ajenti:ajenti_plugin_core:*:*:*:*:*:*:*:*"
|
||||
],
|
||||
"aniso8601": [
|
||||
"cpe:2.3:a:aniso8601_project:aniso8601:*:*:*:*:*:*:*:*"
|
||||
],
|
||||
@@ -6068,6 +6198,9 @@
|
||||
"certifi": [
|
||||
"cpe:2.3:a:certifi:certifi:*:*:*:*:*:python:*:*"
|
||||
],
|
||||
"claude-agent-sdk": [
|
||||
"cpe:2.3:a:anthropic:claude_agent_sdk:*:*:*:*:*:python:*:*"
|
||||
],
|
||||
"cleo": [
|
||||
"cpe:2.3:a:python-poetry:cleo:*:*:*:*:*:*:*:*"
|
||||
],
|
||||
@@ -6093,6 +6226,9 @@
|
||||
"cpe:2.3:a:cryptography.io:cryptography:*:*:*:*:*:*:*:*",
|
||||
"cpe:2.3:a:cryptography.io:cryptography:*:*:*:*:*:python:*:*"
|
||||
],
|
||||
"curl-cffi": [
|
||||
"cpe:2.3:a:lexiforest:curl_cffi:*:*:*:*:*:python:*:*"
|
||||
],
|
||||
"cvxopt": [
|
||||
"cpe:2.3:a:cvxopt_project:cvxopt:*:*:*:*:*:python:*:*"
|
||||
],
|
||||
@@ -6126,6 +6262,9 @@
|
||||
"django-user-sessions": [
|
||||
"cpe:2.3:a:django-user-sessions_project:django-user-sessions:*:*:*:*:*:*:*:*"
|
||||
],
|
||||
"docling-core": [
|
||||
"cpe:2.3:a:docling:docling-core:*:*:*:*:*:python:*:*"
|
||||
],
|
||||
"drf-jwt": [
|
||||
"cpe:2.3:a:styria:django-rest-framework-json_web_tokens:*:*:*:*:*:*:*:*"
|
||||
],
|
||||
@@ -6144,6 +6283,9 @@
|
||||
"ecdsa": [
|
||||
"cpe:2.3:a:tlsfuzzer:ecdsa:*:*:*:*:*:python:*:*"
|
||||
],
|
||||
"emmett": [
|
||||
"cpe:2.3:a:emmett:emmett:*:*:*:*:*:*:*:*"
|
||||
],
|
||||
"enum34": [
|
||||
"cpe:2.3:a:python:enum34:*:*:*:*:*:*:*:*"
|
||||
],
|
||||
@@ -6156,6 +6298,9 @@
|
||||
"fastapi-api-key": [
|
||||
"cpe:2.3:a:athroniaeth:fastapi_api_key:*:*:*:*:*:python:*:*"
|
||||
],
|
||||
"fastfeedparser": [
|
||||
"cpe:2.3:a:kagi:fastfeedparser:*:*:*:*:*:python:*:*"
|
||||
],
|
||||
"feedgen": [
|
||||
"cpe:2.3:a:feedgen_project:feedgen:*:*:*:*:*:python:*:*"
|
||||
],
|
||||
@@ -6217,6 +6362,9 @@
|
||||
"jwcrypto": [
|
||||
"cpe:2.3:a:latchset:jwcrypto:*:*:*:*:*:*:*:*"
|
||||
],
|
||||
"kedro": [
|
||||
"cpe:2.3:a:linuxfoundation:kedro:*:*:*:*:*:python:*:*"
|
||||
],
|
||||
"keep": [
|
||||
"cpe:2.3:a:keep_project:keep:*:*:*:*:*:*:*:*"
|
||||
],
|
||||
@@ -6232,9 +6380,15 @@
|
||||
"langchain-experimental": [
|
||||
"cpe:2.3:a:langchain:langchain_experimental:*:*:*:*:*:python:*:*"
|
||||
],
|
||||
"lerobot": [
|
||||
"cpe:2.3:a:huggingface:lerobot:*:*:*:*:*:python:*:*"
|
||||
],
|
||||
"loguru": [
|
||||
"cpe:2.3:a:loguru_project:loguru:*:*:*:*:*:python:*:*"
|
||||
],
|
||||
"lupa": [
|
||||
"cpe:2.3:a:scoder:lupa:*:*:*:*:*:python:*:*"
|
||||
],
|
||||
"lxml": [
|
||||
"cpe:2.3:a:lxml:lxml:*:*:*:*:*:*:*:*"
|
||||
],
|
||||
@@ -6247,6 +6401,12 @@
|
||||
"mage-ai": [
|
||||
"cpe:2.3:a:mage:mage-ai:*:*:*:*:*:python:*:*"
|
||||
],
|
||||
"magic-wormhole": [
|
||||
"cpe:2.3:a:magic_wormhole_project:magic_wormhole:*:*:*:*:*:python:*:*"
|
||||
],
|
||||
"marimo": [
|
||||
"cpe:2.3:a:coreweave:marimo:*:*:*:*:*:python:*:*"
|
||||
],
|
||||
"marshmallow": [
|
||||
"cpe:2.3:a:marshmallow_project:marshmallow:*:*:*:*:*:python:*:*"
|
||||
],
|
||||
@@ -6274,6 +6434,9 @@
|
||||
"oncall": [
|
||||
"cpe:2.3:a:linkedin:oncall:*:*:*:*:*:*:*:*"
|
||||
],
|
||||
"onnx": [
|
||||
"cpe:2.3:a:linuxfoundation:onnx:*:*:*:*:*:*:*:*"
|
||||
],
|
||||
"openapi-python-client": [
|
||||
"cpe:2.3:a:openapi-python-client_project:openapi-python-client:*:*:*:*:*:*:*:*"
|
||||
],
|
||||
@@ -6307,9 +6470,15 @@
|
||||
"pdm": [
|
||||
"cpe:2.3:a:frostming:pdm:*:*:*:*:*:python:*:*"
|
||||
],
|
||||
"picklescan": [
|
||||
"cpe:2.3:a:mmaitre314:picklescan:*:*:*:*:*:*:*:*"
|
||||
],
|
||||
"pillow-heif": [
|
||||
"cpe:2.3:a:bigcat88:pillow-heif:*:*:*:*:*:python:*:*"
|
||||
],
|
||||
"pipecat-ai": [
|
||||
"cpe:2.3:a:pipecat:pipecat:*:*:*:*:*:python:*:*"
|
||||
],
|
||||
"pipreqs": [
|
||||
"cpe:2.3:a:pipreqs_project:pipreqs:*:*:*:*:*:python:*:*"
|
||||
],
|
||||
@@ -6319,6 +6488,9 @@
|
||||
"poetry": [
|
||||
"cpe:2.3:a:python-poetry:poetry:*:*:*:*:*:python:*:*"
|
||||
],
|
||||
"praisonaiagents": [
|
||||
"cpe:2.3:a:praison:praisonaiagents:*:*:*:*:*:python:*:*"
|
||||
],
|
||||
"pretix": [
|
||||
"cpe:2.3:a:rami:pretix:*:*:*:*:*:*:*:*"
|
||||
],
|
||||
@@ -6367,6 +6539,9 @@
|
||||
"pydash": [
|
||||
"cpe:2.3:a:derrickgilland:pydash:*:*:*:*:*:python:*:*"
|
||||
],
|
||||
"pydicom": [
|
||||
"cpe:2.3:a:pydicom:pydicom:*:*:*:*:*:python:*:*"
|
||||
],
|
||||
"pyesasky": [
|
||||
"cpe:2.3:a:esa:pyesasky:*:*:*:*:*:python:*:*"
|
||||
],
|
||||
@@ -6391,6 +6566,9 @@
|
||||
"pypolicyd-spf": [
|
||||
"cpe:2.3:a:pypolicyd-spf_project:pypolicyd-spf:*:*:*:*:*:*:*:*"
|
||||
],
|
||||
"python-dotenv": [
|
||||
"cpe:2.3:a:saurabh-kumar:python-dotenv:*:*:*:*:*:python:*:*"
|
||||
],
|
||||
"python-gnupg": [
|
||||
"cpe:2.3:a:python:python-gnupg:*:*:*:*:*:*:*:*"
|
||||
],
|
||||
@@ -6463,6 +6641,9 @@
|
||||
"setuptools": [
|
||||
"cpe:2.3:a:python:setuptools:*:*:*:*:*:*:*:*"
|
||||
],
|
||||
"sigstore": [
|
||||
"cpe:2.3:a:linuxfoundation:sigstore-python:*:*:*:*:*:*:*:*"
|
||||
],
|
||||
"simiki": [
|
||||
"cpe:2.3:a:simiki_project:simiki:*:*:*:*:*:*:*:*"
|
||||
],
|
||||
@@ -6490,12 +6671,18 @@
|
||||
"starlette": [
|
||||
"cpe:2.3:a:encode:starlette:*:*:*:*:*:python:*:*"
|
||||
],
|
||||
"strawberry-graphql": [
|
||||
"cpe:2.3:a:strawberry:strawberry_graphql:*:*:*:*:*:python:*:*"
|
||||
],
|
||||
"tablib": [
|
||||
"cpe:2.3:a:python:tablib:*:*:*:*:*:*:*:*"
|
||||
],
|
||||
"taguette": [
|
||||
"cpe:2.3:a:taguette:taguette:*:*:*:*:*:*:*:*"
|
||||
],
|
||||
"telnyx": [
|
||||
"cpe:2.3:a:telnyx:telnyx:*:*:*:*:*:python:*:*"
|
||||
],
|
||||
"tkvideoplayer": [
|
||||
"cpe:2.3:a:python:tkvideoplayer:*:*:*:*:*:*:*:*"
|
||||
],
|
||||
@@ -6511,6 +6698,9 @@
|
||||
"unearth": [
|
||||
"cpe:2.3:a:frostming:unearth:*:*:*:*:*:python:*:*"
|
||||
],
|
||||
"unstructured": [
|
||||
"cpe:2.3:a:unstructured:unstructured:*:*:*:*:*:python:*:*"
|
||||
],
|
||||
"untangle": [
|
||||
"cpe:2.3:a:untangle_project:untangle:*:*:*:*:*:python:*:*"
|
||||
],
|
||||
@@ -6585,6 +6775,12 @@
|
||||
"bson": [
|
||||
"cpe:2.3:a:bson_project:bson:*:*:*:*:*:ruby:*:*"
|
||||
],
|
||||
"bsv-sdk": [
|
||||
"cpe:2.3:a:sgbett:bsv_ruby_sdk:*:*:*:*:*:ruby:*:*"
|
||||
],
|
||||
"bsv-wallet": [
|
||||
"cpe:2.3:a:sgbett:bsv-wallet:*:*:*:*:*:ruby:*:*"
|
||||
],
|
||||
"cap-strap": [
|
||||
"cpe:2.3:a:cap-strap_project:cap-strap:*:*:*:*:*:ruby:*:*"
|
||||
],
|
||||
@@ -6718,11 +6914,15 @@
|
||||
"httparty": [
|
||||
"cpe:2.3:a:jnunemaker:httparty:*:*:*:*:*:ruby:*:*"
|
||||
],
|
||||
"icalendar": [
|
||||
"cpe:2.3:a:icalendar_project:icalendar:*:*:*:*:*:ruby:*:*"
|
||||
],
|
||||
"iodine": [
|
||||
"cpe:2.3:a:boazsegev:iodine:*:*:*:*:*:ruby:*:*"
|
||||
],
|
||||
"json": [
|
||||
"cpe:2.3:a:json_project:json:*:*:*:*:*:ruby:*:*"
|
||||
"cpe:2.3:a:json_project:json:*:*:*:*:*:ruby:*:*",
|
||||
"cpe:2.3:a:ruby-lang:json:*:*:*:*:*:ruby:*:*"
|
||||
],
|
||||
"json-jwt": [
|
||||
"cpe:2.3:a:json-jwt_project:json-jwt:*:*:*:*:*:ruby:*:*"
|
||||
@@ -6754,12 +6954,18 @@
|
||||
"lean-ruport": [
|
||||
"cpe:2.3:a:lean-ruport_project:lean-ruport:*:*:*:*:*:ruby:*:*"
|
||||
],
|
||||
"lodash-rails": [
|
||||
"cpe:2.3:a:lodash:lodash-rails:*:*:*:*:*:ruby:*:*"
|
||||
],
|
||||
"loofah": [
|
||||
"cpe:2.3:a:loofah_project:loofah:*:*:*:*:*:ruby:*:*"
|
||||
],
|
||||
"lynx": [
|
||||
"cpe:2.3:a:lynx_project:lynx:*:*:*:*:*:ruby:*:*"
|
||||
],
|
||||
"mcp": [
|
||||
"cpe:2.3:a:lfprojects:mcp_ruby_sdk:*:*:*:*:*:*:*:*"
|
||||
],
|
||||
"mechanize": [
|
||||
"cpe:2.3:a:mechanize_project:mechanize:*:*:*:*:*:ruby:*:*"
|
||||
],
|
||||
@@ -7189,6 +7395,9 @@
|
||||
"containers": [
|
||||
"cpe:2.3:a:containers_project:containers:*:*:*:*:*:rust:*:*"
|
||||
],
|
||||
"coreutils": [
|
||||
"cpe:2.3:a:uutils:coreutils:*:*:*:*:*:rust:*:*"
|
||||
],
|
||||
"cranelift-codegen": [
|
||||
"cpe:2.3:a:bytecodealliance:cranelift-codegen:*:*:*:*:*:rust:*:*"
|
||||
],
|
||||
@@ -7264,6 +7473,9 @@
|
||||
"heapless": [
|
||||
"cpe:2.3:a:heapless_project:heapless:*:*:*:*:*:rust:*:*"
|
||||
],
|
||||
"httpsig-hyper": [
|
||||
"cpe:2.3:a:junkurihara:httpsig-hyper:*:*:*:*:*:rust:*:*"
|
||||
],
|
||||
"ic-stable-structures": [
|
||||
"cpe:2.3:a:dfinity:stable_structures:*:*:*:*:*:rust:*:*"
|
||||
],
|
||||
@@ -7309,6 +7521,9 @@
|
||||
"libp2p-deflate": [
|
||||
"cpe:2.3:a:libp2p:libp2p-deflate:*:*:*:*:*:rust:*:*"
|
||||
],
|
||||
"libp2p-gossipsub": [
|
||||
"cpe:2.3:a:protocol:libp2p-gossipsub:*:*:*:*:*:rust:*:*"
|
||||
],
|
||||
"libpulse-binding": [
|
||||
"cpe:2.3:a:libpulse-binding_project:libpulse-binding:*:*:*:*:*:rust:*:*"
|
||||
],
|
||||
@@ -7339,6 +7554,9 @@
|
||||
"lucet-runtime-internals": [
|
||||
"cpe:2.3:a:lucet-runtime-internals_project:lucet-runtime-internals:*:*:*:*:*:rust:*:*"
|
||||
],
|
||||
"lz4_flex": [
|
||||
"cpe:2.3:a:pseitz:lz4_flex:*:*:*:*:*:rust:*:*"
|
||||
],
|
||||
"magnetic": [
|
||||
"cpe:2.3:a:magnetic_project:magnetic:*:*:*:*:*:rust:*:*"
|
||||
],
|
||||
@@ -7480,6 +7698,9 @@
|
||||
"simple_asn1": [
|
||||
"cpe:2.3:a:simple_asn1_project:simple_asn1:*:*:*:*:*:rust:*:*"
|
||||
],
|
||||
"skim": [
|
||||
"cpe:2.3:a:skim-rs:skim:*:*:*:*:*:rust:*:*"
|
||||
],
|
||||
"slack_morphism": [
|
||||
"cpe:2.3:a:slack_morphism_project:slack_morphism:*:*:*:*:*:rust:*:*"
|
||||
],
|
||||
@@ -7606,6 +7827,18 @@
|
||||
"zebra-consensus": [
|
||||
"cpe:2.3:a:zfnd:zebra-consensus:*:*:*:*:*:rust:*:*"
|
||||
],
|
||||
"zebra-rpc": [
|
||||
"cpe:2.3:a:zfnd:zebra-rpc:*:*:*:*:*:rust:*:*"
|
||||
],
|
||||
"zebra-script": [
|
||||
"cpe:2.3:a:zfnd:zebra-script:*:*:*:*:*:rust:*:*"
|
||||
],
|
||||
"zebrad": [
|
||||
"cpe:2.3:a:zfnd:zebrad:*:*:*:*:*:rust:*:*"
|
||||
],
|
||||
"zeptoclaw": [
|
||||
"cpe:2.3:a:zeptoclaw:zeptoclaw:*:*:*:*:*:rust:*:*"
|
||||
],
|
||||
"zeroize_derive": [
|
||||
"cpe:2.3:a:zeroize_derive_project:zeroize_derive:*:*:*:*:*:rust:*:*"
|
||||
]
|
||||
@@ -12356,6 +12589,9 @@
|
||||
"friends": [
|
||||
"cpe:2.3:a:alex.kirk:friends:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"front-end-editor": [
|
||||
"cpe:2.3:a:scribu:front-end_editor:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"front-end-only-users": [
|
||||
"cpe:2.3:a:etoilewebdesign:front_end_users:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -14098,6 +14334,10 @@
|
||||
"link-to-bible": [
|
||||
"cpe:2.3:a:bibleserver:link_to_bible:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"link-whisper": [
|
||||
"cpe:2.3:a:linkwhisper:link_whisper:*:*:*:*:*:wordpress:*:*",
|
||||
"cpe:2.3:a:linkwhisper:link_whisper:*:*:*:*:free:wordpress:*:*"
|
||||
],
|
||||
"linked-variation": [
|
||||
"cpe:2.3:a:multidots:advanced_linked_variations_for_woocommerce:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -17243,6 +17483,9 @@
|
||||
"sexy-contact-form": [
|
||||
"cpe:2.3:a:creative-solutions:creative_contact_form:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"sg-cachepress": [
|
||||
"cpe:2.3:a:siteground:speed_optimizer:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"sg-security": [
|
||||
"cpe:2.3:a:siteground:security_optimizer:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -18171,6 +18414,9 @@
|
||||
"sprout-invoices": [
|
||||
"cpe:2.3:a:webventures:client_invoicing_by_sprout_invoices:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"sql-chart-builder": [
|
||||
"cpe:2.3:a:guaven:sql_chart_builder:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"squeeze": [
|
||||
"cpe:2.3:a:squeeze_project:squeeze:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -21864,6 +22110,9 @@
|
||||
"wpshopgermany-protectedshops": [
|
||||
"cpe:2.3:a:maennchen1:wpshopgermany_-_protected_shops:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"wpshopify": [
|
||||
"cpe:2.3:a:shopwp_project:shopwp:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"wpsimpletools-log-viewer": [
|
||||
"cpe:2.3:a:wpsimpletools:basic_log_viewer:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
|
||||
@@ -6,9 +6,7 @@ import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"maps"
|
||||
"regexp"
|
||||
"slices"
|
||||
"strings"
|
||||
|
||||
"github.com/goccy/go-yaml"
|
||||
@@ -25,6 +23,11 @@ import (
|
||||
)
|
||||
|
||||
var (
|
||||
// packageAliasExp matches aliased yarn dependencies and captures the
|
||||
// underlying npm package name instead of the local alias.
|
||||
// For example: "old-async@npm:async@0.9.2" returns "async".
|
||||
packageAliasExp = regexp.MustCompile(`^"?(?:@\w[\w-_.]*\/)?\w[\w-_.]*@npm:((?:@\w[\w-_.]*\/)?\w[\w-_.]*)@`)
|
||||
|
||||
// packageNameExp matches the name of the dependency in yarn.lock
|
||||
// including scope/namespace prefix if found.
|
||||
// For example: "aws-sdk@2.706.0" returns "aws-sdk"
|
||||
@@ -245,7 +248,9 @@ func parseYarnLockYaml(reader io.ReadCloser) ([]yarnPackage, error) {
|
||||
return nil, fmt.Errorf("failed to unmarshal yarn v2 lockfile: %w", err)
|
||||
}
|
||||
|
||||
packages := make(map[string]yarnPackage)
|
||||
var seenPkgs = strset.New()
|
||||
|
||||
pkgs := []yarnPackage{}
|
||||
for key, value := range lockfile {
|
||||
packageName := findPackageName(key)
|
||||
if packageName == "" {
|
||||
@@ -253,10 +258,16 @@ func parseYarnLockYaml(reader io.ReadCloser) ([]yarnPackage, error) {
|
||||
continue
|
||||
}
|
||||
|
||||
packages[packageName] = yarnPackage{Name: packageName, Version: value.Version, Resolved: value.Resolution, Integrity: value.Checksum, Dependencies: value.Dependencies}
|
||||
var pkg = yarnPackage{Name: packageName, Version: value.Version, Resolved: value.Resolution, Integrity: value.Checksum, Dependencies: value.Dependencies}
|
||||
var nameVersion = pkg.Name + "@" + pkg.Version
|
||||
|
||||
if !seenPkgs.Has(nameVersion) {
|
||||
seenPkgs.Add(nameVersion)
|
||||
pkgs = append(pkgs, pkg)
|
||||
}
|
||||
}
|
||||
|
||||
return slices.Collect(maps.Values(packages)), nil
|
||||
return pkgs, nil
|
||||
}
|
||||
|
||||
func (a genericYarnLockAdapter) parseYarnLock(ctx context.Context, resolver file.Resolver, _ *generic.Environment, reader file.LocationReadCloser) ([]pkg.Package, []artifact.Relationship, error) {
|
||||
@@ -305,6 +316,9 @@ func (a genericYarnLockAdapter) parseYarnLock(ctx context.Context, resolver file
|
||||
}
|
||||
|
||||
func findPackageName(line string) string {
|
||||
if matches := packageAliasExp.FindStringSubmatch(line); len(matches) >= 2 {
|
||||
return matches[1]
|
||||
}
|
||||
if matches := packageNameExp.FindStringSubmatch(line); len(matches) >= 2 {
|
||||
return matches[1]
|
||||
}
|
||||
|
||||
@@ -204,6 +204,42 @@ func TestParseYarnBerry(t *testing.T) {
|
||||
pkgtest.TestFileParser(t, fixture, adapter.parseYarnLock, expectedPkgs, expectedRelationships)
|
||||
}
|
||||
|
||||
func TestParseYarnBerryWithDuplicates(t *testing.T) {
|
||||
var expectedRelationships []artifact.Relationship
|
||||
fixture := "testdata/yarn-berry-dups/yarn.lock"
|
||||
locations := file.NewLocationSet(file.NewLocation(fixture))
|
||||
|
||||
expectedPkgs := []pkg.Package{
|
||||
{
|
||||
Name: "async",
|
||||
Version: "3.2.6",
|
||||
Locations: locations,
|
||||
PURL: "pkg:npm/async@3.2.6",
|
||||
Language: pkg.JavaScript,
|
||||
Type: pkg.NpmPkg,
|
||||
Metadata: pkg.YarnLockEntry{
|
||||
Resolved: "async@npm:3.2.6",
|
||||
Integrity: "10c0/36484bb15ceddf07078688d95e27076379cc2f87b10c03b6dd8a83e89475a3c8df5848859dd06a4c95af1e4c16fc973de0171a77f18ea00be899aca2a4f85e70",
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "async",
|
||||
Version: "0.9.2",
|
||||
Locations: locations,
|
||||
PURL: "pkg:npm/async@0.9.2",
|
||||
Language: pkg.JavaScript,
|
||||
Type: pkg.NpmPkg,
|
||||
Metadata: pkg.YarnLockEntry{
|
||||
Resolved: "async@npm:0.9.2",
|
||||
Integrity: "10c0/22ac816db119a9b84ac7182fa969b2cceacfcfa278c3efb0ac6a94d1210a4429e42c8cf6e704039aa7662e4ba62f26cecf039c91d41ceb91355dc9672c9b9ac1",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
adapter := newGenericYarnLockAdapter(CatalogerConfig{})
|
||||
pkgtest.TestFileParser(t, fixture, adapter.parseYarnLock, expectedPkgs, expectedRelationships)
|
||||
}
|
||||
|
||||
func TestParseYarnLock(t *testing.T) {
|
||||
var expectedRelationships []artifact.Relationship
|
||||
fixture := "testdata/yarn/yarn.lock"
|
||||
@@ -708,6 +744,18 @@ func TestParseYarnFindPackageNames(t *testing.T) {
|
||||
line: `"color-convert@npm:^1.9.0":`,
|
||||
expected: "color-convert",
|
||||
},
|
||||
{
|
||||
line: `"old-async@npm:async@0.9.2":`,
|
||||
expected: "async",
|
||||
},
|
||||
{
|
||||
line: `"old-foo@npm:@scope/foo@1.2.3":`,
|
||||
expected: "@scope/foo",
|
||||
},
|
||||
{
|
||||
line: `"@scope/old-foo@npm:@scope/foo@1.2.3":`,
|
||||
expected: "@scope/foo",
|
||||
},
|
||||
{
|
||||
line: `"@npmcorp/code-frame@^7.1.0", "@npmcorp/code-frame@^7.10.4":`,
|
||||
expected: "@npmcorp/code-frame",
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
# This file is generated by running "yarn install" inside your project.
|
||||
# Manual changes might be lost - proceed with caution!
|
||||
|
||||
__metadata:
|
||||
version: 8
|
||||
cacheKey: 10c0
|
||||
|
||||
"async@npm:^3.2.3":
|
||||
version: 3.2.6
|
||||
resolution: "async@npm:3.2.6"
|
||||
checksum: 10c0/36484bb15ceddf07078688d95e27076379cc2f87b10c03b6dd8a83e89475a3c8df5848859dd06a4c95af1e4c16fc973de0171a77f18ea00be899aca2a4f85e70
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"async@npm:0.9.2":
|
||||
version: 0.9.2
|
||||
resolution: "async@npm:0.9.2"
|
||||
checksum: 10c0/22ac816db119a9b84ac7182fa969b2cceacfcfa278c3efb0ac6a94d1210a4429e42c8cf6e704039aa7662e4ba62f26cecf039c91d41ceb91355dc9672c9b9ac1
|
||||
languageName: node
|
||||
linkType: hard
|
||||
@@ -4,7 +4,7 @@ configs: # AUTO-GENERATED - config structs and their fields
|
||||
kernel.LinuxKernelCatalogerConfig:
|
||||
fields:
|
||||
- key: CatalogModules
|
||||
description: CatalogModules enables cataloging linux kernel modules (`*.ko` files) in addition to the kernel itself.
|
||||
description: CatalogModules enables cataloging linux kernel modules (`*.ko` and compressed `*.ko.gz`, `*.ko.xz`, `*.ko.zst` files) in addition to the kernel itself.
|
||||
app_key: linux-kernel.catalog-modules
|
||||
catalogers:
|
||||
- ecosystem: linux # MANUAL
|
||||
@@ -36,6 +36,9 @@ catalogers:
|
||||
- '**/zImage'
|
||||
- '**/zImage-*'
|
||||
- '**/lib/modules/**/*.ko'
|
||||
- '**/lib/modules/**/*.ko.gz'
|
||||
- '**/lib/modules/**/*.ko.xz'
|
||||
- '**/lib/modules/**/*.ko.zst'
|
||||
metadata_types: # AUTO-GENERATED
|
||||
- pkg.LinuxKernel
|
||||
- pkg.LinuxKernelModule
|
||||
|
||||
@@ -17,7 +17,7 @@ import (
|
||||
var _ pkg.Cataloger = (*linuxKernelCataloger)(nil)
|
||||
|
||||
type LinuxKernelCatalogerConfig struct {
|
||||
// CatalogModules enables cataloging linux kernel modules (`*.ko` files) in addition to the kernel itself.
|
||||
// CatalogModules enables cataloging linux kernel modules (`*.ko` and compressed `*.ko.gz`, `*.ko.xz`, `*.ko.zst` files) in addition to the kernel itself.
|
||||
// app-config: linux-kernel.catalog-modules
|
||||
CatalogModules bool `yaml:"catalog-modules" json:"catalog-modules" mapstructure:"catalog-modules"`
|
||||
}
|
||||
@@ -47,6 +47,9 @@ var kernelArchiveGlobs = []string{
|
||||
|
||||
var kernelModuleGlobs = []string{
|
||||
"**/lib/modules/**/*.ko",
|
||||
"**/lib/modules/**/*.ko.gz",
|
||||
"**/lib/modules/**/*.ko.xz",
|
||||
"**/lib/modules/**/*.ko.zst",
|
||||
}
|
||||
|
||||
// NewLinuxKernelCataloger returns a new kernel files cataloger object.
|
||||
|
||||
@@ -3,9 +3,16 @@ package kernel
|
||||
import (
|
||||
"context"
|
||||
"debug/elf"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/mholt/archives"
|
||||
|
||||
intfile "github.com/anchore/syft/internal/file"
|
||||
"github.com/anchore/syft/internal/tmpdir"
|
||||
"github.com/anchore/syft/syft/artifact"
|
||||
"github.com/anchore/syft/syft/file"
|
||||
"github.com/anchore/syft/syft/internal/unionreader"
|
||||
@@ -20,7 +27,14 @@ func parseLinuxKernelModuleFile(ctx context.Context, _ file.Resolver, _ *generic
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("unable to get union reader for file: %w", err)
|
||||
}
|
||||
metadata, err := parseLinuxKernelModuleMetadata(unionReader)
|
||||
|
||||
moduleReader, err := decompressedModuleReader(ctx, reader.RealPath, unionReader)
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("unable to decompress kernel module %q: %w", reader.RealPath, err)
|
||||
}
|
||||
defer moduleReader.Close()
|
||||
|
||||
metadata, err := parseLinuxKernelModuleMetadata(moduleReader)
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("unable to parse kernel module metadata: %w", err)
|
||||
}
|
||||
@@ -39,6 +53,91 @@ func parseLinuxKernelModuleFile(ctx context.Context, _ file.Resolver, _ *generic
|
||||
}, nil, nil
|
||||
}
|
||||
|
||||
// decompressedModuleReader returns a UnionReader over the decompressed contents of the kernel module
|
||||
// when the path indicates compression (e.g. .ko.gz, .ko.xz, .ko.zst). For plain .ko files the original
|
||||
// reader is returned unchanged. ELF parsing requires random access (io.ReaderAt + io.Seeker), so
|
||||
// compressed streams are spilled to a temp file rather than buffered in memory — kernel modules can be
|
||||
// tens of MB decompressed and large numbers of them are scanned per cataloger run. The caller owns
|
||||
// the returned reader and must Close it; the underlying reader (r) is not closed by Close on the
|
||||
// passthrough path — its lifecycle is the caller's.
|
||||
func decompressedModuleReader(ctx context.Context, path string, r unionreader.UnionReader) (unionreader.UnionReader, error) {
|
||||
// fast path: plain .ko files don't need format sniffing
|
||||
if strings.HasSuffix(path, ".ko") {
|
||||
return &nopCloseUnionReader{UnionReader: r}, nil
|
||||
}
|
||||
|
||||
format, stream, err := intfile.IdentifyArchive(ctx, path, r)
|
||||
if err != nil {
|
||||
if errors.Is(err, archives.NoMatch) {
|
||||
return passthrough(r)
|
||||
}
|
||||
return nil, fmt.Errorf("unable to identify compression format: %w", err)
|
||||
}
|
||||
|
||||
decompressor, ok := format.(archives.Decompressor)
|
||||
if !ok {
|
||||
// not a single-stream compressed format (e.g. a tar/zip archive); treat as a plain .ko
|
||||
return passthrough(r)
|
||||
}
|
||||
|
||||
rc, err := decompressor.OpenReader(stream)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unable to open %s decompression stream: %w", format.Extension(), err)
|
||||
}
|
||||
defer rc.Close()
|
||||
|
||||
td := tmpdir.FromContext(ctx)
|
||||
if td == nil {
|
||||
return nil, fmt.Errorf("no temp dir factory in context")
|
||||
}
|
||||
tempFile, fileCleanup, err := td.NewFile("syft-kmod-*.ko") //nolint:gocritic // cleanup outlives this function — runs from tempFileUnionReader.Close on the returned reader
|
||||
if err != nil {
|
||||
fileCleanup()
|
||||
return nil, fmt.Errorf("unable to create temp file for decompressed kernel module: %w", err)
|
||||
}
|
||||
tfr := &tempFileUnionReader{File: tempFile, cleanup: fileCleanup}
|
||||
|
||||
if _, err := io.Copy(tempFile, rc); err != nil {
|
||||
_ = tfr.Close()
|
||||
return nil, fmt.Errorf("unable to write decompressed kernel module: %w", err)
|
||||
}
|
||||
if _, err := tempFile.Seek(0, io.SeekStart); err != nil {
|
||||
_ = tfr.Close()
|
||||
return nil, fmt.Errorf("unable to rewind decompressed kernel module: %w", err)
|
||||
}
|
||||
|
||||
return tfr, nil
|
||||
}
|
||||
|
||||
// passthrough returns the original reader rewound to offset 0. IdentifyArchive consumes bytes to
|
||||
// sniff magic; we rewind explicitly so callers don't have to reason about the seeker's position.
|
||||
func passthrough(r unionreader.UnionReader) (unionreader.UnionReader, error) {
|
||||
if _, err := r.Seek(0, io.SeekStart); err != nil {
|
||||
return nil, fmt.Errorf("unable to rewind reader after format sniff: %w", err)
|
||||
}
|
||||
return &nopCloseUnionReader{UnionReader: r}, nil
|
||||
}
|
||||
|
||||
// nopCloseUnionReader wraps a UnionReader so that Close is a no-op. used on the passthrough path
|
||||
// where the underlying reader's lifecycle is owned by the caller, not by us.
|
||||
type nopCloseUnionReader struct {
|
||||
unionreader.UnionReader
|
||||
}
|
||||
|
||||
func (*nopCloseUnionReader) Close() error { return nil }
|
||||
|
||||
// tempFileUnionReader is a UnionReader backed by a temp file; Close closes the file and removes it.
|
||||
type tempFileUnionReader struct {
|
||||
*os.File
|
||||
cleanup func()
|
||||
}
|
||||
|
||||
func (t *tempFileUnionReader) Close() error {
|
||||
err := t.File.Close()
|
||||
t.cleanup()
|
||||
return err
|
||||
}
|
||||
|
||||
func parseLinuxKernelModuleMetadata(r unionreader.UnionReader) (p *pkg.LinuxKernelModule, err error) {
|
||||
// filename: /lib/modules/5.15.0-1031-aws/kernel/zfs/zzstd.ko
|
||||
// version: 1.4.5a
|
||||
|
||||
@@ -0,0 +1,285 @@
|
||||
package kernel
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"compress/gzip"
|
||||
"context"
|
||||
"debug/elf"
|
||||
"encoding/binary"
|
||||
"io"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/klauspost/compress/zstd"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"github.com/ulikunitz/xz"
|
||||
|
||||
"github.com/anchore/syft/internal/tmpdir"
|
||||
"github.com/anchore/syft/syft/file"
|
||||
"github.com/anchore/syft/syft/pkg"
|
||||
"github.com/anchore/syft/syft/pkg/cataloger/generic"
|
||||
)
|
||||
|
||||
func testContext(t *testing.T) context.Context {
|
||||
t.Helper()
|
||||
td := tmpdir.FromPath(t.TempDir())
|
||||
return tmpdir.WithValue(context.Background(), td)
|
||||
}
|
||||
|
||||
// minimalKOBytes constructs a minimal ELF64 LE relocatable object with a .modinfo
|
||||
// section containing the given null-terminated key=value entries.
|
||||
func minimalKOBytes(entries []string) []byte {
|
||||
// .modinfo section: each entry is key=value\0
|
||||
var modinfo bytes.Buffer
|
||||
for _, e := range entries {
|
||||
modinfo.WriteString(e)
|
||||
modinfo.WriteByte(0)
|
||||
}
|
||||
|
||||
// section header string table — embeds names of all sections back-to-back, leading null required.
|
||||
// offsets below index into this blob.
|
||||
shstrtab := []byte("\x00.modinfo\x00.shstrtab\x00")
|
||||
const (
|
||||
modinfoNameOff uint32 = 1
|
||||
shstrtabNameOff uint32 = 10
|
||||
)
|
||||
|
||||
const (
|
||||
ehdrSize uint64 = 64
|
||||
shdrSize uint64 = 64
|
||||
numSections uint16 = 3 // null + .modinfo + .shstrtab
|
||||
)
|
||||
|
||||
// layout: [ehdr][modinfo][shstrtab][pad to 8][section headers]
|
||||
var (
|
||||
modinfoOff = ehdrSize
|
||||
modinfoSize = uint64(modinfo.Len())
|
||||
shstrtabOff = modinfoOff + modinfoSize
|
||||
shstrtabSize = uint64(len(shstrtab))
|
||||
shdrsOff = alignUp(shstrtabOff+shstrtabSize, 8)
|
||||
)
|
||||
|
||||
header := elf.Header64{
|
||||
Ident: [16]byte{
|
||||
0x7f, 'E', 'L', 'F',
|
||||
byte(elf.ELFCLASS64),
|
||||
byte(elf.ELFDATA2LSB),
|
||||
byte(elf.EV_CURRENT),
|
||||
},
|
||||
Type: uint16(elf.ET_REL),
|
||||
Machine: uint16(elf.EM_X86_64),
|
||||
Version: uint32(elf.EV_CURRENT),
|
||||
Shoff: shdrsOff,
|
||||
Ehsize: uint16(ehdrSize),
|
||||
Shentsize: uint16(shdrSize),
|
||||
Shnum: numSections,
|
||||
Shstrndx: numSections - 1, // .shstrtab is last
|
||||
}
|
||||
|
||||
sections := []elf.Section64{
|
||||
{}, // SHN_UNDEF
|
||||
{
|
||||
Name: modinfoNameOff,
|
||||
Type: uint32(elf.SHT_PROGBITS),
|
||||
Off: modinfoOff,
|
||||
Size: modinfoSize,
|
||||
Addralign: 1,
|
||||
},
|
||||
{
|
||||
Name: shstrtabNameOff,
|
||||
Type: uint32(elf.SHT_STRTAB),
|
||||
Off: shstrtabOff,
|
||||
Size: shstrtabSize,
|
||||
Addralign: 1,
|
||||
},
|
||||
}
|
||||
|
||||
var buf bytes.Buffer
|
||||
_ = binary.Write(&buf, binary.LittleEndian, header)
|
||||
buf.Write(modinfo.Bytes())
|
||||
buf.Write(shstrtab)
|
||||
for uint64(buf.Len()) < shdrsOff {
|
||||
buf.WriteByte(0)
|
||||
}
|
||||
for _, s := range sections {
|
||||
_ = binary.Write(&buf, binary.LittleEndian, s)
|
||||
}
|
||||
return buf.Bytes()
|
||||
}
|
||||
|
||||
func alignUp(v, align uint64) uint64 {
|
||||
if v%align == 0 {
|
||||
return v
|
||||
}
|
||||
return v + (align - v%align)
|
||||
}
|
||||
|
||||
func gzCompress(data []byte) []byte {
|
||||
var buf bytes.Buffer
|
||||
w := gzip.NewWriter(&buf)
|
||||
_, _ = w.Write(data)
|
||||
_ = w.Close()
|
||||
return buf.Bytes()
|
||||
}
|
||||
|
||||
func xzCompress(data []byte) []byte {
|
||||
var buf bytes.Buffer
|
||||
w, _ := xz.NewWriter(&buf)
|
||||
_, _ = w.Write(data)
|
||||
_ = w.Close()
|
||||
return buf.Bytes()
|
||||
}
|
||||
|
||||
func zstCompress(data []byte) []byte {
|
||||
var buf bytes.Buffer
|
||||
w, _ := zstd.NewWriter(&buf)
|
||||
_, _ = w.Write(data)
|
||||
_ = w.Close()
|
||||
return buf.Bytes()
|
||||
}
|
||||
|
||||
// makeLocationReadCloser wraps a byte slice as a file.LocationReadCloser with the given path.
|
||||
func makeLocationReadCloser(path string, data []byte) file.LocationReadCloser {
|
||||
return file.LocationReadCloser{
|
||||
Location: file.NewVirtualLocation(path, path),
|
||||
ReadCloser: io.NopCloser(bytes.NewReader(data)),
|
||||
}
|
||||
}
|
||||
|
||||
func TestParseLinuxKernelModuleFile_Compressed(t *testing.T) {
|
||||
modinfo := []string{
|
||||
"name=dummy_mod",
|
||||
"version=1.2.3",
|
||||
"vermagic=6.1.0-rc1 SMP mod_unload",
|
||||
"license=GPL v2",
|
||||
}
|
||||
koBytes := minimalKOBytes(modinfo)
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
path string
|
||||
data []byte
|
||||
wantName string
|
||||
wantVer string
|
||||
wantKV string // expected KernelVersion from vermagic
|
||||
}{
|
||||
{
|
||||
name: "uncompressed .ko",
|
||||
path: "/lib/modules/6.1.0-rc1/kernel/dummy_mod.ko",
|
||||
data: koBytes,
|
||||
wantName: "dummy_mod",
|
||||
wantVer: "1.2.3",
|
||||
wantKV: "6.1.0-rc1",
|
||||
},
|
||||
{
|
||||
name: "gzip-compressed .ko.gz",
|
||||
path: "/lib/modules/6.1.0-rc1/kernel/dummy_mod.ko.gz",
|
||||
data: gzCompress(koBytes),
|
||||
wantName: "dummy_mod",
|
||||
wantVer: "1.2.3",
|
||||
wantKV: "6.1.0-rc1",
|
||||
},
|
||||
{
|
||||
name: "xz-compressed .ko.xz",
|
||||
path: "/lib/modules/6.1.0-rc1/kernel/dummy_mod.ko.xz",
|
||||
data: xzCompress(koBytes),
|
||||
wantName: "dummy_mod",
|
||||
wantVer: "1.2.3",
|
||||
wantKV: "6.1.0-rc1",
|
||||
},
|
||||
{
|
||||
name: "zstd-compressed .ko.zst",
|
||||
path: "/lib/modules/6.1.0-rc1/kernel/dummy_mod.ko.zst",
|
||||
data: zstCompress(koBytes),
|
||||
wantName: "dummy_mod",
|
||||
wantVer: "1.2.3",
|
||||
wantKV: "6.1.0-rc1",
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
reader := makeLocationReadCloser(tt.path, tt.data)
|
||||
pkgs, rels, err := parseLinuxKernelModuleFile(testContext(t), nil, &generic.Environment{}, reader)
|
||||
require.NoError(t, err)
|
||||
require.Len(t, pkgs, 1)
|
||||
assert.Empty(t, rels)
|
||||
assert.Equal(t, tt.wantName, pkgs[0].Name)
|
||||
assert.Equal(t, tt.wantVer, pkgs[0].Version)
|
||||
|
||||
meta, ok := pkgs[0].Metadata.(pkg.LinuxKernelModule)
|
||||
require.True(t, ok)
|
||||
assert.Equal(t, tt.wantKV, meta.KernelVersion)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestDecompressedModuleReader(t *testing.T) {
|
||||
koBytes := minimalKOBytes([]string{"name=test", "vermagic=5.15.0 SMP mod_unload"})
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
path string
|
||||
data []byte
|
||||
}{
|
||||
{"uncompressed", "/lib/modules/5.15.0/kernel/test.ko", koBytes},
|
||||
{"gz", "/lib/modules/5.15.0/kernel/test.ko.gz", gzCompress(koBytes)},
|
||||
{"xz", "/lib/modules/5.15.0/kernel/test.ko.xz", xzCompress(koBytes)},
|
||||
{"zst", "/lib/modules/5.15.0/kernel/test.ko.zst", zstCompress(koBytes)},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
br := bytes.NewReader(tt.data)
|
||||
wrapped := struct {
|
||||
io.ReadCloser
|
||||
io.ReaderAt
|
||||
io.Seeker
|
||||
}{
|
||||
ReadCloser: io.NopCloser(br),
|
||||
ReaderAt: br,
|
||||
Seeker: br,
|
||||
}
|
||||
got, err := decompressedModuleReader(testContext(t), tt.path, wrapped)
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, got)
|
||||
t.Cleanup(func() { _ = got.Close() })
|
||||
|
||||
b, err := io.ReadAll(got)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, koBytes, b, "decompressed bytes should match original .ko bytes")
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestDecompressedModuleReader_TempFileRemovedOnClose(t *testing.T) {
|
||||
koBytes := minimalKOBytes([]string{"name=test", "vermagic=5.15.0 SMP"})
|
||||
data := gzCompress(koBytes)
|
||||
|
||||
br := bytes.NewReader(data)
|
||||
wrapped := struct {
|
||||
io.ReadCloser
|
||||
io.ReaderAt
|
||||
io.Seeker
|
||||
}{
|
||||
ReadCloser: io.NopCloser(br),
|
||||
ReaderAt: br,
|
||||
Seeker: br,
|
||||
}
|
||||
|
||||
got, err := decompressedModuleReader(testContext(t), "/test.ko.gz", wrapped)
|
||||
require.NoError(t, err)
|
||||
|
||||
tfr, ok := got.(*tempFileUnionReader)
|
||||
require.True(t, ok, "expected compressed path to spill to a temp file")
|
||||
path := tfr.File.Name()
|
||||
|
||||
_, err = os.Stat(path)
|
||||
require.NoError(t, err, "temp file should exist before Close")
|
||||
|
||||
require.NoError(t, got.Close())
|
||||
|
||||
_, err = os.Stat(path)
|
||||
assert.True(t, os.IsNotExist(err), "temp file should be removed after Close, got err=%v", err)
|
||||
}
|
||||
@@ -63,8 +63,11 @@ func parseRockspecBlock(data []byte, i *int, locals map[string]string) ([]rocksp
|
||||
|
||||
parsing.SkipWhitespace(data, i)
|
||||
|
||||
if *i >= len(data) && len(out) > 0 {
|
||||
return nil, fmt.Errorf("unexpected end of block at %d", *i)
|
||||
if *i >= len(data) {
|
||||
if len(out) > 0 {
|
||||
return nil, fmt.Errorf("unexpected end of block at %d", *i)
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
c := data[*i]
|
||||
|
||||
@@ -14,6 +14,17 @@ func Test_parseRockspecData(t *testing.T) {
|
||||
content string
|
||||
wantErr require.ErrorAssertionFunc
|
||||
}{
|
||||
{
|
||||
name: "empty file",
|
||||
content: ``,
|
||||
},
|
||||
{
|
||||
name: "whitespace only",
|
||||
content: `
|
||||
|
||||
|
||||
`,
|
||||
},
|
||||
{
|
||||
name: "basic valid content",
|
||||
content: `
|
||||
|
||||
@@ -73,63 +73,63 @@ func Test_InterpreterCataloger(t *testing.T) {
|
||||
fixture: "image-apache",
|
||||
expectedPkgs: []string{
|
||||
// interpreters
|
||||
"libphp @ 8.2.30 (/usr/lib/apache2/modules/libphp8.2.so)",
|
||||
"libphp @ 8.2.31 (/usr/lib/apache2/modules/libphp8.2.so)",
|
||||
|
||||
// extensions
|
||||
"calendar @ 8.2.30 (/usr/lib/php/20220829/calendar.so)",
|
||||
"ctype @ 8.2.30 (/usr/lib/php/20220829/ctype.so)",
|
||||
"exif @ 8.2.30 (/usr/lib/php/20220829/exif.so)",
|
||||
"ffi @ 8.2.30 (/usr/lib/php/20220829/ffi.so)",
|
||||
"fileinfo @ 8.2.30 (/usr/lib/php/20220829/fileinfo.so)",
|
||||
"ftp @ 8.2.30 (/usr/lib/php/20220829/ftp.so)",
|
||||
"gettext @ 8.2.30 (/usr/lib/php/20220829/gettext.so)",
|
||||
"iconv @ 8.2.30 (/usr/lib/php/20220829/iconv.so)",
|
||||
"mysqli @ 8.2.30 (/usr/lib/php/20220829/mysqli.so)",
|
||||
"opcache @ 8.2.30 (/usr/lib/php/20220829/opcache.so)",
|
||||
"pdo @ 8.2.30 (/usr/lib/php/20220829/pdo.so)",
|
||||
"pdo_mysql @ 8.2.30 (/usr/lib/php/20220829/pdo_mysql.so)",
|
||||
"phar @ 8.2.30 (/usr/lib/php/20220829/phar.so)",
|
||||
"posix @ 8.2.30 (/usr/lib/php/20220829/posix.so)",
|
||||
"readline @ 8.2.30 (/usr/lib/php/20220829/readline.so)",
|
||||
"shmop @ 8.2.30 (/usr/lib/php/20220829/shmop.so)",
|
||||
"simplexml @ 8.2.30 (/usr/lib/php/20220829/simplexml.so)",
|
||||
"sockets @ 8.2.30 (/usr/lib/php/20220829/sockets.so)",
|
||||
"sysvmsg @ 8.2.30 (/usr/lib/php/20220829/sysvmsg.so)",
|
||||
"sysvsem @ 8.2.30 (/usr/lib/php/20220829/sysvsem.so)",
|
||||
"sysvshm @ 8.2.30 (/usr/lib/php/20220829/sysvshm.so)",
|
||||
"tokenizer @ 8.2.30 (/usr/lib/php/20220829/tokenizer.so)",
|
||||
"xml @ 8.2.30 (/usr/lib/php/20220829/xml.so)",
|
||||
"xmlreader @ 8.2.30 (/usr/lib/php/20220829/xmlreader.so)",
|
||||
"xmlwriter @ 8.2.30 (/usr/lib/php/20220829/xmlwriter.so)",
|
||||
"xsl @ 8.2.30 (/usr/lib/php/20220829/xsl.so)",
|
||||
"calendar @ 8.2.31 (/usr/lib/php/20220829/calendar.so)",
|
||||
"ctype @ 8.2.31 (/usr/lib/php/20220829/ctype.so)",
|
||||
"exif @ 8.2.31 (/usr/lib/php/20220829/exif.so)",
|
||||
"ffi @ 8.2.31 (/usr/lib/php/20220829/ffi.so)",
|
||||
"fileinfo @ 8.2.31 (/usr/lib/php/20220829/fileinfo.so)",
|
||||
"ftp @ 8.2.31 (/usr/lib/php/20220829/ftp.so)",
|
||||
"gettext @ 8.2.31 (/usr/lib/php/20220829/gettext.so)",
|
||||
"iconv @ 8.2.31 (/usr/lib/php/20220829/iconv.so)",
|
||||
"mysqli @ 8.2.31 (/usr/lib/php/20220829/mysqli.so)",
|
||||
"opcache @ 8.2.31 (/usr/lib/php/20220829/opcache.so)",
|
||||
"pdo @ 8.2.31 (/usr/lib/php/20220829/pdo.so)",
|
||||
"pdo_mysql @ 8.2.31 (/usr/lib/php/20220829/pdo_mysql.so)",
|
||||
"phar @ 8.2.31 (/usr/lib/php/20220829/phar.so)",
|
||||
"posix @ 8.2.31 (/usr/lib/php/20220829/posix.so)",
|
||||
"readline @ 8.2.31 (/usr/lib/php/20220829/readline.so)",
|
||||
"shmop @ 8.2.31 (/usr/lib/php/20220829/shmop.so)",
|
||||
"simplexml @ 8.2.31 (/usr/lib/php/20220829/simplexml.so)",
|
||||
"sockets @ 8.2.31 (/usr/lib/php/20220829/sockets.so)",
|
||||
"sysvmsg @ 8.2.31 (/usr/lib/php/20220829/sysvmsg.so)",
|
||||
"sysvsem @ 8.2.31 (/usr/lib/php/20220829/sysvsem.so)",
|
||||
"sysvshm @ 8.2.31 (/usr/lib/php/20220829/sysvshm.so)",
|
||||
"tokenizer @ 8.2.31 (/usr/lib/php/20220829/tokenizer.so)",
|
||||
"xml @ 8.2.31 (/usr/lib/php/20220829/xml.so)",
|
||||
"xmlreader @ 8.2.31 (/usr/lib/php/20220829/xmlreader.so)",
|
||||
"xmlwriter @ 8.2.31 (/usr/lib/php/20220829/xmlwriter.so)",
|
||||
"xsl @ 8.2.31 (/usr/lib/php/20220829/xsl.so)",
|
||||
},
|
||||
expectedRels: []string{
|
||||
"calendar @ 8.2.30 (/usr/lib/php/20220829/calendar.so) [dependency-of] libphp @ 8.2.30 (/usr/lib/apache2/modules/libphp8.2.so)",
|
||||
"ctype @ 8.2.30 (/usr/lib/php/20220829/ctype.so) [dependency-of] libphp @ 8.2.30 (/usr/lib/apache2/modules/libphp8.2.so)",
|
||||
"exif @ 8.2.30 (/usr/lib/php/20220829/exif.so) [dependency-of] libphp @ 8.2.30 (/usr/lib/apache2/modules/libphp8.2.so)",
|
||||
"ffi @ 8.2.30 (/usr/lib/php/20220829/ffi.so) [dependency-of] libphp @ 8.2.30 (/usr/lib/apache2/modules/libphp8.2.so)",
|
||||
"fileinfo @ 8.2.30 (/usr/lib/php/20220829/fileinfo.so) [dependency-of] libphp @ 8.2.30 (/usr/lib/apache2/modules/libphp8.2.so)",
|
||||
"ftp @ 8.2.30 (/usr/lib/php/20220829/ftp.so) [dependency-of] libphp @ 8.2.30 (/usr/lib/apache2/modules/libphp8.2.so)",
|
||||
"gettext @ 8.2.30 (/usr/lib/php/20220829/gettext.so) [dependency-of] libphp @ 8.2.30 (/usr/lib/apache2/modules/libphp8.2.so)",
|
||||
"iconv @ 8.2.30 (/usr/lib/php/20220829/iconv.so) [dependency-of] libphp @ 8.2.30 (/usr/lib/apache2/modules/libphp8.2.so)",
|
||||
"mysqli @ 8.2.30 (/usr/lib/php/20220829/mysqli.so) [dependency-of] libphp @ 8.2.30 (/usr/lib/apache2/modules/libphp8.2.so)",
|
||||
"opcache @ 8.2.30 (/usr/lib/php/20220829/opcache.so) [dependency-of] libphp @ 8.2.30 (/usr/lib/apache2/modules/libphp8.2.so)",
|
||||
"pdo @ 8.2.30 (/usr/lib/php/20220829/pdo.so) [dependency-of] libphp @ 8.2.30 (/usr/lib/apache2/modules/libphp8.2.so)",
|
||||
"pdo_mysql @ 8.2.30 (/usr/lib/php/20220829/pdo_mysql.so) [dependency-of] libphp @ 8.2.30 (/usr/lib/apache2/modules/libphp8.2.so)",
|
||||
"phar @ 8.2.30 (/usr/lib/php/20220829/phar.so) [dependency-of] libphp @ 8.2.30 (/usr/lib/apache2/modules/libphp8.2.so)",
|
||||
"posix @ 8.2.30 (/usr/lib/php/20220829/posix.so) [dependency-of] libphp @ 8.2.30 (/usr/lib/apache2/modules/libphp8.2.so)",
|
||||
"readline @ 8.2.30 (/usr/lib/php/20220829/readline.so) [dependency-of] libphp @ 8.2.30 (/usr/lib/apache2/modules/libphp8.2.so)",
|
||||
"shmop @ 8.2.30 (/usr/lib/php/20220829/shmop.so) [dependency-of] libphp @ 8.2.30 (/usr/lib/apache2/modules/libphp8.2.so)",
|
||||
"simplexml @ 8.2.30 (/usr/lib/php/20220829/simplexml.so) [dependency-of] libphp @ 8.2.30 (/usr/lib/apache2/modules/libphp8.2.so)",
|
||||
"sockets @ 8.2.30 (/usr/lib/php/20220829/sockets.so) [dependency-of] libphp @ 8.2.30 (/usr/lib/apache2/modules/libphp8.2.so)",
|
||||
"sysvmsg @ 8.2.30 (/usr/lib/php/20220829/sysvmsg.so) [dependency-of] libphp @ 8.2.30 (/usr/lib/apache2/modules/libphp8.2.so)",
|
||||
"sysvsem @ 8.2.30 (/usr/lib/php/20220829/sysvsem.so) [dependency-of] libphp @ 8.2.30 (/usr/lib/apache2/modules/libphp8.2.so)",
|
||||
"sysvshm @ 8.2.30 (/usr/lib/php/20220829/sysvshm.so) [dependency-of] libphp @ 8.2.30 (/usr/lib/apache2/modules/libphp8.2.so)",
|
||||
"tokenizer @ 8.2.30 (/usr/lib/php/20220829/tokenizer.so) [dependency-of] libphp @ 8.2.30 (/usr/lib/apache2/modules/libphp8.2.so)",
|
||||
"xml @ 8.2.30 (/usr/lib/php/20220829/xml.so) [dependency-of] libphp @ 8.2.30 (/usr/lib/apache2/modules/libphp8.2.so)",
|
||||
"xmlreader @ 8.2.30 (/usr/lib/php/20220829/xmlreader.so) [dependency-of] libphp @ 8.2.30 (/usr/lib/apache2/modules/libphp8.2.so)",
|
||||
"xmlwriter @ 8.2.30 (/usr/lib/php/20220829/xmlwriter.so) [dependency-of] libphp @ 8.2.30 (/usr/lib/apache2/modules/libphp8.2.so)",
|
||||
"xsl @ 8.2.30 (/usr/lib/php/20220829/xsl.so) [dependency-of] libphp @ 8.2.30 (/usr/lib/apache2/modules/libphp8.2.so)",
|
||||
"calendar @ 8.2.31 (/usr/lib/php/20220829/calendar.so) [dependency-of] libphp @ 8.2.31 (/usr/lib/apache2/modules/libphp8.2.so)",
|
||||
"ctype @ 8.2.31 (/usr/lib/php/20220829/ctype.so) [dependency-of] libphp @ 8.2.31 (/usr/lib/apache2/modules/libphp8.2.so)",
|
||||
"exif @ 8.2.31 (/usr/lib/php/20220829/exif.so) [dependency-of] libphp @ 8.2.31 (/usr/lib/apache2/modules/libphp8.2.so)",
|
||||
"ffi @ 8.2.31 (/usr/lib/php/20220829/ffi.so) [dependency-of] libphp @ 8.2.31 (/usr/lib/apache2/modules/libphp8.2.so)",
|
||||
"fileinfo @ 8.2.31 (/usr/lib/php/20220829/fileinfo.so) [dependency-of] libphp @ 8.2.31 (/usr/lib/apache2/modules/libphp8.2.so)",
|
||||
"ftp @ 8.2.31 (/usr/lib/php/20220829/ftp.so) [dependency-of] libphp @ 8.2.31 (/usr/lib/apache2/modules/libphp8.2.so)",
|
||||
"gettext @ 8.2.31 (/usr/lib/php/20220829/gettext.so) [dependency-of] libphp @ 8.2.31 (/usr/lib/apache2/modules/libphp8.2.so)",
|
||||
"iconv @ 8.2.31 (/usr/lib/php/20220829/iconv.so) [dependency-of] libphp @ 8.2.31 (/usr/lib/apache2/modules/libphp8.2.so)",
|
||||
"mysqli @ 8.2.31 (/usr/lib/php/20220829/mysqli.so) [dependency-of] libphp @ 8.2.31 (/usr/lib/apache2/modules/libphp8.2.so)",
|
||||
"opcache @ 8.2.31 (/usr/lib/php/20220829/opcache.so) [dependency-of] libphp @ 8.2.31 (/usr/lib/apache2/modules/libphp8.2.so)",
|
||||
"pdo @ 8.2.31 (/usr/lib/php/20220829/pdo.so) [dependency-of] libphp @ 8.2.31 (/usr/lib/apache2/modules/libphp8.2.so)",
|
||||
"pdo_mysql @ 8.2.31 (/usr/lib/php/20220829/pdo_mysql.so) [dependency-of] libphp @ 8.2.31 (/usr/lib/apache2/modules/libphp8.2.so)",
|
||||
"phar @ 8.2.31 (/usr/lib/php/20220829/phar.so) [dependency-of] libphp @ 8.2.31 (/usr/lib/apache2/modules/libphp8.2.so)",
|
||||
"posix @ 8.2.31 (/usr/lib/php/20220829/posix.so) [dependency-of] libphp @ 8.2.31 (/usr/lib/apache2/modules/libphp8.2.so)",
|
||||
"readline @ 8.2.31 (/usr/lib/php/20220829/readline.so) [dependency-of] libphp @ 8.2.31 (/usr/lib/apache2/modules/libphp8.2.so)",
|
||||
"shmop @ 8.2.31 (/usr/lib/php/20220829/shmop.so) [dependency-of] libphp @ 8.2.31 (/usr/lib/apache2/modules/libphp8.2.so)",
|
||||
"simplexml @ 8.2.31 (/usr/lib/php/20220829/simplexml.so) [dependency-of] libphp @ 8.2.31 (/usr/lib/apache2/modules/libphp8.2.so)",
|
||||
"sockets @ 8.2.31 (/usr/lib/php/20220829/sockets.so) [dependency-of] libphp @ 8.2.31 (/usr/lib/apache2/modules/libphp8.2.so)",
|
||||
"sysvmsg @ 8.2.31 (/usr/lib/php/20220829/sysvmsg.so) [dependency-of] libphp @ 8.2.31 (/usr/lib/apache2/modules/libphp8.2.so)",
|
||||
"sysvsem @ 8.2.31 (/usr/lib/php/20220829/sysvsem.so) [dependency-of] libphp @ 8.2.31 (/usr/lib/apache2/modules/libphp8.2.so)",
|
||||
"sysvshm @ 8.2.31 (/usr/lib/php/20220829/sysvshm.so) [dependency-of] libphp @ 8.2.31 (/usr/lib/apache2/modules/libphp8.2.so)",
|
||||
"tokenizer @ 8.2.31 (/usr/lib/php/20220829/tokenizer.so) [dependency-of] libphp @ 8.2.31 (/usr/lib/apache2/modules/libphp8.2.so)",
|
||||
"xml @ 8.2.31 (/usr/lib/php/20220829/xml.so) [dependency-of] libphp @ 8.2.31 (/usr/lib/apache2/modules/libphp8.2.so)",
|
||||
"xmlreader @ 8.2.31 (/usr/lib/php/20220829/xmlreader.so) [dependency-of] libphp @ 8.2.31 (/usr/lib/apache2/modules/libphp8.2.so)",
|
||||
"xmlwriter @ 8.2.31 (/usr/lib/php/20220829/xmlwriter.so) [dependency-of] libphp @ 8.2.31 (/usr/lib/apache2/modules/libphp8.2.so)",
|
||||
"xsl @ 8.2.31 (/usr/lib/php/20220829/xsl.so) [dependency-of] libphp @ 8.2.31 (/usr/lib/apache2/modules/libphp8.2.so)",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
+8
-1
@@ -1,6 +1,13 @@
|
||||
FROM --platform=linux/amd64 httpd:2.4.63-bookworm AS builder
|
||||
|
||||
RUN apt update -y && apt install -y libapache2-mod-php php8.2-memcache php8.2-memcache php8.2-xml php8.2-mysqli php8.2-opcache
|
||||
# pin php8.2 packages to avoid version drift when debian publishes security updates
|
||||
ARG PHP_VERSION=8.2.31-1~deb12u1
|
||||
RUN apt update -y && apt install -y \
|
||||
libapache2-mod-php8.2=${PHP_VERSION} \
|
||||
php8.2-common=${PHP_VERSION} \
|
||||
php8.2-xml=${PHP_VERSION} \
|
||||
php8.2-mysql=${PHP_VERSION} \
|
||||
php8.2-opcache=${PHP_VERSION}
|
||||
|
||||
FROM busybox:latest
|
||||
|
||||
|
||||
@@ -170,8 +170,8 @@ func (rp requirementsParser) parseRequirementsTxt(ctx context.Context, _ file.Re
|
||||
}
|
||||
|
||||
func parseVersion(version string, guessFromConstraint bool) string {
|
||||
if isPinnedConstraint(version) {
|
||||
return strings.TrimSpace(strings.ReplaceAll(version, "==", ""))
|
||||
if version := parsePinnedVersion(version); version != "" {
|
||||
return version
|
||||
}
|
||||
|
||||
if guessFromConstraint {
|
||||
@@ -181,15 +181,26 @@ func parseVersion(version string, guessFromConstraint bool) string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func isPinnedConstraint(version string) bool {
|
||||
return strings.Contains(version, "==") && !strings.ContainsAny(version, "*,<>!")
|
||||
func parsePinnedVersion(version string) string {
|
||||
version = strings.TrimSpace(version)
|
||||
if strings.ContainsAny(version, "*,<>!") {
|
||||
return ""
|
||||
}
|
||||
|
||||
for _, operator := range []string{"===", "=="} {
|
||||
if strings.HasPrefix(version, operator) && !strings.HasPrefix(version, operator+"=") {
|
||||
return strings.TrimSpace(strings.TrimPrefix(version, operator))
|
||||
}
|
||||
}
|
||||
|
||||
return ""
|
||||
}
|
||||
|
||||
func guessVersion(constraint string) string {
|
||||
// handle "2.8.*" -> "2.8.0"
|
||||
constraint = strings.ReplaceAll(constraint, "*", "0")
|
||||
if isPinnedConstraint(constraint) {
|
||||
return strings.TrimSpace(strings.ReplaceAll(constraint, "==", ""))
|
||||
if version := parsePinnedVersion(constraint); version != "" {
|
||||
return version
|
||||
}
|
||||
|
||||
constraints := strings.Split(constraint, ",")
|
||||
|
||||
@@ -29,6 +29,18 @@ func TestParseRequirementsTxt(t *testing.T) {
|
||||
VersionConstraint: "== 4.0.0",
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "urllib3",
|
||||
Version: "1.26.20",
|
||||
PURL: "pkg:pypi/urllib3@1.26.20",
|
||||
Locations: locations,
|
||||
Language: pkg.Python,
|
||||
Type: pkg.PythonPkg,
|
||||
Metadata: pkg.PythonRequirementsEntry{
|
||||
Name: "urllib3",
|
||||
VersionConstraint: "===1.26.20",
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "foo",
|
||||
Version: "1.0.0",
|
||||
@@ -294,6 +306,14 @@ func Test_newRequirement(t *testing.T) {
|
||||
VersionConstraint: "==2.8",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "arbitrary equality",
|
||||
raw: "urllib3===1.26.20",
|
||||
want: &unprocessedRequirement{
|
||||
Name: "urllib3",
|
||||
VersionConstraint: "===1.26.20",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "comment + constraint",
|
||||
raw: "Mopidy-Dirble ~= 1.1 # Compatible release. Same as >= 1.1, == 1.*",
|
||||
@@ -363,6 +383,11 @@ func Test_parseVersion(t *testing.T) {
|
||||
version: " == 1.0.0 ",
|
||||
want: "1.0.0",
|
||||
},
|
||||
{
|
||||
name: "arbitrary equality constraint",
|
||||
version: " === 1.26.20 ",
|
||||
want: "1.26.20",
|
||||
},
|
||||
{
|
||||
name: "resolve lowest, simple constraint",
|
||||
version: " >= 1.0.0 ",
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
flask == 4.0.0
|
||||
urllib3===1.26.20
|
||||
# a line that is ignored
|
||||
sqlalchemy >= 1.0.0, <= 2.0.0, != 3.0.0, <= 3.0.0
|
||||
foo == 1.0.0 # a comment that needs to be ignored
|
||||
|
||||
+1
-1
@@ -220,7 +220,7 @@ func TypeByName(name string) Type {
|
||||
return CondaPkg
|
||||
case packageurl.TypePub:
|
||||
return DartPubPkg
|
||||
case "dotnet": // here to support legacy use cases
|
||||
case "dotnet", packageurl.TypeNuget: // "dotnet" is here to support legacy use cases; "nuget" is the canonical purl type
|
||||
return DotnetPkg
|
||||
case packageurl.TypeCocoapods:
|
||||
return CocoapodsPkg
|
||||
|
||||
@@ -58,6 +58,11 @@ func TestTypeFromPURL(t *testing.T) {
|
||||
purl: "pkg:dotnet/Microsoft.CodeAnalysis.Razor@2.2.0",
|
||||
expected: DotnetPkg,
|
||||
},
|
||||
{
|
||||
name: "nuget purl maps to dotnet",
|
||||
purl: "pkg:nuget/Minio@7.0.0",
|
||||
expected: DotnetPkg,
|
||||
},
|
||||
{
|
||||
purl: "pkg:composer/laravel/laravel@5.5.0",
|
||||
expected: PhpComposerPkg,
|
||||
|
||||
@@ -145,6 +145,9 @@ func GetDirectoryExclusionFunctions(root string, exclusions []string) ([]fileres
|
||||
// check exclusions for supported paths, these are all relative to the "scan root"
|
||||
if strings.HasPrefix(exclusion, "./") || strings.HasPrefix(exclusion, "*/") || strings.HasPrefix(exclusion, "**/") {
|
||||
exclusion = strings.TrimPrefix(exclusion, "./")
|
||||
// a trailing slash signals a directory but is otherwise discarded by doublestar.Match,
|
||||
// causing the pattern to silently match nothing (see issue #4839)
|
||||
exclusion = strings.TrimSuffix(exclusion, "/")
|
||||
exclusions[idx] = root + exclusion
|
||||
} else {
|
||||
errors = append(errors, exclusion)
|
||||
|
||||
@@ -175,6 +175,18 @@ func Test_DirectorySource_Exclusions(t *testing.T) {
|
||||
},
|
||||
exclusions: []string{"./target"},
|
||||
},
|
||||
{
|
||||
input: "testdata/image-simple",
|
||||
desc: "exclude explicit directory with trailing slash (issue #4839)",
|
||||
glob: "**",
|
||||
expected: []string{
|
||||
"Dockerfile",
|
||||
"file-1.txt",
|
||||
"file-2.txt",
|
||||
//"target/really/nested/file-3.txt", // explicitly skipped
|
||||
},
|
||||
exclusions: []string{"./target/"},
|
||||
},
|
||||
{
|
||||
input: "testdata/image-simple",
|
||||
desc: "exclude explicit file relative to the root",
|
||||
@@ -329,6 +341,14 @@ func Test_getDirectoryExclusionFunctions_crossPlatform(t *testing.T) {
|
||||
finfo: file.ManualInfo{ModeValue: os.ModeDir},
|
||||
walkHint: fs.SkipDir,
|
||||
},
|
||||
{
|
||||
desc: "directory exclusion with trailing slash (issue #4839)",
|
||||
root: "/usr/var",
|
||||
path: "/usr/var/lib",
|
||||
exclude: "./lib/",
|
||||
finfo: file.ManualInfo{ModeValue: os.ModeDir},
|
||||
walkHint: fs.SkipDir,
|
||||
},
|
||||
{
|
||||
desc: "no file info",
|
||||
root: "/",
|
||||
|
||||
@@ -92,6 +92,10 @@ run_test_case test_positive_snapshot_download_asset "linux" "ppc64le" "sbom"
|
||||
run_test_case test_positive_snapshot_download_asset "linux" "ppc64le" "tar.gz"
|
||||
run_test_case test_positive_snapshot_download_asset "linux" "ppc64le" "rpm"
|
||||
run_test_case test_positive_snapshot_download_asset "linux" "ppc64le" "deb"
|
||||
run_test_case test_positive_snapshot_download_asset "linux" "riscv64" "sbom"
|
||||
run_test_case test_positive_snapshot_download_asset "linux" "riscv64" "tar.gz"
|
||||
run_test_case test_positive_snapshot_download_asset "linux" "riscv64" "rpm"
|
||||
run_test_case test_positive_snapshot_download_asset "linux" "riscv64" "deb"
|
||||
run_test_case test_positive_snapshot_download_asset "linux" "s390x" "sbom"
|
||||
run_test_case test_positive_snapshot_download_asset "linux" "s390x" "tar.gz"
|
||||
run_test_case test_positive_snapshot_download_asset "linux" "s390x" "rpm"
|
||||
|
||||
@@ -43,6 +43,11 @@ test_positive_snapshot_install_asset() {
|
||||
local_suffix="_power8"
|
||||
fi
|
||||
|
||||
# note: this is a change made in goreleaser v2.4.0
|
||||
if [ "${arch}" == "riscv64" ]; then
|
||||
local_suffix="_rva20u64"
|
||||
fi
|
||||
|
||||
|
||||
assertFilesEqual \
|
||||
"$(snapshot_dir)/${os}-build_${os}_${arch}${local_suffix}/${binary}" \
|
||||
@@ -95,6 +100,7 @@ trap 'teardown_snapshot_server ${worker_pid}' EXIT
|
||||
run_test_case test_positive_snapshot_install_asset "linux" "amd64" "tar.gz"
|
||||
run_test_case test_positive_snapshot_install_asset "linux" "arm64" "tar.gz"
|
||||
run_test_case test_positive_snapshot_install_asset "linux" "ppc64le" "tar.gz"
|
||||
run_test_case test_positive_snapshot_install_asset "linux" "riscv64" "tar.gz"
|
||||
run_test_case test_positive_snapshot_install_asset "linux" "s390x" "tar.gz"
|
||||
run_test_case test_positive_snapshot_install_asset "darwin" "amd64" "tar.gz"
|
||||
run_test_case test_positive_snapshot_install_asset "darwin" "arm64" "tar.gz"
|
||||
|
||||
@@ -14,6 +14,10 @@ ee2b1289a1e4b0de9409c3a78867949ca42788a5f50072b8a6e6e04e6a269f9c syft_1.5.0_lin
|
||||
dc4b8c4a02ffd8dd394ab94695ed44ed2bfceb06bc239835c51e84dd9b84a68c syft_1.5.0_linux_ppc64le.rpm
|
||||
392044f2951ca6522d0bc71de43763202a548d40bf836098caf286041a7c8fa4 syft_1.5.0_linux_ppc64le.sbom
|
||||
551d98b67f7476bc2e38453a588177b0b038933850a351a94c4bf360813f01d0 syft_1.5.0_linux_ppc64le.tar.gz
|
||||
98cd582d9484f428cccd7351031543038f26d4e3f1481c5916e08e65983f1e21 syft_1.5.0_linux_riscv64.deb
|
||||
3a5197d43a469feaa87c723448a47a2312cf26456eef4580b59eac447baef9d4 syft_1.5.0_linux_riscv64.rpm
|
||||
5805bfb3e30452c8860665ea88bfdf356e9536a35c1b8ba28ac5b4717f2e6388 syft_1.5.0_linux_riscv64.sbom
|
||||
ff15f556660cc4c4279ce41e2475bffe2a0f72eb4423c21edf7380b2484fbf68 syft_1.5.0_linux_riscv64.tar.gz
|
||||
98cd582d9484f428cccd7351031543038f26d4e3f1481c5916e08e65983f1e21 syft_1.5.0_linux_s390x.deb
|
||||
3a5197d43a469feaa87c723448a47a2312cf26456eef4580b59eac447baef9d4 syft_1.5.0_linux_s390x.rpm
|
||||
5805bfb3e30452c8860665ea88bfdf356e9536a35c1b8ba28ac5b4717f2e6388 syft_1.5.0_linux_s390x.sbom
|
||||
|
||||
@@ -14,6 +14,10 @@ a74549794fa5dac79ab9f6401ee7000db3bd9589435b302583c3ee4ca13fb8e3 syft_1.5.0_lin
|
||||
dc4b8c4a02ffd8dd394ab94695ed44ed2bfceb06bc239835c51e84dd9b84a68c syft_1.5.0_linux_ppc64le.rpm
|
||||
392044f2951ca6522d0bc71de43763202a548d40bf836098caf286041a7c8fa4 syft_1.5.0_linux_ppc64le.sbom
|
||||
551d98b67f7476bc2e38453a588177b0b038933850a351a94c4bf360813f01d0 syft_1.5.0_linux_ppc64le.tar.gz
|
||||
98cd582d9484f428cccd7351031543038f26d4e3f1481c5916e08e65983f1e21 syft_1.5.0_linux_riscv64.deb
|
||||
3a5197d43a469feaa87c723448a47a2312cf26456eef4580b59eac447baef9d4 syft_1.5.0_linux_riscv64.rpm
|
||||
5805bfb3e30452c8860665ea88bfdf356e9536a35c1b8ba28ac5b4717f2e6388 syft_1.5.0_linux_riscv64.sbom
|
||||
ff15f556660cc4c4279ce41e2475bffe2a0f72eb4423c21edf7380b2484fbf68 syft_1.5.0_linux_riscv64.tar.gz
|
||||
98cd582d9484f428cccd7351031543038f26d4e3f1481c5916e08e65983f1e21 syft_1.5.0_linux_s390x.deb
|
||||
3a5197d43a469feaa87c723448a47a2312cf26456eef4580b59eac447baef9d4 syft_1.5.0_linux_s390x.rpm
|
||||
5805bfb3e30452c8860665ea88bfdf356e9536a35c1b8ba28ac5b4717f2e6388 syft_1.5.0_linux_s390x.sbom
|
||||
|
||||
Reference in New Issue
Block a user