internal/frontend: list vulnerabilities for standard libraries

Translates the module paths for standard lib packages into
the vulndb specific module names. Packages under cmd/go map
to module path 'toolchain' and other packages in the standard
library, 'stdlib'.

Fixes golang/go#54843.

Change-Id: Ic485466dc31b2b09fb293618bb450034e0800264
Reviewed-on: https://go-review.googlesource.com/c/pkgsite/+/431838
Reviewed-by: Hyang-Ah Hana Kim <hyangah@gmail.com>
Run-TryBot: Jamal Carvalho <jamal@golang.org>
TryBot-Result: kokoro <noreply+kokoro@google.com>
Reviewed-by: Jonathan Amsterdam <jba@google.com>
diff --git a/internal/frontend/versions.go b/internal/frontend/versions.go
index a364033..5de5270 100644
--- a/internal/frontend/versions.go
+++ b/internal/frontend/versions.go
@@ -113,7 +113,7 @@
 		}
 		return constructUnitURL(versionPath, mi.ModulePath, linkVersion(mi.ModulePath, mi.Version, mi.Version))
 	}
-	return buildVersionDetails(ctx, um.ModulePath, versions, sh, linkify, getVulnEntries), nil
+	return buildVersionDetails(ctx, um.ModulePath, um.Path, versions, sh, linkify, getVulnEntries), nil
 }
 
 // pathInVersion constructs the full import path of the package corresponding
@@ -141,7 +141,7 @@
 // versions tab, organizing major versions into those that have the same module
 // path as the package version under consideration, and those that don't.  The
 // given versions MUST be sorted first by module path and then by semver.
-func buildVersionDetails(ctx context.Context, currentModulePath string,
+func buildVersionDetails(ctx context.Context, currentModulePath, packagePath string,
 	modInfos []*internal.ModuleInfo,
 	sh *internal.SymbolHistory,
 	linkify func(v *internal.ModuleInfo) string,
@@ -195,7 +195,12 @@
 		if sv := sh.SymbolsAtVersion(mi.Version); sv != nil {
 			vs.Symbols = symbolsForVersion(linkify(mi), sv)
 		}
-		vs.Vulns = VulnsForPackage(ctx, mi.ModulePath, mi.Version, "", getVulnEntries)
+		// Show only package level vulnerability warnings on stdlib version pages.
+		pkg := ""
+		if mi.ModulePath == stdlib.ModulePath {
+			pkg = packagePath
+		}
+		vs.Vulns = VulnsForPackage(ctx, mi.ModulePath, mi.Version, pkg, getVulnEntries)
 		vl := lists[key]
 		if vl == nil {
 			seenLists = append(seenLists, key)
diff --git a/internal/frontend/vulns.go b/internal/frontend/vulns.go
index 358617f..e797a20 100644
--- a/internal/frontend/vulns.go
+++ b/internal/frontend/vulns.go
@@ -14,6 +14,7 @@
 	"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"
@@ -24,6 +25,12 @@
 	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.
@@ -55,6 +62,11 @@
 	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 {