cmd/vulnreport,internal/report: cleanup filename functions

Now that the ID is in the YAML report, we don't need to call GoID() as
often, and we don't need to pass the Go ID to YAMLFilename or CVEFilename.

Change-Id: I80c161a3be47a54d97837e4d68e789f166c8907b
Reviewed-on: https://go-review.googlesource.com/c/vulndb/+/498282
TryBot-Result: Gopher Robot <gobot@golang.org>
Run-TryBot: Tatiana Bradley <tatianabradley@google.com>
Reviewed-by: Damien Neil <dneil@google.com>
This commit is contained in:
Tatiana Bradley 2023-05-25 11:11:56 -04:00
Родитель f1409b0461
Коммит f762043b08
7 изменённых файлов: 70 добавлений и 72 удалений

Просмотреть файл

@ -84,7 +84,6 @@ func TestLintReports(t *testing.T) {
if len(lints) > 0 { if len(lints) > 0 {
t.Errorf(strings.Join(lints, "\n")) t.Errorf(strings.Join(lints, "\n"))
} }
goID := report.GoID(filename)
for _, alias := range r.Aliases() { for _, alias := range r.Aliases() {
if report, ok := aliases[alias]; ok { if report, ok := aliases[alias]; ok {
t.Errorf("report %s shares duplicate alias %s with report %s", filename, alias, report) t.Errorf("report %s shares duplicate alias %s with report %s", filename, alias, report)
@ -94,8 +93,8 @@ func TestLintReports(t *testing.T) {
} }
// Check that a correct OSV file was generated for each YAML report. // Check that a correct OSV file was generated for each YAML report.
if r.Excluded == "" { if r.Excluded == "" {
generated := r.ToOSV(goID, time.Time{}) generated := r.ToOSV(time.Time{})
osvFilename := report.OSVFilename(goID) osvFilename := r.OSVFilename()
current, err := report.ReadOSV(osvFilename) current, err := report.ReadOSV(osvFilename)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
@ -108,11 +107,11 @@ func TestLintReports(t *testing.T) {
} }
} }
if r.CVEMetadata != nil { if r.CVEMetadata != nil {
generated, err := r.ToCVE5(goID) generated, err := r.ToCVE5()
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
cvePath := report.CVEFilename(goID) cvePath := r.CVEFilename()
current, err := cveschema5.Read(cvePath) current, err := cveschema5.Read(cvePath)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)

Просмотреть файл

@ -32,7 +32,6 @@ import (
"golang.org/x/exp/slices" "golang.org/x/exp/slices"
"golang.org/x/tools/go/packages" "golang.org/x/tools/go/packages"
"golang.org/x/vulndb/internal/cvelistrepo" "golang.org/x/vulndb/internal/cvelistrepo"
"golang.org/x/vulndb/internal/cveschema5"
"golang.org/x/vulndb/internal/database" "golang.org/x/vulndb/internal/database"
"golang.org/x/vulndb/internal/derrors" "golang.org/x/vulndb/internal/derrors"
"golang.org/x/vulndb/internal/ghsa" "golang.org/x/vulndb/internal/ghsa"
@ -367,7 +366,7 @@ func handleExcludedIssue(ctx context.Context, cfg *createCfg, iss *issues.Issue)
if err := irun("git", "add", filename); err != nil { if err := irun("git", "add", filename); err != nil {
return "", fmt.Errorf("git add %s: %v", filename, err) return "", fmt.Errorf("git add %s: %v", filename, err)
} }
return filename, nil return r.ID, nil
} }
func createExcluded(ctx context.Context, cfg *createCfg) (err error) { func createExcluded(ctx context.Context, cfg *createCfg) (err error) {
@ -398,14 +397,14 @@ func createExcluded(ctx context.Context, cfg *createCfg) (err error) {
skipped++ skipped++
continue continue
} }
filename, err := handleExcludedIssue(ctx, cfg, iss) id, err := handleExcludedIssue(ctx, cfg, iss)
if err != nil { if err != nil {
fmt.Printf("skipped issue %d due to error: %v\n", iss.Number, err) fmt.Printf("skipped issue %d due to error: %v\n", iss.Number, err)
skipped++ skipped++
continue continue
} }
successfulIssNums = append(successfulIssNums, fmt.Sprintf("golang/vulndb#%d", iss.Number)) successfulIssNums = append(successfulIssNums, fmt.Sprintf("golang/vulndb#%d", iss.Number))
successfulGoIDs = append(successfulGoIDs, report.GoID(filename)) successfulGoIDs = append(successfulGoIDs, id)
} }
fmt.Printf("Skipped %d issues\n", skipped) fmt.Printf("Skipped %d issues\n", skipped)
@ -695,13 +694,19 @@ func fix(ctx context.Context, filename string, ghsaClient *ghsa.Client) (err err
if err := r.Write(filename); err != nil { if err := r.Write(filename); err != nil {
return err return err
} }
goID := report.GoID(filename)
if _, err := writeOSV(r, goID); err != nil { if !r.IsExcluded() {
return err if err := writeOSV(r); err != nil {
return err
}
} }
if err := writeCVE(r, goID); err != nil {
return err if r.CVEMetadata != nil {
if err := writeCVE(r); err != nil {
return err
}
} }
return nil return nil
} }
@ -874,24 +879,17 @@ func osvCmd(filename string) (err error) {
if err != nil { if err != nil {
return err return err
} }
osvFilename, err := writeOSV(r, report.GoID(filename)) if !r.IsExcluded() {
if err != nil { if err := writeOSV(r); err != nil {
return err return err
}
fmt.Println(r.OSVFilename())
} }
fmt.Println(osvFilename)
return nil return nil
} }
func writeOSV(r *report.Report, goID string) (string, error) { func writeOSV(r *report.Report) error {
if r.Excluded == "" { return database.WriteJSON(r.OSVFilename(), r.ToOSV(time.Time{}), true)
entry := r.ToOSV(goID, time.Time{})
osvFilename := report.OSVFilename(goID)
if err := database.WriteJSON(osvFilename, entry, true); err != nil {
return "", err
}
return osvFilename, nil
}
return "", nil
} }
func cveCmd(ctx context.Context, filename string) (err error) { func cveCmd(ctx context.Context, filename string) (err error) {
@ -900,27 +898,20 @@ func cveCmd(ctx context.Context, filename string) (err error) {
if err != nil { if err != nil {
return err return err
} }
return writeCVE(r, report.GoID(filename)) if r.CVEMetadata != nil {
return writeCVE(r)
}
return nil
} }
// writeCVE takes a report and its Go ID, converts the report // writeCVE converts a report to JSON CVE5 record and writes it to
// into a JSON CVE5 record and writes it to data/cve/v5. // data/cve/v5.
func writeCVE(r *report.Report, goID string) error { func writeCVE(r *report.Report) error {
if r.CVEMetadata == nil { cve, err := r.ToCVE5()
return nil if err != nil {
}
var cve *cveschema5.CVERecord
var err error
cvePath := report.CVEFilename(goID)
if cve, err = r.ToCVE5(goID); err != nil {
return err return err
} }
if err = database.WriteJSON(cvePath, cve, true); err != nil { return database.WriteJSON(r.CVEFilename(), cve, true)
return err
}
return nil
} }
func irun(name string, arg ...string) error { func irun(name string, arg ...string) error {
@ -952,12 +943,11 @@ func commit(ctx context.Context, filename string, ghsaClient *ghsa.Client) (err
// Find all derived files (OSV and CVE). // Find all derived files (OSV and CVE).
files := []string{filename} files := []string{filename}
goID := report.GoID(filename)
if r.Excluded == "" { if r.Excluded == "" {
files = append(files, report.OSVFilename(goID)) files = append(files, r.OSVFilename())
} }
if r.CVEMetadata != nil { if r.CVEMetadata != nil {
files = append(files, report.CVEFilename(goID)) files = append(files, r.CVEFilename())
} }
// Add the files. // Add the files.
@ -969,7 +959,7 @@ func commit(ctx context.Context, filename string, ghsaClient *ghsa.Client) (err
} }
// Commit the files, allowing the user to edit the default commit message. // Commit the files, allowing the user to edit the default commit message.
msg, err := newCommitMsg(r, filename) msg, err := newCommitMsg(r)
if err != nil { if err != nil {
return err return err
} }
@ -983,8 +973,13 @@ func commit(ctx context.Context, filename string, ghsaClient *ghsa.Client) (err
return nil return nil
} }
func newCommitMsg(r *report.Report, filepath string) (string, error) { func newCommitMsg(r *report.Report) (string, error) {
folder, filename, issueID, err := report.ParseFilepath(filepath) f, err := r.YAMLFilename()
if err != nil {
return "", err
}
folder, filename, issueID, err := report.ParseFilepath(f)
if err != nil { if err != nil {
return "", err return "", err
} }

Просмотреть файл

@ -24,8 +24,8 @@ var (
) )
// ToCVE5 creates a CVE in 5.0 format from a YAML report file. // ToCVE5 creates a CVE in 5.0 format from a YAML report file.
func (r *Report) ToCVE5(goID string) (_ *cveschema5.CVERecord, err error) { func (r *Report) ToCVE5() (_ *cveschema5.CVERecord, err error) {
defer derrors.Wrap(&err, "Report.ToCVERecord(%q)", goID) defer derrors.Wrap(&err, "ToCVERecord(%q)", r.ID)
if len(r.CVEs) > 0 { if len(r.CVEs) > 0 {
return nil, errors.New("report has CVE ID is wrong section (should be in cve_metadata for self-issued CVEs)") return nil, errors.New("report has CVE ID is wrong section (should be in cve_metadata for self-issued CVEs)")
@ -93,8 +93,9 @@ func (r *Report) ToCVE5(goID string) (_ *cveschema5.CVERecord, err error) {
for _, ref := range r.References { for _, ref := range r.References {
c.References = append(c.References, cveschema5.Reference{URL: ref.URL}) c.References = append(c.References, cveschema5.Reference{URL: ref.URL})
} }
advisoryLink := GoAdvisory(goID) c.References = append(c.References, cveschema5.Reference{
c.References = append(c.References, cveschema5.Reference{URL: advisoryLink}) URL: GoAdvisory(r.ID),
})
for _, credit := range r.Credits { for _, credit := range r.Credits {
c.Credits = append(c.Credits, cveschema5.Credit{ c.Credits = append(c.Credits, cveschema5.Credit{
@ -115,8 +116,8 @@ func (r *Report) ToCVE5(goID string) (_ *cveschema5.CVERecord, err error) {
}, nil }, nil
} }
func CVEFilename(goID string) string { func (r *Report) CVEFilename() string {
return filepath.Join(cve5Dir, goID+".json") return filepath.Join(cve5Dir, r.ID+".json")
} }
func versionRangeToVersionRange(versions []VersionRange) []cveschema5.VersionRange { func versionRangeToVersionRange(versions []VersionRange) []cveschema5.VersionRange {

Просмотреть файл

@ -263,12 +263,12 @@ func TestToCVE5(t *testing.T) {
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
got, err := r.ToCVE5(GoID(test.filename)) got, err := r.ToCVE5()
if err != nil { if err != nil {
t.Fatalf("ToCVE5(%s) failed unexpectedly; err=%v", test.filename, err) t.Fatalf("ToCVE5() failed unexpectedly; err=%v", err)
} }
if diff := cmp.Diff(test.want, got); diff != "" { if diff := cmp.Diff(test.want, got); diff != "" {
t.Fatalf("ToCVE5(%s): unexpected diffs (-want,+got):\n%v", test.filename, diff) t.Fatalf("ToCVE5(): unexpected diffs (-want,+got):\n%v", diff)
} }
}) })
} }
@ -276,7 +276,8 @@ func TestToCVE5(t *testing.T) {
func TestCVEFilename(t *testing.T) { func TestCVEFilename(t *testing.T) {
want := "data/cve/v5/GO-1999-0001.json" want := "data/cve/v5/GO-1999-0001.json"
if got := CVEFilename("GO-1999-0001"); got != want { r := &Report{ID: "GO-1999-0001"}
if got := r.CVEFilename(); got != want {
t.Errorf("got %s, want %s", got, want) t.Errorf("got %s, want %s", got, want)
} }
} }

Просмотреть файл

@ -30,9 +30,9 @@ var (
) )
// ToOSV creates an osv.Entry for a report. // ToOSV creates an osv.Entry for a report.
// In addition to the report, it takes the ID for the vuln and the time // lastModified is the time the report should be considered to have
// the vuln was last modified. // been most recently modified.
func (r *Report) ToOSV(goID string, lastModified time.Time) osv.Entry { func (r *Report) ToOSV(lastModified time.Time) osv.Entry {
var credits []osv.Credit var credits []osv.Credit
for _, credit := range r.Credits { for _, credit := range r.Credits {
credits = append(credits, osv.Credit{ credits = append(credits, osv.Credit{
@ -46,14 +46,14 @@ func (r *Report) ToOSV(goID string, lastModified time.Time) osv.Entry {
} }
entry := osv.Entry{ entry := osv.Entry{
ID: goID, ID: r.ID,
Published: osv.Time{Time: r.Published}, Published: osv.Time{Time: r.Published},
Modified: osv.Time{Time: lastModified}, Modified: osv.Time{Time: lastModified},
Withdrawn: withdrawn, Withdrawn: withdrawn,
Details: trimWhitespace(r.Description), Details: trimWhitespace(r.Description),
Credits: credits, Credits: credits,
SchemaVersion: SchemaVersion, SchemaVersion: SchemaVersion,
DatabaseSpecific: &osv.DatabaseSpecific{URL: GoAdvisory(goID)}, DatabaseSpecific: &osv.DatabaseSpecific{URL: GoAdvisory(r.ID)},
} }
for _, m := range r.Modules { for _, m := range r.Modules {
@ -69,8 +69,8 @@ func (r *Report) ToOSV(goID string, lastModified time.Time) osv.Entry {
return entry return entry
} }
func OSVFilename(goID string) string { func (r *Report) OSVFilename() string {
return filepath.Join(OSVDir, goID+".json") return filepath.Join(OSVDir, r.ID+".json")
} }
// ReadOSV reads an osv.Entry from a file. // ReadOSV reads an osv.Entry from a file.

Просмотреть файл

@ -15,6 +15,7 @@ import (
func TestToOSV(t *testing.T) { func TestToOSV(t *testing.T) {
r := &Report{ r := &Report{
ID: "GO-1991-0001",
Modules: []*Module{ Modules: []*Module{
{ {
Module: "example.com/vulnerable/v2", Module: "example.com/vulnerable/v2",
@ -200,15 +201,16 @@ func TestToOSV(t *testing.T) {
DatabaseSpecific: &osv.DatabaseSpecific{URL: "https://pkg.go.dev/vuln/GO-1991-0001"}, DatabaseSpecific: &osv.DatabaseSpecific{URL: "https://pkg.go.dev/vuln/GO-1991-0001"},
} }
gotEntry := r.ToOSV("GO-1991-0001", time.Time{}) gotEntry := r.ToOSV(time.Time{})
if diff := cmp.Diff(wantEntry, gotEntry, cmp.Comparer(func(a, b time.Time) bool { return a.Equal(b) })); diff != "" { if diff := cmp.Diff(wantEntry, gotEntry, cmp.Comparer(func(a, b time.Time) bool { return a.Equal(b) })); diff != "" {
t.Errorf("GenerateOSVEntry returned unexpected entry (-want +got):\n%s", diff) t.Errorf("ToOSV() mismatch (-want +got):\n%s", diff)
} }
} }
func TestOSVFilename(t *testing.T) { func TestOSVFilename(t *testing.T) {
want := "data/osv/GO-1999-0001.json" want := "data/osv/GO-1999-0001.json"
if got := OSVFilename("GO-1999-0001"); got != want { r := &Report{ID: "GO-1999-0001"}
if got := r.OSVFilename(); got != want {
t.Errorf("got %s, want %s", got, want) t.Errorf("got %s, want %s", got, want)
} }
} }

Просмотреть файл

@ -46,7 +46,7 @@ func TestUnknownField(t *testing.T) {
} }
} }
func TestGetYAMLFilename(t *testing.T) { func TestYAMLFilename(t *testing.T) {
tests := []struct { tests := []struct {
name string name string
r *Report r *Report