Projects STRLCPY syft Commits e2ebc976
🤬
  • fix: remove APK OriginPackage cpe candidates (#1637)

    Adding APK OriginPackage CPE candidates to the child package
    results in false positives in grype because it can't associate
    CPE-based findings to the corresponding OriginPackage APK fixes.
    
    This reverts changing the `upstream` in the PURL for APK packages
    as the logic in Grype that uses it expects it to be an APK package
    name.  This also allows refactoring to unexport and move the APK
    CPE candidate generation logic closer to where CPE generation occurs
    
    Signed-off-by: Weston Steimel <[email protected]>
  • Loading...
  • Weston Steimel committed with GitHub 1 year ago
    e2ebc976
    1 parent 2e6e3b0c
Revision indexing in progress... (symbol navigation in revisions will be accurate after indexed)
  • ■ ■ ■ ■ ■
    syft/pkg/apk_metadata.go
    skipped 3 lines
    4 4   "encoding/json"
    5 5   "fmt"
    6 6   "reflect"
    7  - "regexp"
    8 7   "sort"
    9 8   "strings"
    10 9   
    11 10   "github.com/mitchellh/mapstructure"
    12 11   "github.com/scylladb/go-set/strset"
    13 12   
    14  - "github.com/anchore/syft/internal"
    15 13   "github.com/anchore/syft/syft/file"
    16 14  )
    17 15   
    18 16  const ApkDBGlob = "**/lib/apk/db/installed"
    19 17   
    20  -var (
    21  - _ FileOwner = (*ApkMetadata)(nil)
    22  - prefixesToPackageType = map[string]Type{
    23  - "py-": PythonPkg,
    24  - "ruby-": GemPkg,
    25  - }
    26  - streamVersionPkgNamePattern = regexp.MustCompile(`^(?P<stream>[a-zA-Z][\w-]*?)(?P<streamVersion>\-?\d[\d\.]*?)($|-(?P<subPackage>[a-zA-Z][\w-]*?)?)$`)
    27  -)
     18 +var _ FileOwner = (*ApkMetadata)(nil)
    28 19   
    29 20  // ApkMetadata represents all captured data for a Alpine DB package entry.
    30 21  // See the following sources for more information:
    skipped 93 lines
    124 115   return result
    125 116  }
    126 117   
    127  -type UpstreamCandidate struct {
    128  - Name string
    129  - Type Type
    130  -}
    131  - 
    132  -func (m ApkMetadata) UpstreamCandidates() (candidates []UpstreamCandidate) {
    133  - name := m.Package
    134  - if m.OriginPackage != "" && m.OriginPackage != m.Package {
    135  - candidates = append(candidates, UpstreamCandidate{Name: m.OriginPackage, Type: ApkPkg})
    136  - }
    137  - 
    138  - groups := internal.MatchNamedCaptureGroups(streamVersionPkgNamePattern, m.Package)
    139  - stream, ok := groups["stream"]
    140  - 
    141  - if ok && stream != "" {
    142  - sub, ok := groups["subPackage"]
    143  - 
    144  - if ok && sub != "" {
    145  - name = fmt.Sprintf("%s-%s", stream, sub)
    146  - } else {
    147  - name = stream
    148  - }
    149  - }
    150  - 
    151  - for prefix, typ := range prefixesToPackageType {
    152  - if strings.HasPrefix(name, prefix) {
    153  - t := strings.TrimPrefix(name, prefix)
    154  - if t != "" {
    155  - candidates = append(candidates, UpstreamCandidate{Name: t, Type: typ})
    156  - return candidates
    157  - }
    158  - }
    159  - }
    160  - 
    161  - if name != "" {
    162  - candidates = append(candidates, UpstreamCandidate{Name: name, Type: UnknownPkg})
    163  - return candidates
    164  - }
    165  - 
    166  - return candidates
    167  -}
    168  - 
  • ■ ■ ■ ■ ■ ■
    syft/pkg/apk_metadata_test.go
    skipped 163 lines
    164 164   }
    165 165  }
    166 166   
    167  -func TestApkMetadata_UpstreamCandidates(t *testing.T) {
    168  - tests := []struct {
    169  - name string
    170  - metadata ApkMetadata
    171  - expected []UpstreamCandidate
    172  - }{
    173  - {
    174  - name: "gocase",
    175  - metadata: ApkMetadata{
    176  - Package: "p",
    177  - },
    178  - expected: []UpstreamCandidate{
    179  - {Name: "p", Type: UnknownPkg},
    180  - },
    181  - },
    182  - {
    183  - name: "same package and origin simple case",
    184  - metadata: ApkMetadata{
    185  - Package: "p",
    186  - OriginPackage: "p",
    187  - },
    188  - expected: []UpstreamCandidate{
    189  - {Name: "p", Type: UnknownPkg},
    190  - },
    191  - },
    192  - {
    193  - name: "different package and origin",
    194  - metadata: ApkMetadata{
    195  - Package: "p",
    196  - OriginPackage: "origin",
    197  - },
    198  - expected: []UpstreamCandidate{
    199  - {Name: "origin", Type: ApkPkg},
    200  - {Name: "p", Type: UnknownPkg},
    201  - },
    202  - },
    203  - {
    204  - name: "upstream python package information as qualifier py- prefix",
    205  - metadata: ApkMetadata{
    206  - Package: "py-potatoes",
    207  - OriginPackage: "py-potatoes",
    208  - },
    209  - expected: []UpstreamCandidate{
    210  - {Name: "potatoes", Type: PythonPkg},
    211  - },
    212  - },
    213  - {
    214  - name: "upstream python package information as qualifier py3- prefix",
    215  - metadata: ApkMetadata{
    216  - Package: "py3-potatoes",
    217  - OriginPackage: "py3-potatoes",
    218  - },
    219  - expected: []UpstreamCandidate{
    220  - {Name: "potatoes", Type: PythonPkg},
    221  - },
    222  - },
    223  - {
    224  - name: "python package with distinct origin package",
    225  - metadata: ApkMetadata{
    226  - Package: "py3-non-existant",
    227  - OriginPackage: "abcdefg",
    228  - },
    229  - expected: []UpstreamCandidate{
    230  - {Name: "abcdefg", Type: ApkPkg},
    231  - {Name: "non-existant", Type: PythonPkg},
    232  - },
    233  - },
    234  - {
    235  - name: "upstream ruby package information as qualifier",
    236  - metadata: ApkMetadata{
    237  - Package: "ruby-something",
    238  - OriginPackage: "ruby-something",
    239  - },
    240  - expected: []UpstreamCandidate{
    241  - {Name: "something", Type: GemPkg},
    242  - },
    243  - },
    244  - {
    245  - name: "ruby package with distinct origin package",
    246  - metadata: ApkMetadata{
    247  - Package: "ruby-something",
    248  - OriginPackage: "1234567",
    249  - },
    250  - expected: []UpstreamCandidate{
    251  - {Name: "1234567", Type: ApkPkg},
    252  - {Name: "something", Type: GemPkg},
    253  - },
    254  - },
    255  - {
    256  - name: "postgesql-15 upstream postgresql",
    257  - metadata: ApkMetadata{
    258  - Package: "postgresql-15",
    259  - },
    260  - expected: []UpstreamCandidate{
    261  - {Name: "postgresql", Type: UnknownPkg},
    262  - },
    263  - },
    264  - {
    265  - name: "postgesql15 upstream postgresql",
    266  - metadata: ApkMetadata{
    267  - Package: "postgresql15",
    268  - },
    269  - expected: []UpstreamCandidate{
    270  - {Name: "postgresql", Type: UnknownPkg},
    271  - },
    272  - },
    273  - {
    274  - name: "go-1.19 upstream go",
    275  - metadata: ApkMetadata{
    276  - Package: "go-1.19",
    277  - },
    278  - expected: []UpstreamCandidate{
    279  - {Name: "go", Type: UnknownPkg},
    280  - },
    281  - },
    282  - {
    283  - name: "go1.143 upstream go",
    284  - metadata: ApkMetadata{
    285  - Package: "go1.143",
    286  - },
    287  - expected: []UpstreamCandidate{
    288  - {Name: "go", Type: UnknownPkg},
    289  - },
    290  - },
    291  - {
    292  - name: "abc-101.191.23456 upstream abc",
    293  - metadata: ApkMetadata{
    294  - Package: "abc-101.191.23456",
    295  - },
    296  - expected: []UpstreamCandidate{
    297  - {Name: "abc", Type: UnknownPkg},
    298  - },
    299  - },
    300  - {
    301  - name: "abc101.191.23456 upstream abc",
    302  - metadata: ApkMetadata{
    303  - Package: "abc101.191.23456",
    304  - },
    305  - expected: []UpstreamCandidate{
    306  - {Name: "abc", Type: UnknownPkg},
    307  - },
    308  - },
    309  - {
    310  - name: "abc101-12345-1045 upstream abc101-12345",
    311  - metadata: ApkMetadata{
    312  - Package: "abc101-12345-1045",
    313  - },
    314  - expected: []UpstreamCandidate{
    315  - {Name: "abc101-12345", Type: UnknownPkg},
    316  - },
    317  - },
    318  - {
    319  - name: "abc101-a12345-1045 upstream abc101-a12345",
    320  - metadata: ApkMetadata{
    321  - Package: "abc101-a12345-1045",
    322  - },
    323  - expected: []UpstreamCandidate{
    324  - {Name: "abc-a12345-1045", Type: UnknownPkg},
    325  - },
    326  - },
    327  - {
    328  - name: "package starting with single digit",
    329  - metadata: ApkMetadata{
    330  - Package: "3proxy",
    331  - },
    332  - expected: []UpstreamCandidate{
    333  - {Name: "3proxy", Type: UnknownPkg},
    334  - },
    335  - },
    336  - {
    337  - name: "package starting with multiple digits",
    338  - metadata: ApkMetadata{
    339  - Package: "356proxy",
    340  - },
    341  - expected: []UpstreamCandidate{
    342  - {Name: "356proxy", Type: UnknownPkg},
    343  - },
    344  - },
    345  - {
    346  - name: "package composed of only digits",
    347  - metadata: ApkMetadata{
    348  - Package: "123456",
    349  - },
    350  - expected: []UpstreamCandidate{
    351  - {Name: "123456", Type: UnknownPkg},
    352  - },
    353  - },
    354  - {
    355  - name: "ruby-3.6 upstream ruby",
    356  - metadata: ApkMetadata{
    357  - Package: "ruby-3.6",
    358  - },
    359  - expected: []UpstreamCandidate{
    360  - {Name: "ruby", Type: UnknownPkg},
    361  - },
    362  - },
    363  - {
    364  - name: "ruby3.6 upstream ruby",
    365  - metadata: ApkMetadata{
    366  - Package: "ruby3.6",
    367  - },
    368  - expected: []UpstreamCandidate{
    369  - {Name: "ruby", Type: UnknownPkg},
    370  - },
    371  - },
    372  - {
    373  - name: "ruby3.6-tacos upstream tacos",
    374  - metadata: ApkMetadata{
    375  - Package: "ruby3.6-tacos",
    376  - },
    377  - expected: []UpstreamCandidate{
    378  - {Name: "tacos", Type: GemPkg},
    379  - },
    380  - },
    381  - {
    382  - name: "ruby-3.6-tacos upstream tacos",
    383  - metadata: ApkMetadata{
    384  - Package: "ruby-3.6-tacos",
    385  - },
    386  - expected: []UpstreamCandidate{
    387  - {Name: "tacos", Type: GemPkg},
    388  - },
    389  - },
    390  - {
    391  - name: "abc1234jksajflksa",
    392  - metadata: ApkMetadata{
    393  - Package: "abc1234jksajflksa",
    394  - },
    395  - expected: []UpstreamCandidate{
    396  - {Name: "abc1234jksajflksa", Type: UnknownPkg},
    397  - },
    398  - },
    399  - }
    400  - 
    401  - for _, test := range tests {
    402  - t.Run(test.name, func(t *testing.T) {
    403  - actual := test.metadata.UpstreamCandidates()
    404  - assert.Equal(t, test.expected, actual)
    405  - })
    406  - }
    407  -}
    408  - 
  • ■ ■ ■ ■ ■
    syft/pkg/cataloger/apkdb/package.go
    skipped 35 lines
    36 36   pkg.PURLQualifierArch: m.Architecture,
    37 37   }
    38 38   
    39  - upstreams := m.UpstreamCandidates()
    40  - if len(upstreams) > 0 {
    41  - // only room for one value so for now just take the first one
    42  - upstream := upstreams[0]
    43  - 
    44  - if upstream.Name != "" && upstream.Name != m.Package {
    45  - qualifiers[pkg.PURLQualifierUpstream] = upstream.Name
    46  - }
     39 + if m.OriginPackage != m.Package {
     40 + qualifiers[pkg.PURLQualifierUpstream] = m.OriginPackage
    47 41   }
    48 42   
    49 43   return packageurl.NewPackageURL(
    skipped 12 lines
  • ■ ■ ■ ■ ■ ■
    syft/pkg/cataloger/apkdb/package_test.go
    skipped 96 lines
    97 97   expected: "pkg:apk/alpine/p@v?arch=a&upstream=origin&distro=alpine-3.4.6",
    98 98   },
    99 99   {
    100  - name: "upstream python package information as qualifier",
    101  - metadata: pkg.ApkMetadata{
    102  - Package: "py3-potatoes",
    103  - Version: "v",
    104  - Architecture: "a",
    105  - OriginPackage: "py3-potatoes",
    106  - },
    107  - distro: linux.Release{
    108  - ID: "alpine",
    109  - VersionID: "3.4.6",
    110  - },
    111  - expected: "pkg:apk/alpine/py3-potatoes@v?arch=a&upstream=potatoes&distro=alpine-3.4.6",
    112  - },
    113  - {
    114  - name: "python package with origin package as upstream",
    115  - metadata: pkg.ApkMetadata{
    116  - Package: "py3-non-existant",
    117  - Version: "v",
    118  - Architecture: "a",
    119  - OriginPackage: "abcdefg",
    120  - },
    121  - distro: linux.Release{
    122  - ID: "alpine",
    123  - VersionID: "3.4.6",
    124  - },
    125  - expected: "pkg:apk/alpine/py3-non-existant@v?arch=a&upstream=abcdefg&distro=alpine-3.4.6",
    126  - },
    127  - {
    128  - name: "postgesql-15 upstream postgresql",
    129  - metadata: pkg.ApkMetadata{
    130  - Package: "postgresql-15",
    131  - Version: "15.0",
    132  - Architecture: "a",
    133  - OriginPackage: "postgresql-15",
    134  - },
    135  - distro: linux.Release{
    136  - ID: "alpine",
    137  - VersionID: "3.4.6",
    138  - },
    139  - expected: "pkg:apk/alpine/[email protected]?arch=a&upstream=postgresql&distro=alpine-3.4.6",
    140  - },
    141  - {
    142  - name: "postgesql15 upstream postgresql",
    143  - metadata: pkg.ApkMetadata{
    144  - Package: "postgresql15",
    145  - Version: "15.0",
    146  - Architecture: "a",
    147  - OriginPackage: "postgresql15",
    148  - },
    149  - distro: linux.Release{
    150  - ID: "alpine",
    151  - VersionID: "3.4.6",
    152  - },
    153  - expected: "pkg:apk/alpine/[email protected]?arch=a&upstream=postgresql&distro=alpine-3.4.6",
    154  - },
    155  - {
    156  - name: "go-1.19 upstream go",
    157  - metadata: pkg.ApkMetadata{
    158  - Package: "go-1.19",
    159  - Version: "1.19",
    160  - Architecture: "a",
    161  - OriginPackage: "go-1.19",
    162  - },
    163  - distro: linux.Release{
    164  - ID: "alpine",
    165  - VersionID: "3.4.6",
    166  - },
    167  - expected: "pkg:apk/alpine/[email protected]?arch=a&upstream=go&distro=alpine-3.4.6",
    168  - },
    169  - {
    170  - name: "go1.19 upstream go",
    171  - metadata: pkg.ApkMetadata{
    172  - Package: "go1.19",
    173  - Version: "1.19",
    174  - Architecture: "a",
    175  - OriginPackage: "go1.19",
    176  - },
    177  - distro: linux.Release{
    178  - ID: "alpine",
    179  - VersionID: "3.4.6",
    180  - },
    181  - expected: "pkg:apk/alpine/[email protected]?arch=a&upstream=go&distro=alpine-3.4.6",
    182  - },
    183  - {
    184  - name: "abc-101.191.23456 upstream abc",
    185  - metadata: pkg.ApkMetadata{
    186  - Package: "abc-101.191.23456",
    187  - Version: "101.191.23456",
    188  - Architecture: "a",
    189  - OriginPackage: "abc-101.191.23456",
    190  - },
    191  - distro: linux.Release{
    192  - ID: "alpine",
    193  - VersionID: "3.4.6",
    194  - },
    195  - expected: "pkg:apk/alpine/[email protected]?arch=a&upstream=abc&distro=alpine-3.4.6",
    196  - },
    197  - {
    198  - name: "abc101.191.23456 upstream abc",
    199  - metadata: pkg.ApkMetadata{
    200  - Package: "abc101.191.23456",
    201  - Version: "101.191.23456",
    202  - Architecture: "a",
    203  - OriginPackage: "abc101.191.23456",
    204  - },
    205  - distro: linux.Release{
    206  - ID: "alpine",
    207  - VersionID: "3.4.6",
    208  - },
    209  - expected: "pkg:apk/alpine/[email protected]?arch=a&upstream=abc&distro=alpine-3.4.6",
    210  - },
    211  - {
    212  - name: "abc101-12345-1045 upstream abc101-12345",
    213  - metadata: pkg.ApkMetadata{
    214  - Package: "abc101-12345-1045",
    215  - Version: "101.191.23456",
    216  - Architecture: "a",
    217  - OriginPackage: "abc101-12345-1045",
    218  - },
    219  - distro: linux.Release{
    220  - ID: "alpine",
    221  - VersionID: "3.4.6",
    222  - },
    223  - expected: "pkg:apk/alpine/[email protected]?arch=a&upstream=abc101-12345&distro=alpine-3.4.6",
    224  - },
    225  - {
    226  - name: "abc101-a12345-1045 upstream abc101-a12345",
    227  - metadata: pkg.ApkMetadata{
    228  - Package: "abc101-a12345-1045",
    229  - Version: "101.191.23456",
    230  - Architecture: "a",
    231  - OriginPackage: "abc101-a12345-1045",
    232  - },
    233  - distro: linux.Release{
    234  - ID: "alpine",
    235  - VersionID: "3.4.6",
    236  - },
    237  - expected: "pkg:apk/alpine/[email protected]?arch=a&upstream=abc-a12345-1045&distro=alpine-3.4.6",
    238  - },
    239  - {
    240 100   name: "wolfi distro",
    241 101   metadata: pkg.ApkMetadata{
    242 102   Package: "p",
    skipped 88 lines
  • ■ ■ ■ ■ ■ ■
    syft/pkg/cataloger/common/cpe/apk.go
    1 1  package cpe
    2 2   
    3 3  import (
     4 + "fmt"
     5 + "regexp"
     6 + "strings"
     7 + 
     8 + "github.com/anchore/syft/internal"
    4 9   "github.com/anchore/syft/syft/pkg"
    5 10  )
    6 11   
     12 +var (
     13 + prefixesToPackageType = map[string]pkg.Type{
     14 + "py-": pkg.PythonPkg,
     15 + "ruby-": pkg.GemPkg,
     16 + }
     17 + streamVersionPkgNamePattern = regexp.MustCompile(`^(?P<stream>[a-zA-Z][\w-]*?)(?P<streamVersion>\-?\d[\d\.]*?)($|-(?P<subPackage>[a-zA-Z][\w-]*?)?)$`)
     18 +)
     19 + 
     20 +type upstreamCandidate struct {
     21 + Name string
     22 + Type pkg.Type
     23 +}
     24 + 
     25 +func upstreamCandidates(m pkg.ApkMetadata) (candidates []upstreamCandidate) {
     26 + // Do not consider OriginPackage variations when generating CPE candidates for the child package
     27 + // because doing so will result in false positives when matching to vulnerabilities in Grype since
     28 + // it won't know to lookup apk fix entries using the OriginPackage name.
     29 + 
     30 + name := m.Package
     31 + groups := internal.MatchNamedCaptureGroups(streamVersionPkgNamePattern, m.Package)
     32 + stream, ok := groups["stream"]
     33 + 
     34 + if ok && stream != "" {
     35 + sub, ok := groups["subPackage"]
     36 + 
     37 + if ok && sub != "" {
     38 + name = fmt.Sprintf("%s-%s", stream, sub)
     39 + } else {
     40 + name = stream
     41 + }
     42 + }
     43 + 
     44 + for prefix, typ := range prefixesToPackageType {
     45 + if strings.HasPrefix(name, prefix) {
     46 + t := strings.TrimPrefix(name, prefix)
     47 + if t != "" {
     48 + candidates = append(candidates, upstreamCandidate{Name: t, Type: typ})
     49 + return candidates
     50 + }
     51 + }
     52 + }
     53 + 
     54 + if name != "" {
     55 + candidates = append(candidates, upstreamCandidate{Name: name, Type: pkg.UnknownPkg})
     56 + return candidates
     57 + }
     58 + 
     59 + return candidates
     60 +}
     61 + 
    7 62  func candidateVendorsForAPK(p pkg.Package) fieldCandidateSet {
    8 63   metadata, ok := p.Metadata.(pkg.ApkMetadata)
    9 64   if !ok {
    skipped 1 lines
    11 66   }
    12 67   
    13 68   vendors := newFieldCandidateSet()
    14  - candidates := metadata.UpstreamCandidates()
     69 + candidates := upstreamCandidates(metadata)
    15 70   
    16 71   for _, c := range candidates {
    17 72   switch c.Type {
    skipped 34 lines
    52 107   }
    53 108   
    54 109   products := newFieldCandidateSet()
    55  - candidates := metadata.UpstreamCandidates()
     110 + candidates := upstreamCandidates(metadata)
    56 111   
    57 112   for _, c := range candidates {
    58 113   switch c.Type {
    skipped 19 lines
  • ■ ■ ■ ■ ■ ■
    syft/pkg/cataloger/common/cpe/apk_test.go
    skipped 30 lines
    31 31   OriginPackage: "abcdefg",
    32 32   },
    33 33   },
    34  - expected: []string{"pypdf", "pypdfproject", "pypdf_project", "abcdefg"},
     34 + expected: []string{"pypdf", "pypdfproject", "pypdf_project"},
    35 35   },
    36 36   {
    37 37   name: "ruby-armadillo Package",
    skipped 59 lines
    97 97   OriginPackage: "ruby",
    98 98   },
    99 99   },
    100  - expected: []string{"rake", "ruby-lang", "ruby"},
     100 + expected: []string{"rake", "ruby-lang"},
    101 101   },
    102 102   }
    103 103   for _, test := range tests {
    skipped 26 lines
    130 130   OriginPackage: "abcdefg",
    131 131   },
    132 132   },
    133  - expected: []string{"pypdf", "abcdefg"},
     133 + expected: []string{"pypdf"},
    134 134   },
    135 135   {
    136 136   name: "ruby-armadillo Package",
    skipped 56 lines
    193 193   OriginPackage: "ruby",
    194 194   },
    195 195   },
    196  - expected: []string{"rake", "ruby"},
     196 + expected: []string{"rake"},
    197 197   },
    198 198   }
    199 199   for _, test := range tests {
    skipped 3 lines
    203 203   }
    204 204  }
    205 205   
     206 +func Test_upstreamCandidates(t *testing.T) {
     207 + tests := []struct {
     208 + name string
     209 + metadata pkg.ApkMetadata
     210 + expected []upstreamCandidate
     211 + }{
     212 + {
     213 + name: "gocase",
     214 + metadata: pkg.ApkMetadata{
     215 + Package: "p",
     216 + },
     217 + expected: []upstreamCandidate{
     218 + {Name: "p", Type: pkg.UnknownPkg},
     219 + },
     220 + },
     221 + {
     222 + name: "same package and origin simple case",
     223 + metadata: pkg.ApkMetadata{
     224 + Package: "p",
     225 + OriginPackage: "p",
     226 + },
     227 + expected: []upstreamCandidate{
     228 + {Name: "p", Type: pkg.UnknownPkg},
     229 + },
     230 + },
     231 + {
     232 + name: "different package and origin",
     233 + metadata: pkg.ApkMetadata{
     234 + Package: "p",
     235 + OriginPackage: "origin",
     236 + },
     237 + expected: []upstreamCandidate{
     238 + {Name: "p", Type: pkg.UnknownPkg},
     239 + },
     240 + },
     241 + {
     242 + name: "upstream python package information as qualifier py- prefix",
     243 + metadata: pkg.ApkMetadata{
     244 + Package: "py-potatoes",
     245 + OriginPackage: "py-potatoes",
     246 + },
     247 + expected: []upstreamCandidate{
     248 + {Name: "potatoes", Type: pkg.PythonPkg},
     249 + },
     250 + },
     251 + {
     252 + name: "upstream python package information as qualifier py3- prefix",
     253 + metadata: pkg.ApkMetadata{
     254 + Package: "py3-potatoes",
     255 + OriginPackage: "py3-potatoes",
     256 + },
     257 + expected: []upstreamCandidate{
     258 + {Name: "potatoes", Type: pkg.PythonPkg},
     259 + },
     260 + },
     261 + {
     262 + name: "python package with distinct origin package",
     263 + metadata: pkg.ApkMetadata{
     264 + Package: "py3-non-existant",
     265 + OriginPackage: "abcdefg",
     266 + },
     267 + expected: []upstreamCandidate{
     268 + {Name: "non-existant", Type: pkg.PythonPkg},
     269 + },
     270 + },
     271 + {
     272 + name: "upstream ruby package information as qualifier",
     273 + metadata: pkg.ApkMetadata{
     274 + Package: "ruby-something",
     275 + OriginPackage: "ruby-something",
     276 + },
     277 + expected: []upstreamCandidate{
     278 + {Name: "something", Type: pkg.GemPkg},
     279 + },
     280 + },
     281 + {
     282 + name: "ruby package with distinct origin package",
     283 + metadata: pkg.ApkMetadata{
     284 + Package: "ruby-something",
     285 + OriginPackage: "1234567",
     286 + },
     287 + expected: []upstreamCandidate{
     288 + {Name: "something", Type: pkg.GemPkg},
     289 + },
     290 + },
     291 + {
     292 + name: "postgesql-15 upstream postgresql",
     293 + metadata: pkg.ApkMetadata{
     294 + Package: "postgresql-15",
     295 + },
     296 + expected: []upstreamCandidate{
     297 + {Name: "postgresql", Type: pkg.UnknownPkg},
     298 + },
     299 + },
     300 + {
     301 + name: "postgesql15 upstream postgresql",
     302 + metadata: pkg.ApkMetadata{
     303 + Package: "postgresql15",
     304 + },
     305 + expected: []upstreamCandidate{
     306 + {Name: "postgresql", Type: pkg.UnknownPkg},
     307 + },
     308 + },
     309 + {
     310 + name: "go-1.19 upstream go",
     311 + metadata: pkg.ApkMetadata{
     312 + Package: "go-1.19",
     313 + },
     314 + expected: []upstreamCandidate{
     315 + {Name: "go", Type: pkg.UnknownPkg},
     316 + },
     317 + },
     318 + {
     319 + name: "go1.143 upstream go",
     320 + metadata: pkg.ApkMetadata{
     321 + Package: "go1.143",
     322 + },
     323 + expected: []upstreamCandidate{
     324 + {Name: "go", Type: pkg.UnknownPkg},
     325 + },
     326 + },
     327 + {
     328 + name: "abc-101.191.23456 upstream abc",
     329 + metadata: pkg.ApkMetadata{
     330 + Package: "abc-101.191.23456",
     331 + },
     332 + expected: []upstreamCandidate{
     333 + {Name: "abc", Type: pkg.UnknownPkg},
     334 + },
     335 + },
     336 + {
     337 + name: "abc101.191.23456 upstream abc",
     338 + metadata: pkg.ApkMetadata{
     339 + Package: "abc101.191.23456",
     340 + },
     341 + expected: []upstreamCandidate{
     342 + {Name: "abc", Type: pkg.UnknownPkg},
     343 + },
     344 + },
     345 + {
     346 + name: "abc101-12345-1045 upstream abc101-12345",
     347 + metadata: pkg.ApkMetadata{
     348 + Package: "abc101-12345-1045",
     349 + },
     350 + expected: []upstreamCandidate{
     351 + {Name: "abc101-12345", Type: pkg.UnknownPkg},
     352 + },
     353 + },
     354 + {
     355 + name: "abc101-a12345-1045 upstream abc101-a12345",
     356 + metadata: pkg.ApkMetadata{
     357 + Package: "abc101-a12345-1045",
     358 + },
     359 + expected: []upstreamCandidate{
     360 + {Name: "abc-a12345-1045", Type: pkg.UnknownPkg},
     361 + },
     362 + },
     363 + {
     364 + name: "package starting with single digit",
     365 + metadata: pkg.ApkMetadata{
     366 + Package: "3proxy",
     367 + },
     368 + expected: []upstreamCandidate{
     369 + {Name: "3proxy", Type: pkg.UnknownPkg},
     370 + },
     371 + },
     372 + {
     373 + name: "package starting with multiple digits",
     374 + metadata: pkg.ApkMetadata{
     375 + Package: "356proxy",
     376 + },
     377 + expected: []upstreamCandidate{
     378 + {Name: "356proxy", Type: pkg.UnknownPkg},
     379 + },
     380 + },
     381 + {
     382 + name: "package composed of only digits",
     383 + metadata: pkg.ApkMetadata{
     384 + Package: "123456",
     385 + },
     386 + expected: []upstreamCandidate{
     387 + {Name: "123456", Type: pkg.UnknownPkg},
     388 + },
     389 + },
     390 + {
     391 + name: "ruby-3.6 upstream ruby",
     392 + metadata: pkg.ApkMetadata{
     393 + Package: "ruby-3.6",
     394 + },
     395 + expected: []upstreamCandidate{
     396 + {Name: "ruby", Type: pkg.UnknownPkg},
     397 + },
     398 + },
     399 + {
     400 + name: "ruby3.6 upstream ruby",
     401 + metadata: pkg.ApkMetadata{
     402 + Package: "ruby3.6",
     403 + },
     404 + expected: []upstreamCandidate{
     405 + {Name: "ruby", Type: pkg.UnknownPkg},
     406 + },
     407 + },
     408 + {
     409 + name: "ruby3.6-tacos upstream tacos",
     410 + metadata: pkg.ApkMetadata{
     411 + Package: "ruby3.6-tacos",
     412 + },
     413 + expected: []upstreamCandidate{
     414 + {Name: "tacos", Type: pkg.GemPkg},
     415 + },
     416 + },
     417 + {
     418 + name: "ruby-3.6-tacos upstream tacos",
     419 + metadata: pkg.ApkMetadata{
     420 + Package: "ruby-3.6-tacos",
     421 + },
     422 + expected: []upstreamCandidate{
     423 + {Name: "tacos", Type: pkg.GemPkg},
     424 + },
     425 + },
     426 + {
     427 + name: "abc1234jksajflksa",
     428 + metadata: pkg.ApkMetadata{
     429 + Package: "abc1234jksajflksa",
     430 + },
     431 + expected: []upstreamCandidate{
     432 + {Name: "abc1234jksajflksa", Type: pkg.UnknownPkg},
     433 + },
     434 + },
     435 + }
     436 + 
     437 + for _, test := range tests {
     438 + t.Run(test.name, func(t *testing.T) {
     439 + actual := upstreamCandidates(test.metadata)
     440 + assert.Equal(t, test.expected, actual)
     441 + })
     442 + }
     443 +}
     444 + 
  • ■ ■ ■ ■ ■ ■
    syft/pkg/cataloger/common/cpe/generate_test.go
    skipped 706 lines
    707 707   "cpe:2.3:a:ruby_rake:rake:2.7.6-r0:*:*:*:*:*:*:*",
    708 708   "cpe:2.3:a:ruby_rake:ruby-rake:2.7.6-r0:*:*:*:*:*:*:*",
    709 709   "cpe:2.3:a:ruby_rake:ruby_rake:2.7.6-r0:*:*:*:*:*:*:*",
    710  - "cpe:2.3:a:rake:ruby:2.7.6-r0:*:*:*:*:*:*:*",
    711  - "cpe:2.3:a:ruby-lang:ruby:2.7.6-r0:*:*:*:*:*:*:*",
    712  - "cpe:2.3:a:ruby-rake:ruby:2.7.6-r0:*:*:*:*:*:*:*",
    713  - "cpe:2.3:a:ruby:ruby:2.7.6-r0:*:*:*:*:*:*:*",
    714  - "cpe:2.3:a:ruby_lang:ruby:2.7.6-r0:*:*:*:*:*:*:*",
    715  - "cpe:2.3:a:ruby_rake:ruby:2.7.6-r0:*:*:*:*:*:*:*",
    716 710   },
    717 711   },
    718 712   }
    skipped 240 lines
Please wait...
Page is in error, reload to recover