diff options
author | Paul Duncan <pabs@pablotron.org> | 2022-02-04 00:35:31 -0500 |
---|---|---|
committer | Paul Duncan <pabs@pablotron.org> | 2022-02-04 00:35:31 -0500 |
commit | 9c17b97cd0f83be3fff9fa4e87fd1d29052ea616 (patch) | |
tree | 0d97030a0d0c3ad983be281ce89f80571338887f /internal/feed | |
parent | 92400d731546557d110c9c3cc3906d700f83dda8 (diff) | |
download | cvez-9c17b97cd0f83be3fff9fa4e87fd1d29052ea616.tar.bz2 cvez-9c17b97cd0f83be3fff9fa4e87fd1d29052ea616.zip |
rename to github.com/pablotron/cvez, remove internal libs
Diffstat (limited to 'internal/feed')
67 files changed, 0 insertions, 3740 deletions
diff --git a/internal/feed/cveid.go b/internal/feed/cveid.go deleted file mode 100644 index 8796029..0000000 --- a/internal/feed/cveid.go +++ /dev/null @@ -1,112 +0,0 @@ -package feed - -import ( - "encoding/json" - "fmt" - "regexp" - "strconv" -) - -// CVE ID -type CveId uint32 - -var cveIdRe = regexp.MustCompile("\\ACVE-(\\d{4})-(\\d{1,8})\\z") - -// parse year component of CVE ID -func parseCveIdYear(s string) (uint16, error) { - // parse year, check for error - year, err := strconv.ParseUint(s, 10, 16) - if err != nil { - return 0, err - } - - // check bounds - if year < 2000 || year > 2127 { - return 0, fmt.Errorf("year out of bounds: %s", s) - } - - // return value - return uint16(year), nil -} - -// parse number component of CVE ID -func parseCveIdNum(s string) (uint32, error) { - // parse number, check for error - num, err := strconv.ParseUint(s, 10, 32) - if err != nil { - return 0, err - } - - // check bounds - if num > 0x01ffffff { - return 0, fmt.Errorf("number out of bounds: %d", num) - } - - // return value - return uint32(num), nil -} - -// Encode CVE ID as uint32. -func encodeCveId(year uint16, num uint32) uint32 { - return uint32((uint32((year - 2000) & 0x7f) << 25) | (num & 0x01ffffff)) -} - -// Create CVE ID from string. -func NewCveId(s string) (CveId, error) { - // match components, check for error - md := cveIdRe.FindStringSubmatch(s) - if len(md) != 3 { - return CveId(0), fmt.Errorf("invalid CVE ID: %s", s) - } - - // parse year, check for error - year, err := parseCveIdYear(md[1]) - if err != nil { - return CveId(0), err - } - - // parse number, check for error - num, err := parseCveIdNum(md[2]) - if err != nil { - return CveId(0), err - } - - // encode and return result - return CveId(encodeCveId(year, num)), nil -} - -// Unmarshal CVE ID from JSON. -func (me *CveId) UnmarshalJSON(b []byte) error { - // decode string, check for error - var s string - if err := json.Unmarshal(b, &s); err != nil { - return err - } - - // parse year, check for error - r, err := NewCveId(s) - if err != nil { - return err - } - - // serialize ID - *me = r - - // return success - return nil -} - -// Get year component. -func (me CveId) Year() uint16 { - return uint16((uint32(me) >> 25) & 0x7f) + 2000 -} - -// Get number component. -func (me CveId) Number() uint32 { - return (uint32(me) & 0x01ffffff) -} - -// Return string representation of CVE ID. -func (me CveId) String() string { - return fmt.Sprintf("CVE-%04d-%04d", me.Year(), me.Number()) -} diff --git a/internal/feed/cveid_test.go b/internal/feed/cveid_test.go deleted file mode 100644 index 8df3642..0000000 --- a/internal/feed/cveid_test.go +++ /dev/null @@ -1,295 +0,0 @@ -package feed - -import ( - "encoding/json" - "fmt" - "strconv" - "testing" -) - -func TestParseCveIdYear(t *testing.T) { - if got, err := parseCveIdYear("asdf"); err == nil { - t.Errorf("got %d, exp error", got) - return - } - - goodTests := []struct { - val string - exp uint16 - } { - { "2000", 2000 }, - { "2001", 2001 }, - { "2100", 2100 }, - } - - for _, test := range(goodTests) { - t.Run(test.val, func(t *testing.T) { - got, err := parseCveIdYear(test.val) - if err != nil { - t.Error(err) - return - } - - if got != test.exp { - t.Errorf("got %d, exp %d", got, test.exp) - return - } - }) - } - - badTests := []struct { - val string - exp string - } { - { "0000", "year out of bounds: 0000" }, - { "0001", "year out of bounds: 0001" }, - { "1999", "year out of bounds: 1999" }, - { "2128", "year out of bounds: 2128" }, - { "9999", "year out of bounds: 9999" }, - } - - for _, test := range(badTests) { - t.Run(test.val, func(t *testing.T) { - if got, err := parseCveIdYear(test.val); err == nil { - t.Errorf("got %d, exp error", got) - return - } else if err.Error() != test.exp { - t.Errorf("got \"%s\", exp \"%s\"", err.Error(), test.exp) - } - }) - } -} - -func TestParseCveIdNum(t *testing.T) { - if got, err := parseCveIdNum("asdf"); err == nil { - t.Errorf("got %d, exp error", got) - return - } - - goodTests := []struct { - val string - exp uint32 - } { - { "0", 0 }, - { "0001", 1 }, - { "2100", 2100 }, - { "999999", 999999 }, - { "33554431", 33554431 }, - } - - for _, test := range(goodTests) { - t.Run(test.val, func(t *testing.T) { - got, err := parseCveIdNum(test.val) - if err != nil { - t.Error(err) - return - } - - if got != test.exp { - t.Errorf("got %d, exp %d", got, test.exp) - return - } - }) - } - - badTests := []struct { - val string - exp string - } { - { "33554432", "number out of bounds: 33554432" }, - { "99999999", "number out of bounds: 99999999" }, - } - - for _, test := range(badTests) { - t.Run(test.val, func(t *testing.T) { - if got, err := parseCveIdNum(test.val); err == nil { - t.Errorf("got %d, exp error", got) - } else if err.Error() != test.exp { - t.Errorf("got \"%s\", exp \"%s\"", err.Error(), test.exp) - } - }) - } -} - -func TestNewCveId(t *testing.T) { - badMatchTests := []string { - "", - "\nCVE-2002-1234", - "CVE-2002-1234\n", - "CVE20021234\n", - "asdf", - } - - for _, test := range(badMatchTests) { - t.Run(test, func(t *testing.T) { - exp := fmt.Sprintf("invalid CVE ID: %s", test) - if got, err := NewCveId(test); err == nil { - t.Errorf("got %s, exp error", got) - } else if err.Error() != exp { - t.Errorf("got \"%s\", exp \"%s\"", err.Error(), exp) - } - }) - } - - badYearTests := []struct { - val string - exp string - } { - { "CVE-0000-1234", "year out of bounds: 0000" }, - { "CVE-1999-1234", "year out of bounds: 1999" }, - { "CVE-2128-1234", "year out of bounds: 2128" }, - { "CVE-9999-1234", "year out of bounds: 9999" }, - } - - for _, test := range(badYearTests) { - t.Run(test.val, func(t *testing.T) { - if got, err := NewCveId(test.val); err == nil { - t.Errorf("got %s, exp error", got) - } else if err.Error() != test.exp { - t.Errorf("got \"%s\", exp \"%s\"", err.Error(), test.exp) - } - }) - } - - badNumTests := []struct { - val string - exp string - } { - { "CVE-2000-33554432", "number out of bounds: 33554432" }, - { "CVE-2000-99999999", "number out of bounds: 99999999" }, - } - - for _, test := range(badNumTests) { - t.Run(test.val, func(t *testing.T) { - if got, err := NewCveId(test.val); err == nil { - t.Errorf("got %s, exp error", got) - } else if err.Error() != test.exp { - t.Errorf("got \"%s\", exp \"%s\"", err.Error(), test.exp) - } - }) - } - - goodTests := []string { - "CVE-2000-0", - "CVE-2127-0", - "CVE-2000-33554431", - "CVE-2127-33554431", - } - - for _, val := range(goodTests) { - t.Run(val, func(t *testing.T) { - if _, err := NewCveId(val); err != nil { - t.Error(err) - } - }) - } -} -func TestCveIdYear(t *testing.T) { - for year := 2000; year < 2127; year++ { - t.Run(strconv.FormatInt(int64(year), 10), func(t *testing.T) { - // expected value - exp := uint16(year) - - // build cve id, check for error - id, err := NewCveId(fmt.Sprintf("CVE-%04d-0000", year)) - if err != nil { - t.Error(err) - return - } - - // check year - got := id.Year() - if got != exp { - t.Errorf("got %d, exp %d", got, exp) - } - }) - } -} - -func TestCveIdNumber(t *testing.T) { - for num := 0; num < 99999; num++ { - t.Run(strconv.FormatInt(int64(num), 10), func(t *testing.T) { - // expected value - exp := uint32(num) - - // build cve id, check for error - id, err := NewCveId(fmt.Sprintf("CVE-2000-%04d", num)) - if err != nil { - t.Error(err) - return - } - - // check number - got := id.Number() - if got != exp { - t.Errorf("got %d, exp %d", got, exp) - } - }) - } -} - -func TestCveIdUnmarshalInvalidData(t *testing.T) { - test := []byte(`{}`) - var val CveId - - if err := json.Unmarshal(test, &val); err == nil { - t.Errorf("got \"%s\", exp error", val) - } -} - -func TestCveIdUnmarshalUnknown(t *testing.T) { - test := []byte(`"foo"`) - exp := "invalid CVE ID: foo" - var val CveId - - err := json.Unmarshal(test, &val) - if err == nil { - t.Errorf("got \"%s\", exp error", val) - return - } - - if err.Error() != exp { - t.Errorf("got \"%s\", exp \"%s\"", err.Error(), exp) - } -} - -func TestCveIdUnmarshalValid(t *testing.T) { - tests := []struct { - val string - expYear uint16 - expNum uint32 - exp string - } { - { "\"CVE-2000-0\"", 2000, 0, "CVE-2000-0000" }, - { "\"CVE-2000-1234\"", 2000, 1234, "CVE-2000-1234" }, - { "\"CVE-2000-33554431\"", 2000, 33554431, "CVE-2000-33554431" }, - { "\"CVE-2127-0\"", 2127, 0, "CVE-2127-0000" }, - { "\"CVE-2127-1234\"", 2127, 1234, "CVE-2127-1234" }, - { "\"CVE-2127-33554431\"", 2127, 33554431, "CVE-2127-33554431" }, - } - - for _, test := range(tests) { - t.Run(test.val, func(t *testing.T) { - var got CveId - if err := json.Unmarshal([]byte(test.val), &got); err != nil { - t.Error(err) - return - } - - // check year - if got.Year() != test.expYear { - t.Errorf("got \"%d\", exp \"%d\"", got.Year(), test.expYear) - } - - // check year - if got.Number() != test.expNum { - t.Errorf("got \"%d\", exp \"%d\"", got.Number(), test.expNum) - } - - // check string - if got.String() != test.exp { - t.Errorf("got \"%s\", exp \"%s\"", got.String(), test.exp) - } - }) - } -} diff --git a/internal/feed/dataformat.go b/internal/feed/dataformat.go deleted file mode 100644 index bb3f8f8..0000000 --- a/internal/feed/dataformat.go +++ /dev/null @@ -1,36 +0,0 @@ -package feed - -//go:generate stringer -linecomment -type=DataFormat - -import ( - "encoding/json" - "fmt" -) - -// Data format for NVD feeds and feed items. -type DataFormat byte - -const ( - MitreFormat DataFormat = iota // MITRE -) - -// Unmarshal DataFormat from JSON. -func (me *DataFormat) UnmarshalJSON(b []byte) error { - // decode string, check for error - var s string - if err := json.Unmarshal(b, &s); err != nil { - return err - } - - // check value - switch s { - case "MITRE": - *me = MitreFormat - default: - // return error - return fmt.Errorf("unknown data format: %s", s) - } - - // return success - return nil -} diff --git a/internal/feed/dataformat_string.go b/internal/feed/dataformat_string.go deleted file mode 100644 index 4b755f4..0000000 --- a/internal/feed/dataformat_string.go +++ /dev/null @@ -1,23 +0,0 @@ -// Code generated by "stringer -linecomment -type=DataFormat"; DO NOT EDIT. - -package feed - -import "strconv" - -func _() { - // An "invalid array index" compiler error signifies that the constant values have changed. - // Re-run the stringer command to generate them again. - var x [1]struct{} - _ = x[MitreFormat-0] -} - -const _DataFormat_name = "MITRE" - -var _DataFormat_index = [...]uint8{0, 5} - -func (i DataFormat) String() string { - if i >= DataFormat(len(_DataFormat_index)-1) { - return "DataFormat(" + strconv.FormatInt(int64(i), 10) + ")" - } - return _DataFormat_name[_DataFormat_index[i]:_DataFormat_index[i+1]] -} diff --git a/internal/feed/dataformat_test.go b/internal/feed/dataformat_test.go deleted file mode 100644 index efb4986..0000000 --- a/internal/feed/dataformat_test.go +++ /dev/null @@ -1,65 +0,0 @@ -package feed - -import ( - "encoding/json" - "testing" -) - -func TestDataFormatUnmarshalInvalidData(t *testing.T) { - test := []byte(`{}`) - var val DataFormat - - if err := json.Unmarshal(test, &val); err == nil { - t.Errorf("got \"%s\", exp error", val) - } -} - -func TestDataFormatUnmarshalUnknown(t *testing.T) { - test := []byte(`"foo"`) - exp := "unknown data format: foo" - var val DataFormat - - err := json.Unmarshal(test, &val) - if err == nil { - t.Errorf("got \"%s\", exp error", val) - return - } - - if err.Error() != exp { - t.Errorf("got \"%s\", exp \"%s\"", err.Error(), exp) - } -} - -func TestDataFormatUnmarshalValid(t *testing.T) { - test := []byte(`"MITRE"`) - exp := MitreFormat - var got DataFormat - - if err := json.Unmarshal(test, &got); err != nil { - t.Error(err) - return - } - - if got != exp { - t.Errorf("got \"%s\", exp \"%s\"", got, exp) - } -} - -func TestDataFormatString(t *testing.T) { - tests := []struct { - val DataFormat - exp string - } { - { MitreFormat, "MITRE" }, - { DataFormat(255), "DataFormat(255)" }, - } - - for _, test := range(tests) { - t.Run(test.val.String(), func(t *testing.T) { - got := test.val.String() - if got != test.exp { - t.Errorf("got \"%s\", exp \"%s\"", got, test.exp) - } - }) - } -} diff --git a/internal/feed/datatype.go b/internal/feed/datatype.go deleted file mode 100644 index 6eaa145..0000000 --- a/internal/feed/datatype.go +++ /dev/null @@ -1,36 +0,0 @@ -package feed - -//go:generate stringer -linecomment -type=DataType - -import ( - "encoding/json" - "fmt" -) - -// Data type for NVD feeds and feed items. -type DataType byte - -const ( - CveType DataType = iota // CVE -) - -// Unmarshal DataType from JSON. -func (me *DataType) UnmarshalJSON(b []byte) error { - // decode string, check for error - var s string - if err := json.Unmarshal(b, &s); err != nil { - return err - } - - // check value - switch s { - case "CVE": - *me = CveType - default: - // return error - return fmt.Errorf("unknown data type: %s", s) - } - - // return success - return nil -} diff --git a/internal/feed/datatype_string.go b/internal/feed/datatype_string.go deleted file mode 100644 index f126add..0000000 --- a/internal/feed/datatype_string.go +++ /dev/null @@ -1,23 +0,0 @@ -// Code generated by "stringer -linecomment -type=DataType"; DO NOT EDIT. - -package feed - -import "strconv" - -func _() { - // An "invalid array index" compiler error signifies that the constant values have changed. - // Re-run the stringer command to generate them again. - var x [1]struct{} - _ = x[CveType-0] -} - -const _DataType_name = "CVE" - -var _DataType_index = [...]uint8{0, 3} - -func (i DataType) String() string { - if i >= DataType(len(_DataType_index)-1) { - return "DataType(" + strconv.FormatInt(int64(i), 10) + ")" - } - return _DataType_name[_DataType_index[i]:_DataType_index[i+1]] -} diff --git a/internal/feed/datatype_test.go b/internal/feed/datatype_test.go deleted file mode 100644 index 05f6a74..0000000 --- a/internal/feed/datatype_test.go +++ /dev/null @@ -1,65 +0,0 @@ -package feed - -import ( - "encoding/json" - "testing" -) - -func TestDataTypeUnmarshalInvalidData(t *testing.T) { - test := []byte(`{}`) - var val DataType - - if err := json.Unmarshal(test, &val); err == nil { - t.Errorf("got \"%s\", exp error", val) - } -} - -func TestDataTypeUnmarshalUnknown(t *testing.T) { - test := []byte(`"foo"`) - exp := "unknown data type: foo" - var val DataType - - err := json.Unmarshal(test, &val) - if err == nil { - t.Errorf("got \"%s\", exp error", val) - return - } - - if err.Error() != exp { - t.Errorf("got \"%s\", exp \"%s\"", err.Error(), exp) - } -} - -func TestDataTypeUnmarshalValid(t *testing.T) { - test := []byte(`"CVE"`) - exp := CveType - var got DataType - - if err := json.Unmarshal(test, &got); err != nil { - t.Error(err) - return - } - - if got != exp { - t.Errorf("got \"%s\", exp \"%s\"", got, exp) - } -} - -func TestDataTypeString(t *testing.T) { - tests := []struct { - val DataType - exp string - } { - { CveType, "CVE" }, - { DataType(255), "DataType(255)" }, - } - - for _, test := range(tests) { - t.Run(test.val.String(), func(t *testing.T) { - got := test.val.String() - if got != test.exp { - t.Errorf("got \"%s\", exp \"%s\"", got, test.exp) - } - }) - } -} diff --git a/internal/feed/dataversion.go b/internal/feed/dataversion.go deleted file mode 100644 index c6f1b8d..0000000 --- a/internal/feed/dataversion.go +++ /dev/null @@ -1,36 +0,0 @@ -package feed - -//go:generate stringer -linecomment -type=DataVersion - -import ( - "encoding/json" - "fmt" -) - -// Data version for NVD feeds and feed items. -type DataVersion byte - -const ( - V40 DataVersion = iota // 4.0 -) - -// Unmarshal data version from JSON. -func (me *DataVersion) UnmarshalJSON(b []byte) error { - // decode string, check for error - var s string - if err := json.Unmarshal(b, &s); err != nil { - return err - } - - // check value - switch s { - case "4.0": - *me = V40 - default: - // return error - return fmt.Errorf("unknown data version: %s", s) - } - - // return success - return nil -} diff --git a/internal/feed/dataversion_string.go b/internal/feed/dataversion_string.go deleted file mode 100644 index 26a0fdb..0000000 --- a/internal/feed/dataversion_string.go +++ /dev/null @@ -1,23 +0,0 @@ -// Code generated by "stringer -linecomment -type=DataVersion"; DO NOT EDIT. - -package feed - -import "strconv" - -func _() { - // An "invalid array index" compiler error signifies that the constant values have changed. - // Re-run the stringer command to generate them again. - var x [1]struct{} - _ = x[V40-0] -} - -const _DataVersion_name = "4.0" - -var _DataVersion_index = [...]uint8{0, 3} - -func (i DataVersion) String() string { - if i >= DataVersion(len(_DataVersion_index)-1) { - return "DataVersion(" + strconv.FormatInt(int64(i), 10) + ")" - } - return _DataVersion_name[_DataVersion_index[i]:_DataVersion_index[i+1]] -} diff --git a/internal/feed/dataversion_test.go b/internal/feed/dataversion_test.go deleted file mode 100644 index 6bf683c..0000000 --- a/internal/feed/dataversion_test.go +++ /dev/null @@ -1,65 +0,0 @@ -package feed - -import ( - "encoding/json" - "testing" -) - -func TestDataVersionUnmarshalInvalidData(t *testing.T) { - test := []byte(`{}`) - var val DataVersion - - if err := json.Unmarshal(test, &val); err == nil { - t.Errorf("got \"%s\", exp error", val) - } -} - -func TestDataVersionUnmarshalUnknown(t *testing.T) { - test := []byte(`"foo"`) - exp := "unknown data version: foo" - var val DataVersion - - err := json.Unmarshal(test, &val) - if err == nil { - t.Errorf("got \"%s\", exp error", val) - return - } - - if err.Error() != exp { - t.Errorf("got \"%s\", exp \"%s\"", err.Error(), exp) - } -} - -func TestDataVersionUnmarshalValid(t *testing.T) { - test := []byte(`"4.0"`) - exp := V40 - var got DataVersion - - if err := json.Unmarshal(test, &got); err != nil { - t.Error(err) - return - } - - if got != exp { - t.Errorf("got \"%s\", exp \"%s\"", got, exp) - } -} - -func TestDataVersionString(t *testing.T) { - tests := []struct { - val DataVersion - exp string - } { - { V40, "4.0" }, - { DataVersion(255), "DataVersion(255)" }, - } - - for _, test := range(tests) { - t.Run(test.val.String(), func(t *testing.T) { - got := test.val.String() - if got != test.exp { - t.Errorf("got \"%s\", exp \"%s\"", got, test.exp) - } - }) - } -} diff --git a/internal/feed/feed.go b/internal/feed/feed.go deleted file mode 100644 index bdf260c..0000000 --- a/internal/feed/feed.go +++ /dev/null @@ -1,255 +0,0 @@ -// NVD JSON feed parser. -package feed - -// import "nvd/internal/cvss" - -// TODO: parse cpe - -// CVE metadata -type CveMetadata struct { - // CVE ID - Id CveId `json:"ID"` - - // CVE assigner email address - Assigner string `json:"ASSIGNER"` -} - -// CVE description string. -type Description struct { - // Language code - Lang string `json:"lang"` - - // String value - Value string `json:"value"` -} - -// CVE problem type -type CveProblemType struct { - // problem type descriptions - Descriptions []Description `json:"description"` -} - -// Slice of CVE problem types. -type CveProblemTypes struct { - // problem types - ProblemTypes []CveProblemType `json:"problemtype_data"` -} - -// CVE reference -type CveReference struct { - // reference URL - Url string `json:"url"` - - // reference name - Name string `json:"name"` - - // reference source - RefSource string `json:"refsource"` - - // tags - Tags []string `json:"tags"` -} - -// Slice of CVE references -type CveReferences struct { - References []CveReference `json:"reference_data"` -} - -// CVE item descriptions -type CveDescription struct { - // slice of descriptions - Descriptions []Description `json:"description_data"` -} - -// CVE data -type Cve struct { - // feed data type - DataType DataType `json:"CVE_data_type"` - - // feed data format - DataFormat DataFormat `json:"CVE_data_format"` - - // feed data format version - DataVersion DataVersion `json:"CVE_data_version"` - - // CVE metadata - Metadata CveMetadata `json:"CVE_data_meta"` - - // CVE problem types - ProblemTypes CveProblemTypes `json:"problemtype"` - - // CVE references - References CveReferences `json:"references"` - - // CVE description - Description CveDescription `json:"description"` -} - -// CPE match -type CpeMatch struct { - // Vulnerable? - Vulnerable bool `json:"vulnerable"` - - VersionEndExcluding string `json:"versionEndExcluding"` - - // CPE URI (FIXME: decode this) - Cpe23Uri string `json:"cpe23Uri"` - - // CPE names (not sure if this is correct) - Names []string `json:"cpe_name"` -} - -// CVE item configuration node -type ConfigurationNode struct { - // node operator - Operator NodeOp `json:"operator"` - - // node children - Children []ConfigurationNode `json:"children"` - - CpeMatches []CpeMatch `json:"cpe_match"` -} - -// CVE item configurations -type ItemConfigurations struct { - // data version - DataVersion DataVersion `json:"CVE_data_version"` - - // slice of configuration nodes - Nodes []ConfigurationNode `json:"nodes"` -} - -// CVSS V3 -type CvssV3 struct { - // CVSS V3 version - Version V3Version `json:"version"` - - // CVSS V3 vector string - // VectorString string `json:"vectorString"` - - // CVSS vector - Vector Vector `json:"vectorString"` - - // attack vector - AttackVector V3AttackVector `json:"attackVector"` - - // attack complexity - AttackComplexity V3AttackComplexity `json:"attackComplexity"` - - // privileges required - PrivilegesRequired V3PrivilegesRequired `json:"privilegesRequired"` - - // user interaction - UserInteraction V3UserInteraction `json:"userInteraction"` - - // scope - Scope V3Scope `json:"scope"` - - // integrity impact - IntegrityImpact V3Impact `json:"integrityImpact"` - - // availability impact - AvailabilityImpact V3Impact `json:"availabilityImpact"` - - // base score - BaseScore Score `json:"baseScore"` - - // base severity - BaseSeverity Severity `json:"baseSeverity"` -} - -// CVSS V3 base metrics -type BaseMetricV3 struct { - CvssV3 CvssV3 `json:"cvssV3"` - ExploitabilityScore Score `json:"exploitabilityScore"` - ImpactScore Score `json:"impactScore"` -} - -// CVSS V2 -type CvssV2 struct { - // CVSS V2 version - Version V2Version `json:"version"` - - // CVSS vector string - // VectorString string `json:"vectorString"` - - // CVSS vector - Vector Vector `json:"vectorString"` - - // attack vector - AccessVector V2AccessVector `json:"accessVector"` - - // attack complexity - AccessComplexity V2AccessComplexity `json:"accessComplexity"` - - // authentication - Authentication V2Authentication `json:"authentication"` - - ConfidentialityImpact V2Impact `json:"confidentialityImpact"` - IntegrityImpact V2Impact `json:"integrityImpact"` - AvailabilityImpact V2Impact `json:"availabilityImpact"` - - // base score - BaseScore Score `json:"baseScore"` -} - -// CVSS V2 base metrics -type BaseMetricV2 struct { - CvssV2 CvssV2 `json:"cvssV2"` - Severity Severity `json:"severity"` - ExploitabilityScore Score `json:"exploitabilityScore"` - ImpactScore Score `json:"impactScore"` - InsufficientInfo bool `json:"acInsufInfo"` - ObtainAllPrivilege bool `json:"obtainAllPrivilege"` - ObtainUserPrivilege bool `json:"obtainUserPrivilege"` - ObtainOtherPrivilege bool `json:"obtainOtherPrivilege"` - UserInteractionRequired bool `json:"userInteractionRequired"` -} - -// Item impact -type Impact struct { - // CVSS V3 base metrics - BaseMetricV3 BaseMetricV3 `json:"baseMetricV3"` - - // CVSS V2 base metrics - BaseMetricV2 BaseMetricV2 `json:"baseMetricV2"` -} - -// CVE feed item -type Item struct { - // item CVE data - Cve Cve `json:"cve"` - - // item configuration - Configurations ItemConfigurations `json:"configurations"` - - // item impact - Impact Impact `json:"impact"` - - // item published date - PublishedDate Time `json:"publishedDate"` - - // last modification date - LastModifiedDate Time `json:"lastModifiedDate"` -} - -// NVD feed -type Feed struct { - // feed data type - DataType DataType `json:"CVE_data_type"` - - // feed data format - DataFormat DataFormat `json:"CVE_data_format"` - - // feed data format version - DataVersion DataVersion `json:"CVE_data_version"` - - // number of CVEs in feed - NumCVEs uint64 `json:"CVE_data_numberOfCVEs,string"` - - // data timestamp - Timestamp Time `json:"CVE_data_timestamp"` - - // CVE items - Items []Item `json:"CVE_Items"` -} diff --git a/internal/feed/feed_test.go b/internal/feed/feed_test.go deleted file mode 100644 index f31a3ae..0000000 --- a/internal/feed/feed_test.go +++ /dev/null @@ -1,56 +0,0 @@ -package feed - -import ( - "compress/gzip" - "encoding/json" - "io" - // "fmt" - "os" - "testing" -) - -func openTest(path string) (io.Reader, error) { - // open file for reading - file, err := os.Open(path) - if err != nil { - return nil, err - } - - // wrap in reader, return success - return gzip.NewReader(file) -} - -// Test feed parser -func TestFeedParser(t *testing.T) { - t.Run("TestUnmarshalJSON", func(t *testing.T) { - var f Feed - - // read test data, check for error - src, err := openTest("testdata/nvdcve-1.1-2021.json.gz") - if err != nil { - t.Error(err) - } - - // decode cve feed, check for error - d := json.NewDecoder(src) - if err := d.Decode(&f); err != nil { - t.Error(err) - } - }) -// var f Feed -// -// // decode cve feed -// d := json.NewDecoder(os.Stdin) -// if err := d.Decode(&f); err != nil { -// t.Error(err) -// } -// -// var dst bytes.Buffer -// -// // create json encoder -// e := json.NewEncoder(&dst) -// if err := e.Encode(f); err != nil { -// t.Error(err) -// } -} - diff --git a/internal/feed/meta.go b/internal/feed/meta.go deleted file mode 100644 index fd46025..0000000 --- a/internal/feed/meta.go +++ /dev/null @@ -1,106 +0,0 @@ -package feed - -import ( - "bufio" - "encoding/hex" - "fmt" - "io" - "strconv" - "strings" - "time" -) - -// NVD metadata. -type Meta struct { - LastModifiedDate time.Time // last modified time - Size uint64 // uncompressed size, in bytes - ZipSize uint64 // zip file size, in bytes - GzSize uint64 // gz file size, in bytes - Sha256 [32]byte // sha256 hash of uncompressed data -} - -func parseMetaSize(name, val string) (uint64, error) { - // parse value, check for error - v, err := strconv.ParseUint(val, 10, 64) - if err == nil { - // return size - return v, nil - } else { - // return error - return 0, fmt.Errorf("invalid %s: \"%s\"", name, val) - } -} - -// Unmarshal new Metadata from reader. -func NewMeta(r io.Reader) (*Meta, error) { - // declare result - var m Meta - - // create scanner - scanner := bufio.NewScanner(r) - - // read lines - for scanner.Scan() { - // split into key/value pair, check for error - pair := strings.SplitN(scanner.Text(), ":", 2) - if len(pair) != 2 { - return nil, fmt.Errorf("bad meta line: \"%s\"", scanner.Text()) - } - - switch pair[0] { - case "lastModifiedDate": - // parse time, check for error - if err := m.LastModifiedDate.UnmarshalText([]byte(pair[1])); err != nil { - return nil, err - } - case "size": - if v, err := parseMetaSize("size", pair[1]); err == nil { - m.Size = v - } else { - return nil, err - } - case "zipSize": - if v, err := parseMetaSize("zipSize", pair[1]); err == nil { - m.ZipSize = v - } else { - return nil, err - } - case "gzSize": - if v, err := parseMetaSize("gzSize", pair[1]); err == nil { - m.GzSize = v - } else { - return nil, err - } - case "sha256": - // check hash length - if len(pair[1]) != 64 { - return nil, fmt.Errorf("invalid sha256 hash length: %d", len(pair[1])) - } - - // decode hex, check for error - buf, err := hex.DecodeString(pair[1]) - if err != nil { - return nil, fmt.Errorf("invalid sha256 hash: %v", err) - } - - // save to buffer, check for error - len := copy(m.Sha256[:], buf[0:32]) - if len != 32 { - // difficult to test, but this basically doesn't happen, see here: - // https://github.com/golang/go/blob/2ebe77a2fda1ee9ff6fd9a3e08933ad1ebaea039/src/runtime/slice.go#L247 - return nil, fmt.Errorf("invalid copy length: %d", len) - } - default: - // return error - return nil, fmt.Errorf("unknown key: \"%s\"", pair[0]) - } - } - - // check for scanner error - if err := scanner.Err(); err != nil { - return nil, err - } - - // return success - return &m, nil -} diff --git a/internal/feed/meta_test.go b/internal/feed/meta_test.go deleted file mode 100644 index 3ea5acb..0000000 --- a/internal/feed/meta_test.go +++ /dev/null @@ -1,149 +0,0 @@ -package feed - -import ( - "bytes" - "encoding/json" - "fmt" - "testing" -) - -func TestParseMetaSize(t *testing.T) { - passTests := []struct { - val string - exp uint64 - } { - { "0", 0 }, - { "1024", 1024 }, - { "18446744073709551615", 18446744073709551615 }, - } - - for _, test := range(passTests) { - t.Run(test.val, func(t *testing.T) { - got, err := parseMetaSize("foo", test.val) - if err != nil { - t.Error(err) - return - } - - if got != test.exp { - t.Errorf("got %d, exp %d", got, test.exp) - return - } - }) - } - - failTests := []struct { - val string - exp string - } { - { "-1", "invalid foo: \"-1\"" }, - { "a", "invalid foo: \"a\"" }, - { "18446744073709551616", "invalid foo: \"18446744073709551616\"" }, - } - - for _, test := range(failTests) { - t.Run(test.val, func(t *testing.T) { - got, err := parseMetaSize("foo", test.val) - if err == nil { - t.Errorf("got %d, exp error", got) - } else if err.Error() != test.exp { - t.Errorf("got \"%s\", exp \"%s\"", err.Error(), test.exp) - } - }) - } -} - -// test data -const testMeta = `lastModifiedDate:2022-01-29T03:01:16-05:00 -size:73202582 -zipSize:3753799 -gzSize:3753663 -sha256:B86258D5D9861507A1894A7B92011764803D7267787B1487539E240EA2405440 -` - -// Test meta parser -func TestNewMeta(t *testing.T) { - passTests := []string { - `lastModifiedDate:2022-01-29T03:01:16-05:00 -size:73202582 -zipSize:3753799 -gzSize:3753663 -sha256:B86258D5D9861507A1894A7B92011764803D7267787B1487539E240EA2405440 -`, - } - - for i, val := range(passTests) { - // build test name - name := fmt.Sprintf("passTests[%d]", i) - - t.Run(name, func(t *testing.T) { - // create buffer - buf := bytes.NewBufferString(val) - - // decode meta, check for error - _, err := NewMeta(buf) - if err != nil { - t.Error(err) - } - }) - } - - // build 65k token to make scanner fail - longVal := make([]byte, 65536) - for i := 0; i < cap(longVal); i++ { - longVal[i] = 'a' - } - - failTests := []struct { - val string - exp string - } { - { "asdf", "bad meta line: \"asdf\"" }, - { "lastModifiedDate:asdf", "parsing time \"asdf\" as \"2006-01-02T15:04:05Z07:00\": cannot parse \"asdf\" as \"2006\"" }, - { "size:a", "invalid size: \"a\"" }, - { "zipSize:a", "invalid zipSize: \"a\"" }, - { "gzSize:a", "invalid gzSize: \"a\"" }, - { "sha256:a", "invalid sha256 hash length: 1" }, - { - val: "sha256:0z00000000000000000000000000000000000000000000000000000000000000", - exp: "invalid sha256 hash: encoding/hex: invalid byte: U+007A 'z'", - }, - { string(longVal), "bufio.Scanner: token too long" }, - { "foo:bar", "unknown key: \"foo\"" }, - } - - for _, test := range(failTests) { - t.Run(test.val, func(t *testing.T) { - // create buffer - buf := bytes.NewBufferString(test.val) - - // decode meta, check for error - got, err := NewMeta(buf) - if err == nil { - t.Errorf("got %v, exp error", got) - } else if err.Error() != test.exp { - t.Errorf("got \"%s\", exp \"%s\"", err.Error(), test.exp) - } - }) - } - - t.Run("JsonEncode", func(t *testing.T) { - // create buffer - buf := bytes.NewBufferString(passTests[0]) - - // decode meta, check for error - meta, err := NewMeta(buf) - if err != nil { - t.Error(err) - } - - // create destination buffer - var dst bytes.Buffer - - // create json encoder - e := json.NewEncoder(&dst) - if err := e.Encode(meta); err != nil { - t.Error(err) - } - }) -} diff --git a/internal/feed/nodeop.go b/internal/feed/nodeop.go deleted file mode 100644 index 8bfa0a0..0000000 --- a/internal/feed/nodeop.go +++ /dev/null @@ -1,39 +0,0 @@ -package feed - -//go:generate stringer -linecomment -type=NodeOp - -import ( - "encoding/json" - "fmt" -) - -// Node boolean operator. -type NodeOp byte - -const ( - OrOp NodeOp = iota // OR - AndOp // AND -) - -// Unmarshal DataVersion from JSON. -func (me *NodeOp) UnmarshalJSON(b []byte) error { - // decode string, check for error - var s string - if err := json.Unmarshal(b, &s); err != nil { - return err - } - - // check value - switch s { - case "AND": - *me = AndOp - case "OR": - *me = OrOp - default: - // return error - return fmt.Errorf("unknown operator: %s", s) - } - - // return success - return nil -} diff --git a/internal/feed/nodeop_string.go b/internal/feed/nodeop_string.go deleted file mode 100644 index 2c120d4..0000000 --- a/internal/feed/nodeop_string.go +++ /dev/null @@ -1,24 +0,0 @@ -// Code generated by "stringer -linecomment -type=NodeOp"; DO NOT EDIT. - -package feed - -import "strconv" - -func _() { - // An "invalid array index" compiler error signifies that the constant values have changed. - // Re-run the stringer command to generate them again. - var x [1]struct{} - _ = x[OrOp-0] - _ = x[AndOp-1] -} - -const _NodeOp_name = "ORAND" - -var _NodeOp_index = [...]uint8{0, 2, 5} - -func (i NodeOp) String() string { - if i >= NodeOp(len(_NodeOp_index)-1) { - return "NodeOp(" + strconv.FormatInt(int64(i), 10) + ")" - } - return _NodeOp_name[_NodeOp_index[i]:_NodeOp_index[i+1]] -} diff --git a/internal/feed/nodeop_test.go b/internal/feed/nodeop_test.go deleted file mode 100644 index dd538e5..0000000 --- a/internal/feed/nodeop_test.go +++ /dev/null @@ -1,77 +0,0 @@ -package feed - -import ( - "encoding/json" - "testing" -) - -func TestNodeOpUnmarshalInvalidData(t *testing.T) { - test := []byte(`{}`) - var val NodeOp - - if err := json.Unmarshal(test, &val); err == nil { - t.Errorf("got \"%s\", exp error", val) - } -} - -func TestNodeOpUnmarshalUnknown(t *testing.T) { - test := []byte(`"foo"`) - exp := "unknown operator: foo" - var val NodeOp - - err := json.Unmarshal(test, &val) - if err == nil { - t.Errorf("got \"%s\", exp error", val) - return - } - - if err.Error() != exp { - t.Errorf("got \"%s\", exp \"%s\"", err.Error(), exp) - } -} - -func TestNodeOpUnmarshalValid(t *testing.T) { - tests := []struct { - val string - exp NodeOp - } { - { "\"AND\"", AndOp }, - { "\"OR\"", OrOp }, - } - - for _, test := range(tests) { - t.Run(test.val, func(t *testing.T) { - var got NodeOp - if err := json.Unmarshal([]byte(test.val), &got); err != nil { - t.Error(err) - return - } - - if got != test.exp { - t.Errorf("got \"%s\", exp \"%s\"", got, test.exp) - } - }) - } -} - -func TestNodeOpString(t *testing.T) { - tests := []struct { - val NodeOp - exp string - } { - { AndOp, "AND" }, - { OrOp, "OR" }, - - { NodeOp(255), "NodeOp(255)" }, - } - - for _, test := range(tests) { - t.Run(test.exp, func(t *testing.T) { - got := test.val.String() - - if got != test.exp { - t.Errorf("got \"%s\", exp \"%s\"", got, test.exp) - } - }) - } -} diff --git a/internal/feed/score.go b/internal/feed/score.go deleted file mode 100644 index 051522f..0000000 --- a/internal/feed/score.go +++ /dev/null @@ -1,34 +0,0 @@ -package feed - -import ( - "encoding/json" - "fmt" - "math" - "strconv" -) - -// CVSS score -type Score uint8 - -// Unmarshal CVSS score from JSON. -func (me *Score) UnmarshalJSON(b []byte) error { - // decode float, check for error - var v float64 - if err := json.Unmarshal(b, &v); err != nil { - return err - } - - // check score - if v < 0.0 || v > 10.0 { - return fmt.Errorf("CVSS score out of bounds: %2.1f", v) - } - - // save result, return success - *me = Score(uint8(math.Trunc(10.0 * v))) - return nil -} - -func (me Score) String() string { - val := float64(me) / 10.0 - return strconv.FormatFloat(val, 'f', 1, 64) -} diff --git a/internal/feed/score_test.go b/internal/feed/score_test.go deleted file mode 100644 index 2baa7ab..0000000 --- a/internal/feed/score_test.go +++ /dev/null @@ -1,92 +0,0 @@ -package feed - -import ( - "encoding/json" - "testing" -) - -func TestScoreUnmarshalInvalidData(t *testing.T) { - test := []byte(`{}`) - var val Score - - if err := json.Unmarshal(test, &val); err == nil { - t.Errorf("got \"%s\", exp error", val) - } -} - -func TestScoreUnmarshalInvalidValues(t *testing.T) { - tests := []struct { - val string - exp string - } { - { `-100.0`, "CVSS score out of bounds: -100.0" }, - { `-90.0`, "CVSS score out of bounds: -90.0" }, - { `-9.3`, "CVSS score out of bounds: -9.3" }, - { `-1`, "CVSS score out of bounds: -1.0" }, - { `10.1`, "CVSS score out of bounds: 10.1" }, - { `100.0`, "CVSS score out of bounds: 100.0" }, - } - - for _, test := range(tests) { - t.Run(test.val, func(t *testing.T) { - var got Score - - if err := json.Unmarshal([]byte(test.val), &got); err == nil { - t.Errorf("got \"%s\", exp error", got) - } else if err.Error() != test.exp { - t.Errorf("got \"%s\", exp \"%s\"", err.Error(), test.exp) - } - }) - } -} - -func TestScoreUnmarshalValidValues(t *testing.T) { - tests := []struct { - val string - exp uint8 - } { - { `0.0`, 0 }, - { `0.1`, 1 }, - { `1.2`, 12 }, - { `5.9`, 59 }, - { `9.9`, 99 }, - { `10.0`, 100 }, - } - - for _, test := range(tests) { - t.Run(test.val, func(t *testing.T) { - var got Score - - if err := json.Unmarshal([]byte(test.val), &got); err != nil { - t.Error(err) - return - } else if uint8(got) != test.exp { - t.Errorf("got \"%d\", exp \"%d\"", uint8(got), test.exp) - } - }) - } -} - -func TestScoreString(t *testing.T) { - tests := []struct { - val uint8 - exp string - } { - { 0, "0.0" }, - { 1, "0.1" }, - { 9, "0.9" }, - { 12, "1.2" }, - { 59, "5.9" }, - { 99, "9.9" }, - { 100, "10.0" }, - } - - for _, test := range(tests) { - t.Run(test.exp, func(t *testing.T) { - got := Score(test.val).String() - if got != test.exp { - t.Errorf("got \"%s\", exp \"%s\"", got, test.exp) - } - }) - } -} diff --git a/internal/feed/severity.go b/internal/feed/severity.go deleted file mode 100644 index 50969ed..0000000 --- a/internal/feed/severity.go +++ /dev/null @@ -1,47 +0,0 @@ -package feed - -//go:generate stringer -linecomment -type=Severity - -import ( - "encoding/json" - "fmt" -) - -type Severity byte - -const ( - SeverityNone Severity = iota // NONE - SeverityLow // LOW - SeverityMedium // MEDIUM - SeverityHigh // HIGH - SeverityCritical // CRITICAL -) - -// Unmarshal CVSS severity from JSON. -func (me *Severity) UnmarshalJSON(b []byte) error { - // decode string, check for error - var s string - if err := json.Unmarshal(b, &s); err != nil { - return err - } - - // check value - switch s { - case "NONE": - *me = SeverityNone - case "LOW": - *me = SeverityLow - case "MEDIUM": - *me = SeverityMedium - case "HIGH": - *me = SeverityHigh - case "CRITICAL": - *me = SeverityCritical - default: - // return error - return fmt.Errorf("unknown severity: %s", s) - } - - // return success - return nil -} diff --git a/internal/feed/severity_string.go b/internal/feed/severity_string.go deleted file mode 100644 index 28e1e91..0000000 --- a/internal/feed/severity_string.go +++ /dev/null @@ -1,27 +0,0 @@ -// Code generated by "stringer -linecomment -type=Severity"; DO NOT EDIT. - -package feed - -import "strconv" - -func _() { - // An "invalid array index" compiler error signifies that the constant values have changed. - // Re-run the stringer command to generate them again. - var x [1]struct{} - _ = x[SeverityNone-0] - _ = x[SeverityLow-1] - _ = x[SeverityMedium-2] - _ = x[SeverityHigh-3] - _ = x[SeverityCritical-4] -} - -const _Severity_name = "NONELOWMEDIUMHIGHCRITICAL" - -var _Severity_index = [...]uint8{0, 4, 7, 13, 17, 25} - -func (i Severity) String() string { - if i >= Severity(len(_Severity_index)-1) { - return "Severity(" + strconv.FormatInt(int64(i), 10) + ")" - } - return _Severity_name[_Severity_index[i]:_Severity_index[i+1]] -} diff --git a/internal/feed/severity_test.go b/internal/feed/severity_test.go deleted file mode 100644 index 75aec72..0000000 --- a/internal/feed/severity_test.go +++ /dev/null @@ -1,83 +0,0 @@ -package feed - -import ( - "encoding/json" - "testing" -) - -func TestSeverityUnmarshalInvalidData(t *testing.T) { - test := []byte(`{}`) - var val Severity - - if err := json.Unmarshal(test, &val); err == nil { - t.Errorf("got \"%s\", exp error", val) - } -} - -func TestSeverityUnmarshalUnknown(t *testing.T) { - test := []byte(`"foo"`) - exp := "unknown severity: foo" - var val Severity - - err := json.Unmarshal(test, &val) - if err == nil { - t.Errorf("got \"%s\", exp error", val) - return - } - - if err.Error() != exp { - t.Errorf("got \"%s\", exp \"%s\"", err.Error(), exp) - } -} - -func TestSeverityUnmarshalValid(t *testing.T) { - tests := []struct { - val string - exp Severity - } { - { "\"NONE\"", SeverityNone }, - { "\"LOW\"", SeverityLow }, - { "\"MEDIUM\"", SeverityMedium }, - { "\"HIGH\"", SeverityHigh }, - { "\"CRITICAL\"", SeverityCritical }, - } - - for _, test := range(tests) { - t.Run(test.val, func(t *testing.T) { - var got Severity - if err := json.Unmarshal([]byte(test.val), &got); err != nil { - t.Error(err) - return - } - - if got != test.exp { - t.Errorf("got \"%s\", exp \"%s\"", got, test.exp) - } - }) - } -} - -func TestSeverityString(t *testing.T) { - tests := []struct { - val Severity - exp string - } { - { SeverityNone, "NONE" }, - { SeverityLow, "LOW" }, - { SeverityMedium, "MEDIUM" }, - { SeverityHigh, "HIGH" }, - { SeverityCritical, "CRITICAL" }, - - { Severity(255), "Severity(255)" }, - } - - for _, test := range(tests) { - t.Run(test.exp, func(t *testing.T) { - got := test.val.String() - - if got != test.exp { - t.Errorf("got \"%s\", exp \"%s\"", got, test.exp) - } - }) - } -} diff --git a/internal/feed/testdata/nvdcve-1.1-2002.json.gz b/internal/feed/testdata/nvdcve-1.1-2002.json.gz Binary files differdeleted file mode 100644 index 45e714d..0000000 --- a/internal/feed/testdata/nvdcve-1.1-2002.json.gz +++ /dev/null diff --git a/internal/feed/testdata/nvdcve-1.1-2003.json.gz b/internal/feed/testdata/nvdcve-1.1-2003.json.gz Binary files differdeleted file mode 100644 index c7796a6..0000000 --- a/internal/feed/testdata/nvdcve-1.1-2003.json.gz +++ /dev/null diff --git a/internal/feed/testdata/nvdcve-1.1-2021.json.gz b/internal/feed/testdata/nvdcve-1.1-2021.json.gz Binary files differdeleted file mode 100644 index 83ca5e6..0000000 --- a/internal/feed/testdata/nvdcve-1.1-2021.json.gz +++ /dev/null diff --git a/internal/feed/testdata/nvdcve-1.1-modified.json.gz b/internal/feed/testdata/nvdcve-1.1-modified.json.gz Binary files differdeleted file mode 100644 index c675fb6..0000000 --- a/internal/feed/testdata/nvdcve-1.1-modified.json.gz +++ /dev/null diff --git a/internal/feed/time.go b/internal/feed/time.go deleted file mode 100644 index 6eb5d37..0000000 --- a/internal/feed/time.go +++ /dev/null @@ -1,44 +0,0 @@ -package feed - -import ( - "encoding/json" - "fmt" - // "strconv" - "regexp" - "time" -) - -// partial timestamp -type Time time.Time - -var timeRe = regexp.MustCompile("\\A\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}Z\\z") - -// Unmarshal timestamp from JSON. -func (me *Time) UnmarshalJSON(b []byte) error { - // decode string, check for error - var s string - if err := json.Unmarshal(b, &s); err != nil { - return err - } - - // match partial string regex - if !timeRe.MatchString(s) { - return fmt.Errorf("invalid time: \"%s\"", s) - } - - // correct string suffix - s = s[0:16] + ":00Z" - - // unmarshal time - var t time.Time - if err := t.UnmarshalText([]byte(s)); err != nil { - return err - } - - // save time - *me = Time(t) - - // return success - return nil -} - diff --git a/internal/feed/time_test.go b/internal/feed/time_test.go deleted file mode 100644 index cc490c5..0000000 --- a/internal/feed/time_test.go +++ /dev/null @@ -1,66 +0,0 @@ -package feed - -import ( - "encoding/json" - "testing" - "time" -) - -func TestTimeUnmarshallInvalidData(t *testing.T) { - test := []byte(`{}`) - var val Time - - if err := json.Unmarshal(test, &val); err == nil { - t.Errorf("got \"%v\", exp error", val) - } -} - -func TestTimeUnmarshallInvalidString(t *testing.T) { - test := []byte(`"2020-"`) - exp := "invalid time: \"2020-\"" - var val Time - - if err := json.Unmarshal(test, &val); err == nil { - t.Errorf("got \"%v\", exp error", val) - } else if err.Error() != exp { - t.Errorf("got \"%s\", exp \"%s\"", err.Error(), exp) - } -} - -func TestTimeUnmarshallInvalidTime(t *testing.T) { - test := []byte(`"2020-99-99T99:99Z"`) - var val Time - - if err := json.Unmarshal(test, &val); err == nil { - t.Errorf("got \"%v\", exp error", val) - } -} - -func TestTimeString(t *testing.T) { - tests := []struct { - val string - exp string - } { - { "\"2021-06-09T20:15Z\"", "2021-06-09T20:15:00Z" }, - } - - for _, test := range(tests) { - t.Run(test.val, func(t *testing.T) { - var gotTime Time - if err := json.Unmarshal([]byte(test.val), &gotTime); err != nil { - t.Error(err) - return - } - - got, err := time.Time(gotTime).MarshalText() - if err != nil { - t.Error(err) - return - } - - if string(got) != test.exp { - t.Errorf("got \"%s\", exp \"%s\"", string(got), test.exp) - } - }) - } -} diff --git a/internal/feed/v2accesscomplexity.go b/internal/feed/v2accesscomplexity.go deleted file mode 100644 index 5885e0d..0000000 --- a/internal/feed/v2accesscomplexity.go +++ /dev/null @@ -1,42 +0,0 @@ -package feed - -//go:generate stringer -linecomment -type=V2AccessComplexity - -import ( - "encoding/json" - "fmt" -) - -// CVSS v2 access complexity -type V2AccessComplexity byte - -const ( - V2ACLow V2AccessComplexity = iota // LOW - V2ACMedium // MEDIUM - V2ACHigh // HIGH -) - -// Unmarshal CVSS V2 access complexity from JSON. -func (me *V2AccessComplexity) UnmarshalJSON(b []byte) error { - // decode string, check for error - var s string - if err := json.Unmarshal(b, &s); err != nil { - return err - } - - // check value - switch s { - case "LOW": - *me = V2ACLow - case "MEDIUM": - *me = V2ACMedium - case "HIGH": - *me = V2ACHigh - default: - // return error - return fmt.Errorf("unknown CVSS v2 access complexity: %s", s) - } - - // return success - return nil -} diff --git a/internal/feed/v2accesscomplexity_string.go b/internal/feed/v2accesscomplexity_string.go deleted file mode 100644 index 8638b3d..0000000 --- a/internal/feed/v2accesscomplexity_string.go +++ /dev/null @@ -1,25 +0,0 @@ -// Code generated by "stringer -linecomment -type=V2AccessComplexity"; DO NOT EDIT. - -package feed - -import "strconv" - -func _() { - // An "invalid array index" compiler error signifies that the constant values have changed. - // Re-run the stringer command to generate them again. - var x [1]struct{} - _ = x[V2ACLow-0] - _ = x[V2ACMedium-1] - _ = x[V2ACHigh-2] -} - -const _V2AccessComplexity_name = "LOWMEDIUMHIGH" - -var _V2AccessComplexity_index = [...]uint8{0, 3, 9, 13} - -func (i V2AccessComplexity) String() string { - if i >= V2AccessComplexity(len(_V2AccessComplexity_index)-1) { - return "V2AccessComplexity(" + strconv.FormatInt(int64(i), 10) + ")" - } - return _V2AccessComplexity_name[_V2AccessComplexity_index[i]:_V2AccessComplexity_index[i+1]] -} diff --git a/internal/feed/v2accesscomplexity_test.go b/internal/feed/v2accesscomplexity_test.go deleted file mode 100644 index 2dd173d..0000000 --- a/internal/feed/v2accesscomplexity_test.go +++ /dev/null @@ -1,79 +0,0 @@ -package feed - -import ( - "encoding/json" - "testing" -) - -func TestV2AccessComplexityUnmarshalInvalidData(t *testing.T) { - test := []byte(`{}`) - var val V2AccessComplexity - - if err := json.Unmarshal(test, &val); err == nil { - t.Errorf("got \"%s\", exp error", val) - } -} - -func TestV2AccessComplexityUnmarshalUnknown(t *testing.T) { - test := []byte(`"foo"`) - exp := "unknown CVSS v2 access complexity: foo" - var val V2AccessComplexity - - err := json.Unmarshal(test, &val) - if err == nil { - t.Errorf("got \"%s\", exp error", val) - return - } - - if err.Error() != exp { - t.Errorf("got \"%s\", exp \"%s\"", err.Error(), exp) - } -} - -func TestV2AccessComplexityUnmarshalValid(t *testing.T) { - tests := []struct { - val string - exp V2AccessComplexity - } { - { "\"LOW\"", V2ACLow }, - { "\"MEDIUM\"", V2ACMedium }, - { "\"HIGH\"", V2ACHigh }, - } - - for _, test := range(tests) { - t.Run(test.val, func(t *testing.T) { - var got V2AccessComplexity - if err := json.Unmarshal([]byte(test.val), &got); err != nil { - t.Error(err) - return - } - - if got != test.exp { - t.Errorf("got \"%s\", exp \"%s\"", got, test.exp) - } - }) - } -} - -func TestV2AccessComplexityString(t *testing.T) { - tests := []struct { - val V2AccessComplexity - exp string - } { - { V2ACLow, "LOW" }, - { V2ACMedium, "MEDIUM" }, - { V2ACHigh, "HIGH" }, - - { V2AccessComplexity(255), "V2AccessComplexity(255)" }, - } - - for _, test := range(tests) { - t.Run(test.exp, func(t *testing.T) { - got := test.val.String() - - if got != test.exp { - t.Errorf("got \"%s\", exp \"%s\"", got, test.exp) - } - }) - } -} diff --git a/internal/feed/v2accessvector.go b/internal/feed/v2accessvector.go deleted file mode 100644 index 80490c2..0000000 --- a/internal/feed/v2accessvector.go +++ /dev/null @@ -1,42 +0,0 @@ -package feed - -//go:generate stringer -linecomment -type=V2AccessVector - -import ( - "encoding/json" - "fmt" -) - -type V2AccessVector byte - -const ( - V2AVAdjacentNetwork V2AccessVector = iota // ADJACENT_NETWORK - V2AVLocal // LOCAL - V2AVNetwork // NETWORK -) - -// Unmarshal CVSS V2 access vector from JSON. -func (me *V2AccessVector) UnmarshalJSON(b []byte) error { - // decode string, check for error - var s string - if err := json.Unmarshal(b, &s); err != nil { - return err - } - - // check value - switch s { - case "ADJACENT_NETWORK": - *me = V2AVAdjacentNetwork - case "LOCAL": - *me = V2AVLocal - case "NETWORK": - *me = V2AVNetwork - default: - // return error - return fmt.Errorf("unknown CVSS v2 access vector: %s", s) - } - - // return success - return nil -} - diff --git a/internal/feed/v2accessvector_string.go b/internal/feed/v2accessvector_string.go deleted file mode 100644 index bf354fc..0000000 --- a/internal/feed/v2accessvector_string.go +++ /dev/null @@ -1,25 +0,0 @@ -// Code generated by "stringer -linecomment -type=V2AccessVector"; DO NOT EDIT. - -package feed - -import "strconv" - -func _() { - // An "invalid array index" compiler error signifies that the constant values have changed. - // Re-run the stringer command to generate them again. - var x [1]struct{} - _ = x[V2AVAdjacentNetwork-0] - _ = x[V2AVLocal-1] - _ = x[V2AVNetwork-2] -} - -const _V2AccessVector_name = "ADJACENT_NETWORKLOCALNETWORK" - -var _V2AccessVector_index = [...]uint8{0, 16, 21, 28} - -func (i V2AccessVector) String() string { - if i >= V2AccessVector(len(_V2AccessVector_index)-1) { - return "V2AccessVector(" + strconv.FormatInt(int64(i), 10) + ")" - } - return _V2AccessVector_name[_V2AccessVector_index[i]:_V2AccessVector_index[i+1]] -} diff --git a/internal/feed/v2accessvector_test.go b/internal/feed/v2accessvector_test.go deleted file mode 100644 index 6e0df24..0000000 --- a/internal/feed/v2accessvector_test.go +++ /dev/null @@ -1,79 +0,0 @@ -package feed - -import ( - "encoding/json" - "testing" -) - -func TestV2AccessVectorUnmarshalInvalidData(t *testing.T) { - test := []byte(`{}`) - var val V2AccessVector - - if err := json.Unmarshal(test, &val); err == nil { - t.Errorf("got \"%s\", exp error", val) - } -} - -func TestV2AccessVectorUnmarshalUnknown(t *testing.T) { - test := []byte(`"foo"`) - exp := "unknown CVSS v2 access vector: foo" - var val V2AccessVector - - err := json.Unmarshal(test, &val) - if err == nil { - t.Errorf("got \"%s\", exp error", val) - return - } - - if err.Error() != exp { - t.Errorf("got \"%s\", exp \"%s\"", err.Error(), exp) - } -} - -func TestV2AccessVectorUnmarshalValid(t *testing.T) { - tests := []struct { - val string - exp V2AccessVector - } { - { "\"ADJACENT_NETWORK\"", V2AVAdjacentNetwork }, - { "\"LOCAL\"", V2AVLocal }, - { "\"NETWORK\"", V2AVNetwork }, - } - - for _, test := range(tests) { - t.Run(test.val, func(t *testing.T) { - var got V2AccessVector - if err := json.Unmarshal([]byte(test.val), &got); err != nil { - t.Error(err) - return - } - - if got != test.exp { - t.Errorf("got \"%s\", exp \"%s\"", got, test.exp) - } - }) - } -} - -func TestV2AccessVectorString(t *testing.T) { - tests := []struct { - val V2AccessVector - exp string - } { - { V2AVAdjacentNetwork, "ADJACENT_NETWORK" }, - { V2AVLocal, "LOCAL" }, - { V2AVNetwork, "NETWORK" }, - - { V2AccessVector(255), "V2AccessVector(255)" }, - } - - for _, test := range(tests) { - t.Run(test.exp, func(t *testing.T) { - got := test.val.String() - - if got != test.exp { - t.Errorf("got \"%s\", exp \"%s\"", got, test.exp) - } - }) - } -} diff --git a/internal/feed/v2authentication.go b/internal/feed/v2authentication.go deleted file mode 100644 index 853954f..0000000 --- a/internal/feed/v2authentication.go +++ /dev/null @@ -1,39 +0,0 @@ -package feed - -//go:generate stringer -linecomment -type=V2Authentication - -import ( - "encoding/json" - "fmt" -) - -// CVSS v2 authentication -type V2Authentication byte - -const ( - V2AuthNone V2Authentication = iota // NONE - V2AuthSingle // SINGLE -) - -// Unmarshal CVSS V2 authentication from JSON. -func (me *V2Authentication) UnmarshalJSON(b []byte) error { - // decode string, check for error - var s string - if err := json.Unmarshal(b, &s); err != nil { - return err - } - - // check value - switch s { - case "NONE": - *me = V2AuthNone - case "SINGLE": - *me = V2AuthSingle - default: - // return error - return fmt.Errorf("unknown CVSS v2 authentication: %s", s) - } - - // return success - return nil -} diff --git a/internal/feed/v2authentication_string.go b/internal/feed/v2authentication_string.go deleted file mode 100644 index 856c808..0000000 --- a/internal/feed/v2authentication_string.go +++ /dev/null @@ -1,24 +0,0 @@ -// Code generated by "stringer -linecomment -type=V2Authentication"; DO NOT EDIT. - -package feed - -import "strconv" - -func _() { - // An "invalid array index" compiler error signifies that the constant values have changed. - // Re-run the stringer command to generate them again. - var x [1]struct{} - _ = x[V2AuthNone-0] - _ = x[V2AuthSingle-1] -} - -const _V2Authentication_name = "NONESINGLE" - -var _V2Authentication_index = [...]uint8{0, 4, 10} - -func (i V2Authentication) String() string { - if i >= V2Authentication(len(_V2Authentication_index)-1) { - return "V2Authentication(" + strconv.FormatInt(int64(i), 10) + ")" - } - return _V2Authentication_name[_V2Authentication_index[i]:_V2Authentication_index[i+1]] -} diff --git a/internal/feed/v2authentication_test.go b/internal/feed/v2authentication_test.go deleted file mode 100644 index 4f23764..0000000 --- a/internal/feed/v2authentication_test.go +++ /dev/null @@ -1,77 +0,0 @@ -package feed - -import ( - "encoding/json" - "testing" -) - -func TestV2AuthenticationUnmarshalInvalidData(t *testing.T) { - test := []byte(`{}`) - var val V2Authentication - - if err := json.Unmarshal(test, &val); err == nil { - t.Errorf("got \"%s\", exp error", val) - } -} - -func TestV2AuthenticationUnmarshalUnknown(t *testing.T) { - test := []byte(`"foo"`) - exp := "unknown CVSS v2 authentication: foo" - var val V2Authentication - - err := json.Unmarshal(test, &val) - if err == nil { - t.Errorf("got \"%s\", exp error", val) - return - } - - if err.Error() != exp { - t.Errorf("got \"%s\", exp \"%s\"", err.Error(), exp) - } -} - -func TestV2AuthenticationUnmarshalValid(t *testing.T) { - tests := []struct { - val string - exp V2Authentication - } { - { "\"NONE\"", V2AuthNone }, - { "\"SINGLE\"", V2AuthSingle }, - } - - for _, test := range(tests) { - t.Run(test.val, func(t *testing.T) { - var got V2Authentication - if err := json.Unmarshal([]byte(test.val), &got); err != nil { - t.Error(err) - return - } - - if got != test.exp { - t.Errorf("got \"%s\", exp \"%s\"", got, test.exp) - } - }) - } -} - -func TestV2AuthenticationString(t *testing.T) { - tests := []struct { - val V2Authentication - exp string - } { - { V2AuthNone, "NONE" }, - { V2AuthSingle, "SINGLE" }, - - { V2Authentication(255), "V2Authentication(255)" }, - } - - for _, test := range(tests) { - t.Run(test.exp, func(t *testing.T) { - got := test.val.String() - - if got != test.exp { - t.Errorf("got \"%s\", exp \"%s\"", got, test.exp) - } - }) - } -} diff --git a/internal/feed/v2impact.go b/internal/feed/v2impact.go deleted file mode 100644 index 1585e18..0000000 --- a/internal/feed/v2impact.go +++ /dev/null @@ -1,42 +0,0 @@ -package feed - -//go:generate stringer -linecomment -type=V2Impact - -import ( - "encoding/json" - "fmt" -) - -// CVSS v2 impact level. -type V2Impact byte - -const ( - V2ImpactNone V2Impact = iota // NONE - V2ImpactPartial // PARTIAL - V2ImpactComplete // COMPLETE -) - -// Unmarshal CVSS v2 impact level from JSON. -func (me *V2Impact) UnmarshalJSON(b []byte) error { - // decode string, check for error - var s string - if err := json.Unmarshal(b, &s); err != nil { - return err - } - - // check value - switch s { - case "NONE": - *me = V2ImpactNone - case "PARTIAL": - *me = V2ImpactPartial - case "COMPLETE": - *me = V2ImpactComplete - default: - // return error - return fmt.Errorf("unknown CVSS v2 impact: %s", s) - } - - // return success - return nil -} diff --git a/internal/feed/v2impact_string.go b/internal/feed/v2impact_string.go deleted file mode 100644 index 1dcf21b..0000000 --- a/internal/feed/v2impact_string.go +++ /dev/null @@ -1,25 +0,0 @@ -// Code generated by "stringer -linecomment -type=V2Impact"; DO NOT EDIT. - -package feed - -import "strconv" - -func _() { - // An "invalid array index" compiler error signifies that the constant values have changed. - // Re-run the stringer command to generate them again. - var x [1]struct{} - _ = x[V2ImpactNone-0] - _ = x[V2ImpactPartial-1] - _ = x[V2ImpactComplete-2] -} - -const _V2Impact_name = "NONEPARTIALCOMPLETE" - -var _V2Impact_index = [...]uint8{0, 4, 11, 19} - -func (i V2Impact) String() string { - if i >= V2Impact(len(_V2Impact_index)-1) { - return "V2Impact(" + strconv.FormatInt(int64(i), 10) + ")" - } - return _V2Impact_name[_V2Impact_index[i]:_V2Impact_index[i+1]] -} diff --git a/internal/feed/v2impact_test.go b/internal/feed/v2impact_test.go deleted file mode 100644 index 54dc566..0000000 --- a/internal/feed/v2impact_test.go +++ /dev/null @@ -1,79 +0,0 @@ -package feed - -import ( - "encoding/json" - "testing" -) - -func TestV2ImpactUnmarshalInvalidData(t *testing.T) { - test := []byte(`{}`) - var val V2Impact - - if err := json.Unmarshal(test, &val); err == nil { - t.Errorf("got \"%s\", exp error", val) - } -} - -func TestV2ImpactUnmarshalUnknown(t *testing.T) { - test := []byte(`"foo"`) - exp := "unknown CVSS v2 impact: foo" - var val V2Impact - - err := json.Unmarshal(test, &val) - if err == nil { - t.Errorf("got \"%s\", exp error", val) - return - } - - if err.Error() != exp { - t.Errorf("got \"%s\", exp \"%s\"", err.Error(), exp) - } -} - -func TestV2ImpactUnmarshalValid(t *testing.T) { - tests := []struct { - val string - exp V2Impact - } { - { "\"NONE\"", V2ImpactNone }, - { "\"PARTIAL\"", V2ImpactPartial }, - { "\"COMPLETE\"", V2ImpactComplete }, - } - - for _, test := range(tests) { - t.Run(test.val, func(t *testing.T) { - var got V2Impact - if err := json.Unmarshal([]byte(test.val), &got); err != nil { - t.Error(err) - return - } - - if got != test.exp { - t.Errorf("got \"%s\", exp \"%s\"", got, test.exp) - } - }) - } -} - -func TestV2ImpactString(t *testing.T) { - tests := []struct { - val V2Impact - exp string - } { - { V2ImpactNone, "NONE" }, - { V2ImpactPartial, "PARTIAL" }, - { V2ImpactComplete, "COMPLETE" }, - - { V2Impact(255), "V2Impact(255)" }, - } - - for _, test := range(tests) { - t.Run(test.exp, func(t *testing.T) { - got := test.val.String() - - if got != test.exp { - t.Errorf("got \"%s\", exp \"%s\"", got, test.exp) - } - }) - } -} diff --git a/internal/feed/v2version.go b/internal/feed/v2version.go deleted file mode 100644 index 76e6134..0000000 --- a/internal/feed/v2version.go +++ /dev/null @@ -1,36 +0,0 @@ -package feed - -//go:generate stringer -linecomment -type=V2Version - -import ( - "encoding/json" - "fmt" -) - -// CVSS v2 version -type V2Version byte - -const ( - V20 V2Version = iota // 2.0 -) - -// Unmarshal CVSS V2 version from JSON. -func (me *V2Version) UnmarshalJSON(b []byte) error { - // decode string, check for error - var s string - if err := json.Unmarshal(b, &s); err != nil { - return err - } - - // check value - switch s { - case "2.0": - *me = V20 - default: - // return error - return fmt.Errorf("unknown CVSS version: %s", s) - } - - // return success - return nil -} diff --git a/internal/feed/v2version_string.go b/internal/feed/v2version_string.go deleted file mode 100644 index 6b13870..0000000 --- a/internal/feed/v2version_string.go +++ /dev/null @@ -1,23 +0,0 @@ -// Code generated by "stringer -linecomment -type=V2Version"; DO NOT EDIT. - -package feed - -import "strconv" - -func _() { - // An "invalid array index" compiler error signifies that the constant values have changed. - // Re-run the stringer command to generate them again. - var x [1]struct{} - _ = x[V20-0] -} - -const _V2Version_name = "2.0" - -var _V2Version_index = [...]uint8{0, 3} - -func (i V2Version) String() string { - if i >= V2Version(len(_V2Version_index)-1) { - return "V2Version(" + strconv.FormatInt(int64(i), 10) + ")" - } - return _V2Version_name[_V2Version_index[i]:_V2Version_index[i+1]] -} diff --git a/internal/feed/v2version_test.go b/internal/feed/v2version_test.go deleted file mode 100644 index 3b9b029..0000000 --- a/internal/feed/v2version_test.go +++ /dev/null @@ -1,75 +0,0 @@ -package feed - -import ( - "encoding/json" - "testing" -) - -func TestV2VersionUnmarshalInvalidData(t *testing.T) { - test := []byte(`{}`) - var val V2Version - - if err := json.Unmarshal(test, &val); err == nil { - t.Errorf("got \"%s\", exp error", val) - } -} - -func TestV2VersionUnmarshalUnknown(t *testing.T) { - test := []byte(`"foo"`) - exp := "unknown CVSS version: foo" - var val V2Version - - err := json.Unmarshal(test, &val) - if err == nil { - t.Errorf("got \"%s\", exp error", val) - return - } - - if err.Error() != exp { - t.Errorf("got \"%s\", exp \"%s\"", err.Error(), exp) - } -} - -func TestV2VersionUnmarshalValid(t *testing.T) { - tests := []struct { - val string - exp V2Version - } { - { "\"2.0\"", V20 }, - } - - for _, test := range(tests) { - t.Run(test.val, func(t *testing.T) { - var got V2Version - if err := json.Unmarshal([]byte(test.val), &got); err != nil { - t.Error(err) - return - } - - if got != test.exp { - t.Errorf("got \"%s\", exp \"%s\"", got, test.exp) - } - }) - } -} - -func TestV2VersionString(t *testing.T) { - tests := []struct { - val V2Version - exp string - } { - { V20, "2.0" }, - - { V2Version(255), "V2Version(255)" }, - } - - for _, test := range(tests) { - t.Run(test.exp, func(t *testing.T) { - got := test.val.String() - - if got != test.exp { - t.Errorf("got \"%s\", exp \"%s\"", got, test.exp) - } - }) - } -} diff --git a/internal/feed/v3attackcomplexity.go b/internal/feed/v3attackcomplexity.go deleted file mode 100644 index 6e7481c..0000000 --- a/internal/feed/v3attackcomplexity.go +++ /dev/null @@ -1,42 +0,0 @@ -package feed - -//go:generate stringer -linecomment -type=V3AttackComplexity - -import ( - "encoding/json" - "fmt" -) - -// CVSS v3 attack complexity -type V3AttackComplexity byte - -const ( - V3ACLow V3AttackComplexity = iota // LOW - V3ACMedium // MEDIUM - V3ACHigh // HIGH -) - -// Unmarshal CVSS v3 attack complexity from JSON. -func (me *V3AttackComplexity) UnmarshalJSON(b []byte) error { - // decode string, check for error - var s string - if err := json.Unmarshal(b, &s); err != nil { - return err - } - - // check value - switch s { - case "LOW": - *me = V3ACLow - case "MEDIUM": - *me = V3ACMedium - case "HIGH": - *me = V3ACHigh - default: - // return error - return fmt.Errorf("unknown CVSS v3 attack complexity: %s", s) - } - - // return success - return nil -} diff --git a/internal/feed/v3attackcomplexity_string.go b/internal/feed/v3attackcomplexity_string.go deleted file mode 100644 index 12110c8..0000000 --- a/internal/feed/v3attackcomplexity_string.go +++ /dev/null @@ -1,25 +0,0 @@ -// Code generated by "stringer -linecomment -type=V3AttackComplexity"; DO NOT EDIT. - -package feed - -import "strconv" - -func _() { - // An "invalid array index" compiler error signifies that the constant values have changed. - // Re-run the stringer command to generate them again. - var x [1]struct{} - _ = x[V3ACLow-0] - _ = x[V3ACMedium-1] - _ = x[V3ACHigh-2] -} - -const _V3AttackComplexity_name = "LOWMEDIUMHIGH" - -var _V3AttackComplexity_index = [...]uint8{0, 3, 9, 13} - -func (i V3AttackComplexity) String() string { - if i >= V3AttackComplexity(len(_V3AttackComplexity_index)-1) { - return "V3AttackComplexity(" + strconv.FormatInt(int64(i), 10) + ")" - } - return _V3AttackComplexity_name[_V3AttackComplexity_index[i]:_V3AttackComplexity_index[i+1]] -} diff --git a/internal/feed/v3attackcomplexity_test.go b/internal/feed/v3attackcomplexity_test.go deleted file mode 100644 index a76efe3..0000000 --- a/internal/feed/v3attackcomplexity_test.go +++ /dev/null @@ -1,79 +0,0 @@ -package feed - -import ( - "encoding/json" - "testing" -) - -func TestV3AttackComplexityUnmarshalInvalidData(t *testing.T) { - test := []byte(`{}`) - var val V3AttackComplexity - - if err := json.Unmarshal(test, &val); err == nil { - t.Errorf("got \"%s\", exp error", val) - } -} - -func TestV3AttackComplexityUnmarshalUnknown(t *testing.T) { - test := []byte(`"foo"`) - exp := "unknown CVSS v3 attack complexity: foo" - var val V3AttackComplexity - - err := json.Unmarshal(test, &val) - if err == nil { - t.Errorf("got \"%s\", exp error", val) - return - } - - if err.Error() != exp { - t.Errorf("got \"%s\", exp \"%s\"", err.Error(), exp) - } -} - -func TestV3AttackComplexityUnmarshalValid(t *testing.T) { - tests := []struct { - val string - exp V3AttackComplexity - } { - { "\"LOW\"", V3ACLow }, - { "\"MEDIUM\"", V3ACMedium }, - { "\"HIGH\"", V3ACHigh }, - } - - for _, test := range(tests) { - t.Run(test.val, func(t *testing.T) { - var got V3AttackComplexity - if err := json.Unmarshal([]byte(test.val), &got); err != nil { - t.Error(err) - return - } - - if got != test.exp { - t.Errorf("got \"%s\", exp \"%s\"", got, test.exp) - } - }) - } -} - -func TestV3AttackComplexityString(t *testing.T) { - tests := []struct { - val V3AttackComplexity - exp string - } { - { V3ACLow, "LOW" }, - { V3ACMedium, "MEDIUM" }, - { V3ACHigh, "HIGH" }, - - { V3AttackComplexity(255), "V3AttackComplexity(255)" }, - } - - for _, test := range(tests) { - t.Run(test.exp, func(t *testing.T) { - got := test.val.String() - - if got != test.exp { - t.Errorf("got \"%s\", exp \"%s\"", got, test.exp) - } - }) - } -} diff --git a/internal/feed/v3attackvector.go b/internal/feed/v3attackvector.go deleted file mode 100644 index ecc309a..0000000 --- a/internal/feed/v3attackvector.go +++ /dev/null @@ -1,46 +0,0 @@ -package feed - -//go:generate stringer -linecomment -type=V3AttackVector - -import ( - "encoding/json" - "fmt" -) - -// CVSS v3 attack vector. -type V3AttackVector byte - -const ( - V3AVAdjacentNetwork V3AttackVector = iota // ADJACENT_NETWORK - V3AVNetwork // NETWORK - V3AVLocal // LOCAL - V3AVPhysical // PHYSICAL -) - -// Unmarshal CVSS v3 attack vector from JSON. -func (me *V3AttackVector) UnmarshalJSON(b []byte) error { - // decode string, check for error - var s string - if err := json.Unmarshal(b, &s); err != nil { - return err - } - - // check value - switch s { - case "ADJACENT_NETWORK": - *me = V3AVAdjacentNetwork - case "LOCAL": - *me = V3AVLocal - case "NETWORK": - *me = V3AVNetwork - case "PHYSICAL": - *me = V3AVPhysical - default: - // return error - return fmt.Errorf("unknown CVSS v3 attack vector: %s", s) - } - - // return success - return nil -} - diff --git a/internal/feed/v3attackvector_string.go b/internal/feed/v3attackvector_string.go deleted file mode 100644 index 277520f..0000000 --- a/internal/feed/v3attackvector_string.go +++ /dev/null @@ -1,26 +0,0 @@ -// Code generated by "stringer -linecomment -type=V3AttackVector"; DO NOT EDIT. - -package feed - -import "strconv" - -func _() { - // An "invalid array index" compiler error signifies that the constant values have changed. - // Re-run the stringer command to generate them again. - var x [1]struct{} - _ = x[V3AVAdjacentNetwork-0] - _ = x[V3AVNetwork-1] - _ = x[V3AVLocal-2] - _ = x[V3AVPhysical-3] -} - -const _V3AttackVector_name = "ADJACENT_NETWORKNETWORKLOCALPHYSICAL" - -var _V3AttackVector_index = [...]uint8{0, 16, 23, 28, 36} - -func (i V3AttackVector) String() string { - if i >= V3AttackVector(len(_V3AttackVector_index)-1) { - return "V3AttackVector(" + strconv.FormatInt(int64(i), 10) + ")" - } - return _V3AttackVector_name[_V3AttackVector_index[i]:_V3AttackVector_index[i+1]] -} diff --git a/internal/feed/v3attackvector_test.go b/internal/feed/v3attackvector_test.go deleted file mode 100644 index 251cfd4..0000000 --- a/internal/feed/v3attackvector_test.go +++ /dev/null @@ -1,81 +0,0 @@ -package feed - -import ( - "encoding/json" - "testing" -) - -func TestV3AttackVectorUnmarshalInvalidData(t *testing.T) { - test := []byte(`{}`) - var val V3AttackVector - - if err := json.Unmarshal(test, &val); err == nil { - t.Errorf("got \"%s\", exp error", val) - } -} - -func TestV3AttackVectorUnmarshalUnknown(t *testing.T) { - test := []byte(`"foo"`) - exp := "unknown CVSS v3 attack vector: foo" - var val V3AttackVector - - err := json.Unmarshal(test, &val) - if err == nil { - t.Errorf("got \"%s\", exp error", val) - return - } - - if err.Error() != exp { - t.Errorf("got \"%s\", exp \"%s\"", err.Error(), exp) - } -} - -func TestV3AttackVectorUnmarshalValid(t *testing.T) { - tests := []struct { - val string - exp V3AttackVector - } { - { "\"ADJACENT_NETWORK\"", V3AVAdjacentNetwork }, - { "\"LOCAL\"", V3AVLocal }, - { "\"NETWORK\"", V3AVNetwork }, - { "\"PHYSICAL\"", V3AVPhysical }, - } - - for _, test := range(tests) { - t.Run(test.val, func(t *testing.T) { - var got V3AttackVector - if err := json.Unmarshal([]byte(test.val), &got); err != nil { - t.Error(err) - return - } - - if got != test.exp { - t.Errorf("got \"%s\", exp \"%s\"", got, test.exp) - } - }) - } -} - -func TestV3AttackVectorString(t *testing.T) { - tests := []struct { - val V3AttackVector - exp string - } { - { V3AVAdjacentNetwork, "ADJACENT_NETWORK" }, - { V3AVLocal, "LOCAL" }, - { V3AVNetwork, "NETWORK" }, - { V3AVPhysical, "PHYSICAL" }, - - { V3AttackVector(255), "V3AttackVector(255)" }, - } - - for _, test := range(tests) { - t.Run(test.exp, func(t *testing.T) { - got := test.val.String() - - if got != test.exp { - t.Errorf("got \"%s\", exp \"%s\"", got, test.exp) - } - }) - } -} diff --git a/internal/feed/v3impact.go b/internal/feed/v3impact.go deleted file mode 100644 index d6c450e..0000000 --- a/internal/feed/v3impact.go +++ /dev/null @@ -1,42 +0,0 @@ -package feed - -//go:generate stringer -linecomment -type=V3Impact - -import ( - "encoding/json" - "fmt" -) - -// CVSS v3 impact level. -type V3Impact byte - -const ( - V3ImpactNone V3Impact = iota // NONE - V3ImpactLow // LOW - V3ImpactHigh // HIGH -) - -// Unmarshal CVSS v3 impact level from JSON. -func (me *V3Impact) UnmarshalJSON(b []byte) error { - // decode string, check for error - var s string - if err := json.Unmarshal(b, &s); err != nil { - return err - } - - // check value - switch s { - case "NONE": - *me = V3ImpactNone - case "LOW": - *me = V3ImpactLow - case "HIGH": - *me = V3ImpactHigh - default: - // return error - return fmt.Errorf("unknown CVSS v3 impact: %s", s) - } - - // return success - return nil -} diff --git a/internal/feed/v3impact_string.go b/internal/feed/v3impact_string.go deleted file mode 100644 index 13c7ee3..0000000 --- a/internal/feed/v3impact_string.go +++ /dev/null @@ -1,25 +0,0 @@ -// Code generated by "stringer -linecomment -type=V3Impact"; DO NOT EDIT. - -package feed - -import "strconv" - -func _() { - // An "invalid array index" compiler error signifies that the constant values have changed. - // Re-run the stringer command to generate them again. - var x [1]struct{} - _ = x[V3ImpactNone-0] - _ = x[V3ImpactLow-1] - _ = x[V3ImpactHigh-2] -} - -const _V3Impact_name = "NONELOWHIGH" - -var _V3Impact_index = [...]uint8{0, 4, 7, 11} - -func (i V3Impact) String() string { - if i >= V3Impact(len(_V3Impact_index)-1) { - return "V3Impact(" + strconv.FormatInt(int64(i), 10) + ")" - } - return _V3Impact_name[_V3Impact_index[i]:_V3Impact_index[i+1]] -} diff --git a/internal/feed/v3impact_test.go b/internal/feed/v3impact_test.go deleted file mode 100644 index a369f44..0000000 --- a/internal/feed/v3impact_test.go +++ /dev/null @@ -1,79 +0,0 @@ -package feed - -import ( - "encoding/json" - "testing" -) - -func TestV3ImpactUnmarshalInvalidData(t *testing.T) { - test := []byte(`{}`) - var val V3Impact - - if err := json.Unmarshal(test, &val); err == nil { - t.Errorf("got \"%s\", exp error", val) - } -} - -func TestV3ImpactUnmarshalUnknown(t *testing.T) { - test := []byte(`"foo"`) - exp := "unknown CVSS v3 impact: foo" - var val V3Impact - - err := json.Unmarshal(test, &val) - if err == nil { - t.Errorf("got \"%s\", exp error", val) - return - } - - if err.Error() != exp { - t.Errorf("got \"%s\", exp \"%s\"", err.Error(), exp) - } -} - -func TestV3ImpactUnmarshalValid(t *testing.T) { - tests := []struct { - val string - exp V3Impact - } { - { "\"NONE\"", V3ImpactNone }, - { "\"LOW\"", V3ImpactLow }, - { "\"HIGH\"", V3ImpactHigh }, - } - - for _, test := range(tests) { - t.Run(test.val, func(t *testing.T) { - var got V3Impact - if err := json.Unmarshal([]byte(test.val), &got); err != nil { - t.Error(err) - return - } - - if got != test.exp { - t.Errorf("got \"%s\", exp \"%s\"", got, test.exp) - } - }) - } -} - -func TestV3ImpactString(t *testing.T) { - tests := []struct { - val V3Impact - exp string - } { - { V3ImpactNone, "NONE" }, - { V3ImpactLow, "LOW" }, - { V3ImpactHigh, "HIGH" }, - - { V3Impact(255), "V3Impact(255)" }, - } - - for _, test := range(tests) { - t.Run(test.exp, func(t *testing.T) { - got := test.val.String() - - if got != test.exp { - t.Errorf("got \"%s\", exp \"%s\"", got, test.exp) - } - }) - } -} diff --git a/internal/feed/v3privilegesrequired.go b/internal/feed/v3privilegesrequired.go deleted file mode 100644 index 3e69334..0000000 --- a/internal/feed/v3privilegesrequired.go +++ /dev/null @@ -1,45 +0,0 @@ -package feed - -//go:generate stringer -linecomment -type=V3PrivilegesRequired - -import ( - "encoding/json" - "fmt" -) - -// CVSS v3 privileges required. -type V3PrivilegesRequired byte - -const ( - V3PRNone V3PrivilegesRequired = iota // NONE - V3PRLow // LOW - V3PRMedium // MEDIUM - V3PRHigh // HIGH -) - -// Unmarshal CVSS privileges required from JSON. -func (me *V3PrivilegesRequired) UnmarshalJSON(b []byte) error { - // decode string, check for error - var s string - if err := json.Unmarshal(b, &s); err != nil { - return err - } - - // check value - switch s { - case "NONE": - *me = V3PRNone - case "LOW": - *me = V3PRLow - case "MEDIUM": - *me = V3PRMedium - case "HIGH": - *me = V3PRHigh - default: - // return error - return fmt.Errorf("unknown CVSS v3 privileges required: %s", s) - } - - // return success - return nil -} diff --git a/internal/feed/v3privilegesrequired_string.go b/internal/feed/v3privilegesrequired_string.go deleted file mode 100644 index 2951a64..0000000 --- a/internal/feed/v3privilegesrequired_string.go +++ /dev/null @@ -1,26 +0,0 @@ -// Code generated by "stringer -linecomment -type=V3PrivilegesRequired"; DO NOT EDIT. - -package feed - -import "strconv" - -func _() { - // An "invalid array index" compiler error signifies that the constant values have changed. - // Re-run the stringer command to generate them again. - var x [1]struct{} - _ = x[V3PRNone-0] - _ = x[V3PRLow-1] - _ = x[V3PRMedium-2] - _ = x[V3PRHigh-3] -} - -const _V3PrivilegesRequired_name = "NONELOWMEDIUMHIGH" - -var _V3PrivilegesRequired_index = [...]uint8{0, 4, 7, 13, 17} - -func (i V3PrivilegesRequired) String() string { - if i >= V3PrivilegesRequired(len(_V3PrivilegesRequired_index)-1) { - return "V3PrivilegesRequired(" + strconv.FormatInt(int64(i), 10) + ")" - } - return _V3PrivilegesRequired_name[_V3PrivilegesRequired_index[i]:_V3PrivilegesRequired_index[i+1]] -} diff --git a/internal/feed/v3privilegesrequired_test.go b/internal/feed/v3privilegesrequired_test.go deleted file mode 100644 index f200ed1..0000000 --- a/internal/feed/v3privilegesrequired_test.go +++ /dev/null @@ -1,81 +0,0 @@ -package feed - -import ( - "encoding/json" - "testing" -) - -func TestV3PrivilegesRequiredUnmarshalInvalidData(t *testing.T) { - test := []byte(`{}`) - var val V3PrivilegesRequired - - if err := json.Unmarshal(test, &val); err == nil { - t.Errorf("got \"%s\", exp error", val) - } -} - -func TestV3PrivilegesRequiredUnmarshalUnknown(t *testing.T) { - test := []byte(`"foo"`) - exp := "unknown CVSS v3 privileges required: foo" - var val V3PrivilegesRequired - - err := json.Unmarshal(test, &val) - if err == nil { - t.Errorf("got \"%s\", exp error", val) - return - } - - if err.Error() != exp { - t.Errorf("got \"%s\", exp \"%s\"", err.Error(), exp) - } -} - -func TestV3PrivilegesRequiredUnmarshalValid(t *testing.T) { - tests := []struct { - val string - exp V3PrivilegesRequired - } { - { "\"NONE\"", V3PRNone }, - { "\"LOW\"", V3PRLow }, - { "\"MEDIUM\"", V3PRMedium }, - { "\"HIGH\"", V3PRHigh }, - } - - for _, test := range(tests) { - t.Run(test.val, func(t *testing.T) { - var got V3PrivilegesRequired - if err := json.Unmarshal([]byte(test.val), &got); err != nil { - t.Error(err) - return - } - - if got != test.exp { - t.Errorf("got \"%s\", exp \"%s\"", got, test.exp) - } - }) - } -} - -func TestV3PrivilegesRequiredString(t *testing.T) { - tests := []struct { - val V3PrivilegesRequired - exp string - } { - { V3PRNone, "NONE" }, - { V3PRLow, "LOW" }, - { V3PRMedium, "MEDIUM" }, - { V3PRHigh, "HIGH" }, - - { V3PrivilegesRequired(255), "V3PrivilegesRequired(255)" }, - } - - for _, test := range(tests) { - t.Run(test.exp, func(t *testing.T) { - got := test.val.String() - - if got != test.exp { - t.Errorf("got \"%s\", exp \"%s\"", got, test.exp) - } - }) - } -} diff --git a/internal/feed/v3scope.go b/internal/feed/v3scope.go deleted file mode 100644 index 20fe0a5..0000000 --- a/internal/feed/v3scope.go +++ /dev/null @@ -1,39 +0,0 @@ -package feed - -//go:generate stringer -linecomment -type=V3Scope - -import ( - "encoding/json" - "fmt" -) - -// CVSS v3 scope. -type V3Scope byte - -const ( - V3ScopeChanged V3Scope = iota // CHANGED - V3ScopeUnchanged // UNCHANGED -) - -// Unmarshal CVSS scope from JSON. -func (me *V3Scope) UnmarshalJSON(b []byte) error { - // decode string, check for error - var s string - if err := json.Unmarshal(b, &s); err != nil { - return err - } - - // check value - switch s { - case "CHANGED": - *me = V3ScopeChanged - case "UNCHANGED": - *me = V3ScopeUnchanged - default: - // return error - return fmt.Errorf("unknown CVSS v3 scope: %s", s) - } - - // return success - return nil -} diff --git a/internal/feed/v3scope_string.go b/internal/feed/v3scope_string.go deleted file mode 100644 index 982cead..0000000 --- a/internal/feed/v3scope_string.go +++ /dev/null @@ -1,24 +0,0 @@ -// Code generated by "stringer -linecomment -type=V3Scope"; DO NOT EDIT. - -package feed - -import "strconv" - -func _() { - // An "invalid array index" compiler error signifies that the constant values have changed. - // Re-run the stringer command to generate them again. - var x [1]struct{} - _ = x[V3ScopeChanged-0] - _ = x[V3ScopeUnchanged-1] -} - -const _V3Scope_name = "CHANGEDUNCHANGED" - -var _V3Scope_index = [...]uint8{0, 7, 16} - -func (i V3Scope) String() string { - if i >= V3Scope(len(_V3Scope_index)-1) { - return "V3Scope(" + strconv.FormatInt(int64(i), 10) + ")" - } - return _V3Scope_name[_V3Scope_index[i]:_V3Scope_index[i+1]] -} diff --git a/internal/feed/v3scope_test.go b/internal/feed/v3scope_test.go deleted file mode 100644 index 54170b0..0000000 --- a/internal/feed/v3scope_test.go +++ /dev/null @@ -1,77 +0,0 @@ -package feed - -import ( - "encoding/json" - "testing" -) - -func TestV3ScopeUnmarshalInvalidData(t *testing.T) { - test := []byte(`{}`) - var val V3Scope - - if err := json.Unmarshal(test, &val); err == nil { - t.Errorf("got \"%s\", exp error", val) - } -} - -func TestV3ScopeUnmarshalUnknown(t *testing.T) { - test := []byte(`"foo"`) - exp := "unknown CVSS v3 scope: foo" - var val V3Scope - - err := json.Unmarshal(test, &val) - if err == nil { - t.Errorf("got \"%s\", exp error", val) - return - } - - if err.Error() != exp { - t.Errorf("got \"%s\", exp \"%s\"", err.Error(), exp) - } -} - -func TestV3ScopeUnmarshalValid(t *testing.T) { - tests := []struct { - val string - exp V3Scope - } { - { "\"CHANGED\"", V3ScopeChanged }, - { "\"UNCHANGED\"", V3ScopeUnchanged }, - } - - for _, test := range(tests) { - t.Run(test.val, func(t *testing.T) { - var got V3Scope - if err := json.Unmarshal([]byte(test.val), &got); err != nil { - t.Error(err) - return - } - - if got != test.exp { - t.Errorf("got \"%s\", exp \"%s\"", got, test.exp) - } - }) - } -} - -func TestV3ScopeString(t *testing.T) { - tests := []struct { - val V3Scope - exp string - } { - { V3ScopeChanged, "CHANGED" }, - { V3ScopeUnchanged, "UNCHANGED" }, - - { V3Scope(255), "V3Scope(255)" }, - } - - for _, test := range(tests) { - t.Run(test.exp, func(t *testing.T) { - got := test.val.String() - - if got != test.exp { - t.Errorf("got \"%s\", exp \"%s\"", got, test.exp) - } - }) - } -} diff --git a/internal/feed/v3userinteraction.go b/internal/feed/v3userinteraction.go deleted file mode 100644 index a6a53ca..0000000 --- a/internal/feed/v3userinteraction.go +++ /dev/null @@ -1,40 +0,0 @@ -package feed - -//go:generate stringer -linecomment -type=V3UserInteraction - -import ( - "encoding/json" - "fmt" -) - -// CVSS v3 user interaction -type V3UserInteraction byte - -const ( - V3UINone V3UserInteraction = iota // NONE - V3UIRequired // REQUIRED -) - -// Unmarshal CVSS user interaction from JSON. -func (me *V3UserInteraction) UnmarshalJSON(b []byte) error { - // decode string, check for error - var s string - if err := json.Unmarshal(b, &s); err != nil { - return err - } - - // check value - switch s { - case "NONE": - *me = V3UINone - case "REQUIRED": - *me = V3UIRequired - default: - // return error - return fmt.Errorf("unknown CVSS v3 user interaction: %s", s) - } - - // return success - return nil -} - diff --git a/internal/feed/v3userinteraction_string.go b/internal/feed/v3userinteraction_string.go deleted file mode 100644 index be78920..0000000 --- a/internal/feed/v3userinteraction_string.go +++ /dev/null @@ -1,24 +0,0 @@ -// Code generated by "stringer -linecomment -type=V3UserInteraction"; DO NOT EDIT. - -package feed - -import "strconv" - -func _() { - // An "invalid array index" compiler error signifies that the constant values have changed. - // Re-run the stringer command to generate them again. - var x [1]struct{} - _ = x[V3UINone-0] - _ = x[V3UIRequired-1] -} - -const _V3UserInteraction_name = "NONEREQUIRED" - -var _V3UserInteraction_index = [...]uint8{0, 4, 12} - -func (i V3UserInteraction) String() string { - if i >= V3UserInteraction(len(_V3UserInteraction_index)-1) { - return "V3UserInteraction(" + strconv.FormatInt(int64(i), 10) + ")" - } - return _V3UserInteraction_name[_V3UserInteraction_index[i]:_V3UserInteraction_index[i+1]] -} diff --git a/internal/feed/v3userinteraction_test.go b/internal/feed/v3userinteraction_test.go deleted file mode 100644 index c5949c2..0000000 --- a/internal/feed/v3userinteraction_test.go +++ /dev/null @@ -1,77 +0,0 @@ -package feed - -import ( - "encoding/json" - "testing" -) - -func TestV3UserInteractionUnmarshalInvalidData(t *testing.T) { - test := []byte(`{}`) - var val V3UserInteraction - - if err := json.Unmarshal(test, &val); err == nil { - t.Errorf("got \"%s\", exp error", val) - } -} - -func TestV3UserInteractionUnmarshalUnknown(t *testing.T) { - test := []byte(`"foo"`) - exp := "unknown CVSS v3 user interaction: foo" - var val V3UserInteraction - - err := json.Unmarshal(test, &val) - if err == nil { - t.Errorf("got \"%s\", exp error", val) - return - } - - if err.Error() != exp { - t.Errorf("got \"%s\", exp \"%s\"", err.Error(), exp) - } -} - -func TestV3UserInteractionUnmarshalValid(t *testing.T) { - tests := []struct { - val string - exp V3UserInteraction - } { - { "\"NONE\"", V3UINone }, - { "\"REQUIRED\"", V3UIRequired }, - } - - for _, test := range(tests) { - t.Run(test.val, func(t *testing.T) { - var got V3UserInteraction - if err := json.Unmarshal([]byte(test.val), &got); err != nil { - t.Error(err) - return - } - - if got != test.exp { - t.Errorf("got \"%s\", exp \"%s\"", got, test.exp) - } - }) - } -} - -func TestV3UserInteractionString(t *testing.T) { - tests := []struct { - val V3UserInteraction - exp string - } { - { V3UINone, "NONE" }, - { V3UIRequired, "REQUIRED" }, - - { V3UserInteraction(255), "V3UserInteraction(255)" }, - } - - for _, test := range(tests) { - t.Run(test.exp, func(t *testing.T) { - got := test.val.String() - - if got != test.exp { - t.Errorf("got \"%s\", exp \"%s\"", got, test.exp) - } - }) - } -} diff --git a/internal/feed/v3version.go b/internal/feed/v3version.go deleted file mode 100644 index 537fecc..0000000 --- a/internal/feed/v3version.go +++ /dev/null @@ -1,36 +0,0 @@ -package feed - -//go:generate stringer -linecomment -type=V3Version - -import ( - "encoding/json" - "fmt" -) - -// CVSS v3 version -type V3Version byte - -const ( - V31 V3Version = iota // 3.1 -) - -// Unmarshal CVSS V3 version from JSON. -func (me *V3Version) UnmarshalJSON(b []byte) error { - // decode string, check for error - var s string - if err := json.Unmarshal(b, &s); err != nil { - return err - } - - // check value - switch s { - case "3.1": - *me = V31 - default: - // return error - return fmt.Errorf("unknown CVSS version: %s", s) - } - - // return success - return nil -} diff --git a/internal/feed/v3version_string.go b/internal/feed/v3version_string.go deleted file mode 100644 index 9de58a7..0000000 --- a/internal/feed/v3version_string.go +++ /dev/null @@ -1,23 +0,0 @@ -// Code generated by "stringer -linecomment -type=V3Version"; DO NOT EDIT. - -package feed - -import "strconv" - -func _() { - // An "invalid array index" compiler error signifies that the constant values have changed. - // Re-run the stringer command to generate them again. - var x [1]struct{} - _ = x[V31-0] -} - -const _V3Version_name = "3.1" - -var _V3Version_index = [...]uint8{0, 3} - -func (i V3Version) String() string { - if i >= V3Version(len(_V3Version_index)-1) { - return "V3Version(" + strconv.FormatInt(int64(i), 10) + ")" - } - return _V3Version_name[_V3Version_index[i]:_V3Version_index[i+1]] -} diff --git a/internal/feed/v3version_test.go b/internal/feed/v3version_test.go deleted file mode 100644 index 89cc6ed..0000000 --- a/internal/feed/v3version_test.go +++ /dev/null @@ -1,75 +0,0 @@ -package feed - -import ( - "encoding/json" - "testing" -) - -func TestV3VersionUnmarshalInvalidData(t *testing.T) { - test := []byte(`{}`) - var val V3Version - - if err := json.Unmarshal(test, &val); err == nil { - t.Errorf("got \"%s\", exp error", val) - } -} - -func TestV3VersionUnmarshalUnknown(t *testing.T) { - test := []byte(`"foo"`) - exp := "unknown CVSS version: foo" - var val V3Version - - err := json.Unmarshal(test, &val) - if err == nil { - t.Errorf("got \"%s\", exp error", val) - return - } - - if err.Error() != exp { - t.Errorf("got \"%s\", exp \"%s\"", err.Error(), exp) - } -} - -func TestV3VersionUnmarshalValid(t *testing.T) { - tests := []struct { - val string - exp V3Version - } { - { "\"3.1\"", V31 }, - } - - for _, test := range(tests) { - t.Run(test.val, func(t *testing.T) { - var got V3Version - if err := json.Unmarshal([]byte(test.val), &got); err != nil { - t.Error(err) - return - } - - if got != test.exp { - t.Errorf("got \"%s\", exp \"%s\"", got, test.exp) - } - }) - } -} - -func TestV3VersionString(t *testing.T) { - tests := []struct { - val V3Version - exp string - } { - { V31, "3.1" }, - - { V3Version(255), "V3Version(255)" }, - } - - for _, test := range(tests) { - t.Run(test.exp, func(t *testing.T) { - got := test.val.String() - - if got != test.exp { - t.Errorf("got \"%s\", exp \"%s\"", got, test.exp) - } - }) - } -} diff --git a/internal/feed/vector.go b/internal/feed/vector.go deleted file mode 100644 index 9e75de7..0000000 --- a/internal/feed/vector.go +++ /dev/null @@ -1,39 +0,0 @@ -// NVD JSON feed parser. -package feed - -import ( - "encoding/json" - "nvd/internal/cvss" -) - -// CVSS vector -type Vector struct { - // CVSS vector - Vector cvss.Vector -} - -// Unmarshal CVSS vector from JSON. -func (me *Vector) UnmarshalJSON(b []byte) error { - // decode string, check for error - var s string - if err := json.Unmarshal(b, &s); err != nil { - return err - } - - // parse vector - vec, err := cvss.NewVector(s) - if err != nil { - return err - } - - // save result - me.Vector = vec - - // return success - return nil -} - -// Marshal CVSS vector to JSON. -func (me Vector) MarshalJSON() ([]byte, error) { - return json.Marshal(me.Vector.String()) -} diff --git a/internal/feed/vector_test.go b/internal/feed/vector_test.go deleted file mode 100644 index 5dee8ba..0000000 --- a/internal/feed/vector_test.go +++ /dev/null @@ -1,99 +0,0 @@ -package feed - -import ( - "encoding/json" - "nvd/internal/cvss" - "testing" -) - -func TestVectorUnmarshalInvalidData(t *testing.T) { - test := []byte(`{}`) - var val Vector - - if err := json.Unmarshal(test, &val); err == nil { - t.Errorf("got \"%s\", exp error", val) - } -} - -func TestVectorUnmarshalJSON(t *testing.T) { - failTests := []struct { - val string - exp string - } { - { - val: "\"AV:N/junk/Au:S/C:P/I:P/A:P\"", - exp: "invalid CVSS vector: AV:N/junk/Au:S/C:P/I:P/A:P", - }, { - val: "\"CVSS:3.0/junk/AC:H/PR:H/UI:R/S:U/C:H/I:H/A:H\"", - exp: "invalid CVSS vector: CVSS:3.0/junk/AC:H/PR:H/UI:R/S:U/C:H/I:H/A:H", - }, { - val: "\"CVSS:3.1/AV:A/junk/PR:N/UI:N/S:U/C:H/I:H/A:H\"", - exp: "invalid CVSS vector: CVSS:3.1/AV:A/junk/PR:N/UI:N/S:U/C:H/I:H/A:H", - }, - } - - for _, test := range(failTests) { - t.Run(test.val, func(t *testing.T) { - var got Vector - - if err := json.Unmarshal([]byte(test.val), &got); err == nil { - t.Errorf("got \"%v\", exp error", got) - } else if err.Error() != test.exp { - t.Errorf("got \"%s\", exp \"%s\"", err.Error(), test.exp) - } - }) - } - - passTests := []string { - "AV:N/AC:M/Au:S/C:P/I:P/A:P", - "CVSS:3.0/AV:A/AC:H/PR:H/UI:R/S:U/C:H/I:H/A:H", - "CVSS:3.1/AV:A/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H", - } - - for _, val := range(passTests) { - t.Run(val, func(t *testing.T) { - var got Vector - - if err := json.Unmarshal([]byte("\"" + val + "\""), &got); err != nil { - t.Error(err) - } else if got.Vector.String() != val { - t.Errorf("got \"%s\", exp \"%s\"", got.Vector.String(), val) - } - }) - } -} - -func TestVectorMarshalJSON(t *testing.T) { - tests := []string { - "AV:N/AC:M/Au:S/C:P/I:P/A:P", - "CVSS:3.0/AV:A/AC:H/PR:H/UI:R/S:U/C:H/I:H/A:H", - "CVSS:3.1/AV:A/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H", - } - - for _, val := range(tests) { - t.Run(val, func(t *testing.T) { - // get expected string - exp := "\"" + val + "\"" - - // create inner vector - vec, err := cvss.NewVector(val) - if err != nil { - t.Error(err) - return - } - - // serialize as json - buf, err := json.Marshal(Vector { vec }) - if err != nil { - t.Error(err) - return - } - - // check result - got := string(buf) - if got != exp { - t.Errorf("got \"%s\", exp \"%s\"", got, exp) - } - }) - } -} |