Skip to content

Commit

Permalink
suggest fixed version
Browse files Browse the repository at this point in the history
Signed-off-by: tomersein <[email protected]>
  • Loading branch information
tomersein committed Jan 4, 2025
1 parent 688fd41 commit a331bce
Showing 1 changed file with 27 additions and 51 deletions.
78 changes: 27 additions & 51 deletions grype/db/v5/search/cpe.go
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,33 @@ func addNewMatch(matchesByFingerprint map[match.Fingerprint]match.Match, vuln vu
candidateMatch = existingMatch
}

sortFixedVersions(candidateMatch, p)
// filter unrelated fixed versions in case fixed versions are larger than 1
if len(candidateMatch.Vulnerability.Fix.Versions) > 1 {
var filteredVersions []string
format := version.FormatFromPkg(p)
cons, err := version.GetConstraint(fmt.Sprintf("<=%s", candidateMatch.Package.Version), format)
if err != nil {
log.WithFields("package", p.Name).Trace("skipping filtering fixed versions")
}

for _, v := range candidateMatch.Vulnerability.Fix.Versions {
comparedVersion, err := version.NewVersion(v, format)
if err != nil {
log.WithFields("package", p.Name, "version", v).Trace("error while creating version in filtering fixed versions")
}
skip, err := cons.Satisfied(comparedVersion)
if err != nil {
log.WithFields("package", p.Name, "version", v).Trace("error while comparing version in filtering fixed versions")
continue
}
if skip {
continue
}
filteredVersions = append(filteredVersions, v)
}

candidateMatch.Vulnerability.Fix.Versions = filteredVersions
}

candidateMatch.Details = addMatchDetails(candidateMatch.Details,
match.Detail{
Expand Down Expand Up @@ -205,56 +231,6 @@ func addNewMatch(matchesByFingerprint map[match.Fingerprint]match.Match, vuln vu
matchesByFingerprint[candidateMatch.Fingerprint()] = candidateMatch
}

func sortFixedVersions(candidateMatch match.Match, p pkg.Package) {
if len(candidateMatch.Vulnerability.Fix.Versions) <= 1 {
return
}

format := version.FormatFromPkg(p)
parseConstraint := func(constStr string) (version.Constraint, error) {
constraint, err := version.GetConstraint(constStr, format)
if err != nil {
log.WithFields("package", p.Name).Trace("skipping sorting fixed versions")
}
return constraint, err
}

checkSatisfaction := func(constraint version.Constraint, v *version.Version) bool {
satisfied, err := constraint.Satisfied(v)
if err != nil {
log.WithFields("package", p.Name).Trace("error while checking version satisfaction for sorting")
}
return satisfied && err == nil
}

sort.SliceStable(candidateMatch.Vulnerability.Fix.Versions, func(i, j int) bool {
v1, err1 := version.NewVersion(candidateMatch.Vulnerability.Fix.Versions[i], format)
v2, err2 := version.NewVersion(candidateMatch.Vulnerability.Fix.Versions[j], format)
if err1 != nil || err2 != nil {
log.WithFields("package", p.Name).Trace("error while parsing version for sorting")
return false
}

packageConstraint, err := parseConstraint(fmt.Sprintf("<=%s", candidateMatch.Package.Version))
if err != nil {
return false
}

v1Satisfied := checkSatisfaction(packageConstraint, v1)
v2Satisfied := checkSatisfaction(packageConstraint, v2)

if v1Satisfied != v2Satisfied {
return !v1Satisfied
}

internalConstraint, err := parseConstraint(fmt.Sprintf("<=%s", v1.Raw))
if err != nil {
return false
}
return !checkSatisfaction(internalConstraint, v2)
})
}

func addMatchDetails(existingDetails []match.Detail, newDetails match.Detail) []match.Detail {
newFound, ok := newDetails.Found.(CPEResult)
if !ok {
Expand Down

0 comments on commit a331bce

Please sign in to comment.