mirror of
https://github.com/anchore/syft.git
synced 2026-10-23 11:32:21 +02:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
16223e6dd7 | ||
|
|
1286689419 | ||
|
|
295454945c | ||
|
|
86baeeb481 | ||
|
|
2dcf5163b8 | ||
|
|
12b8ba47fb | ||
|
|
138d9ce2a0 | ||
|
|
8a229b16c4 | ||
|
|
9af0098a68 | ||
|
|
2840ea6653 | ||
|
|
b38e40e3e6 | ||
|
|
a6eedecd31 | ||
|
|
691b1357b2 | ||
|
|
c890e7f17f | ||
|
|
29fd7d0dec | ||
|
|
289137ff3c | ||
|
|
22ffd5209d | ||
|
|
a0852ebf98 | ||
|
|
d380ad08b5 | ||
|
|
ae9534203d | ||
|
|
dc1ef98237 | ||
|
|
36a3af41d9 | ||
|
|
3e2bc6ed09 |
@@ -75,7 +75,7 @@ jobs:
|
||||
packages: write # required for publishing release artifacts to GitHub packages
|
||||
id-token: write # required for keyless signing (cosign/sigstore OIDC)
|
||||
steps:
|
||||
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 #v7.0.0
|
||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 #v7.0.1
|
||||
with:
|
||||
fetch-depth: 0
|
||||
persist-credentials: true
|
||||
@@ -83,6 +83,11 @@ jobs:
|
||||
- name: Bootstrap environment
|
||||
uses: ./.github/actions/bootstrap
|
||||
|
||||
# dockers_v2 builds multi-platform manifests in a single buildx invocation, which requires a
|
||||
# docker-container driver builder (the default builder on the runner cannot build multi-platform).
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@bb05f3f5519dd87d3ba754cc423b652a5edd6d2c # v4.2.0
|
||||
|
||||
- name: Login to Docker Hub
|
||||
uses: docker/login-action@af1e73f918a031802d376d3c8bbc3fe56130a9b0 #v4.4.0
|
||||
with:
|
||||
|
||||
@@ -20,12 +20,12 @@ jobs:
|
||||
contents: read
|
||||
security-events: write # for uploading SARIF results
|
||||
steps:
|
||||
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- name: "Run zizmor"
|
||||
uses: zizmorcore/zizmor-action@192e21d79ab29983730a13d1382995c2307fbcaa # v0.5.7
|
||||
uses: zizmorcore/zizmor-action@6599ee8b7a49aef6a770f63d261d214911a7ce02 # v0.6.0
|
||||
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
|
||||
|
||||
@@ -28,7 +28,7 @@ jobs:
|
||||
permissions:
|
||||
contents: read
|
||||
steps:
|
||||
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 #v7.0.0
|
||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 #v7.0.1
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
@@ -50,7 +50,7 @@ jobs:
|
||||
permissions:
|
||||
contents: read
|
||||
steps:
|
||||
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 #v7.0.0
|
||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 #v7.0.1
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
@@ -72,7 +72,7 @@ jobs:
|
||||
permissions:
|
||||
contents: read
|
||||
steps:
|
||||
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 #v7.0.0
|
||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 #v7.0.1
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
@@ -105,7 +105,7 @@ jobs:
|
||||
permissions:
|
||||
contents: read
|
||||
steps:
|
||||
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 #v7.0.0
|
||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 #v7.0.1
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
@@ -135,7 +135,7 @@ jobs:
|
||||
permissions:
|
||||
contents: read
|
||||
steps:
|
||||
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 #v7.0.0
|
||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 #v7.0.1
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
@@ -179,7 +179,7 @@ jobs:
|
||||
- name: Install Cosign
|
||||
uses: sigstore/cosign-installer@6f9f17788090df1f26f669e9d70d6ae9567deba6 # v4.1.2
|
||||
|
||||
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 #v7.0.0
|
||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 #v7.0.1
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
@@ -213,7 +213,7 @@ jobs:
|
||||
permissions:
|
||||
contents: read
|
||||
steps:
|
||||
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 #v7.0.0
|
||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 #v7.0.1
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
|
||||
@@ -0,0 +1,145 @@
|
||||
package integration
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"runtime"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/anchore/stereoscope/pkg/image"
|
||||
"github.com/anchore/stereoscope/pkg/imagetest"
|
||||
"github.com/anchore/syft/syft"
|
||||
"github.com/anchore/syft/syft/source"
|
||||
)
|
||||
|
||||
// TestMultiPlatformOCIImageSelection verifies that syft can load a single platform out of a
|
||||
// multi-platform OCI image on disk (both --from oci-dir and --from oci-archive) by selecting the
|
||||
// image that matches the requested platform.
|
||||
func TestMultiPlatformOCIImageSelection(t *testing.T) {
|
||||
remoteImage := "docker.io/library/busybox:1.38.0"
|
||||
|
||||
// Per-platform image config digests within the multi-platform index, obtained from the OCI layout
|
||||
// (see anchore/stereoscope integration tests: TestPlatformSelectionWithOciLocalSources).
|
||||
expectedDigest := map[string]string{
|
||||
"arm64": "sha256:e0e8b3cbfed68a90084781e2962f9c0deead51c5a3f11a488eef0283a4284bc2",
|
||||
"s390x": "sha256:0cf160e720a8e4f20883b72276a6eaded83b79539f3f1d39e35a3336154b9960",
|
||||
"amd64": "sha256:c6348fa86ba0fb2108c9334f5fe913ddc6d853313e655891f133a0127c30099f",
|
||||
"ppc64le": "sha256:b144fc0e06537d07956cde340b878a81a717e394edb736d3110858a12a6635cb",
|
||||
}
|
||||
|
||||
// syft --from source tag -> stereoscope OCI source used to prepare the local fixture
|
||||
sources := map[string]image.Source{
|
||||
"oci-dir": image.OciDirectorySource,
|
||||
"oci-archive": image.OciTarballSource,
|
||||
}
|
||||
|
||||
for from, imageSource := range sources {
|
||||
t.Run(from, func(t *testing.T) {
|
||||
localPath := imagetest.PrepareMultiplatformFixtureImage(t, imageSource, remoteImage)
|
||||
for _, arch := range []string{"amd64", "arm64", "s390x", "ppc64le"} {
|
||||
t.Run(fmt.Sprintf("linux/%s", arch), func(t *testing.T) {
|
||||
platform, err := image.NewPlatform("linux/" + arch)
|
||||
require.NoError(t, err)
|
||||
|
||||
src, err := syft.GetSource(
|
||||
context.Background(),
|
||||
localPath,
|
||||
syft.DefaultGetSourceConfig().WithSources(from).WithPlatform(platform),
|
||||
)
|
||||
require.NoError(t, err)
|
||||
t.Cleanup(func() {
|
||||
require.NoError(t, src.Close())
|
||||
})
|
||||
|
||||
meta, ok := src.Describe().Metadata.(source.ImageMetadata)
|
||||
require.True(t, ok, "expected image metadata, got %T", src.Describe().Metadata)
|
||||
|
||||
// The raw config of the selected image must match the requested platform...
|
||||
assertConfigPlatform(t, meta.RawConfig, "linux", arch)
|
||||
// ...and it must be the exact per-platform image from the multi-platform index.
|
||||
assert.Equal(t, expectedDigest[arch], meta.ID)
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// TestMultiPlatformOCIImageSelection_UnavailablePlatform verifies that requesting a platform not present
|
||||
// in the multi-platform OCI image results in an error rather than silently selecting the wrong image.
|
||||
func TestMultiPlatformOCIImageSelection_UnavailablePlatform(t *testing.T) {
|
||||
remoteImage := "docker.io/library/busybox:1.38.0"
|
||||
|
||||
// windows/amd64 is not present in this linux-only multi-platform image
|
||||
platform, err := image.NewPlatform("windows/amd64")
|
||||
require.NoError(t, err)
|
||||
|
||||
sources := map[string]image.Source{
|
||||
"oci-dir": image.OciDirectorySource,
|
||||
"oci-archive": image.OciTarballSource,
|
||||
}
|
||||
|
||||
for from, imageSource := range sources {
|
||||
t.Run(from, func(t *testing.T) {
|
||||
localPath := imagetest.PrepareMultiplatformFixtureImage(t, imageSource, remoteImage)
|
||||
|
||||
_, err := syft.GetSource(
|
||||
context.Background(),
|
||||
localPath,
|
||||
syft.DefaultGetSourceConfig().WithSources(from).WithPlatform(platform),
|
||||
)
|
||||
require.ErrorContains(t, err, "windows/amd64")
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// TestMultiPlatformOCIImageSelection_DefaultPlatform verifies that not specifying a platform results
|
||||
// in the current platform being selected.
|
||||
func TestMultiPlatformOCIImageSelection_DefaultPlatform(t *testing.T) {
|
||||
remoteImage := "docker.io/library/busybox:1.38.0"
|
||||
|
||||
sources := map[string]image.Source{
|
||||
"oci-dir": image.OciDirectorySource,
|
||||
"oci-archive": image.OciTarballSource,
|
||||
}
|
||||
|
||||
for from, imageSource := range sources {
|
||||
t.Run(from, func(t *testing.T) {
|
||||
localPath := imagetest.PrepareMultiplatformFixtureImage(t, imageSource, remoteImage)
|
||||
|
||||
src, err := syft.GetSource(
|
||||
context.Background(),
|
||||
localPath,
|
||||
syft.DefaultGetSourceConfig().WithSources(from),
|
||||
)
|
||||
require.NoError(t, err)
|
||||
t.Cleanup(func() {
|
||||
require.NoError(t, src.Close())
|
||||
})
|
||||
|
||||
meta, ok := src.Describe().Metadata.(source.ImageMetadata)
|
||||
require.True(t, ok, "expected image metadata, got %T", src.Describe().Metadata)
|
||||
|
||||
// The raw config of the selected image must match the current platform
|
||||
assertConfigPlatform(t, meta.RawConfig, "linux", runtime.GOARCH)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// assertConfigPlatform asserts the os/architecture recorded in a raw OCI image config document.
|
||||
func assertConfigPlatform(t *testing.T, rawConfig []byte, os, architecture string) {
|
||||
t.Helper()
|
||||
require.NotEmpty(t, rawConfig)
|
||||
|
||||
var cfg struct {
|
||||
OS string `json:"os"`
|
||||
Architecture string `json:"architecture"`
|
||||
}
|
||||
require.NoError(t, json.Unmarshal(rawConfig, &cfg))
|
||||
|
||||
assert.Equal(t, os, cfg.OS)
|
||||
assert.Equal(t, architecture, cfg.Architecture)
|
||||
}
|
||||
@@ -7,4 +7,6 @@
|
||||
!image-pkg-coverage/pkgs/java/*.hpi
|
||||
|
||||
**/go.sum
|
||||
!image-go-bin-arch-coverage/go.sum
|
||||
!image-go-bin-arch-coverage/go.sum
|
||||
|
||||
cache/
|
||||
@@ -18,11 +18,11 @@ require (
|
||||
github.com/anchore/go-homedir v0.1.1
|
||||
github.com/anchore/go-logger v0.1.1
|
||||
github.com/anchore/go-macholibre v0.1.1
|
||||
github.com/anchore/go-rpmdb v0.1.0
|
||||
github.com/anchore/go-rpmdb v0.2.0
|
||||
github.com/anchore/go-sync v0.1.1
|
||||
github.com/anchore/go-version v1.2.2-0.20200701162849-18adb9c92b9b
|
||||
github.com/anchore/packageurl-go v0.2.0
|
||||
github.com/anchore/stereoscope v0.2.2
|
||||
github.com/anchore/stereoscope v0.3.0
|
||||
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
|
||||
@@ -40,7 +40,7 @@ require (
|
||||
github.com/elliotchance/phpserialize v1.4.0
|
||||
github.com/facebookincubator/nvdtools v0.1.5
|
||||
github.com/github/go-spdx/v2 v2.7.0
|
||||
github.com/gkampitakis/go-snaps v0.5.22
|
||||
github.com/gkampitakis/go-snaps v0.5.23
|
||||
github.com/go-git/go-billy/v5 v5.9.0
|
||||
github.com/go-git/go-git/v5 v5.19.1
|
||||
github.com/go-test/deep v1.1.1
|
||||
@@ -52,7 +52,7 @@ require (
|
||||
github.com/google/licensecheck v0.3.1
|
||||
github.com/google/uuid v1.6.0
|
||||
github.com/gookit/color v1.6.1
|
||||
github.com/gpustack/gguf-parser-go v0.24.1
|
||||
github.com/gpustack/gguf-parser-go v0.25.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
|
||||
@@ -93,12 +93,12 @@ require (
|
||||
go.uber.org/goleak v1.3.0
|
||||
go.yaml.in/yaml/v3 v3.0.4
|
||||
golang.org/x/exp v0.0.0-20260410095643-746e56fc9e2f
|
||||
golang.org/x/mod v0.37.0
|
||||
golang.org/x/net v0.56.0
|
||||
golang.org/x/mod v0.38.0
|
||||
golang.org/x/net v0.57.0
|
||||
golang.org/x/time v0.15.0
|
||||
golang.org/x/tools v0.47.0
|
||||
golang.org/x/tools v0.48.0
|
||||
gopkg.in/yaml.v3 v3.0.1
|
||||
modernc.org/sqlite v1.53.0
|
||||
modernc.org/sqlite v1.54.0
|
||||
)
|
||||
|
||||
require (
|
||||
@@ -118,7 +118,7 @@ require (
|
||||
cloud.google.com/go/storage v1.61.3 // 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.31.0 // indirect
|
||||
github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.32.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
|
||||
@@ -168,10 +168,10 @@ require (
|
||||
github.com/clipperhouse/displaywidth v0.11.0 // indirect
|
||||
github.com/clipperhouse/uax29/v2 v2.7.0 // indirect
|
||||
github.com/cloudflare/circl v1.6.3 // indirect
|
||||
github.com/cncf/xds/go v0.0.0-20251210132809-ee656c7534f5 // indirect
|
||||
github.com/cncf/xds/go v0.0.0-20260202195803-dba9d589def2 // indirect
|
||||
github.com/containerd/cgroups/v3 v3.1.3 // indirect
|
||||
github.com/containerd/containerd/api v1.11.1 // indirect
|
||||
github.com/containerd/containerd/v2 v2.3.2 // indirect
|
||||
github.com/containerd/containerd/v2 v2.3.3 // indirect
|
||||
github.com/containerd/continuity v0.5.0 // indirect
|
||||
github.com/containerd/errdefs v1.0.0 // indirect
|
||||
github.com/containerd/errdefs/pkg v0.3.0 // indirect
|
||||
@@ -183,14 +183,14 @@ require (
|
||||
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.5.3+incompatible // indirect
|
||||
github.com/docker/cli v29.6.1+incompatible // indirect
|
||||
github.com/docker/docker-credential-helpers v0.9.5 // indirect
|
||||
github.com/docker/go-connections v0.7.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/envoyproxy/go-control-plane/envoy v1.37.0 // indirect
|
||||
github.com/envoyproxy/protoc-gen-validate v1.3.3 // 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
|
||||
@@ -238,8 +238,8 @@ require (
|
||||
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.2 // indirect
|
||||
github.com/moby/moby/client v0.4.1 // indirect
|
||||
github.com/moby/moby/api v1.55.0 // indirect
|
||||
github.com/moby/moby/client v0.5.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
|
||||
@@ -257,7 +257,7 @@ require (
|
||||
github.com/opencontainers/image-spec v1.1.1 // indirect
|
||||
github.com/opencontainers/runtime-spec v1.3.0 // indirect
|
||||
github.com/pborman/indent v1.2.1 // indirect
|
||||
github.com/pelletier/go-toml/v2 v2.3.1 // indirect
|
||||
github.com/pelletier/go-toml/v2 v2.4.3 // indirect
|
||||
github.com/pierrec/lz4/v4 v4.1.26 // indirect
|
||||
github.com/piprate/json-gold v0.7.0 // indirect
|
||||
github.com/pjbgf/sha1cd v0.6.0 // indirect
|
||||
@@ -299,7 +299,7 @@ require (
|
||||
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/detectors/gcp v1.43.0 // indirect
|
||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.68.0 // indirect
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.68.0 // indirect
|
||||
go.opentelemetry.io/otel v1.43.0 // indirect
|
||||
@@ -309,22 +309,22 @@ require (
|
||||
go.opentelemetry.io/otel/trace v1.43.0 // indirect
|
||||
go.yaml.in/yaml/v4 v4.0.0-rc.2 // indirect
|
||||
go4.org v0.0.0-20230225012048-214862532bf5 // indirect
|
||||
golang.org/x/crypto v0.53.0 // indirect
|
||||
golang.org/x/crypto v0.54.0 // indirect
|
||||
golang.org/x/oauth2 v0.36.0 // indirect
|
||||
golang.org/x/sync v0.21.0 // indirect
|
||||
golang.org/x/sys v0.46.0 // indirect
|
||||
golang.org/x/term v0.44.0 // indirect
|
||||
golang.org/x/text v0.38.0 // indirect
|
||||
golang.org/x/sync v0.22.0 // indirect
|
||||
golang.org/x/sys v0.47.0 // indirect
|
||||
golang.org/x/term v0.45.0 // indirect
|
||||
golang.org/x/text v0.40.0 // indirect
|
||||
golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 // indirect
|
||||
gonum.org/v1/gonum v0.17.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-20260401024825-9d38bb4040a9 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20260406210006-6f92a3bedf2d // indirect
|
||||
google.golang.org/grpc v1.80.0 // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20260414002931-afd174a4e478 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20260414002931-afd174a4e478 // indirect
|
||||
google.golang.org/grpc v1.82.1 // indirect
|
||||
google.golang.org/protobuf v1.36.12-0.20260120151049-f2248ac996af // indirect
|
||||
gopkg.in/warnings.v0 v0.1.2 // indirect
|
||||
modernc.org/libc v1.73.4 // indirect
|
||||
modernc.org/libc v1.74.1 // indirect
|
||||
modernc.org/mathutil v1.7.1 // indirect
|
||||
modernc.org/memory v1.11.0 // indirect
|
||||
)
|
||||
|
||||
@@ -82,8 +82,8 @@ github.com/CycloneDX/cyclonedx-go v0.11.0/go.mod h1:vUvbCXQsEm48OI6oOlanxstwNByX
|
||||
github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ=
|
||||
github.com/DataDog/zstd v1.5.5 h1:oWf5W7GtOLgp6bciQYDmhHHjdhYkALu6S/5Ni9ZgSvQ=
|
||||
github.com/DataDog/zstd v1.5.5/go.mod h1:g4AWEaM3yOg3HYfnJ3YIawPnVdXJh9QME85blwSAmyw=
|
||||
github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.31.0 h1:DHa2U07rk8syqvCge0QIGMCE1WxGj9njT44GH7zNJLQ=
|
||||
github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.31.0/go.mod h1:P4WPRUkOhJC13W//jWpyfJNDAIpvRbAUIYLX/4jtlE0=
|
||||
github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.32.0 h1:rIkQfkCOVKc1OiRCNcSDD8ml5RJlZbH/Xsq7lbpynwc=
|
||||
github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.32.0/go.mod h1:RD2SsorTmYhF6HkTmDw7KmPYQk8OBYwTkuasChwv7R4=
|
||||
github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.55.0 h1:UnDZ/zFfG1JhH/DqxIZYU/1CUAlTUScoXD/LcM2Ykk8=
|
||||
github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.55.0/go.mod h1:IA1C1U7jO/ENqm/vhi7V9YYpBsp+IMyqNrEN94N7tVc=
|
||||
github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/cloudmock v0.55.0 h1:7t/qx5Ost0s0wbA/VDrByOooURhp+ikYwv20i9Y07TQ=
|
||||
@@ -136,8 +136,8 @@ github.com/anchore/go-lzo v0.1.1 h1:IwL/fvkdtlIrYIXck6WxZ3nb8WjjHziYYmGxlooyOnM=
|
||||
github.com/anchore/go-lzo v0.1.1/go.mod h1:3kLx0bve2oN1iDwgM1U5zGku1Tfbdb0No5qp1eL1fIk=
|
||||
github.com/anchore/go-macholibre v0.1.1 h1:sTBHi3S1WVIOCamc6NyT8Sn9mBmD30DCTfjfVm4k6/M=
|
||||
github.com/anchore/go-macholibre v0.1.1/go.mod h1:YNq2610RlvGCK0Za+Klz/OCMtUaEnwwAGA/VfUAQaro=
|
||||
github.com/anchore/go-rpmdb v0.1.0 h1:Q8dc208/HYzCqhx0L1zurfm1UPil24hlo9NjkdFmLdE=
|
||||
github.com/anchore/go-rpmdb v0.1.0/go.mod h1:eQVa6QFGzKy0qMcnW2pez0XBczvgwSjw9vA23qifEyU=
|
||||
github.com/anchore/go-rpmdb v0.2.0 h1:ixcyMg/guhBL9XjBVwhTv9CG48xO07Qkg2uDX2+zx/c=
|
||||
github.com/anchore/go-rpmdb v0.2.0/go.mod h1:ATsRlpCXstnoYfzqBfhwGw0U2dolx1BBQ9rAU8jWBAw=
|
||||
github.com/anchore/go-struct-converter v0.2.0-rc2 h1:q+859fW2/jbHJHB2etbNfRlFwYpknyvbqqk1hUdamQ4=
|
||||
github.com/anchore/go-struct-converter v0.2.0-rc2/go.mod h1:cDBA5vhcR62nXWo8QH9/Kk2807o65ISaHPNPX66L+Uw=
|
||||
github.com/anchore/go-sync v0.1.1 h1:91SZ+YqUIIHmf2jPAYZPuHqM/ZqnK1pVJDWtET6+AJE=
|
||||
@@ -146,8 +146,8 @@ github.com/anchore/go-version v1.2.2-0.20200701162849-18adb9c92b9b h1:e1bmaoJfZV
|
||||
github.com/anchore/go-version v1.2.2-0.20200701162849-18adb9c92b9b/go.mod h1:Bkc+JYWjMCF8OyZ340IMSIi2Ebf3uwByOk6ho4wne1E=
|
||||
github.com/anchore/packageurl-go v0.2.0 h1:CkrM4RMUwrEGAiE1OVlxaZNzWj0TuHRey7o4T/EAErk=
|
||||
github.com/anchore/packageurl-go v0.2.0/go.mod h1:2JCgOQMIsqZ7TmliXG4PnUthPJAKE3mWQbsW2XHjAOE=
|
||||
github.com/anchore/stereoscope v0.2.2 h1:SGTLGoF6GHmKEn9Bb6LYpzzgz9nhvMZgN/c4fTSQjYY=
|
||||
github.com/anchore/stereoscope v0.2.2/go.mod h1:ylJXJKebLctP7u9ewguB1d0zUETJxvAA7r2DiuljDTM=
|
||||
github.com/anchore/stereoscope v0.3.0 h1:6mGGRxm4zRKj/jNiSM7g6XGwWihrnkQRJj11hcULDqY=
|
||||
github.com/anchore/stereoscope v0.3.0/go.mod h1:QIBWxa5WCrjtBqXH0+RIuECATrffcbaNdMWquZ83+OI=
|
||||
github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8=
|
||||
github.com/andybalholm/brotli v1.2.0 h1:ukwgCxwYrmACq68yiUqwIWnGY0cTPox/M94sVwToPjQ=
|
||||
github.com/andybalholm/brotli v1.2.0/go.mod h1:rzTDkvFWvIrjDXZHkuS16NPggd91W3kUSvPlQ1pLaKY=
|
||||
@@ -290,14 +290,14 @@ github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWH
|
||||
github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
|
||||
github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
|
||||
github.com/cncf/xds/go v0.0.0-20211130200136-a8f946100490/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
|
||||
github.com/cncf/xds/go v0.0.0-20251210132809-ee656c7534f5 h1:6xNmx7iTtyBRev0+D/Tv1FZd4SCg8axKApyNyRsAt/w=
|
||||
github.com/cncf/xds/go v0.0.0-20251210132809-ee656c7534f5/go.mod h1:KdCmV+x/BuvyMxRnYBlmVaq4OLiKW6iRQfvC62cvdkI=
|
||||
github.com/cncf/xds/go v0.0.0-20260202195803-dba9d589def2 h1:aBangftG7EVZoUb69Os8IaYg++6uMOdKK83QtkkvJik=
|
||||
github.com/cncf/xds/go v0.0.0-20260202195803-dba9d589def2/go.mod h1:qwXFYgsP6T7XnJtbKlf1HP8AjxZZyzxMmc+Lq5GjlU4=
|
||||
github.com/containerd/cgroups/v3 v3.1.3 h1:eUNflyMddm18+yrDmZPn3jI7C5hJ9ahABE5q6dyLYXQ=
|
||||
github.com/containerd/cgroups/v3 v3.1.3/go.mod h1:PKZ2AcWmSBsY/tJUVhtS/rluX0b1uq1GmPO1ElCmbOw=
|
||||
github.com/containerd/containerd/api v1.11.1 h1:h8nfoDW9+fNsC/9TwiAHj8B1GzXKtR4eFtkhi/X5RLU=
|
||||
github.com/containerd/containerd/api v1.11.1/go.mod h1:CaQFRu+N1MtbgL6JDOJLUB1hCKESU1lD6MuTJhgtdlw=
|
||||
github.com/containerd/containerd/v2 v2.3.2 h1:eLven1YxRMkeiKu7IcMrPKE+gn8sGR1DqHbbshMEvWM=
|
||||
github.com/containerd/containerd/v2 v2.3.2/go.mod h1:rHKGm3VW6wNrINb3x8mNT+w7qYXFVElTt/8HTuxVhD4=
|
||||
github.com/containerd/containerd/v2 v2.3.3 h1:MUNBVVBTBpPll7KPh5GTvkC3cfG03PQLAHVdsUoue9k=
|
||||
github.com/containerd/containerd/v2 v2.3.3/go.mod h1:rHKGm3VW6wNrINb3x8mNT+w7qYXFVElTt/8HTuxVhD4=
|
||||
github.com/containerd/continuity v0.5.0 h1:7a85HZpCSs+1Zps0Ee3DPSuAWY+0SJM1JNM51nlEVDg=
|
||||
github.com/containerd/continuity v0.5.0/go.mod h1:/lNJvtJKUQStBzpVQ1+rasXO1LAWtUQssk28EZvJ3nE=
|
||||
github.com/containerd/errdefs v1.0.0 h1:tg5yIfIlQIrxYtu9ajqY42W3lpS19XqdxRQeEwYG8PI=
|
||||
@@ -339,8 +339,8 @@ github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5Qvfr
|
||||
github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E=
|
||||
github.com/djherbis/times v1.6.0 h1:w2ctJ92J8fBvWPxugmXIv7Nz7Q3iDMKNx9v5ocVH20c=
|
||||
github.com/djherbis/times v1.6.0/go.mod h1:gOHeRAz2h+VJNZ5Gmc/o7iD9k4wW7NMVqieYCY99oc0=
|
||||
github.com/docker/cli v29.5.3+incompatible h1:nbEFfz774vBwQ5KRYv7c/AghjReqnGISvrRhzjV0evs=
|
||||
github.com/docker/cli v29.5.3+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
|
||||
github.com/docker/cli v29.6.1+incompatible h1:oO7F4nn3Ovr/5TlfTUWFbMwBSS/B7Xs6Epv26gBrUP8=
|
||||
github.com/docker/cli v29.6.1+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
|
||||
github.com/docker/docker-credential-helpers v0.9.5 h1:EFNN8DHvaiK8zVqFA2DT6BjXE0GzfLOZ38ggPTKePkY=
|
||||
github.com/docker/docker-credential-helpers v0.9.5/go.mod h1:v1S+hepowrQXITkEfw6o4+BMbGot02wiKpzWhGUZK6c=
|
||||
github.com/docker/go-connections v0.7.0 h1:6SsRfJddP22WMrCkj19x9WKjEDTB+ahsdiGYf0mN39c=
|
||||
@@ -371,14 +371,14 @@ github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.
|
||||
github.com/envoyproxy/go-control-plane v0.10.1/go.mod h1:AY7fTTXNdv/aJ2O5jwpxAPOWUZ7hQAEvzN5Pf27BkQQ=
|
||||
github.com/envoyproxy/go-control-plane v0.14.0 h1:hbG2kr4RuFj222B6+7T83thSPqLjwBIfQawTkC++2HA=
|
||||
github.com/envoyproxy/go-control-plane v0.14.0/go.mod h1:NcS5X47pLl/hfqxU70yPwL9ZMkUlwlKxtAohpi2wBEU=
|
||||
github.com/envoyproxy/go-control-plane/envoy v1.36.0 h1:yg/JjO5E7ubRyKX3m07GF3reDNEnfOboJ0QySbH736g=
|
||||
github.com/envoyproxy/go-control-plane/envoy v1.36.0/go.mod h1:ty89S1YCCVruQAm9OtKeEkQLTb+Lkz0k8v9W0Oxsv98=
|
||||
github.com/envoyproxy/go-control-plane/envoy v1.37.0 h1:u3riX6BoYRfF4Dr7dwSOroNfdSbEPe9Yyl09/B6wBrQ=
|
||||
github.com/envoyproxy/go-control-plane/envoy v1.37.0/go.mod h1:DReE9MMrmecPy+YvQOAOHNYMALuowAnbjjEMkkWOi6A=
|
||||
github.com/envoyproxy/go-control-plane/ratelimit v0.1.0 h1:/G9QYbddjL25KvtKTv3an9lx6VBE2cnb8wp1vEGNYGI=
|
||||
github.com/envoyproxy/go-control-plane/ratelimit v0.1.0/go.mod h1:Wk+tMFAFbCXaJPzVVHnPgRKdUdwW/KdbRt94AzgRee4=
|
||||
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
||||
github.com/envoyproxy/protoc-gen-validate v0.6.2/go.mod h1:2t7qjJNvHPx8IjnBOzl9E9/baC+qXE/TeeyBRzgJDws=
|
||||
github.com/envoyproxy/protoc-gen-validate v1.3.0 h1:TvGH1wof4H33rezVKWSpqKz5NXWg5VPuZ0uONDT6eb4=
|
||||
github.com/envoyproxy/protoc-gen-validate v1.3.0/go.mod h1:HvYl7zwPa5mffgyeTUHA9zHIH36nmrm7oCbo4YKoSWA=
|
||||
github.com/envoyproxy/protoc-gen-validate v1.3.3 h1:MVQghNeW+LZcmXe7SY1V36Z+WFMDjpqGAGacLe2T0ds=
|
||||
github.com/envoyproxy/protoc-gen-validate v1.3.3/go.mod h1:TsndJ/ngyIdQRhMcVVGDDHINPLWB7C82oDArY51KfB0=
|
||||
github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f h1:Y/CXytFA4m6baUTXGLOoWe4PQhGxaX0KpnayAqC48p4=
|
||||
github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f/go.mod h1:vw97MGsxSvLiUE2X8qFplwetxpGLQrlU1Q9AUEIzCaM=
|
||||
github.com/erofs/go-erofs v0.3.0 h1:o/W5ABAA3sHYl97WL93dacKEfeDpJhdFf3c2snAti7I=
|
||||
@@ -410,8 +410,8 @@ github.com/github/go-spdx/v2 v2.7.0 h1:GzfXx4wFdlilARxmFRXW/mgUy3A4vSqZocCMFV6XF
|
||||
github.com/github/go-spdx/v2 v2.7.0/go.mod h1:Ftc45YYG1WzpzwEPKRVm9Jv8vDqOrN4gWoCkK+bHer0=
|
||||
github.com/gkampitakis/ciinfo v0.3.4 h1:5eBSibVuSMbb/H6Elc0IIEFbkzCJi3lm94n0+U7Z0KY=
|
||||
github.com/gkampitakis/ciinfo v0.3.4/go.mod h1:1NIwaOcFChN4fa/B0hEBdAb6npDlFL8Bwx4dfRLRqAo=
|
||||
github.com/gkampitakis/go-snaps v0.5.22 h1:xg9omphRnbDnimMCl1KqznC4krlxOGpkB0vDSfX2P7M=
|
||||
github.com/gkampitakis/go-snaps v0.5.22/go.mod h1:uy3lVzCCRRsAwYqSocyw5fY8xRLCYEfqoOJNxr8HonM=
|
||||
github.com/gkampitakis/go-snaps v0.5.23 h1:okh5QR48zpUjpWtu65AtqxdCY8huJq+dEDuUzd1PuKg=
|
||||
github.com/gkampitakis/go-snaps v0.5.23/go.mod h1:uy3lVzCCRRsAwYqSocyw5fY8xRLCYEfqoOJNxr8HonM=
|
||||
github.com/glebarez/go-sqlite v1.20.3 h1:89BkqGOXR9oRmG58ZrzgoY/Fhy5x0M+/WV48U5zVrZ4=
|
||||
github.com/glebarez/go-sqlite v1.20.3/go.mod h1:u3N6D/wftiAzIOJtZl6BmedqxmmkDfH3q+ihjqxC9u0=
|
||||
github.com/gliderlabs/ssh v0.3.8 h1:a4YXD1V7xMF9g5nTkdfnja3Sxy1PVDCj1Zg4Wb8vY6c=
|
||||
@@ -558,8 +558,8 @@ github.com/gookit/assert v0.1.1/go.mod h1:jS5bmIVQZTIwk42uXl4lyj4iaaxx32tqH16CFj
|
||||
github.com/gookit/color v1.2.5/go.mod h1:AhIE+pS6D4Ql0SQWbBeXPHw7gY0/sjHoA4s/n1KB7xg=
|
||||
github.com/gookit/color v1.6.1 h1:KoTnDxJPRgrL0SoX0f8rCFg2zI0t4E3GZZBMo2nN8LU=
|
||||
github.com/gookit/color v1.6.1/go.mod h1:9ACFc7/1IpHGBW8RwuDm/0YEnhg3dwwXpoMsmtyHfjs=
|
||||
github.com/gpustack/gguf-parser-go v0.24.1 h1:nTYtL8HFK6ZhB90RKBu4oX2b3ZHpJLrMmKRfL9w9Cyc=
|
||||
github.com/gpustack/gguf-parser-go v0.24.1/go.mod h1:y4TwTtDqFWTK+xvprOjRUh+dowgU2TKCX37vRKvGiZ0=
|
||||
github.com/gpustack/gguf-parser-go v0.25.0 h1:1AMBhMKtI24nTtn588Bq53FqNiOvEw1x9Nb4HbRrThs=
|
||||
github.com/gpustack/gguf-parser-go v0.25.0/go.mod h1:y4TwTtDqFWTK+xvprOjRUh+dowgU2TKCX37vRKvGiZ0=
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=
|
||||
github.com/hashicorp/aws-sdk-go-base/v2 v2.0.0-beta.72 h1:vTCWu1wbdYo7PEZFem/rlr01+Un+wwVmI7wiegFdRLk=
|
||||
github.com/hashicorp/aws-sdk-go-base/v2 v2.0.0-beta.72/go.mod h1:Vn+BBgKQHVQYdVQ4NZDICE1Brb+JfaONyDHr3q07oQc=
|
||||
@@ -723,10 +723,10 @@ github.com/moby/docker-image-spec v1.3.1 h1:jMKff3w6PgbfSa69GfNg+zN/XLhfXJGnEx3N
|
||||
github.com/moby/docker-image-spec v1.3.1/go.mod h1:eKmb5VW8vQEh/BAr2yvVNvuiJuY6UIocYsFu/DxxRpo=
|
||||
github.com/moby/locker v1.0.1 h1:fOXqR41zeveg4fFODix+1Ch4mj/gT0NE1XJbp/epuBg=
|
||||
github.com/moby/locker v1.0.1/go.mod h1:S7SDdo5zpBK84bzzVlKr2V0hz+7x9hWbYC/kq7oQppc=
|
||||
github.com/moby/moby/api v1.54.2 h1:wiat9QAhnDQjA7wk1kh/TqHz2I1uUA7M7t9SAl/JNXg=
|
||||
github.com/moby/moby/api v1.54.2/go.mod h1:+RQ6wluLwtYaTd1WnPLykIDPekkuyD/ROWQClE83pzs=
|
||||
github.com/moby/moby/client v0.4.1 h1:DMQgisVoMkmMs7fp3ROSdiBnoAu8+vo3GggFl06M/wY=
|
||||
github.com/moby/moby/client v0.4.1/go.mod h1:z52C9O2POPOsnxZAy//WtKcQ32P+jT/NGeXu/7nfjGQ=
|
||||
github.com/moby/moby/api v1.55.0 h1:2/sexvQyqIWS8pRSCFddBfpW2qE7vR7FCL+vN8pxwMc=
|
||||
github.com/moby/moby/api v1.55.0/go.mod h1:+RQ6wluLwtYaTd1WnPLykIDPekkuyD/ROWQClE83pzs=
|
||||
github.com/moby/moby/client v0.5.0 h1:5XhyPk2fuOWf6RlSFa3MkIIgDZkF25xToXW8Q/BH7cc=
|
||||
github.com/moby/moby/client v0.5.0/go.mod h1:rcVpF8ncl9vo5gaIBdol6CnbEtSj1uxMvEV/UrykF/s=
|
||||
github.com/moby/sys/mountinfo v0.7.2 h1:1shs6aH5s4o5H2zQLn796ADW1wMrIwHsyJ2v9KouLrg=
|
||||
github.com/moby/sys/mountinfo v0.7.2/go.mod h1:1YOa8w8Ih7uW0wALDUgT1dTTSBrZ+HiBLGws92L2RU4=
|
||||
github.com/moby/sys/sequential v0.6.0 h1:qrx7XFUd/5DxtqcoH1h438hF5TmOvzC/lspjy7zgvCU=
|
||||
@@ -786,8 +786,8 @@ github.com/pborman/indent v1.2.1/go.mod h1:FitS+t35kIYtB5xWTZAPhnmrxcciEEOdbyrrp
|
||||
github.com/pelletier/go-toml v1.9.4/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c=
|
||||
github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8=
|
||||
github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c=
|
||||
github.com/pelletier/go-toml/v2 v2.3.1 h1:MYEvvGnQjeNkRF1qUuGolNtNExTDwct51yp7olPtrEc=
|
||||
github.com/pelletier/go-toml/v2 v2.3.1/go.mod h1:2gIqNv+qfxSVS7cM2xJQKtLSTLUE9V8t9Stt+h56mCY=
|
||||
github.com/pelletier/go-toml/v2 v2.4.3 h1:GTRvJQutkOSftxIFD5xw9aepkYNuPWmVJpffdDPYVpY=
|
||||
github.com/pelletier/go-toml/v2 v2.4.3/go.mod h1:2gIqNv+qfxSVS7cM2xJQKtLSTLUE9V8t9Stt+h56mCY=
|
||||
github.com/pierrec/lz4/v4 v4.1.26 h1:GrpZw1gZttORinvzBdXPUXATeqlJjqUG/D87TKMnhjY=
|
||||
github.com/pierrec/lz4/v4 v4.1.26/go.mod h1:EoQMVJgeeEOMsCqCzqFm2O0cJvljX2nGZjcRIPL34O4=
|
||||
github.com/piprate/json-gold v0.7.0 h1:bEMirgA5y8Z2loTQfxyIFfY+EflxH1CTP6r/KIlcJNw=
|
||||
@@ -998,8 +998,8 @@ go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0=
|
||||
go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo=
|
||||
go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64=
|
||||
go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y=
|
||||
go.opentelemetry.io/contrib/detectors/gcp v1.39.0 h1:kWRNZMsfBHZ+uHjiH4y7Etn2FK26LAGkNFw7RHv1DhE=
|
||||
go.opentelemetry.io/contrib/detectors/gcp v1.39.0/go.mod h1:t/OGqzHBa5v6RHZwrDBJ2OirWc+4q/w2fTbLZwAKjTk=
|
||||
go.opentelemetry.io/contrib/detectors/gcp v1.43.0 h1:62yY3dT7/ShwOxzA0RsKRgshBmfElKI4d/Myu2OxDFU=
|
||||
go.opentelemetry.io/contrib/detectors/gcp v1.43.0/go.mod h1:RyaZMFY7yi1kAs45S6mbFGz8O8rqB0dTY14uzvG4LCs=
|
||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.68.0 h1:0Qx7VGBacMm9ZENQ7TnNObTYI4ShC+lHI16seduaxZo=
|
||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.68.0/go.mod h1:Sje3i3MjSPKTSPvVWCaL8ugBzJwik3u4smCjUeuupqg=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.68.0 h1:CqXxU8VOmDefoh0+ztfGaymYbhdB/tT3zs79QaZTNGY=
|
||||
@@ -1040,8 +1040,8 @@ golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPh
|
||||
golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/crypto v0.53.0 h1:QZ4Muo8THX6CizN2vPPd5fBGHyogrdK9fG4wLPFUsto=
|
||||
golang.org/x/crypto v0.53.0/go.mod h1:DNLU434OwVakk9PzuwV8w62mAJpRJL3vsgcfp4Qnsio=
|
||||
golang.org/x/crypto v0.54.0 h1:YLIA59K4fiNzHzjnZt2tUJQjQtUWfWbeHBqKtk3eScw=
|
||||
golang.org/x/crypto v0.54.0/go.mod h1:KWL8ny2AZdGR2cWmzeHrp2azQPGogOv+HeQaVEXC2dk=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
|
||||
@@ -1081,8 +1081,8 @@ golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.5.0/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro=
|
||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||
golang.org/x/mod v0.37.0 h1:vF1DjpVEshcIqoEaauuHebaLk1O1forxjxBaVn884JQ=
|
||||
golang.org/x/mod v0.37.0/go.mod h1:m8S8VeM9r4dzDwjrKO0a1sZP3YjeMamRRlD+fmR2Q/0=
|
||||
golang.org/x/mod v0.38.0 h1:MECBjubtXD7yj4HrhIUcywNaGeNVUdfVnxmPajOk4yk=
|
||||
golang.org/x/mod v0.38.0/go.mod h1:V6Xz0pq8TQ3dGqVQ1FVHuelZpAL0uNhSkk9ogYP3c40=
|
||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
@@ -1127,8 +1127,8 @@ golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d/go.mod h1:9nx3DQGgdP8bBQD5qx
|
||||
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||
golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
||||
golang.org/x/net v0.56.0 h1:Rw8j/hFzGvJUZwNBXnAtf5sVDVt+65SK2C7IxCxZt5o=
|
||||
golang.org/x/net v0.56.0/go.mod h1:D3Ku6r+V6JROoZK144D2XfMHFcMq/0zSfLelVTCFKec=
|
||||
golang.org/x/net v0.57.0 h1:K5+3DljvIuDG9/Jv9rvyMywYNFCQ9RSUY6OOTTkT+tE=
|
||||
golang.org/x/net v0.57.0/go.mod h1:KpXc8iv+r3XplLAG/f7Jsf9RPszJzdR0f58q9vGOuEU=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
@@ -1160,8 +1160,8 @@ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJ
|
||||
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.21.0 h1:HLII4xRRTtCRkxYp4HNFF0Js/Og6q2i++KXbg0gHCwM=
|
||||
golang.org/x/sync v0.21.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0=
|
||||
golang.org/x/sync v0.22.0 h1:SZjpbeLmrCk4xhRSZFNZW5gFUeCeFgjekvI/+gfScek=
|
||||
golang.org/x/sync v0.22.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0=
|
||||
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
@@ -1236,13 +1236,13 @@ golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBc
|
||||
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.46.0 h1:noSf2Fq6F8DBgS+LysIkx7rIExoNHJsxOAtPp4rthXw=
|
||||
golang.org/x/sys v0.46.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
|
||||
golang.org/x/sys v0.47.0 h1:o7XGOvZQCADBQQ4Y7VNq2dRWQR7JmOUW8Kxx4ZsNgWs=
|
||||
golang.org/x/sys v0.47.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
|
||||
golang.org/x/term v0.44.0 h1:0rLvDRCtNj0gZkyIXhCyOb2OAzEhLVqc4B+hrsBhrmc=
|
||||
golang.org/x/term v0.44.0/go.mod h1:7ze4MdzUzLXpSAoFP1H0bOI9aXDqveSvatT5vKcFh2Y=
|
||||
golang.org/x/term v0.45.0 h1:NwWyBmoJCbfTHpxrWoZ9C6/VxOf7ic219I8xZZFdrf0=
|
||||
golang.org/x/term v0.45.0/go.mod h1:9aqxs0blBcrm/n0L9QW0aRVD+ktan8ssZromtqJC43w=
|
||||
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
@@ -1253,8 +1253,8 @@ golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/text v0.38.0 h1:sXmwo9DwP3OK9EZ7PqAdaooSGozfl/3a6/xJcbzPRhE=
|
||||
golang.org/x/text v0.38.0/go.mod h1:YXZt3QhHUKYT53r2lLKFIVi6Ao1jdzrTR/KQ09qyxF4=
|
||||
golang.org/x/text v0.40.0 h1:Ub2Z6/xjgF1WrYQz2nuITOEegKFtiIy+rieRJ5lHZKs=
|
||||
golang.org/x/text v0.40.0/go.mod h1:hpnzDAfGV753zIKo+wk3u1bVKCGPbrnF7+7LBF/UHVY=
|
||||
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
@@ -1315,8 +1315,8 @@ golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||
golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||
golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||
golang.org/x/tools v0.47.0 h1:7Kn5x/d1svx/PzryTsqeoZN4TZwqeH5pGWjefhLi/1Q=
|
||||
golang.org/x/tools v0.47.0/go.mod h1:dFHnyTvFWY212G+h7ZY4Vsp/K3U4/7W9TyVaAul8uCA=
|
||||
golang.org/x/tools v0.48.0 h1:3+hClM1aLL5mjMKm5ovokw9epgRXPuu2tILgismM6RE=
|
||||
golang.org/x/tools v0.48.0/go.mod h1:08xX0orndb/F7jJxGDicx061tyd5pcMto75YMAXr6lk=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
@@ -1431,10 +1431,10 @@ google.golang.org/genproto v0.0.0-20211206160659-862468c7d6e0/go.mod h1:5CzLGKJ6
|
||||
google.golang.org/genproto v0.0.0-20211208223120-3a66f561d7aa/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
|
||||
google.golang.org/genproto v0.0.0-20260128011058-8636f8732409 h1:VQZ/yAbAtjkHgH80teYd2em3xtIkkHd7ZhqfH2N9CsM=
|
||||
google.golang.org/genproto v0.0.0-20260128011058-8636f8732409/go.mod h1:rxKD3IEILWEu3P44seeNOAwZN4SaoKaQ/2eTg4mM6EM=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20260401024825-9d38bb4040a9 h1:VPWxll4HlMw1Vs/qXtN7BvhZqsS9cdAittCNvVENElA=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20260401024825-9d38bb4040a9/go.mod h1:7QBABkRtR8z+TEnmXTqIqwJLlzrZKVfAUm7tY3yGv0M=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20260406210006-6f92a3bedf2d h1:wT2n40TBqFY6wiwazVK9/iTWbsQrgk5ZfCSVFLO9LQA=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20260406210006-6f92a3bedf2d/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20260414002931-afd174a4e478 h1:yQugLulqltosq0B/f8l4w9VryjV+N/5gcW0jQ3N8Qec=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20260414002931-afd174a4e478/go.mod h1:C6ADNqOxbgdUUeRTU+LCHDPB9ttAMCTff6auwCVa4uc=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20260414002931-afd174a4e478 h1:RmoJA1ujG+/lRGNfUnOMfhCy5EipVMyvUE+KNbPbTlw=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20260414002931-afd174a4e478/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8=
|
||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
|
||||
google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
|
||||
@@ -1462,8 +1462,8 @@ google.golang.org/grpc v1.39.1/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnD
|
||||
google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34=
|
||||
google.golang.org/grpc v1.40.1/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34=
|
||||
google.golang.org/grpc v1.42.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU=
|
||||
google.golang.org/grpc v1.80.0 h1:Xr6m2WmWZLETvUNvIUmeD5OAagMw3FiKmMlTdViWsHM=
|
||||
google.golang.org/grpc v1.80.0/go.mod h1:ho/dLnxwi3EDJA4Zghp7k2Ec1+c2jqup0bFkw07bwF4=
|
||||
google.golang.org/grpc v1.82.1 h1:NnAxzGRA0677vCa4BUkOAnO5+FfQqVl9iUXeD0IqcGE=
|
||||
google.golang.org/grpc v1.82.1/go.mod h1:yzTZ1TB1Z3SG+LIYaI+WiE8D5+PZ3ArnrSp8zF3+/ZA=
|
||||
google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw=
|
||||
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
|
||||
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
|
||||
@@ -1513,20 +1513,20 @@ honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9
|
||||
honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
||||
howett.net/plist v1.0.1 h1:37GdZ8tP09Q35o9ych3ehygcsL+HqKSwzctveSlarvM=
|
||||
howett.net/plist v1.0.1/go.mod h1:lqaXoTrLY4hg8tnEzNru53gicrbv7rrk+2xJA/7hw9g=
|
||||
modernc.org/cc/v4 v4.28.4 h1:Hd/4Es+MBj+/7hSdZaisNyu6bv3V0Dp2MdllyfqaH+c=
|
||||
modernc.org/cc/v4 v4.28.4/go.mod h1:OnovgIhbbMXMu1aISnJ0wvVD1KnW+cAUJkIrAWh+kVI=
|
||||
modernc.org/ccgo/v4 v4.34.4 h1:OVnSOWQjVKOYkFxoHYB+qQmSHK5gqMqARM+K9DpR/Ws=
|
||||
modernc.org/ccgo/v4 v4.34.4/go.mod h1:qdKqE8FNIYyysougB1RX9MxCzp5oJOcQXSobANJ4TuE=
|
||||
modernc.org/cc/v4 v4.29.0 h1:CXgwL8cvxmyzBQZzbSl/6xFtMCryb6u8IOqDci39cgc=
|
||||
modernc.org/cc/v4 v4.29.0/go.mod h1:OnovgIhbbMXMu1aISnJ0wvVD1KnW+cAUJkIrAWh+kVI=
|
||||
modernc.org/ccgo/v4 v4.34.6 h1:sBgfIwyN0TQ9C5hwIeuqyeAKyMWnbvj2fvpF4L11uzU=
|
||||
modernc.org/ccgo/v4 v4.34.6/go.mod h1:SZ8YcN9NG7XVsQYdm6jYBvi8PQP1qi+kqB6OhjqI3Fk=
|
||||
modernc.org/fileutil v1.4.0 h1:j6ZzNTftVS054gi281TyLjHPp6CPHr2KCxEXjEbD6SM=
|
||||
modernc.org/fileutil v1.4.0/go.mod h1:EqdKFDxiByqxLk8ozOxObDSfcVOv/54xDs/DUHdvCUU=
|
||||
modernc.org/gc/v2 v2.6.5 h1:nyqdV8q46KvTpZlsw66kWqwXRHdjIlJOhG6kxiV/9xI=
|
||||
modernc.org/gc/v2 v2.6.5/go.mod h1:YgIahr1ypgfe7chRuJi2gD7DBQiKSLMPgBQe9oIiito=
|
||||
modernc.org/gc/v3 v3.1.3 h1:6QAplYyVO+KdPW3pGnqmJDUxtkec8ooEWvks/hhU3lc=
|
||||
modernc.org/gc/v3 v3.1.3/go.mod h1:HFK/6AGESC7Ex+EZJhJ2Gni6cTaYpSMmU/cT9RmlfYY=
|
||||
modernc.org/gc/v3 v3.1.4 h1:2g65LGVSmFQrXeITAw97x7hCRvZFcyE1uDP+7Vng7JI=
|
||||
modernc.org/gc/v3 v3.1.4/go.mod h1:HFK/6AGESC7Ex+EZJhJ2Gni6cTaYpSMmU/cT9RmlfYY=
|
||||
modernc.org/goabi0 v0.2.0 h1:HvEowk7LxcPd0eq6mVOAEMai46V+i7Jrj13t4AzuNks=
|
||||
modernc.org/goabi0 v0.2.0/go.mod h1:CEFRnnJhKvWT1c1JTI3Avm+tgOWbkOu5oPA8eH8LnMI=
|
||||
modernc.org/libc v1.73.4 h1:+ra4Ui8ngyt8HDcO1FTDPWlkAh6yOdaO2yAoh8MddQA=
|
||||
modernc.org/libc v1.73.4/go.mod h1:DXZ3eO8qMCNn2SnmTNCiC71nJ9Rcq3PsnpU6Vc4rWK8=
|
||||
modernc.org/libc v1.74.1 h1:bdR4VTKFMC4966QSNZ05XLGI/VwzVa2kTUX51Dm0riQ=
|
||||
modernc.org/libc v1.74.1/go.mod h1:uH4t5bOx3G3g9Xcmj10YKlTcVISlRDwv8VoQJG9n8Os=
|
||||
modernc.org/mathutil v1.7.1 h1:GCZVGXdaN8gTqB1Mf/usp1Y/hSqgI2vAGGP4jZMCxOU=
|
||||
modernc.org/mathutil v1.7.1/go.mod h1:4p5IwJITfppl0G4sUEDtCr4DthTaT47/N3aT6MhfgJg=
|
||||
modernc.org/memory v1.11.0 h1:o4QC8aMQzmcwCK3t3Ux/ZHmwFPzE6hf2Y5LbkRs+hbI=
|
||||
@@ -1535,8 +1535,8 @@ modernc.org/opt v0.2.0 h1:tGyef5ApycA7FSEOMraay9SaTk5zmbx7Tu+cJs4QKZg=
|
||||
modernc.org/opt v0.2.0/go.mod h1:03fq9lsNfvkYSfxrfUhZCWPk1lm4cq4N+Bh//bEtgns=
|
||||
modernc.org/sortutil v1.2.1 h1:+xyoGf15mM3NMlPDnFqrteY07klSFxLElE2PVuWIJ7w=
|
||||
modernc.org/sortutil v1.2.1/go.mod h1:7ZI3a3REbai7gzCLcotuw9AC4VZVpYMjDzETGsSMqJE=
|
||||
modernc.org/sqlite v1.53.0 h1:20WG8N9q4ji/dEqGk4uiI0c6OPjSeLTNYGFCc3+7c1M=
|
||||
modernc.org/sqlite v1.53.0/go.mod h1:xoEpOIpGrgT48H5iiyt/YXPCZPEzlfmfFwtk8Lklw8s=
|
||||
modernc.org/sqlite v1.54.0 h1:JCxR4qwkJvOaqAoYcgDoO25Nc+ROg6EJ2LfBVzdrgog=
|
||||
modernc.org/sqlite v1.54.0/go.mod h1:4ntCLuNmnH8+GNqjka1wNg7KJd5/Hi5FYp8K+XQ7GZw=
|
||||
modernc.org/strutil v1.2.1 h1:UneZBkQA+DX2Rp35KcM69cSsNES9ly8mQWD71HKlOA0=
|
||||
modernc.org/strutil v1.2.1/go.mod h1:EHkiggD70koQxjVdSBM3JKM7k6L0FbGE5eymy9i3B9A=
|
||||
modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y=
|
||||
|
||||
@@ -32,12 +32,15 @@ type parsedData struct {
|
||||
pkg.ApkDBEntry
|
||||
}
|
||||
|
||||
const maxApkDBFieldSize = 10 * 1024 * 1024
|
||||
|
||||
// parseApkDB parses packages from a given APK "installed" flat-file DB. For more
|
||||
// information on specific fields, see https://wiki.alpinelinux.org/wiki/Apk_spec.
|
||||
//
|
||||
//nolint:funlen
|
||||
func parseApkDB(ctx context.Context, resolver file.Resolver, env *generic.Environment, reader file.LocationReadCloser) ([]pkg.Package, []artifact.Relationship, error) {
|
||||
scanner := bufio.NewScanner(reader)
|
||||
scanner.Buffer(nil, maxApkDBFieldSize)
|
||||
|
||||
var errs error
|
||||
var apks []parsedData
|
||||
|
||||
@@ -719,6 +719,25 @@ func Test_processChecksum(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestParseApkDBAllowsLargeFieldValues(t *testing.T) {
|
||||
contents := strings.Join([]string{
|
||||
"P:large-description",
|
||||
"V:1.0-r0",
|
||||
"A:x86_64",
|
||||
"S:1",
|
||||
"I:1",
|
||||
"T:" + strings.Repeat("a", 70*1024),
|
||||
"",
|
||||
}, "\n")
|
||||
reader := file.NewLocationReadCloser(file.NewLocation("large-installed-db"), io.NopCloser(strings.NewReader(contents)))
|
||||
|
||||
pkgs, _, err := parseApkDB(context.Background(), nil, new(generic.Environment), reader)
|
||||
|
||||
require.NoError(t, err)
|
||||
require.Len(t, pkgs, 1)
|
||||
assert.Equal(t, "large-description", pkgs[0].Name)
|
||||
}
|
||||
|
||||
func Test_parseApkDB_expectedPkgNames(t *testing.T) {
|
||||
tests := []struct {
|
||||
fixture string
|
||||
|
||||
@@ -433,6 +433,16 @@ catalogers:
|
||||
cpes:
|
||||
- cpe:2.3:a:deno:deno:*:*:*:*:*:*:*:*
|
||||
type: BinaryPkg
|
||||
- method: glob
|
||||
criteria:
|
||||
- '**/bun'
|
||||
packages:
|
||||
- class: bun-binary
|
||||
name: bun
|
||||
purl: pkg:generic/bun
|
||||
cpes:
|
||||
- cpe:2.3:a:oven-sh:bun:*:*:*:*:*:*:*:*
|
||||
type: BinaryPkg
|
||||
- method: glob
|
||||
criteria:
|
||||
- '**/ghc*'
|
||||
|
||||
@@ -1565,6 +1565,50 @@ func Test_Cataloger_PositiveCases(t *testing.T) {
|
||||
Metadata: metadata("deno-binary"),
|
||||
},
|
||||
},
|
||||
{
|
||||
logicalFixture: "bun/0.5.9/linux-amd64",
|
||||
expected: pkg.Package{
|
||||
Name: "bun",
|
||||
Version: "0.5.9",
|
||||
Type: "binary",
|
||||
PURL: "pkg:generic/bun@0.5.9",
|
||||
Locations: locations("bun"),
|
||||
Metadata: metadata("bun-binary"),
|
||||
},
|
||||
},
|
||||
{
|
||||
logicalFixture: "bun/1.0.0/linux-amd64",
|
||||
expected: pkg.Package{
|
||||
Name: "bun",
|
||||
Version: "1.0.0",
|
||||
Type: "binary",
|
||||
PURL: "pkg:generic/bun@1.0.0",
|
||||
Locations: locations("bun"),
|
||||
Metadata: metadata("bun-binary"),
|
||||
},
|
||||
},
|
||||
{
|
||||
logicalFixture: "bun/1.1.0/linux-amd64",
|
||||
expected: pkg.Package{
|
||||
Name: "bun",
|
||||
Version: "1.1.0",
|
||||
Type: "binary",
|
||||
PURL: "pkg:generic/bun@1.1.0",
|
||||
Locations: locations("bun"),
|
||||
Metadata: metadata("bun-binary"),
|
||||
},
|
||||
},
|
||||
{
|
||||
logicalFixture: "bun/1.3.5/linux-amd64",
|
||||
expected: pkg.Package{
|
||||
Name: "bun",
|
||||
Version: "1.3.5",
|
||||
Type: "binary",
|
||||
PURL: "pkg:generic/bun@1.3.5",
|
||||
Locations: locations("bun"),
|
||||
Metadata: metadata("bun-binary"),
|
||||
},
|
||||
},
|
||||
{
|
||||
logicalFixture: "haskell-ghc/7.10.3/linux-amd64",
|
||||
expected: pkg.Package{
|
||||
|
||||
@@ -611,6 +611,20 @@ func DefaultClassifiers() []binutils.Classifier {
|
||||
PURL: mustPURL("pkg:generic/deno@version"),
|
||||
CPEs: singleCPE("cpe:2.3:a:deno:deno:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
|
||||
},
|
||||
{
|
||||
Class: "bun-binary",
|
||||
FileGlob: "**/bun",
|
||||
EvidenceMatcher: binutils.MatchAny(
|
||||
// bun 1.1.0
|
||||
// Bun v1.0.0
|
||||
m.FileContentsVersionMatcher(`(?m)[Bb]un v?(?P<version>[0-9]+\.[0-9]+\.[0-9]+)`),
|
||||
// bun-1.1.0
|
||||
m.FileContentsVersionMatcher(`(?m)bun-(?P<version>[0-9]+\.[0-9]+\.[0-9]+)`),
|
||||
),
|
||||
Package: "bun",
|
||||
PURL: mustPURL("pkg:generic/bun@version"),
|
||||
CPEs: singleCPE("cpe:2.3:a:oven-sh:bun:*:*:*:*:*:*:*:*"),
|
||||
},
|
||||
{
|
||||
Class: "haskell-ghc-binary",
|
||||
FileGlob: "**/ghc*",
|
||||
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
name: bun
|
||||
offset: 1000000
|
||||
length: 100
|
||||
snippetSha256: 0000000000000000000000000000000000000000000000000000000000000001
|
||||
fileSha256: 0000000000000000000000000000000000000000000000000000000000000001
|
||||
|
||||
### byte snippet to follow ###
|
||||
]
|
||||
|
||||
Bun v0.5.9
|
||||
bun-0.5.9
|
||||
JavaScript runtime for developing, testing, and bundling
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
name: bun
|
||||
offset: 1000000
|
||||
length: 100
|
||||
snippetSha256: 0000000000000000000000000000000000000000000000000000000000000002
|
||||
fileSha256: 0000000000000000000000000000000000000000000000000000000000000002
|
||||
|
||||
### byte snippet to follow ###
|
||||
]
|
||||
|
||||
Bun v1.0.0
|
||||
bun-1.0.0
|
||||
JavaScript runtime for developing, testing, and bundling
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
name: bun
|
||||
offset: 1000000
|
||||
length: 100
|
||||
snippetSha256: 0000000000000000000000000000000000000000000000000000000000000003
|
||||
fileSha256: 0000000000000000000000000000000000000000000000000000000000000003
|
||||
|
||||
### byte snippet to follow ###
|
||||
]
|
||||
|
||||
Bun v1.1.0
|
||||
bun-1.1.0
|
||||
JavaScript runtime for developing, testing, and bundling
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
name: bun
|
||||
offset: 1000000
|
||||
length: 100
|
||||
snippetSha256: 0000000000000000000000000000000000000000000000000000000000000004
|
||||
fileSha256: 0000000000000000000000000000000000000000000000000000000000000004
|
||||
|
||||
### byte snippet to follow ###
|
||||
]
|
||||
|
||||
Bun v1.3.5
|
||||
bun-1.3.5
|
||||
JavaScript runtime for developing, testing, and bundling
|
||||
@@ -156,7 +156,7 @@ func parseErlangString(data []byte, i *int) (erlangNode, error) {
|
||||
}
|
||||
if c == '\\' {
|
||||
*i++
|
||||
if len(data) >= *i {
|
||||
if *i >= len(data) {
|
||||
return node(nil), fmt.Errorf("invalid escape without closed string at %d", *i)
|
||||
}
|
||||
c = data[*i]
|
||||
|
||||
@@ -96,6 +96,11 @@ func Test_parseErlang(t *testing.T) {
|
||||
{ foo, bar }
|
||||
]}`,
|
||||
},
|
||||
{
|
||||
name: "string with an escaped quote",
|
||||
content: `
|
||||
{escaped, ["a\"b"]}`,
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
@@ -112,3 +117,14 @@ func Test_parseErlang(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func Test_parseErlangString_escapedByte(t *testing.T) {
|
||||
// a backslash escape mid-string used to always error out, since the bounds
|
||||
// check at the escape site was inverted (len(data) >= *i is true for
|
||||
// almost every position, not just an out-of-range one).
|
||||
data := []byte(`"a\"b"`)
|
||||
i := 0
|
||||
got, err := parseErlangString(data, &i)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, `a"b`, got.String())
|
||||
}
|
||||
|
||||
@@ -72,7 +72,7 @@ func (c *goModCataloger) parseGoModFile(ctx context.Context, resolver file.Resol
|
||||
|
||||
// only use go.mod packages NOT found in source analysis
|
||||
goModPackages := c.createGoModPackages(ctx, resolver, modFile, sourceModules, reader, digests)
|
||||
c.applyReplaceDirectives(ctx, resolver, modFile, goModPackages, reader, digests)
|
||||
c.applyReplaceDirectives(ctx, resolver, modFile, sourceModules, goModPackages, reader, digests)
|
||||
c.applyExcludeDirectives(modFile, goModPackages)
|
||||
|
||||
pkgs = c.assembleResults(catalogedModules, goModPackages)
|
||||
@@ -365,8 +365,11 @@ func (c *goModCataloger) createGoModPackages(ctx context.Context, resolver file.
|
||||
}
|
||||
|
||||
// applyReplaceDirectives processes replace directives from go.mod
|
||||
func (c *goModCataloger) applyReplaceDirectives(ctx context.Context, resolver file.Resolver, modFile *modfile.File, goModPackages map[string]pkg.Package, reader file.LocationReadCloser, digests map[string]string) {
|
||||
func (c *goModCataloger) applyReplaceDirectives(ctx context.Context, resolver file.Resolver, modFile *modfile.File, sourceModules map[string]*packages.Module, goModPackages map[string]pkg.Package, reader file.LocationReadCloser, digests map[string]string) {
|
||||
for _, m := range modFile.Replace {
|
||||
if sourceModules != nil && sourceModules[m.Old.Path] != nil {
|
||||
continue
|
||||
}
|
||||
lics := c.licenseResolver.getLicenses(ctx, resolver, m.New.Path, m.New.Version)
|
||||
var finalPath string
|
||||
if !strings.HasPrefix(m.New.Path, ".") && !strings.HasPrefix(m.New.Path, "/") {
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
package golang
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
stereofile "github.com/anchore/stereoscope/pkg/file"
|
||||
"github.com/anchore/syft/syft/file"
|
||||
"github.com/anchore/syft/syft/pkg/cataloger/internal/pkgtest"
|
||||
"github.com/anchore/syft/syft/source"
|
||||
"github.com/anchore/syft/syft/source/directorysource"
|
||||
)
|
||||
|
||||
func Test_parseGoSource_replacedModulesAreNotDuplicated(t *testing.T) {
|
||||
fixture := filepath.Join("testdata", "go-source-replacements")
|
||||
s, err := directorysource.NewFromPath(fixture)
|
||||
require.NoError(t, err)
|
||||
resolver, err := s.FileResolver(source.AllLayersScope)
|
||||
require.NoError(t, err)
|
||||
|
||||
modPath, err := filepath.Abs(filepath.Join(fixture, "go.mod"))
|
||||
require.NoError(t, err)
|
||||
contents, err := os.Open(modPath)
|
||||
require.NoError(t, err)
|
||||
t.Cleanup(func() { require.NoError(t, contents.Close()) })
|
||||
|
||||
reader := file.LocationReadCloser{
|
||||
Location: file.NewVirtualLocationFromDirectory("go.mod", "go.mod", *stereofile.NewFileReference(stereofile.Path(modPath))),
|
||||
ReadCloser: contents,
|
||||
}
|
||||
config := DefaultCatalogerConfig().WithUsePackagesLib(true).WithSearchRemoteLicenses(false)
|
||||
pkgs, _, err := newGoModCataloger(config).parseGoModFile(pkgtest.Context(t), resolver, nil, reader)
|
||||
require.NoError(t, err)
|
||||
|
||||
versions := make(map[string][]string)
|
||||
for _, p := range pkgs {
|
||||
versions[p.Name] = append(versions[p.Name], p.Version)
|
||||
}
|
||||
require.Equal(t, []string{"v1.5.2"}, versions["rsc.io/quote"])
|
||||
require.Equal(t, []string{"v1.3.1"}, versions["rsc.io/sampler"])
|
||||
}
|
||||
@@ -16,6 +16,10 @@ import (
|
||||
// mainPackage is the import path the linker assigns to the binary's main package.
|
||||
const mainPackage = "main"
|
||||
|
||||
// vendorPrefix is the import-path prefix carried by vendored packages (e.g. from `go mod vendor`, or the
|
||||
// standard library's own vendored dependencies such as "vendor/golang.org/x/net/http2").
|
||||
const vendorPrefix = "vendor/"
|
||||
|
||||
// binarySymbol represents a single function symbol extracted from a go binary's pclntab.
|
||||
type binarySymbol struct {
|
||||
// packagePath is the import path of the package that owns the symbol (e.g. "github.com/foo/bar/internal/baz")
|
||||
@@ -52,10 +56,7 @@ func getSymbols(r io.ReaderAt) (syms []binarySymbol, err error) {
|
||||
continue
|
||||
}
|
||||
seen[fn.Name] = struct{}{}
|
||||
syms = append(syms, binarySymbol{
|
||||
packagePath: fn.PackageName(),
|
||||
name: fn.Name,
|
||||
})
|
||||
syms = append(syms, makeBinarySymbol(fn.Name, fn.PackageName()))
|
||||
}
|
||||
|
||||
// debug/gosym only exposes top-level functions; functions that the compiler inlined into their
|
||||
@@ -71,7 +72,7 @@ func getSymbols(r io.ReaderAt) (syms []binarySymbol, err error) {
|
||||
continue
|
||||
}
|
||||
seen[name] = struct{}{}
|
||||
syms = append(syms, binarySymbol{packagePath: pkgPath, name: name})
|
||||
syms = append(syms, makeBinarySymbol(name, pkgPath))
|
||||
}
|
||||
|
||||
return syms, nil
|
||||
@@ -94,6 +95,55 @@ func packagePathFromSymbolName(name string) string {
|
||||
return name[:slash+1+dot]
|
||||
}
|
||||
|
||||
// makeBinarySymbol builds a binarySymbol, unescaping the %xx sequences the go linker introduces in the
|
||||
// import-path portion of a symbol name (see unescapePackagePath). The local-symbol suffix (method and
|
||||
// function names) is left untouched, so only the path prefix shared by packagePath and name is rewritten.
|
||||
func makeBinarySymbol(name, pkgPath string) binarySymbol {
|
||||
unescaped := unescapePackagePath(pkgPath)
|
||||
if unescaped != pkgPath && strings.HasPrefix(name, pkgPath) {
|
||||
name = unescaped + name[len(pkgPath):]
|
||||
}
|
||||
return binarySymbol{packagePath: unescaped, name: name}
|
||||
}
|
||||
|
||||
// unescapePackagePath reverses the escaping cmd/internal/objabi.PathToPrefix applies to import paths in
|
||||
// symbol names: bytes like '.' (at or after the final '/'), '%', '"', control bytes, and high bytes are
|
||||
// written as lowercase "%xx". For example "gopkg.in/yaml.v2" is stored as "gopkg.in/yaml%2ev2", so this
|
||||
// restores it before matching against the (unescaped) module paths from build info. A lone or malformed
|
||||
// '%' sequence is left as-is.
|
||||
func unescapePackagePath(path string) string {
|
||||
if !strings.Contains(path, "%") {
|
||||
return path
|
||||
}
|
||||
var b strings.Builder
|
||||
b.Grow(len(path))
|
||||
for i := 0; i < len(path); i++ {
|
||||
if path[i] == '%' && i+2 < len(path) {
|
||||
if hi, ok1 := unhex(path[i+1]); ok1 {
|
||||
if lo, ok2 := unhex(path[i+2]); ok2 {
|
||||
b.WriteByte(hi<<4 | lo)
|
||||
i += 2
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
b.WriteByte(path[i])
|
||||
}
|
||||
return b.String()
|
||||
}
|
||||
|
||||
func unhex(c byte) (byte, bool) {
|
||||
switch {
|
||||
case c >= '0' && c <= '9':
|
||||
return c - '0', true
|
||||
case c >= 'a' && c <= 'f':
|
||||
return c - 'a' + 10, true
|
||||
case c >= 'A' && c <= 'F':
|
||||
return c - 'A' + 10, true
|
||||
}
|
||||
return 0, false
|
||||
}
|
||||
|
||||
// nameWithoutTypeArgs strips the type-argument portion from an instantiated generic symbol name, e.g.
|
||||
// "foo/bar.Do[net/url.Values]" -> "foo/bar.Do". The slashes and dots inside the brackets would otherwise
|
||||
// corrupt package-path derivation (yielding "foo/bar.Do[net" for the example above). Mirrors
|
||||
@@ -273,8 +323,13 @@ func readPclntab(r io.ReaderAt) (pclntab []byte, textStart uint64, err error) {
|
||||
// "(*T).M"). Symbols from the "main" package are attributed to the main module and keyed by the "main"
|
||||
// import path the linker assigns. Standard-library symbols (which belong to no module) are collected
|
||||
// separately and returned as the second value, grouped by import path, so they can be attached to the
|
||||
// synthetic "stdlib" package. Compiler/runtime-internal symbols that are neither module-owned nor a
|
||||
// recognizable stdlib import path are dropped.
|
||||
// synthetic "stdlib" package. Vendored packages carry a "vendor/" import-path prefix: such symbols match
|
||||
// both modules whose own path carries the prefix and modules without it (matched with the prefix trimmed),
|
||||
// and the prefix is retained in the group key only when the owning module itself is named "vendor/...".
|
||||
// Module-less vendored packages (the stdlib's own vendored dependencies, e.g.
|
||||
// "vendor/golang.org/x/net/http2") are dropped: stdlib vulnerabilities seem to be reported against the public
|
||||
// packages (e.g. "crypto/x509"), not the vendored internal copies. Compiler/runtime-internal symbols that
|
||||
// are neither module-owned nor a recognizable stdlib import path are likewise dropped.
|
||||
func moduleSymbols(symbols []binarySymbol, main *debug.Module, deps []*debug.Module) (byModule map[string]map[string][]string, stdlib map[string][]string) {
|
||||
if len(symbols) == 0 {
|
||||
return nil, nil
|
||||
@@ -302,16 +357,17 @@ func moduleSymbols(symbols []binarySymbol, main *debug.Module, deps []*debug.Mod
|
||||
attrPath = main.Path
|
||||
}
|
||||
|
||||
var best string
|
||||
for _, modPath := range modulePaths {
|
||||
if len(modPath) > len(best) && (attrPath == modPath || strings.HasPrefix(attrPath, modPath+"/")) {
|
||||
best = modPath
|
||||
}
|
||||
best := findBestMatch(modulePaths, attrPath)
|
||||
|
||||
// the vendor/ prefix is only retained when the owning module itself is named "vendor/...";
|
||||
// in all other cases (non-vendored modules and vendored stdlib) the recorded import path is trimmed
|
||||
if !strings.HasPrefix(best, vendorPrefix) {
|
||||
importPath = strings.TrimPrefix(importPath, vendorPrefix)
|
||||
}
|
||||
|
||||
local := localSymbolName(sym.name, importPath)
|
||||
if best == "" {
|
||||
if importPath != mainPackage && isStandardImportPath(importPath) {
|
||||
if importPath != mainPackage && isStandardImportPath(importPath) { // drop stdlib vendored packages
|
||||
stdlib[importPath] = append(stdlib[importPath], local)
|
||||
}
|
||||
continue
|
||||
@@ -333,11 +389,36 @@ func moduleSymbols(symbols []binarySymbol, main *debug.Module, deps []*debug.Mod
|
||||
return results, stdlib
|
||||
}
|
||||
|
||||
// findBestMatch returns the module path that owns the given package path taking into account vendor/ prefixes: a vendor/ import path
|
||||
// will take precedence and continue to match, non-vendored imports will match against their vendored equivalent
|
||||
func findBestMatch(modulePaths []string, importPath string) string {
|
||||
trimmedPath, trimmed := strings.CutPrefix(importPath, vendorPrefix)
|
||||
candidatePaths := []string{importPath, trimmedPath}
|
||||
if !trimmed {
|
||||
candidatePaths = candidatePaths[:1]
|
||||
}
|
||||
|
||||
var best string
|
||||
for _, candidate := range candidatePaths {
|
||||
for _, modPath := range modulePaths {
|
||||
// the prefix must end at a path-segment boundary in candidate, so that e.g. the module
|
||||
// "github.com/foo/bar" matches the package "github.com/foo/bar/baz" but not "github.com/foo/barbaz"
|
||||
if len(modPath) > len(best) && strings.HasPrefix(candidate, modPath) && (candidate == modPath || candidate[len(modPath)] == '/') {
|
||||
best = modPath
|
||||
}
|
||||
}
|
||||
}
|
||||
return best
|
||||
}
|
||||
|
||||
// localSymbolName strips the owning package's import path prefix from a fully qualified symbol name, e.g.
|
||||
// "github.com/foo/bar.(*T).M" with import path "github.com/foo/bar" becomes "(*T).M". The name is returned
|
||||
// unchanged when it does not carry the expected prefix.
|
||||
func localSymbolName(name, importPath string) string {
|
||||
if importPath != "" && strings.HasPrefix(name, importPath+".") {
|
||||
if !strings.HasPrefix(importPath, vendorPrefix) {
|
||||
name = strings.TrimPrefix(name, vendorPrefix)
|
||||
}
|
||||
if len(importPath) < len(name) && strings.HasPrefix(name, importPath) && name[len(importPath)] == '.' {
|
||||
return name[len(importPath)+1:]
|
||||
}
|
||||
return name
|
||||
|
||||
@@ -16,6 +16,8 @@ func Test_moduleSymbols(t *testing.T) {
|
||||
deps := []*debug.Module{
|
||||
{Path: "github.com/foo/bar"},
|
||||
{Path: "github.com/foo/bar/v2"},
|
||||
{Path: "vendor/github.com/vendored/mod"},
|
||||
{Path: "github.com/vendored/mod"},
|
||||
nil,
|
||||
}
|
||||
|
||||
@@ -74,6 +76,63 @@ func Test_moduleSymbols(t *testing.T) {
|
||||
"runtime": {"main"},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "vendored packages match non-vendored modules and are recorded under the canonical import path",
|
||||
symbols: []binarySymbol{
|
||||
{packagePath: "vendor/github.com/foo/bar", name: "vendor/github.com/foo/bar.Parse"},
|
||||
{packagePath: "vendor/github.com/foo/bar/internal/util", name: "vendor/github.com/foo/bar/internal/util.(*Helper).Do"},
|
||||
},
|
||||
expected: map[string]map[string][]string{
|
||||
"github.com/foo/bar": {
|
||||
"github.com/foo/bar": {"Parse"},
|
||||
"github.com/foo/bar/internal/util": {"(*Helper).Do"},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "stdlib-vendored packages are dropped",
|
||||
symbols: []binarySymbol{
|
||||
{packagePath: "vendor/golang.org/x/net/http2", name: "vendor/golang.org/x/net/http2.(*Framer).ReadFrame"},
|
||||
},
|
||||
expected: map[string]map[string][]string{},
|
||||
},
|
||||
{
|
||||
name: "modules whose own path carries the vendor/ prefix match exactly and win over the trimmed match",
|
||||
symbols: []binarySymbol{
|
||||
{packagePath: "vendor/github.com/vendored/mod", name: "vendor/github.com/vendored/mod.Run"},
|
||||
{packagePath: "github.com/vendored/mod", name: "github.com/vendored/mod.Run"},
|
||||
},
|
||||
expected: map[string]map[string][]string{
|
||||
"vendor/github.com/vendored/mod": {
|
||||
"vendor/github.com/vendored/mod": {"Run"},
|
||||
},
|
||||
"github.com/vendored/mod": {
|
||||
"github.com/vendored/mod": {"Run"},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "vendored and unvendored symbols for the same package are merged and deduplicated under the canonical import path",
|
||||
symbols: []binarySymbol{
|
||||
{packagePath: "github.com/foo/bar", name: "github.com/foo/bar.Parse"},
|
||||
{packagePath: "vendor/github.com/foo/bar", name: "vendor/github.com/foo/bar.Parse"},
|
||||
},
|
||||
expected: map[string]map[string][]string{
|
||||
"github.com/foo/bar": {
|
||||
"github.com/foo/bar": {"Parse"},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
// "github.com/foo/barbaz" shares a string prefix with the "github.com/foo/bar" module but not a
|
||||
// path-segment boundary, so it must not be attributed to it (and, having a dotted first element,
|
||||
// it is not a stdlib path either — it is dropped)
|
||||
name: "module paths only match the package path at a path-segment boundary",
|
||||
symbols: []binarySymbol{
|
||||
{packagePath: "github.com/foo/barbaz", name: "github.com/foo/barbaz.Parse"},
|
||||
},
|
||||
expected: map[string]map[string][]string{},
|
||||
},
|
||||
{
|
||||
name: "duplicate symbols are deduplicated",
|
||||
symbols: []binarySymbol{
|
||||
@@ -97,6 +156,58 @@ func Test_moduleSymbols(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func Test_escapedImportPathAttribution(t *testing.T) {
|
||||
// the go linker escapes the '.' in the last path element, so "gopkg.in/yaml.v2" appears in the symbol
|
||||
// table as "gopkg.in/yaml%2ev2". attribution must still land these under the unescaped module path.
|
||||
mainModule := &debug.Module{Path: "github.com/someorg/somecli"}
|
||||
deps := []*debug.Module{{Path: "gopkg.in/yaml.v2"}}
|
||||
|
||||
symbols := []binarySymbol{
|
||||
makeBinarySymbol("gopkg.in/yaml%2ev2.(*decoder).alias", "gopkg.in/yaml%2ev2"),
|
||||
makeBinarySymbol("gopkg.in/yaml%2ev2.(*TypeError).Error", "gopkg.in/yaml%2ev2"),
|
||||
}
|
||||
|
||||
gotByModule, gotStdlib := moduleSymbols(symbols, mainModule, deps)
|
||||
assert.Nil(t, gotStdlib)
|
||||
assert.Equal(t, map[string]map[string][]string{
|
||||
"gopkg.in/yaml.v2": {
|
||||
"gopkg.in/yaml.v2": {"(*TypeError).Error", "(*decoder).alias"},
|
||||
},
|
||||
}, gotByModule)
|
||||
}
|
||||
|
||||
func Test_unescapePackagePath(t *testing.T) {
|
||||
tests := []struct {
|
||||
input string
|
||||
expected string
|
||||
}{
|
||||
{"gopkg.in/yaml%2ev2", "gopkg.in/yaml.v2"},
|
||||
{"foo%25bar", "foo%bar"},
|
||||
{"foo%22bar", "foo\"bar"},
|
||||
// no escapes: unchanged
|
||||
{"github.com/foo/bar", "github.com/foo/bar"},
|
||||
{"", ""},
|
||||
// malformed sequences are left as-is
|
||||
{"foo%2", "foo%2"},
|
||||
{"foo%zz", "foo%zz"},
|
||||
{"foo%", "foo%"},
|
||||
// uppercase hex is accepted too
|
||||
{"foo%2Ebar", "foo.bar"},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.input, func(t *testing.T) {
|
||||
assert.Equal(t, tt.expected, unescapePackagePath(tt.input))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func Test_makeBinarySymbol(t *testing.T) {
|
||||
// only the import-path prefix is unescaped; the local-symbol suffix is preserved verbatim
|
||||
sym := makeBinarySymbol("gopkg.in/yaml%2ev2.(*decoder).alias", "gopkg.in/yaml%2ev2")
|
||||
assert.Equal(t, "gopkg.in/yaml.v2", sym.packagePath)
|
||||
assert.Equal(t, "gopkg.in/yaml.v2.(*decoder).alias", sym.name)
|
||||
}
|
||||
|
||||
func Test_localSymbolName(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
@@ -239,6 +350,9 @@ func Test_packagePathFromSymbolName(t *testing.T) {
|
||||
// module paths that begin with "go." are not compiler-generated
|
||||
{"go.uber.org/zap.(*Logger).Info", "go.uber.org/zap"},
|
||||
{"go.opentelemetry.io/otel.Tracer", "go.opentelemetry.io/otel"},
|
||||
// vendored packages retain their "vendor/" import-path prefix in symbol names
|
||||
{"vendor/golang.org/x/net/http2.(*Framer).ReadFrame", "vendor/golang.org/x/net/http2"},
|
||||
{"vendor/github.com/foo/bar.Parse", "vendor/github.com/foo/bar"},
|
||||
}
|
||||
for _, test := range tests {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
module example.com/repro
|
||||
|
||||
go 1.23
|
||||
|
||||
require rsc.io/quote v1.5.1
|
||||
|
||||
require (
|
||||
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c // indirect
|
||||
rsc.io/sampler v1.3.0 // indirect
|
||||
)
|
||||
|
||||
replace (
|
||||
rsc.io/quote => rsc.io/quote v1.5.2
|
||||
rsc.io/sampler => rsc.io/sampler v1.3.1
|
||||
)
|
||||
@@ -0,0 +1,6 @@
|
||||
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c h1:qgOY6WgZOaTkIIMiVjBQcw93ERBE4m30iBm00nkL0i8=
|
||||
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
rsc.io/quote v1.5.2 h1:w5fcysjrx7yqtD/aO+QwRjYZOKnaM9Uh2b40tElTs3Y=
|
||||
rsc.io/quote v1.5.2/go.mod h1:LzX7hefJvL54yjefDEDHNONDjII0t9xZLPXsUe+TKr0=
|
||||
rsc.io/sampler v1.3.1 h1:F0c3J2nQCdk9ODsNhU3sElnvPIxM/xV1c/qZuAeZmac=
|
||||
rsc.io/sampler v1.3.1/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
|
||||
@@ -0,0 +1,11 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"rsc.io/quote"
|
||||
)
|
||||
|
||||
func main() {
|
||||
fmt.Println(quote.Hello())
|
||||
}
|
||||
@@ -7,6 +7,9 @@
|
||||
"chainguard.dev/apko": [
|
||||
"cpe:2.3:a:chainguard:apko:*:*:*:*:*:go:*:*"
|
||||
],
|
||||
"github.com/Azure/go-ntlmssp": [
|
||||
"cpe:2.3:a:microsoft:go-ntlmssp:*:*:*:*:*:go:*:*"
|
||||
],
|
||||
"github.com/ClickHouse/ch-go": [
|
||||
"cpe:2.3:a:clickhouse:ch:*:*:*:*:*:go:*:*"
|
||||
],
|
||||
@@ -223,6 +226,9 @@
|
||||
"github.com/xddxdd/bird-lg-go": [
|
||||
"cpe:2.3:a:xddxdd:bird-lg-go:*:*:*:*:*:go:*:*"
|
||||
],
|
||||
"github.com/xuri/excelize/v2": [
|
||||
"cpe:2.3:a:excelize:excelize:*:*:*:*:*:go:*:*"
|
||||
],
|
||||
"github.com/yuin/goldmark": [
|
||||
"cpe:2.3:a:yuin:goldmark:*:*:*:*:*:go:*:*"
|
||||
],
|
||||
@@ -2349,6 +2355,9 @@
|
||||
"@apollosproject/data-connector-rock": [
|
||||
"cpe:2.3:a:apollosapp:data-connector-rock:*:*:*:*:*:node.js:*:*"
|
||||
],
|
||||
"@appium/base-driver": [
|
||||
"cpe:2.3:a:appium:appium\\/base-driver:*:*:*:*:*:node.js:*:*"
|
||||
],
|
||||
"@appium/support": [
|
||||
"cpe:2.3:a:appium:appium\\/support:*:*:*:*:*:node.js:*:*"
|
||||
],
|
||||
@@ -2403,6 +2412,9 @@
|
||||
"@better-auth/oauth-provider": [
|
||||
"cpe:2.3:a:better-auth:better-auth\\/oauth-provider:*:*:*:*:*:node.js:*:*"
|
||||
],
|
||||
"@better-auth/sso": [
|
||||
"cpe:2.3:a:better-auth:better-auth\\/sso:*:*:*:*:*:node.js:*:*"
|
||||
],
|
||||
"@braintree/sanitize-url": [
|
||||
"cpe:2.3:a:paypal:braintree\\/sanitize-url:*:*:*:*:*:node.js:*:*"
|
||||
],
|
||||
@@ -2616,6 +2628,9 @@
|
||||
"@octokit/webhooks": [
|
||||
"cpe:2.3:a:octokit:webhooks:*:*:*:*:*:node.js:*:*"
|
||||
],
|
||||
"@openclaw/feishu": [
|
||||
"cpe:2.3:a:openclaw:openclaw\\/feishu:*:*:*:*:*:node.js:*:*"
|
||||
],
|
||||
"@openclaw/voice-call": [
|
||||
"cpe:2.3:a:openclaw:openclaw\\/voice-call:*:*:*:*:*:node.js:*:*"
|
||||
],
|
||||
@@ -3086,6 +3101,9 @@
|
||||
"cli": [
|
||||
"cpe:2.3:a:cli_project:cli:*:*:*:*:*:node.js:*:*"
|
||||
],
|
||||
"client-certificate-auth": [
|
||||
"cpe:2.3:a:tgies:client-certificate-auth:*:*:*:*:*:node.js:*:*"
|
||||
],
|
||||
"closure-compiler-stream": [
|
||||
"cpe:2.3:a:closure-compiler-stream_project:closure-compiler-stream:*:*:*:*:*:node.js:*:*"
|
||||
],
|
||||
@@ -5752,6 +5770,9 @@
|
||||
"ssrf-agent": [
|
||||
"cpe:2.3:a:ssrf-agent_project:ssrf-agent:*:*:*:*:*:node.js:*:*"
|
||||
],
|
||||
"ssrfcheck": [
|
||||
"cpe:2.3:a:felippe-regazio:ssrf_check:*:*:*:*:*:node.js:*:*"
|
||||
],
|
||||
"ssri": [
|
||||
"cpe:2.3:a:ssri_project:ssri:*:*:*:*:*:node.js:*:*"
|
||||
],
|
||||
@@ -6819,6 +6840,9 @@
|
||||
"pyanyapi": [
|
||||
"cpe:2.3:a:pyanyapi_project:pyanyapi:*:*:*:*:*:*:*:*"
|
||||
],
|
||||
"pyasn1": [
|
||||
"cpe:2.3:a:pyasn1:pyasn1:*:*:*:*:*:python:*:*"
|
||||
],
|
||||
"pybluemonday": [
|
||||
"cpe:2.3:a:python:pybluemonday:*:*:*:*:*:*:*:*"
|
||||
],
|
||||
@@ -6978,6 +7002,9 @@
|
||||
"sqlparse": [
|
||||
"cpe:2.3:a:sqlparse_project:sqlparse:*:*:*:*:*:python:*:*"
|
||||
],
|
||||
"stanza": [
|
||||
"cpe:2.3:a:stanford:stanza:*:*:*:*:*:python:*:*"
|
||||
],
|
||||
"starlette": [
|
||||
"cpe:2.3:a:encode:starlette:*:*:*:*:*:python:*:*"
|
||||
],
|
||||
@@ -7690,6 +7717,12 @@
|
||||
"bzip2": [
|
||||
"cpe:2.3:a:bzip2_project:bzip2:*:*:*:*:*:rust:*:*"
|
||||
],
|
||||
"c2pa": [
|
||||
"cpe:2.3:a:adobe:c2pa:*:*:*:*:*:rust:*:*"
|
||||
],
|
||||
"c2patool": [
|
||||
"cpe:2.3:a:adobe:c2patool:*:*:*:*:*:*:*:*"
|
||||
],
|
||||
"cache": [
|
||||
"cpe:2.3:a:cache_project:cache:*:*:*:*:*:rust:*:*"
|
||||
],
|
||||
@@ -8530,6 +8563,9 @@
|
||||
"add-subtitle": [
|
||||
"cpe:2.3:a:viitorcloud:add_subtitle:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"add-svg-support-for-media-uploader-inventivo": [
|
||||
"cpe:2.3:a:inventivo:inventivo:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"add-to-any": [
|
||||
"cpe:2.3:a:addtoany:addtoany_share_buttons:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -8720,6 +8756,9 @@
|
||||
"advanced-recent-posts": [
|
||||
"cpe:2.3:a:advanced_recent_posts_project:advanced_recent_posts:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"advanced-schedule-posts": [
|
||||
"cpe:2.3:a:hijiriworld:advanced_schedule_posts:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"advanced-sermons": [
|
||||
"cpe:2.3:a:wpcodeus:advanced_sermons:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -8784,6 +8823,7 @@
|
||||
"cpe:2.3:a:ai_contact_us_form_project:ai_contact_us_form:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"ai-engine": [
|
||||
"cpe:2.3:a:jordymeow:ai_engine:*:*:*:*:*:wordpress:*:*",
|
||||
"cpe:2.3:a:meowapps:ai_engine:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"ai-image-alt-text-generator-for-wp": [
|
||||
@@ -9175,7 +9215,8 @@
|
||||
"cpe:2.3:a:article_directory_project:article_directory:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"article-directory-redux": [
|
||||
"cpe:2.3:a:icontrolwp:article_directory_redux:*:*:*:*:*:wordpress:*:*"
|
||||
"cpe:2.3:a:icontrolwp:article_directory_redux:*:*:*:*:*:wordpress:*:*",
|
||||
"cpe:2.3:a:icontrolwp:icontrolwp:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"article2pdf": [
|
||||
"cpe:2.3:a:article2pdf_project:article2pdf:*:*:*:*:*:wordpress:*:*"
|
||||
@@ -10993,6 +11034,9 @@
|
||||
"cost-calculator-builder": [
|
||||
"cpe:2.3:a:stylemixthemes:cost_calculator_builder:*:*:*:*:free:wordpress:*:*"
|
||||
],
|
||||
"coub": [
|
||||
"cpe:2.3:a:chartscss:coub:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"countdown-block": [
|
||||
"cpe:2.3:a:wpdeveloper:countdown_block:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -12122,9 +12166,12 @@
|
||||
"cpe:2.3:a:mandsconsulting:email_before_download:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"email-encoder-bundle": [
|
||||
"cpe:2.3:a:jannisthuemmig:email_encoder:*:*:*:*:*:wordpress:*:*",
|
||||
"cpe:2.3:a:onlineoptimisation:email_encoder:*:*:*:*:*:wordpress:*:*",
|
||||
"cpe:2.3:a:wp-webhooks:email_encoder:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"email-keep": [
|
||||
"cpe:2.3:a:intricateweb:email_keep:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"email-log": [
|
||||
"cpe:2.3:a:email_log_project:email_log:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -13104,6 +13151,9 @@
|
||||
"game-server-status": [
|
||||
"cpe:2.3:a:game-server-status_project:game-server-status:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"game-users-share-buttons": [
|
||||
"cpe:2.3:a:gameusers:game_users_share_button:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"gamepress": [
|
||||
"cpe:2.3:a:gamepress_project:gamepress:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -13113,6 +13163,9 @@
|
||||
"gamipress-link": [
|
||||
"cpe:2.3:a:gamipress:gamipress_-_link:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"gamipress-reset-user": [
|
||||
"cpe:2.3:a:gamipress:gamipress_-_reset_user:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"garden-gnome-package": [
|
||||
"cpe:2.3:a:ggnome:garden_gnome_package:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -13197,6 +13250,9 @@
|
||||
"gestpay-for-woocommerce": [
|
||||
"cpe:2.3:a:fabrick:gestpay_for_woocommerce:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"get-bookings-wp": [
|
||||
"cpe:2.3:a:istmoplugins:get_bookings_wp:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"get-custom-field-values": [
|
||||
"cpe:2.3:a:get_custom_field_values_project:get_custom_field_values:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -13227,6 +13283,15 @@
|
||||
"gf-custom-style": [
|
||||
"cpe:2.3:a:alefypimentel:gf_custom_style:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"gf-hubspot": [
|
||||
"cpe:2.3:a:crmperks:wp_gravity_forms_hubspot:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"gf-insightly": [
|
||||
"cpe:2.3:a:crmperks:wp_gravity_forms_insightly:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"gf-salesforce-crmperks": [
|
||||
"cpe:2.3:a:crmperks:wp_gravity_forms_salesforce:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"gf-zoho": [
|
||||
"cpe:2.3:a:crmperks:wp_gravity_forms_zoho_crm_and_bigin:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -13659,6 +13724,9 @@
|
||||
"heureka": [
|
||||
"cpe:2.3:a:heureka:heureka:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"hide-links": [
|
||||
"cpe:2.3:a:avovkdesign:hide_links:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"hide-my-wp": [
|
||||
"cpe:2.3:a:wpplugins:hide_my_wp_ghost:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -13683,6 +13751,9 @@
|
||||
"hkdev-maintenance-mode": [
|
||||
"cpe:2.3:a:helderk:maintenance_mode:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"hmapsprem": [
|
||||
"cpe:2.3:a:heroplugins:hero_maps_premium:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"hms-testimonials": [
|
||||
"cpe:2.3:a:hitmyserver:hms_testimonials:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -13831,6 +13902,9 @@
|
||||
"ibtana-visual-editor": [
|
||||
"cpe:2.3:a:vowelweb:ibtana:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"ibuildapp": [
|
||||
"cpe:2.3:a:ibuildapp:ibuildapp:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"icegram": [
|
||||
"cpe:2.3:a:icegram:icegram_engage:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -14054,6 +14128,9 @@
|
||||
"cpe:2.3:a:infusionsoft_project:infusionsoft:*:*:*:*:*:wordpress:*:*",
|
||||
"cpe:2.3:a:katz:infusionsoft_gravity_forms:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"infusionsoft-official-opt-in-forms": [
|
||||
"cpe:2.3:a:keap:keap_official_opt_in_forms:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"inline-google-spreadsheet-viewer": [
|
||||
"cpe:2.3:a:inline_google_spreadsheet_viewer_project:inline_google_spreadsheet_viewer:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -14154,6 +14231,9 @@
|
||||
"intelly-related-posts": [
|
||||
"cpe:2.3:a:data443:inline_related_posts:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"interact-quiz-embed": [
|
||||
"cpe:2.3:a:tryinteract:embed_a_quiz_on_your_site:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"interactive-3d-flipbook-powered-physics-engine": [
|
||||
"cpe:2.3:a:3dflipbook:3d_flipbook:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -14390,6 +14470,9 @@
|
||||
"jvm-rich-text-icons": [
|
||||
"cpe:2.3:a:jorisvm:jvm_gutenberg_rich_text_icons:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"jwp-a11y": [
|
||||
"cpe:2.3:a:jidaikobo:jwp-a11y:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"kadence-blocks": [
|
||||
"cpe:2.3:a:kadencewp:gutenberg_blocks_with_ai:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -14879,6 +14962,9 @@
|
||||
"logo-slider-wp": [
|
||||
"cpe:2.3:a:logichunt:logo_slider:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"logs-de-connexion": [
|
||||
"cpe:2.3:a:floriansimunek:connexion_logs:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"logwpmail": [
|
||||
"cpe:2.3:a:premierethemes:log_wp_mail:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -14951,6 +15037,9 @@
|
||||
"cpe:2.3:a:custom_popup_builder_project:custom_popup_builder:*:*:*:*:*:wordpress:*:*",
|
||||
"cpe:2.3:a:popup_\\|_custom_popup_builder_project:popup_\\|_custom_popup_builder:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"magayo-lottery-results": [
|
||||
"cpe:2.3:a:magayo:magayo_lottery_results:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"magazine-blocks": [
|
||||
"cpe:2.3:a:themegrill:magazine_blocks:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -15147,7 +15236,8 @@
|
||||
"cpe:2.3:a:master-addons:master_addons:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"master-slider": [
|
||||
"cpe:2.3:a:averta:master_slider:*:*:*:*:*:wordpress:*:*"
|
||||
"cpe:2.3:a:averta:master_slider:*:*:*:*:*:wordpress:*:*",
|
||||
"cpe:2.3:a:averta:master_slider:*:*:*:*:free:wordpress:*:*"
|
||||
],
|
||||
"masterstudy-lms-learning-management-system": [
|
||||
"cpe:2.3:a:stylemixthemes:masterstudy_lms:*:*:*:*:*:wordpress:*:*"
|
||||
@@ -15167,6 +15257,9 @@
|
||||
"materialis-companion": [
|
||||
"cpe:2.3:a:extendthemes:materialis_companion:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"matomo": [
|
||||
"cpe:2.3:a:matomo:matomo:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"matrix-pre-loader": [
|
||||
"cpe:2.3:a:nkb-bd:preloader_matrix:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -15185,6 +15278,9 @@
|
||||
"mdc-youtube-downloader": [
|
||||
"cpe:2.3:a:mdc_youtube_downloader_project:mdc_youtube_downloader:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"media-alt-renamer": [
|
||||
"cpe:2.3:a:jordymeow:media_alt_renamer:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"media-downloader": [
|
||||
"cpe:2.3:a:media_downloader_project:media_downloader:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -15508,7 +15604,7 @@
|
||||
"cpe:2.3:a:motor_racing_league_project:motor_racing_league:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"motors-car-dealership-classified-listings": [
|
||||
"cpe:2.3:a:stylemixthemes:motors_-_car_dealer\\,_classifieds_\\\u0026_listing:*:*:*:*:*:wordpress:*:*"
|
||||
"cpe:2.3:a:stylemixthemes:motors_-_car_dealer\\,_classifieds_\\\u0026_listing:*:*:*:*:starter:wordpress:*:*"
|
||||
],
|
||||
"mousewheel-smooth-scroll": [
|
||||
"cpe:2.3:a:mousewheel_smooth_scroll_project:mousewheel_smooth_scroll:*:*:*:*:*:wordpress:*:*"
|
||||
@@ -15516,6 +15612,9 @@
|
||||
"move-addons": [
|
||||
"cpe:2.3:a:moveaddons:move_addons_for_elementor:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"movie-database": [
|
||||
"cpe:2.3:a:heimkino-praxis:movie_database:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"movies": [
|
||||
"cpe:2.3:a:movies_project:movies:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -16208,6 +16307,7 @@
|
||||
"cpe:2.3:a:benhuson:page_parts:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"page-scroll-to-id": [
|
||||
"cpe:2.3:a:malihu:page_scroll_to_id:*:*:*:*:*:wordpress:*:*",
|
||||
"cpe:2.3:a:page_scroll_to_id_project:page_scroll_to_id:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"page-views-count": [
|
||||
@@ -16641,6 +16741,9 @@
|
||||
"popup-zyrex": [
|
||||
"cpe:2.3:a:zyrex:popup:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"popup4phone": [
|
||||
"cpe:2.3:a:ivanweb:popup4phone:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"popupally": [
|
||||
"cpe:2.3:a:accessally:popupally:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -16654,6 +16757,9 @@
|
||||
"portfolio": [
|
||||
"cpe:2.3:a:bestwebsoft:portfolio:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"portfolio-and-projects": [
|
||||
"cpe:2.3:a:essentialplugin:portfolio_and_projects:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"portfolio-by-lisa-westlund": [
|
||||
"cpe:2.3:a:portfolio_project:portfolio:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -17441,6 +17547,9 @@
|
||||
"responsive-css-editor": [
|
||||
"cpe:2.3:a:wpwox:responsive_css_editor:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"responsive-filterable-portfolio": [
|
||||
"cpe:2.3:a:i13websolution:responsive_filterable_portfolio:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"responsive-food-and-drink-menu": [
|
||||
"cpe:2.3:a:corporatezen:responsive_food_and_drink_menu:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -17470,6 +17579,12 @@
|
||||
"responsive-vector-maps": [
|
||||
"cpe:2.3:a:thinkupthemes:responsive_vector_maps:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"responsive-video-embed": [
|
||||
"cpe:2.3:a:lepileppanen:responsive_video_embed:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"rest-api-to-miniprogram": [
|
||||
"cpe:2.3:a:jianbo:rest_api_to_miniprogram:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"restaurant-cafe-addon-for-elementor": [
|
||||
"cpe:2.3:a:nicheaddons:restaurant_\\\u0026_cafe_addon_for_elementor:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -17655,6 +17770,9 @@
|
||||
"safe-svg": [
|
||||
"cpe:2.3:a:10up:safe_svg:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"safetymails-forms": [
|
||||
"cpe:2.3:a:henriquerodrigues:safetyforms:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"sagepay-server-gateway-for-woocommerce": [
|
||||
"cpe:2.3:a:patsatech:sagepay_server_gateway_for_woocommerce:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -18545,6 +18663,9 @@
|
||||
"slideshow-se": [
|
||||
"cpe:2.3:a:slideshow_se_project:slideshow_se:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"slingblocks": [
|
||||
"cpe:2.3:a:funnelkit:slingblocks:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"small-package-quotes-fedex-edition": [
|
||||
"cpe:2.3:a:eniture:small_package_quotes:*:*:*:*:fedex:wordpress:*:*"
|
||||
],
|
||||
@@ -18837,6 +18958,9 @@
|
||||
"sportspress": [
|
||||
"cpe:2.3:a:themeboy:sportspress:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"spotbot": [
|
||||
"cpe:2.3:a:jakehelbig:spotbot:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"spotify-play-button-for-wordpress": [
|
||||
"cpe:2.3:a:followmedarling:spotify-play-button-for-wordpress:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -19939,6 +20063,9 @@
|
||||
"user-login-log": [
|
||||
"cpe:2.3:a:intechnosoftware:user_login_log:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"user-messages": [
|
||||
"cpe:2.3:a:marvinlabs:user_messages:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"user-meta": [
|
||||
"cpe:2.3:a:user-meta:user_meta_user_profile_builder_and_user_management:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -19962,6 +20089,9 @@
|
||||
"user-role": [
|
||||
"cpe:2.3:a:bestwebsoft:user_role:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"user-shortcodes-plus": [
|
||||
"cpe:2.3:a:kylebjohnson:user_shortcodes_plus:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"user-spam-remover": [
|
||||
"cpe:2.3:a:joelhardi:user_spam_remover:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -20574,6 +20704,9 @@
|
||||
"woo-gutenberg-products-block": [
|
||||
"cpe:2.3:a:automattic:woocommerce_blocks:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"woo-mailerlite": [
|
||||
"cpe:2.3:a:mailerlite:mailerlite:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"woo-moneybird": [
|
||||
"cpe:2.3:a:techastha:integration_of_moneybird_for_woocommerce:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -20923,6 +21056,9 @@
|
||||
"wordpress-users": [
|
||||
"cpe:2.3:a:jonathonkemp:wordpress_users:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"work-the-flow-file-upload": [
|
||||
"cpe:2.3:a:lyntonreed:work_the_flow_file_upload:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"workreap": [
|
||||
"cpe:2.3:a:amentotech:workreap:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -21154,6 +21290,9 @@
|
||||
"wp-consultant": [
|
||||
"cpe:2.3:a:wp_consultant_project:wp_consultant:*:*:-:*:-:wordpress:*:*"
|
||||
],
|
||||
"wp-contact-form": [
|
||||
"cpe:2.3:a:ftwr:wp_contact_form:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"wp-contact-slider": [
|
||||
"cpe:2.3:a:wpexperts:wp_contact_slider:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -21452,6 +21591,9 @@
|
||||
"wp-fountain": [
|
||||
"cpe:2.3:a:wp_fountain_project:wp_fountain:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"wp-front-end-login-and-register": [
|
||||
"cpe:2.3:a:hellomohsinkhan:wp_front-end_login_and_register:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"wp-front-end-profile": [
|
||||
"cpe:2.3:a:wp_front_end_profile_project:wp_front_end_profile:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -21904,6 +22046,9 @@
|
||||
"wp-product-gallery-lite": [
|
||||
"cpe:2.3:a:accesspressthemes:wp_product_gallery_lite:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"wp-programmmanager": [
|
||||
"cpe:2.3:a:mantus667:wp-pmanager:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"wp-propagator": [
|
||||
"cpe:2.3:a:widgilabs:plugin_propagator:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
@@ -23112,6 +23257,9 @@
|
||||
"empowerwp": [
|
||||
"cpe:2.3:a:extendthemes:empowerwp:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"enfold": [
|
||||
"cpe:2.3:a:kriesi:enfold:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
"enlighten": [
|
||||
"cpe:2.3:a:accesspressthemes:enlighten:*:*:*:*:*:wordpress:*:*"
|
||||
],
|
||||
|
||||
@@ -1,26 +1,49 @@
|
||||
package cpegenerate
|
||||
|
||||
import "github.com/anchore/syft/syft/pkg"
|
||||
import (
|
||||
"net/url"
|
||||
"strings"
|
||||
|
||||
"github.com/anchore/syft/syft/pkg"
|
||||
)
|
||||
|
||||
func candidateVendorsForRPM(p pkg.Package) fieldCandidateSet {
|
||||
vendors := newFieldCandidateSet()
|
||||
var vendor string
|
||||
|
||||
switch m := p.Metadata.(type) {
|
||||
case pkg.RpmDBEntry:
|
||||
if m.Vendor != "" {
|
||||
vendors.add(fieldCandidate{
|
||||
value: normalizeName(m.Vendor),
|
||||
disallowSubSelections: true,
|
||||
})
|
||||
}
|
||||
vendor = m.Vendor
|
||||
case pkg.RpmArchive:
|
||||
if m.Vendor != "" {
|
||||
vendors.add(fieldCandidate{
|
||||
value: normalizeName(m.Vendor),
|
||||
disallowSubSelections: true,
|
||||
})
|
||||
}
|
||||
vendor = m.Vendor
|
||||
}
|
||||
|
||||
vendor = stripTrailingURL(vendor)
|
||||
if vendor != "" {
|
||||
vendors.add(fieldCandidate{
|
||||
value: normalizeName(vendor),
|
||||
disallowSubSelections: true,
|
||||
})
|
||||
}
|
||||
|
||||
return vendors
|
||||
}
|
||||
|
||||
func stripTrailingURL(value string) string {
|
||||
trimmed := strings.TrimSpace(value)
|
||||
if !strings.HasSuffix(trimmed, ">") {
|
||||
return value
|
||||
}
|
||||
|
||||
open := strings.LastIndex(trimmed, "<")
|
||||
if open == -1 {
|
||||
return value
|
||||
}
|
||||
|
||||
parsed, err := url.Parse(trimmed[open+1 : len(trimmed)-1])
|
||||
if err != nil || parsed.Host == "" || (parsed.Scheme != "http" && parsed.Scheme != "https") {
|
||||
return value
|
||||
}
|
||||
|
||||
return strings.TrimSpace(trimmed[:open])
|
||||
}
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
package cpegenerate
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/anchore/syft/syft/pkg"
|
||||
)
|
||||
|
||||
func TestCandidateVendorsForRPM(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
metadata any
|
||||
expected []string
|
||||
}{
|
||||
{
|
||||
name: "database vendor with publisher URL",
|
||||
metadata: pkg.RpmDBEntry{
|
||||
Vendor: "SUSE LLC <https://www.suse.com/>",
|
||||
},
|
||||
expected: []string{"susellc"},
|
||||
},
|
||||
{
|
||||
name: "archive vendor with publisher URL",
|
||||
metadata: pkg.RpmArchive{
|
||||
Vendor: "SUSE LLC <https://www.suse.com/>",
|
||||
},
|
||||
expected: []string{"susellc"},
|
||||
},
|
||||
{
|
||||
name: "plain vendor",
|
||||
metadata: pkg.RpmDBEntry{
|
||||
Vendor: "Red Hat, Inc.",
|
||||
},
|
||||
expected: []string{"redhat"},
|
||||
},
|
||||
{
|
||||
name: "non-URL angle-bracket suffix",
|
||||
metadata: pkg.RpmDBEntry{
|
||||
Vendor: "Example <support@example.com>",
|
||||
},
|
||||
expected: []string{"example<support@example.com>"},
|
||||
},
|
||||
{
|
||||
name: "non-HTTP URL",
|
||||
metadata: pkg.RpmDBEntry{
|
||||
Vendor: "Example <ftp://example.com>",
|
||||
},
|
||||
expected: []string{"example<ftp://example.com>"},
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
p := pkg.Package{Metadata: test.metadata}
|
||||
assert.ElementsMatch(t, test.expected, candidateVendorsForRPM(p).uniqueValues())
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -27,10 +27,11 @@ type packageLock struct {
|
||||
|
||||
// lockDependency represents a single package dependency listed in the package.lock json file
|
||||
type lockDependency struct {
|
||||
Version string `json:"version"`
|
||||
Resolved string `json:"resolved"`
|
||||
Integrity string `json:"integrity"`
|
||||
Dev bool `json:"dev"`
|
||||
Version string `json:"version"`
|
||||
Resolved string `json:"resolved"`
|
||||
Integrity string `json:"integrity"`
|
||||
Dev bool `json:"dev"`
|
||||
Dependencies map[string]lockDependency `json:"dependencies"`
|
||||
}
|
||||
|
||||
type lockPackage struct {
|
||||
@@ -77,14 +78,7 @@ func (a genericPackageLockAdapter) parsePackageLock(ctx context.Context, resolve
|
||||
}
|
||||
|
||||
if lock.LockfileVersion == 1 {
|
||||
for name, pkgMeta := range lock.Dependencies {
|
||||
// skip packages that are only present as a dev dependency
|
||||
if !a.cfg.IncludeDevDependencies && pkgMeta.Dev {
|
||||
continue
|
||||
}
|
||||
|
||||
pkgs = append(pkgs, newPackageLockV1Package(ctx, a.cfg, resolver, reader.Location, name, pkgMeta))
|
||||
}
|
||||
pkgs = append(pkgs, a.packageLockV1Packages(ctx, resolver, reader.Location, lock.Dependencies)...)
|
||||
}
|
||||
|
||||
if lock.LockfileVersion == 2 || lock.LockfileVersion == 3 {
|
||||
@@ -116,6 +110,32 @@ func (a genericPackageLockAdapter) parsePackageLock(ctx context.Context, resolve
|
||||
return pkgs, dependency.Resolve(packageLockDependencySpecifier, pkgs), unknown.IfEmptyf(pkgs, "unable to determine packages")
|
||||
}
|
||||
|
||||
func (a genericPackageLockAdapter) packageLockV1Packages(ctx context.Context, resolver file.Resolver, location file.Location, dependencies map[string]lockDependency) []pkg.Package {
|
||||
var pkgs []pkg.Package
|
||||
seen := make(map[string]struct{})
|
||||
|
||||
var walk func(map[string]lockDependency)
|
||||
walk = func(dependencies map[string]lockDependency) {
|
||||
for name, pkgMeta := range dependencies {
|
||||
// Skipping a dev-only dependency also skips its dev-only subtree.
|
||||
if !a.cfg.IncludeDevDependencies && pkgMeta.Dev {
|
||||
continue
|
||||
}
|
||||
|
||||
p := newPackageLockV1Package(ctx, a.cfg, resolver, location, name, pkgMeta)
|
||||
if _, exists := seen[p.PURL]; !exists {
|
||||
pkgs = append(pkgs, p)
|
||||
seen[p.PURL] = struct{}{}
|
||||
}
|
||||
|
||||
walk(pkgMeta.Dependencies)
|
||||
}
|
||||
}
|
||||
|
||||
walk(dependencies)
|
||||
return pkgs
|
||||
}
|
||||
|
||||
func (licenses *packageLockLicense) UnmarshalJSON(data []byte) (err error) {
|
||||
// The license field could be either a string or an array.
|
||||
|
||||
|
||||
@@ -111,6 +111,66 @@ func TestParsePackageLock(t *testing.T) {
|
||||
pkgtest.TestFileParser(t, fixture, adapter.parsePackageLock, expectedPkgs, expectedRelationships)
|
||||
}
|
||||
|
||||
func TestParsePackageLockV1NestedDependencies(t *testing.T) {
|
||||
fixture := "testdata/pkg-lock/nested-package-lock-1.json"
|
||||
expectedPkgs := []pkg.Package{
|
||||
{
|
||||
Name: "duplicate",
|
||||
Version: "1.0.0",
|
||||
PURL: "pkg:npm/duplicate@1.0.0",
|
||||
Language: pkg.JavaScript,
|
||||
Type: pkg.NpmPkg,
|
||||
Metadata: pkg.NpmPackageLockEntry{Resolved: "https://registry.npmjs.org/duplicate/-/duplicate-1.0.0.tgz", Integrity: "sha512-duplicate"},
|
||||
},
|
||||
{
|
||||
Name: "middle",
|
||||
Version: "1.0.0",
|
||||
PURL: "pkg:npm/middle@1.0.0",
|
||||
Language: pkg.JavaScript,
|
||||
Type: pkg.NpmPkg,
|
||||
Metadata: pkg.NpmPackageLockEntry{Resolved: "https://registry.npmjs.org/middle/-/middle-1.0.0.tgz", Integrity: "sha512-middle"},
|
||||
},
|
||||
{
|
||||
Name: "parent",
|
||||
Version: "1.0.0",
|
||||
PURL: "pkg:npm/parent@1.0.0",
|
||||
Language: pkg.JavaScript,
|
||||
Type: pkg.NpmPkg,
|
||||
Metadata: pkg.NpmPackageLockEntry{Resolved: "https://registry.npmjs.org/parent/-/parent-1.0.0.tgz", Integrity: "sha512-parent"},
|
||||
},
|
||||
{
|
||||
Name: "shared",
|
||||
Version: "0.5.0",
|
||||
PURL: "pkg:npm/shared@0.5.0",
|
||||
Language: pkg.JavaScript,
|
||||
Type: pkg.NpmPkg,
|
||||
Metadata: pkg.NpmPackageLockEntry{Resolved: "https://registry.npmjs.org/shared/-/shared-0.5.0.tgz", Integrity: "sha512-shared-0.5"},
|
||||
},
|
||||
{
|
||||
Name: "shared",
|
||||
Version: "1.0.0",
|
||||
PURL: "pkg:npm/shared@1.0.0",
|
||||
Language: pkg.JavaScript,
|
||||
Type: pkg.NpmPkg,
|
||||
Metadata: pkg.NpmPackageLockEntry{Resolved: "https://registry.npmjs.org/shared/-/shared-1.0.0.tgz", Integrity: "sha512-shared-1"},
|
||||
},
|
||||
{
|
||||
Name: "shared",
|
||||
Version: "2.0.0",
|
||||
PURL: "pkg:npm/shared@2.0.0",
|
||||
Language: pkg.JavaScript,
|
||||
Type: pkg.NpmPkg,
|
||||
Metadata: pkg.NpmPackageLockEntry{Resolved: "https://registry.npmjs.org/shared/-/shared-2.0.0.tgz", Integrity: "sha512-shared-2"},
|
||||
},
|
||||
}
|
||||
for i := range expectedPkgs {
|
||||
expectedPkgs[i].Locations.Add(file.NewLocation(fixture))
|
||||
}
|
||||
|
||||
adapter := newGenericPackageLockAdapter(CatalogerConfig{})
|
||||
pkgtest.TestFileParser(t, fixture, adapter.parsePackageLock, expectedPkgs, nil)
|
||||
}
|
||||
|
||||
func TestParsePackageLockV2(t *testing.T) {
|
||||
ctx := context.TODO()
|
||||
fixture := "testdata/pkg-lock/package-lock-2.json"
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
{
|
||||
"requires": true,
|
||||
"lockfileVersion": 1,
|
||||
"dependencies": {
|
||||
"parent": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/parent/-/parent-1.0.0.tgz",
|
||||
"integrity": "sha512-parent",
|
||||
"dependencies": {
|
||||
"shared": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/shared/-/shared-1.0.0.tgz",
|
||||
"integrity": "sha512-shared-1"
|
||||
},
|
||||
"middle": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/middle/-/middle-1.0.0.tgz",
|
||||
"integrity": "sha512-middle",
|
||||
"dependencies": {
|
||||
"shared": {
|
||||
"version": "0.5.0",
|
||||
"resolved": "https://registry.npmjs.org/shared/-/shared-0.5.0.tgz",
|
||||
"integrity": "sha512-shared-0.5"
|
||||
}
|
||||
}
|
||||
},
|
||||
"duplicate": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/duplicate/-/duplicate-1.0.0.tgz",
|
||||
"integrity": "sha512-duplicate"
|
||||
}
|
||||
}
|
||||
},
|
||||
"shared": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/shared/-/shared-2.0.0.tgz",
|
||||
"integrity": "sha512-shared-2"
|
||||
},
|
||||
"duplicate": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/duplicate/-/duplicate-1.0.0.tgz",
|
||||
"integrity": "sha512-duplicate"
|
||||
},
|
||||
"dev-parent": {
|
||||
"version": "1.0.0",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"dev-nested": {
|
||||
"version": "1.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -14,7 +14,7 @@ func newPackageFromCargoMetadata(m pkg.RustCargoLockEntry, locations ...file.Loc
|
||||
Name: m.Name,
|
||||
Version: m.Version,
|
||||
Locations: file.NewLocationSet(locations...),
|
||||
PURL: packageURL(m.Name, m.Version),
|
||||
PURL: cargoLockPackageURL(m),
|
||||
Language: pkg.Rust,
|
||||
Type: pkg.RustPkg,
|
||||
Metadata: m,
|
||||
@@ -25,6 +25,18 @@ func newPackageFromCargoMetadata(m pkg.RustCargoLockEntry, locations ...file.Loc
|
||||
return p
|
||||
}
|
||||
|
||||
func cargoLockPackageURL(m pkg.RustCargoLockEntry) string {
|
||||
// Cargo omits source for packages resolved from the local workspace or a
|
||||
// path dependency. A cargo PURL without a repository qualifier identifies
|
||||
// a package on crates.io, so emitting one for a local package can cause
|
||||
// downstream scanners to match unrelated registry vulnerabilities.
|
||||
if m.Source == "" {
|
||||
return ""
|
||||
}
|
||||
|
||||
return packageURL(m.Name, m.Version)
|
||||
}
|
||||
|
||||
func newPackageFromAudit(dep *rustaudit.Package, locations ...file.Location) pkg.Package {
|
||||
p := pkg.Package{
|
||||
Name: dep.Name,
|
||||
|
||||
@@ -4,6 +4,8 @@ import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/anchore/syft/syft/pkg"
|
||||
)
|
||||
|
||||
func Test_packageURL(t *testing.T) {
|
||||
@@ -31,3 +33,34 @@ func Test_packageURL(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestNewPackageFromCargoMetadataPURL(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
source string
|
||||
want string
|
||||
}{
|
||||
{
|
||||
name: "crates.io package",
|
||||
source: "registry+https://github.com/rust-lang/crates.io-index",
|
||||
want: "pkg:cargo/telemetry@0.1.0",
|
||||
},
|
||||
{
|
||||
name: "local path package",
|
||||
source: "",
|
||||
want: "",
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
got := newPackageFromCargoMetadata(pkg.RustCargoLockEntry{
|
||||
Name: "telemetry",
|
||||
Version: "0.1.0",
|
||||
Source: tt.source,
|
||||
})
|
||||
|
||||
assert.Equal(t, tt.want, got.PURL)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -351,7 +351,7 @@ func TestCargoLockWithGitDependencies(t *testing.T) {
|
||||
helloWorld := pkg.Package{
|
||||
Name: "hello_world",
|
||||
Version: "0.1.0",
|
||||
PURL: "pkg:cargo/hello_world@0.1.0",
|
||||
PURL: "",
|
||||
Locations: locations,
|
||||
Language: pkg.Rust,
|
||||
Type: pkg.RustPkg,
|
||||
@@ -673,6 +673,77 @@ func TestCargoLockWithGitDependencies(t *testing.T) {
|
||||
pkgtest.TestFileParser(t, fixture, parseCargoLock, expectedPkgs, expectedRelationships)
|
||||
}
|
||||
|
||||
func TestCargoLockWithPathDependencies(t *testing.T) {
|
||||
fixture := "testdata/path-deps/Cargo.lock"
|
||||
locations := file.NewLocationSet(file.NewLocation(fixture))
|
||||
|
||||
app := pkg.Package{
|
||||
Name: "app",
|
||||
Version: "1.0.0",
|
||||
Locations: locations,
|
||||
Language: pkg.Rust,
|
||||
Type: pkg.RustPkg,
|
||||
Licenses: pkg.NewLicenseSet(),
|
||||
Metadata: pkg.RustCargoLockEntry{
|
||||
Name: "app",
|
||||
Version: "1.0.0",
|
||||
Dependencies: []string{
|
||||
"memchr",
|
||||
"telemetry",
|
||||
},
|
||||
},
|
||||
}
|
||||
memchr := pkg.Package{
|
||||
Name: "memchr",
|
||||
Version: "2.7.4",
|
||||
PURL: "pkg:cargo/memchr@2.7.4",
|
||||
Locations: locations,
|
||||
Language: pkg.Rust,
|
||||
Type: pkg.RustPkg,
|
||||
Licenses: pkg.NewLicenseSet(),
|
||||
Metadata: pkg.RustCargoLockEntry{
|
||||
Name: "memchr",
|
||||
Version: "2.7.4",
|
||||
Source: "registry+https://github.com/rust-lang/crates.io-index",
|
||||
Checksum: "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3",
|
||||
Dependencies: []string{},
|
||||
},
|
||||
}
|
||||
telemetry := pkg.Package{
|
||||
Name: "telemetry",
|
||||
Version: "0.1.0",
|
||||
Locations: locations,
|
||||
Language: pkg.Rust,
|
||||
Type: pkg.RustPkg,
|
||||
Licenses: pkg.NewLicenseSet(),
|
||||
Metadata: pkg.RustCargoLockEntry{
|
||||
Name: "telemetry",
|
||||
Version: "0.1.0",
|
||||
Dependencies: []string{},
|
||||
},
|
||||
}
|
||||
|
||||
expectedPkgs := []pkg.Package{
|
||||
app,
|
||||
memchr,
|
||||
telemetry,
|
||||
}
|
||||
expectedRelationships := []artifact.Relationship{
|
||||
{
|
||||
From: memchr,
|
||||
To: app,
|
||||
Type: artifact.DependencyOfRelationship,
|
||||
},
|
||||
{
|
||||
From: telemetry,
|
||||
To: app,
|
||||
Type: artifact.DependencyOfRelationship,
|
||||
},
|
||||
}
|
||||
|
||||
pkgtest.TestFileParser(t, fixture, parseCargoLock, expectedPkgs, expectedRelationships)
|
||||
}
|
||||
|
||||
func TestCargoLockDependencySpecification(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "app"
|
||||
version = "1.0.0"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
"telemetry",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.7.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
|
||||
|
||||
[[package]]
|
||||
name = "telemetry"
|
||||
version = "0.1.0"
|
||||
Reference in New Issue
Block a user