internal/report: add a lint check for module existence
Add a basic lint check that the proxy knows about each module
listed in a report. This allows us to do basic checking on
low-information reports where we don't know versions, packages or symbols.
Change-Id: I92d06cbd27d89ead7725d131e69087085c4cdba5
Reviewed-on: https://go-review.googlesource.com/c/vulndb/+/576996
Reviewed-by: Damien Neil <dneil@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
diff --git a/internal/report/lint.go b/internal/report/lint.go
index d66d05c..47ce631 100644
--- a/internal/report/lint.go
+++ b/internal/report/lint.go
@@ -25,6 +25,10 @@
)
func (m *Module) checkModVersions(pc *proxy.Client) error {
+ if ok := pc.ModuleExists(m.Module); !ok {
+ return fmt.Errorf("module %s not known to proxy", m.Module)
+ }
+
var notFound []string
var nonCanonical []string
for _, vr := range m.Versions {
@@ -272,8 +276,8 @@
}
func (r *Report) missingAdvisory(advisoryCount int) bool {
- return !r.IsExcluded() && !r.IsFirstParty() &&
- advisoryCount == 0 && r.Description == "" && r.CVEMetadata == nil
+ return !r.IsExcluded() && r.Description == "" && !r.IsFirstParty() &&
+ advisoryCount == 0 && r.CVEMetadata == nil
}
func (d *Description) lint(l *linter, r *Report) {
@@ -309,13 +313,8 @@
if strings.HasSuffix(summary, ".") {
l.Error("must not end in a period (should be a phrase, not a sentence)")
}
- for i, r := range summary {
- if i != 0 {
- break
- }
- if !unicode.IsUpper(r) {
- l.Error("must begin with a capital letter")
- }
+ if !startsWithUpper(summary) {
+ l.Error("must begin with a capital letter")
}
// Summary must contain one of the listed module or package
@@ -330,6 +329,18 @@
}
}
+func startsWithUpper(s string) bool {
+ for i, r := range s {
+ if i != 0 {
+ return true
+ }
+ if !unicode.IsUpper(r) {
+ return false
+ }
+ }
+ return false
+}
+
// containsPath returns whether the summary contains one of
// the paths in paths.
// As a special case, if the summary contains a word that contains a "/"
@@ -482,7 +493,7 @@
l.Error("no module name")
}
- if !m.IsFirstParty() && pc != nil {
+ if !r.IsExcluded() && !m.IsFirstParty() && pc != nil {
if err := m.checkModVersions(pc); err != nil {
l.Error(err)
}
diff --git a/internal/report/testdata/proxy/TestGHSAToReport.json b/internal/report/testdata/proxy/TestGHSAToReport.json
index c7e57d1..da6abb5 100644
--- a/internal/report/testdata/proxy/TestGHSAToReport.json
+++ b/internal/report/testdata/proxy/TestGHSAToReport.json
@@ -1,13 +1,13 @@
{
"golang.org/x/tools/@v/list": {
- "body": "v0.1.4\nv0.9.3\nv0.7.0\nv0.1.12\nv0.1.3\nv0.9.2\nv0.3.0\nv0.8.0\nv0.6.0\nv0.10.0\nv0.1.9\nv0.5.0\nv0.1.7\nv0.1.10\nv0.12.0\nv0.1.6\nv0.1.2\nv0.9.0\nv0.1.11\nv0.4.0\nv0.1.8\nv0.11.0\nv0.1.0\nv0.1.5\nv0.9.1\nv0.1.1\nv0.11.1\nv0.2.0\n",
+ "body": "v0.15.0\nv0.1.4\nv0.9.3\nv0.7.0\nv0.1.12\nv0.1.3\nv0.9.2\nv0.3.0\nv0.8.0\nv0.6.0\nv0.10.0\nv0.20.0\nv0.1.9\nv0.5.0\nv0.18.0\nv0.1.7\nv0.1.10\nv0.12.0\nv0.1.6\nv0.19.0\nv0.1.2\nv0.9.0\nv0.1.11\nv0.4.0\nv0.1.8\nv0.14.0\nv0.11.0\nv0.1.0\nv0.1.5\nv0.9.1\nv0.1.1\nv0.11.1\nv0.16.1\nv0.13.0\nv0.17.0\nv0.2.0\nv0.16.0\n",
"status_code": 200
},
"golang.org/x/tools/@v/v0.9.0.mod": {
"body": "module golang.org/x/tools\n\ngo 1.18 // tagx:compat 1.16\n\nrequire (\n\tgithub.com/yuin/goldmark v1.4.13\n\tgolang.org/x/mod v0.10.0\n\tgolang.org/x/net v0.10.0\n\tgolang.org/x/sys v0.8.0\n)\n\nrequire golang.org/x/sync v0.2.0\n",
"status_code": 200
},
- "golang.org/x/tools/go/packages/@v/v0.9.0.mod": {
+ "golang.org/x/tools/go/packages/@v/list": {
"status_code": 404
}
}
\ No newline at end of file
diff --git a/internal/report/testdata/proxy/TestLint.json b/internal/report/testdata/proxy/TestLint.json
index f4783e7..a2ed531 100644
--- a/internal/report/testdata/proxy/TestLint.json
+++ b/internal/report/testdata/proxy/TestLint.json
@@ -1,4 +1,8 @@
{
+ "github.com/golang/vuln/@v/list": {
+ "body": "v1.0.2\nv1.0.0\nv1.0.3\nv1.0.4\nv0.1.0\nv1.0.1\nv0.2.0\n",
+ "status_code": 200
+ },
"github.com/golang/vuln/@v/v0.1.0.mod": {
"body": "module golang.org/x/vuln\n\ngo 1.18\n\nrequire (\n\tgithub.com/client9/misspell v0.3.4\n\tgithub.com/google/go-cmdtest v0.4.1-0.20220921163831-55ab3332a786\n\tgithub.com/google/go-cmp v0.5.8\n\tgolang.org/x/mod v0.10.0\n\tgolang.org/x/sync v0.1.0\n\tgolang.org/x/tools v0.8.1-0.20230421161920-b9619ee54b47\n\thonnef.co/go/tools v0.4.3\n\tmvdan.cc/unparam v0.0.0-20230312165513-e84e2d14e3b8\n)\n\nrequire (\n\tgithub.com/BurntSushi/toml v1.2.1 // indirect\n\tgithub.com/google/renameio v0.1.0 // indirect\n\tgolang.org/x/exp/typeparams v0.0.0-20221208152030-732eee02a75a // indirect\n\tgolang.org/x/sys v0.7.0 // indirect\n)\n",
"status_code": 200
@@ -9,6 +13,10 @@
"github.com/golang/vuln/@v/v0.2.6.mod": {
"status_code": 404
},
+ "golang.org/x/net/@v/list": {
+ "body": "v0.15.0\nv0.7.0\nv0.3.0\nv0.8.0\nv0.6.0\nv0.10.0\nv0.20.0\nv0.24.0\nv0.23.0\nv0.5.0\nv0.22.0\nv0.18.0\nv0.21.0\nv0.12.0\nv0.19.0\nv0.9.0\nv0.4.0\nv0.14.0\nv0.11.0\nv0.1.0\nv0.13.0\nv0.17.0\nv0.2.0\nv0.16.0\n",
+ "status_code": 200
+ },
"golang.org/x/net/@v/v0.2.0.mod": {
"body": "module golang.org/x/net\n\ngo 1.17\n\nrequire (\n\tgolang.org/x/sys v0.2.0\n\tgolang.org/x/term v0.2.0\n\tgolang.org/x/text v0.4.0\n)\n",
"status_code": 200