ci/internal/cve/record.go (42 lines of code) (raw):

//go:generate npx quicktype -o internal/cve/record_gen.go --package cve --top-level Record --just-types-and-package --omit-empty --field-tags json --src-lang schema CVE_Record_bundled.schema.json package cve import ( "encoding/json" "errors" "io" "log/slog" "strings" ) const expectedDataTypeValue = "CVE_RECORD" // ErrNotCVERecord is an error returned when data is not a CVE record. var ErrNotCVERecord = errors.New("not a CVE record") // RecordFromReader loads a CVE record from given reader expected to contain // a CVE JSON record following the v5 format. // Returns [ErrNotCVERecord] if the reader does not contain a CVE record. func RecordFromReader(r io.Reader) (*Record, error) { var record Record if err := json.NewDecoder(r).Decode(&record); err != nil { return nil, ErrNotCVERecord } if record.DataType != expectedDataTypeValue { return nil, ErrNotCVERecord } if !strings.HasPrefix(record.DataVersion, "5.") { return nil, ErrNotCVERecord } return &record, nil } // RecordVersion determines the version of a CVE record from the given reader. // Returns [ErrNotCVERecord] if the reader does not contain a CVE record. func RecordVersion(r io.Reader) (string, error) { s := struct { DataType string `json:"dataType"` DataVersion string `json:"dataVersion"` }{} if err := json.NewDecoder(r).Decode(&s); err != nil { return "", ErrNotCVERecord } if s.DataType != expectedDataTypeValue { return "", ErrNotCVERecord } if s.DataVersion == "" { return "", ErrNotCVERecord } return s.DataVersion, nil } // LogValue satisfies the [slog.LogValuer] interface. func (r *Record) LogValue() slog.Value { return slog.StringValue(r.CveMetadata.CveID) }