Skip to content

Commit

Permalink
fix: disregard RPM module build number in version comparison
Browse files Browse the repository at this point in the history
Previously, different build numbers of the same RPM version release
string were compared lexicographically, leading to incorrect comparisons
between RedHat and RedHat clone RPMs, resulting in FPs or FNs on centOS.

Signed-off-by: Will Murphy <[email protected]>
  • Loading branch information
willmurphyscode committed Jan 14, 2025
1 parent ac48e0d commit 2b2cd45
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 2 deletions.
27 changes: 26 additions & 1 deletion grype/version/rpm_version.go
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,32 @@ func (v rpmVersion) compare(v2 rpmVersion) int {
return ret
}

return compareRpmVersions(v.release, v2.release)
return compareRpmReleases(v.release, v2.release)
}

// compareRpmReleases normalizes two release strigns before
// calling compareRpmVersions to compare them.
// It normalize the release strings by removing the build number
// from the end:
// "1.module_el8.3.0+757+d382997d" -> "1.module_el8.3.0"
// This is important because the build numbers are not identical between CentOS
// 8 and RHEL 8, even for the same package version, leading to FPs or FNs.
func compareRpmReleases(a, b string) int {
if a == b {
return 0
}

aParts := strings.Split(a, "+")
bParts := strings.Split(b, "+")
if len(aParts) > 2 {
aParts = aParts[:len(aParts)-2]
}
if len(bParts) > 2 {
bParts = bParts[:len(bParts)-2]
}
trimmedA := strings.Join(aParts, "+")
trimmedB := strings.Join(bParts, "+")
return compareRpmVersions(trimmedA, trimmedB)
}

func epochIsPresent(epoch *int) bool {
Expand Down
5 changes: 4 additions & 1 deletion grype/version/rpm_version_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,15 @@ func TestVersionRpm(t *testing.T) {
{"1:2", "1", 1},
{"0:4.19.1-1.el7_5", "2:4.19.1-1.el7_5", -1},
{"4:1.2.3-3-el7_5", "1.2.3-el7_5~snapshot1", 1},
//Non-standard comparisons that ignore epochs due to only one being available
// Non-standard comparisons that ignore epochs due to only one being available
{"1:0", "1", -1},
{"2:4.19.01-1.el7_5", "4.19.1-1.el7_5", 0},
{"4.19.01-1.el7_5", "2:4.19.1-1.el7_5", 0},
{"4.19.0-1.el7_5", "12:4.19.0-1.el7", 1},
{"3:4.19.0-1.el7_5", "4.21.0-1.el7", -1},
// centos and rhel build numbers differ on same version of same package
// ensure these are equal.
{"3:10.3.28-1.module_el8.3.0+757+d382997d", "3:10.3.28-1.module+el8.3.0+10472+7adc332a", 0},
}

for _, test := range tests {
Expand Down

0 comments on commit 2b2cd45

Please sign in to comment.