internal/frontend: use internal/vulns.VulnsForPackages

See https://go-review.git.corp.google.com/c/pkgsite/+/429677
for motivation.

VulnsForPackages can be outside of the frontend package too.

Change-Id: I98f49145e148ad82f6e0e6063390cd1d29a1f6e9
Reviewed-on: https://go-review.googlesource.com/c/pkgsite/+/444677
Reviewed-by: Jamal Carvalho <jamal@golang.org>
TryBot-Result: kokoro <noreply+kokoro@google.com>
Run-TryBot: Hyang-Ah Hana Kim <hyangah@gmail.com>
diff --git a/internal/frontend/vulns.go b/internal/frontend/vulns.go
index 3ab57f4..8549da0 100644
--- a/internal/frontend/vulns.go
+++ b/internal/frontend/vulns.go
@@ -6,15 +6,12 @@
 
 import (
 	"context"
-	"fmt"
 	"net/http"
 	"sort"
 	"strings"
 
-	"golang.org/x/mod/semver"
 	"golang.org/x/pkgsite/internal"
 	"golang.org/x/pkgsite/internal/derrors"
-	"golang.org/x/pkgsite/internal/stdlib"
 	"golang.org/x/pkgsite/internal/vulns"
 	"golang.org/x/sync/errgroup"
 	vulnc "golang.org/x/vuln/client"
@@ -25,63 +22,14 @@
 	githubAdvisoryUrlPrefix = "https://github.com/advisories/"
 	mitreAdvisoryUrlPrefix  = "https://cve.mitre.org/cgi-bin/cvename.cgi?name="
 	nistAdvisoryUrlPrefix   = "https://nvd.nist.gov/vuln/detail/"
-
-	// The vulndb stores vulns in cmd/go under the modulepath toolchain.
-	vulnCmdGoModulePath = "toolchain"
-	// The vulndb stores vulns under the modulepath stdlib for all other packages
-	// in the standard library.
-	vulnStdlibModulePath = "stdlib"
 )
 
 // A Vuln contains information to display about a vulnerability.
-type Vuln struct {
-	// The vulndb ID.
-	ID string
-	// A description of the vulnerability, or the problem in obtaining it.
-	Details string
-}
+type Vuln = vulns.Vuln
 
-type vulnEntriesFunc func(context.Context, string) ([]*osv.Entry, error)
+type vulnEntriesFunc = vulns.VulnEntriesFunc
 
-// VulnsForPackage obtains vulnerability information for the given package.
-// If packagePath is empty, it returns all entries for the module at version.
-// The getVulnEntries function should retrieve all entries for the given module path.
-// It is passed to facilitate testing.
-// If there is an error, VulnsForPackage returns a single Vuln that describes the error.
-func VulnsForPackage(ctx context.Context, modulePath, version, packagePath string, getVulnEntries vulnEntriesFunc) []Vuln {
-	vs, err := vulnsForPackage(ctx, modulePath, version, packagePath, getVulnEntries)
-	if err != nil {
-		return []Vuln{{Details: fmt.Sprintf("could not get vulnerability data: %v", err)}}
-	}
-	return vs
-}
-
-func vulnsForPackage(ctx context.Context, modulePath, version, packagePath string, getVulnEntries vulnEntriesFunc) (_ []Vuln, err error) {
-	defer derrors.Wrap(&err, "vulns(%q, %q, %q)", modulePath, version, packagePath)
-
-	if getVulnEntries == nil {
-		return nil, nil
-	}
-	if modulePath == stdlib.ModulePath && strings.HasPrefix(packagePath, "cmd/go") {
-		modulePath = vulnCmdGoModulePath
-	} else if modulePath == stdlib.ModulePath {
-		modulePath = vulnStdlibModulePath
-	}
-	// Get all the vulns for this module.
-	entries, err := getVulnEntries(ctx, modulePath)
-	if err != nil {
-		return nil, err
-	}
-	// Each entry describes a single vuln. Select the ones that apply to this
-	// package at this version.
-	var vulns []Vuln
-	for _, e := range entries {
-		if vuln, ok := entryVuln(e, packagePath, version); ok {
-			vulns = append(vulns, vuln)
-		}
-	}
-	return vulns, nil
-}
+var VulnsForPackage = vulns.VulnsForPackage
 
 // VulnListPage holds the information for a page that lists vuln entries.
 type VulnListPage struct {
@@ -121,47 +69,6 @@
 	return affected
 }
 
-func entryVuln(e *osv.Entry, packagePath, version string) (Vuln, bool) {
-	for _, a := range e.Affected {
-		if !a.Ranges.AffectsSemver(version) {
-			continue
-		}
-		if packageMatches := func() bool {
-			if packagePath == "" {
-				return true //  match module only
-			}
-			if len(a.EcosystemSpecific.Imports) == 0 {
-				return true // no package info available, so match on module
-			}
-			for _, p := range a.EcosystemSpecific.Imports {
-				if packagePath == p.Path {
-					return true // package matches
-				}
-			}
-			return false
-		}(); !packageMatches {
-			continue
-		}
-		// Choose the latest fixed version, if any.
-		var fixed string
-		for _, r := range a.Ranges {
-			if r.Type == osv.TypeGit {
-				continue
-			}
-			for _, re := range r.Events {
-				if re.Fixed != "" && (fixed == "" || semver.Compare(re.Fixed, fixed) > 0) {
-					fixed = re.Fixed
-				}
-			}
-		}
-		return Vuln{
-			ID:      e.ID,
-			Details: e.Details,
-		}, true
-	}
-	return Vuln{}, false
-}
-
 func (s *Server) serveVuln(w http.ResponseWriter, r *http.Request, _ internal.DataSource) error {
 	path := strings.TrimPrefix(r.URL.Path, "/vuln")
 	switch path {
diff --git a/internal/vulns/vulns.go b/internal/vulns/vulns.go
index 303bafa..80df880 100644
--- a/internal/vulns/vulns.go
+++ b/internal/vulns/vulns.go
@@ -33,14 +33,14 @@
 	Details string
 }
 
-type vulnEntriesFunc func(context.Context, string) ([]*osv.Entry, error)
+type VulnEntriesFunc func(context.Context, string) ([]*osv.Entry, error)
 
 // VulnsForPackage obtains vulnerability information for the given package.
 // If packagePath is empty, it returns all entries for the module at version.
 // The getVulnEntries function should retrieve all entries for the given module path.
 // It is passed to facilitate testing.
 // If there is an error, VulnsForPackage returns a single Vuln that describes the error.
-func VulnsForPackage(ctx context.Context, modulePath, version, packagePath string, getVulnEntries vulnEntriesFunc) []Vuln {
+func VulnsForPackage(ctx context.Context, modulePath, version, packagePath string, getVulnEntries VulnEntriesFunc) []Vuln {
 	vs, err := vulnsForPackage(ctx, modulePath, version, packagePath, getVulnEntries)
 	if err != nil {
 		return []Vuln{{Details: fmt.Sprintf("could not get vulnerability data: %v", err)}}
@@ -48,7 +48,7 @@
 	return vs
 }
 
-func vulnsForPackage(ctx context.Context, modulePath, version, packagePath string, getVulnEntries vulnEntriesFunc) (_ []Vuln, err error) {
+func vulnsForPackage(ctx context.Context, modulePath, version, packagePath string, getVulnEntries VulnEntriesFunc) (_ []Vuln, err error) {
 	defer derrors.Wrap(&err, "vulns(%q, %q, %q)", modulePath, version, packagePath)
 
 	if getVulnEntries == nil {