Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package grype for openSUSE:Factory checked in at 2026-01-30 18:23:49 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/grype (Old) and /work/SRC/openSUSE:Factory/.grype.new.1995 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "grype" Fri Jan 30 18:23:49 2026 rev:113 rq:1329948 version:0.107.0 Changes: -------- --- /work/SRC/openSUSE:Factory/grype/grype.changes 2026-01-28 15:10:03.341252181 +0100 +++ /work/SRC/openSUSE:Factory/.grype.new.1995/grype.changes 2026-01-30 18:23:57.893759150 +0100 @@ -1,0 +2,19 @@ +Fri Jan 30 06:20:31 UTC 2026 - Johannes Kastl <[email protected]> + +- Update to version 0.107.0: + * Added Features + - Add secureos distro [#3086 @divolgin] + - add hex matcher for Erlang/Elixir ecosystem [#3194 + @willmurphyscode] + * Bug Fixes + - disable version fallback in EOL query [#3195 + @willmurphyscode] + - VEX documents with docker.io registry reference not matching, + require index.docker.io instead [#2818 #3172 @jainlakshya] + * Dependencies + - chore(deps): update anchore dependencies (#3198) + - chore(deps): bump actions/setup-python in + /.github/actions/bootstrap (#3196) + - chore(deps): update tools to latest versions (#3189) + +------------------------------------------------------------------- Old: ---- grype-0.106.0.obscpio New: ---- grype-0.107.0.obscpio ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ grype.spec ++++++ --- /var/tmp/diff_new_pack.da5ffB/_old 2026-01-30 18:24:00.709878141 +0100 +++ /var/tmp/diff_new_pack.da5ffB/_new 2026-01-30 18:24:00.709878141 +0100 @@ -17,7 +17,7 @@ Name: grype -Version: 0.106.0 +Version: 0.107.0 Release: 0 Summary: A vulnerability scanner for container images and filesystems License: Apache-2.0 ++++++ _service ++++++ --- /var/tmp/diff_new_pack.da5ffB/_old 2026-01-30 18:24:00.753880000 +0100 +++ /var/tmp/diff_new_pack.da5ffB/_new 2026-01-30 18:24:00.757880169 +0100 @@ -3,7 +3,7 @@ <param name="url">https://github.com/anchore/grype</param> <param name="scm">git</param> <param name="exclude">.git</param> - <param name="revision">v0.106.0</param> + <param name="revision">v0.107.0</param> <param name="match-tag">v*</param> <param name="versionformat">@PARENT_TAG@</param> <param name="versionrewrite-pattern">v(.*)</param> ++++++ _servicedata ++++++ --- /var/tmp/diff_new_pack.da5ffB/_old 2026-01-30 18:24:00.789881521 +0100 +++ /var/tmp/diff_new_pack.da5ffB/_new 2026-01-30 18:24:00.797881859 +0100 @@ -1,6 +1,6 @@ <servicedata> <service name="tar_scm"> <param name="url">https://github.com/anchore/grype</param> - <param name="changesrevision">823d98b8e9939d9f1a7e713463ff4c9b47fa051a</param></service></servicedata> + <param name="changesrevision">3e8647396b9b201136afe07a30b98cd5850dcc64</param></service></servicedata> (No newline at EOF) ++++++ grype-0.106.0.obscpio -> grype-0.107.0.obscpio ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/grype-0.106.0/.binny.yaml new/grype-0.107.0/.binny.yaml --- old/grype-0.106.0/.binny.yaml 2026-01-27 12:35:16.000000000 +0100 +++ new/grype-0.107.0/.binny.yaml 2026-01-29 22:30:09.000000000 +0100 @@ -82,7 +82,7 @@ # used for running all local and CI tasks - name: task version: - want: v3.47.0 + want: v3.48.0 method: github-release with: repo: go-task/task diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/grype-0.106.0/cmd/grype/cli/commands/root.go new/grype-0.107.0/cmd/grype/cli/commands/root.go --- old/grype-0.106.0/cmd/grype/cli/commands/root.go 2026-01-27 12:35:16.000000000 +0100 +++ new/grype-0.107.0/cmd/grype/cli/commands/root.go 2026-01-29 22:30:09.000000000 +0100 @@ -21,6 +21,7 @@ "github.com/anchore/grype/grype/matcher/dotnet" "github.com/anchore/grype/grype/matcher/dpkg" "github.com/anchore/grype/grype/matcher/golang" + "github.com/anchore/grype/grype/matcher/hex" "github.com/anchore/grype/grype/matcher/java" "github.com/anchore/grype/grype/matcher/javascript" "github.com/anchore/grype/grype/matcher/python" @@ -371,6 +372,7 @@ AlwaysUseCPEForStdlib: opts.Match.Golang.AlwaysUseCPEForStdlib, AllowMainModulePseudoVersionComparison: opts.Match.Golang.AllowMainModulePseudoVersionComparison, }, + Hex: hex.MatcherConfig(opts.Match.Hex), Stock: stock.MatcherConfig(opts.Match.Stock), Dpkg: dpkg.MatcherConfig{ MissingEpochStrategy: opts.Match.Dpkg.MissingEpochStrategy, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/grype-0.106.0/cmd/grype/cli/commands/root_test.go new/grype-0.107.0/cmd/grype/cli/commands/root_test.go --- old/grype-0.106.0/cmd/grype/cli/commands/root_test.go 2026-01-27 12:35:16.000000000 +0100 +++ new/grype-0.107.0/cmd/grype/cli/commands/root_test.go 2026-01-29 22:30:09.000000000 +0100 @@ -16,6 +16,7 @@ "github.com/anchore/grype/grype/matcher/dotnet" "github.com/anchore/grype/grype/matcher/dpkg" "github.com/anchore/grype/grype/matcher/golang" + "github.com/anchore/grype/grype/matcher/hex" "github.com/anchore/grype/grype/matcher/java" "github.com/anchore/grype/grype/matcher/javascript" "github.com/anchore/grype/grype/matcher/python" @@ -114,6 +115,7 @@ AlwaysUseCPEForStdlib: true, AllowMainModulePseudoVersionComparison: false, }, + Hex: hex.MatcherConfig{}, Stock: stock.MatcherConfig{UseCPEs: true}, Rpm: rpm.MatcherConfig{ MissingEpochStrategy: "auto", @@ -148,6 +150,7 @@ AlwaysUseCPEForStdlib: true, AllowMainModulePseudoVersionComparison: false, }, + Hex: hex.MatcherConfig{}, Stock: stock.MatcherConfig{UseCPEs: true}, Rpm: rpm.MatcherConfig{ MissingEpochStrategy: "zero", @@ -182,6 +185,7 @@ AlwaysUseCPEForStdlib: true, AllowMainModulePseudoVersionComparison: false, }, + Hex: hex.MatcherConfig{}, Stock: stock.MatcherConfig{UseCPEs: true}, Rpm: rpm.MatcherConfig{ MissingEpochStrategy: "auto", diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/grype-0.106.0/cmd/grype/cli/options/match.go new/grype-0.107.0/cmd/grype/cli/options/match.go --- old/grype-0.106.0/cmd/grype/cli/options/match.go 2026-01-27 12:35:16.000000000 +0100 +++ new/grype-0.107.0/cmd/grype/cli/options/match.go 2026-01-29 22:30:09.000000000 +0100 @@ -17,6 +17,7 @@ Python matcherConfig `yaml:"python" json:"python" mapstructure:"python"` // settings for the python matcher Ruby matcherConfig `yaml:"ruby" json:"ruby" mapstructure:"ruby"` // settings for the ruby matcher Rust matcherConfig `yaml:"rust" json:"rust" mapstructure:"rust"` // settings for the rust matcher + Hex matcherConfig `yaml:"hex" json:"hex" mapstructure:"hex"` // settings for the hex matcher (Elixir/Erlang) Stock matcherConfig `yaml:"stock" json:"stock" mapstructure:"stock"` // settings for the default/stock matcher Dpkg dpkgConfig `yaml:"dpkg" json:"dpkg" mapstructure:"dpkg"` // settings for the dpkg matcher Rpm rpmConfig `yaml:"rpm" json:"rpm" mapstructure:"rpm"` // settings for the rpm matcher @@ -125,6 +126,7 @@ Python: dontUseCpe, Ruby: dontUseCpe, Rust: dontUseCpe, + Hex: dontUseCpe, Stock: useCpe, Dpkg: defaultDpkgConfig(), Rpm: defaultRpmConfig(), @@ -170,6 +172,7 @@ descriptions.Add(&cfg.Python.UseCPEs, usingCpeDescription) descriptions.Add(&cfg.Ruby.UseCPEs, usingCpeDescription) descriptions.Add(&cfg.Rust.UseCPEs, usingCpeDescription) + descriptions.Add(&cfg.Hex.UseCPEs, usingCpeDescription) descriptions.Add(&cfg.Stock.UseCPEs, usingCpeDescription) descriptions.Add(&cfg.Dpkg.MissingEpochStrategy, `strategy for handling missing epochs in dpkg package versions during matching (options: zero, auto)`) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/grype-0.106.0/go.mod new/grype-0.107.0/go.mod --- old/grype-0.106.0/go.mod 2026-01-27 12:35:16.000000000 +0100 +++ new/grype-0.107.0/go.mod 2026-01-29 22:30:09.000000000 +0100 @@ -18,7 +18,7 @@ github.com/anchore/go-version v1.2.2-0.20210903204242-51efa5b487c4 github.com/anchore/packageurl-go v0.1.1-0.20250220190351-d62adb6e1115 github.com/anchore/stereoscope v0.1.19 - github.com/anchore/syft v1.41.0 + github.com/anchore/syft v1.41.1 github.com/aquasecurity/go-pep440-version v0.0.1 github.com/araddon/dateparse v0.0.0-20210429162001-6b43995a97de github.com/bitnami/go-version v0.0.0-20250505154626-452e8c5ee607 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/grype-0.106.0/go.sum new/grype-0.107.0/go.sum --- old/grype-0.106.0/go.sum 2026-01-27 12:35:16.000000000 +0100 +++ new/grype-0.107.0/go.sum 2026-01-29 22:30:09.000000000 +0100 @@ -158,8 +158,8 @@ github.com/anchore/packageurl-go v0.1.1-0.20250220190351-d62adb6e1115/go.mod h1:KoYIv7tdP5+CC9VGkeZV4/vGCKsY55VvoG+5dadg4YI= github.com/anchore/stereoscope v0.1.19 h1:1G5LVmRN1Sz6qNezpVAEeN7QfWwCE9zw9TJK1ZGnkvw= github.com/anchore/stereoscope v0.1.19/go.mod h1:+laNHlk05xA2YqgEzq8mxkFzclL3NRdeNIsiQQVeZZ4= -github.com/anchore/syft v1.41.0 h1:OyiSnf4OpkwSnDMK+9D/ZNJymtzzdZ2VokjwAmpNlrA= -github.com/anchore/syft v1.41.0/go.mod h1:vrE06rTzgwrHB3T7fh83S/M555rpxy/olUG5c+oVcoU= +github.com/anchore/syft v1.41.1 h1:lUoEi/ICCSe8eqDmwwG7Kw6brVT20Ap5OmiqWlmddAg= +github.com/anchore/syft v1.41.1/go.mod h1:vrE06rTzgwrHB3T7fh83S/M555rpxy/olUG5c+oVcoU= 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= diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/grype-0.106.0/grype/db/v6/data.go new/grype-0.107.0/grype/db/v6/data.go --- old/grype-0.106.0/grype/db/v6/data.go 2026-01-27 12:35:16.000000000 +0100 +++ new/grype-0.107.0/grype/db/v6/data.go 2026-01-29 22:30:09.000000000 +0100 @@ -40,6 +40,7 @@ {Alias: "alpine", VersionPattern: `.*_alpha.*`, ReplacementLabelVersion: strRef("edge"), Rolling: true}, {Alias: "wolfi", Rolling: true}, {Alias: "chainguard", Rolling: true}, + {Alias: "secureos", Rolling: true}, // others {Alias: "archlinux", Rolling: true}, @@ -78,7 +79,8 @@ {Ecosystem: pkg.Dart.String(), ReplacementEcosystem: ptr(string(pkg.DartPubPkg))}, {Ecosystem: pkg.Dotnet.String(), ReplacementEcosystem: ptr(string(pkg.DotnetPkg))}, {Ecosystem: pkg.Elixir.String(), ReplacementEcosystem: ptr(string(pkg.HexPkg))}, - {Ecosystem: pkg.Erlang.String(), ReplacementEcosystem: ptr(string(pkg.ErlangOTPPkg))}, + {Ecosystem: pkg.Erlang.String(), ReplacementEcosystem: ptr(string(pkg.HexPkg))}, // Erlang packages use hex.pm, same as Elixir + {Ecosystem: string(pkg.ErlangOTPPkg), ReplacementEcosystem: ptr(string(pkg.HexPkg))}, // remap erlang-otp to hex for GHSA matching {Ecosystem: pkg.Go.String(), ReplacementEcosystem: ptr(string(pkg.GoModulePkg))}, {Ecosystem: pkg.Haskell.String(), ReplacementEcosystem: ptr(string(pkg.HackagePkg))}, {Ecosystem: pkg.Java.String(), ReplacementEcosystem: ptr(string(pkg.JavaPkg))}, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/grype-0.106.0/grype/db/v6/operating_system_store.go new/grype-0.107.0/grype/db/v6/operating_system_store.go --- old/grype-0.106.0/grype/db/v6/operating_system_store.go 2026-01-27 12:35:16.000000000 +0100 +++ new/grype-0.107.0/grype/db/v6/operating_system_store.go 2026-01-29 22:30:09.000000000 +0100 @@ -37,6 +37,11 @@ // DisableAliasing prevents OS aliasing when true (used for exact distro matching) DisableAliasing bool + + // DisableFallback prevents fallback to less specific version matching when true. + // When set, only exact version matches are returned (no major-only fallback). + // Used for EOL lookups where we don't want e.g. Alpine 3.24 to match Alpine 3.12. + DisableFallback bool } func (d *OSSpecifier) clean() { @@ -381,6 +386,11 @@ } } + // when fallback is disabled, don't try less specific version matches + if d.DisableFallback { + return nil, nil + } + // fallback to major version only, requiring the minor version to be blank. Note: it is important that we don't // match on any record with the given major version, we must only match on records that are intentionally empty // minor version. For instance, the DB may have rhel 8.1, 8.2, 8.3, 8.4, etc. We don't want to arbitrarily match diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/grype-0.106.0/grype/db/v6/operating_system_store_test.go new/grype-0.107.0/grype/db/v6/operating_system_store_test.go --- old/grype-0.106.0/grype/db/v6/operating_system_store_test.go 2026-01-27 12:35:16.000000000 +0100 +++ new/grype-0.107.0/grype/db/v6/operating_system_store_test.go 2026-01-29 22:30:09.000000000 +0100 @@ -314,6 +314,25 @@ }, expected: []OperatingSystem{*minimos}, }, + { + name: "nonexistent minor version falls back to major by default", + os: OSSpecifier{ + Name: "alpine", + MajorVersion: "3", + MinorVersion: "99", // doesn't exist, should fall back to 3.18 + }, + expected: []OperatingSystem{*alpine318}, + }, + { + name: "nonexistent minor version with DisableFallback returns nothing", + os: OSSpecifier{ + Name: "alpine", + MajorVersion: "3", + MinorVersion: "99", // doesn't exist + DisableFallback: true, // should NOT fall back + }, + expected: nil, + }, } for _, tt := range tests { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/grype-0.106.0/grype/db/v6/vulnerability_provider.go new/grype-0.107.0/grype/db/v6/vulnerability_provider.go --- old/grype-0.106.0/grype/db/v6/vulnerability_provider.go 2026-01-27 12:35:16.000000000 +0100 +++ new/grype-0.107.0/grype/db/v6/vulnerability_provider.go 2026-01-29 22:30:09.000000000 +0100 @@ -362,6 +362,7 @@ RemainingVersion: d.RemainingVersion(), LabelVersion: d.Codename, DisableAliasing: true, // EOL lookups must use exact distro match + DisableFallback: true, // don't fall back to major-only matching (e.g. Alpine 3.24 shouldn't match EOL'd 3.12) } results, err := vp.reader.GetOperatingSystems(spec) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/grype-0.106.0/grype/distro/distro_test.go new/grype-0.107.0/grype/distro/distro_test.go --- old/grype-0.106.0/grype/distro/distro_test.go 2026-01-27 12:35:16.000000000 +0100 +++ new/grype-0.107.0/grype/distro/distro_test.go 2026-01-29 22:30:09.000000000 +0100 @@ -471,6 +471,11 @@ Type: Scientific, Version: "6.10", }, + { + Name: "test-fixtures/os/secureos", + Type: SecureOS, + Version: "2025.09.09", + }, } for _, tt := range tests { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/grype-0.106.0/grype/distro/test-fixtures/os/secureos/etc/os-release new/grype-0.107.0/grype/distro/test-fixtures/os/secureos/etc/os-release --- old/grype-0.106.0/grype/distro/test-fixtures/os/secureos/etc/os-release 1970-01-01 01:00:00.000000000 +0100 +++ new/grype-0.107.0/grype/distro/test-fixtures/os/secureos/etc/os-release 2026-01-29 22:30:09.000000000 +0100 @@ -0,0 +1,5 @@ +ID=secureos +NAME="SecureOS" +PRETTY_NAME="SecureOS (SecureBuild)" +VERSION_ID="2025.09.09" +HOME_URL="https://securebuild.com/" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/grype-0.106.0/grype/distro/type.go new/grype-0.107.0/grype/distro/type.go --- old/grype-0.106.0/grype/distro/type.go 2026-01-27 12:35:16.000000000 +0100 +++ new/grype-0.107.0/grype/distro/type.go 2026-01-29 22:30:09.000000000 +0100 @@ -35,6 +35,7 @@ MinimOS Type = "minimos" Raspbian Type = "raspbian" Scientific Type = "scientific" + SecureOS Type = "secureos" ) // All contains all Linux distribution options @@ -64,6 +65,7 @@ MinimOS, Raspbian, Scientific, + SecureOS, } // IDMapping maps a distro ID from the /etc/os-release (e.g. like "ubuntu") to a Distro type. @@ -92,6 +94,7 @@ "minimos": MinimOS, "raspbian": Raspbian, "scientific": Scientific, + "secureos": SecureOS, } // aliasTypes maps common aliases to their corresponding Type. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/grype-0.106.0/grype/match/matcher_type.go new/grype-0.107.0/grype/match/matcher_type.go --- old/grype-0.106.0/grype/match/matcher_type.go 2026-01-27 12:35:16.000000000 +0100 +++ new/grype-0.107.0/grype/match/matcher_type.go 2026-01-29 22:30:09.000000000 +0100 @@ -19,6 +19,7 @@ RustMatcher MatcherType = "rust-matcher" BitnamiMatcher MatcherType = "bitnami-matcher" PacmanMatcher MatcherType = "pacman-matcher" + HexMatcher MatcherType = "hex-matcher" ) var AllMatcherTypes = []MatcherType{ @@ -38,6 +39,7 @@ RustMatcher, BitnamiMatcher, PacmanMatcher, + HexMatcher, } type MatcherType string diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/grype-0.106.0/grype/matcher/hex/matcher.go new/grype-0.107.0/grype/matcher/hex/matcher.go --- old/grype-0.106.0/grype/matcher/hex/matcher.go 1970-01-01 01:00:00.000000000 +0100 +++ new/grype-0.107.0/grype/matcher/hex/matcher.go 2026-01-29 22:30:09.000000000 +0100 @@ -0,0 +1,35 @@ +package hex + +import ( + "github.com/anchore/grype/grype/match" + "github.com/anchore/grype/grype/matcher/internal" + "github.com/anchore/grype/grype/pkg" + "github.com/anchore/grype/grype/vulnerability" + syftPkg "github.com/anchore/syft/syft/pkg" +) + +type Matcher struct { + cfg MatcherConfig +} + +type MatcherConfig struct { + UseCPEs bool +} + +func NewHexMatcher(cfg MatcherConfig) *Matcher { + return &Matcher{ + cfg: cfg, + } +} + +func (m *Matcher) PackageTypes() []syftPkg.Type { + return []syftPkg.Type{syftPkg.HexPkg, syftPkg.ErlangOTPPkg} +} + +func (m *Matcher) Type() match.MatcherType { + return match.HexMatcher +} + +func (m *Matcher) Match(store vulnerability.Provider, p pkg.Package) ([]match.Match, []match.IgnoreFilter, error) { + return internal.MatchPackageByEcosystemAndCPEs(store, p, m.Type(), m.cfg.UseCPEs) +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/grype-0.106.0/grype/matcher/matchers.go new/grype-0.107.0/grype/matcher/matchers.go --- old/grype-0.106.0/grype/matcher/matchers.go 2026-01-27 12:35:16.000000000 +0100 +++ new/grype-0.107.0/grype/matcher/matchers.go 2026-01-29 22:30:09.000000000 +0100 @@ -7,6 +7,7 @@ "github.com/anchore/grype/grype/matcher/dotnet" "github.com/anchore/grype/grype/matcher/dpkg" "github.com/anchore/grype/grype/matcher/golang" + "github.com/anchore/grype/grype/matcher/hex" "github.com/anchore/grype/grype/matcher/java" "github.com/anchore/grype/grype/matcher/javascript" "github.com/anchore/grype/grype/matcher/msrc" @@ -28,6 +29,7 @@ Javascript javascript.MatcherConfig Golang golang.MatcherConfig Rust rust.MatcherConfig + Hex hex.MatcherConfig Stock stock.MatcherConfig Dpkg dpkg.MatcherConfig Rpm rpm.MatcherConfig @@ -47,6 +49,7 @@ &msrc.Matcher{}, &portage.Matcher{}, rust.NewRustMatcher(mc.Rust), + hex.NewHexMatcher(mc.Hex), stock.NewStockMatcher(mc.Stock), &bitnami.Matcher{}, &pacman.Matcher{}, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/grype-0.106.0/grype/vex/openvex/implementation.go new/grype-0.107.0/grype/vex/openvex/implementation.go --- old/grype-0.106.0/grype/vex/openvex/implementation.go 2026-01-27 12:35:16.000000000 +0100 +++ new/grype-0.107.0/grype/vex/openvex/implementation.go 2026-01-29 22:30:09.000000000 +0100 @@ -83,6 +83,30 @@ return products } +func normalizeDockerHubRepositoryURL(repoURL string) string { + repoURL = strings.TrimSpace(repoURL) + if repoURL == "" { + return repoURL + } + + repoURL = strings.TrimPrefix(repoURL, "https://") + repoURL = strings.TrimPrefix(repoURL, "http://") + + repoURL = strings.TrimSuffix(repoURL, "/") + + host, rest, hasSlash := strings.Cut(repoURL, "/") + + switch strings.ToLower(host) { + case "docker.io", "index.docker.io", "registry-1.docker.io": + host = "index.docker.io" + } + + if !hasSlash || rest == "" { + return host + } + return host + "/" + rest +} + func identifiersFromTags(tags []string, name string) []string { identifiers := []string{} @@ -130,11 +154,14 @@ fmt.Sprintf("/%s", name), ) + repoURL = normalizeDockerHubRepositoryURL(repoURL) + qMap := map[string]string{} if repoURL != "" { qMap["repository_url"] = repoURL } + qs := packageurl.QualifiersFromMap(qMap) identifiers = append(identifiers, packageurl.NewPackageURL( "oci", "", name, shaString, qs, "", diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/grype-0.106.0/grype/vex/openvex/implementation_test.go new/grype-0.107.0/grype/vex/openvex/implementation_test.go --- old/grype-0.106.0/grype/vex/openvex/implementation_test.go 2026-01-27 12:35:16.000000000 +0100 +++ new/grype-0.107.0/grype/vex/openvex/implementation_test.go 2026-01-29 22:30:09.000000000 +0100 @@ -1,8 +1,10 @@ package openvex import ( + "strings" "testing" + "github.com/anchore/packageurl-go" openvex "github.com/openvex/go-vex/pkg/vex" "github.com/stretchr/testify/require" @@ -413,3 +415,53 @@ }) } } + +func TestIdentifiersFromDigests_NormalizesDockerHubRepositoryURL(t *testing.T) { + const hash = "124c7d2707904eea7431fffe91522a01e5a861a624ee31d03372cc1d138a3126" + const digest = "docker.io/library/alpine@sha256:" + hash + + ids := identifiersFromDigests([]string{digest}) + + var repoURL string + for _, id := range ids { + if !strings.HasPrefix(id, "pkg:oci/") { + continue + } + + p, err := packageurl.FromString(id) + require.NoError(t, err) + + if p.Name == "alpine" && p.Version == "sha256:"+hash { + repoURL = p.Qualifiers.Map()["repository_url"] + break + } + } + + require.NotEmpty(t, repoURL, "expected to find alpine purl in identifiers: %#v", ids) + require.Equal(t, "index.docker.io/library", repoURL) +} + +func TestNormalizeDockerHubRepositoryURL(t *testing.T) { + tests := []struct { + input string + expected string + }{ + {"docker.io/library", "index.docker.io/library"}, + {"index.docker.io/library", "index.docker.io/library"}, + {"registry-1.docker.io/library", "index.docker.io/library"}, + {"https://docker.io/library", "index.docker.io/library"}, + {"http://docker.io/library", "index.docker.io/library"}, + {"gcr.io/myorg", "gcr.io/myorg"}, + {"", ""}, + {"DOCKER.IO/Library", "index.docker.io/Library"}, + {"docker.io", "index.docker.io"}, + {"docker.io/", "index.docker.io"}, + {" docker.io/library ", "index.docker.io/library"}, + } + for _, tc := range tests { + t.Run(tc.input, func(t *testing.T) { + got := normalizeDockerHubRepositoryURL(tc.input) + require.Equal(t, tc.expected, got) + }) + } +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/grype-0.106.0/test/integration/db_mock_test.go new/grype-0.107.0/test/integration/db_mock_test.go --- old/grype-0.106.0/test/integration/db_mock_test.go 2026-01-27 12:35:16.000000000 +0100 +++ new/grype-0.107.0/test/integration/db_mock_test.go 2026-01-29 22:30:09.000000000 +0100 @@ -174,6 +174,14 @@ }, { Reference: vulnerability.Reference{ + ID: "CVE-hex-plug", + Namespace: "github:language:elixir", + }, + PackageName: "plug", + Constraint: version.MustGetConstraint("< 1.12.0", version.UnknownFormat), + }, + { + Reference: vulnerability.Reference{ ID: "CVE-rust-sample-1", Namespace: "github:language:rust", }, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/grype-0.106.0/test/integration/match_by_image_test.go new/grype-0.107.0/test/integration/match_by_image_test.go --- old/grype-0.106.0/test/integration/match_by_image_test.go 2026-01-27 12:35:16.000000000 +0100 +++ new/grype-0.107.0/test/integration/match_by_image_test.go 2026-01-29 22:30:09.000000000 +0100 @@ -613,6 +613,43 @@ }) } +func addHexMatches(t *testing.T, theSource source.Source, catalog *syftPkg.Collection, provider vulnerability.Provider, theResult *match.Matches) { + packages := catalog.PackagesByPath("/hex/mix.lock") + if len(packages) < 1 { + t.Logf("Hex Packages: %+v", packages) + t.Fatalf("problem with upstream syft cataloger (elixir-mix-lock)") + } + thePkg := pkg.New(packages[0]) + vulns, err := provider.FindVulnerabilities(byNamespace("github:language:elixir"), search.ByPackageName(thePkg.Name)) + require.NoError(t, err) + require.NotEmpty(t, vulns) + vulnObj := vulns[0] + + theResult.Add(match.Match{ + Vulnerability: vulnObj, + Package: thePkg, + Details: []match.Detail{ + { + Type: match.ExactDirectMatch, + Confidence: 1.0, + SearchedBy: match.EcosystemParameters{ + Language: "elixir", + Namespace: "github:language:elixir", + Package: match.PackageParameter{ + Name: thePkg.Name, + Version: thePkg.Version, + }, + }, + Found: match.EcosystemResult{ + VersionConstraint: "< 1.12.0 (unknown)", + VulnerabilityID: "CVE-hex-plug", + }, + Matcher: match.HexMatcher, + }, + }, + }) +} + func addJvmMatches(t *testing.T, theSource source.Source, catalog *syftPkg.Collection, provider vulnerability.Provider, theResult *match.Matches) { packages := catalog.PackagesByPath("/opt/java/openjdk/release") if len(packages) < 1 { @@ -723,6 +760,7 @@ addDotnetMatches(t, theSource, catalog, provider, &expectedMatches) addGolangMatches(t, theSource, catalog, provider, &expectedMatches) addHaskellMatches(t, theSource, catalog, provider, &expectedMatches) + addHexMatches(t, theSource, catalog, provider, &expectedMatches) return expectedMatches }, }, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/grype-0.106.0/test/integration/test-fixtures/image-debian-match-coverage/hex/mix.lock new/grype-0.107.0/test/integration/test-fixtures/image-debian-match-coverage/hex/mix.lock --- old/grype-0.106.0/test/integration/test-fixtures/image-debian-match-coverage/hex/mix.lock 1970-01-01 01:00:00.000000000 +0100 +++ new/grype-0.107.0/test/integration/test-fixtures/image-debian-match-coverage/hex/mix.lock 2026-01-29 22:30:09.000000000 +0100 @@ -0,0 +1,3 @@ +%{ + "plug": {:hex, :plug, "1.11.0", "f17217525597628298998bc3baed9f8ea1fa3f1160aa9871aee6df47a6e4d38e", [:mix], [{:mime, "~> 1.0", [hex: :mime, repo: "hexpm", optional: false]}, {:plug_crypto, "~> 1.1.1 or ~> 1.2", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "2d9c633f0499f9dc5c2fd069161af4e2e7756890b81adcbb2ceaa074e8308876"}, +} ++++++ grype.obsinfo ++++++ --- /var/tmp/diff_new_pack.da5ffB/_old 2026-01-30 18:24:13.230407177 +0100 +++ /var/tmp/diff_new_pack.da5ffB/_new 2026-01-30 18:24:13.258408360 +0100 @@ -1,5 +1,5 @@ name: grype -version: 0.106.0 -mtime: 1769513716 -commit: 823d98b8e9939d9f1a7e713463ff4c9b47fa051a +version: 0.107.0 +mtime: 1769722209 +commit: 3e8647396b9b201136afe07a30b98cd5850dcc64 ++++++ vendor.tar.gz ++++++ /work/SRC/openSUSE:Factory/grype/vendor.tar.gz /work/SRC/openSUSE:Factory/.grype.new.1995/vendor.tar.gz differ: char 133, line 1
