Skip to content

Commit b445f27

Browse files
committed
cmd/govulncheck: fail in GOPATH mode
govulncheck requires module information to find vulnerabilities. But in GOPATH mode, there is no module information. Instead of silently succeeding in that case, govulncheck fails with an error. Also, fix an off-by-one bug that could result in a panic if only the top function in a call stack is in a top package. Fixes golang/go#51591 Change-Id: I9923c1f03aa0a101de86fe03daaeeefc1d1f5bdf Reviewed-on: https://go-review.googlesource.com/c/exp/+/394774 Trust: Jonathan Amsterdam <[email protected]> Run-TryBot: Jonathan Amsterdam <[email protected]> TryBot-Result: Gopher Robot <[email protected]> Reviewed-by: Zvonimir Pavlinovic <[email protected]>
1 parent a90fa8a commit b445f27

File tree

1 file changed

+19
-12
lines changed

1 file changed

+19
-12
lines changed

cmd/govulncheck/main.go

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -88,8 +88,11 @@ func main() {
8888
ctx := context.Background()
8989

9090
patterns := flag.Args()
91-
var r *vulncheck.Result
92-
var pkgs []*packages.Package
91+
var (
92+
r *vulncheck.Result
93+
pkgs []*packages.Package
94+
moduleVersions map[string]string
95+
)
9396
if len(patterns) == 1 && isFile(patterns[0]) {
9497
f, err := os.Open(patterns[0])
9598
if err != nil {
@@ -110,6 +113,17 @@ func main() {
110113
if err != nil {
111114
die("govulncheck: %v", err)
112115
}
116+
// Build a map from module paths to versions.
117+
moduleVersions = map[string]string{}
118+
packages.Visit(pkgs, nil, func(p *packages.Package) {
119+
if m := packageModule(p); m != nil {
120+
moduleVersions[m.Path] = m.Version
121+
}
122+
})
123+
124+
if len(moduleVersions) == 0 {
125+
die("govulncheck: no modules found; are you in GOPATH mode? Module mode required.")
126+
}
113127
r, err = vulncheck.Source(ctx, vulncheck.Convert(pkgs), vcfg)
114128
if err != nil {
115129
die("govulncheck: %v", err)
@@ -118,7 +132,7 @@ func main() {
118132
if *jsonFlag {
119133
writeJSON(r)
120134
} else {
121-
writeText(r, pkgs)
135+
writeText(r, pkgs, moduleVersions)
122136
}
123137
exitCode := 0
124138
// Following go vet, fail with 3 if there are findings (in this case, vulns).
@@ -137,17 +151,10 @@ func writeJSON(r *vulncheck.Result) {
137151
fmt.Println()
138152
}
139153

140-
func writeText(r *vulncheck.Result, pkgs []*packages.Package) {
154+
func writeText(r *vulncheck.Result, pkgs []*packages.Package, moduleVersions map[string]string) {
141155
if len(r.Vulns) == 0 {
142156
return
143157
}
144-
// Build a map from module paths to versions.
145-
moduleVersions := map[string]string{}
146-
packages.Visit(pkgs, nil, func(p *packages.Package) {
147-
if m := packageModule(p); m != nil {
148-
moduleVersions[m.Path] = m.Version
149-
}
150-
})
151158
callStacks := vulncheck.CallStacks(r)
152159

153160
const labelWidth = 16
@@ -283,7 +290,7 @@ func representativeFuncs(vg []*vulncheck.Vuln, topPkgs map[string]bool, callStac
283290
for _, cs := range callStacks[v] {
284291
// Find the lowest function in the stack that is in
285292
// one of the top packages.
286-
for i := len(cs) - 1; i > 0; i-- {
293+
for i := len(cs) - 1; i >= 0; i-- {
287294
pkg := pkgPath(cs[i].Function)
288295
if topPkgs[pkg] {
289296
fns[cs[i].Function] = true

0 commit comments

Comments
 (0)