From a7a304d53e1ce230f881c28c4f35885774cf3b9a Mon Sep 17 00:00:00 2001 From: DmitriyLewen <91113035+DmitriyLewen@users.noreply.github.com> Date: Thu, 4 Jul 2024 15:52:23 +0600 Subject: [PATCH] fix(java): use `go-mvn-version` to remove `Package` duplicates (#7088) Co-authored-by: Teppei Fukuda --- pkg/dependency/parser/java/jar/parse.go | 27 ++++++++-- pkg/dependency/parser/java/jar/parse_test.go | 48 +++++++++++++++--- ...nal.jar => io.quarkus.gizmo.gizmo-1.1.jar} | Bin 882367 -> 884288 bytes 3 files changed, 62 insertions(+), 13 deletions(-) rename pkg/dependency/parser/java/jar/testdata/{io.quarkus.gizmo.gizmo-1.1.1.Final.jar => io.quarkus.gizmo.gizmo-1.1.jar} (99%) diff --git a/pkg/dependency/parser/java/jar/parse.go b/pkg/dependency/parser/java/jar/parse.go index 8cb81d1fc48e..be767e0cf248 100644 --- a/pkg/dependency/parser/java/jar/parse.go +++ b/pkg/dependency/parser/java/jar/parse.go @@ -6,15 +6,15 @@ import ( "crypto/sha1" // nolint:gosec "encoding/hex" "errors" - "fmt" "io" "os" "path" "path/filepath" "regexp" + "slices" "strings" - "github.com/samber/lo" + mavenversion "github.com/masahiro331/go-mvn-version" "golang.org/x/xerrors" ftypes "github.com/aquasecurity/trivy/pkg/fanal/types" @@ -439,7 +439,24 @@ func (m manifest) determineVersion() (string, error) { } func removePackageDuplicates(pkgs []ftypes.Package) []ftypes.Package { - return lo.UniqBy(pkgs, func(pkg ftypes.Package) string { - return fmt.Sprintf("%s::%s::%s", pkg.Name, pkg.Version, pkg.FilePath) - }) + // name::filePath => versions + var uniq = make(map[string][]mavenversion.Version) + var uniqPkgs []ftypes.Package + for _, pkg := range pkgs { + uniqID := pkg.Name + "::" + pkg.FilePath + // err is always nil + // cf. https://github.com/masahiro331/go-mvn-version/blob/d3157d602a08806ad94464c443e0cef1370694a1/version.go#L20-L25 + pkgVer, _ := mavenversion.NewVersion(pkg.Version) + savedVers, ok := uniq[uniqID] + if !ok || !slices.ContainsFunc(savedVers, func(v mavenversion.Version) bool { + // There are times when patch `0` is omitted. + // So we can't compare versions just as strings + // for example `2.17.0` and `2.17` must be equal + return v.Equal(pkgVer) + }) { + uniq[uniqID] = append(uniq[uniqID], pkgVer) + uniqPkgs = append(uniqPkgs, pkg) + } + } + return uniqPkgs } diff --git a/pkg/dependency/parser/java/jar/parse_test.go b/pkg/dependency/parser/java/jar/parse_test.go index 20f9c682be3b..958b2d0667a5 100644 --- a/pkg/dependency/parser/java/jar/parse_test.go +++ b/pkg/dependency/parser/java/jar/parse_test.go @@ -168,22 +168,54 @@ var ( }, } - // manually created + // Manually created. + // Files of `io.quarkus.gizmo.gizmo-1.1.jar` (gizmo:1.1.0 (from sha1)): + //├── bar + //│ ├── bar + //│ │ └── pom.properties (jackson-databind:2.13.4) + //│ └── foo + //│ └── pom.properties (jackson-databind:2.12.3) + //├── foo + //│ ├── bar + //│ │ └── pom.properties (jackson-databind:2.12.3) + //│ └── foo + //│ └── pom.properties (jackson-databind:2.13.4) + //├── jars + //│ ├── log4j-1.2.16.jar (log4j:1.2.16) + //│ └── log4j-1.2.17.jar (log4j:1.2.17) + //└── META-INF + // ├── INDEX.LIST + // ├── MANIFEST.MF + // └── maven + // └── io.quarkus.gizmo + // └── gizmo + // ├── pom.properties (gizmo:1.1) + // └── pom.xml wantDuplicatesJar = []ftypes.Package{ { Name: "io.quarkus.gizmo:gizmo", - Version: "1.1.1.Final", - FilePath: "testdata/io.quarkus.gizmo.gizmo-1.1.1.Final.jar", + Version: "1.1", + FilePath: "testdata/io.quarkus.gizmo.gizmo-1.1.jar", }, { Name: "log4j:log4j", Version: "1.2.16", - FilePath: "testdata/io.quarkus.gizmo.gizmo-1.1.1.Final.jar/jars/log4j-1.2.16.jar", + FilePath: "testdata/io.quarkus.gizmo.gizmo-1.1.jar/jars/log4j-1.2.16.jar", }, { Name: "log4j:log4j", Version: "1.2.17", - FilePath: "testdata/io.quarkus.gizmo.gizmo-1.1.1.Final.jar/jars/log4j-1.2.17.jar", + FilePath: "testdata/io.quarkus.gizmo.gizmo-1.1.jar/jars/log4j-1.2.17.jar", + }, + { + Name: "com.fasterxml.jackson.core:jackson-databind", + Version: "2.12.3", + FilePath: "testdata/io.quarkus.gizmo.gizmo-1.1.jar", + }, + { + Name: "com.fasterxml.jackson.core:jackson-databind", + Version: "2.13.4", + FilePath: "testdata/io.quarkus.gizmo.gizmo-1.1.jar", }, } ) @@ -251,7 +283,7 @@ func TestParse(t *testing.T) { }, { name: "duplicate libraries", - file: "testdata/io.quarkus.gizmo.gizmo-1.1.1.Final.jar", + file: "testdata/io.quarkus.gizmo.gizmo-1.1.jar", want: wantDuplicatesJar, }, } @@ -277,13 +309,13 @@ func TestParse(t *testing.T) { } case strings.Contains(r.URL.Query().Get("q"), "Gizmo"): res.Response.NumFound = 0 - case strings.Contains(r.URL.Query().Get("q"), "85d30c06026afd9f5be26da3194d4698c447a904"): + case strings.Contains(r.URL.Query().Get("q"), "1c78bbc4d8c58b9af8eee82b84f2c26ec48e9a2b"): res.Response.Docs = []doc{ { ID: "io.quarkus.gizmo.gizmo", GroupID: "io.quarkus.gizmo", ArtifactID: "gizmo", - Version: "1.1.1.Final", + Version: "1.1.0", }, } case strings.Contains(r.URL.Query().Get("q"), "heuristic"): diff --git a/pkg/dependency/parser/java/jar/testdata/io.quarkus.gizmo.gizmo-1.1.1.Final.jar b/pkg/dependency/parser/java/jar/testdata/io.quarkus.gizmo.gizmo-1.1.jar similarity index 99% rename from pkg/dependency/parser/java/jar/testdata/io.quarkus.gizmo.gizmo-1.1.1.Final.jar rename to pkg/dependency/parser/java/jar/testdata/io.quarkus.gizmo.gizmo-1.1.jar index 080b15ba5e40ec9431d97d41fd2cd9afa29be811..3b82fae55ec99e93c949375061ebf7af82aa96bd 100644 GIT binary patch delta 2596 zcmdo0*7U$1(}ott7N!>F7M2#)7Pc1l7LFFq7OocV7M?A<<{9-KuoJ-S+y-uqLU451)7(nDefM>7oVO`O3+jtiLoI8ejWJ%`BGq zs2ek_DRS|9tGB+(CIu#^9~93lay&5ikH(j!-@Obrm#h|AZ1FYyGQ-brECw&W2AulETq4o7 zer@JSE{m&PoN0di*yj(KiX!#)Ang+sX(K0=$m{-5PErub$ zo0)|RsFi`?TgsCNFat`k0Ao8Tu}B|m%zEdxGzHf-bYl>@Wm8dgb3k>c<>y08_z5(D z%>~7TdQd6>86g6+l7m4BXhdDFMyw~0=L^JQNJbRo=js&{7!J(cf5T-?WyARu ztUjSDGFN~6X|*HnonDrXt*eBxPh#lKbC&9p*hJ5E+r6!C;LS9D>99z3fmOK5|7-7^ z-Hx|b^XcPH)F79^g9ntTS@FfYInZyuYRooXXnq5kP*9JVsJVb117S4JAt!1I;=O5fh-~_@r{X+?_tVC!CE2NZ1bK7*@QeG{_ zlhZ9qd2N`#W%7bbAjRo3fP%~>Szw;}^fw@01%#)k3vvU@Qp_R@YAMj_Esbi$U;`ip zT0PhWSPC0KxrGzFUTfglxXz~$VRc0K#YQ<1)y=D zw1Cw(T%{YbN8ON2Lr?QSvq5EDX+3JqitJX*T!`${`%uFnc@k(GsJO!8RLsH(Y+5}7 zupI!56va}A&#@Ir7gocGiJ)CTv*96%7D3SJ0+e=e70bxJ{sA?LSYKlnL&yY S*+6++6bP$7#IK@@7W0e delta 663 zcmX@`$8`T&(}ott7N!>F7M2#)7Pc1l7LFFq7OocV7M?A<<{9;20Y0IZ3thH{FfuTt zFflNQFfcIqx`sIFdiuHP`#So0y1532==r+!PB@)+$UwmL`@~QD{~9g$eOTf|SN!r= zxYj8#+H#w4Op>*)jNIQ}Qj3CIB167;81LFwe9Tzc>&YI&dy}sBUf^mLU|VOr($a8F ziJlB(ZTGsBZJi5}fZC&vR7d;KbZPUN2`J6P| zAs!zTpOwDHexGW%&vglv^@pNnb6i#0V-L)oViu)D*Gd;0d_n9|<*_)YVx^j>57!7tn zY%*Oii&uGiN-?j<^eM%>`Wy-`rp=r_<1p*?b>+NfjCLZR2;<;jz!r@_?O?E_Q8$AZ zYot!Ms^ryT+&n$ClGldmLFV+2mAp#RkAlSHrhlm94Q5ONQJT|pt9ZFJkgY;-BFr8j jy`@p07-WjZ^sHiDKCu9ARyL3