client: query index in GetByModule for localSource

This keeps logic in sync with httpSource and supports local development
where top-level module names are invalid, aka, "moduleX". Otherwise,
EscapeModulePath needs to be changed.

Fixes golang/go#56179

Change-Id: Ic91c89155cb985ddcd56e812ce48497a4c87812c
Reviewed-on: https://go-review.googlesource.com/c/vuln/+/442975
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Jonathan Amsterdam <jba@google.com>
Run-TryBot: Zvonimir Pavlinovic <zpavlinovic@google.com>
Reviewed-by: Hyang-Ah Hana Kim <hyangah@gmail.com>
diff --git a/client/client.go b/client/client.go
index 31a5e34..be6ce68 100644
--- a/client/client.go
+++ b/client/client.go
@@ -89,8 +89,20 @@
 
 func (*localSource) unexported() {}
 
-func (ls *localSource) GetByModule(_ context.Context, modulePath string) (_ []*osv.Entry, err error) {
+func (ls *localSource) GetByModule(ctx context.Context, modulePath string) (_ []*osv.Entry, err error) {
 	defer derrors.Wrap(&err, "localSource.GetByModule(%q)", modulePath)
+
+	index, err := ls.Index(ctx)
+	if err != nil {
+		return nil, err
+	}
+	// Query index first to be consistent with the way httpSource.GetByModule works.
+	// Prevents opening and stating files on disk that don't need to be touched. Also
+	// solves #56179.
+	if _, present := index[modulePath]; !present {
+		return nil, nil
+	}
+
 	epath, err := EscapeModulePath(modulePath)
 	if err != nil {
 		return nil, err
diff --git a/cmd/govulncheck/testdata/vulndb/index.json b/cmd/govulncheck/testdata/vulndb/index.json
new file mode 100644
index 0000000..304a664
--- /dev/null
+++ b/cmd/govulncheck/testdata/vulndb/index.json
@@ -0,0 +1 @@
+{"stdlib":"2022-09-20T15:16:04Z","github.com/shiyanhui/dht":"2022-09-20T15:16:04Z","github.com/tidwall/gjson":"2022-09-20T15:16:04Z","golang.org/x/crypto":"2022-09-20T15:16:04Z","golang.org/x/net":"2022-09-20T15:16:04Z","golang.org/x/text":"2022-09-20T15:16:04Z"}