vulndb/internal/audit: skip loading vulns for local modules

Change-Id: Id3539c778e6f32e9e1c783eba9fadcd4ad074841
Reviewed-on: https://go-review.googlesource.com/c/exp/+/344611
Run-TryBot: Zvonimir Pavlinovic <zpavlinovic@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Roland Shoemaker <roland@golang.org>
Trust: Zvonimir Pavlinovic <zpavlinovic@google.com>
diff --git a/vulndb/internal/audit/vulnerability.go b/vulndb/internal/audit/vulnerability.go
index 600b193..50113f9 100644
--- a/vulndb/internal/audit/vulnerability.go
+++ b/vulndb/internal/audit/vulnerability.go
@@ -5,6 +5,11 @@
 package audit
 
 import (
+	"go/build"
+	"os"
+	"path/filepath"
+	"strings"
+
 	"golang.org/x/tools/go/packages"
 	"golang.org/x/vulndb/client"
 )
@@ -17,6 +22,13 @@
 		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
@@ -31,3 +43,23 @@
 	}
 	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
+}
diff --git a/vulndb/internal/audit/vulnerability_test.go b/vulndb/internal/audit/vulnerability_test.go
index 6a01e83..6a3346f 100644
--- a/vulndb/internal/audit/vulnerability_test.go
+++ b/vulndb/internal/audit/vulnerability_test.go
@@ -26,13 +26,15 @@
 			"example.mod/a": {{ID: "a", Affected: []osv.Affected{{Package: osv.Package{Name: "example.mod/a"}, Ranges: osv.Affects{{Type: osv.TypeSemver, Events: []osv.RangeEvent{{Fixed: "2.0.0"}}}}}}}},
 			"example.mod/b": {{ID: "b", Affected: []osv.Affected{{Package: osv.Package{Name: "example.mod/b"}, Ranges: osv.Affects{{Type: osv.TypeSemver, Events: []osv.RangeEvent{{Fixed: "1.1.1"}}}}}}}},
 			"example.mod/d": {{ID: "c", Affected: []osv.Affected{{Package: osv.Package{Name: "example.mod/d"}, Ranges: osv.Affects{{Type: osv.TypeSemver, Events: []osv.RangeEvent{{Fixed: "2.0.0"}}}}}}}},
+			"example.mod/e": {{ID: "e", Affected: []osv.Affected{{Package: osv.Package{Name: "example.mod/e"}, Ranges: osv.Affects{{Type: osv.TypeSemver, Events: []osv.RangeEvent{{Fixed: "2.2.0"}}}}}}}},
 		},
 	}
 
 	mv, err := FetchVulnerabilities(mc, []*packages.Module{
-		{Path: "example.mod/a", Version: "v1.0.0"},
-		{Path: "example.mod/b", Version: "v1.0.4"},
-		{Path: "example.mod/c", Replace: &packages.Module{Path: "example.mod/d", Version: "v1.0.0"}, Version: "v2.0.0"},
+		{Path: "example.mod/a", Dir: modCacheDirectory(), Version: "v1.0.0"},
+		{Path: "example.mod/b", Dir: modCacheDirectory(), Version: "v1.0.4"},
+		{Path: "example.mod/c", Replace: &packages.Module{Path: "example.mod/d", Dir: modCacheDirectory(), Version: "v1.0.0"}, Version: "v2.0.0"},
+		{Path: "example.mod/e", Replace: &packages.Module{Path: "../local/example.mod/d", Dir: modCacheDirectory(), Version: "v1.0.1"}, Version: "v2.1.0"},
 	})
 	if err != nil {
 		t.Fatalf("FetchVulnerabilities failed: %s", err)
@@ -40,19 +42,19 @@
 
 	expected := ModuleVulnerabilities{
 		{
-			mod: &packages.Module{Path: "example.mod/a", Version: "v1.0.0"},
+			mod: &packages.Module{Path: "example.mod/a", Dir: modCacheDirectory(), Version: "v1.0.0"},
 			vulns: []*osv.Entry{
 				{ID: "a", Affected: []osv.Affected{{Package: osv.Package{Name: "example.mod/a"}, Ranges: osv.Affects{{Type: osv.TypeSemver, Events: []osv.RangeEvent{{Fixed: "2.0.0"}}}}}}},
 			},
 		},
 		{
-			mod: &packages.Module{Path: "example.mod/b", Version: "v1.0.4"},
+			mod: &packages.Module{Path: "example.mod/b", Dir: modCacheDirectory(), Version: "v1.0.4"},
 			vulns: []*osv.Entry{
 				{ID: "b", Affected: []osv.Affected{{Package: osv.Package{Name: "example.mod/b"}, Ranges: osv.Affects{{Type: osv.TypeSemver, Events: []osv.RangeEvent{{Fixed: "1.1.1"}}}}}}},
 			},
 		},
 		{
-			mod: &packages.Module{Path: "example.mod/c", Replace: &packages.Module{Path: "example.mod/d", Version: "v1.0.0"}, Version: "v2.0.0"},
+			mod: &packages.Module{Path: "example.mod/c", Replace: &packages.Module{Path: "example.mod/d", Dir: modCacheDirectory(), Version: "v1.0.0"}, Version: "v2.0.0"},
 			vulns: []*osv.Entry{
 				{ID: "c", Affected: []osv.Affected{{Package: osv.Package{Name: "example.mod/d"}, Ranges: osv.Affects{{Type: osv.TypeSemver, Events: []osv.RangeEvent{{Fixed: "2.0.0"}}}}}}},
 			},