internal/govulncheck: report only version for Summary.FixedIn/FoundIn

Initially I thought <pkgpath>@<version> may be helpful when the
suggested fix requires to use different package/module than the
currently used package. However, that can be a non-trivial change
most likely, and it's better to communicate differently instead.

Include only the version (either 'v' or 'go' prefixed).

This change does not affect the regular govulncheck text output format
but affects the version fields of Summary type.

Change-Id: I6712ad760349f05e7b092ea3c9c758863600b03e
Reviewed-on: https://go-review.googlesource.com/c/vuln/+/440217
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Julie Qiu <julieqiu@google.com>
Run-TryBot: Hyang-Ah Hana Kim <hyangah@gmail.com>
diff --git a/cmd/govulncheck/testdata/json-summary.ct b/cmd/govulncheck/testdata/json-summary.ct
index bc1fb7a..0baaccc 100644
--- a/cmd/govulncheck/testdata/json-summary.ct
+++ b/cmd/govulncheck/testdata/json-summary.ct
@@ -74,8 +74,8 @@
 			},
 			"PkgPath": "golang.org/x/text/language",
 			"ModPath": "golang.org/x/text",
-			"FoundIn": "golang.org/x/text/language@v0.3.0",
-			"FixedIn": "golang.org/x/text/language@v0.3.7",
+			"FoundIn": "v0.3.0",
+			"FixedIn": "v0.3.7",
 			"Trace": [
 				{
 					"Symbol": "Parse",
@@ -166,8 +166,8 @@
 			},
 			"PkgPath": "github.com/tidwall/gjson",
 			"ModPath": "github.com/tidwall/gjson",
-			"FoundIn": "github.com/tidwall/gjson@v1.9.2",
-			"FixedIn": "github.com/tidwall/gjson@v1.9.3",
+			"FoundIn": "v1.9.2",
+			"FixedIn": "v1.9.3",
 			"Trace": null
 		},
 		{
@@ -260,8 +260,8 @@
 			},
 			"PkgPath": "github.com/tidwall/gjson",
 			"ModPath": "github.com/tidwall/gjson",
-			"FoundIn": "github.com/tidwall/gjson@v1.9.2",
-			"FixedIn": "github.com/tidwall/gjson@v1.9.3",
+			"FoundIn": "v1.9.2",
+			"FixedIn": "v1.9.3",
 			"Trace": null
 		}
 	]
diff --git a/internal/govulncheck/run.go b/internal/govulncheck/run.go
index 1b62670..49a95bc 100644
--- a/internal/govulncheck/run.go
+++ b/internal/govulncheck/run.go
@@ -162,8 +162,8 @@
 		v0 := vg[0]
 		id := v0.OSV.ID
 		details := wrap(v0.OSV.Details, 80-labelWidth)
-		found := foundVersion(v0.ModPath, v0.PkgPath, ci)
-		fixed := fixedVersion(v0.ModPath, v0.PkgPath, v0.OSV.Affected)
+		found := packageVersionString(v0.PkgPath, foundVersion(v0.ModPath, ci))
+		fixed := packageVersionString(v0.PkgPath, fixedVersion(v0.ModPath, v0.OSV.Affected))
 
 		// TODO(https://go.dev/issue/56042): add stacks to govulncheck.Result.
 		var stacks string
@@ -185,8 +185,8 @@
 		fmt.Println()
 		fmt.Println(informationalMessage)
 		for idx, vuln := range unaffected {
-			found := foundVersion(vuln.ModPath, vuln.PkgPath, ci)
-			fixed := fixedVersion(vuln.ModPath, vuln.PkgPath, vuln.OSV.Affected)
+			found := packageVersionString(vuln.PkgPath, foundVersion(vuln.ModPath, ci))
+			fixed := packageVersionString(vuln.PkgPath, fixedVersion(vuln.ModPath, vuln.OSV.Affected))
 			fmt.Println()
 			writeVulnerability(idx+1, vuln.OSV.ID, vuln.OSV.Details, "", found, fixed, platforms(vuln.OSV))
 		}
@@ -208,18 +208,18 @@
 `, idx, id, indent(details, 2), callstack, found, fixed, platforms, id)
 }
 
-func foundVersion(modulePath, pkgPath string, ci *callInfo) string {
+func foundVersion(modulePath string, ci *callInfo) string {
 	var found string
 	if v := ci.moduleVersions[modulePath]; v != "" {
-		found = packageVersionString(modulePath, pkgPath, v[1:])
+		found = versionString(modulePath, v[1:])
 	}
 	return found
 }
 
-func fixedVersion(modulePath, pkgPath string, affected []osv.Affected) string {
+func fixedVersion(modulePath string, affected []osv.Affected) string {
 	fixed := LatestFixed(affected)
 	if fixed != "" {
-		fixed = packageVersionString(modulePath, pkgPath, fixed)
+		fixed = versionString(modulePath, fixed)
 	}
 	return fixed
 }
@@ -319,12 +319,24 @@
 	return s[:i]
 }
 
-func packageVersionString(modulePath, packagePath, version string) string {
-	v := "v" + version
-	if modulePath == internal.GoStdModulePath {
-		v = semverToGoTag(v)
+func packageVersionString(packagePath, version string) string {
+	if version == "" {
+		return ""
 	}
-	return fmt.Sprintf("%s@%s", packagePath, v)
+	return fmt.Sprintf("%s@%s", packagePath, version)
+}
+
+// versionString prepends a version string prefix (`v` or `go`
+// depending on the modulePath) to the given semver-style version string.
+func versionString(modulePath, version string) string {
+	if version == "" {
+		return ""
+	}
+	v := "v" + version
+	if modulePath == internal.GoStdModulePath || modulePath == internal.GoCmdModulePath {
+		return semverToGoTag(v)
+	}
+	return v
 }
 
 // indent returns the output of prefixing n spaces to s at every line break,
diff --git a/internal/govulncheck/summary.go b/internal/govulncheck/summary.go
index 2a6ff63..7102cff 100644
--- a/internal/govulncheck/summary.go
+++ b/internal/govulncheck/summary.go
@@ -25,8 +25,8 @@
 	OSV     *osv.Entry
 	PkgPath string // Package path.
 	ModPath string // Module path.
-	FoundIn string // <package path>@<version> if we know when it was introduced. Empty otherwise.
-	FixedIn string // <package path>@<version> if fix is available. Empty otherwise.
+	FoundIn string // Module version used in the analyzed code. Empty if unknown.
+	FixedIn string // Fixed version if fix is available. Empty otherwise.
 	// Trace contains a call stack for each affecting symbol.
 	// For vulnerabilities found from binary analysis, and vulnerabilities
 	// that are reported as Unaffecting ones, this will be always empty.
@@ -60,8 +60,8 @@
 			OSV:     vg[0].OSV,
 			PkgPath: v0.PkgPath,
 			ModPath: v0.ModPath,
-			FoundIn: foundVersion(v0.ModPath, v0.PkgPath, ci),
-			FixedIn: fixedVersion(v0.ModPath, v0.PkgPath, v0.OSV.Affected),
+			FoundIn: foundVersion(v0.ModPath, ci),
+			FixedIn: fixedVersion(v0.ModPath, v0.OSV.Affected),
 			Trace:   stacks,
 		})
 	}
@@ -70,8 +70,8 @@
 			OSV:     vuln.OSV,
 			PkgPath: vuln.PkgPath,
 			ModPath: vuln.ModPath,
-			FoundIn: foundVersion(vuln.ModPath, vuln.PkgPath, ci),
-			FixedIn: fixedVersion(vuln.ModPath, vuln.PkgPath, vuln.OSV.Affected),
+			FoundIn: foundVersion(vuln.ModPath, ci),
+			FixedIn: fixedVersion(vuln.ModPath, vuln.OSV.Affected),
 		})
 	}
 	return Summary{