mirror of
https://github.com/anchore/grype
synced 2024-11-12 23:37:06 +00:00
Correctly match JVM version ranges (#2114)
* add jvm version comparison Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com> * add integration tests Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com> * remove jvm matcher Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com> * add syft binary jre/jdk packages Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com> * bump syft rev to get permissive glob change Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com> * fix test cases Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com> * pull in syft cataloger from main Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com> * fix tests Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com> --------- Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>
This commit is contained in:
parent
eeeea9e96d
commit
2e206052bc
30 changed files with 1243 additions and 168 deletions
4
.gitignore
vendored
4
.gitignore
vendored
|
@ -18,8 +18,8 @@ bin/
|
|||
/.task
|
||||
|
||||
# changelog generation
|
||||
CHANGELOG.md
|
||||
VERSION
|
||||
/CHANGELOG.md
|
||||
/VERSION
|
||||
|
||||
# IDE configuration
|
||||
.vscode/
|
||||
|
|
|
@ -5,6 +5,7 @@ import "github.com/anchore/clio"
|
|||
// matchConfig contains all matching-related configuration options available to the user via the application config.
|
||||
type matchConfig struct {
|
||||
Java matcherConfig `yaml:"java" json:"java" mapstructure:"java"` // settings for the java matcher
|
||||
JVM matcherConfig `yaml:"jvm" json:"jvm" mapstructure:"jvm"` // settings for the jvm matcher
|
||||
Dotnet matcherConfig `yaml:"dotnet" json:"dotnet" mapstructure:"dotnet"` // settings for the dotnet matcher
|
||||
Golang golangConfig `yaml:"golang" json:"golang" mapstructure:"golang"` // settings for the golang matcher
|
||||
Javascript matcherConfig `yaml:"javascript" json:"javascript" mapstructure:"javascript"` // settings for the javascript matcher
|
||||
|
@ -43,6 +44,7 @@ func defaultMatchConfig() matchConfig {
|
|||
dontUseCpe := matcherConfig{UseCPEs: false}
|
||||
return matchConfig{
|
||||
Java: dontUseCpe,
|
||||
JVM: useCpe,
|
||||
Dotnet: dontUseCpe,
|
||||
Golang: defaultGolangConfig(),
|
||||
Javascript: dontUseCpe,
|
||||
|
|
54
go.mod
54
go.mod
|
@ -9,18 +9,19 @@ require (
|
|||
github.com/adrg/xdg v0.5.0
|
||||
github.com/anchore/bubbly v0.0.0-20231115134915-def0aba654a9
|
||||
github.com/anchore/clio v0.0.0-20240522144804-d81e109008aa
|
||||
github.com/anchore/go-collections v0.0.0-20240216171411-9321230ce537
|
||||
github.com/anchore/go-logger v0.0.0-20230725134548-c21dafa1ec5a
|
||||
github.com/anchore/go-testutils v0.0.0-20200925183923-d5f45b0d3c04
|
||||
github.com/anchore/go-version v1.2.2-0.20210903204242-51efa5b487c4
|
||||
github.com/anchore/packageurl-go v0.1.1-0.20240507183024-848e011fc24f
|
||||
github.com/anchore/stereoscope v0.0.3
|
||||
github.com/anchore/syft v1.12.2
|
||||
github.com/anchore/syft v1.12.3-0.20240923212138-01de99b25304
|
||||
github.com/aquasecurity/go-pep440-version v0.0.0-20210121094942-22b2f8951d46
|
||||
github.com/bmatcuk/doublestar/v2 v2.0.4
|
||||
github.com/charmbracelet/bubbletea v1.1.1
|
||||
github.com/charmbracelet/lipgloss v0.13.0
|
||||
github.com/dave/jennifer v1.7.1
|
||||
github.com/docker/docker v27.2.1+incompatible
|
||||
github.com/docker/docker v27.3.0+incompatible
|
||||
github.com/dustin/go-humanize v1.0.1
|
||||
github.com/facebookincubator/nvdtools v0.1.5
|
||||
github.com/gabriel-vasile/mimetype v1.4.5
|
||||
|
@ -49,7 +50,6 @@ require (
|
|||
// pinned to pull in 386 arch fix: https://github.com/scylladb/go-set/commit/cc7b2070d91ebf40d233207b633e28f5bd8f03a5
|
||||
github.com/scylladb/go-set v1.0.3-0.20200225121959-cc7b2070d91e
|
||||
github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3
|
||||
github.com/sirupsen/logrus v1.9.3 // indirect
|
||||
github.com/spf13/afero v1.11.0
|
||||
github.com/spf13/cobra v1.8.1
|
||||
github.com/stretchr/testify v1.9.0
|
||||
|
@ -60,14 +60,12 @@ require (
|
|||
gorm.io/gorm v1.25.12
|
||||
)
|
||||
|
||||
require github.com/anchore/go-collections v0.0.0-20240216171411-9321230ce537
|
||||
|
||||
require (
|
||||
cloud.google.com/go v0.110.10 // indirect
|
||||
cloud.google.com/go/compute v1.23.3 // indirect
|
||||
cloud.google.com/go v0.112.1 // indirect
|
||||
cloud.google.com/go/compute v1.24.0 // indirect
|
||||
cloud.google.com/go/compute/metadata v0.2.3 // indirect
|
||||
cloud.google.com/go/iam v1.1.5 // indirect
|
||||
cloud.google.com/go/storage v1.35.1 // indirect
|
||||
cloud.google.com/go/iam v1.1.6 // indirect
|
||||
cloud.google.com/go/storage v1.38.0 // indirect
|
||||
dario.cat/mergo v1.0.1 // indirect
|
||||
github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24 // indirect
|
||||
github.com/AdamKorcz/go-118-fuzz-build v0.0.0-20230306123547-8075edf89bb0 // indirect
|
||||
|
@ -80,7 +78,7 @@ require (
|
|||
github.com/Microsoft/hcsshim v0.11.4 // indirect
|
||||
github.com/ProtonMail/go-crypto v1.0.0 // indirect
|
||||
github.com/acobaugh/osrelease v0.1.0 // indirect
|
||||
github.com/anchore/fangs v0.0.0-20240508143433-f016b099950f // indirect
|
||||
github.com/anchore/fangs v0.0.0-20240903175602-e716ef12c23d // indirect
|
||||
github.com/anchore/go-macholibre v0.0.0-20220308212642-53e6d0aaf6fb // indirect
|
||||
github.com/anchore/go-struct-converter v0.0.0-20221118182256-c68fdcfa2092 // indirect
|
||||
github.com/andybalholm/brotli v1.0.4 // indirect
|
||||
|
@ -120,16 +118,16 @@ require (
|
|||
github.com/emirpasic/gods v1.18.1 // indirect
|
||||
github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f // indirect
|
||||
github.com/felixge/fgprof v0.9.3 // indirect
|
||||
github.com/felixge/httpsnoop v1.0.3 // indirect
|
||||
github.com/felixge/httpsnoop v1.0.4 // indirect
|
||||
github.com/fsnotify/fsnotify v1.7.0 // indirect
|
||||
github.com/github/go-spdx/v2 v2.3.1 // indirect
|
||||
github.com/github/go-spdx/v2 v2.3.2 // indirect
|
||||
github.com/gkampitakis/ciinfo v0.3.0 // indirect
|
||||
github.com/gkampitakis/go-diff v1.3.2 // indirect
|
||||
github.com/glebarez/go-sqlite v1.21.2 // indirect
|
||||
github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect
|
||||
github.com/go-git/go-billy/v5 v5.5.0 // indirect
|
||||
github.com/go-git/go-git/v5 v5.12.0 // indirect
|
||||
github.com/go-logr/logr v1.2.4 // indirect
|
||||
github.com/go-logr/logr v1.4.1 // indirect
|
||||
github.com/go-logr/stdr v1.2.2 // indirect
|
||||
github.com/go-restruct/restruct v1.2.0-alpha // indirect
|
||||
github.com/gogo/protobuf v1.3.2 // indirect
|
||||
|
@ -140,7 +138,7 @@ require (
|
|||
github.com/google/pprof v0.0.0-20240409012703-83162a5b38cd // indirect
|
||||
github.com/google/s2a-go v0.1.7 // indirect
|
||||
github.com/googleapis/enterprise-certificate-proxy v0.3.2 // indirect
|
||||
github.com/googleapis/gax-go/v2 v2.12.0 // indirect
|
||||
github.com/googleapis/gax-go/v2 v2.12.3 // indirect
|
||||
github.com/hashicorp/errwrap v1.1.0 // indirect
|
||||
github.com/hashicorp/go-safetemp v1.0.0 // indirect
|
||||
github.com/hashicorp/hcl v1.0.0 // indirect
|
||||
|
@ -191,7 +189,7 @@ require (
|
|||
github.com/package-url/packageurl-go v0.1.1 // indirect
|
||||
github.com/pborman/indent v1.2.1 // indirect
|
||||
github.com/pelletier/go-toml v1.9.5 // indirect
|
||||
github.com/pelletier/go-toml/v2 v2.1.0 // indirect
|
||||
github.com/pelletier/go-toml/v2 v2.2.2 // indirect
|
||||
github.com/pierrec/lz4/v4 v4.1.19 // indirect
|
||||
github.com/pjbgf/sha1cd v0.3.0 // indirect
|
||||
github.com/pkg/errors v0.9.1 // indirect
|
||||
|
@ -207,12 +205,13 @@ require (
|
|||
github.com/sassoftware/go-rpmutils v0.4.0 // indirect
|
||||
github.com/secDre4mer/pkcs7 v0.0.0-20240322103146-665324a4461d // indirect
|
||||
github.com/shopspring/decimal v1.4.0 // indirect
|
||||
github.com/sirupsen/logrus v1.9.3 // indirect
|
||||
github.com/skeema/knownhosts v1.2.2 // indirect
|
||||
github.com/sourcegraph/conc v0.3.0 // indirect
|
||||
github.com/spdx/tools-golang v0.5.5 // indirect
|
||||
github.com/spf13/cast v1.7.0 // indirect
|
||||
github.com/spf13/pflag v1.0.5 // indirect
|
||||
github.com/spf13/viper v1.18.2 // indirect
|
||||
github.com/spf13/viper v1.19.0 // indirect
|
||||
github.com/subosito/gotenv v1.6.0 // indirect
|
||||
github.com/sylabs/sif/v2 v2.17.1 // indirect
|
||||
github.com/sylabs/squashfs v1.0.0 // indirect
|
||||
|
@ -231,10 +230,11 @@ require (
|
|||
github.com/zclconf/go-cty v1.14.0 // indirect
|
||||
github.com/zyedidia/generic v1.2.2-0.20230320175451-4410d2372cb1 // indirect
|
||||
go.opencensus.io v0.24.0 // indirect
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.45.0 // indirect
|
||||
go.opentelemetry.io/otel v1.19.0 // indirect
|
||||
go.opentelemetry.io/otel/metric v1.19.0 // indirect
|
||||
go.opentelemetry.io/otel/trace v1.19.0 // indirect
|
||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.49.0 // indirect
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0 // indirect
|
||||
go.opentelemetry.io/otel v1.24.0 // indirect
|
||||
go.opentelemetry.io/otel/metric v1.24.0 // indirect
|
||||
go.opentelemetry.io/otel/trace v1.24.0 // indirect
|
||||
go.uber.org/atomic v1.9.0 // indirect
|
||||
go.uber.org/multierr v1.9.0 // indirect
|
||||
golang.org/x/crypto v0.27.0 // indirect
|
||||
|
@ -247,12 +247,12 @@ require (
|
|||
golang.org/x/text v0.18.0 // indirect
|
||||
golang.org/x/time v0.5.0 // indirect
|
||||
golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d // indirect
|
||||
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect
|
||||
google.golang.org/api v0.153.0 // indirect
|
||||
google.golang.org/genproto v0.0.0-20231106174013-bbf56f31fb17 // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20231106174013-bbf56f31fb17 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20231120223509-83a465c0220f // indirect
|
||||
google.golang.org/grpc v1.59.0 // indirect
|
||||
golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 // indirect
|
||||
google.golang.org/api v0.171.0 // indirect
|
||||
google.golang.org/genproto v0.0.0-20240213162025-012b6fc9bca9 // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20240311132316-a219d84964c2 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240314234333-6e1732d8331c // indirect
|
||||
google.golang.org/grpc v1.62.1 // indirect
|
||||
google.golang.org/protobuf v1.33.0 // indirect
|
||||
gopkg.in/ini.v1 v1.67.0 // indirect
|
||||
gopkg.in/warnings.v0 v0.1.2 // indirect
|
||||
|
@ -260,7 +260,7 @@ require (
|
|||
modernc.org/libc v1.55.3 // indirect
|
||||
modernc.org/mathutil v1.6.0 // indirect
|
||||
modernc.org/memory v1.8.0 // indirect
|
||||
modernc.org/sqlite v1.33.0 // indirect
|
||||
modernc.org/sqlite v1.33.1 // indirect
|
||||
)
|
||||
|
||||
replace github.com/mholt/archiver/v3 v3.5.1 => github.com/anchore/archiver/v3 v3.5.2
|
||||
|
|
101
go.sum
101
go.sum
|
@ -31,8 +31,8 @@ cloud.google.com/go v0.100.2/go.mod h1:4Xra9TjzAeYHrl5+oeLlzbM2k3mjVhZh4UqTZ//w9
|
|||
cloud.google.com/go v0.102.0/go.mod h1:oWcCzKlqJ5zgHQt9YsaeTY9KzIvjyy0ArmiBUgpQ+nc=
|
||||
cloud.google.com/go v0.102.1/go.mod h1:XZ77E9qnTEnrgEOvr4xzfdX5TRo7fB4T2F4O6+34hIU=
|
||||
cloud.google.com/go v0.104.0/go.mod h1:OO6xxXdJyvuJPcEPBLN9BJPD+jep5G1+2U5B5gkRYtA=
|
||||
cloud.google.com/go v0.110.10 h1:LXy9GEO+timppncPIAZoOj3l58LIU9k+kn48AN7IO3Y=
|
||||
cloud.google.com/go v0.110.10/go.mod h1:v1OoFqYxiBkUrruItNM3eT4lLByNjxmJSV/xDKJNnic=
|
||||
cloud.google.com/go v0.112.1 h1:uJSeirPke5UNZHIb4SxfZklVSiWWVqW4oXlETwZziwM=
|
||||
cloud.google.com/go v0.112.1/go.mod h1:+Vbu+Y1UU+I1rjmzeMOb/8RfkKJK2Gyxi1X6jJCZLo4=
|
||||
cloud.google.com/go/aiplatform v1.22.0/go.mod h1:ig5Nct50bZlzV6NvKaTwmplLLddFx0YReh9WfTO5jKw=
|
||||
cloud.google.com/go/aiplatform v1.24.0/go.mod h1:67UUvRBKG6GTayHKV8DBv2RtR1t93YRu5B1P3x99mYY=
|
||||
cloud.google.com/go/analytics v0.11.0/go.mod h1:DjEWCu41bVbYcKyvlws9Er60YE4a//bK6mnhWvQeFNI=
|
||||
|
@ -69,8 +69,8 @@ cloud.google.com/go/compute v1.6.0/go.mod h1:T29tfhtVbq1wvAPo0E3+7vhgmkOYeXjhFvz
|
|||
cloud.google.com/go/compute v1.6.1/go.mod h1:g85FgpzFvNULZ+S8AYq87axRKuf2Kh7deLqV/jJ3thU=
|
||||
cloud.google.com/go/compute v1.7.0/go.mod h1:435lt8av5oL9P3fv1OEzSbSUe+ybHXGMPQHHZWZxy9U=
|
||||
cloud.google.com/go/compute v1.10.0/go.mod h1:ER5CLbMxl90o2jtNbGSbtfOpQKR0t15FOtRsugnLrlU=
|
||||
cloud.google.com/go/compute v1.23.3 h1:6sVlXXBmbd7jNX0Ipq0trII3e4n1/MsADLK6a+aiVlk=
|
||||
cloud.google.com/go/compute v1.23.3/go.mod h1:VCgBUoMnIVIR0CscqQiPJLAG25E3ZRZMzcFZeQ+h8CI=
|
||||
cloud.google.com/go/compute v1.24.0 h1:phWcR2eWzRJaL/kOiJwfFsPs4BaKq1j6vnpZrc1YlVg=
|
||||
cloud.google.com/go/compute v1.24.0/go.mod h1:kw1/T+h/+tK2LJK0wiPPx1intgdAM3j/g3hFDlscY40=
|
||||
cloud.google.com/go/compute/metadata v0.2.3 h1:mg4jlk7mCAj6xXp9UJ4fjI9VUI5rubuGBW5aJ7UnBMY=
|
||||
cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA=
|
||||
cloud.google.com/go/containeranalysis v0.5.1/go.mod h1:1D92jd8gRR/c0fGMlymRgxWD3Qw9C1ff6/T7mLgVL8I=
|
||||
|
@ -111,8 +111,8 @@ cloud.google.com/go/gkehub v0.10.0/go.mod h1:UIPwxI0DsrpsVoWpLB0stwKCP+WFVG9+y97
|
|||
cloud.google.com/go/grafeas v0.2.0/go.mod h1:KhxgtF2hb0P191HlY5besjYm6MqTSTj3LSI+M+ByZHc=
|
||||
cloud.google.com/go/iam v0.3.0/go.mod h1:XzJPvDayI+9zsASAFO68Hk07u3z+f+JrT2xXNdp4bnY=
|
||||
cloud.google.com/go/iam v0.5.0/go.mod h1:wPU9Vt0P4UmCux7mqtRu6jcpPAb74cP1fh50J3QpkUc=
|
||||
cloud.google.com/go/iam v1.1.5 h1:1jTsCu4bcsNsE4iiqNT5SHwrDRCfRmIaaaVFhRveTJI=
|
||||
cloud.google.com/go/iam v1.1.5/go.mod h1:rB6P/Ic3mykPbFio+vo7403drjlgvoWfYpJhMXEbzv8=
|
||||
cloud.google.com/go/iam v1.1.6 h1:bEa06k05IO4f4uJonbB5iAgKTPpABy1ayxaIZV/GHVc=
|
||||
cloud.google.com/go/iam v1.1.6/go.mod h1:O0zxdPeGBoFdWW3HWmBxJsk0pfvNM/p/qa82rWOGTwI=
|
||||
cloud.google.com/go/language v1.4.0/go.mod h1:F9dRpNFQmJbkaop6g0JhSBXCNlO90e1KWx5iDdxbWic=
|
||||
cloud.google.com/go/language v1.6.0/go.mod h1:6dJ8t3B+lUYfStgls25GusK04NLh3eDLQnWM3mdEbhI=
|
||||
cloud.google.com/go/lifesciences v0.5.0/go.mod h1:3oIKy8ycWGPUyZDR/8RNnTOYevhaMLqh5vLUXs9zvT8=
|
||||
|
@ -173,8 +173,8 @@ cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9
|
|||
cloud.google.com/go/storage v1.22.1/go.mod h1:S8N1cAStu7BOeFfE8KAQzmyyLkK8p/vmRq6kuBTW58Y=
|
||||
cloud.google.com/go/storage v1.23.0/go.mod h1:vOEEDNFnciUMhBeT6hsJIn3ieU5cFRmzeLgDvXzfIXc=
|
||||
cloud.google.com/go/storage v1.27.0/go.mod h1:x9DOL8TK/ygDUMieqwfhdpQryTeEkhGKMi80i/iqR2s=
|
||||
cloud.google.com/go/storage v1.35.1 h1:B59ahL//eDfx2IIKFBeT5Atm9wnNmj3+8xG/W4WB//w=
|
||||
cloud.google.com/go/storage v1.35.1/go.mod h1:M6M/3V/D3KpzMTJyPOR/HU6n2Si5QdaXYEsng2xgOs8=
|
||||
cloud.google.com/go/storage v1.38.0 h1:Az68ZRGlnNTpIBbLjSMIV2BDcwwXYlRlQzis0llkpJg=
|
||||
cloud.google.com/go/storage v1.38.0/go.mod h1:tlUADB0mAb9BgYls9lq+8MGkfzOXuLrnHXlpHmvFJoY=
|
||||
cloud.google.com/go/talent v1.1.0/go.mod h1:Vl4pt9jiHKvOgF9KoZo6Kob9oV4lwd/ZD5Cto54zDRw=
|
||||
cloud.google.com/go/talent v1.2.0/go.mod h1:MoNF9bhFQbiJ6eFD3uSsg0uBALw4n4gaCaEjBw9zo8g=
|
||||
cloud.google.com/go/videointelligence v1.6.0/go.mod h1:w0DIDlVRKtwPCn/C4iwZIJdvC69yInhW0cfi+p546uU=
|
||||
|
@ -240,8 +240,8 @@ github.com/anchore/bubbly v0.0.0-20231115134915-def0aba654a9 h1:p0ZIe0htYOX284Y4
|
|||
github.com/anchore/bubbly v0.0.0-20231115134915-def0aba654a9/go.mod h1:3ZsFB9tzW3vl4gEiUeuSOMDnwroWxIxJelOOHUp8dSw=
|
||||
github.com/anchore/clio v0.0.0-20240522144804-d81e109008aa h1:pwlAn4O9SBUnlgfa69YcqIynbUyobLVFYu8HxSoCffA=
|
||||
github.com/anchore/clio v0.0.0-20240522144804-d81e109008aa/go.mod h1:nD3H5uIvjxlfmakOBgtyFQbk5Zjp3l538kxfpHPslzI=
|
||||
github.com/anchore/fangs v0.0.0-20240508143433-f016b099950f h1:NOhzafCyNYFi88qxkBFjMzQo4dRa1vDhBzx+0Uovx8Q=
|
||||
github.com/anchore/fangs v0.0.0-20240508143433-f016b099950f/go.mod h1:sVpRS2yNCw6tLVpvA1QSDVWTJVpCuAm8JNZgn4Sjz/k=
|
||||
github.com/anchore/fangs v0.0.0-20240903175602-e716ef12c23d h1:ZD4wdCBgJJzJybjTUIEiiupLF7B9H3WLuBTjspBO2Mc=
|
||||
github.com/anchore/fangs v0.0.0-20240903175602-e716ef12c23d/go.mod h1:Xh4ObY3fmoMzOEVXwDtS1uK44JC7+nRD0n29/1KYFYg=
|
||||
github.com/anchore/go-collections v0.0.0-20240216171411-9321230ce537 h1:GjNGuwK5jWjJMyVppBjYS54eOiiSNv4Ba869k4wh72Q=
|
||||
github.com/anchore/go-collections v0.0.0-20240216171411-9321230ce537/go.mod h1:1aiktV46ATCkuVg0O573ZrH56BUawTECPETbZyBcqT8=
|
||||
github.com/anchore/go-logger v0.0.0-20230725134548-c21dafa1ec5a h1:nJ2G8zWKASyVClGVgG7sfM5mwoZlZ2zYpIzN2OhjWkw=
|
||||
|
@ -258,8 +258,8 @@ github.com/anchore/packageurl-go v0.1.1-0.20240507183024-848e011fc24f h1:B/E9ixK
|
|||
github.com/anchore/packageurl-go v0.1.1-0.20240507183024-848e011fc24f/go.mod h1:Blo6OgJNiYF41ufcgHKkbCKF2MDOMlrqhXv/ij6ocR4=
|
||||
github.com/anchore/stereoscope v0.0.3 h1:JRPHySy8S6P+Ff3IDiQ29ap1i8/laUQxDk9K1eFh/2U=
|
||||
github.com/anchore/stereoscope v0.0.3/go.mod h1:5DJheGPjVRsSqegTB24Zi6SCHnYQnA519yeIG+RG+I4=
|
||||
github.com/anchore/syft v1.12.2 h1:K5YXJ2Ox4C3+Q+rA4jDpsLAoYNd27RMfinvY2JmbEiM=
|
||||
github.com/anchore/syft v1.12.2/go.mod h1:xFMGMFmhWTK0CJvaKwz6OPVgRdcyCkl7QO/3O/JAXI0=
|
||||
github.com/anchore/syft v1.12.3-0.20240923212138-01de99b25304 h1:NHX8OBV167K2JhGxluQRag2VAZrsg+JREndBkmzs9C0=
|
||||
github.com/anchore/syft v1.12.3-0.20240923212138-01de99b25304/go.mod h1:zL9Z5vtq8O+h6RRYo0lyb61NLx00OqcvoVNgk8qoMXA=
|
||||
github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8=
|
||||
github.com/andybalholm/brotli v1.0.1/go.mod h1:loMXtMfwqflxFJPmdbJO0a3KNoPuLBgiu3qAvBg8x/Y=
|
||||
github.com/andybalholm/brotli v1.0.4 h1:V7DdXeJtZscaqfNuAdSRuRFzuiKlHSC/Zh3zl9qY3JY=
|
||||
|
@ -381,8 +381,8 @@ github.com/docker/cli v27.1.1+incompatible h1:goaZxOqs4QKxznZjjBWKONQci/MywhtRv2
|
|||
github.com/docker/cli v27.1.1+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
|
||||
github.com/docker/distribution v2.8.3+incompatible h1:AtKxIZ36LoNK51+Z6RpzLpddBirtxJnzDrHLEKxTAYk=
|
||||
github.com/docker/distribution v2.8.3+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
|
||||
github.com/docker/docker v27.2.1+incompatible h1:fQdiLfW7VLscyoeYEBz7/J8soYFDZV1u6VW6gJEjNMI=
|
||||
github.com/docker/docker v27.2.1+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
|
||||
github.com/docker/docker v27.3.0+incompatible h1:BNb1QY6o4JdKpqwi9IB+HUYcRRrVN4aGFUTvDmWYK1A=
|
||||
github.com/docker/docker v27.3.0+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
|
||||
github.com/docker/docker-credential-helpers v0.7.0 h1:xtCHsjxogADNZcdv1pKUHXryefjlVRqWqIhk/uXJp0A=
|
||||
github.com/docker/docker-credential-helpers v0.7.0/go.mod h1:rETQfLdHNT3foU5kuNkFR1R1V12OJRRO5lzt2D1b5X0=
|
||||
github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ=
|
||||
|
@ -428,8 +428,8 @@ github.com/fatih/set v0.2.1 h1:nn2CaJyknWE/6txyUDGwysr3G5QC6xWB/PtVjPBbeaA=
|
|||
github.com/fatih/set v0.2.1/go.mod h1:+RKtMCH+favT2+3YecHGxcc0b4KyVWA1QWWJUs4E0CI=
|
||||
github.com/felixge/fgprof v0.9.3 h1:VvyZxILNuCiUCSXtPtYmmtGvb65nqXh2QFWc0Wpf2/g=
|
||||
github.com/felixge/fgprof v0.9.3/go.mod h1:RdbpDgzqYVh/T9fPELJyV7EYJuHB55UTEULNun8eiPw=
|
||||
github.com/felixge/httpsnoop v1.0.3 h1:s/nj+GCswXYzN5v2DpNMuMQYe+0DDwt5WVCU6CWBdXk=
|
||||
github.com/felixge/httpsnoop v1.0.3/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
|
||||
github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg=
|
||||
github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
|
||||
github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8=
|
||||
github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0=
|
||||
github.com/fsnotify/fsnotify v1.5.1/go.mod h1:T3375wBYaZdLLcVNkcVbzGHY7f1l/uK5T5Ai1i3InKU=
|
||||
|
@ -438,8 +438,8 @@ github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyT
|
|||
github.com/gabriel-vasile/mimetype v1.4.5 h1:J7wGKdGu33ocBOhGy0z653k/lFKLFDPJMG8Gql0kxn4=
|
||||
github.com/gabriel-vasile/mimetype v1.4.5/go.mod h1:ibHel+/kbxn9x2407k1izTA1S81ku1z/DlgOW2QE0M4=
|
||||
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||
github.com/github/go-spdx/v2 v2.3.1 h1:ffGuHTbHuHzWPt53n8f9o8clGutuLPObo3zB4JAjxU8=
|
||||
github.com/github/go-spdx/v2 v2.3.1/go.mod h1:2ZxKsOhvBp+OYBDlsGnUMcchLeo2mrpEBn2L1C+U3IQ=
|
||||
github.com/github/go-spdx/v2 v2.3.2 h1:IfdyNHTqzs4zAJjXdVQfRnxt1XMfycXoHBE2Vsm1bjs=
|
||||
github.com/github/go-spdx/v2 v2.3.2/go.mod h1:2ZxKsOhvBp+OYBDlsGnUMcchLeo2mrpEBn2L1C+U3IQ=
|
||||
github.com/gkampitakis/ciinfo v0.3.0 h1:gWZlOC2+RYYttL0hBqcoQhM7h1qNkVqvRCV1fOvpAv8=
|
||||
github.com/gkampitakis/ciinfo v0.3.0/go.mod h1:1NIwaOcFChN4fa/B0hEBdAb6npDlFL8Bwx4dfRLRqAo=
|
||||
github.com/gkampitakis/go-diff v1.3.2 h1:Qyn0J9XJSDTgnsgHRdz9Zp24RaJeKMUHg2+PDZZdC4M=
|
||||
|
@ -468,8 +468,8 @@ github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2
|
|||
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
|
||||
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
|
||||
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
||||
github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ=
|
||||
github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
||||
github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ=
|
||||
github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
|
||||
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
|
||||
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
|
||||
github.com/go-restruct/restruct v1.2.0-alpha h1:2Lp474S/9660+SJjpVxoKuWX09JsXHSrdV7Nv3/gkvc=
|
||||
|
@ -589,8 +589,8 @@ github.com/googleapis/gax-go/v2 v2.3.0/go.mod h1:b8LNqSzNabLiUpXKkY7HAR5jr6bIT99
|
|||
github.com/googleapis/gax-go/v2 v2.4.0/go.mod h1:XOTVJ59hdnfJLIP/dh8n5CGryZR2LxK9wbMD5+iXC6c=
|
||||
github.com/googleapis/gax-go/v2 v2.5.1/go.mod h1:h6B0KMMFNtI2ddbGJn3T3ZbwkeT6yqEF02fYlzkUCyo=
|
||||
github.com/googleapis/gax-go/v2 v2.6.0/go.mod h1:1mjbznJAPHFpesgE5ucqfYEscaz5kMdcIDwU/6+DDoY=
|
||||
github.com/googleapis/gax-go/v2 v2.12.0 h1:A+gCJKdRfqXkr+BIRGtZLibNXf0m1f9E4HG56etFpas=
|
||||
github.com/googleapis/gax-go/v2 v2.12.0/go.mod h1:y+aIqrI5eb1YGMVJfuV3185Ts/D7qKpsEkdD5+I6QGU=
|
||||
github.com/googleapis/gax-go/v2 v2.12.3 h1:5/zPPDvw8Q1SuXjrqrZslrqT7dL/uJT2CQii/cLCKqA=
|
||||
github.com/googleapis/gax-go/v2 v2.12.3/go.mod h1:AKloxT6GtNbaLm8QTNSidHUVsHYcBHwWRvkNFJUQcS4=
|
||||
github.com/googleapis/go-type-adapters v1.0.0/go.mod h1:zHW75FOG2aur7gAO2B+MLby+cLsWGBF62rFAi7WjWO4=
|
||||
github.com/gookit/color v1.2.5/go.mod h1:AhIE+pS6D4Ql0SQWbBeXPHw7gY0/sjHoA4s/n1KB7xg=
|
||||
github.com/gookit/color v1.5.4 h1:FZmqs7XOyGgCAxmWyPslpiok1k05wmY3SJTytgvYFs0=
|
||||
|
@ -826,8 +826,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.1.0 h1:FnwAJ4oYMvbT/34k9zzHuZNrhlz48GB3/s6at6/MHO4=
|
||||
github.com/pelletier/go-toml/v2 v2.1.0/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc=
|
||||
github.com/pelletier/go-toml/v2 v2.2.2 h1:aYUidT7k73Pcl9nb2gScu7NSrKCSHIDE89b3+6Wq+LM=
|
||||
github.com/pelletier/go-toml/v2 v2.2.2/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs=
|
||||
github.com/pierrec/lz4/v4 v4.1.2/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4=
|
||||
github.com/pierrec/lz4/v4 v4.1.19 h1:tYLzDnjDXh9qIxSTKHwXwOYmm9d887Y7Y1ZkyXYHAN4=
|
||||
github.com/pierrec/lz4/v4 v4.1.19/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4=
|
||||
|
@ -932,8 +932,8 @@ github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0
|
|||
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
|
||||
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||
github.com/spf13/viper v1.10.0/go.mod h1:SoyBPwAtKDzypXNDFKN5kzH7ppppbGZtls1UpIy5AsM=
|
||||
github.com/spf13/viper v1.18.2 h1:LUXCnvUvSM6FXAsj6nnfc8Q2tp1dIgUfY9Kc8GsSOiQ=
|
||||
github.com/spf13/viper v1.18.2/go.mod h1:EKmWIqdnk5lOcmR72yw6hS+8OPYcwD0jteitLMVB+yk=
|
||||
github.com/spf13/viper v1.19.0 h1:RWq5SEjt8o25SROyN3z2OrDB9l7RPd3lwTWU8EcEdcI=
|
||||
github.com/spf13/viper v1.19.0/go.mod h1:GQUN9bilAbhU/jgc1bKs99f/suXKeUMct8Adx5+Ntkg=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||
|
@ -1029,20 +1029,22 @@ go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk=
|
|||
go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E=
|
||||
go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0=
|
||||
go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.45.0 h1:x8Z78aZx8cOF0+Kkazoc7lwUNMGy0LrzEMxTm4BbTxg=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.45.0/go.mod h1:62CPTSry9QZtOaSsE3tOzhx6LzDhHnXJ6xHeMNNiM6Q=
|
||||
go.opentelemetry.io/otel v1.19.0 h1:MuS/TNf4/j4IXsZuJegVzI1cwut7Qc00344rgH7p8bs=
|
||||
go.opentelemetry.io/otel v1.19.0/go.mod h1:i0QyjOq3UPoTzff0PJB2N66fb4S0+rSbSB15/oyH9fY=
|
||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.49.0 h1:4Pp6oUg3+e/6M4C0A/3kJ2VYa++dsWVTtGgLVj5xtHg=
|
||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.49.0/go.mod h1:Mjt1i1INqiaoZOMGR1RIUJN+i3ChKoFRqzrRQhlkbs0=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0 h1:jq9TW8u3so/bN+JPT166wjOI6/vQPF6Xe7nMNIltagk=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0/go.mod h1:p8pYQP+m5XfbZm9fxtSKAbM6oIllS7s2AfxrChvc7iw=
|
||||
go.opentelemetry.io/otel v1.24.0 h1:0LAOdjNmQeSTzGBzduGe/rU4tZhMwL5rWgtp9Ku5Jfo=
|
||||
go.opentelemetry.io/otel v1.24.0/go.mod h1:W7b9Ozg4nkF5tWI5zsXkaKKDjdVjpD4oAt9Qi/MArHo=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.19.0 h1:Mne5On7VWdx7omSrSSZvM4Kw7cS7NQkOOmLcgscI51U=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.19.0/go.mod h1:IPtUMKL4O3tH5y+iXVyAXqpAwMuzC1IrxVS81rummfE=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.19.0 h1:IeMeyr1aBvBiPVYihXIaeIZba6b8E1bYp7lbdxK8CQg=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.19.0/go.mod h1:oVdCUtjq9MK9BlS7TtucsQwUcXcymNiEDjgDD2jMtZU=
|
||||
go.opentelemetry.io/otel/metric v1.19.0 h1:aTzpGtV0ar9wlV4Sna9sdJyII5jTVJEvKETPiOKwvpE=
|
||||
go.opentelemetry.io/otel/metric v1.19.0/go.mod h1:L5rUsV9kM1IxCj1MmSdS+JQAcVm319EUrDVLrt7jqt8=
|
||||
go.opentelemetry.io/otel/sdk v1.19.0 h1:6USY6zH+L8uMH8L3t1enZPR3WFEmSTADlqldyHtJi3o=
|
||||
go.opentelemetry.io/otel/sdk v1.19.0/go.mod h1:NedEbbS4w3C6zElbLdPJKOpJQOrGUJ+GfzpjUvI0v1A=
|
||||
go.opentelemetry.io/otel/trace v1.19.0 h1:DFVQmlVbfVeOuBRrwdtaehRrWiL1JoVs9CPIQ1Dzxpg=
|
||||
go.opentelemetry.io/otel/trace v1.19.0/go.mod h1:mfaSyvGyEJEI0nyV2I4qhNQnbBOUUmYZpYojqMnX2vo=
|
||||
go.opentelemetry.io/otel/metric v1.24.0 h1:6EhoGWWK28x1fbpA4tYTOWBkPefTDQnb8WSGXlc88kI=
|
||||
go.opentelemetry.io/otel/metric v1.24.0/go.mod h1:VYhLe1rFfxuTXLgj4CBiyz+9WYBA8pNGJgDcSFRKBco=
|
||||
go.opentelemetry.io/otel/sdk v1.22.0 h1:6coWHw9xw7EfClIC/+O31R8IY3/+EiRFHevmHafB2Gw=
|
||||
go.opentelemetry.io/otel/sdk v1.22.0/go.mod h1:iu7luyVGYovrRpe2fmj3CVKouQNdTOkxtLzPvPz1DOc=
|
||||
go.opentelemetry.io/otel/trace v1.24.0 h1:CsKnnL4dUAr/0llH9FKuc698G04IrpWV0MQA/Y1YELI=
|
||||
go.opentelemetry.io/otel/trace v1.24.0/go.mod h1:HPc3Xr/cOApsBI154IU0OI0HJexz+aw5uPdbs3UCjNU=
|
||||
go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI=
|
||||
go.opentelemetry.io/proto/otlp v1.0.0 h1:T0TX0tmXU8a3CbNXzEKGeU5mIVOdf0oykP+u2lIVU/I=
|
||||
go.opentelemetry.io/proto/otlp v1.0.0/go.mod h1:Sy6pihPLfYHkr3NkUbEhGHFhINUSI/v80hjKIs5JXpM=
|
||||
|
@ -1403,8 +1405,9 @@ golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8T
|
|||
golang.org/x/xerrors v0.0.0-20220411194840-2f41105eb62f/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8=
|
||||
golang.org/x/xerrors v0.0.0-20220609144429-65e65417b02f/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8=
|
||||
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 h1:H2TDz8ibqkAF6YGhCdN3jS9O0/s90v0rJh3X/OLHEUk=
|
||||
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8=
|
||||
golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 h1:+cNy6SZtPcJQH3LJVLOSmiC7MMxXNOb3PU/VUEz+EhU=
|
||||
golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028/go.mod h1:NDW/Ps6MPRej6fsCIbMTohpP40sJ/P/vI1MoTEGwX90=
|
||||
google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
|
||||
google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M=
|
||||
google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
|
||||
|
@ -1455,8 +1458,8 @@ google.golang.org/api v0.96.0/go.mod h1:w7wJQLTM+wvQpNf5JyEcBoxK0RH7EDrh/L4qfsuJ
|
|||
google.golang.org/api v0.97.0/go.mod h1:w7wJQLTM+wvQpNf5JyEcBoxK0RH7EDrh/L4qfsuJ13s=
|
||||
google.golang.org/api v0.98.0/go.mod h1:w7wJQLTM+wvQpNf5JyEcBoxK0RH7EDrh/L4qfsuJ13s=
|
||||
google.golang.org/api v0.100.0/go.mod h1:ZE3Z2+ZOr87Rx7dqFsdRQkRBk36kDtp/h+QpHbB7a70=
|
||||
google.golang.org/api v0.153.0 h1:N1AwGhielyKFaUqH07/ZSIQR3uNPcV7NVw0vj+j4iR4=
|
||||
google.golang.org/api v0.153.0/go.mod h1:3qNJX5eOmhiWYc67jRA/3GsDw97UFb5ivv7Y2PrriAY=
|
||||
google.golang.org/api v0.171.0 h1:w174hnBPqut76FzW5Qaupt7zY8Kql6fiVjgys4f58sU=
|
||||
google.golang.org/api v0.171.0/go.mod h1:Hnq5AHm4OTMt2BUVjael2CWZFD6vksJdWCWiUAmjC9o=
|
||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
|
@ -1569,12 +1572,12 @@ google.golang.org/genproto v0.0.0-20221010155953-15ba04fc1c0e/go.mod h1:3526vdqw
|
|||
google.golang.org/genproto v0.0.0-20221014173430-6e2ab493f96b/go.mod h1:1vXfmgAz9N9Jx0QA82PqRVauvCz1SGSz739p0f183jM=
|
||||
google.golang.org/genproto v0.0.0-20221014213838-99cd37c6964a/go.mod h1:1vXfmgAz9N9Jx0QA82PqRVauvCz1SGSz739p0f183jM=
|
||||
google.golang.org/genproto v0.0.0-20221025140454-527a21cfbd71/go.mod h1:9qHF0xnpdSfF6knlcsnpzUu5y+rpwgbvsyGAZPBMg4s=
|
||||
google.golang.org/genproto v0.0.0-20231106174013-bbf56f31fb17 h1:wpZ8pe2x1Q3f2KyT5f8oP/fa9rHAKgFPr/HZdNuS+PQ=
|
||||
google.golang.org/genproto v0.0.0-20231106174013-bbf56f31fb17/go.mod h1:J7XzRzVy1+IPwWHZUzoD0IccYZIrXILAQpc+Qy9CMhY=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20231106174013-bbf56f31fb17 h1:JpwMPBpFN3uKhdaekDpiNlImDdkUAyiJ6ez/uxGaUSo=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20231106174013-bbf56f31fb17/go.mod h1:0xJLfVdJqpAPl8tDg1ujOCGzx6LFLttXT5NhllGOXY4=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20231120223509-83a465c0220f h1:ultW7fxlIvee4HYrtnaRPon9HpEgFk5zYpmfMgtKB5I=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20231120223509-83a465c0220f/go.mod h1:L9KNLi232K1/xB6f7AlSX692koaRnKaWSR0stBki0Yc=
|
||||
google.golang.org/genproto v0.0.0-20240213162025-012b6fc9bca9 h1:9+tzLLstTlPTRyJTh+ah5wIMsBW5c4tQwGTN3thOW9Y=
|
||||
google.golang.org/genproto v0.0.0-20240213162025-012b6fc9bca9/go.mod h1:mqHbVIp48Muh7Ywss/AD6I5kNVKZMmAa/QEW58Gxp2s=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20240311132316-a219d84964c2 h1:rIo7ocm2roD9DcFIX67Ym8icoGCKSARAiPljFhh5suQ=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20240311132316-a219d84964c2/go.mod h1:O1cOfN1Cy6QEYr7VxtjOyP5AdAuR0aJ/MYZaaof623Y=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240314234333-6e1732d8331c h1:lfpJ/2rWPa/kJgxyyXM8PrNnfCzcmxJ265mADgwmvLI=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240314234333-6e1732d8331c/go.mod h1:WtryC6hu0hhx87FDGxWCDptyssuo68sk10vYjF+T9fY=
|
||||
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=
|
||||
|
@ -1611,8 +1614,8 @@ google.golang.org/grpc v1.48.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACu
|
|||
google.golang.org/grpc v1.49.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI=
|
||||
google.golang.org/grpc v1.50.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI=
|
||||
google.golang.org/grpc v1.50.1/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI=
|
||||
google.golang.org/grpc v1.59.0 h1:Z5Iec2pjwb+LEOqzpB2MR12/eKFhDPhuqW91O+4bwUk=
|
||||
google.golang.org/grpc v1.59.0/go.mod h1:aUPDwccQo6OTjy7Hct4AfBPD1GptF4fyUjIkQ9YtF98=
|
||||
google.golang.org/grpc v1.62.1 h1:B4n+nfKzOICUXMgyrNd19h/I9oH0L1pizfk1d4zSgTk=
|
||||
google.golang.org/grpc v1.62.1/go.mod h1:IWTG0VlJLCh1SkC58F7np9ka9mx/WNkjl4PGJaiq+QE=
|
||||
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=
|
||||
|
@ -1687,8 +1690,8 @@ modernc.org/opt v0.1.3 h1:3XOZf2yznlhC+ibLltsDGzABUGVx8J6pnFMS3E4dcq4=
|
|||
modernc.org/opt v0.1.3/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0=
|
||||
modernc.org/sortutil v1.2.0 h1:jQiD3PfS2REGJNzNCMMaLSp/wdMNieTbKX920Cqdgqc=
|
||||
modernc.org/sortutil v1.2.0/go.mod h1:TKU2s7kJMf1AE84OoiGppNHJwvB753OYfNl2WRb++Ss=
|
||||
modernc.org/sqlite v1.32.0 h1:6BM4uGza7bWypsw4fdLRsLxut6bHe4c58VeqjRgST8s=
|
||||
modernc.org/sqlite v1.32.0/go.mod h1:UqoylwmTb9F+IqXERT8bW9zzOWN8qwAIcLdzeBZs4hA=
|
||||
modernc.org/sqlite v1.33.1 h1:trb6Z3YYoeM9eDL1O8do81kP+0ejv+YzgyFo+Gwy0nM=
|
||||
modernc.org/sqlite v1.33.1/go.mod h1:pXV2xHxhzXZsgT/RtTFAPY6JJDEvOTcTdwADQCCWD4k=
|
||||
modernc.org/strutil v1.2.0 h1:agBi9dp1I+eOnxXeiZawM8F4LawKv4NzGWSaLfyeNZA=
|
||||
modernc.org/strutil v1.2.0/go.mod h1:/mdcBmfOibveCTBxUl5B5l6W+TTH1FXPLHZE6bTosX0=
|
||||
modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y=
|
||||
|
|
|
@ -24,8 +24,10 @@ func NewSlice(cpeStrs ...string) ([]cpe.CPE, error) {
|
|||
func MatchWithoutVersion(c cpe.CPE, candidates []cpe.CPE) []cpe.CPE {
|
||||
matches := make([]cpe.CPE, 0)
|
||||
a := wfn.Attributes(c.Attributes)
|
||||
a.Update = wfn.Any
|
||||
for _, candidate := range candidates {
|
||||
canCopy := wfn.Attributes(candidate.Attributes)
|
||||
canCopy.Update = wfn.Any
|
||||
if a.MatchWithoutVersion(&canCopy) {
|
||||
matches = append(matches, candidate)
|
||||
}
|
||||
|
|
|
@ -6,5 +6,5 @@ import "github.com/anchore/grype/grype/pkg"
|
|||
|
||||
// AllTypes returns a list of all pkg metadata types that grype supports (that are represented in the pkg.Package.Metadata field).
|
||||
func AllTypes() []any {
|
||||
return []any{pkg.ApkMetadata{}, pkg.GolangBinMetadata{}, pkg.GolangModMetadata{}, pkg.JavaMetadata{}, pkg.RpmMetadata{}}
|
||||
return []any{pkg.ApkMetadata{}, pkg.GolangBinMetadata{}, pkg.GolangModMetadata{}, pkg.JavaMetadata{}, pkg.JavaVMInstallationMetadata{}, pkg.RpmMetadata{}}
|
||||
}
|
||||
|
|
|
@ -13,11 +13,12 @@ import (
|
|||
// not the same it may be important to select different names. This design decision has been deferred, for now
|
||||
// the same metadata types that have been used in the past should be used here.
|
||||
var jsonNameFromType = map[reflect.Type][]string{
|
||||
reflect.TypeOf(pkg.ApkMetadata{}): nameList("ApkMetadata"),
|
||||
reflect.TypeOf(pkg.GolangBinMetadata{}): nameList("GolangBinMetadata"),
|
||||
reflect.TypeOf(pkg.GolangModMetadata{}): nameList("GolangModMetadata"),
|
||||
reflect.TypeOf(pkg.JavaMetadata{}): nameList("JavaMetadata"),
|
||||
reflect.TypeOf(pkg.RpmMetadata{}): nameList("RpmMetadata"),
|
||||
reflect.TypeOf(pkg.ApkMetadata{}): nameList("ApkMetadata"),
|
||||
reflect.TypeOf(pkg.GolangBinMetadata{}): nameList("GolangBinMetadata"),
|
||||
reflect.TypeOf(pkg.GolangModMetadata{}): nameList("GolangModMetadata"),
|
||||
reflect.TypeOf(pkg.JavaMetadata{}): nameList("JavaMetadata"),
|
||||
reflect.TypeOf(pkg.RpmMetadata{}): nameList("RpmMetadata"),
|
||||
reflect.TypeOf(pkg.JavaVMInstallationMetadata{}): nameList("JavaVMInstallationMetadata"),
|
||||
}
|
||||
|
||||
//nolint:unparam
|
||||
|
|
|
@ -58,6 +58,11 @@ func TestReflectTypeFromJSONName(t *testing.T) {
|
|||
lookup: "RpmMetadata",
|
||||
wantRecord: reflect.TypeOf(pkg.RpmMetadata{}),
|
||||
},
|
||||
{
|
||||
name: "JavaVMInstallationMetadata lookup",
|
||||
lookup: "JavaVMInstallationMetadata",
|
||||
wantRecord: reflect.TypeOf(pkg.JavaVMInstallationMetadata{}),
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
|
|
147
grype/matcher/stock/matcher_test.go
Normal file
147
grype/matcher/stock/matcher_test.go
Normal file
|
@ -0,0 +1,147 @@
|
|||
package stock
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/scylladb/go-set/strset"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/anchore/grype/grype/distro"
|
||||
"github.com/anchore/grype/grype/match"
|
||||
"github.com/anchore/grype/grype/pkg"
|
||||
"github.com/anchore/grype/grype/version"
|
||||
"github.com/anchore/grype/grype/vulnerability"
|
||||
"github.com/anchore/syft/syft/cpe"
|
||||
syftPkg "github.com/anchore/syft/syft/pkg"
|
||||
)
|
||||
|
||||
func TestMatcher_JVMPackage(t *testing.T) {
|
||||
p := pkg.Package{
|
||||
ID: pkg.ID(uuid.NewString()),
|
||||
Name: "java_se",
|
||||
Version: "1.8.0_400",
|
||||
Type: syftPkg.BinaryPkg,
|
||||
CPEs: []cpe.CPE{
|
||||
cpe.Must("cpe:2.3:a:oracle:java_se:1.8.0:update400:*:*:*:*:*:*", cpe.DeclaredSource),
|
||||
},
|
||||
}
|
||||
matcher := Matcher{
|
||||
cfg: MatcherConfig{
|
||||
UseCPEs: true,
|
||||
},
|
||||
}
|
||||
store := newMockProvider()
|
||||
actual, err := matcher.Match(store, nil, p)
|
||||
require.NoError(t, err)
|
||||
|
||||
foundCVEs := strset.New()
|
||||
for _, v := range actual {
|
||||
foundCVEs.Add(v.Vulnerability.ID)
|
||||
|
||||
require.NotEmpty(t, v.Details)
|
||||
for _, d := range v.Details {
|
||||
assert.Equal(t, match.CPEMatch, d.Type, "indirect match not indicated")
|
||||
assert.Equal(t, matcher.Type(), d.Matcher, "failed to capture matcher type")
|
||||
}
|
||||
assert.Equal(t, p.Name, v.Package.Name, "failed to capture original package name")
|
||||
}
|
||||
|
||||
expected := strset.New(
|
||||
"CVE-2024-20919-real",
|
||||
"CVE-2024-20919-bonkers-format",
|
||||
"CVE-2024-20919-post-jep223",
|
||||
)
|
||||
|
||||
for _, id := range expected.List() {
|
||||
if !foundCVEs.Has(id) {
|
||||
t.Errorf("missing CVE: %s", id)
|
||||
}
|
||||
}
|
||||
|
||||
extra := strset.Difference(foundCVEs, expected)
|
||||
|
||||
for _, id := range extra.List() {
|
||||
t.Errorf("unexpected CVE: %s", id)
|
||||
}
|
||||
|
||||
if t.Failed() {
|
||||
t.Logf("discovered CVES: %d", foundCVEs.Size())
|
||||
for _, id := range foundCVEs.List() {
|
||||
t.Logf(" - %s", id)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func newMockProvider() *mockProvider {
|
||||
mp := mockProvider{
|
||||
data: make(map[syftPkg.Language]map[string][]vulnerability.Vulnerability),
|
||||
}
|
||||
|
||||
mp.populateData()
|
||||
|
||||
return &mp
|
||||
}
|
||||
|
||||
type mockProvider struct {
|
||||
data map[syftPkg.Language]map[string][]vulnerability.Vulnerability
|
||||
}
|
||||
|
||||
func (mp *mockProvider) Get(_, _ string) ([]vulnerability.Vulnerability, error) {
|
||||
// TODO implement me
|
||||
panic("not implemented")
|
||||
}
|
||||
|
||||
func (mp *mockProvider) populateData() {
|
||||
|
||||
// derived from vuln data found on CVE-2024-20919
|
||||
hit := "< 1.8.0_401 || >= 1.9-ea, < 8.0.401 || >= 9-ea, < 11.0.22 || >= 12-ea, < 17.0.10 || >= 18-ea, < 21.0.2"
|
||||
|
||||
mp.data["nvd:cpe"] = map[string][]vulnerability.Vulnerability{
|
||||
"java_se": {
|
||||
{
|
||||
// positive cases
|
||||
Constraint: version.MustGetConstraint(hit, version.JVMFormat),
|
||||
ID: "CVE-2024-20919-real",
|
||||
},
|
||||
{
|
||||
// positive cases
|
||||
Constraint: version.MustGetConstraint("< 22.22.22", version.UnknownFormat),
|
||||
ID: "CVE-2024-20919-bonkers-format",
|
||||
},
|
||||
{
|
||||
// negative case
|
||||
Constraint: version.MustGetConstraint("< 1.8.0_399 || >= 1.9-ea, < 8.0.399 || >= 9-ea", version.JVMFormat),
|
||||
ID: "CVE-FAKE-bad-update",
|
||||
},
|
||||
{
|
||||
// positive case
|
||||
Constraint: version.MustGetConstraint("< 8.0.401", version.JVMFormat),
|
||||
ID: "CVE-2024-20919-post-jep223",
|
||||
},
|
||||
{
|
||||
// negative case
|
||||
Constraint: version.MustGetConstraint("< 8.0.399", version.JVMFormat),
|
||||
ID: "CVE-FAKE-bad-range-post-jep223",
|
||||
},
|
||||
{
|
||||
// negative case
|
||||
Constraint: version.MustGetConstraint("< 7.0.0", version.JVMFormat),
|
||||
ID: "CVE-FAKE-bad-range-post-jep223",
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (mp *mockProvider) GetByCPE(p cpe.CPE) ([]vulnerability.Vulnerability, error) {
|
||||
return mp.data["nvd:cpe"][p.Attributes.Product], nil
|
||||
}
|
||||
|
||||
func (mp *mockProvider) GetByDistro(d *distro.Distro, p pkg.Package) ([]vulnerability.Vulnerability, error) {
|
||||
return []vulnerability.Vulnerability{}, nil
|
||||
}
|
||||
|
||||
func (mp *mockProvider) GetByLanguage(l syftPkg.Language, p pkg.Package) ([]vulnerability.Vulnerability, error) {
|
||||
return mp.data[l][p.Name], nil
|
||||
}
|
|
@ -1,5 +1,11 @@
|
|||
package pkg
|
||||
|
||||
import (
|
||||
"github.com/scylladb/go-set/strset"
|
||||
|
||||
"github.com/anchore/syft/syft/pkg"
|
||||
)
|
||||
|
||||
type JavaMetadata struct {
|
||||
VirtualPath string `json:"virtualPath"`
|
||||
PomArtifactID string `json:"pomArtifactID"`
|
||||
|
@ -12,3 +18,34 @@ type Digest struct {
|
|||
Algorithm string `json:"algorithm"`
|
||||
Value string `json:"value"`
|
||||
}
|
||||
|
||||
type JavaVMInstallationMetadata struct {
|
||||
Release JavaVMReleaseMetadata `json:"release,omitempty"`
|
||||
}
|
||||
|
||||
type JavaVMReleaseMetadata struct {
|
||||
JavaRuntimeVersion string `json:"javaRuntimeVersion,omitempty"`
|
||||
JavaVersion string `json:"javaVersion,omitempty"`
|
||||
FullVersion string `json:"fullVersion,omitempty"`
|
||||
SemanticVersion string `json:"semanticVersion,omitempty"`
|
||||
}
|
||||
|
||||
func IsJvmPackage(p Package) bool {
|
||||
if _, ok := p.Metadata.(JavaVMInstallationMetadata); ok {
|
||||
return true
|
||||
}
|
||||
|
||||
if p.Type == pkg.BinaryPkg {
|
||||
if HasJvmPackageName(p.Name) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
var jvmIndications = strset.New("java_se", "jre", "jdk", "zulu", "openjdk", "java", "java/jre", "java/jdk")
|
||||
|
||||
func HasJvmPackageName(name string) bool {
|
||||
return jvmIndications.Has(name)
|
||||
}
|
||||
|
|
115
grype/pkg/java_metadata_test.go
Normal file
115
grype/pkg/java_metadata_test.go
Normal file
|
@ -0,0 +1,115 @@
|
|||
package pkg
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
syftPkg "github.com/anchore/syft/syft/pkg"
|
||||
)
|
||||
|
||||
func TestIsJvmPackage(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
pkg Package
|
||||
expected bool
|
||||
}{
|
||||
{
|
||||
name: "binary package with jdk in name set",
|
||||
pkg: Package{
|
||||
Type: syftPkg.BinaryPkg,
|
||||
Name: "jdk",
|
||||
},
|
||||
expected: true,
|
||||
},
|
||||
{
|
||||
name: "binary package with jre in name set",
|
||||
pkg: Package{
|
||||
Type: syftPkg.BinaryPkg,
|
||||
Name: "jre",
|
||||
},
|
||||
expected: true,
|
||||
},
|
||||
{
|
||||
name: "binary package with java_se in name set",
|
||||
pkg: Package{
|
||||
Type: syftPkg.BinaryPkg,
|
||||
Name: "java_se",
|
||||
},
|
||||
expected: true,
|
||||
},
|
||||
{
|
||||
name: "binary package with zulu in name set",
|
||||
pkg: Package{
|
||||
Type: syftPkg.BinaryPkg,
|
||||
Name: "zulu",
|
||||
},
|
||||
expected: true,
|
||||
},
|
||||
{
|
||||
name: "binary package with openjdk in name set",
|
||||
pkg: Package{
|
||||
Type: syftPkg.BinaryPkg,
|
||||
Name: "openjdk",
|
||||
},
|
||||
expected: true,
|
||||
},
|
||||
{
|
||||
name: "binary package from syft (java/jdk",
|
||||
pkg: Package{
|
||||
Type: syftPkg.BinaryPkg,
|
||||
Name: "java/jre",
|
||||
},
|
||||
expected: true,
|
||||
},
|
||||
{
|
||||
name: "binary package from syft (java/jre)",
|
||||
pkg: Package{
|
||||
Type: syftPkg.BinaryPkg,
|
||||
Name: "java/jdk",
|
||||
},
|
||||
expected: true,
|
||||
},
|
||||
{
|
||||
name: "binary package without jvm-related name",
|
||||
pkg: Package{
|
||||
Type: syftPkg.BinaryPkg,
|
||||
Name: "nodejs",
|
||||
},
|
||||
expected: false,
|
||||
},
|
||||
{
|
||||
name: "non-binary package with jvm-related name",
|
||||
pkg: Package{
|
||||
Type: syftPkg.NpmPkg, // we know this could not be a JVM package installation
|
||||
Name: "jdk",
|
||||
},
|
||||
expected: false,
|
||||
},
|
||||
{
|
||||
name: "package with JavaVMInstallationMetadata",
|
||||
pkg: Package{
|
||||
Type: syftPkg.RpmPkg,
|
||||
Name: "random-package",
|
||||
Metadata: JavaVMInstallationMetadata{},
|
||||
},
|
||||
expected: true,
|
||||
},
|
||||
{
|
||||
name: "package without JavaVMInstallationMetadata",
|
||||
pkg: Package{
|
||||
Type: syftPkg.RpmPkg,
|
||||
Name: "non-jvm-package",
|
||||
Metadata: nil,
|
||||
},
|
||||
expected: false,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
result := IsJvmPackage(tt.pkg)
|
||||
assert.Equal(t, tt.expected, result)
|
||||
})
|
||||
}
|
||||
}
|
|
@ -214,10 +214,27 @@ func dataFromPkg(p pkg.Package) (interface{}, []UpstreamPackage) {
|
|||
case pkg.ApkDBEntry:
|
||||
metadata = apkMetadataFromPkg(p)
|
||||
upstreams = apkDataFromPkg(p)
|
||||
case pkg.JavaVMInstallation:
|
||||
metadata = javaVMDataFromPkg(p)
|
||||
}
|
||||
return metadata, upstreams
|
||||
}
|
||||
|
||||
func javaVMDataFromPkg(p pkg.Package) any {
|
||||
if value, ok := p.Metadata.(pkg.JavaVMInstallation); ok {
|
||||
return JavaVMInstallationMetadata{
|
||||
Release: JavaVMReleaseMetadata{
|
||||
JavaRuntimeVersion: value.Release.JavaRuntimeVersion,
|
||||
JavaVersion: value.Release.JavaVersion,
|
||||
FullVersion: value.Release.FullVersion,
|
||||
SemanticVersion: value.Release.SemanticVersion,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func apkMetadataFromPkg(p pkg.Package) interface{} {
|
||||
if m, ok := p.Metadata.(pkg.ApkDBEntry); ok {
|
||||
metadata := ApkMetadata{}
|
||||
|
|
|
@ -692,6 +692,45 @@ func TestNew(t *testing.T) {
|
|||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "jvm-installation-entry",
|
||||
syftPkg: syftPkg.Package{
|
||||
Metadata: syftPkg.JavaVMInstallation{
|
||||
Release: syftPkg.JavaVMRelease{
|
||||
Implementor: "a",
|
||||
ImplementorVersion: "a",
|
||||
JavaRuntimeVersion: "b",
|
||||
JavaVersion: "c",
|
||||
JavaVersionDate: "a",
|
||||
Libc: "a",
|
||||
Modules: []string{"a"},
|
||||
OsArch: "a",
|
||||
OsName: "a",
|
||||
OsVersion: "a",
|
||||
Source: "a",
|
||||
BuildSource: "a",
|
||||
BuildSourceRepo: "a",
|
||||
SourceRepo: "a",
|
||||
FullVersion: "d",
|
||||
SemanticVersion: "e",
|
||||
BuildInfo: "a",
|
||||
JvmVariant: "a",
|
||||
JvmVersion: "a",
|
||||
ImageType: "a",
|
||||
BuildType: "a",
|
||||
},
|
||||
Files: []string{"a"},
|
||||
},
|
||||
},
|
||||
metadata: JavaVMInstallationMetadata{
|
||||
Release: JavaVMReleaseMetadata{
|
||||
JavaRuntimeVersion: "b",
|
||||
JavaVersion: "c",
|
||||
FullVersion: "d",
|
||||
SemanticVersion: "e",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
// capture each observed metadata type, we should see all of them relate to what syft provides by the end of testing
|
||||
|
|
|
@ -105,7 +105,14 @@ func ByPackageCPE(store vulnerability.ProviderByCPE, d *distro.Distro, p pkg.Pac
|
|||
if searchVersion == wfn.NA || searchVersion == wfn.Any {
|
||||
searchVersion = p.Version
|
||||
}
|
||||
verObj, err := version.NewVersion(searchVersion, version.FormatFromPkgType(p.Type))
|
||||
|
||||
format := version.FormatFromPkg(p)
|
||||
|
||||
if format == version.JVMFormat {
|
||||
searchVersion = transformJvmVersion(searchVersion, c.Attributes.Update)
|
||||
}
|
||||
|
||||
verObj, err := version.NewVersion(searchVersion, format)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("matcher failed to parse version pkg=%q ver=%q: %w", p.Name, p.Version, err)
|
||||
}
|
||||
|
@ -140,6 +147,14 @@ func ByPackageCPE(store vulnerability.ProviderByCPE, d *distro.Distro, p pkg.Pac
|
|||
return toMatches(matchesByFingerprint), nil
|
||||
}
|
||||
|
||||
func transformJvmVersion(searchVersion, updateCpeField string) string {
|
||||
// we should take into consideration the CPE update field for JVM packages
|
||||
if strings.HasPrefix(searchVersion, "1.") && !strings.Contains(searchVersion, "_") && updateCpeField != wfn.NA && updateCpeField != wfn.Any {
|
||||
searchVersion = fmt.Sprintf("%s_%s", searchVersion, strings.TrimPrefix(updateCpeField, "update"))
|
||||
}
|
||||
return searchVersion
|
||||
}
|
||||
|
||||
func addNewMatch(matchesByFingerprint map[match.Fingerprint]match.Match, vuln vulnerability.Vulnerability, p pkg.Package, searchVersion version.Version, upstreamMatcher match.MatcherType, searchedByCPE cpe.CPE) {
|
||||
candidateMatch := match.Match{
|
||||
|
||||
|
@ -223,7 +238,15 @@ func filterCPEsByVersion(pkgVersion version.Version, allCPEs []cpe.CPE) (matched
|
|||
continue
|
||||
}
|
||||
|
||||
constraint, err := version.GetConstraint(c.Attributes.Version, version.UnknownFormat)
|
||||
ver := c.Attributes.Version
|
||||
|
||||
if pkgVersion.Format == version.JVMFormat {
|
||||
if c.Attributes.Update != wfn.Any && c.Attributes.Update != wfn.NA {
|
||||
ver = transformJvmVersion(ver, c.Attributes.Update)
|
||||
}
|
||||
}
|
||||
|
||||
constraint, err := version.GetConstraint(ver, pkgVersion.Format)
|
||||
if err != nil {
|
||||
// if we can't get a version constraint, don't filter out the CPE
|
||||
matchedCPEs = append(matchedCPEs, c)
|
||||
|
|
|
@ -29,6 +29,8 @@ func GetConstraint(constStr string, format Format) (Constraint, error) {
|
|||
return newKBConstraint(constStr)
|
||||
case PortageFormat:
|
||||
return newPortageConstraint(constStr)
|
||||
case JVMFormat:
|
||||
return newJvmConstraint(constStr)
|
||||
case UnknownFormat:
|
||||
return newFuzzyConstraint(constStr, "unknown")
|
||||
}
|
||||
|
|
|
@ -3,7 +3,8 @@ package version
|
|||
import (
|
||||
"strings"
|
||||
|
||||
"github.com/anchore/syft/syft/pkg"
|
||||
"github.com/anchore/grype/grype/pkg"
|
||||
syftPkg "github.com/anchore/syft/syft/pkg"
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -18,12 +19,13 @@ const (
|
|||
GemFormat
|
||||
PortageFormat
|
||||
GolangFormat
|
||||
JVMFormat
|
||||
)
|
||||
|
||||
type Format int
|
||||
|
||||
var formatStr = []string{
|
||||
"UnknownFormat",
|
||||
"Unknown",
|
||||
"Semantic",
|
||||
"Apk",
|
||||
"Deb",
|
||||
|
@ -34,6 +36,7 @@ var formatStr = []string{
|
|||
"Gem",
|
||||
"Portage",
|
||||
"Go",
|
||||
"JVM",
|
||||
}
|
||||
|
||||
var Formats = []Format{
|
||||
|
@ -46,6 +49,8 @@ var Formats = []Format{
|
|||
KBFormat,
|
||||
GemFormat,
|
||||
PortageFormat,
|
||||
GolangFormat,
|
||||
JVMFormat,
|
||||
}
|
||||
|
||||
func ParseFormat(userStr string) Format {
|
||||
|
@ -70,35 +75,39 @@ func ParseFormat(userStr string) Format {
|
|||
return GemFormat
|
||||
case strings.ToLower(PortageFormat.String()), "portage":
|
||||
return PortageFormat
|
||||
case strings.ToLower(JVMFormat.String()), "jvm", "jre", "jdk", "openjdk", "jep223":
|
||||
return JVMFormat
|
||||
}
|
||||
return UnknownFormat
|
||||
}
|
||||
|
||||
func FormatFromPkgType(t pkg.Type) Format {
|
||||
var format Format
|
||||
switch t {
|
||||
case pkg.ApkPkg:
|
||||
format = ApkFormat
|
||||
case pkg.DebPkg:
|
||||
format = DebFormat
|
||||
case pkg.JavaPkg:
|
||||
format = MavenFormat
|
||||
case pkg.RpmPkg:
|
||||
format = RpmFormat
|
||||
case pkg.GemPkg:
|
||||
format = GemFormat
|
||||
case pkg.PythonPkg:
|
||||
format = PythonFormat
|
||||
case pkg.KbPkg:
|
||||
format = KBFormat
|
||||
case pkg.PortagePkg:
|
||||
format = PortageFormat
|
||||
case pkg.GoModulePkg:
|
||||
format = GolangFormat
|
||||
default:
|
||||
format = UnknownFormat
|
||||
func FormatFromPkg(p pkg.Package) Format {
|
||||
switch p.Type {
|
||||
case syftPkg.ApkPkg:
|
||||
return ApkFormat
|
||||
case syftPkg.DebPkg:
|
||||
return DebFormat
|
||||
case syftPkg.JavaPkg:
|
||||
return MavenFormat
|
||||
case syftPkg.RpmPkg:
|
||||
return RpmFormat
|
||||
case syftPkg.GemPkg:
|
||||
return GemFormat
|
||||
case syftPkg.PythonPkg:
|
||||
return PythonFormat
|
||||
case syftPkg.KbPkg:
|
||||
return KBFormat
|
||||
case syftPkg.PortagePkg:
|
||||
return PortageFormat
|
||||
case syftPkg.GoModulePkg:
|
||||
return GolangFormat
|
||||
}
|
||||
return format
|
||||
|
||||
if pkg.IsJvmPackage(p) {
|
||||
return JVMFormat
|
||||
}
|
||||
|
||||
return UnknownFormat
|
||||
}
|
||||
|
||||
func (f Format) String() string {
|
||||
|
|
|
@ -4,7 +4,8 @@ import (
|
|||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/anchore/syft/syft/pkg"
|
||||
"github.com/anchore/grype/grype/pkg"
|
||||
syftPkg "github.com/anchore/syft/syft/pkg"
|
||||
)
|
||||
|
||||
func TestParseFormat(t *testing.T) {
|
||||
|
@ -51,29 +52,78 @@ func TestParseFormat(t *testing.T) {
|
|||
|
||||
func TestFormatFromPkgType(t *testing.T) {
|
||||
tests := []struct {
|
||||
pkgType pkg.Type
|
||||
format Format
|
||||
name string
|
||||
p pkg.Package
|
||||
format Format
|
||||
}{
|
||||
{
|
||||
pkgType: pkg.DebPkg,
|
||||
format: DebFormat,
|
||||
name: "deb",
|
||||
p: pkg.Package{
|
||||
Type: syftPkg.DebPkg,
|
||||
},
|
||||
format: DebFormat,
|
||||
},
|
||||
{
|
||||
pkgType: pkg.JavaPkg,
|
||||
format: MavenFormat,
|
||||
name: "java jar",
|
||||
p: pkg.Package{
|
||||
Type: syftPkg.JavaPkg,
|
||||
},
|
||||
format: MavenFormat,
|
||||
},
|
||||
{
|
||||
pkgType: pkg.GemPkg,
|
||||
format: GemFormat,
|
||||
name: "gem",
|
||||
p: pkg.Package{
|
||||
Type: syftPkg.GemPkg,
|
||||
},
|
||||
format: GemFormat,
|
||||
},
|
||||
{
|
||||
name: "jvm by metadata",
|
||||
p: pkg.Package{
|
||||
Metadata: pkg.JavaVMInstallationMetadata{},
|
||||
},
|
||||
format: JVMFormat,
|
||||
},
|
||||
{
|
||||
name: "jvm by type and name (jdk)",
|
||||
p: pkg.Package{
|
||||
Type: syftPkg.BinaryPkg,
|
||||
Name: "jdk",
|
||||
},
|
||||
format: JVMFormat,
|
||||
},
|
||||
{
|
||||
name: "jvm by type and name (openjdk)",
|
||||
p: pkg.Package{
|
||||
Type: syftPkg.BinaryPkg,
|
||||
Name: "openjdk",
|
||||
},
|
||||
format: JVMFormat,
|
||||
},
|
||||
{
|
||||
name: "jvm by type and name (jre)",
|
||||
p: pkg.Package{
|
||||
Type: syftPkg.BinaryPkg,
|
||||
Name: "jre",
|
||||
},
|
||||
format: JVMFormat,
|
||||
},
|
||||
{
|
||||
name: "jvm by type and name (java_se)",
|
||||
p: pkg.Package{
|
||||
Type: syftPkg.BinaryPkg,
|
||||
Name: "java_se",
|
||||
},
|
||||
format: JVMFormat,
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
name := fmt.Sprintf("pkgType[%s]->format[%s]", test.pkgType, test.format)
|
||||
name := fmt.Sprintf("pkgType[%s]->format[%s]", test.p.Type, test.format)
|
||||
t.Run(name, func(t *testing.T) {
|
||||
actual := FormatFromPkgType(test.pkgType)
|
||||
actual := FormatFromPkg(test.p)
|
||||
if actual != test.format {
|
||||
t.Errorf("mismatched pkgType->format mapping, pkgType='%s': '%s'!='%s'", test.pkgType, test.format, actual)
|
||||
t.Errorf("mismatched pkgType->format mapping, pkgType='%s': '%s'!='%s'", test.p.Type, test.format, actual)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
38
grype/version/generic_constraint.go
Normal file
38
grype/version/generic_constraint.go
Normal file
|
@ -0,0 +1,38 @@
|
|||
package version
|
||||
|
||||
import "fmt"
|
||||
|
||||
var _ Constraint = (*genericConstraint)(nil)
|
||||
|
||||
type genericConstraint struct {
|
||||
raw string
|
||||
expression constraintExpression
|
||||
name string
|
||||
}
|
||||
|
||||
func newGenericConstraint(raw string, genFn comparatorGenerator, name string) (genericConstraint, error) {
|
||||
constraints, err := newConstraintExpression(raw, genFn)
|
||||
if err != nil {
|
||||
return genericConstraint{}, err
|
||||
}
|
||||
return genericConstraint{
|
||||
expression: constraints,
|
||||
raw: raw,
|
||||
name: name,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (g genericConstraint) String() string {
|
||||
value := "none"
|
||||
if g.raw != "" {
|
||||
value = g.raw
|
||||
}
|
||||
return fmt.Sprintf("%s (%s)", value, g.name)
|
||||
}
|
||||
|
||||
func (g genericConstraint) Satisfied(version *Version) (bool, error) {
|
||||
if g.raw == "" {
|
||||
return true, nil // the empty constraint is always satisfied
|
||||
}
|
||||
return g.expression.satisfied(version)
|
||||
}
|
|
@ -2,42 +2,14 @@ package version
|
|||
|
||||
import "fmt"
|
||||
|
||||
var _ Constraint = (*golangConstraint)(nil)
|
||||
|
||||
type golangConstraint struct {
|
||||
raw string
|
||||
expression constraintExpression
|
||||
}
|
||||
|
||||
func newGolangConstraint(raw string) (golangConstraint, error) {
|
||||
constraints, err := newConstraintExpression(raw, newGolangComparator)
|
||||
if err != nil {
|
||||
return golangConstraint{}, err
|
||||
}
|
||||
return golangConstraint{
|
||||
expression: constraints,
|
||||
raw: raw,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (g golangConstraint) String() string {
|
||||
if g.raw == "" {
|
||||
return "none (go)"
|
||||
}
|
||||
return fmt.Sprintf("%s (go)", g.raw)
|
||||
}
|
||||
|
||||
func (g golangConstraint) Satisfied(version *Version) (bool, error) {
|
||||
if g.raw == "" {
|
||||
return true, nil // the empty constraint is always satisfied
|
||||
}
|
||||
return g.expression.satisfied(version)
|
||||
func newGolangConstraint(raw string) (Constraint, error) {
|
||||
return newGenericConstraint(raw, newGolangComparator, "go")
|
||||
}
|
||||
|
||||
func newGolangComparator(unit constraintUnit) (Comparator, error) {
|
||||
ver, err := newGolangVersion(unit.version)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unable to parse constraint version (%s): %w", unit.version, err)
|
||||
return nil, fmt.Errorf("unable to parse Golang constraint version (%s): %w", unit.version, err)
|
||||
}
|
||||
return ver, nil
|
||||
}
|
||||
|
|
15
grype/version/jvm_constraint.go
Normal file
15
grype/version/jvm_constraint.go
Normal file
|
@ -0,0 +1,15 @@
|
|||
package version
|
||||
|
||||
import "fmt"
|
||||
|
||||
func newJvmConstraint(raw string) (Constraint, error) {
|
||||
return newGenericConstraint(raw, newJvmComparator, "jvm")
|
||||
}
|
||||
|
||||
func newJvmComparator(unit constraintUnit) (Comparator, error) {
|
||||
ver, err := newJvmVersion(unit.version)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unable to parse JVM constraint version (%s): %w", unit.version, err)
|
||||
}
|
||||
return ver, nil
|
||||
}
|
70
grype/version/jvm_constraint_test.go
Normal file
70
grype/version/jvm_constraint_test.go
Normal file
|
@ -0,0 +1,70 @@
|
|||
package version
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestVersionConstraintJVM(t *testing.T) {
|
||||
tests := []testCase{
|
||||
// pre jep 223 versions
|
||||
{version: "1.7.0_80", constraint: "< 1.8.0", satisfied: true},
|
||||
{version: "1.8.0_131", constraint: "> 1.8.0", satisfied: true},
|
||||
{version: "1.8.0_131", constraint: "< 1.8.0_132", satisfied: true},
|
||||
{version: "1.8.0_131-b11", constraint: "< 1.8.0_132", satisfied: true},
|
||||
|
||||
{version: "1.7.0_80", constraint: "> 1.8.0", satisfied: false},
|
||||
{version: "1.8.0_131", constraint: "< 1.8.0", satisfied: false},
|
||||
{version: "1.8.0_131", constraint: "> 1.8.0_132", satisfied: false},
|
||||
{version: "1.8.0_131-b11", constraint: "> 1.8.0_132", satisfied: false},
|
||||
|
||||
{version: "1.7.0_80", constraint: "= 1.8.0", satisfied: false},
|
||||
{version: "1.8.0_131", constraint: "= 1.8.0", satisfied: false},
|
||||
{version: "1.8.0_131", constraint: "= 1.8.0_132", satisfied: false},
|
||||
{version: "1.8.0_131-b11", constraint: "= 1.8.0_132", satisfied: false},
|
||||
|
||||
{version: "1.8.0_80", constraint: "= 1.8.0_80", satisfied: true},
|
||||
{version: "1.8.0_131", constraint: ">= 1.8.0_131", satisfied: true},
|
||||
{version: "1.8.0_131", constraint: "= 1.8.0_131-b001", satisfied: true}, // builds should not matter
|
||||
{version: "1.8.0_131-ea-b11", constraint: "= 1.8.0_131-ea", satisfied: true},
|
||||
|
||||
// jep 223 versions
|
||||
{version: "8.0.4", constraint: "> 8.0.3", satisfied: true},
|
||||
{version: "8.0.4", constraint: "< 8.0.5", satisfied: true},
|
||||
{version: "9.0.0", constraint: "> 8.0.5", satisfied: true},
|
||||
{version: "9.0.0", constraint: "< 9.1.0", satisfied: true},
|
||||
{version: "11.0.4", constraint: "<= 11.0.4", satisfied: true},
|
||||
{version: "11.0.5", constraint: "> 11.0.4", satisfied: true},
|
||||
|
||||
{version: "8.0.4", constraint: "< 8.0.3", satisfied: false},
|
||||
{version: "8.0.4", constraint: "> 8.0.5", satisfied: false},
|
||||
{version: "9.0.0", constraint: "< 8.0.5", satisfied: false},
|
||||
{version: "9.0.0", constraint: "> 9.1.0", satisfied: false},
|
||||
{version: "11.0.4", constraint: "> 11.0.4", satisfied: false},
|
||||
{version: "11.0.5", constraint: "< 11.0.4", satisfied: false},
|
||||
|
||||
// mixed versions
|
||||
{version: "1.8.0_131", constraint: "< 9.0.0", satisfied: true}, // 1.8.0_131 -> 8.0.131
|
||||
{version: "9.0.0", constraint: "> 1.8.0_131", satisfied: true}, // 1.8.0_131 -> 8.0.131
|
||||
{version: "1.8.0_131", constraint: "<= 8.0.131", satisfied: true},
|
||||
{version: "1.8.0_131", constraint: "> 7.0.79", satisfied: true},
|
||||
{version: "1.8.0_131", constraint: "= 8.0.131", satisfied: true},
|
||||
{version: "1.8.0_131", constraint: ">= 9.0.0", satisfied: false},
|
||||
{version: "9.0.1", constraint: "< 8.0.131", satisfied: false},
|
||||
|
||||
// pre-release versions
|
||||
{version: "1.8.0_131-ea", constraint: "< 1.8.0_131", satisfied: true},
|
||||
{version: "1.8.0_131", constraint: "> 1.8.0_131-ea", satisfied: true},
|
||||
{version: "9.0.0-ea", constraint: "< 9.0.0", satisfied: true},
|
||||
{version: "9.0.0-ea", constraint: "> 1.8.0_131", satisfied: true},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run(test.version+"_constraint_"+test.constraint, func(t *testing.T) {
|
||||
constraint, err := newJvmConstraint(test.constraint)
|
||||
require.NoError(t, err)
|
||||
test.assertVersionConstraint(t, JVMFormat, constraint)
|
||||
})
|
||||
}
|
||||
}
|
151
grype/version/jvm_version.go
Normal file
151
grype/version/jvm_version.go
Normal file
|
@ -0,0 +1,151 @@
|
|||
package version
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
hashiVer "github.com/anchore/go-version"
|
||||
"github.com/anchore/grype/internal"
|
||||
"github.com/anchore/grype/internal/log"
|
||||
)
|
||||
|
||||
var _ Comparator = (*jvmVersion)(nil)
|
||||
|
||||
var (
|
||||
preJep223VersionPattern = regexp.MustCompile(`^1\.(?P<major>\d+)(\.(?P<minor>\d+)([_-](update)?(_)?(?P<patch>\d+))?(-(?P<prerelease>[^b][^-]+))?(-b(?P<build>\d+))?)?`)
|
||||
nonCompliantSemverIsh = regexp.MustCompile(`^(?P<major>\d+)(\.(?P<minor>\d+)(\.(?P<patch>\d+))?([_-](update)?(_)?(?P<update>\d+))?(-(?P<prerelease>[^b][^-]+))?(-b(?P<build>\d+))?)?`)
|
||||
)
|
||||
|
||||
type jvmVersion struct {
|
||||
isPreJep223 bool
|
||||
semVer *hashiVer.Version
|
||||
}
|
||||
|
||||
func newJvmVersion(raw string) (*jvmVersion, error) {
|
||||
isPreJep233 := strings.HasPrefix(raw, "1.")
|
||||
|
||||
if isPreJep233 {
|
||||
// convert the pre-JEP 223 version to semver
|
||||
raw = convertPreJep223Version(raw)
|
||||
} else {
|
||||
raw = convertNonCompliantSemver(raw)
|
||||
}
|
||||
verObj, err := hashiVer.NewVersion(raw)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unable to create semver obj for JVM version: %w", err)
|
||||
}
|
||||
|
||||
return &jvmVersion{
|
||||
isPreJep223: isPreJep233,
|
||||
semVer: verObj,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (v *jvmVersion) Compare(other *Version) (int, error) {
|
||||
if other.Format == JVMFormat {
|
||||
if other.rich.jvmVersion == nil {
|
||||
return -1, fmt.Errorf("given empty jvmVersion object")
|
||||
}
|
||||
return other.rich.jvmVersion.compare(*v), nil
|
||||
}
|
||||
|
||||
if other.Format == SemanticFormat {
|
||||
if other.rich.semVer == nil {
|
||||
return -1, fmt.Errorf("given empty semVer object")
|
||||
}
|
||||
return other.rich.semVer.verObj.Compare(v.semVer), nil
|
||||
}
|
||||
|
||||
return -1, fmt.Errorf("unable to compare JVM to given format: %s", other.Format)
|
||||
}
|
||||
|
||||
func (v jvmVersion) compare(other jvmVersion) int {
|
||||
return v.semVer.Compare(other.semVer)
|
||||
}
|
||||
|
||||
func convertNonCompliantSemver(version string) string {
|
||||
// if there is -update as a prerelease, and the patch version is missing or 0, then we should parse the prerelease
|
||||
// info that has the update value and extract the version. This should be used as the patch version.
|
||||
|
||||
// 8.0-update302 --> 8.0.302
|
||||
// 8.0-update302-b08 --> 8.0.302+8
|
||||
// 8.0-update_302-b08 --> 8.0.302+8
|
||||
|
||||
matches := internal.MatchNamedCaptureGroups(nonCompliantSemverIsh, version)
|
||||
if len(matches) == 0 {
|
||||
log.WithFields("version", version).Trace("unable to convert pre-JEP 223 JVM version")
|
||||
return version
|
||||
}
|
||||
|
||||
// extract relevant parts from the matches
|
||||
majorVersion := trim0sFromLeft(matches["major"])
|
||||
minorVersion := trim0sFromLeft(matches["minor"])
|
||||
patchVersion := trim0sFromLeft(matches["patch"])
|
||||
update := trim0sFromLeft(matches["update"])
|
||||
preRelease := trim0sFromLeft(matches["prerelease"])
|
||||
build := trim0sFromLeft(matches["build"])
|
||||
|
||||
if (patchVersion == "" || patchVersion == "0") && update != "" {
|
||||
patchVersion = update
|
||||
}
|
||||
|
||||
return buildSemVer(majorVersion, minorVersion, patchVersion, preRelease, build)
|
||||
}
|
||||
|
||||
func convertPreJep223Version(version string) string {
|
||||
// convert the following pre JEP 223 version strings to semvers
|
||||
// 1.8.0_302-b08 --> 8.0.302+8
|
||||
// 1.9.0-ea-b19 --> 9.0.0-ea+19
|
||||
// NOTE: this makes an assumption that the old update field is the patch version in semver...
|
||||
// this is NOT strictly in the spec, but for 1.8 this tends to be true (especially for temurin-based builds)
|
||||
version = strings.TrimSpace(version)
|
||||
|
||||
matches := internal.MatchNamedCaptureGroups(preJep223VersionPattern, version)
|
||||
if len(matches) == 0 {
|
||||
log.WithFields("version", version).Trace("unable to convert pre-JEP 223 JVM version")
|
||||
return version
|
||||
}
|
||||
|
||||
// extract relevant parts from the matches
|
||||
majorVersion := trim0sFromLeft(matches["major"])
|
||||
minorVersion := trim0sFromLeft(matches["minor"])
|
||||
patchVersion := trim0sFromLeft(matches["patch"])
|
||||
preRelease := trim0sFromLeft(matches["prerelease"])
|
||||
build := trim0sFromLeft(matches["build"])
|
||||
|
||||
if patchVersion == "" {
|
||||
patchVersion = "0"
|
||||
}
|
||||
|
||||
return buildSemVer(majorVersion, minorVersion, patchVersion, preRelease, build)
|
||||
}
|
||||
func buildSemVer(majorVersion, minorVersion, patchVersion, preRelease, build string) string {
|
||||
if minorVersion == "" {
|
||||
minorVersion = "0"
|
||||
}
|
||||
|
||||
segs := []string{majorVersion, minorVersion}
|
||||
if patchVersion != "" {
|
||||
segs = append(segs, patchVersion)
|
||||
}
|
||||
|
||||
var semver strings.Builder
|
||||
semver.WriteString(strings.Join(segs, "."))
|
||||
|
||||
if preRelease != "" {
|
||||
semver.WriteString(fmt.Sprintf("-%s", preRelease))
|
||||
}
|
||||
if build != "" {
|
||||
semver.WriteString(fmt.Sprintf("+%s", build))
|
||||
}
|
||||
|
||||
return semver.String()
|
||||
}
|
||||
|
||||
func trim0sFromLeft(v string) string {
|
||||
if v == "0" {
|
||||
return v
|
||||
}
|
||||
return strings.TrimLeft(v, "0")
|
||||
}
|
152
grype/version/jvm_version_test.go
Normal file
152
grype/version/jvm_version_test.go
Normal file
|
@ -0,0 +1,152 @@
|
|||
package version
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestVersionJVM(t *testing.T) {
|
||||
tests := []struct {
|
||||
v1 string
|
||||
v2 string
|
||||
expected int
|
||||
}{
|
||||
// pre jep223 versions
|
||||
{"1.8", "1.8.0", 0},
|
||||
{"1.8.0", "1.8.0_0", 0},
|
||||
{"1.8.0", "1.8.0", 0},
|
||||
{"1.7.0", "1.8.0", -1},
|
||||
{"1.8.0_131", "1.8.0_131", 0},
|
||||
{"1.8.0_131", "1.8.0_132", -1},
|
||||
|
||||
// builds should not matter
|
||||
{"1.8.0_131", "1.8.0_130", 1},
|
||||
{"1.8.0_131", "1.8.0_132-b11", -1},
|
||||
{"1.8.0_131-b11", "1.8.0_132-b11", -1},
|
||||
{"1.8.0_131-b11", "1.8.0_131-b12", 0},
|
||||
{"1.8.0_131-b11", "1.8.0_131-b10", 0},
|
||||
{"1.8.0_131-b11", "1.8.0_131", 0},
|
||||
{"1.8.0_131-b11", "1.8.0_131-b11", 0},
|
||||
|
||||
// jep223 versions (semver)
|
||||
{"8.0.4", "8.0.4", 0},
|
||||
{"8.0.4", "8.0.5", -1},
|
||||
{"8.0.4", "8.0.3", 1},
|
||||
{"8.0.4", "8.0.4+b1", 0},
|
||||
|
||||
// mix comparison
|
||||
{"1.8.0_131", "8.0.4", 1}, // 1.8.0_131 --> 8.0.131
|
||||
{"8.0.4", "1.8.0_131", -1}, // doesn't matter which side the comparison is on
|
||||
{"1.8.0_131-b002", "8.0.131+b2", 0}, // builds should not matter
|
||||
{"1.8.0_131-b002", "8.0.131+b1", 0}, // builds should not matter
|
||||
{"1.6.0", "8.0.1", -1}, // 1.6.0 --> 6.0.0
|
||||
|
||||
// prerelease
|
||||
{"1.8.0_13-ea-b002", "1.8.0_13-ea-b001", 0},
|
||||
{"1.8.0_13-ea", "1.8.0_13-ea-b001", 0},
|
||||
{"1.8.0_13-ea-b002", "8.0.13-ea+b2", 0},
|
||||
{"1.8.0_13-ea-b002", "8.0.13+b2", -1},
|
||||
{"1.8.0_13-b002", "8.0.13-ea+b2", 1},
|
||||
|
||||
// pre 1.8 (when the jep 223 was introduced)
|
||||
{"1.7.0", "7.0.0", 0}, // there is no v7 of the JVM, but we want to honor this comparison since it may be someone mistakenly using the wrong version format
|
||||
|
||||
// invalid but we should work with these
|
||||
{"1.8.0_131", "1.8.0-update131-b02", 0},
|
||||
{"1.8.0_131", "1.8.0-update_131-b02", 0},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
name := test.v1 + "_vs_" + test.v2
|
||||
t.Run(name, func(t *testing.T) {
|
||||
v1, err := newJvmVersion(test.v1)
|
||||
require.NotNil(t, v1)
|
||||
require.NoError(t, err)
|
||||
|
||||
v2, err := newJvmVersion(test.v2)
|
||||
require.NotNil(t, v2)
|
||||
require.NoError(t, err)
|
||||
|
||||
actual := v1.compare(*v2)
|
||||
assert.Equal(t, test.expected, actual)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestConvertNonCompliantSemver(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
input string
|
||||
expected string
|
||||
}{
|
||||
{
|
||||
name: "simple update",
|
||||
input: "8.0-update302",
|
||||
expected: "8.0.302",
|
||||
},
|
||||
{
|
||||
name: "update with build",
|
||||
input: "8.0-update302-b08",
|
||||
expected: "8.0.302+8",
|
||||
},
|
||||
{
|
||||
name: "update with underscore and build",
|
||||
input: "8.0-update_302-b08",
|
||||
expected: "8.0.302+8",
|
||||
},
|
||||
{
|
||||
name: "version without patch and prerelease",
|
||||
input: "8.0.0",
|
||||
expected: "8.0.0",
|
||||
},
|
||||
{
|
||||
name: "version with patch, no update",
|
||||
input: "8.0.100",
|
||||
expected: "8.0.100",
|
||||
},
|
||||
{
|
||||
name: "version with patch and prerelease",
|
||||
input: "8.0.0-rc1",
|
||||
expected: "8.0.0-rc1",
|
||||
},
|
||||
{
|
||||
name: "invalid update format, no update keyword",
|
||||
input: "8.0-foo302",
|
||||
expected: "8.0-foo302",
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
result := convertNonCompliantSemver(tt.input)
|
||||
assert.Equal(t, tt.expected, result)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestVersionJVM_invalid(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
version string
|
||||
wantErr require.ErrorAssertionFunc
|
||||
}{
|
||||
{
|
||||
name: "invalid version",
|
||||
version: "1.a",
|
||||
wantErr: require.Error,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if tt.wantErr == nil {
|
||||
tt.wantErr = require.NoError
|
||||
}
|
||||
v, err := newJvmVersion(tt.version)
|
||||
assert.Nil(t, v)
|
||||
tt.wantErr(t, err)
|
||||
})
|
||||
}
|
||||
}
|
|
@ -28,6 +28,7 @@ type rich struct {
|
|||
kbVer *kbVersion
|
||||
portVer *portageVersion
|
||||
pep440version *pep440Version
|
||||
jvmVersion *jvmVersion
|
||||
}
|
||||
|
||||
func NewVersion(raw string, format Format) (*Version, error) {
|
||||
|
@ -45,7 +46,9 @@ func NewVersion(raw string, format Format) (*Version, error) {
|
|||
}
|
||||
|
||||
func NewVersionFromPkg(p pkg.Package) (*Version, error) {
|
||||
ver, err := NewVersion(p.Version, FormatFromPkgType(p.Type))
|
||||
format := FormatFromPkg(p)
|
||||
|
||||
ver, err := NewVersion(p.Version, format)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -96,6 +99,10 @@ func (v *Version) populate() error {
|
|||
ver := newPortageVersion(v.Raw)
|
||||
v.rich.portVer = &ver
|
||||
return nil
|
||||
case JVMFormat:
|
||||
ver, err := newJvmVersion(v.Raw)
|
||||
v.rich.jvmVersion = ver
|
||||
return err
|
||||
case UnknownFormat:
|
||||
// use the raw string + fuzzy constraint
|
||||
return nil
|
||||
|
|
45
internal/regex_helpers.go
Normal file
45
internal/regex_helpers.go
Normal file
|
@ -0,0 +1,45 @@
|
|||
package internal
|
||||
|
||||
import "regexp"
|
||||
|
||||
// MatchNamedCaptureGroups takes a regular expression and string and returns all of the named capture group results in a map.
|
||||
// This is only for the first match in the regex. Callers shouldn't be providing regexes with multiple capture groups with the same name.
|
||||
func MatchNamedCaptureGroups(regEx *regexp.Regexp, content string) map[string]string {
|
||||
// note: we are looking across all matches and stopping on the first non-empty match. Why? Take the following example:
|
||||
// input: "cool something to match against" pattern: `((?P<name>match) (?P<version>against))?`. Since the pattern is
|
||||
// encapsulated in an optional capture group, there will be results for each character, but the results will match
|
||||
// on nothing. The only "true" match will be at the end ("match against").
|
||||
allMatches := regEx.FindAllStringSubmatch(content, -1)
|
||||
var results map[string]string
|
||||
for _, match := range allMatches {
|
||||
// fill a candidate results map with named capture group results, accepting empty values, but not groups with
|
||||
// no names
|
||||
for nameIdx, name := range regEx.SubexpNames() {
|
||||
if nameIdx > len(match) || len(name) == 0 {
|
||||
continue
|
||||
}
|
||||
if results == nil {
|
||||
results = make(map[string]string)
|
||||
}
|
||||
results[name] = match[nameIdx]
|
||||
}
|
||||
// note: since we are looking for the first best potential match we should stop when we find the first one
|
||||
// with non-empty results.
|
||||
if !isEmptyMap(results) {
|
||||
break
|
||||
}
|
||||
}
|
||||
return results
|
||||
}
|
||||
|
||||
func isEmptyMap(m map[string]string) bool {
|
||||
if len(m) == 0 {
|
||||
return true
|
||||
}
|
||||
for _, value := range m {
|
||||
if value != "" {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
70
internal/regex_helpers_test.go
Normal file
70
internal/regex_helpers_test.go
Normal file
|
@ -0,0 +1,70 @@
|
|||
package internal
|
||||
|
||||
import (
|
||||
"regexp"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestMatchCaptureGroups(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
input string
|
||||
pattern string
|
||||
expected map[string]string
|
||||
}{
|
||||
{
|
||||
name: "go-case",
|
||||
input: "match this thing",
|
||||
pattern: `(?P<name>match).*(?P<version>thing)`,
|
||||
expected: map[string]string{
|
||||
"name": "match",
|
||||
"version": "thing",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "only matches the first instance",
|
||||
input: "match this thing batch another think",
|
||||
pattern: `(?P<name>[mb]atch).*?(?P<version>thin[gk])`,
|
||||
expected: map[string]string{
|
||||
"name": "match",
|
||||
"version": "thing",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "nested capture groups",
|
||||
input: "cool something to match against",
|
||||
pattern: `((?P<name>match) (?P<version>against))`,
|
||||
expected: map[string]string{
|
||||
"name": "match",
|
||||
"version": "against",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "nested optional capture groups",
|
||||
input: "cool something to match against",
|
||||
pattern: `((?P<name>match) (?P<version>against))?`,
|
||||
expected: map[string]string{
|
||||
"name": "match",
|
||||
"version": "against",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "nested optional capture groups with larger match",
|
||||
input: "cool something to match against match never",
|
||||
pattern: `.*?((?P<name>match) (?P<version>(against|never)))?`,
|
||||
expected: map[string]string{
|
||||
"name": "match",
|
||||
"version": "against",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
actual := MatchNamedCaptureGroups(regexp.MustCompile(test.pattern), test.input)
|
||||
assert.Equal(t, test.expected, actual)
|
||||
})
|
||||
}
|
||||
}
|
|
@ -43,6 +43,15 @@ func newMockDbStore() *mockStore {
|
|||
},
|
||||
backend: map[string]map[string][]grypeDB.Vulnerability{
|
||||
"nvd:cpe": {
|
||||
"jdk": []grypeDB.Vulnerability{
|
||||
{
|
||||
ID: "CVE-jdk",
|
||||
PackageName: "jdk",
|
||||
VersionConstraint: "< 1.8.0_401",
|
||||
VersionFormat: "jvm",
|
||||
CPEs: []string{"cpe:2.3:a:oracle:jdk:*:*:*:*:*:*:*:*"},
|
||||
},
|
||||
},
|
||||
"libvncserver": []grypeDB.Vulnerability{
|
||||
{
|
||||
ID: "CVE-alpine-libvncserver",
|
||||
|
|
|
@ -14,7 +14,16 @@ import (
|
|||
"github.com/anchore/grype/grype/db"
|
||||
"github.com/anchore/grype/grype/match"
|
||||
"github.com/anchore/grype/grype/matcher"
|
||||
"github.com/anchore/grype/grype/matcher/dotnet"
|
||||
"github.com/anchore/grype/grype/matcher/golang"
|
||||
"github.com/anchore/grype/grype/matcher/java"
|
||||
"github.com/anchore/grype/grype/matcher/javascript"
|
||||
"github.com/anchore/grype/grype/matcher/python"
|
||||
"github.com/anchore/grype/grype/matcher/ruby"
|
||||
"github.com/anchore/grype/grype/matcher/rust"
|
||||
"github.com/anchore/grype/grype/matcher/stock"
|
||||
"github.com/anchore/grype/grype/pkg"
|
||||
"github.com/anchore/grype/grype/search"
|
||||
"github.com/anchore/grype/grype/store"
|
||||
"github.com/anchore/grype/grype/vex"
|
||||
"github.com/anchore/grype/grype/vulnerability"
|
||||
|
@ -541,6 +550,50 @@ func addHaskellMatches(t *testing.T, theSource source.Source, catalog *syftPkg.C
|
|||
})
|
||||
}
|
||||
|
||||
func addJvmMatches(t *testing.T, theSource source.Source, catalog *syftPkg.Collection, theStore *mockStore, theResult *match.Matches) {
|
||||
packages := catalog.PackagesByPath("/opt/java/openjdk/release")
|
||||
if len(packages) < 1 {
|
||||
t.Logf("JVM Packages: %+v", packages)
|
||||
t.Fatalf("problem with upstream syft cataloger (java-jvm-cataloger)")
|
||||
}
|
||||
|
||||
for _, p := range packages {
|
||||
thePkg := pkg.New(p)
|
||||
theVuln := theStore.backend["nvd:cpe"][strings.ToLower(thePkg.Name)][0]
|
||||
vulnObj, err := vulnerability.NewVulnerability(theVuln)
|
||||
vulnObj.CPEs = []cpe.CPE{
|
||||
cpe.Must("cpe:2.3:a:oracle:jdk:*:*:*:*:*:*:*:*", ""),
|
||||
}
|
||||
require.NoError(t, err)
|
||||
|
||||
theResult.Add(match.Match{
|
||||
Vulnerability: *vulnObj,
|
||||
Package: thePkg,
|
||||
Details: []match.Detail{
|
||||
{
|
||||
Type: match.CPEMatch,
|
||||
Confidence: 0.9,
|
||||
SearchedBy: search.CPEParameters{
|
||||
Namespace: "nvd:cpe",
|
||||
CPEs: []string{
|
||||
"cpe:2.3:a:oracle:jdk:1.8.0:update400:*:*:*:*:*:*",
|
||||
},
|
||||
Package: search.CPEPackageParameter{Name: "jdk", Version: "1.8.0_400-b07"},
|
||||
},
|
||||
Found: search.CPEResult{
|
||||
VulnerabilityID: "CVE-jdk",
|
||||
VersionConstraint: "< 1.8.0_401 (jvm)",
|
||||
CPEs: []string{
|
||||
"cpe:2.3:a:oracle:jdk:*:*:*:*:*:*:*:*",
|
||||
},
|
||||
},
|
||||
Matcher: match.StockMatcher,
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func addRustMatches(t *testing.T, theSource source.Source, catalog *syftPkg.Collection, theStore *mockStore, theResult *match.Matches) {
|
||||
packages := catalog.PackagesByPath("/hello-auditable")
|
||||
if len(packages) < 1 {
|
||||
|
@ -588,11 +641,11 @@ func TestMatchByImage(t *testing.T) {
|
|||
}
|
||||
|
||||
tests := []struct {
|
||||
fixtureImage string
|
||||
expectedFn func(source.Source, *syftPkg.Collection, *mockStore) match.Matches
|
||||
name string
|
||||
expectedFn func(source.Source, *syftPkg.Collection, *mockStore) match.Matches
|
||||
}{
|
||||
{
|
||||
fixtureImage: "image-debian-match-coverage",
|
||||
name: "image-debian-match-coverage",
|
||||
expectedFn: func(theSource source.Source, catalog *syftPkg.Collection, theStore *mockStore) match.Matches {
|
||||
expectedMatches := match.NewMatches()
|
||||
addPythonMatches(t, theSource, catalog, theStore, &expectedMatches)
|
||||
|
@ -607,7 +660,7 @@ func TestMatchByImage(t *testing.T) {
|
|||
},
|
||||
},
|
||||
{
|
||||
fixtureImage: "image-centos-match-coverage",
|
||||
name: "image-centos-match-coverage",
|
||||
expectedFn: func(theSource source.Source, catalog *syftPkg.Collection, theStore *mockStore) match.Matches {
|
||||
expectedMatches := match.NewMatches()
|
||||
addRhelMatches(t, theSource, catalog, theStore, &expectedMatches)
|
||||
|
@ -615,7 +668,7 @@ func TestMatchByImage(t *testing.T) {
|
|||
},
|
||||
},
|
||||
{
|
||||
fixtureImage: "image-alpine-match-coverage",
|
||||
name: "image-alpine-match-coverage",
|
||||
expectedFn: func(theSource source.Source, catalog *syftPkg.Collection, theStore *mockStore) match.Matches {
|
||||
expectedMatches := match.NewMatches()
|
||||
addAlpineMatches(t, theSource, catalog, theStore, &expectedMatches)
|
||||
|
@ -623,7 +676,7 @@ func TestMatchByImage(t *testing.T) {
|
|||
},
|
||||
},
|
||||
{
|
||||
fixtureImage: "image-sles-match-coverage",
|
||||
name: "image-sles-match-coverage",
|
||||
expectedFn: func(theSource source.Source, catalog *syftPkg.Collection, theStore *mockStore) match.Matches {
|
||||
expectedMatches := match.NewMatches()
|
||||
addSlesMatches(t, theSource, catalog, theStore, &expectedMatches)
|
||||
|
@ -631,7 +684,7 @@ func TestMatchByImage(t *testing.T) {
|
|||
},
|
||||
},
|
||||
{
|
||||
fixtureImage: "image-portage-match-coverage",
|
||||
name: "image-portage-match-coverage",
|
||||
expectedFn: func(theSource source.Source, catalog *syftPkg.Collection, theStore *mockStore) match.Matches {
|
||||
expectedMatches := match.NewMatches()
|
||||
addPortageMatches(t, theSource, catalog, theStore, &expectedMatches)
|
||||
|
@ -639,21 +692,29 @@ func TestMatchByImage(t *testing.T) {
|
|||
},
|
||||
},
|
||||
{
|
||||
fixtureImage: "image-rust-auditable-match-coverage",
|
||||
name: "image-rust-auditable-match-coverage",
|
||||
expectedFn: func(theSource source.Source, catalog *syftPkg.Collection, theStore *mockStore) match.Matches {
|
||||
expectedMatches := match.NewMatches()
|
||||
addRustMatches(t, theSource, catalog, theStore, &expectedMatches)
|
||||
return expectedMatches
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "image-jvm-match-coverage",
|
||||
expectedFn: func(theSource source.Source, catalog *syftPkg.Collection, theStore *mockStore) match.Matches {
|
||||
expectedMatches := match.NewMatches()
|
||||
addJvmMatches(t, theSource, catalog, theStore, &expectedMatches)
|
||||
return expectedMatches
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run(test.fixtureImage, func(t *testing.T) {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
theStore := newMockDbStore()
|
||||
|
||||
imagetest.GetFixtureImage(t, "docker-archive", test.fixtureImage)
|
||||
tarPath := imagetest.GetFixtureImageTarPath(t, test.fixtureImage)
|
||||
imagetest.GetFixtureImage(t, "docker-archive", test.name)
|
||||
tarPath := imagetest.GetFixtureImageTarPath(t, test.name)
|
||||
|
||||
// this is purely done to help setup mocks
|
||||
theSource, err := syft.GetSource(context.Background(), tarPath, syft.DefaultGetSourceConfig().WithSources("docker-archive"))
|
||||
|
@ -671,7 +732,33 @@ func TestMatchByImage(t *testing.T) {
|
|||
require.NoError(t, err)
|
||||
require.NotNil(t, s)
|
||||
|
||||
matchers := matcher.NewDefaultMatchers(matcher.Config{})
|
||||
// TODO: we need to use the API default configuration, not something hard coded here
|
||||
matchers := matcher.NewDefaultMatchers(matcher.Config{
|
||||
Java: java.MatcherConfig{
|
||||
UseCPEs: true,
|
||||
},
|
||||
Ruby: ruby.MatcherConfig{
|
||||
UseCPEs: true,
|
||||
},
|
||||
Python: python.MatcherConfig{
|
||||
UseCPEs: true,
|
||||
},
|
||||
Dotnet: dotnet.MatcherConfig{
|
||||
UseCPEs: true,
|
||||
},
|
||||
Javascript: javascript.MatcherConfig{
|
||||
UseCPEs: true,
|
||||
},
|
||||
Golang: golang.MatcherConfig{
|
||||
UseCPEs: true,
|
||||
},
|
||||
Rust: rust.MatcherConfig{
|
||||
UseCPEs: true,
|
||||
},
|
||||
Stock: stock.MatcherConfig{
|
||||
UseCPEs: true,
|
||||
},
|
||||
})
|
||||
|
||||
vp, err := db.NewVulnerabilityProvider(theStore)
|
||||
require.NoError(t, err)
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
FROM scratch
|
||||
COPY . .
|
|
@ -0,0 +1,5 @@
|
|||
JAVA_VERSION="1.8.0_400"
|
||||
FULL_VERSION="1.8.0_400-b07"
|
||||
NOPE_SEMANTIC_VERSION="8.0.400+7"
|
||||
IMPLEMENTOR="Oracle"
|
||||
IMAGE_TYPE="JDK"
|
Loading…
Reference in a new issue