Skip to content

Commit e6debf3

Browse files
committed
Create SetOutcome function to handle updating conversion status
1 parent 0b8caa5 commit e6debf3

3 files changed

Lines changed: 50 additions & 29 deletions

File tree

vulnfeeds/conversion/common.go

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -243,18 +243,6 @@ func GitVersionsToCommits(versionRanges []*osvschema.Range, repos []string, metr
243243
unresolvedRanges = stillUnresolvedRanges
244244
}
245245

246-
if len(newVersionRanges) > 0 {
247-
metrics.ResolvedRangesCount += len(newVersionRanges)
248-
metrics.Outcome = models.Successful
249-
}
250-
251-
if len(unresolvedRanges) > 0 {
252-
metrics.UnresolvedRangesCount += len(unresolvedRanges)
253-
if len(newVersionRanges) == 0 {
254-
metrics.Outcome = models.NoCommitRanges
255-
}
256-
}
257-
258246
return newVersionRanges, unresolvedRanges, successfulRepos
259247
}
260248

vulnfeeds/conversion/nvd/converter.go

Lines changed: 38 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,9 @@ func CVEToOSV(cve models.NVDCVE, repos []string, cache *git.RepoTagsCache, direc
6161

6262
// Exit early if there are no repositories
6363
if len(repos) == 0 {
64-
affected := MergeRangesAndCreateAffected(resolvedRanges, unresolvedRanges, nil, nil, metrics)
64+
metrics.SetOutcome(models.NoRepos)
65+
metrics.UnresolvedRangesCount += len(cpeRanges)
66+
affected := MergeRangesAndCreateAffected(resolvedRanges, cpeRanges, nil, nil, metrics)
6567
v.Affected = append(v.Affected, affected)
6668
// Exit early
6769
outputFiles(v, directory, maybeVendorName, maybeProductName, metrics, rejectFailed, outputMetrics)
@@ -72,8 +74,20 @@ func CVEToOSV(cve models.NVDCVE, repos []string, cache *git.RepoTagsCache, direc
7274
// If we have ranges, try to resolve them
7375
if len(cpeRanges) > 0 {
7476
r, un, sR := conversion.GitVersionsToCommits(cpeRanges, repos, metrics, cache)
75-
resolvedRanges = append(resolvedRanges, r...)
76-
unresolvedRanges = append(unresolvedRanges, un...)
77+
if len(r) > 0 {
78+
metrics.ResolvedRangesCount += len(r)
79+
resolvedRanges = append(resolvedRanges, r...)
80+
metrics.SetOutcome(models.Successful)
81+
}
82+
83+
if len(un) > 0 {
84+
metrics.UnresolvedRangesCount += len(un)
85+
unresolvedRanges = append(unresolvedRanges, un...)
86+
if len(r) == 0 {
87+
metrics.SetOutcome(models.NoCommitRanges)
88+
}
89+
}
90+
7791
for _, s := range sR {
7892
successfulRepos[s] = true
7993
}
@@ -90,6 +104,7 @@ func CVEToOSV(cve models.NVDCVE, repos []string, cache *git.RepoTagsCache, direc
90104
for _, commit := range commits {
91105
successfulRepos[commit.Repo] = true
92106
}
107+
metrics.SetOutcome(models.Successful)
93108
metrics.VersionSources = append(metrics.VersionSources, models.VersionSourceRefs)
94109
}
95110

@@ -100,8 +115,19 @@ func CVEToOSV(cve models.NVDCVE, repos []string, cache *git.RepoTagsCache, direc
100115
metrics.AddNote("Extracted versions from description: %v", textRanges)
101116
}
102117
r, un, sR := conversion.GitVersionsToCommits(textRanges, repos, metrics, cache)
103-
resolvedRanges = append(resolvedRanges, r...)
104-
unresolvedRanges = append(unresolvedRanges, un...)
118+
if len(r) > 0 {
119+
metrics.ResolvedRangesCount += len(r)
120+
resolvedRanges = append(resolvedRanges, r...)
121+
metrics.SetOutcome(models.Successful)
122+
}
123+
124+
if len(un) > 0 {
125+
metrics.UnresolvedRangesCount += len(un)
126+
unresolvedRanges = append(unresolvedRanges, un...)
127+
if len(r) == 0 {
128+
metrics.SetOutcome(models.NoCommitRanges)
129+
}
130+
}
105131
for _, s := range sR {
106132
successfulRepos[s] = true
107133
}
@@ -110,13 +136,14 @@ func CVEToOSV(cve models.NVDCVE, repos []string, cache *git.RepoTagsCache, direc
110136

111137
if len(resolvedRanges) == 0 && len(commits) == 0 {
112138
metrics.AddNote("No ranges detected for %q", maybeProductName)
113-
metrics.Outcome = models.NoRanges
114-
} else {
115-
keys := slices.Collect(maps.Keys(successfulRepos))
116-
affected := MergeRangesAndCreateAffected(resolvedRanges, unresolvedRanges, commits, keys, metrics)
117-
v.Affected = append(v.Affected, affected)
139+
metrics.SetOutcome(models.NoRanges)
118140
}
119141

142+
// Use the successful repos for more efficient merging.
143+
keys := slices.Collect(maps.Keys(successfulRepos))
144+
affected := MergeRangesAndCreateAffected(resolvedRanges, unresolvedRanges, commits, keys, metrics)
145+
v.Affected = append(v.Affected, affected)
146+
120147
if !outputMetrics && rejectFailed && metrics.Outcome != models.Successful {
121148
return metrics.Outcome
122149
}
@@ -239,7 +266,7 @@ func FindRepos(cve models.NVDCVE, vpRepoCache *cves.VPRepoCache, repoTagsCache *
239266
if len(refs) == 0 && len(CPEs) == 0 {
240267
metrics.AddNote("Skipping due to lack of CPEs and lack of references")
241268
// 100% of these in 2022 were rejected CVEs
242-
metrics.Outcome = models.Rejected
269+
metrics.SetOutcome(models.Rejected)
243270

244271
return nil
245272
}
@@ -297,7 +324,6 @@ func FindRepos(cve models.NVDCVE, vpRepoCache *cves.VPRepoCache, repoTagsCache *
297324
if len(reposForCVE) == 0 {
298325
// We have nothing useful to work with, so we'll assume it's out of scope
299326
metrics.AddNote("Passing due to lack of viable repository")
300-
metrics.Outcome = models.NoRepos
301327

302328
return nil
303329
}
@@ -360,7 +386,6 @@ func MergeRangesAndCreateAffected(resolvedRanges []*osvschema.Range, unresolvedR
360386
newResolvedRanges = append(newResolvedRanges, conversion.BuildVersionRange(commit.Introduced, commit.LastAffected, commit.Fixed))
361387
metrics.ResolvedRangesCount++
362388
}
363-
metrics.Outcome = models.Successful
364389
}
365390

366391
newAffected := &osvschema.Affected{

vulnfeeds/models/metrics.go

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,14 @@ func (m *ConversionMetrics) AddNote(format string, a ...any) {
5959
logger.Debug(fmt.Sprintf(format, a...), slog.String("cna", m.CNA), slog.String("cve", string(m.CVEID)))
6060
}
6161

62+
// SetOutcome sets the outcome of the conversion only if it's not already set, or has become successful.
63+
func (m *ConversionMetrics) SetOutcome(outcome ConversionOutcome) {
64+
if m.Outcome != ConversionUnknown || outcome != Successful {
65+
return
66+
}
67+
m.Outcome = outcome
68+
}
69+
6270
// AddSource appends a source to the ConversionMetrics
6371
func (m *ConversionMetrics) AddSource(source VersionSource) {
6472
m.VersionSources = append(m.VersionSources, source)
@@ -80,15 +88,15 @@ func DetermineOutcome(metrics *ConversionMetrics) {
8088
// check if we have affected ranges/versions.
8189
if len(metrics.Repos) == 0 {
8290
// Fix unlikely, as no repos to resolve
83-
metrics.Outcome = NoRepos
91+
metrics.SetOutcome(NoRepos)
8492
return
8593
}
8694

8795
if metrics.ResolvedRangesCount > 0 {
88-
metrics.Outcome = Successful
96+
metrics.SetOutcome(Successful)
8997
} else if metrics.UnresolvedRangesCount > 0 {
90-
metrics.Outcome = NoCommitRanges
98+
metrics.SetOutcome(NoCommitRanges)
9199
} else {
92-
metrics.Outcome = NoRanges
100+
metrics.SetOutcome(NoRanges)
93101
}
94102
}

0 commit comments

Comments
 (0)