aboutsummaryrefslogtreecommitdiff
path: root/internal
diff options
context:
space:
mode:
Diffstat (limited to 'internal')
-rw-r--r--internal/feed/feed.go39
-rw-r--r--internal/feed/time.go44
-rw-r--r--internal/feed/time_test.go66
3 files changed, 113 insertions, 36 deletions
diff --git a/internal/feed/feed.go b/internal/feed/feed.go
index c013877..cf0fd2d 100644
--- a/internal/feed/feed.go
+++ b/internal/feed/feed.go
@@ -4,8 +4,6 @@ import (
"encoding/json"
"fmt"
// "strconv"
- "regexp"
- "time"
)
const (
@@ -40,37 +38,6 @@ const (
// TODO: parse cpe
-// partial timestamp
-type PartialTime time.Time
-
-var partialTimeRe = regexp.MustCompile("\\A\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}Z\\z")
-
-// Unmarshal partial timestamp from JSON.
-func (me *PartialTime) 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 !partialTimeRe.MatchString(s) {
- return fmt.Errorf("invalid partial time string: %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
- }
-
- // return success
- return nil
-}
-
// Configuration node boolean operator.
type NodeOp int
@@ -666,10 +633,10 @@ type Item struct {
Impact Impact `json:"impact"`
// item published date
- PublishedDate PartialTime `json:"publishedDate"`
+ PublishedDate Time `json:"publishedDate"`
// last modification date
- LastModifiedDate PartialTime `json:"lastModifiedDate"`
+ LastModifiedDate Time `json:"lastModifiedDate"`
}
// NVD feed
@@ -687,7 +654,7 @@ type Feed struct {
NumCVEs uint64 `json:"CVE_data_numberOfCVEs,string"`
// data timestamp
- Timestamp PartialTime `json:"CVE_data_timestamp"`
+ Timestamp Time `json:"CVE_data_timestamp"`
// CVE items
Items []Item `json:"CVE_Items"`
diff --git a/internal/feed/time.go b/internal/feed/time.go
new file mode 100644
index 0000000..6eb5d37
--- /dev/null
+++ b/internal/feed/time.go
@@ -0,0 +1,44 @@
+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
new file mode 100644
index 0000000..cc490c5
--- /dev/null
+++ b/internal/feed/time_test.go
@@ -0,0 +1,66 @@
+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)
+ }
+ })
+ }
+}