Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(java): check if a version exists when determining GAV by file name for jar files #5630

2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ require (
github.com/alicebob/miniredis/v2 v2.30.4
github.com/aquasecurity/bolt-fixtures v0.0.0-20200903104109-d34e7f983986
github.com/aquasecurity/defsec v0.93.2-0.20231120220217-6818261529c8
github.com/aquasecurity/go-dep-parser v0.0.0-20231120074854-8322cc2242bf
github.com/aquasecurity/go-dep-parser v0.0.0-20231128011057-a175d05161dd
github.com/aquasecurity/go-gem-version v0.0.0-20201115065557-8eed6fe000ce
github.com/aquasecurity/go-npm-version v0.0.0-20201110091526-0b796d180798
github.com/aquasecurity/go-pep440-version v0.0.0-20210121094942-22b2f8951d46
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -322,8 +322,8 @@ github.com/aquasecurity/bolt-fixtures v0.0.0-20200903104109-d34e7f983986 h1:2a30
github.com/aquasecurity/bolt-fixtures v0.0.0-20200903104109-d34e7f983986/go.mod h1:NT+jyeCzXk6vXR5MTkdn4z64TgGfE5HMLC8qfj5unl8=
github.com/aquasecurity/defsec v0.93.2-0.20231120220217-6818261529c8 h1:w/Sm2fVtb0Rv1bcLLwsW9j37mNUya8MwzKMcjG9OW/Q=
github.com/aquasecurity/defsec v0.93.2-0.20231120220217-6818261529c8/go.mod h1:J30VViSgmoW2Ic/6aqVJO2qvuADsmZ3MYuNxPcU6Vt0=
github.com/aquasecurity/go-dep-parser v0.0.0-20231120074854-8322cc2242bf h1:kweQrNMfarPfjZGI1537GtuujhpzhsuT/MvmW2FwaBE=
github.com/aquasecurity/go-dep-parser v0.0.0-20231120074854-8322cc2242bf/go.mod h1:7+xrs6AWD5+onpmX8f7qIkAhUgkPP0mhUdBjxJBcfas=
github.com/aquasecurity/go-dep-parser v0.0.0-20231128011057-a175d05161dd h1:bhSbfJyZg4okPlAfIQ8pKsj8BCvs9LZErdkqUcpvD04=
github.com/aquasecurity/go-dep-parser v0.0.0-20231128011057-a175d05161dd/go.mod h1:7+xrs6AWD5+onpmX8f7qIkAhUgkPP0mhUdBjxJBcfas=
github.com/aquasecurity/go-gem-version v0.0.0-20201115065557-8eed6fe000ce h1:QgBRgJvtEOBtUXilDb1MLi1p1MWoyFDXAu5DEUl5nwM=
github.com/aquasecurity/go-gem-version v0.0.0-20201115065557-8eed6fe000ce/go.mod h1:HXgVzOPvXhVGLJs4ZKO817idqr/xhwsTcj17CLYY74s=
github.com/aquasecurity/go-mock-aws v0.0.0-20230810212901-d6feebd39060 h1:V7nC90NpRDEubNpNEgRDtTfLH3RKQlZeY9/HSqxEze8=
Expand Down
46 changes: 29 additions & 17 deletions pkg/javadb/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -142,37 +142,49 @@ func (d *DB) SearchBySHA1(sha1 string) (jar.Properties, error) {
}, nil
}

func (d *DB) SearchByArtifactID(artifactID string) (string, error) {
func (d *DB) SearchByArtifactID(artifactID, version string) (string, error) {
indexes, err := d.driver.SelectIndexesByArtifactIDAndFileType(artifactID, types.JarType)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What if changing this method to match the version as well as the artifact ID?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you mean just to move the following logic to trivy-java-db?

trivy/pkg/javadb/client.go

Lines 157 to 188 in 2f10ed1

func foundGroupID(version string, indexes []types.Index) string {
var groupID, maxGroupID string
var count, maxCount int
var versionFound bool
sort.Slice(indexes, func(i, j int) bool {
return indexes[i].GroupID < indexes[j].GroupID
})
for _, index := range indexes {
if index.GroupID != groupID {
// save a new GroupID with the max number of indexes (if this GroupID contains the required version)
if count > maxCount && versionFound {
maxGroupID = groupID
maxCount = count
}
count = 0
versionFound = false
}
// iterate over all indexes of the current GroupID
groupID = index.GroupID
count++
if index.Version == version {
versionFound = true
}
}
// save latest groupID
if count > maxCount && versionFound {
maxGroupID = groupID
}
return maxGroupID
}

Or update our sql query in trivy-java-db?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I meant SQL query. Is it possible?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I need more knowledge on SQL.
I will try to do this and then write to you.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I created aquasecurity/trivy-java-db#23 and updated this PR.
Take a look, when you have time, please.

if err != nil {
return "", xerrors.Errorf("select error: %w", err)
} else if len(indexes) == 0 {
return "", xerrors.Errorf("artifactID %s: %w", artifactID, jar.ArtifactNotFoundErr)
}

return foundGroupID(version, indexes), nil
}

// foundGroupID checks all indexes and returns a group ID containing the required version and with the maximum number of indexes(versions).
func foundGroupID(version string, indexes []types.Index) string {
var groupID, maxGroupID string
var count, maxCount int
var versionFound bool

sort.Slice(indexes, func(i, j int) bool {
return indexes[i].GroupID < indexes[j].GroupID
})

// Some artifacts might have the same artifactId.
// e.g. "javax.servlet:jstl" and "jstl:jstl"
groupIDs := make(map[string]int)
for _, index := range indexes {
if i, ok := groupIDs[index.GroupID]; ok {
groupIDs[index.GroupID] = i + 1
continue
if index.GroupID != groupID {
// save a new GroupID with the max number of indexes (if this GroupID contains the required version)
if count > maxCount && versionFound {
maxGroupID = groupID
maxCount = count
}
count = 0
versionFound = false
}
groupIDs[index.GroupID] = 1
}
maxCount := 0
var groupID string
for k, v := range groupIDs {
if v > maxCount {
maxCount = v
groupID = k
// iterate over all indexes of the current GroupID
groupID = index.GroupID
count++
if index.Version == version {
versionFound = true
}
}

return groupID, nil
// save latest groupID
if count > maxCount && versionFound {
maxGroupID = groupID
}
return maxGroupID
}

func (d *DB) Close() error {
Expand Down
81 changes: 81 additions & 0 deletions pkg/javadb/client_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
package javadb

import (
"github.com/aquasecurity/trivy-java-db/pkg/types"
"github.com/stretchr/testify/assert"
"testing"
)

func TestFoundGroupID(t *testing.T) {
tests := []struct {
name string
indexes []types.Index
version string
wantGroupID string
}{
{
name: "Only one groupID has required version",
indexes: []types.Index{
{
GroupID: "com.example1",
Version: "1.0.0",
},
{
GroupID: "com.example1",
Version: "1.0.1",
},
{
GroupID: "com.example2",
Version: "2.0.0",
},
},
version: "2.0.0",
wantGroupID: "com.example2",
},
{
name: "Two groupIDs have required version",
indexes: []types.Index{
{
GroupID: "com.example1",
Version: "1.0.0",
},
{
GroupID: "com.example2",
Version: "1.0.1",
},
{
GroupID: "com.example2",
Version: "1.0.0",
},
},
version: "1.0.0",
wantGroupID: "com.example2",
},
{
name: "There are no groupIDs with required version",
indexes: []types.Index{
{
GroupID: "com.example1",
Version: "1.0.0",
},
{
GroupID: "com.example1",
Version: "2.0.0",
},
{
GroupID: "com.example2",
Version: "2.0.0",
},
},
version: "3.0.0",
wantGroupID: "",
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
gotGroupID := foundGroupID(tt.version, tt.indexes)
assert.Equal(t, tt.wantGroupID, gotGroupID)
})
}
}