gopls/internal/vulncheck: synchronize cache access
Corresponds to
https://go.dev/cl/396594
adds basic support for cache thread safety
https://go.dev/cl/398115
change references to GCS bucket to vuln.go.dev
Change-Id: I16587a703431e1e28bc6d5f84ab54b4c88fcbdce
Reviewed-on: https://go-review.googlesource.com/c/tools/+/405794
Reviewed-by: Jonathan Amsterdam <jba@google.com>
diff --git a/gopls/internal/vulncheck/cache.go b/gopls/internal/vulncheck/cache.go
index 524ccfa..39a38fb 100644
--- a/gopls/internal/vulncheck/cache.go
+++ b/gopls/internal/vulncheck/cache.go
@@ -10,6 +10,7 @@
"io/ioutil"
"os"
"path/filepath"
+ "sync"
"time"
"golang.org/x/vuln/client"
@@ -18,12 +19,6 @@
// copy from x/vuln/cmd/govulncheck/cache.go
-// NOTE: this cache implementation should be kept internal to the go tooling
-// (i.e. cmd/go/internal/something) so that the vulndb cache is owned by the
-// go command. Also it is currently NOT CONCURRENCY SAFE since it does not
-// implement file locking. If ported to the stdlib it should use
-// cmd/go/internal/lockedfile.
-
// The cache uses a single JSON index file for each vulnerability database
// which contains the map from packages to the time the last
// vulnerability for that package was added/modified and the time that
@@ -42,9 +37,11 @@
// $GOPATH/pkg/mod/cache/download/vulndb/{db hostname}/{import path}/vulns.json
// []*osv.Entry
-// fsCache is file-system cache implementing osv.Cache
-// TODO: make cache thread-safe
+// fsCache is a thread-safe file-system cache implementing osv.Cache
+//
+// TODO: use something like cmd/go/internal/lockedfile for thread safety?
type fsCache struct {
+ mu sync.Mutex
rootDir string
}
@@ -61,6 +58,9 @@
}
func (c *fsCache) ReadIndex(dbName string) (client.DBIndex, time.Time, error) {
+ c.mu.Lock()
+ defer c.mu.Unlock()
+
b, err := ioutil.ReadFile(filepath.Join(c.rootDir, dbName, "index.json"))
if err != nil {
if os.IsNotExist(err) {
@@ -76,6 +76,9 @@
}
func (c *fsCache) WriteIndex(dbName string, index client.DBIndex, retrieved time.Time) error {
+ c.mu.Lock()
+ defer c.mu.Unlock()
+
path := filepath.Join(c.rootDir, dbName)
if err := os.MkdirAll(path, 0755); err != nil {
return err
@@ -94,6 +97,9 @@
}
func (c *fsCache) ReadEntries(dbName string, p string) ([]*osv.Entry, error) {
+ c.mu.Lock()
+ defer c.mu.Unlock()
+
b, err := ioutil.ReadFile(filepath.Join(c.rootDir, dbName, p, "vulns.json"))
if err != nil {
if os.IsNotExist(err) {
@@ -109,6 +115,9 @@
}
func (c *fsCache) WriteEntries(dbName string, p string, entries []*osv.Entry) error {
+ c.mu.Lock()
+ defer c.mu.Unlock()
+
path := filepath.Join(c.rootDir, dbName, p)
if err := os.MkdirAll(path, 0777); err != nil {
return err
diff --git a/gopls/internal/vulncheck/command.go b/gopls/internal/vulncheck/command.go
index 7040ae7..06ddacd 100644
--- a/gopls/internal/vulncheck/command.go
+++ b/gopls/internal/vulncheck/command.go
@@ -53,7 +53,7 @@
if GOVULNDB := os.Getenv("GOVULNDB"); GOVULNDB != "" {
return strings.Split(GOVULNDB, ",")
}
- return []string{"https://storage.googleapis.com/go-vulndb"}
+ return []string{"https://vuln.go.dev"}
}
type Vuln = command.Vuln