internal: add some helper functions to support CVE v5
Adds various helper functions that will be used to add support for the
new CVE v5 schema.
For golang/go#49289
Change-Id: I3e9aaa95e30000c01a3f6b5738950b9dccdd84cc
Reviewed-on: https://go-review.googlesource.com/c/vulndb/+/545296
Reviewed-by: Damien Neil <dneil@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
diff --git a/internal/cveschema5/cveschema5.go b/internal/cveschema5/cveschema5.go
index d251a48..815cc5c 100644
--- a/internal/cveschema5/cveschema5.go
+++ b/internal/cveschema5/cveschema5.go
@@ -135,10 +135,17 @@
return record.Metadata.ID, &record.Containers, nil
}
-const Regex = `CVE-\d{4}-\d{4,}`
+const RegexStr = `CVE-\d{4}-\d{4,}`
-var cveRegex = regexp.MustCompile(`^` + Regex + `$`)
+var (
+ Regex = regexp.MustCompile(RegexStr)
+ RegexStrict = regexp.MustCompile(`^` + RegexStr + `$`)
+)
func IsCVE(s string) bool {
- return cveRegex.MatchString(s)
+ return RegexStrict.MatchString(s)
+}
+
+func FindCVE(s string) string {
+ return Regex.FindString(s)
}
diff --git a/internal/cveschema5/cveschema5_test.go b/internal/cveschema5/cveschema5_test.go
index f48ff59..681ca34 100644
--- a/internal/cveschema5/cveschema5_test.go
+++ b/internal/cveschema5/cveschema5_test.go
@@ -72,3 +72,11 @@
t.Errorf("Read(%s) = %v\n want %v", f, got, want)
}
}
+
+func TestFindCVE(t *testing.T) {
+ s := "something/CVE-1999-0004.json"
+ got, want := FindCVE(s), "CVE-1999-0004"
+ if got != want {
+ t.Errorf("FindCVE(%s) = %s, want %s", s, got, want)
+ }
+}
diff --git a/internal/gitrepo/gitrepo.go b/internal/gitrepo/gitrepo.go
index 9e9ab33..eb04d41 100644
--- a/internal/gitrepo/gitrepo.go
+++ b/internal/gitrepo/gitrepo.go
@@ -29,10 +29,15 @@
ctx = event.Start(ctx, "gitrepo.Clone")
defer event.End(ctx)
- log.Infof(ctx, "Cloning repo %q at HEAD", repoURL)
+ return CloneAt(ctx, repoURL, plumbing.HEAD)
+}
+
+// Clone returns a bare repo by cloning the repo at repoURL at the given ref.
+func CloneAt(ctx context.Context, repoURL string, ref plumbing.ReferenceName) (repo *git.Repository, err error) {
+ log.Infof(ctx, "Cloning repo %q at %s", repoURL, ref)
return git.Clone(memory.NewStorage(), nil, &git.CloneOptions{
URL: repoURL,
- ReferenceName: plumbing.HEAD,
+ ReferenceName: ref,
SingleBranch: true,
Depth: 1,
Tags: git.NoTags,
diff --git a/internal/report/lint.go b/internal/report/lint.go
index 6086bce..16fccbc 100644
--- a/internal/report/lint.go
+++ b/internal/report/lint.go
@@ -192,9 +192,9 @@
issueRegex = regexp.MustCompile(`https://go.dev/issue/\d+`)
announceRegex = regexp.MustCompile(`https://groups.google.com/g/golang-(announce|dev|nuts)/c/([^/]+)`)
- nistRegex = regexp.MustCompile(`^https://nvd.nist.gov/vuln/detail/(` + cveschema5.Regex + `)$`)
+ nistRegex = regexp.MustCompile(`^https://nvd.nist.gov/vuln/detail/(` + cveschema5.RegexStr + `)$`)
ghsaLinkRegex = regexp.MustCompile(`^https://github.com/.*/(` + ghsa.Regex + `)$`)
- mitreRegex = regexp.MustCompile(`^https://cve.mitre.org/.*(` + cveschema5.Regex + `)$`)
+ mitreRegex = regexp.MustCompile(`^https://cve.mitre.org/.*(` + cveschema5.RegexStr + `)$`)
)
// Checks that the "links" section of a Report for a package in the
diff --git a/internal/test/txtar.go b/internal/test/txtar.go
new file mode 100644
index 0000000..6397c96
--- /dev/null
+++ b/internal/test/txtar.go
@@ -0,0 +1,44 @@
+// Copyright 2023 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 test
+
+import (
+ "fmt"
+ "os"
+ "path/filepath"
+ "time"
+
+ "golang.org/x/tools/txtar"
+)
+
+func WriteTxtar(filename string, files []txtar.File, comment string) error {
+ if err := os.MkdirAll(filepath.Dir(filename), os.ModePerm); err != nil {
+ return err
+ }
+
+ if err := os.WriteFile(filename, txtar.Format(
+ &txtar.Archive{
+ Comment: []byte(addCopyright(comment)),
+ Files: files,
+ },
+ ), os.ModePerm); err != nil {
+ return err
+ }
+
+ return nil
+}
+
+func addCopyright(comment string) string {
+ return fmt.Sprintf("%s\n\n%s\n\n", copyright, comment)
+}
+
+var copyright = fmt.Sprintf(`Copyright %d 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.`, currentYear())
+
+func currentYear() int {
+ year, _, _ := time.Now().Date()
+ return year
+}
diff --git a/internal/test/txtar_test.go b/internal/test/txtar_test.go
new file mode 100644
index 0000000..2762a09
--- /dev/null
+++ b/internal/test/txtar_test.go
@@ -0,0 +1,48 @@
+// Copyright 2023 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 test
+
+import (
+ "path/filepath"
+ "testing"
+
+ "github.com/google/go-cmp/cmp"
+ "golang.org/x/tools/txtar"
+)
+
+func TestWriteTxtar(t *testing.T) {
+ tmp := t.TempDir()
+
+ filename := filepath.Join(tmp, "example", "file.txtar")
+ files := []txtar.File{
+ {
+ Name: "a.txt",
+ Data: []byte("abcdefg\n"),
+ },
+ {
+ Name: "b.txt",
+ Data: []byte("hijklmnop\n"),
+ },
+ }
+ comment := "Context about this archive"
+
+ if err := WriteTxtar(filename, files, comment); err != nil {
+ t.Fatal(err)
+ }
+
+ got, err := txtar.ParseFile(filename)
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ want := &txtar.Archive{
+ Comment: []byte(addCopyright(comment)),
+ Files: files,
+ }
+
+ if diff := cmp.Diff(want, got); diff != "" {
+ t.Errorf("mismatch (-want, +got):\n%s", diff)
+ }
+}