mirror of
https://github.com/anchore/grype
synced 2024-11-10 06:34:13 +00:00
add matcher tests + dpkg constraint adapter (add <)
This commit is contained in:
parent
d9c922218c
commit
622f09feff
18 changed files with 378 additions and 96 deletions
|
@ -91,7 +91,7 @@ func runDefaultCmd(_ *cobra.Command, args []string) int {
|
|||
// })
|
||||
|
||||
// store := db.NewMockDb()
|
||||
store := db.GetStoreFromSqlite()
|
||||
store := db.GetStore()
|
||||
provider := vulnerability.NewProviderFromStore(store)
|
||||
|
||||
results := vulnscan.FindAllVulnerabilities(provider, osObj, catalog)
|
||||
|
|
|
@ -2,6 +2,7 @@ package db
|
|||
|
||||
import "github.com/anchore/vulnscan-db/pkg/db"
|
||||
|
||||
func GetStoreFromSqlite() *db.SqliteStore {
|
||||
func GetStore() db.VulnStore {
|
||||
// TODO: add connection options and info
|
||||
return db.NewSqliteStore(nil)
|
||||
}
|
||||
|
|
20
internal/stringset.go
Normal file
20
internal/stringset.go
Normal file
|
@ -0,0 +1,20 @@
|
|||
package internal
|
||||
|
||||
type Set map[string]struct{}
|
||||
|
||||
func NewStringSet() Set {
|
||||
return make(Set)
|
||||
}
|
||||
|
||||
func (s Set) Add(i string) {
|
||||
s[i] = struct{}{}
|
||||
}
|
||||
|
||||
func (s Set) Remove(i string) {
|
||||
delete(s, i)
|
||||
}
|
||||
|
||||
func (s Set) Contains(i string) bool {
|
||||
_, ok := s[i]
|
||||
return ok
|
||||
}
|
|
@ -25,13 +25,13 @@ func ExactPackageNameMatch(store vulnerability.Provider, o distro.Distro, p *pkg
|
|||
|
||||
for _, vuln := range allPkgVulns {
|
||||
// if the constraint it met, then the given package has the vulnerability
|
||||
satisfied, err := vuln.Constraint.Satisfied(verObj)
|
||||
isPackageVulnerable, err := vuln.Constraint.Satisfied(verObj)
|
||||
if err != nil {
|
||||
// TODO: not enough information (cannot back track constraint object)
|
||||
return nil, fmt.Errorf("matcher failed to check constraint='%s' version='%s': %w", vuln.Constraint, verObj, err)
|
||||
}
|
||||
|
||||
if satisfied {
|
||||
if isPackageVulnerable {
|
||||
matches = append(matches, match.Match{
|
||||
Type: match.ExactDirectMatch,
|
||||
Confidence: 1.0, // TODO: this is hard coded for now
|
||||
|
|
55
vulnscan/matcher/distro/matcher_mocks_test.go
Normal file
55
vulnscan/matcher/distro/matcher_mocks_test.go
Normal file
|
@ -0,0 +1,55 @@
|
|||
package distro
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"github.com/anchore/imgbom/imgbom/distro"
|
||||
"github.com/anchore/imgbom/imgbom/pkg"
|
||||
"github.com/anchore/vulnscan/vulnscan/version"
|
||||
"github.com/anchore/vulnscan/vulnscan/vulnerability"
|
||||
)
|
||||
|
||||
type mockProvider struct {
|
||||
data map[string]map[string][]*vulnerability.Vulnerability
|
||||
}
|
||||
|
||||
func newMockProvider() *mockProvider {
|
||||
pr := mockProvider{
|
||||
data: make(map[string]map[string][]*vulnerability.Vulnerability),
|
||||
}
|
||||
pr.stub()
|
||||
return &pr
|
||||
}
|
||||
|
||||
func (pr *mockProvider) stub() {
|
||||
pr.data["debian:8"] = map[string][]*vulnerability.Vulnerability{
|
||||
// direct...
|
||||
"neutron": {
|
||||
{
|
||||
Constraint: version.MustGetConstraint("< 2014.1.5-6", version.DpkgFormat),
|
||||
ID: "CVE-2014-fake-1",
|
||||
},
|
||||
},
|
||||
// indirect...
|
||||
"neutron-devel": {
|
||||
// expected...
|
||||
{
|
||||
Constraint: version.MustGetConstraint("< 2014.1.4-5", version.DpkgFormat),
|
||||
ID: "CVE-2014-fake-2",
|
||||
},
|
||||
{
|
||||
Constraint: version.MustGetConstraint("< 2015.0.0-1", version.DpkgFormat),
|
||||
ID: "CVE-2013-fake-3",
|
||||
},
|
||||
// unexpected...
|
||||
{
|
||||
Constraint: version.MustGetConstraint("< 2014.0.4-1", version.DpkgFormat),
|
||||
ID: "CVE-2013-fake-BAD",
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (pr *mockProvider) GetByDistro(d distro.Distro, p *pkg.Package) ([]*vulnerability.Vulnerability, error) {
|
||||
return pr.data[strings.ToLower(d.Type.String())+":"+d.FullVersion()][p.Name], nil
|
||||
}
|
63
vulnscan/matcher/distro/matcher_test.go
Normal file
63
vulnscan/matcher/distro/matcher_test.go
Normal file
|
@ -0,0 +1,63 @@
|
|||
package distro
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/anchore/imgbom/imgbom/distro"
|
||||
"github.com/anchore/imgbom/imgbom/pkg"
|
||||
"github.com/anchore/vulnscan/internal"
|
||||
"github.com/anchore/vulnscan/vulnscan/match"
|
||||
)
|
||||
|
||||
func TestMatcher_ExactPackageNameMatch(t *testing.T) {
|
||||
|
||||
p := pkg.Package{
|
||||
Name: "neutron",
|
||||
Version: "2014.1.3-6",
|
||||
Type: pkg.DebPkg,
|
||||
Metadata: pkg.DpkgMetadata{
|
||||
Source: "neutron-devel",
|
||||
},
|
||||
}
|
||||
|
||||
d, err := distro.NewDistro(distro.Debian, "8")
|
||||
if err != nil {
|
||||
t.Fatal("could not create distro: ", err)
|
||||
}
|
||||
|
||||
store := newMockProvider()
|
||||
actual, err := ExactPackageNameMatch(store, d, &p, "SOME_OTHER_MATCHER")
|
||||
|
||||
if len(actual) != 1 {
|
||||
t.Fatalf("unexpected direct matches count: %d", len(actual))
|
||||
}
|
||||
|
||||
foundCVEs := internal.NewStringSet()
|
||||
|
||||
for _, a := range actual {
|
||||
foundCVEs.Add(a.Vulnerability.ID)
|
||||
|
||||
if a.Type != match.ExactDirectMatch {
|
||||
t.Error("direct match not indicated")
|
||||
}
|
||||
|
||||
if a.Package.Name != p.Name {
|
||||
t.Errorf("failed to capture correct original package: %s", a.Package.Name)
|
||||
}
|
||||
|
||||
if a.Matcher != "SOME_OTHER_MATCHER" {
|
||||
t.Errorf("failed to capture matcher name: %s", a.Matcher)
|
||||
}
|
||||
|
||||
if a.IndirectPackage != nil {
|
||||
t.Fatalf("should not have captured indirect package")
|
||||
}
|
||||
}
|
||||
|
||||
for _, id := range []string{"CVE-2014-fake-1"} {
|
||||
if !foundCVEs.Contains(id) {
|
||||
t.Errorf("missing discovered CVE: %s", id)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -40,7 +40,7 @@ func (m *Matcher) Match(store vulnerability.Provider, d _distro.Distro, p *pkg.P
|
|||
return matches, nil
|
||||
}
|
||||
|
||||
func (m *Matcher) matchBySourceIndirection(store vulnerability.Provider, d _distro.Distro, p *pkg.Package) ([]match.Match, error) {
|
||||
func (m *Matcher) matchBySourceIndirection(store vulnerability.ProviderByDistro, d _distro.Distro, p *pkg.Package) ([]match.Match, error) {
|
||||
value, ok := p.Metadata.(pkg.DpkgMetadata)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("bad dpkg metadata type='%T'", value)
|
||||
|
|
55
vulnscan/matcher/dpkg/matcher_mocks_test.go
Normal file
55
vulnscan/matcher/dpkg/matcher_mocks_test.go
Normal file
|
@ -0,0 +1,55 @@
|
|||
package dpkg
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"github.com/anchore/imgbom/imgbom/distro"
|
||||
"github.com/anchore/imgbom/imgbom/pkg"
|
||||
"github.com/anchore/vulnscan/vulnscan/version"
|
||||
"github.com/anchore/vulnscan/vulnscan/vulnerability"
|
||||
)
|
||||
|
||||
type mockProvider struct {
|
||||
data map[string]map[string][]*vulnerability.Vulnerability
|
||||
}
|
||||
|
||||
func newMockProvider() *mockProvider {
|
||||
pr := mockProvider{
|
||||
data: make(map[string]map[string][]*vulnerability.Vulnerability),
|
||||
}
|
||||
pr.stub()
|
||||
return &pr
|
||||
}
|
||||
|
||||
func (pr *mockProvider) stub() {
|
||||
pr.data["debian:8"] = map[string][]*vulnerability.Vulnerability{
|
||||
// direct...
|
||||
"neutron": {
|
||||
{
|
||||
Constraint: version.MustGetConstraint("< 2014.1.3-6", version.DpkgFormat),
|
||||
ID: "CVE-2014-fake-1",
|
||||
},
|
||||
},
|
||||
// indirect...
|
||||
"neutron-devel": {
|
||||
// expected...
|
||||
{
|
||||
Constraint: version.MustGetConstraint("< 2014.1.4-5", version.DpkgFormat),
|
||||
ID: "CVE-2014-fake-2",
|
||||
},
|
||||
{
|
||||
Constraint: version.MustGetConstraint("< 2015.0.0-1", version.DpkgFormat),
|
||||
ID: "CVE-2013-fake-3",
|
||||
},
|
||||
// unexpected...
|
||||
{
|
||||
Constraint: version.MustGetConstraint("< 2014.0.4-1", version.DpkgFormat),
|
||||
ID: "CVE-2013-fake-BAD",
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (pr *mockProvider) GetByDistro(d distro.Distro, p *pkg.Package) ([]*vulnerability.Vulnerability, error) {
|
||||
return pr.data[strings.ToLower(d.Type.String())+":"+d.FullVersion()][p.Name], nil
|
||||
}
|
70
vulnscan/matcher/dpkg/matcher_test.go
Normal file
70
vulnscan/matcher/dpkg/matcher_test.go
Normal file
|
@ -0,0 +1,70 @@
|
|||
package dpkg
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/anchore/imgbom/imgbom/distro"
|
||||
"github.com/anchore/imgbom/imgbom/pkg"
|
||||
"github.com/anchore/vulnscan/internal"
|
||||
"github.com/anchore/vulnscan/vulnscan/match"
|
||||
)
|
||||
|
||||
func TestMatcherDpkg_matchBySourceIndirection(t *testing.T) {
|
||||
matcher := Matcher{}
|
||||
p := pkg.Package{
|
||||
Name: "neutron",
|
||||
Version: "2014.1.3-6",
|
||||
Type: pkg.DebPkg,
|
||||
Metadata: pkg.DpkgMetadata{
|
||||
Source: "neutron-devel",
|
||||
},
|
||||
}
|
||||
|
||||
d, err := distro.NewDistro(distro.Debian, "8")
|
||||
if err != nil {
|
||||
t.Fatal("could not create distro: ", err)
|
||||
}
|
||||
|
||||
store := newMockProvider()
|
||||
actual, err := matcher.matchBySourceIndirection(store, d, &p)
|
||||
|
||||
if len(actual) != 2 {
|
||||
t.Fatalf("unexpected indirect matches count: %d", len(actual))
|
||||
}
|
||||
|
||||
foundCVEs := internal.NewStringSet()
|
||||
|
||||
for _, a := range actual {
|
||||
foundCVEs.Add(a.Vulnerability.ID)
|
||||
|
||||
if a.Type != match.ExactIndirectMatch {
|
||||
t.Error("indirect match not indicated")
|
||||
}
|
||||
|
||||
if a.Package.Name != p.Name {
|
||||
t.Errorf("failed to capture correct original package: %s", a.Package.Name)
|
||||
}
|
||||
|
||||
if a.Matcher != matcher.Name() {
|
||||
t.Errorf("failed to capture matcher name: %s", a.Matcher)
|
||||
}
|
||||
|
||||
if a.IndirectPackage == nil {
|
||||
t.Fatalf("failed to capture correct indirect package")
|
||||
}
|
||||
|
||||
if a.IndirectPackage.Name != p.Name+"-devel" {
|
||||
t.Errorf("failed to capture correct indirect package name: %s", a.IndirectPackage.Name)
|
||||
}
|
||||
}
|
||||
|
||||
for _, id := range []string{"CVE-2014-fake-2", "CVE-2013-fake-3"} {
|
||||
if !foundCVEs.Contains(id) {
|
||||
t.Errorf("missing discovered CVE: %s", id)
|
||||
}
|
||||
}
|
||||
if t.Failed() {
|
||||
t.Logf("discovered CVES: %+v", foundCVEs)
|
||||
}
|
||||
|
||||
}
|
|
@ -2,6 +2,7 @@ package version
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
deb "github.com/knqyf263/go-deb-version"
|
||||
)
|
||||
|
@ -21,12 +22,20 @@ type dpkgConstraint struct {
|
|||
}
|
||||
|
||||
func newDpkgConstraint(raw string) (dpkgConstraint, error) {
|
||||
// TODO: allow for "<" parsing
|
||||
if raw == "" {
|
||||
// an empty constraint is always satisfied
|
||||
return dpkgConstraint{}, nil
|
||||
}
|
||||
fixedIn, err := newDpkgVersion(raw)
|
||||
|
||||
fixedVersion := strings.TrimPrefix(strings.TrimSpace(raw), "<")
|
||||
if strings.ContainsAny(fixedVersion, "><=") {
|
||||
return dpkgConstraint{}, fmt.Errorf("invalid constraint given (%s), only '< fixedversion' allowed for DPKG version constraints", fixedVersion)
|
||||
}
|
||||
if fixedVersion == raw {
|
||||
return dpkgConstraint{}, fmt.Errorf("no constraints found (< operator)")
|
||||
}
|
||||
|
||||
fixedIn, err := newDpkgVersion(fixedVersion)
|
||||
if err != nil {
|
||||
return dpkgConstraint{}, fmt.Errorf("failed to create Dpkg constraint: %w", err)
|
||||
}
|
||||
|
@ -57,9 +66,8 @@ func (c dpkgConstraint) Satisfied(version *Version) (bool, error) {
|
|||
}
|
||||
|
||||
func (c dpkgConstraint) String() string {
|
||||
// TODO: don't put the "<" here, allow the vulnscan-db to insert this for us
|
||||
if c.raw == "" {
|
||||
return "None (dpkg)"
|
||||
return "[no constraint] (dpkg)"
|
||||
}
|
||||
return fmt.Sprintf("< %s (dpkg)", c.raw)
|
||||
return fmt.Sprintf("%s (dpkg)", c.raw)
|
||||
}
|
||||
|
|
|
@ -7,43 +7,43 @@ import (
|
|||
|
||||
func TestVersionDpkg(t *testing.T) {
|
||||
tests := []testCase{
|
||||
{version: "2.3.1", constraint: "2.0.0", expected: false},
|
||||
{version: "2.3.1", constraint: "2.0", expected: false},
|
||||
{version: "2.3.1", constraint: "2", expected: false},
|
||||
{version: "2.3.1", constraint: "2.3", expected: false},
|
||||
{version: "2.3.1", constraint: "2.3.1", expected: false},
|
||||
{version: "2.3.1", constraint: "2.3.2", expected: true},
|
||||
{version: "2.3.1", constraint: "2.4", expected: true},
|
||||
{version: "2.3.1", constraint: "3", expected: true},
|
||||
{version: "2.3.1", constraint: "3.0", expected: true},
|
||||
{version: "2.3.1", constraint: "3.0.0", expected: true},
|
||||
{version: "2.3.1-1ubuntu0.14.04.1", constraint: "2.0.0", expected: false},
|
||||
{version: "2.3.1-1ubuntu0.14.04.1", constraint: "2.0", expected: false},
|
||||
{version: "2.3.1-1ubuntu0.14.04.1", constraint: "2", expected: false},
|
||||
{version: "2.3.1-1ubuntu0.14.04.1", constraint: "2.3", expected: false},
|
||||
{version: "2.3.1-1ubuntu0.14.04.1", constraint: "2.3.1", expected: false},
|
||||
{version: "2.3.1-1ubuntu0.14.04.1", constraint: "2.3.2", expected: true},
|
||||
{version: "2.3.1-1ubuntu0.14.04.1", constraint: "2.4", expected: true},
|
||||
{version: "2.3.1-1ubuntu0.14.04.1", constraint: "3", expected: true},
|
||||
{version: "2.3.1-1ubuntu0.14.04.1", constraint: "3.0", expected: true},
|
||||
{version: "2.3.1-1ubuntu0.14.04.1", constraint: "3.0.0", expected: true},
|
||||
{version: "7u151-2.6.11-2ubuntu0.14.04.1", constraint: "7u151-2.6.11-2ubuntu0.14.04.1", expected: false},
|
||||
{version: "7u151-2.6.11-2ubuntu0.14.04.1", constraint: "7u151-2.6.11", expected: false},
|
||||
{version: "7u151-2.6.11-2ubuntu0.14.04.1", constraint: "7u151-2.7", expected: false},
|
||||
{version: "7u151-2.6.11-2ubuntu0.14.04.1", constraint: "7u151", expected: false},
|
||||
{version: "7u151-2.6.11-2ubuntu0.14.04.1", constraint: "7u150", expected: false},
|
||||
{version: "7u151-2.6.11-2ubuntu0.14.04.1", constraint: "7u152", expected: true},
|
||||
{version: "7u151-2.6.11-2ubuntu0.14.04.1", constraint: "7u152-2.6.11-2ubuntu0.14.04.1", expected: true},
|
||||
{version: "7u151-2.6.11-2ubuntu0.14.04.1", constraint: "8u1-2.6.11-2ubuntu0.14.04.1", expected: true},
|
||||
{version: "43.0.2357.81-0ubuntu0.14.04.1.1089", constraint: "43", expected: false},
|
||||
{version: "43.0.2357.81-0ubuntu0.14.04.1.1089", constraint: "43.0", expected: false},
|
||||
{version: "43.0.2357.81-0ubuntu0.14.04.1.1089", constraint: "43.0.2357", expected: false},
|
||||
{version: "43.0.2357.81-0ubuntu0.14.04.1.1089", constraint: "43.0.2357.81", expected: false},
|
||||
{version: "43.0.2357.81-0ubuntu0.14.04.1.1089", constraint: "43.0.2357.81-0ubuntu0.14.04.1.1089", expected: false},
|
||||
{version: "43.0.2357.81-0ubuntu0.14.04.1.1089", constraint: "43.0.2357.82-0ubuntu0.14.04.1.1089", expected: true},
|
||||
{version: "43.0.2357.81-0ubuntu0.14.04.1.1089", constraint: "43.0.2358-0ubuntu0.14.04.1.1089", expected: true},
|
||||
{version: "43.0.2357.81-0ubuntu0.14.04.1.1089", constraint: "43.1-0ubuntu0.14.04.1.1089", expected: true},
|
||||
{version: "43.0.2357.81-0ubuntu0.14.04.1.1089", constraint: "44-0ubuntu0.14.04.1.1089", expected: true},
|
||||
{version: "2.3.1", constraint: "< 2.0.0", isVulnerable: false},
|
||||
{version: "2.3.1", constraint: "< 2.0", isVulnerable: false},
|
||||
{version: "2.3.1", constraint: "< 2", isVulnerable: false},
|
||||
{version: "2.3.1", constraint: "< 2.3", isVulnerable: false},
|
||||
{version: "2.3.1", constraint: "< 2.3.1", isVulnerable: false},
|
||||
{version: "2.3.1", constraint: "< 2.3.2", isVulnerable: true},
|
||||
{version: "2.3.1", constraint: "< 2.4", isVulnerable: true},
|
||||
{version: "2.3.1", constraint: "< 3", isVulnerable: true},
|
||||
{version: "2.3.1", constraint: "< 3.0", isVulnerable: true},
|
||||
{version: "2.3.1", constraint: "< 3.0.0", isVulnerable: true},
|
||||
{version: "2.3.1-1ubuntu0.14.04.1", constraint: " <2.0.0", isVulnerable: false},
|
||||
{version: "2.3.1-1ubuntu0.14.04.1", constraint: " <2.0", isVulnerable: false},
|
||||
{version: "2.3.1-1ubuntu0.14.04.1", constraint: " <2", isVulnerable: false},
|
||||
{version: "2.3.1-1ubuntu0.14.04.1", constraint: " <2.3", isVulnerable: false},
|
||||
{version: "2.3.1-1ubuntu0.14.04.1", constraint: " <2.3.1", isVulnerable: false},
|
||||
{version: "2.3.1-1ubuntu0.14.04.1", constraint: " <2.3.2", isVulnerable: true},
|
||||
{version: "2.3.1-1ubuntu0.14.04.1", constraint: " <2.4", isVulnerable: true},
|
||||
{version: "2.3.1-1ubuntu0.14.04.1", constraint: " <3", isVulnerable: true},
|
||||
{version: "2.3.1-1ubuntu0.14.04.1", constraint: " <3.0", isVulnerable: true},
|
||||
{version: "2.3.1-1ubuntu0.14.04.1", constraint: " <3.0.0", isVulnerable: true},
|
||||
{version: "7u151-2.6.11-2ubuntu0.14.04.1", constraint: " < 7u151-2.6.11-2ubuntu0.14.04.1", isVulnerable: false},
|
||||
{version: "7u151-2.6.11-2ubuntu0.14.04.1", constraint: " < 7u151-2.6.11", isVulnerable: false},
|
||||
{version: "7u151-2.6.11-2ubuntu0.14.04.1", constraint: " < 7u151-2.7", isVulnerable: false},
|
||||
{version: "7u151-2.6.11-2ubuntu0.14.04.1", constraint: " < 7u151", isVulnerable: false},
|
||||
{version: "7u151-2.6.11-2ubuntu0.14.04.1", constraint: " < 7u150", isVulnerable: false},
|
||||
{version: "7u151-2.6.11-2ubuntu0.14.04.1", constraint: " < 7u152", isVulnerable: true},
|
||||
{version: "7u151-2.6.11-2ubuntu0.14.04.1", constraint: " < 7u152-2.6.11-2ubuntu0.14.04.1", isVulnerable: true},
|
||||
{version: "7u151-2.6.11-2ubuntu0.14.04.1", constraint: " < 8u1-2.6.11-2ubuntu0.14.04.1", isVulnerable: true},
|
||||
{version: "43.0.2357.81-0ubuntu0.14.04.1.1089", constraint: "<43", isVulnerable: false},
|
||||
{version: "43.0.2357.81-0ubuntu0.14.04.1.1089", constraint: "<43.0", isVulnerable: false},
|
||||
{version: "43.0.2357.81-0ubuntu0.14.04.1.1089", constraint: "<43.0.2357", isVulnerable: false},
|
||||
{version: "43.0.2357.81-0ubuntu0.14.04.1.1089", constraint: "<43.0.2357.81", isVulnerable: false},
|
||||
{version: "43.0.2357.81-0ubuntu0.14.04.1.1089", constraint: "<43.0.2357.81-0ubuntu0.14.04.1.1089", isVulnerable: false},
|
||||
{version: "43.0.2357.81-0ubuntu0.14.04.1.1089", constraint: "<43.0.2357.82-0ubuntu0.14.04.1.1089", isVulnerable: true},
|
||||
{version: "43.0.2357.81-0ubuntu0.14.04.1.1089", constraint: "<43.0.2358-0ubuntu0.14.04.1.1089", isVulnerable: true},
|
||||
{version: "43.0.2357.81-0ubuntu0.14.04.1.1089", constraint: "<43.1-0ubuntu0.14.04.1.1089", isVulnerable: true},
|
||||
{version: "43.0.2357.81-0ubuntu0.14.04.1.1089", constraint: "<44-0ubuntu0.14.04.1.1089", isVulnerable: true},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
|
|
|
@ -8,12 +8,12 @@ import (
|
|||
)
|
||||
|
||||
type testCase struct {
|
||||
version string
|
||||
constraint string
|
||||
expected bool
|
||||
createErr error
|
||||
constErr error
|
||||
checkErr error
|
||||
version string
|
||||
constraint string
|
||||
isVulnerable bool
|
||||
createErr error
|
||||
constErr error
|
||||
checkErr error
|
||||
}
|
||||
|
||||
func (c *testCase) name() string {
|
||||
|
@ -26,13 +26,13 @@ func (c *testCase) assert(t *testing.T, format Format, constraint Constraint) {
|
|||
t.Fatalf("unexpected create error: '%+v'!='%+v'", err, c.createErr)
|
||||
}
|
||||
|
||||
actual, err := constraint.Satisfied(verObj)
|
||||
isVulnerable, err := constraint.Satisfied(verObj)
|
||||
if !errors.Is(err, c.checkErr) {
|
||||
t.Fatalf("unexpected check error: '%+v'!='%+v'", err, c.checkErr)
|
||||
}
|
||||
|
||||
if actual != c.expected {
|
||||
t.Errorf("unexpected constraint check result: expected %+v, got %+v", c.expected, actual)
|
||||
if isVulnerable != c.isVulnerable {
|
||||
t.Errorf("unexpected constraint check result: expected %+v, got %+v", c.isVulnerable, isVulnerable)
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -7,42 +7,42 @@ import (
|
|||
|
||||
func TestVersionSemantic(t *testing.T) {
|
||||
tests := []testCase{
|
||||
{version: "2.3.1", constraint: "2.3.1", expected: true},
|
||||
{version: "2.3.1", constraint: "= 2.3.1", expected: true},
|
||||
{version: "2.3.1", constraint: " = 2.3.1", expected: true},
|
||||
{version: "2.3.1", constraint: ">= 2.3.1", expected: true},
|
||||
{version: "2.3.1", constraint: "> 2.0.0", expected: true},
|
||||
{version: "2.3.1", constraint: "> 2.0", expected: true},
|
||||
{version: "2.3.1", constraint: "> 2", expected: true},
|
||||
{version: "2.3.1", constraint: "> 2, < 3", expected: true},
|
||||
{version: "2.3.1", constraint: "> 2.3, < 3.1", expected: true},
|
||||
{version: "2.3.1", constraint: "> 2.3.0, < 3.1", expected: true},
|
||||
{version: "2.3.1", constraint: ">= 2.3.1, < 3.1", expected: true},
|
||||
{version: "2.3.1", constraint: " = 2.3.2", expected: false},
|
||||
{version: "2.3.1", constraint: ">= 2.3.2", expected: false},
|
||||
{version: "2.3.1", constraint: "> 2.3.1", expected: false},
|
||||
{version: "2.3.1", constraint: "< 2.0.0", expected: false},
|
||||
{version: "2.3.1", constraint: "< 2.0", expected: false},
|
||||
{version: "2.3.1", constraint: "< 2", expected: false},
|
||||
{version: "2.3.1", constraint: "< 2, > 3", expected: false},
|
||||
{version: "2.3.1+meta", constraint: "2.3.1", expected: true},
|
||||
{version: "2.3.1+meta", constraint: "= 2.3.1", expected: true},
|
||||
{version: "2.3.1+meta", constraint: " = 2.3.1", expected: true},
|
||||
{version: "2.3.1+meta", constraint: ">= 2.3.1", expected: true},
|
||||
{version: "2.3.1+meta", constraint: "> 2.0.0", expected: true},
|
||||
{version: "2.3.1+meta", constraint: "> 2.0", expected: true},
|
||||
{version: "2.3.1+meta", constraint: "> 2", expected: true},
|
||||
{version: "2.3.1+meta", constraint: "> 2, < 3", expected: true},
|
||||
{version: "2.3.1+meta", constraint: "> 2.3, < 3.1", expected: true},
|
||||
{version: "2.3.1+meta", constraint: "> 2.3.0, < 3.1", expected: true},
|
||||
{version: "2.3.1+meta", constraint: ">= 2.3.1, < 3.1", expected: true},
|
||||
{version: "2.3.1+meta", constraint: " = 2.3.2", expected: false},
|
||||
{version: "2.3.1+meta", constraint: ">= 2.3.2", expected: false},
|
||||
{version: "2.3.1+meta", constraint: "> 2.3.1", expected: false},
|
||||
{version: "2.3.1+meta", constraint: "< 2.0.0", expected: false},
|
||||
{version: "2.3.1+meta", constraint: "< 2.0", expected: false},
|
||||
{version: "2.3.1+meta", constraint: "< 2", expected: false},
|
||||
{version: "2.3.1+meta", constraint: "< 2, > 3", expected: false},
|
||||
{version: "2.3.1", constraint: "2.3.1", isVulnerable: true},
|
||||
{version: "2.3.1", constraint: "= 2.3.1", isVulnerable: true},
|
||||
{version: "2.3.1", constraint: " = 2.3.1", isVulnerable: true},
|
||||
{version: "2.3.1", constraint: ">= 2.3.1", isVulnerable: true},
|
||||
{version: "2.3.1", constraint: "> 2.0.0", isVulnerable: true},
|
||||
{version: "2.3.1", constraint: "> 2.0", isVulnerable: true},
|
||||
{version: "2.3.1", constraint: "> 2", isVulnerable: true},
|
||||
{version: "2.3.1", constraint: "> 2, < 3", isVulnerable: true},
|
||||
{version: "2.3.1", constraint: "> 2.3, < 3.1", isVulnerable: true},
|
||||
{version: "2.3.1", constraint: "> 2.3.0, < 3.1", isVulnerable: true},
|
||||
{version: "2.3.1", constraint: ">= 2.3.1, < 3.1", isVulnerable: true},
|
||||
{version: "2.3.1", constraint: " = 2.3.2", isVulnerable: false},
|
||||
{version: "2.3.1", constraint: ">= 2.3.2", isVulnerable: false},
|
||||
{version: "2.3.1", constraint: "> 2.3.1", isVulnerable: false},
|
||||
{version: "2.3.1", constraint: "< 2.0.0", isVulnerable: false},
|
||||
{version: "2.3.1", constraint: "< 2.0", isVulnerable: false},
|
||||
{version: "2.3.1", constraint: "< 2", isVulnerable: false},
|
||||
{version: "2.3.1", constraint: "< 2, > 3", isVulnerable: false},
|
||||
{version: "2.3.1+meta", constraint: "2.3.1", isVulnerable: true},
|
||||
{version: "2.3.1+meta", constraint: "= 2.3.1", isVulnerable: true},
|
||||
{version: "2.3.1+meta", constraint: " = 2.3.1", isVulnerable: true},
|
||||
{version: "2.3.1+meta", constraint: ">= 2.3.1", isVulnerable: true},
|
||||
{version: "2.3.1+meta", constraint: "> 2.0.0", isVulnerable: true},
|
||||
{version: "2.3.1+meta", constraint: "> 2.0", isVulnerable: true},
|
||||
{version: "2.3.1+meta", constraint: "> 2", isVulnerable: true},
|
||||
{version: "2.3.1+meta", constraint: "> 2, < 3", isVulnerable: true},
|
||||
{version: "2.3.1+meta", constraint: "> 2.3, < 3.1", isVulnerable: true},
|
||||
{version: "2.3.1+meta", constraint: "> 2.3.0, < 3.1", isVulnerable: true},
|
||||
{version: "2.3.1+meta", constraint: ">= 2.3.1, < 3.1", isVulnerable: true},
|
||||
{version: "2.3.1+meta", constraint: " = 2.3.2", isVulnerable: false},
|
||||
{version: "2.3.1+meta", constraint: ">= 2.3.2", isVulnerable: false},
|
||||
{version: "2.3.1+meta", constraint: "> 2.3.1", isVulnerable: false},
|
||||
{version: "2.3.1+meta", constraint: "< 2.0.0", isVulnerable: false},
|
||||
{version: "2.3.1+meta", constraint: "< 2.0", isVulnerable: false},
|
||||
{version: "2.3.1+meta", constraint: "< 2", isVulnerable: false},
|
||||
{version: "2.3.1+meta", constraint: "< 2, > 3", isVulnerable: false},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
|
|
|
@ -38,7 +38,6 @@ func NewVersionFromPkg(p *pkg.Package) (*Version, error) {
|
|||
switch p.Type {
|
||||
case pkg.DebPkg:
|
||||
format = DpkgFormat
|
||||
// ...
|
||||
default:
|
||||
format = UnknownFormat
|
||||
}
|
||||
|
|
|
@ -6,5 +6,9 @@ import (
|
|||
)
|
||||
|
||||
type Provider interface {
|
||||
ProviderByDistro
|
||||
}
|
||||
|
||||
type ProviderByDistro interface {
|
||||
GetByDistro(distro.Distro, *pkg.Package) ([]*Vulnerability, error)
|
||||
}
|
||||
|
|
|
@ -34,7 +34,14 @@ func (pr *StoreProvider) GetByDistro(d distro.Distro, p *pkg.Package) ([]*Vulner
|
|||
for _, vuln := range allPkgVulns {
|
||||
format := version.ParseFormat(vuln.VersionFormat)
|
||||
|
||||
constraint, err := version.GetConstraint(vuln.Version, format)
|
||||
// TODO: delete me, this should be implemented in the vulnscan-db repo
|
||||
var prefix string
|
||||
if format == version.DpkgFormat && vuln.Version != "" {
|
||||
prefix = "< "
|
||||
}
|
||||
// </TODO>
|
||||
|
||||
constraint, err := version.GetConstraint(prefix+vuln.Version, format)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("provider failed to parse constraint='%s' format='%s': %w", vuln.Version, format, err)
|
||||
}
|
||||
|
|
|
@ -32,11 +32,11 @@ func TestGetByDistro(t *testing.T) {
|
|||
|
||||
expected := []Vulnerability{
|
||||
{
|
||||
Constraint: version.MustGetConstraint("2014.1.3-6", version.DpkgFormat),
|
||||
Constraint: version.MustGetConstraint("< 2014.1.3-6", version.DpkgFormat),
|
||||
ID: "CVE-2014-fake-1",
|
||||
},
|
||||
{
|
||||
Constraint: version.MustGetConstraint("2013.0.2-1", version.DpkgFormat),
|
||||
Constraint: version.MustGetConstraint("< 2013.0.2-1", version.DpkgFormat),
|
||||
ID: "CVE-2013-fake-2",
|
||||
},
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue