Bump Syft in Grype to pull in unmarshaling fix (#1703)

* WIP: package builds but tests do not

Signed-off-by: Will Murphy <will.murphy@anchore.com>

* WIP: some unit tests compile

Signed-off-by: Will Murphy <will.murphy@anchore.com>

* WIP: unit tests compile but do not pass

Signed-off-by: Will Murphy <will.murphy@anchore.com>

* Units passing with some changes to syft

Signed-off-by: Will Murphy <will.murphy@anchore.com>

* fix: excludes plus bad sbom should not suppress error

Signed-off-by: Will Murphy <will.murphy@anchore.com>

* add conan entry v2 package test

Signed-off-by: Will Murphy <will.murphy@anchore.com>

* bump syft again

Signed-off-by: Will Murphy <will.murphy@anchore.com>

* chore: fix compiler error in integration tests

Signed-off-by: Will Murphy <will.murphy@anchore.com>

* chore: remove erlang OTP from package types that must be seen in test image

Signed-off-by: Will Murphy <will.murphy@anchore.com>

* bump syft version used

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

---------

Signed-off-by: Will Murphy <will.murphy@anchore.com>
Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>
Co-authored-by: Alex Goodman <wagoodman@users.noreply.github.com>
This commit is contained in:
William Murphy 2024-02-07 14:28:48 -05:00 committed by GitHub
parent 68b2796026
commit 396cc0aea7
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
27 changed files with 268 additions and 203 deletions

14
go.mod
View file

@ -8,13 +8,13 @@ require (
github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d
github.com/adrg/xdg v0.4.0
github.com/anchore/bubbly v0.0.0-20231115134915-def0aba654a9
github.com/anchore/clio v0.0.0-20231016125544-c98a83e1c7fc
github.com/anchore/clio v0.0.0-20240131202212-9eba61247448
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.20230104203445-02e0a6721501
github.com/anchore/stereoscope v0.0.1
github.com/anchore/syft v0.103.1
github.com/anchore/packageurl-go v0.1.1-0.20240202171727-877e1747d426
github.com/anchore/stereoscope v0.0.2-0.20240202153536-bfa15e446f06
github.com/anchore/syft v0.103.2-0.20240207163149-da31eed6374d
github.com/aquasecurity/go-pep440-version v0.0.0-20210121094942-22b2f8951d46
github.com/bmatcuk/doublestar/v2 v2.0.4
github.com/charmbracelet/bubbletea v0.25.0
@ -89,7 +89,7 @@ require (
github.com/becheran/wildmatch-go v1.0.0 // indirect
github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d // indirect
github.com/bmatcuk/doublestar/v4 v4.6.1 // indirect
github.com/charmbracelet/bubbles v0.17.1 // indirect
github.com/charmbracelet/bubbles v0.18.0 // indirect
github.com/charmbracelet/harmonica v0.2.0 // indirect
github.com/cloudflare/circl v1.3.7 // indirect
github.com/containerd/cgroups v1.1.0 // indirect
@ -194,7 +194,7 @@ require (
github.com/pkg/profile v1.7.0 // indirect
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect
github.com/rivo/uniseg v0.2.0 // indirect
github.com/rivo/uniseg v0.4.6 // indirect
github.com/rogpeppe/go-internal v1.12.0 // indirect
github.com/saferwall/pe v1.4.8 // indirect
github.com/sagikazarmark/locafero v0.3.0 // indirect
@ -234,7 +234,7 @@ require (
go.uber.org/atomic v1.9.0 // indirect
go.uber.org/multierr v1.9.0 // indirect
golang.org/x/crypto v0.18.0 // indirect
golang.org/x/mod v0.14.0 // indirect
golang.org/x/mod v0.15.0 // indirect
golang.org/x/net v0.20.0 // indirect
golang.org/x/oauth2 v0.15.0 // indirect
golang.org/x/sync v0.5.0 // indirect

27
go.sum
View file

@ -235,8 +235,8 @@ github.com/anchore/archiver/v3 v3.5.2 h1:Bjemm2NzuRhmHy3m0lRe5tNoClB9A4zYyDV58Pa
github.com/anchore/archiver/v3 v3.5.2/go.mod h1:e3dqJ7H78uzsRSEACH1joayhuSyhnonssnDhppzS1L4=
github.com/anchore/bubbly v0.0.0-20231115134915-def0aba654a9 h1:p0ZIe0htYOX284Y4axJaGBvXHU0VCCzLN5Wf5XbKStU=
github.com/anchore/bubbly v0.0.0-20231115134915-def0aba654a9/go.mod h1:3ZsFB9tzW3vl4gEiUeuSOMDnwroWxIxJelOOHUp8dSw=
github.com/anchore/clio v0.0.0-20231016125544-c98a83e1c7fc h1:A1KFO+zZZmbNlz1+WKsCF0RKVx6XRoxsAG3lrqH9hUQ=
github.com/anchore/clio v0.0.0-20231016125544-c98a83e1c7fc/go.mod h1:QeWvNzxsrUNxcs6haQo3OtISfXUXW0qAuiG4EQiz0GU=
github.com/anchore/clio v0.0.0-20240131202212-9eba61247448 h1:ZgecmkxhH5im+9jPs7Ra1Thmv/p4IBDsoCFD6W8pENg=
github.com/anchore/clio v0.0.0-20240131202212-9eba61247448/go.mod h1:t5Mld8naKcG8RTPjW/2n7bfyBKFl1A6PvtXw+v64gK0=
github.com/anchore/fangs v0.0.0-20231201140849-5075d28d6d8b h1:L/djgY7ZbZ/38+wUtdkk398W3PIBJLkt1N8nU/7e47A=
github.com/anchore/fangs v0.0.0-20231201140849-5075d28d6d8b/go.mod h1:TLcE0RE5+8oIx2/NPWem/dq1DeaMoC+fPEH7hoSzPLo=
github.com/anchore/go-logger v0.0.0-20230725134548-c21dafa1ec5a h1:nJ2G8zWKASyVClGVgG7sfM5mwoZlZ2zYpIzN2OhjWkw=
@ -249,12 +249,12 @@ github.com/anchore/go-testutils v0.0.0-20200925183923-d5f45b0d3c04 h1:VzprUTpc0v
github.com/anchore/go-testutils v0.0.0-20200925183923-d5f45b0d3c04/go.mod h1:6dK64g27Qi1qGQZ67gFmBFvEHScy0/C8qhQhNe5B5pQ=
github.com/anchore/go-version v1.2.2-0.20210903204242-51efa5b487c4 h1:rmZG77uXgE+o2gozGEBoUMpX27lsku+xrMwlmBZJtbg=
github.com/anchore/go-version v1.2.2-0.20210903204242-51efa5b487c4/go.mod h1:Bkc+JYWjMCF8OyZ340IMSIi2Ebf3uwByOk6ho4wne1E=
github.com/anchore/packageurl-go v0.1.1-0.20230104203445-02e0a6721501 h1:AV7qjwMcM4r8wFhJq3jLRztew3ywIyPTRapl2T1s9o8=
github.com/anchore/packageurl-go v0.1.1-0.20230104203445-02e0a6721501/go.mod h1:Blo6OgJNiYF41ufcgHKkbCKF2MDOMlrqhXv/ij6ocR4=
github.com/anchore/stereoscope v0.0.1 h1:OxF7PaxMltnAxjLnDMyka+SKRIQar/bBkDdavsnjyxM=
github.com/anchore/stereoscope v0.0.1/go.mod h1:IylG7ofLoUKHwS1XDF6rPhOmaE3GgpAgsMdvvYfooTU=
github.com/anchore/syft v0.103.1 h1:E5VJoNeFDh8AOetPkT8h5tyl8GmCRV8aeA1XZlwxS4U=
github.com/anchore/syft v0.103.1/go.mod h1:Ph25SA9kx4nJS8XlgTmI4/FvPCX7PbRyA5LBdlcH1zQ=
github.com/anchore/packageurl-go v0.1.1-0.20240202171727-877e1747d426 h1:agoiZchSf1Nnnos1azwIg5hk5Ao9TzZNBD9++AChGEg=
github.com/anchore/packageurl-go v0.1.1-0.20240202171727-877e1747d426/go.mod h1:Blo6OgJNiYF41ufcgHKkbCKF2MDOMlrqhXv/ij6ocR4=
github.com/anchore/stereoscope v0.0.2-0.20240202153536-bfa15e446f06 h1:3NAS33Bqrw87wckTff6/yXYDL1h3Wm6OiqaR1kcvW10=
github.com/anchore/stereoscope v0.0.2-0.20240202153536-bfa15e446f06/go.mod h1:uydT2ful8TY7Hr1WH1V1ZecSq/2TqXpAsGkMiy7lxD0=
github.com/anchore/syft v0.103.2-0.20240207163149-da31eed6374d h1:YivlSmLJgnOdxAhKitf5sjYIsPrBFUn5nbAtYuanv7o=
github.com/anchore/syft v0.103.2-0.20240207163149-da31eed6374d/go.mod h1:Sp1juSmwcyo1fg1r7YE8TYLgRG+mcA0IKDeJcrGF8Dk=
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=
@ -304,8 +304,8 @@ github.com/census-instrumentation/opencensus-proto v0.3.0/go.mod h1:f6KPmirojxKA
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/charmbracelet/bubbles v0.17.1 h1:0SIyjOnkrsfDo88YvPgAWvZMwXe26TP6drRvmkjyUu4=
github.com/charmbracelet/bubbles v0.17.1/go.mod h1:9HxZWlkCqz2PRwsCbYl7a3KXvGzFaDHpYbSYMJ+nE3o=
github.com/charmbracelet/bubbles v0.18.0 h1:PYv1A036luoBGroX6VWjQIE9Syf2Wby2oOl/39KLfy0=
github.com/charmbracelet/bubbles v0.18.0/go.mod h1:08qhZhtIwzgrtBjAcJnij1t1H0ZRjwHyGsy6AL11PSw=
github.com/charmbracelet/bubbletea v0.25.0 h1:bAfwk7jRz7FKFl9RzlIULPkStffg5k6pNt5dywy4TcM=
github.com/charmbracelet/bubbletea v0.25.0/go.mod h1:EN3QDR1T5ZdWmdfDzYcqOCAps45+QIJbLOBxmVNWNNg=
github.com/charmbracelet/harmonica v0.2.0 h1:8NxJWRWg/bzKqqEaaeFNipOu77YR5t8aSwG4pgaUBiQ=
@ -866,8 +866,9 @@ github.com/prometheus/procfs v0.8.0/go.mod h1:z7EfXMXOkbkqb9IINtpCn86r/to3BnA0ua
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE=
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY=
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
github.com/rivo/uniseg v0.4.6 h1:Sovz9sDSwbOz9tgUy8JpT+KgCkPYJEN/oYzlJiYTNLg=
github.com/rivo/uniseg v0.4.6/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
@ -1115,8 +1116,8 @@ golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.5.0/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/mod v0.14.0 h1:dGoOF9QVLYng8IHTm7BAyWqCqSheQ5pYWGhzW00YJr0=
golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/mod v0.15.0 h1:SernR4v+D55NyBH2QiEQrlBAnj1ECL6AGrA5+dPaMY8=
golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=

View file

@ -10,7 +10,7 @@ import (
func NewSlice(cpeStrs ...string) ([]cpe.CPE, error) {
var cpes []cpe.CPE
for _, c := range cpeStrs {
value, err := cpe.New(c)
value, err := cpe.New(c, "")
if err != nil {
log.Warnf("excluding invalid CPE %q: %v", c, err)
continue
@ -23,9 +23,9 @@ 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)
a := wfn.Attributes(c.Attributes)
for _, candidate := range candidates {
canCopy := wfn.Attributes(candidate)
canCopy := wfn.Attributes(candidate.Attributes)
if a.MatchWithoutVersion(&canCopy) {
matches = append(matches, candidate)
}

View file

@ -17,88 +17,88 @@ func TestMatchWithoutVersion(t *testing.T) {
}{
{
name: "GoCase",
compare: cpe.Must("cpe:2.3:*:python-requests:requests:2.3.0:*:*:*:*:python:*:*"),
compare: cpe.Must("cpe:2.3:*:python-requests:requests:2.3.0:*:*:*:*:python:*:*", ""),
candidates: []cpe.CPE{
cpe.Must("cpe:2.3:a:python-requests:requests:2.2.1:*:*:*:*:*:*:*"),
cpe.Must("cpe:2.3:a:python-requests:requests:2.2.1:*:*:*:*:*:*:*", ""),
},
expected: []cpe.CPE{
cpe.Must("cpe:2.3:a:python-requests:requests:2.2.1:*:*:*:*:*:*:*"),
cpe.Must("cpe:2.3:a:python-requests:requests:2.2.1:*:*:*:*:*:*:*", ""),
},
},
{
name: "IgnoreVersion",
compare: cpe.Must("cpe:2.3:*:name:name:3.2:*:*:*:*:java:*:*"),
compare: cpe.Must("cpe:2.3:*:name:name:3.2:*:*:*:*:java:*:*", ""),
candidates: []cpe.CPE{
cpe.Must("cpe:2.3:*:name:name:3.2:*:*:*:*:java:*:*"),
cpe.Must("cpe:2.3:*:name:name:3.3:*:*:*:*:java:*:*"),
cpe.Must("cpe:2.3:*:name:name:5.5:*:*:*:*:java:*:*"),
cpe.Must("cpe:2.3:*:name:name:3.2:*:*:*:*:java:*:*", ""),
cpe.Must("cpe:2.3:*:name:name:3.3:*:*:*:*:java:*:*", ""),
cpe.Must("cpe:2.3:*:name:name:5.5:*:*:*:*:java:*:*", ""),
},
expected: []cpe.CPE{
cpe.Must("cpe:2.3:*:name:name:3.2:*:*:*:*:java:*:*"),
cpe.Must("cpe:2.3:*:name:name:3.3:*:*:*:*:java:*:*"),
cpe.Must("cpe:2.3:*:name:name:5.5:*:*:*:*:java:*:*"),
cpe.Must("cpe:2.3:*:name:name:3.2:*:*:*:*:java:*:*", ""),
cpe.Must("cpe:2.3:*:name:name:3.3:*:*:*:*:java:*:*", ""),
cpe.Must("cpe:2.3:*:name:name:5.5:*:*:*:*:java:*:*", ""),
},
},
{
name: "MatchByTargetSW",
compare: cpe.Must("cpe:2.3:*:name:name:3.2:*:*:*:*:java:*:*"),
compare: cpe.Must("cpe:2.3:*:name:name:3.2:*:*:*:*:java:*:*", ""),
candidates: []cpe.CPE{
cpe.Must("cpe:2.3:*:name:name:3.2:*:*:*:*:java:*:*"),
cpe.Must("cpe:2.3:*:name:name:3.2:*:*:*:*:maven:*:*"),
cpe.Must("cpe:2.3:*:name:name:3.2:*:*:*:*:jenkins:*:*"),
cpe.Must("cpe:2.3:*:name:name:3.2:*:*:*:*:cloudbees_jenkins:*:*"),
cpe.Must("cpe:2.3:*:name:name:3.2:*:*:*:*:*:*:*"),
cpe.Must("cpe:2.3:*:name:name:3.2:*:*:*:*:java:*:*", ""),
cpe.Must("cpe:2.3:*:name:name:3.2:*:*:*:*:maven:*:*", ""),
cpe.Must("cpe:2.3:*:name:name:3.2:*:*:*:*:jenkins:*:*", ""),
cpe.Must("cpe:2.3:*:name:name:3.2:*:*:*:*:cloudbees_jenkins:*:*", ""),
cpe.Must("cpe:2.3:*:name:name:3.2:*:*:*:*:*:*:*", ""),
},
expected: []cpe.CPE{
cpe.Must("cpe:2.3:*:name:name:3.2:*:*:*:*:java:*:*"),
cpe.Must("cpe:2.3:*:name:name:3.2:*:*:*:*:*:*:*"),
cpe.Must("cpe:2.3:*:name:name:3.2:*:*:*:*:java:*:*", ""),
cpe.Must("cpe:2.3:*:name:name:3.2:*:*:*:*:*:*:*", ""),
},
},
{
name: "MatchByName",
compare: cpe.Must("cpe:2.3:*:name:name5:3.2:*:*:*:*:java:*:*"),
compare: cpe.Must("cpe:2.3:*:name:name5:3.2:*:*:*:*:java:*:*", ""),
candidates: []cpe.CPE{
cpe.Must("cpe:2.3:*:name:name1:3.2:*:*:*:*:java:*:*"),
cpe.Must("cpe:2.3:*:name:name2:3.2:*:*:*:*:java:*:*"),
cpe.Must("cpe:2.3:*:name:name3:3.2:*:*:*:*:java:*:*"),
cpe.Must("cpe:2.3:*:name:name4:3.2:*:*:*:*:java:*:*"),
cpe.Must("cpe:2.3:*:name:name5:3.2:*:*:*:*:*:*:*"),
cpe.Must("cpe:2.3:*:name:name1:3.2:*:*:*:*:java:*:*", ""),
cpe.Must("cpe:2.3:*:name:name2:3.2:*:*:*:*:java:*:*", ""),
cpe.Must("cpe:2.3:*:name:name3:3.2:*:*:*:*:java:*:*", ""),
cpe.Must("cpe:2.3:*:name:name4:3.2:*:*:*:*:java:*:*", ""),
cpe.Must("cpe:2.3:*:name:name5:3.2:*:*:*:*:*:*:*", ""),
},
expected: []cpe.CPE{
cpe.Must("cpe:2.3:*:name:name5:3.2:*:*:*:*:*:*:*"),
cpe.Must("cpe:2.3:*:name:name5:3.2:*:*:*:*:*:*:*", ""),
},
},
{
name: "MatchByVendor",
compare: cpe.Must("cpe:2.3:*:name3:name:3.2:*:*:*:*:java:*:*"),
compare: cpe.Must("cpe:2.3:*:name3:name:3.2:*:*:*:*:java:*:*", ""),
candidates: []cpe.CPE{
cpe.Must("cpe:2.3:*:name1:name:3.2:*:*:*:*:java:*:*"),
cpe.Must("cpe:2.3:*:name3:name:3.2:*:*:*:*:jaba-no-bother:*:*"),
cpe.Must("cpe:2.3:*:name3:name:3.2:*:*:*:*:java:*:*"),
cpe.Must("cpe:2.3:*:name4:name:3.2:*:*:*:*:java:*:*"),
cpe.Must("cpe:2.3:*:name5:name:3.2:*:*:*:*:*:*:*"),
cpe.Must("cpe:2.3:*:name1:name:3.2:*:*:*:*:java:*:*", ""),
cpe.Must("cpe:2.3:*:name3:name:3.2:*:*:*:*:jaba-no-bother:*:*", ""),
cpe.Must("cpe:2.3:*:name3:name:3.2:*:*:*:*:java:*:*", ""),
cpe.Must("cpe:2.3:*:name4:name:3.2:*:*:*:*:java:*:*", ""),
cpe.Must("cpe:2.3:*:name5:name:3.2:*:*:*:*:*:*:*", ""),
},
expected: []cpe.CPE{
cpe.Must("cpe:2.3:*:name3:name:3.2:*:*:*:*:java:*:*"),
cpe.Must("cpe:2.3:*:name3:name:3.2:*:*:*:*:java:*:*", ""),
},
},
{
name: "MatchAnyVendorOrTargetSW",
compare: cpe.Must("cpe:2.3:*:*:name:3.2:*:*:*:*:*:*:*"),
compare: cpe.Must("cpe:2.3:*:*:name:3.2:*:*:*:*:*:*:*", ""),
candidates: []cpe.CPE{
cpe.Must("cpe:2.3:*:name1:name:3.2:*:*:*:*:java:*:*"),
cpe.Must("cpe:2.3:*:name3:name:3.2:*:*:*:*:jaba-no-bother:*:*"),
cpe.Must("cpe:2.3:*:name3:name:3.2:*:*:*:*:java:*:*"),
cpe.Must("cpe:2.3:*:name4:name:3.2:*:*:*:*:java:*:*"),
cpe.Must("cpe:2.3:*:name5:name:3.2:*:*:*:*:*:*:*"),
cpe.Must("cpe:2.3:*:name5:NOMATCH:3.2:*:*:*:*:*:*:*"),
cpe.Must("cpe:2.3:*:name1:name:3.2:*:*:*:*:java:*:*", ""),
cpe.Must("cpe:2.3:*:name3:name:3.2:*:*:*:*:jaba-no-bother:*:*", ""),
cpe.Must("cpe:2.3:*:name3:name:3.2:*:*:*:*:java:*:*", ""),
cpe.Must("cpe:2.3:*:name4:name:3.2:*:*:*:*:java:*:*", ""),
cpe.Must("cpe:2.3:*:name5:name:3.2:*:*:*:*:*:*:*", ""),
cpe.Must("cpe:2.3:*:name5:NOMATCH:3.2:*:*:*:*:*:*:*", ""),
},
expected: []cpe.CPE{
cpe.Must("cpe:2.3:*:name1:name:3.2:*:*:*:*:java:*:*"),
cpe.Must("cpe:2.3:*:name3:name:3.2:*:*:*:*:jaba-no-bother:*:*"),
cpe.Must("cpe:2.3:*:name3:name:3.2:*:*:*:*:java:*:*"),
cpe.Must("cpe:2.3:*:name4:name:3.2:*:*:*:*:java:*:*"),
cpe.Must("cpe:2.3:*:name5:name:3.2:*:*:*:*:*:*:*"),
cpe.Must("cpe:2.3:*:name1:name:3.2:*:*:*:*:java:*:*", ""),
cpe.Must("cpe:2.3:*:name3:name:3.2:*:*:*:*:jaba-no-bother:*:*", ""),
cpe.Must("cpe:2.3:*:name3:name:3.2:*:*:*:*:java:*:*", ""),
cpe.Must("cpe:2.3:*:name4:name:3.2:*:*:*:*:java:*:*", ""),
cpe.Must("cpe:2.3:*:name5:name:3.2:*:*:*:*:*:*:*", ""),
},
},
}
@ -109,17 +109,17 @@ func TestMatchWithoutVersion(t *testing.T) {
if len(actual) != len(test.expected) {
for _, e := range actual {
t.Errorf(" unexpected entry: %+v", e.BindToFmtString())
t.Errorf(" unexpected entry: %+v", e.Attributes.BindToFmtString())
}
t.Fatalf("unexpected number of entries: %d", len(actual))
}
for idx, a := range actual {
e := test.expected[idx]
if a.BindToFmtString() != e.BindToFmtString() {
if a.Attributes.BindToFmtString() != e.Attributes.BindToFmtString() {
dmp := diffmatchpatch.New()
diffs := dmp.DiffMain(a.BindToFmtString(), e.BindToFmtString(), true)
t.Errorf("mismatched entries @ %d:\n\texpected:%+v\n\t actual:%+v\n\t diff:%+v\n", idx, e.BindToFmtString(), a.BindToFmtString(), dmp.DiffPrettyText(diffs))
diffs := dmp.DiffMain(a.Attributes.BindToFmtString(), e.Attributes.BindToFmtString(), true)
t.Errorf("mismatched entries @ %d:\n\texpected:%+v\n\t actual:%+v\n\t diff:%+v\n", idx, e.Attributes.BindToFmtString(), a.Attributes.BindToFmtString(), dmp.DiffPrettyText(diffs))
}
}
})

View file

@ -141,17 +141,17 @@ func (pr *VulnerabilityProvider) GetByCPE(requestCPE cpe.CPE) ([]vulnerability.V
return nil, nil
}
if requestCPE.Product == wfn.Any || requestCPE.Product == wfn.NA {
if requestCPE.Attributes.Product == wfn.Any || requestCPE.Attributes.Product == wfn.NA {
return nil, fmt.Errorf("product name is required")
}
for _, ns := range namespaces {
allPkgVulns, err := pr.reader.SearchForVulnerabilities(ns.String(), ns.Resolver().Normalize(requestCPE.Product))
allPkgVulns, err := pr.reader.SearchForVulnerabilities(ns.String(), ns.Resolver().Normalize(requestCPE.Attributes.Product))
if err != nil {
return nil, fmt.Errorf("provider failed to fetch namespace=%q product=%q: %w", ns, requestCPE.Product, err)
return nil, fmt.Errorf("provider failed to fetch namespace=%q product=%q: %w", ns, requestCPE.Attributes.Product, err)
}
normalizedRequestCPE, err := cpe.New(ns.Resolver().Normalize(requestCPE.BindToFmtString()))
normalizedRequestCPE, err := cpe.New(ns.Resolver().Normalize(requestCPE.Attributes.BindToFmtString()), requestCPE.Source)
if err != nil {
normalizedRequestCPE = requestCPE
@ -169,7 +169,7 @@ func (pr *VulnerabilityProvider) GetByCPE(requestCPE cpe.CPE) ([]vulnerability.V
if len(candidateMatchCpes) > 0 {
vulnObj, err := vulnerability.NewVulnerability(vuln)
if err != nil {
return nil, fmt.Errorf("provider failed to inflate vulnerability record (namespace=%q id=%q cpe=%q): %w", vuln.Namespace, vuln.ID, requestCPE.BindToFmtString(), err)
return nil, fmt.Errorf("provider failed to inflate vulnerability record (namespace=%q id=%q cpe=%q): %w", vuln.Namespace, vuln.ID, requestCPE.Attributes.BindToFmtString(), err)
}
vulnObj.CPEs = candidateMatchCpes

View file

@ -84,13 +84,13 @@ func Test_GetByCPE(t *testing.T) {
}{
{
name: "match from name and target SW",
cpe: cpe.Must("cpe:2.3:*:activerecord:activerecord:*:*:*:*:*:ruby:*:*"),
cpe: cpe.Must("cpe:2.3:*:activerecord:activerecord:*:*:*:*:*:ruby:*:*", ""),
expected: []vulnerability.Vulnerability{
{
Constraint: version.MustGetConstraint("< 3.7.4", version.UnknownFormat),
ID: "CVE-2014-fake-4",
CPEs: []cpe.CPE{
cpe.Must("cpe:2.3:*:activerecord:activerecord:*:*:something:*:*:ruby:*:*"),
cpe.Must("cpe:2.3:*:activerecord:activerecord:*:*:something:*:*:ruby:*:*", ""),
},
Namespace: "nvd:cpe",
PackageQualifiers: []qualifier.Qualifier{},
@ -100,13 +100,13 @@ func Test_GetByCPE(t *testing.T) {
},
{
name: "match with normalization",
cpe: cpe.Must("cpe:2.3:*:ActiVERecord:ACTiveRecord:*:*:*:*:*:ruby:*:*"),
cpe: cpe.Must("cpe:2.3:*:ActiVERecord:ACTiveRecord:*:*:*:*:*:ruby:*:*", ""),
expected: []vulnerability.Vulnerability{
{
Constraint: version.MustGetConstraint("< 3.7.4", version.UnknownFormat),
ID: "CVE-2014-fake-4",
CPEs: []cpe.CPE{
cpe.Must("cpe:2.3:*:activerecord:activerecord:*:*:something:*:*:ruby:*:*"),
cpe.Must("cpe:2.3:*:activerecord:activerecord:*:*:something:*:*:ruby:*:*", ""),
},
Namespace: "nvd:cpe",
PackageQualifiers: []qualifier.Qualifier{},
@ -116,13 +116,13 @@ func Test_GetByCPE(t *testing.T) {
},
{
name: "match from vendor & name",
cpe: cpe.Must("cpe:2.3:*:activerecord:activerecord:*:*:*:*:*:*:*:*"),
cpe: cpe.Must("cpe:2.3:*:activerecord:activerecord:*:*:*:*:*:*:*:*", ""),
expected: []vulnerability.Vulnerability{
{
Constraint: version.MustGetConstraint("< 3.7.6", version.UnknownFormat),
ID: "CVE-2014-fake-3",
CPEs: []cpe.CPE{
cpe.Must("cpe:2.3:*:activerecord:activerecord:*:*:*:*:*:rails:*:*"),
cpe.Must("cpe:2.3:*:activerecord:activerecord:*:*:*:*:*:rails:*:*", ""),
},
Namespace: "nvd:cpe",
PackageQualifiers: []qualifier.Qualifier{},
@ -132,7 +132,7 @@ func Test_GetByCPE(t *testing.T) {
Constraint: version.MustGetConstraint("< 3.7.4", version.UnknownFormat),
ID: "CVE-2014-fake-4",
CPEs: []cpe.CPE{
cpe.Must("cpe:2.3:*:activerecord:activerecord:*:*:something:*:*:ruby:*:*"),
cpe.Must("cpe:2.3:*:activerecord:activerecord:*:*:something:*:*:ruby:*:*", ""),
},
Namespace: "nvd:cpe",
PackageQualifiers: []qualifier.Qualifier{},
@ -143,7 +143,7 @@ func Test_GetByCPE(t *testing.T) {
{
name: "dont allow any name",
cpe: cpe.Must("cpe:2.3:*:couldntgetthisrightcouldyou:*:*:*:*:*:*:*:*:*"),
cpe: cpe.Must("cpe:2.3:*:couldntgetthisrightcouldyou:*:*:*:*:*:*:*:*:*", ""),
err: true,
},
}

View file

@ -82,7 +82,7 @@ func TestSecDBOnlyMatch(t *testing.T) {
Version: "0.9.9",
Type: syftPkg.ApkPkg,
CPEs: []cpe.CPE{
cpe.Must("cpe:2.3:a:*:libvncserver:0.9.9:*:*:*:*:*:*:*"),
cpe.Must("cpe:2.3:a:*:libvncserver:0.9.9:*:*:*:*:*:*:*", ""),
},
}
@ -168,7 +168,7 @@ func TestBothSecdbAndNvdMatches(t *testing.T) {
Version: "0.9.9",
Type: syftPkg.ApkPkg,
CPEs: []cpe.CPE{
cpe.Must("cpe:2.3:a:*:libvncserver:0.9.9:*:*:*:*:*:*:*"),
cpe.Must("cpe:2.3:a:*:libvncserver:0.9.9:*:*:*:*:*:*:*", ""),
},
}
@ -256,7 +256,7 @@ func TestBothSecdbAndNvdMatches_DifferentPackageName(t *testing.T) {
Type: syftPkg.ApkPkg,
CPEs: []cpe.CPE{
// Note: the product name is NOT the same as the package name
cpe.Must("cpe:2.3:a:*:libvncumbrellaproject:0.9.9:*:*:*:*:*:*:*"),
cpe.Must("cpe:2.3:a:*:libvncumbrellaproject:0.9.9:*:*:*:*:*:*:*", ""),
},
}
@ -330,13 +330,13 @@ func TestNvdOnlyMatches(t *testing.T) {
Version: "0.9.9",
Type: syftPkg.ApkPkg,
CPEs: []cpe.CPE{
cpe.Must("cpe:2.3:a:*:libvncserver:0.9.9:*:*:*:*:*:*:*"),
cpe.Must("cpe:2.3:a:*:libvncserver:0.9.9:*:*:*:*:*:*:*", ""),
},
}
vulnFound, err := vulnerability.NewVulnerability(nvdVuln)
assert.NoError(t, err)
vulnFound.CPEs = []cpe.CPE{cpe.Must(nvdVuln.CPEs[0])}
vulnFound.CPEs = []cpe.CPE{cpe.Must(nvdVuln.CPEs[0], "")}
expected := []match.Match{
{
@ -356,7 +356,7 @@ func TestNvdOnlyMatches(t *testing.T) {
},
},
Found: search.CPEResult{
CPEs: []string{vulnFound.CPEs[0].BindToFmtString()},
CPEs: []string{vulnFound.CPEs[0].Attributes.BindToFmtString()},
VersionConstraint: vulnFound.Constraint.String(),
VulnerabilityID: "CVE-2020-1",
},
@ -409,13 +409,13 @@ func TestNvdMatchesProperVersionFiltering(t *testing.T) {
Version: "0.9.11-r10",
Type: syftPkg.ApkPkg,
CPEs: []cpe.CPE{
cpe.Must("cpe:2.3:a:*:libvncserver:0.9.11:*:*:*:*:*:*:*"),
cpe.Must("cpe:2.3:a:*:libvncserver:0.9.11:*:*:*:*:*:*:*", ""),
},
}
vulnFound, err := vulnerability.NewVulnerability(nvdVulnMatch)
assert.NoError(t, err)
vulnFound.CPEs = []cpe.CPE{cpe.Must(nvdVulnMatch.CPEs[0])}
vulnFound.CPEs = []cpe.CPE{cpe.Must(nvdVulnMatch.CPEs[0], "")}
expected := []match.Match{
{
@ -435,7 +435,7 @@ func TestNvdMatchesProperVersionFiltering(t *testing.T) {
},
},
Found: search.CPEResult{
CPEs: []string{vulnFound.CPEs[0].BindToFmtString()},
CPEs: []string{vulnFound.CPEs[0].Attributes.BindToFmtString()},
VersionConstraint: vulnFound.Constraint.String(),
VulnerabilityID: "CVE-2020-1",
},
@ -491,7 +491,7 @@ func TestNvdMatchesWithSecDBFix(t *testing.T) {
Version: "0.9.11",
Type: syftPkg.ApkPkg,
CPEs: []cpe.CPE{
cpe.Must("cpe:2.3:a:*:libvncserver:0.9.9:*:*:*:*:*:*:*"),
cpe.Must("cpe:2.3:a:*:libvncserver:0.9.9:*:*:*:*:*:*:*", ""),
},
}
@ -544,7 +544,7 @@ func TestNvdMatchesNoConstraintWithSecDBFix(t *testing.T) {
Version: "0.9.11",
Type: syftPkg.ApkPkg,
CPEs: []cpe.CPE{
cpe.Must("cpe:2.3:a:*:libvncserver:0.9.9:*:*:*:*:*:*:*"),
cpe.Must("cpe:2.3:a:*:libvncserver:0.9.9:*:*:*:*:*:*:*", ""),
},
}
@ -662,8 +662,8 @@ func TestNVDMatchBySourceIndirection(t *testing.T) {
Version: "1.3.2-r0",
Type: syftPkg.ApkPkg,
CPEs: []cpe.CPE{
cpe.Must("cpe:2.3:a:musl-utils:musl-utils:*:*:*:*:*:*:*:*"),
cpe.Must("cpe:2.3:a:musl-utils:musl-utils:*:*:*:*:*:*:*:*"),
cpe.Must("cpe:2.3:a:musl-utils:musl-utils:*:*:*:*:*:*:*:*", ""),
cpe.Must("cpe:2.3:a:musl-utils:musl-utils:*:*:*:*:*:*:*:*", ""),
},
Upstreams: []pkg.UpstreamPackage{
{
@ -674,7 +674,7 @@ func TestNVDMatchBySourceIndirection(t *testing.T) {
vulnFound, err := vulnerability.NewVulnerability(nvdVuln)
assert.NoError(t, err)
vulnFound.CPEs = []cpe.CPE{cpe.Must(nvdVuln.CPEs[0])}
vulnFound.CPEs = []cpe.CPE{cpe.Must(nvdVuln.CPEs[0], "")}
expected := []match.Match{
{
@ -693,7 +693,7 @@ func TestNVDMatchBySourceIndirection(t *testing.T) {
},
},
Found: search.CPEResult{
CPEs: []string{vulnFound.CPEs[0].BindToFmtString()},
CPEs: []string{vulnFound.CPEs[0].Attributes.BindToFmtString()},
VersionConstraint: vulnFound.Constraint.String(),
VulnerabilityID: "CVE-2020-1",
},

View file

@ -62,7 +62,7 @@ func TestMatcher_SearchForStdlib(t *testing.T) {
Type: syftPkg.GoModulePkg,
Language: syftPkg.Go,
CPEs: []cpe.CPE{
cpe.Must("cpe:2.3:a:golang:go:1.18.3:-:*:*:*:*:*:*"),
cpe.Must("cpe:2.3:a:golang:go:1.18.3:-:*:*:*:*:*:*", ""),
},
Metadata: pkg.GolangBinMetadata{},
}
@ -201,7 +201,7 @@ func (mp *mockProvider) populateData() {
}
func (mp *mockProvider) GetByCPE(p cpe.CPE) ([]vulnerability.Vulnerability, error) {
return mp.data["nvd:cpe"][p.BindToFmtString()], nil
return mp.data["nvd:cpe"][p.Attributes.BindToFmtString()], nil
}
func (mp *mockProvider) GetByDistro(d *distro.Distro, p pkg.Package) ([]vulnerability.Vulnerability, error) {

View file

@ -1,11 +1,14 @@
package pkg
import "github.com/anchore/syft/syft/pkg"
type GolangBinMetadata struct {
BuildSettings map[string]string `json:"goBuildSettings,omitempty"`
GoCompiledVersion string `json:"goCompiledVersion"`
Architecture string `json:"architecture"`
H1Digest string `json:"h1Digest,omitempty"`
MainModule string `json:"mainModule,omitempty"`
BuildSettings pkg.KeyValues `json:"goBuildSettings,omitempty" cyclonedx:"goBuildSettings"`
GoCompiledVersion string `json:"goCompiledVersion" cyclonedx:"goCompiledVersion"`
Architecture string `json:"architecture" cyclonedx:"architecture"`
H1Digest string `json:"h1Digest,omitempty" cyclonedx:"h1Digest"`
MainModule string `json:"mainModule,omitempty" cyclonedx:"mainModule"`
GoCryptoSettings []string `json:"goCryptoSettings,omitempty" cyclonedx:"goCryptoSettings"`
}
type GolangModMetadata struct {

View file

@ -331,8 +331,10 @@ func javaDataFromPkg(p pkg.Package) (metadata *JavaMetadata) {
groupID = value.PomProperties.GroupID
}
if value.Manifest != nil {
if n, ok := value.Manifest.Main["Name"]; ok {
name = n
for _, kv := range value.Manifest.Main {
if kv.Key == "Name" {
name = kv.Value
}
}
}

View file

@ -171,12 +171,18 @@ func TestNew(t *testing.T) {
Metadata: syftPkg.JavaArchive{
VirtualPath: "virtual-path-info",
Manifest: &syftPkg.JavaManifest{
Main: map[string]string{
"Name": "main-section-name-info",
Main: syftPkg.KeyValues{
{
Key: "Name",
Value: "main-section-name-info",
},
},
NamedSections: map[string]map[string]string{
"named-section": {
"named-section-key": "named-section-value",
Sections: []syftPkg.KeyValues{
{
{
Key: "named-section-key",
Value: "named-section-value",
},
},
},
},
@ -288,14 +294,14 @@ func TestNew(t *testing.T) {
name: "golang-metadata",
syftPkg: syftPkg.Package{
Metadata: syftPkg.GolangBinaryBuildinfoEntry{
BuildSettings: map[string]string{},
BuildSettings: syftPkg.KeyValues{},
GoCompiledVersion: "1.0.0",
H1Digest: "a",
MainModule: "myMainModule",
},
},
metadata: GolangBinMetadata{
BuildSettings: map[string]string{},
BuildSettings: syftPkg.KeyValues{},
GoCompiledVersion: "1.0.0",
H1Digest: "a",
MainModule: "myMainModule",
@ -360,19 +366,34 @@ func TestNew(t *testing.T) {
},
},
{
name: "cpp conan lock metadata",
name: "cpp conan v1 lock metadata",
syftPkg: syftPkg.Package{
Metadata: syftPkg.ConanLockEntry{
Metadata: syftPkg.ConanV1LockEntry{
Ref: "zlib/1.2.12",
Options: map[string]string{
"fPIC": "True",
"shared": "False",
Options: syftPkg.KeyValues{
{
Key: "fPIC",
Value: "True",
},
{
Key: "shared",
Value: "false",
},
},
Path: "all/conanfile.py",
Context: "host",
},
},
},
{
name: "cpp conan v2 lock metadata",
syftPkg: syftPkg.Package{
Metadata: syftPkg.ConanV2LockEntry{
Ref: "zlib/1.2.12",
PackageID: "some-id",
},
},
},
{
name: "cocoapods cocoapods-metadata",
syftPkg: syftPkg.Package{
@ -579,6 +600,21 @@ func TestNew(t *testing.T) {
},
},
},
{
name: "python-poetry-lock-entry",
syftPkg: syftPkg.Package{
Metadata: syftPkg.PythonPoetryLockEntry{Index: "some-index"},
},
},
{
name: "yarn-lock-entry",
syftPkg: syftPkg.Package{
Metadata: syftPkg.YarnLockEntry{
Resolved: "some-resolution",
Integrity: "some-digest",
},
},
},
}
// capture each observed metadata type, we should see all of them relate to what syft provides by the end of testing

View file

@ -17,9 +17,10 @@ func Provide(userInput string, config ProviderConfig) ([]Package, Context, *sbom
packages, ctx, s, err := syftSBOMProvider(userInput, config)
if !errors.Is(err, errDoesNotProvide) {
if len(config.Exclusions) > 0 {
packages, err = filterPackageExclusions(packages, config.Exclusions)
if err != nil {
return nil, ctx, s, err
var exclusionsErr error
packages, exclusionsErr = filterPackageExclusions(packages, config.Exclusions)
if exclusionsErr != nil {
return nil, ctx, s, exclusionsErr
}
}
return packages, ctx, s, err

View file

@ -16,6 +16,7 @@ func TestProviderLocationExcludes(t *testing.T) {
fixture string
excludes []string
expected []string
wantErr assert.ErrorAssertionFunc
}{
{
name: "exclude everything",
@ -41,6 +42,12 @@ func TestProviderLocationExcludes(t *testing.T) {
excludes: []string{},
expected: []string{"charsets", "tomcat-embed-el"},
},
{
name: "exclusions must not hide parsing error",
fixture: "test-fixtures/bad-sbom.json",
excludes: []string{"**/some-glob/*"},
wantErr: assert.Error,
},
}
for _, test := range tests {
@ -51,7 +58,14 @@ func TestProviderLocationExcludes(t *testing.T) {
SBOMOptions: syft.DefaultCreateSBOMConfig(),
},
}
pkgs, _, _, _ := Provide(test.fixture, cfg)
if test.wantErr == nil {
test.wantErr = assert.NoError
}
pkgs, _, _, err := Provide(test.fixture, cfg)
test.wantErr(t, err)
if err != nil {
return
}
var pkgNames []string

View file

@ -58,7 +58,7 @@ func decodePurlFile(reader io.Reader) ([]Package, error) {
if qualifier.Key == cpesQualifierKey {
rawCpes := strings.Split(qualifier.Value, ",")
for _, rawCpe := range rawCpes {
c, err := cpe.New(rawCpe)
c, err := cpe.New(rawCpe, "")
if err != nil {
return nil, fmt.Errorf("unable to decode cpe %s in purl %s: %w", rawCpe, rawLine, err)
}

View file

@ -18,15 +18,15 @@ func New(cpe string) qualifier.Qualifier {
}
func isWindowsPlatformCPE(c cpe.CPE) bool {
return c.Vendor == "microsoft" && strings.HasPrefix(c.Product, "windows")
return c.Attributes.Vendor == "microsoft" && strings.HasPrefix(c.Attributes.Product, "windows")
}
func isUbuntuPlatformCPE(c cpe.CPE) bool {
if c.Vendor == "canonical" && c.Product == "ubuntu_linux" {
if c.Attributes.Vendor == "canonical" && c.Attributes.Product == "ubuntu_linux" {
return true
}
if c.Vendor == "ubuntu" {
if c.Attributes.Vendor == "ubuntu" {
return true
}
@ -34,11 +34,11 @@ func isUbuntuPlatformCPE(c cpe.CPE) bool {
}
func isDebianPlatformCPE(c cpe.CPE) bool {
return c.Vendor == "debian" && (c.Product == "debian_linux" || c.Product == "linux")
return c.Attributes.Vendor == "debian" && (c.Attributes.Product == "debian_linux" || c.Attributes.Product == "linux")
}
func isWordpressPlatformCPE(c cpe.CPE) bool {
return c.Vendor == "wordpress" && c.Product == "wordpress"
return c.Attributes.Vendor == "wordpress" && c.Attributes.Product == "wordpress"
}
func (p platformCPE) Satisfied(d *distro.Distro, _ pkg.Package) (bool, error) {
@ -46,7 +46,7 @@ func (p platformCPE) Satisfied(d *distro.Distro, _ pkg.Package) (bool, error) {
return true, nil
}
c, err := cpe.New(p.cpe)
c, err := cpe.New(p.cpe, "")
if err != nil {
return true, err

View file

@ -39,7 +39,7 @@ func TestParseSyftJSON(t *testing.T) {
},
Type: "apk",
CPEs: []cpe.CPE{
cpe.Must("cpe:2.3:a:alpine:alpine_baselayout:3.2.0-r6:*:*:*:*:*:*:*"),
cpe.Must("cpe:2.3:a:alpine:alpine_baselayout:3.2.0-r6:*:*:*:*:*:*:*", ""),
},
PURL: "pkg:alpine/alpine-baselayout@3.2.0-r6?arch=x86_64",
Upstreams: []UpstreamPackage{
@ -164,8 +164,8 @@ func TestParseSyftJSON(t *testing.T) {
},
Type: "dpkg",
CPEs: []cpe.CPE{
cpe.Must("cpe:2.3:a:*:fake:1.2.0:*:*:*:*:*:*:*"),
cpe.Must("cpe:2.3:a:fake:fake:1.2.0:*:*:*:*:*:*:*"),
cpe.Must("cpe:2.3:a:*:fake:1.2.0:*:*:*:*:*:*:*", ""),
cpe.Must("cpe:2.3:a:fake:fake:1.2.0:*:*:*:*:*:*:*", ""),
},
PURL: "pkg:deb/debian/fake@1.2.0?arch=x86_64",
Upstreams: []UpstreamPackage{
@ -190,8 +190,8 @@ func TestParseSyftJSON(t *testing.T) {
},
Type: "java-archive",
CPEs: []cpe.CPE{
cpe.Must("cpe:2.3:a:*:gmp:6.2.0-r0:*:*:*:*:*:*:*"),
cpe.Must("cpe:2.3:a:gmp:gmp:6.2.0-r0:*:*:*:*:*:*:*"),
cpe.Must("cpe:2.3:a:*:gmp:6.2.0-r0:*:*:*:*:*:*:*", ""),
cpe.Must("cpe:2.3:a:gmp:gmp:6.2.0-r0:*:*:*:*:*:*:*", ""),
},
PURL: "pkg:alpine/gmp@6.2.0-r0?arch=x86_64",
Metadata: JavaMetadata{
@ -292,8 +292,8 @@ var springImageTestCase = struct {
Licenses: []string{},
Type: "java-archive",
CPEs: []cpe.CPE{
cpe.Must("cpe:2.3:a:charsets:charsets:*:*:*:*:*:java:*:*"),
cpe.Must("cpe:2.3:a:charsets:charsets:*:*:*:*:*:maven:*:*"),
cpe.Must("cpe:2.3:a:charsets:charsets:*:*:*:*:*:java:*:*", ""),
cpe.Must("cpe:2.3:a:charsets:charsets:*:*:*:*:*:maven:*:*", ""),
},
PURL: "",
Metadata: JavaMetadata{VirtualPath: "/usr/lib/jvm/java-8-openjdk-amd64/jre/lib/charsets.jar"},
@ -311,8 +311,8 @@ var springImageTestCase = struct {
Licenses: []string{},
Type: "java-archive",
CPEs: []cpe.CPE{
cpe.Must("cpe:2.3:a:tomcat_embed_el:tomcat-embed-el:9.0.27:*:*:*:*:java:*:*"),
cpe.Must("cpe:2.3:a:tomcat-embed-el:tomcat_embed_el:9.0.27:*:*:*:*:maven:*:*"),
cpe.Must("cpe:2.3:a:tomcat_embed_el:tomcat-embed-el:9.0.27:*:*:*:*:java:*:*", ""),
cpe.Must("cpe:2.3:a:tomcat-embed-el:tomcat_embed_el:9.0.27:*:*:*:*:maven:*:*", ""),
},
PURL: "",
Metadata: JavaMetadata{VirtualPath: "/app/libs/tomcat-embed-el-9.0.27.jar"},

View file

@ -0,0 +1 @@
{}

View file

@ -32,10 +32,10 @@ func UpstreamPackages(p Package) (pkgs []Package) {
cpeStrings := strset.New()
for _, c := range tmp.CPEs {
if u.Version != "" {
c.Version = u.Version
c.Attributes.Version = u.Version
}
updatedCPEString := strings.ReplaceAll(c.BindToFmtString(), p.Name, u.Name)
updatedCPEString := strings.ReplaceAll(c.Attributes.BindToFmtString(), p.Name, u.Name)
cpeStrings.Add(updatedCPEString)
}
@ -43,7 +43,7 @@ func UpstreamPackages(p Package) (pkgs []Package) {
// with each entry in set, convert string to CPE and update the new CPEs
var updatedCPEs []cpe.CPE
for _, cpeString := range cpeStrings.List() {
updatedCPE, _ := cpe.New(cpeString)
updatedCPE, _ := cpe.New(cpeString, "")
updatedCPEs = append(updatedCPEs, updatedCPE)
}
tmp.CPEs = updatedCPEs

View file

@ -28,7 +28,7 @@ func TestUpstreamPackages(t *testing.T) {
Name: "name",
Version: "version",
CPEs: []cpe.CPE{
cpe.Must("cpe:2.3:*:name:name:version:*:*:*:*:*:*:*"),
cpe.Must("cpe:2.3:*:name:name:version:*:*:*:*:*:*:*", ""),
},
Upstreams: []UpstreamPackage{
{
@ -42,7 +42,7 @@ func TestUpstreamPackages(t *testing.T) {
Version: "version", // original
CPEs: []cpe.CPE{
// name and vendor replaced
cpe.Must("cpe:2.3:*:new-name:new-name:version:*:*:*:*:*:*:*"),
cpe.Must("cpe:2.3:*:new-name:new-name:version:*:*:*:*:*:*:*", ""),
},
// no upstreams
},
@ -54,7 +54,7 @@ func TestUpstreamPackages(t *testing.T) {
Name: "name",
Version: "version",
CPEs: []cpe.CPE{
cpe.Must("cpe:2.3:*:name:name:version:*:*:*:*:*:*:*"),
cpe.Must("cpe:2.3:*:name:name:version:*:*:*:*:*:*:*", ""),
},
Upstreams: []UpstreamPackage{
{
@ -69,7 +69,7 @@ func TestUpstreamPackages(t *testing.T) {
Version: "new-version", // new
CPEs: []cpe.CPE{
// name, vendor, and version replaced
cpe.Must("cpe:2.3:*:new-name:new-name:new-version:*:*:*:*:*:*:*"),
cpe.Must("cpe:2.3:*:new-name:new-name:new-version:*:*:*:*:*:*:*", ""),
},
// no upstreams
},
@ -81,7 +81,7 @@ func TestUpstreamPackages(t *testing.T) {
Name: "name",
Version: "version",
CPEs: []cpe.CPE{
cpe.Must("cpe:2.3:*:name:name:version:*:*:*:*:*:*:*"),
cpe.Must("cpe:2.3:*:name:name:version:*:*:*:*:*:*:*", ""),
},
Upstreams: []UpstreamPackage{
{

View file

@ -230,11 +230,13 @@ func generatePackages(t *testing.T) []syftPkg.Package {
Locations: file.NewLocationSet(file.NewVirtualLocation("/foo/bar/somefile-1.txt", "somefile-1.txt")),
CPEs: []cpe.CPE{
{
Part: "a",
Vendor: "anchore",
Product: "engine",
Version: "0.9.2",
Language: "python",
Attributes: cpe.Attributes{
Part: "a",
Vendor: "anchore",
Product: "engine",
Version: "0.9.2",
Language: "python",
},
},
},
Metadata: syftPkg.RpmDBEntry{
@ -249,11 +251,13 @@ func generatePackages(t *testing.T) []syftPkg.Package {
Locations: file.NewLocationSet(file.NewVirtualLocation("/foo/bar/somefile-2.txt", "somefile-2.txt")),
CPEs: []cpe.CPE{
{
Part: "a",
Vendor: "anchore",
Product: "engine",
Version: "2.2.2",
Language: "python",
Attributes: cpe.Attributes{
Part: "a",
Vendor: "anchore",
Product: "engine",
Version: "2.2.2",
Language: "python",
},
},
},
Licenses: syftPkg.NewLicenseSet(

View file

@ -31,7 +31,7 @@ type UpstreamPackage struct {
func newPackage(p pkg.Package) Package {
var cpes = make([]string, 0)
for _, c := range p.CPEs {
cpes = append(cpes, c.BindToFmtString())
cpes = append(cpes, c.Attributes.BindToFmtString())
}
licenses := p.Licenses

View file

@ -88,7 +88,7 @@ func ByPackageCPE(store vulnerability.ProviderByCPE, d *distro.Distro, p pkg.Pac
matchesByFingerprint := make(map[match.Fingerprint]match.Match)
for _, c := range p.CPEs {
// prefer the CPE version, but if npt specified use the package version
searchVersion := c.Version
searchVersion := c.Attributes.Version
if p.Type == syftPkg.ApkPkg {
searchVersion = alpineCPEComparableVersion(searchVersion)
@ -151,7 +151,7 @@ func addNewMatch(matchesByFingerprint map[match.Fingerprint]match.Match, vuln vu
SearchedBy: CPEParameters{
Namespace: vuln.Namespace,
CPEs: []string{
searchedByCPE.BindToFmtString(),
searchedByCPE.Attributes.BindToFmtString(),
},
Package: CPEPackageParameter{
Name: p.Name,
@ -210,12 +210,12 @@ func addMatchDetails(existingDetails []match.Detail, newDetails match.Detail) []
func filterCPEsByVersion(pkgVersion version.Version, allCPEs []cpe.CPE) (matchedCPEs []cpe.CPE) {
for _, c := range allCPEs {
if c.Version == wfn.Any || c.Version == wfn.NA {
if c.Attributes.Version == wfn.Any || c.Attributes.Version == wfn.NA {
matchedCPEs = append(matchedCPEs, c)
continue
}
constraint, err := version.GetConstraint(c.Version, version.UnknownFormat)
constraint, err := version.GetConstraint(c.Attributes.Version, version.UnknownFormat)
if err != nil {
// if we can't get a version constraint, don't filter out the CPE
matchedCPEs = append(matchedCPEs, c)
@ -244,7 +244,7 @@ func toMatches(matchesByFingerprint map[match.Fingerprint]match.Match) (matches
func cpesToString(cpes []cpe.CPE) []string {
var strs = make([]string, len(cpes))
for idx, c := range cpes {
strs[idx] = c.BindToFmtString()
strs[idx] = c.Attributes.BindToFmtString()
}
sort.Strings(strs)
return strs

View file

@ -166,8 +166,8 @@ func TestFindMatchesByPackageCPE(t *testing.T) {
name: "match from range",
p: pkg.Package{
CPEs: []cpe.CPE{
cpe.Must("cpe:2.3:*:activerecord:activerecord:3.7.5:rando1:*:ra:*:ruby:*:*"),
cpe.Must("cpe:2.3:*:activerecord:activerecord:3.7.5:rando4:*:re:*:rails:*:*"),
cpe.Must("cpe:2.3:*:activerecord:activerecord:3.7.5:rando1:*:ra:*:ruby:*:*", ""),
cpe.Must("cpe:2.3:*:activerecord:activerecord:3.7.5:rando4:*:re:*:rails:*:*", ""),
},
Name: "activerecord",
Version: "3.7.5",
@ -182,8 +182,8 @@ func TestFindMatchesByPackageCPE(t *testing.T) {
},
Package: pkg.Package{
CPEs: []cpe.CPE{
cpe.Must("cpe:2.3:*:activerecord:activerecord:3.7.5:rando1:*:ra:*:ruby:*:*"),
cpe.Must("cpe:2.3:*:activerecord:activerecord:3.7.5:rando4:*:re:*:rails:*:*"),
cpe.Must("cpe:2.3:*:activerecord:activerecord:3.7.5:rando1:*:ra:*:ruby:*:*", ""),
cpe.Must("cpe:2.3:*:activerecord:activerecord:3.7.5:rando4:*:re:*:rails:*:*", ""),
},
Name: "activerecord",
Version: "3.7.5",
@ -217,8 +217,8 @@ func TestFindMatchesByPackageCPE(t *testing.T) {
name: "multiple matches",
p: pkg.Package{
CPEs: []cpe.CPE{
cpe.Must("cpe:2.3:*:activerecord:activerecord:3.7.3:rando1:*:ra:*:ruby:*:*"),
cpe.Must("cpe:2.3:*:activerecord:activerecord:3.7.3:rando4:*:re:*:rails:*:*"),
cpe.Must("cpe:2.3:*:activerecord:activerecord:3.7.3:rando1:*:ra:*:ruby:*:*", ""),
cpe.Must("cpe:2.3:*:activerecord:activerecord:3.7.3:rando4:*:re:*:rails:*:*", ""),
},
Name: "activerecord",
Version: "3.7.3",
@ -233,8 +233,8 @@ func TestFindMatchesByPackageCPE(t *testing.T) {
},
Package: pkg.Package{
CPEs: []cpe.CPE{
cpe.Must("cpe:2.3:*:activerecord:activerecord:3.7.3:rando1:*:ra:*:ruby:*:*"),
cpe.Must("cpe:2.3:*:activerecord:activerecord:3.7.3:rando4:*:re:*:rails:*:*"),
cpe.Must("cpe:2.3:*:activerecord:activerecord:3.7.3:rando1:*:ra:*:ruby:*:*", ""),
cpe.Must("cpe:2.3:*:activerecord:activerecord:3.7.3:rando4:*:re:*:rails:*:*", ""),
},
Name: "activerecord",
Version: "3.7.3",
@ -272,8 +272,8 @@ func TestFindMatchesByPackageCPE(t *testing.T) {
},
Package: pkg.Package{
CPEs: []cpe.CPE{
cpe.Must("cpe:2.3:*:activerecord:activerecord:3.7.3:rando1:*:ra:*:ruby:*:*"),
cpe.Must("cpe:2.3:*:activerecord:activerecord:3.7.3:rando4:*:re:*:rails:*:*"),
cpe.Must("cpe:2.3:*:activerecord:activerecord:3.7.3:rando1:*:ra:*:ruby:*:*", ""),
cpe.Must("cpe:2.3:*:activerecord:activerecord:3.7.3:rando4:*:re:*:rails:*:*", ""),
},
Name: "activerecord",
Version: "3.7.3",
@ -308,7 +308,7 @@ func TestFindMatchesByPackageCPE(t *testing.T) {
name: "exact match",
p: pkg.Package{
CPEs: []cpe.CPE{
cpe.Must("cpe:2.3:*:*:activerecord:4.0.1:*:*:*:*:*:*:*"),
cpe.Must("cpe:2.3:*:*:activerecord:4.0.1:*:*:*:*:*:*:*", ""),
},
Name: "activerecord",
Version: "4.0.1",
@ -323,7 +323,7 @@ func TestFindMatchesByPackageCPE(t *testing.T) {
},
Package: pkg.Package{
CPEs: []cpe.CPE{
cpe.Must("cpe:2.3:*:*:activerecord:4.0.1:*:*:*:*:*:*:*"),
cpe.Must("cpe:2.3:*:*:activerecord:4.0.1:*:*:*:*:*:*:*", ""),
},
Name: "activerecord",
Version: "4.0.1",
@ -368,7 +368,7 @@ func TestFindMatchesByPackageCPE(t *testing.T) {
name: "fuzzy version match",
p: pkg.Package{
CPEs: []cpe.CPE{
cpe.Must("cpe:2.3:*:awesome:awesome:98SE1:rando1:*:ra:*:dunno:*:*"),
cpe.Must("cpe:2.3:*:awesome:awesome:98SE1:rando1:*:ra:*:dunno:*:*", ""),
},
Name: "awesome",
Version: "98SE1",
@ -381,7 +381,7 @@ func TestFindMatchesByPackageCPE(t *testing.T) {
},
Package: pkg.Package{
CPEs: []cpe.CPE{
cpe.Must("cpe:2.3:*:awesome:awesome:98SE1:rando1:*:ra:*:dunno:*:*"),
cpe.Must("cpe:2.3:*:awesome:awesome:98SE1:rando1:*:ra:*:dunno:*:*", ""),
},
Name: "awesome",
Version: "98SE1",
@ -414,7 +414,7 @@ func TestFindMatchesByPackageCPE(t *testing.T) {
name: "multiple matched CPEs",
p: pkg.Package{
CPEs: []cpe.CPE{
cpe.Must("cpe:2.3:*:multiple:multiple:1.0:*:*:*:*:*:*:*"),
cpe.Must("cpe:2.3:*:multiple:multiple:1.0:*:*:*:*:*:*:*", ""),
},
Name: "multiple",
Version: "1.0",
@ -429,7 +429,7 @@ func TestFindMatchesByPackageCPE(t *testing.T) {
},
Package: pkg.Package{
CPEs: []cpe.CPE{
cpe.Must("cpe:2.3:*:multiple:multiple:1.0:*:*:*:*:*:*:*"),
cpe.Must("cpe:2.3:*:multiple:multiple:1.0:*:*:*:*:*:*:*", ""),
},
Name: "multiple",
Version: "1.0",
@ -467,7 +467,7 @@ func TestFindMatchesByPackageCPE(t *testing.T) {
name: "filtered out match due to target_sw mismatch",
p: pkg.Package{
CPEs: []cpe.CPE{
cpe.Must("cpe:2.3:*:funfun:funfun:*:*:*:*:*:*:*:*"),
cpe.Must("cpe:2.3:*:funfun:funfun:*:*:*:*:*:*:*:*", ""),
},
Name: "funfun",
Version: "5.2.1",
@ -480,7 +480,7 @@ func TestFindMatchesByPackageCPE(t *testing.T) {
name: "target_sw mismatch with unsupported target_sw",
p: pkg.Package{
CPEs: []cpe.CPE{
cpe.Must("cpe:2.3:*:sw:sw:*:*:*:*:*:*:*:*"),
cpe.Must("cpe:2.3:*:sw:sw:*:*:*:*:*:*:*:*", ""),
},
Name: "sw",
Version: "0.1",
@ -494,7 +494,7 @@ func TestFindMatchesByPackageCPE(t *testing.T) {
},
Package: pkg.Package{
CPEs: []cpe.CPE{
cpe.Must("cpe:2.3:*:sw:sw:*:*:*:*:*:*:*:*"),
cpe.Must("cpe:2.3:*:sw:sw:*:*:*:*:*:*:*:*", ""),
},
Name: "sw",
Version: "0.1",
@ -530,10 +530,10 @@ func TestFindMatchesByPackageCPE(t *testing.T) {
name: "match included even though multiple cpes are mismatch",
p: pkg.Package{
CPEs: []cpe.CPE{
cpe.Must("cpe:2.3:*:funfun:funfun:*:*:*:*:*:rust:*:*"),
cpe.Must("cpe:2.3:*:funfun:funfun:*:*:*:*:*:rails:*:*"),
cpe.Must("cpe:2.3:*:funfun:funfun:*:*:*:*:*:ruby:*:*"),
cpe.Must("cpe:2.3:*:funfun:funfun:*:*:*:*:*:python:*:*"),
cpe.Must("cpe:2.3:*:funfun:funfun:*:*:*:*:*:rust:*:*", ""),
cpe.Must("cpe:2.3:*:funfun:funfun:*:*:*:*:*:rails:*:*", ""),
cpe.Must("cpe:2.3:*:funfun:funfun:*:*:*:*:*:ruby:*:*", ""),
cpe.Must("cpe:2.3:*:funfun:funfun:*:*:*:*:*:python:*:*", ""),
},
Name: "funfun",
Version: "5.2.1",
@ -547,10 +547,10 @@ func TestFindMatchesByPackageCPE(t *testing.T) {
},
Package: pkg.Package{
CPEs: []cpe.CPE{
cpe.Must("cpe:2.3:*:funfun:funfun:*:*:*:*:*:rust:*:*"),
cpe.Must("cpe:2.3:*:funfun:funfun:*:*:*:*:*:rails:*:*"),
cpe.Must("cpe:2.3:*:funfun:funfun:*:*:*:*:*:ruby:*:*"),
cpe.Must("cpe:2.3:*:funfun:funfun:*:*:*:*:*:python:*:*"),
cpe.Must("cpe:2.3:*:funfun:funfun:*:*:*:*:*:rust:*:*", ""),
cpe.Must("cpe:2.3:*:funfun:funfun:*:*:*:*:*:rails:*:*", ""),
cpe.Must("cpe:2.3:*:funfun:funfun:*:*:*:*:*:ruby:*:*", ""),
cpe.Must("cpe:2.3:*:funfun:funfun:*:*:*:*:*:python:*:*", ""),
},
Name: "funfun",
Version: "5.2.1",
@ -587,7 +587,7 @@ func TestFindMatchesByPackageCPE(t *testing.T) {
name: "Ensure target_sw mismatch does not apply to java packages",
p: pkg.Package{
CPEs: []cpe.CPE{
cpe.Must("cpe:2.3:a:handlebarsjs:handlebars:*:*:*:*:*:*:*:*"),
cpe.Must("cpe:2.3:a:handlebarsjs:handlebars:*:*:*:*:*:*:*:*", ""),
},
Name: "handlebars",
Version: "0.1",
@ -601,7 +601,7 @@ func TestFindMatchesByPackageCPE(t *testing.T) {
},
Package: pkg.Package{
CPEs: []cpe.CPE{
cpe.Must("cpe:2.3:a:handlebarsjs:handlebars:*:*:*:*:*:*:*:*"),
cpe.Must("cpe:2.3:a:handlebarsjs:handlebars:*:*:*:*:*:*:*:*", ""),
},
Name: "handlebars",
Version: "0.1",
@ -637,7 +637,7 @@ func TestFindMatchesByPackageCPE(t *testing.T) {
name: "Ensure target_sw mismatch does not apply to java jenkins plugins packages",
p: pkg.Package{
CPEs: []cpe.CPE{
cpe.Must("cpe:2.3:a:handlebarsjs:handlebars:*:*:*:*:*:*:*:*"),
cpe.Must("cpe:2.3:a:handlebarsjs:handlebars:*:*:*:*:*:*:*:*", ""),
},
Name: "handlebars",
Version: "0.1",
@ -651,7 +651,7 @@ func TestFindMatchesByPackageCPE(t *testing.T) {
},
Package: pkg.Package{
CPEs: []cpe.CPE{
cpe.Must("cpe:2.3:a:handlebarsjs:handlebars:*:*:*:*:*:*:*:*"),
cpe.Must("cpe:2.3:a:handlebarsjs:handlebars:*:*:*:*:*:*:*:*", ""),
},
Name: "handlebars",
Version: "0.1",
@ -728,7 +728,7 @@ func TestFilterCPEsByVersion(t *testing.T) {
// format strings to CPE objects...
vulnerabilityCPEs := make([]cpe.CPE, len(test.vulnerabilityCPEs))
for idx, c := range test.vulnerabilityCPEs {
vulnerabilityCPEs[idx] = cpe.Must(c)
vulnerabilityCPEs[idx] = cpe.Must(c, "")
}
versionObj, err := version.NewVersion(test.version, version.UnknownFormat)
@ -742,7 +742,7 @@ func TestFilterCPEsByVersion(t *testing.T) {
// format CPE objects to string...
actualStrs := make([]string, len(actual))
for idx, a := range actual {
actualStrs[idx] = a.BindToFmtString()
actualStrs[idx] = a.Attributes.BindToFmtString()
}
assert.ElementsMatch(t, test.expected, actualStrs)

View file

@ -55,7 +55,7 @@ func onlyVulnerableTargets(p pkg.Package, allVulns []vulnerability.Vulnerability
for _, vuln := range allVulns {
isPackageVulnerable := len(vuln.CPEs) == 0
for _, cpe := range vuln.CPEs {
targetSW := cpe.TargetSW
targetSW := cpe.Attributes.TargetSW
mismatchWithUnknownLanguage := targetSW != string(p.Language) && isUnknownTarget(targetSW)
if targetSW == wfn.Any || targetSW == wfn.NA || targetSW == string(p.Language) || mismatchWithUnknownLanguage {
isPackageVulnerable = true

View file

@ -305,7 +305,7 @@ func TestVulnerabilityMatcher_FindMatches(t *testing.T) {
}
mustCPE := func(c string) cpe.CPE {
cp, err := cpe.New(c)
cp, err := cpe.New(c, "")
if err != nil {
t.Fatal(err)
}

View file

@ -82,6 +82,7 @@ func TestCompareSBOMInputToLibResults(t *testing.T) {
string(syftPkg.SwiftPkg),
string(syftPkg.GithubActionPkg),
string(syftPkg.GithubActionWorkflowPkg),
string(syftPkg.ErlangOTPPkg),
)
observedPkgTypes := strset.New()
testCases := []struct {

View file

@ -779,10 +779,12 @@ func testIgnoredMatches() []match.IgnoredMatch {
Type: "apk",
CPEs: []cpe.CPE{
{
Part: "a",
Vendor: "libvncserver",
Product: "libvncserver",
Version: "0.9.9",
Attributes: cpe.Attributes{
Part: "a",
Vendor: "libvncserver",
Product: "libvncserver",
Version: "0.9.9",
},
},
},
PURL: "pkg:apk/alpine/libvncserver@0.9.9?arch=x86_64&distro=alpine-3.12.0",