blob: 50113f959fcc75122005605a1d198aa29eeff689 [file] [log] [blame]
// Copyright 2021 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package audit
import (
"go/build"
"os"
"path/filepath"
"strings"
"golang.org/x/tools/go/packages"
"golang.org/x/vulndb/client"
)
// FetchVulnerabilities fetches vulnerabilities that affect the supplied modules.
func FetchVulnerabilities(client client.Client, modules []*packages.Module) (ModuleVulnerabilities, error) {
mv := ModuleVulnerabilities{}
for _, mod := range modules {
modPath := mod.Path
if mod.Replace != nil {
modPath = mod.Replace.Path
}
// skip loading vulns for local imports
if isLocal(mod) {
// TODO: what if client has its own db
// with local vulns?
continue
}
vulns, err := client.Get(modPath)
if err != nil {
return nil, err
}
if len(vulns) == 0 {
continue
}
mv = append(mv, modVulns{
mod: mod,
vulns: vulns,
})
}
return mv, nil
}
func isLocal(mod *packages.Module) bool {
modDir := mod.Dir
if mod.Replace != nil {
modDir = mod.Replace.Dir
}
return !strings.HasPrefix(modDir, modCacheDirectory())
}
func modCacheDirectory() string {
var modCacheDir string
// TODO: define modCacheDir using cmd/go/internal/cfg.GOMODCACHE
if modCacheDir = os.Getenv("GOMODCACHE"); modCacheDir == "" {
if modCacheDir = os.Getenv("GOPATH"); modCacheDir == "" {
modCacheDir = build.Default.GOPATH
}
modCacheDir = filepath.Join(modCacheDir, "pkg", "mod")
}
return modCacheDir
}