From 509fb045b6e3f3fba5302e178f53226edb20703a Mon Sep 17 00:00:00 2001 From: Kota Kanbe Date: Fri, 5 May 2017 12:12:05 +0900 Subject: [PATCH] Refactoring diff logic --- commands/util.go | 48 ++++++------- commands/util_test.go | 156 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 180 insertions(+), 24 deletions(-) diff --git a/commands/util.go b/commands/util.go index feecb61d..c0eaa04e 100644 --- a/commands/util.go +++ b/commands/util.go @@ -219,7 +219,7 @@ func getDiffCves(previous, current models.ScanResult) (new, updated []models.Vul for _, v := range current.ScannedCves { if previousCveIDsSet[v.CveID] { - if isCveInfoUpdated(current, previous, v.CveID) { + if isCveInfoUpdated(v.CveID, previous, current) { updated = append(updated, v) } } else { @@ -229,40 +229,40 @@ func getDiffCves(previous, current models.ScanResult) (new, updated []models.Vul return } -func isCveInfoUpdated(current, previous models.ScanResult, CveID string) bool { - type lastModified struct { - Nvd time.Time - Jvn time.Time +func isCveInfoUpdated(cveID string, previous, current models.ScanResult) bool { + cTypes := []models.CveContentType{ + models.NVD, + models.JVN, + models.NewCveContentType(current.Family), } - //TODO - previousModifies := lastModified{} + prevLastModified := map[models.CveContentType]time.Time{} for _, c := range previous.ScannedCves { - if CveID == c.CveID { - //TODO - if nvd, found := c.CveContents.Get(models.NVD); found { - previousModifies.Nvd = nvd.LastModified - } - if jvn, found := c.CveContents.Get(models.JVN); found { - previousModifies.Jvn = jvn.LastModified + if cveID == c.CveID { + for _, cType := range cTypes { + content, _ := c.CveContents.Get(cType) + prevLastModified[cType] = content.LastModified } + break } } - currentModifies := lastModified{} + curLastModified := map[models.CveContentType]time.Time{} for _, c := range current.ScannedCves { - if CveID == c.CveID { - //TODO - if nvd, found := c.CveContents.Get(models.NVD); found { - previousModifies.Nvd = nvd.LastModified - } - if jvn, found := c.CveContents.Get(models.JVN); found { - previousModifies.Jvn = jvn.LastModified + if cveID == c.CveID { + for _, cType := range cTypes { + content, _ := c.CveContents.Get(cType) + curLastModified[cType] = content.LastModified } + break } } - return !currentModifies.Nvd.Equal(previousModifies.Nvd) || - !currentModifies.Jvn.Equal(previousModifies.Jvn) + for _, cType := range cTypes { + if equal := prevLastModified[cType].Equal(curLastModified[cType]); !equal { + return true + } + } + return false } func overwriteJSONFile(dir string, r models.ScanResult) error { diff --git a/commands/util_test.go b/commands/util_test.go index e32db3e0..0c598a01 100644 --- a/commands/util_test.go +++ b/commands/util_test.go @@ -26,6 +26,162 @@ import ( "github.com/k0kubun/pp" ) +func TestIsCveInfoUpdated(t *testing.T) { + f := "2006-01-02" + old, _ := time.Parse(f, "2015-12-15") + new, _ := time.Parse(f, "2015-12-16") + + type In struct { + cveID string + cur models.ScanResult + prev models.ScanResult + } + var tests = []struct { + in In + expected bool + }{ + // NVD compare non-initialized times + { + in: In{ + cveID: "CVE-2017-0001", + cur: models.ScanResult{ + ScannedCves: []models.VulnInfo{ + { + CveID: "CVE-2017-0001", + CveContents: []models.CveContent{ + { + Type: models.NVD, + CveID: "CVE-2017-0001", + LastModified: time.Time{}, + }, + }, + }, + }, + }, + prev: models.ScanResult{ + ScannedCves: []models.VulnInfo{ + { + CveID: "CVE-2017-0001", + CveContents: []models.CveContent{ + { + Type: models.NVD, + CveID: "CVE-2017-0001", + LastModified: time.Time{}, + }, + }, + }, + }, + }, + }, + expected: false, + }, + // JVN not updated + { + in: In{ + cveID: "CVE-2017-0002", + cur: models.ScanResult{ + ScannedCves: []models.VulnInfo{ + { + CveID: "CVE-2017-0002", + CveContents: []models.CveContent{ + { + Type: models.JVN, + CveID: "CVE-2017-0002", + LastModified: old, + }, + }, + }, + }, + }, + prev: models.ScanResult{ + ScannedCves: []models.VulnInfo{ + { + CveID: "CVE-2017-0002", + CveContents: []models.CveContent{ + { + Type: models.JVN, + CveID: "CVE-2017-0002", + LastModified: old, + }, + }, + }, + }, + }, + }, + expected: false, + }, + // OVAL updated + { + in: In{ + cveID: "CVE-2017-0003", + cur: models.ScanResult{ + Family: "ubuntu", + ScannedCves: []models.VulnInfo{ + { + CveID: "CVE-2017-0003", + CveContents: []models.CveContent{ + { + Type: models.Ubuntu, + CveID: "CVE-2017-0003", + LastModified: new, + }, + }, + }, + }, + }, + prev: models.ScanResult{ + Family: "ubuntu", + ScannedCves: []models.VulnInfo{ + { + CveID: "CVE-2017-0003", + CveContents: []models.CveContent{ + { + Type: models.Ubuntu, + CveID: "CVE-2017-0003", + LastModified: old, + }, + }, + }, + }, + }, + }, + expected: true, + }, + // OVAL newly detected + { + in: In{ + cveID: "CVE-2017-0004", + cur: models.ScanResult{ + Family: "redhat", + ScannedCves: []models.VulnInfo{ + { + CveID: "CVE-2017-0004", + CveContents: []models.CveContent{ + { + Type: models.RedHat, + CveID: "CVE-2017-0004", + LastModified: old, + }, + }, + }, + }, + }, + prev: models.ScanResult{ + Family: "redhat", + ScannedCves: []models.VulnInfo{}, + }, + }, + expected: true, + }, + } + for i, tt := range tests { + actual := isCveInfoUpdated(tt.in.cveID, tt.in.prev, tt.in.cur) + if actual != tt.expected { + t.Errorf("[%d] actual: %t, expected: %t", i, actual, tt.expected) + } + } +} + func TestDiff(t *testing.T) { atCurrent, _ := time.Parse("2006-01-02", "2014-12-31") atPrevious, _ := time.Parse("2006-01-02", "2014-11-31")