Skip to content

Commit

Permalink
simplify version selection
Browse files Browse the repository at this point in the history
Signed-off-by: Alex Goodman <[email protected]>
  • Loading branch information
wagoodman committed Sep 12, 2024
1 parent 1542f45 commit ac8f7e7
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 188 deletions.
4 changes: 2 additions & 2 deletions syft/pkg/cataloger/java/cataloger_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -151,13 +151,13 @@ func TestJvmDistributionCataloger(t *testing.T) {
fixture: "test-fixtures/jvm-installs/valid-post-jep223",
expected: pkg.Package{
Name: "openjdk",
Version: "21.0.4+7",
Version: "21.0.4+7-LTS",
FoundBy: "java-jvm-cataloger",
Locations: file.NewLocationSet(file.NewLocation("jvm/openjdk/release")),
Licenses: pkg.NewLicenseSet(),
Type: pkg.BinaryPkg,
CPEs: []cpe.CPE{cpe.Must("cpe:2.3:a:oracle:openjdk:21.0.4:*:*:*:*:*:*:*", cpe.GeneratedSource)},
PURL: "pkg:generic/oracle/[email protected]%2B7?repository_url=https://github.com/adoptium/temurin-build.git",
PURL: "pkg:generic/oracle/[email protected]%2B7-LTS?repository_url=https://github.com/adoptium/jdk21u.git",
Metadata: pkg.JavaVMInstallation{
Release: pkg.JavaVMRelease{
Implementor: "Eclipse Adoptium",
Expand Down
92 changes: 20 additions & 72 deletions syft/pkg/cataloger/java/parse_jvm_release.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import (
"io"
"path"
"sort"
"strconv"
"strings"

"github.com/mitchellh/mapstructure"
Expand Down Expand Up @@ -87,13 +86,11 @@ func parseJVMRelease(_ context.Context, resolver file.Resolver, _ *generic.Envir

vendor, product := jvmPrimaryVendorProduct(ri.Implementor, reader.Path(), ri.ImageType, hasJdk)

legacyVersion := jvmLegacyVersion(ri)

p := pkg.Package{
Name: product,
Locations: locations,
Version: version,
CPEs: jvmCpes(version, legacyVersion, vendor, product, ri.ImageType, hasJdk),
CPEs: jvmCpes(version, vendor, product, ri.ImageType, hasJdk),
PURL: jvmPurl(*ri, version, vendor, product),
Licenses: licenses,
Type: pkg.BinaryPkg,
Expand Down Expand Up @@ -137,15 +134,15 @@ func findJvmFiles(resolver file.Resolver, installDir string) ([]string, bool) {

func jvmPurl(ri pkg.JavaVMRelease, version, vendor, product string) string {
var qualifiers []packageurl.Qualifier
if ri.BuildSourceRepo != "" {
if ri.SourceRepo != "" {
qualifiers = append(qualifiers, packageurl.Qualifier{
Key: "repository_url",
Value: ri.BuildSourceRepo,
Value: ri.SourceRepo,
})
} else if ri.SourceRepo != "" {
} else if ri.BuildSourceRepo != "" {
qualifiers = append(qualifiers, packageurl.Qualifier{
Key: "repository_url",
Value: ri.SourceRepo,
Value: ri.BuildSourceRepo,
})
}

Expand Down Expand Up @@ -182,20 +179,9 @@ func jvmPrimaryVendorProduct(implementor, path, imageType string, hasJdk bool) (
return oracleVendor, openJdkProduct
}

func jvmCpes(pkgVersion, legacyVersion, primaryVendor, primaryProduct, imageType string, hasJdk bool) []cpe.CPE {
func jvmCpes(version, primaryVendor, primaryProduct, imageType string, hasJdk bool) []cpe.CPE {
// see https://github.com/anchore/syft/issues/2422 for more context

versions := []string{pkgVersion}

if legacyVersion != "" {
legacyMajor := getMajorVersion(legacyVersion)
pkgMajor := getMajorVersion(pkgVersion)

if legacyMajor != pkgMajor {
versions = append(versions, legacyVersion)
}
}

var candidates []jvmCpeInfo

newCandidate := func(ven, prod, ver string) {
Expand All @@ -213,21 +199,19 @@ func jvmCpes(pkgVersion, legacyVersion, primaryVendor, primaryProduct, imageType
}
}

for _, version := range versions {
switch {
case primaryVendor == "azul":
newCandidate(primaryVendor, "zulu", version)
newCandidate(oracleVendor, openJdkProduct, version)

case primaryVendor == "sun":
newEnterpriseCandidate(primaryVendor, version)

case primaryVendor == oracleVendor && primaryProduct != openJdkProduct:
newCandidate(primaryVendor, "java_se", version)
newEnterpriseCandidate(primaryVendor, version)
default:
newCandidate(primaryVendor, primaryProduct, version)
}
switch {
case primaryVendor == "azul":
newCandidate(primaryVendor, "zulu", version)
newCandidate(oracleVendor, openJdkProduct, version)

case primaryVendor == "sun":
newEnterpriseCandidate(primaryVendor, version)

case primaryVendor == oracleVendor && primaryProduct != openJdkProduct:
newCandidate(primaryVendor, "java_se", version)
newEnterpriseCandidate(primaryVendor, version)
default:
newCandidate(primaryVendor, primaryProduct, version)
}

var cpes []cpe.CPE
Expand Down Expand Up @@ -366,51 +350,15 @@ func jvmProjectByType(ty string) string {
// JAVA_VERSION Most prevalent, but least specific (jep 223 sensitive)
// IMPLEMENTOR_VERSION Unusable or missing in some cases
func jvmPackageVersion(ri *pkg.JavaVMRelease) string {
if ri.SemanticVersion != "" {
return ri.SemanticVersion
}

var version string
switch {
case ri.FullVersion != "":
version = ri.FullVersion
case ri.JavaRuntimeVersion != "":
version = ri.JavaRuntimeVersion
case ri.JavaVersion != "":
version = ri.JavaVersion
}

return version
}

func jvmLegacyVersion(ri *pkg.JavaVMRelease) string {
switch {
case ri.JavaRuntimeVersion != "":
return ri.JavaRuntimeVersion
case ri.JavaVersion != "":
return ri.JavaVersion
}
return ""
}

func getMajorVersion(v string) int {
fields := strings.Split(v, ".")
if len(fields) == 0 {
return -1
}

var err error
var majV int

if len(fields) >= 1 {
majV, err = strconv.Atoi(fields[0])
if err != nil {
log.WithFields("version", v, "error", err).Trace("unable to parse JVM major version")
return -1
}
}

return majV
return version
}

func trim0sFromLeft(v string) string {
Expand Down
122 changes: 8 additions & 114 deletions syft/pkg/cataloger/java/parse_jvm_release_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ func TestJvmCpes(t *testing.T) {
tests := []struct {
name string
pkgVersion string
legacyVersion string
primaryVendor string
primaryProduct string
imageType string
Expand All @@ -23,7 +22,6 @@ func TestJvmCpes(t *testing.T) {
{
name: "zulu release",
pkgVersion: "9.0.1+20",
legacyVersion: "",
primaryVendor: "azul",
primaryProduct: "zulu",
imageType: "jdk",
Expand Down Expand Up @@ -53,7 +51,6 @@ func TestJvmCpes(t *testing.T) {
{
name: "sun release",
pkgVersion: "1.6.0_322-b002",
legacyVersion: "",
primaryVendor: "sun",
primaryProduct: "jre",
imageType: "jre",
Expand Down Expand Up @@ -83,43 +80,12 @@ func TestJvmCpes(t *testing.T) {
},
{
name: "oracle se release",
pkgVersion: "8.0.1+2",
legacyVersion: "1.8.0_322-b02",
pkgVersion: "1.8.0_322-b02",
primaryVendor: "oracle",
primaryProduct: "java_se",
imageType: "jdk",
hasJdk: true,
expected: []cpe.CPE{
{
Attributes: cpe.Attributes{
Part: "a",
Vendor: "oracle",
Product: "java_se",
Version: "8.0.1",
Update: "",
},
Source: cpe.GeneratedSource,
},
{
Attributes: cpe.Attributes{
Part: "a",
Vendor: "oracle",
Product: "jre",
Version: "8.0.1",
Update: "",
},
Source: cpe.GeneratedSource,
},
{
Attributes: cpe.Attributes{
Part: "a",
Vendor: "oracle",
Product: "jdk",
Version: "8.0.1",
Update: "",
},
Source: cpe.GeneratedSource,
},
{
Attributes: cpe.Attributes{
Part: "a",
Expand Down Expand Up @@ -155,7 +121,6 @@ func TestJvmCpes(t *testing.T) {
{
name: "JEP 223 version with build info",
pkgVersion: "9.0.1+20",
legacyVersion: "",
primaryVendor: "oracle",
primaryProduct: "openjdk",
imageType: "openjdk",
Expand All @@ -175,7 +140,6 @@ func TestJvmCpes(t *testing.T) {
{
name: "JEP 223 version without build info",
pkgVersion: "11.0.9",
legacyVersion: "",
primaryVendor: "oracle",
primaryProduct: "openjdk",
imageType: "openjdk",
Expand All @@ -195,7 +159,6 @@ func TestJvmCpes(t *testing.T) {
{
name: "no plus sign in version string",
pkgVersion: "1.8.0",
legacyVersion: "",
primaryVendor: "oracle",
primaryProduct: "openjdk",
imageType: "openjdk",
Expand All @@ -215,7 +178,6 @@ func TestJvmCpes(t *testing.T) {
{
name: "empty version string",
pkgVersion: "",
legacyVersion: "",
primaryVendor: "oracle",
primaryProduct: "",
imageType: "",
Expand All @@ -225,7 +187,7 @@ func TestJvmCpes(t *testing.T) {

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
result := jvmCpes(tt.pkgVersion, tt.legacyVersion, tt.primaryVendor, tt.primaryProduct, tt.imageType, tt.hasJdk)
result := jvmCpes(tt.pkgVersion, tt.primaryVendor, tt.primaryProduct, tt.imageType, tt.hasJdk)
assert.Equal(t, tt.expected, result)
})
}
Expand All @@ -237,47 +199,26 @@ func TestJvmVersion(t *testing.T) {
input *pkg.JavaVMRelease
expected string
}{
{
name: "SemanticVersion available",
input: &pkg.JavaVMRelease{
SemanticVersion: "21.0.4+7",
FullVersion: "bogus",
JavaVersion: "bogus",
JavaRuntimeVersion: "bogus",
},
expected: "21.0.4+7",
},
{
name: "FullVersion fallback",
input: &pkg.JavaVMRelease{
FullVersion: "21.0.4+7-LTS",
JavaVersion: "bogus",
JavaRuntimeVersion: "bogus",
},
expected: "21.0.4+7-LTS",
},

{
name: "JavaRuntimeVersion fallback",
input: &pkg.JavaVMRelease{
JavaRuntimeVersion: "21.0.4+7-LTS",
JavaVersion: "bogus",
FullVersion: "bogus",
SemanticVersion: "bogus",
},
expected: "21.0.4+7-LTS",
},
{
name: "JavaVersion fallback",
input: &pkg.JavaVMRelease{
JavaVersion: "21.0.4",
JavaVersion: "21.0.4",
FullVersion: "bogus",
SemanticVersion: "bogus",
},
expected: "21.0.4",
},
{
name: "non-legacy version",
input: &pkg.JavaVMRelease{
JavaVersion: "11.0.11",
},
expected: "11.0.11",
},
{
name: "empty input fields",
input: &pkg.JavaVMRelease{},
Expand All @@ -293,53 +234,6 @@ func TestJvmVersion(t *testing.T) {
}
}

func TestGetMajorVersion(t *testing.T) {
tests := []struct {
name string
version string
expectedMajor int
}{
{
name: "valid version with major and minor",
version: "1.8",
expectedMajor: 1,
},
{
name: "valid version with only major",
version: "11",
expectedMajor: 11,
},
{
name: "invalid version format",
version: "not-a-version",
expectedMajor: -1,
},
{
name: "empty string",
version: "",
expectedMajor: -1,
},
{
name: "extra segments in version",
version: "1.8.0",
expectedMajor: 1,
},
{
name: "non-numeric major",
version: "a.8",
expectedMajor: -1,
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
major := getMajorVersion(tt.version)
assert.Equal(t, tt.expectedMajor, major)

})
}
}

func TestGetJVMVersionAndUpdate(t *testing.T) {
tests := []struct {
name string
Expand Down

0 comments on commit ac8f7e7

Please sign in to comment.