Skip to content

Commit 2aa57d2

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 Cherry-picked: https://go-review.googlesource.com/c/exp/+/394774 Change-Id: I9923c1f03aa0a101de86fe03daaeeefc1d1f5bdf Reviewed-on: https://go-review.googlesource.com/c/vuln/+/395241 Trust: Julie Qiu <julie@golang.org> Run-TryBot: Julie Qiu <julie@golang.org> Reviewed-by: Jonathan Amsterdam <jba@google.com> TryBot-Result: Gopher Robot <gobot@golang.org>
1 parent ef4735b commit 2aa57d2

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
@@ -91,8 +91,11 @@ func main() {
9191
ctx := context.Background()
9292

9393
patterns := flag.Args()
94-
var r *vulncheck.Result
95-
var pkgs []*packages.Package
94+
var (
95+
r *vulncheck.Result
96+
pkgs []*packages.Package
97+
moduleVersions map[string]string
98+
)
9699
if len(patterns) == 1 && isFile(patterns[0]) {
97100
f, err := os.Open(patterns[0])
98101
if err != nil {
@@ -113,6 +116,17 @@ func main() {
113116
if err != nil {
114117
die("govulncheck: %v", err)
115118
}
119+
// Build a map from module paths to versions.
120+
moduleVersions = map[string]string{}
121+
packages.Visit(pkgs, nil, func(p *packages.Package) {
122+
if m := packageModule(p); m != nil {
123+
moduleVersions[m.Path] = m.Version
124+
}
125+
})
126+
127+
if len(moduleVersions) == 0 {
128+
die("govulncheck: no modules found; are you in GOPATH mode? Module mode required.")
129+
}
116130
r, err = vulncheck.Source(ctx, vulncheck.Convert(pkgs), vcfg)
117131
if err != nil {
118132
die("govulncheck: %v", err)
@@ -121,7 +135,7 @@ func main() {
121135
if *jsonFlag {
122136
writeJSON(r)
123137
} else {
124-
writeText(r, pkgs)
138+
writeText(r, pkgs, moduleVersions)
125139
}
126140
exitCode := 0
127141
// Following go vet, fail with 3 if there are findings (in this case, vulns).
@@ -140,17 +154,10 @@ func writeJSON(r *vulncheck.Result) {
140154
fmt.Println()
141155
}
142156

143-
func writeText(r *vulncheck.Result, pkgs []*packages.Package) {
157+
func writeText(r *vulncheck.Result, pkgs []*packages.Package, moduleVersions map[string]string) {
144158
if len(r.Vulns) == 0 {
145159
return
146160
}
147-
// Build a map from module paths to versions.
148-
moduleVersions := map[string]string{}
149-
packages.Visit(pkgs, nil, func(p *packages.Package) {
150-
if m := packageModule(p); m != nil {
151-
moduleVersions[m.Path] = m.Version
152-
}
153-
})
154161
callStacks := vulncheck.CallStacks(r)
155162

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

0 commit comments

Comments
 (0)