internal/vulncheck: emit package findings all at once

Emitting one by one does not provide much benefits as traversal of
package import graphs is done fast. Emitting all at once makes the code
more consistent.

Change-Id: I9cb2617aeb60efa85c584bb41286d247af4d78c1
Reviewed-on: https://go-review.googlesource.com/c/vuln/+/539735
Run-TryBot: Zvonimir Pavlinovic <zpavlinovic@google.com>
Reviewed-by: Maceo Thompson <maceothompson@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
This commit is contained in:
Zvonimir Pavlinovic 2023-11-03 14:19:55 -07:00
Родитель d9895b7aff
Коммит 94af419e51
2 изменённых файлов: 35 добавлений и 14 удалений

Просмотреть файл

@ -41,6 +41,33 @@ func emitModuleFindings(handler govulncheck.Handler, affVulns affectingVulns) er
return nil
}
// emitPackageFinding emits package-level findings fod vulnerabilities in vulns.
//
// It does not emit imported symbols. Only the package information is emitted.
func emitPackageFindings(handler govulncheck.Handler, vulns []*Vuln) error {
emitted := make(map[Vuln]bool)
for _, vuln := range vulns {
v := Vuln{
Package: vuln.Package,
OSV: vuln.OSV,
}
if emitted[v] {
// do not emit the same finding all over again
continue
}
emitted[v] = true
if err := handler.Finding(&govulncheck.Finding{
OSV: v.OSV.ID,
FixedVersion: FixedVersion(modPath(v.Package.Module), modVersion(v.Package.Module), v.OSV.Affected),
Trace: []*govulncheck.Frame{frameFromPackage(v.Package)},
}); err != nil {
return err
}
}
return nil
}
// emitCallFindings emits call-level findings for vulnerabilities
// that have a call stack in callstacks.
func emitCallFindings(handler govulncheck.Handler, callstacks map[*Vuln]CallStack) error {
@ -70,14 +97,6 @@ func emitCallFindings(handler govulncheck.Handler, callstacks map[*Vuln]CallStac
return nil
}
func emitPackageFinding(handler govulncheck.Handler, vuln *Vuln) error {
return handler.Finding(&govulncheck.Finding{
OSV: vuln.OSV.ID,
FixedVersion: FixedVersion(modPath(vuln.Package.Module), modVersion(vuln.Package.Module), vuln.OSV.Affected),
Trace: []*govulncheck.Frame{frameFromPackage(vuln.Package)},
})
}
// tracefromEntries creates a sequence of
// frames from vcs. Position of a Frame is the
// call position of the corresponding stack entry.

Просмотреть файл

@ -81,7 +81,13 @@ func source(ctx context.Context, handler govulncheck.Handler, pkgs []*packages.P
return result, nil
}
importedVulnSymbols(pkgs, affVulns, result, handler)
importedVulnSymbols(pkgs, affVulns, result)
// Emit information on imported vulnerable packages now as
// call graph computation might take a while.
if err := emitPackageFindings(handler, result.Vulns); err != nil {
return nil, err
}
// Return result immediately if not in symbol mode or
// if there are no vulnerabilities imported.
if !cfg.ScanLevel.WantSymbols() || len(result.Vulns) == 0 {
@ -98,7 +104,7 @@ func source(ctx context.Context, handler govulncheck.Handler, pkgs []*packages.P
}
// importedVulnSymbols detects imported vulnerable symbols.
func importedVulnSymbols(pkgs []*packages.Package, affVulns affectingVulns, result *Result, handler govulncheck.Handler) {
func importedVulnSymbols(pkgs []*packages.Package, affVulns affectingVulns, result *Result) {
analyzed := make(map[*packages.Package]bool) // skip analyzing the same package multiple times
var vulnImports func(pkg *packages.Package)
vulnImports = func(pkg *packages.Package) {
@ -119,10 +125,6 @@ func importedVulnSymbols(pkgs []*packages.Package, affVulns affectingVulns, resu
if len(symbols) == 0 {
symbols = allSymbols(pkg.Types)
}
emitPackageFinding(handler, &Vuln{
OSV: osv,
Package: pkg,
})
for _, symbol := range symbols {
vuln := &Vuln{
OSV: osv,