From d81cadb731298a78442e28e454cf6dfcef2bd3a8 Mon Sep 17 00:00:00 2001 From: Spiegel Date: Tue, 24 Jan 2023 10:08:18 +0900 Subject: [PATCH] Fixed setting error when "name:value" has no value (issue: #10) --- .github/workflows/lint.yml | 4 ++++ .github/workflows/vulns.yml | 4 ++-- Taskfile.yml | 2 +- go.mod | 2 +- go.sum | 4 ++-- v3/metric/base.go | 16 ++++++++-------- v3/metric/base_test.go | 1 + v3/metric/environmental.go | 16 ++++++++-------- v3/metric/environmental_test.go | 20 +++++++++++++------- v3/metric/temporal.go | 18 +++++++++--------- v3/metric/temporal_test.go | 1 + 11 files changed, 50 insertions(+), 38 deletions(-) diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 61e6786..03d8e17 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -44,3 +44,7 @@ jobs: # skip-build-cache: true - name: testing run: go test -shuffle on ./... + - name: install govulncheck + run: go install golang.org/x/vuln/cmd/govulncheck@latest + - name: running govulncheck + run: govulncheck ./... diff --git a/.github/workflows/vulns.yml b/.github/workflows/vulns.yml index 0850078..46327b7 100644 --- a/.github/workflows/vulns.yml +++ b/.github/workflows/vulns.yml @@ -11,8 +11,8 @@ jobs: name: Vulnerability scanner runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 - - uses: actions/setup-go@v2 + - uses: actions/checkout@v3 + - uses: actions/setup-go@v3 with: go-version: ^1.19 - name: WriteGoList diff --git a/Taskfile.yml b/Taskfile.yml index 374971d..d2d4b95 100644 --- a/Taskfile.yml +++ b/Taskfile.yml @@ -12,7 +12,7 @@ tasks: cmds: - go mod verify - go test -shuffle on ./... - - docker run --rm -v $(pwd):/app -w /app golangci/golangci-lint:v1.49.0 golangci-lint run --enable gosec --timeout 3m0s ./... + - docker run --rm -v $(pwd):/app -w /app golangci/golangci-lint:v1.50.1 golangci-lint run --enable gosec --timeout 3m0s ./... sources: - ./go.mod - '**/*.go' diff --git a/go.mod b/go.mod index 93b6f65..2197271 100644 --- a/go.mod +++ b/go.mod @@ -4,5 +4,5 @@ go 1.19 require ( github.com/goark/errs v1.1.0 - golang.org/x/text v0.3.7 + golang.org/x/text v0.6.0 ) diff --git a/go.sum b/go.sum index abfa916..6170d52 100644 --- a/go.sum +++ b/go.sum @@ -1,4 +1,4 @@ github.com/goark/errs v1.1.0 h1:FKnyw4LVyRADIjM8Nj0Up6r0/y5cfADvZAd1E+tthXE= github.com/goark/errs v1.1.0/go.mod h1:TtaPEoadm2mzqzfXdkkfpN2xuniCFm2q4JH+c1qzaqw= -golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= -golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.6.0 h1:3XmdazWV+ubf7QgHSTWeykHOci5oeekaGJBLkrkaw4k= +golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= diff --git a/v3/metric/base.go b/v3/metric/base.go index b8b90b6..466224a 100644 --- a/v3/metric/base.go +++ b/v3/metric/base.go @@ -8,7 +8,7 @@ import ( "github.com/goark/go-cvss/cvsserr" ) -//Base is Base Metrics for CVSSv3 +// Base is Base Metrics for CVSSv3 type Base struct { Ver Version AV AttackVector @@ -21,7 +21,7 @@ type Base struct { A AvailabilityImpact } -//NewBase returns Base Metrics instance +// NewBase returns Base Metrics instance func NewBase() *Base { return &Base{ Ver: VUnknown, @@ -58,7 +58,7 @@ func (bm *Base) Decode(vector string) (*Base, error) { for _, value := range values[1:] { if err := bm.decodeOne(value); err != nil { if !errs.Is(err, cvsserr.ErrNotSupportMetric) { - return bm, errs.Wrap(err, errs.WithContext("vector", vector)) + return nil, errs.Wrap(err, errs.WithContext("vector", vector)) } lastErr = err } @@ -70,7 +70,7 @@ func (bm *Base) Decode(vector string) (*Base, error) { } func (bm *Base) decodeOne(str string) error { m := strings.Split(str, ":") - if len(m) != 2 { + if len(m) != 2 || len(m[1]) == 0 { return errs.Wrap(cvsserr.ErrInvalidVector, errs.WithContext("metric", str)) } switch strings.ToUpper(m[0]) { @@ -96,7 +96,7 @@ func (bm *Base) decodeOne(str string) error { return nil } -//GetError returns error instance if undefined metric +// GetError returns error instance if undefined metric func (bm *Base) GetError() error { if bm == nil { return errs.Wrap(cvsserr.ErrUndefinedMetric) @@ -109,7 +109,7 @@ func (bm *Base) GetError() error { } } -//Encode returns CVSSv3 vector string +// Encode returns CVSSv3 vector string func (bm *Base) Encode() (string, error) { if err := bm.GetError(); err != nil { return "", err @@ -127,7 +127,7 @@ func (bm *Base) Encode() (string, error) { return r.String(), nil } -//Score returns score of Base metrics +// Score returns score of Base metrics func (bm *Base) Score() float64 { if err := bm.GetError(); err != nil { return 0.0 @@ -152,7 +152,7 @@ func (bm *Base) Score() float64 { return score } -//Severity returns severity by score of Base metrics +// Severity returns severity by score of Base metrics func (bm *Base) Severity() Severity { return severity(bm.Score()) } diff --git a/v3/metric/base_test.go b/v3/metric/base_test.go index e51bf9f..c1bf108 100644 --- a/v3/metric/base_test.go +++ b/v3/metric/base_test.go @@ -19,6 +19,7 @@ func TestDecodeError(t *testing.T) { {vector: "CVSS:3.1", err: cvsserr.ErrInvalidVector}, {vector: "CVSS3.1/AV:X/AC:H/PR:H/UI:R/S:U/C:N/I:N/A:N", err: cvsserr.ErrInvalidVector}, {vector: "CVSS:3.1/AV:P/AC:H/PR:H/UI:R/S:U/C:N/I:N/A-N", err: cvsserr.ErrInvalidVector}, + {vector: "CVSS:3.1/AV:P/AC:H/PR:H/UI:R/S:U/C:N/I:N/A:", err: cvsserr.ErrInvalidVector}, {vector: "CVSS:3.1/AV:P/AC:H/PR:H/UI:R/S:U/C:N/I:N/X:N", err: cvsserr.ErrNotSupportMetric}, {vector: "CVSS:3.1/AV:P/AC:H/PR:H/UI:R/S:U/C:N/I:N/A:X", err: cvsserr.ErrUndefinedMetric}, {vector: "CVSS:3.1/AV:P/AC:H/PR:H/UI:R/S:U/C:N/I:X/A:N", err: cvsserr.ErrUndefinedMetric}, diff --git a/v3/metric/environmental.go b/v3/metric/environmental.go index f9bad93..af0e022 100644 --- a/v3/metric/environmental.go +++ b/v3/metric/environmental.go @@ -8,7 +8,7 @@ import ( "github.com/goark/go-cvss/cvsserr" ) -//Base is Environmental Metrics for CVSSv3 +// Base is Environmental Metrics for CVSSv3 type Environmental struct { *Temporal CR ConfidentialityRequirement @@ -24,7 +24,7 @@ type Environmental struct { MA ModifiedAvailabilityImpact } -//NewBase returns Base Metrics instance +// NewBase returns Base Metrics instance func NewEnvironmental() *Environmental { return &Environmental{ Temporal: NewTemporal(), @@ -64,7 +64,7 @@ func (em *Environmental) Decode(vector string) (*Environmental, error) { for _, value := range values[1:] { if err := em.decodeOne(value); err != nil { if !errs.Is(err, cvsserr.ErrNotSupportMetric) { - return em, errs.Wrap(err, errs.WithContext("vector", vector)) + return nil, errs.Wrap(err, errs.WithContext("vector", vector)) } lastErr = err } @@ -83,7 +83,7 @@ func (em *Environmental) decodeOne(str string) error { return nil } m := strings.Split(str, ":") - if len(m) != 2 { + if len(m) != 2 || len(m[1]) == 0 { return errs.Wrap(cvsserr.ErrInvalidVector, errs.WithContext("metric", str)) } switch strings.ToUpper(m[0]) { @@ -115,7 +115,7 @@ func (em *Environmental) decodeOne(str string) error { return nil } -//GetError returns error instance if undefined metric +// GetError returns error instance if undefined metric func (em *Environmental) GetError() error { if em == nil { return errs.Wrap(cvsserr.ErrUndefinedMetric) @@ -132,7 +132,7 @@ func (em *Environmental) GetError() error { } } -//Encode returns CVSSv3 vector string +// Encode returns CVSSv3 vector string func (em *Environmental) Encode() (string, error) { if err := em.GetError(); err != nil { return "", errs.Wrap(err) @@ -196,12 +196,12 @@ func (em *Environmental) Score() float64 { return score } -//Severity returns severity by score of Environmental metrics +// Severity returns severity by score of Environmental metrics func (em *Environmental) Severity() Severity { return severity(em.Score()) } -//BaseMetrics returns Base metrics in Environmental metrics instance +// BaseMetrics returns Base metrics in Environmental metrics instance func (em *Environmental) BaseMetrics() *Base { if em == nil { return nil diff --git a/v3/metric/environmental_test.go b/v3/metric/environmental_test.go index d09ff72..4987c44 100644 --- a/v3/metric/environmental_test.go +++ b/v3/metric/environmental_test.go @@ -18,6 +18,8 @@ func TestEnvironmentalScore(t *testing.T) { {vector: "CVSS:1.0/S:U/AV:N/AC:L/PR:H/UI:N/C:L/I:L/A:N", err: cvsserr.ErrNotSupportVer, score: 0, sav: SeverityNone}, {vector: "CVSS:3.0/AV:N/AC:L/PR:H/UI:N/C:L/I:L/A:N", err: cvsserr.ErrInvalidVector, score: 0, sav: SeverityNone}, {vector: "CVSS:3.0/S:U/AV:N/AC:L/PR:H/UI:N/C:L/I:L/X:N", err: cvsserr.ErrNotSupportMetric, score: 0, sav: SeverityNone}, + {vector: "CVSS:3.1/AV:A/AC:H/PR:L/UI:N/S:C/C:H/I:L/A:L/RC:", err: cvsserr.ErrInvalidVector, score: 0, sav: SeverityNone}, + {vector: "CVSS:3.1/AV:A/AC:H/PR:L/UI:N/S:C/C:H/I:L/A:L/MC:", err: cvsserr.ErrInvalidVector, score: 0, sav: SeverityNone}, {vector: "CVSS:3.0/S:U/AV:N/AC:L/PR:H/UI:N/C:L/I:L/A:N", err: nil, score: 3.8, sav: SeverityLow}, {vector: "CVSS:3.1/AV:A/AC:H/PR:L/UI:N/S:C/C:L/I:H/A:L/E:P/RL:O/RC:U/CR:L/IR:M/AR:L/MAV:P/MAC:L/MPR:L/MUI:R/MS:C/MC:H/MI:H/MA:H", err: nil, score: 5.5, sav: SeverityMedium}, {vector: "CVSS:3.1/S:U/AV:N/AC:L/PR:H/UI:N/C:L/I:L/A:N/E:F", err: nil, score: 3.7, sav: SeverityLow}, @@ -32,15 +34,19 @@ func TestEnvironmentalScore(t *testing.T) { if !errors.Is(err, tc.err) { t.Errorf("Decode(%s) = \"%+v\", want \"%v\".", tc.vector, err, tc.err) } - score := e.Score() - if score != tc.score { - t.Errorf("Score(%s) = %v, want %v.", tc.vector, score, tc.score) - } - sav := e.Severity() - if sav != tc.sav { - t.Errorf("Severity(%s) = %v, want %v.", tc.vector, sav, tc.sav) + if err == nil { + score := e.Score() + if score != tc.score { + t.Errorf("Score(%s) = %v, want %v.", tc.vector, score, tc.score) + } + sav := e.Severity() + if sav != tc.sav { + t.Errorf("Severity(%s) = %v, want %v.", tc.vector, sav, tc.sav) + } + } } } /* Copyright 2022 thejohnbrown */ +/* Copyright 2023 Spiegel */ diff --git a/v3/metric/temporal.go b/v3/metric/temporal.go index c14c3fb..c6bf6e1 100644 --- a/v3/metric/temporal.go +++ b/v3/metric/temporal.go @@ -7,7 +7,7 @@ import ( "github.com/goark/go-cvss/cvsserr" ) -//Base is Temporal Metrics for CVSSv3 +// Base is Temporal Metrics for CVSSv3 type Temporal struct { *Base E Exploitability @@ -15,7 +15,7 @@ type Temporal struct { RC ReportConfidence } -//NewBase returns Base Metrics instance +// NewBase returns Base Metrics instance func NewTemporal() *Temporal { return &Temporal{ Base: NewBase(), @@ -47,7 +47,7 @@ func (tm *Temporal) Decode(vector string) (*Temporal, error) { for _, value := range values[1:] { if err := tm.decodeOne(value); err != nil { if !errs.Is(err, cvsserr.ErrNotSupportMetric) { - return tm, errs.Wrap(err, errs.WithContext("vector", vector)) + return nil, errs.Wrap(err, errs.WithContext("vector", vector)) } lastErr = err } @@ -66,7 +66,7 @@ func (tm *Temporal) decodeOne(str string) error { return nil } m := strings.Split(str, ":") - if len(m) != 2 { + if len(m) != 2 || len(m[1]) == 0 { return errs.Wrap(cvsserr.ErrInvalidVector, errs.WithContext("metric", str)) } switch strings.ToUpper(m[0]) { @@ -82,7 +82,7 @@ func (tm *Temporal) decodeOne(str string) error { return nil } -//GetError returns error instance if undefined metric +// GetError returns error instance if undefined metric func (tm *Temporal) GetError() error { if tm == nil { return errs.Wrap(cvsserr.ErrUndefinedMetric) @@ -98,7 +98,7 @@ func (tm *Temporal) GetError() error { } } -//Encode returns CVSSv3 vector string +// Encode returns CVSSv3 vector string func (tm *Temporal) Encode() (string, error) { if err := tm.GetError(); err != nil { return "", errs.Wrap(err) @@ -115,7 +115,7 @@ func (tm *Temporal) Encode() (string, error) { return r.String(), nil } -//Score returns score of Temporal metrics +// Score returns score of Temporal metrics func (tm *Temporal) Score() float64 { if err := tm.GetError(); err != nil { return 0.0 @@ -123,12 +123,12 @@ func (tm *Temporal) Score() float64 { return roundUp(tm.Base.Score() * tm.E.Value() * tm.RL.Value() * tm.RC.Value()) } -//Severity returns severity by score of Temporal metrics +// Severity returns severity by score of Temporal metrics func (tm *Temporal) Severity() Severity { return severity(tm.Score()) } -//BaseMetrics returns Base metrics in Temporal metrics instance +// BaseMetrics returns Base metrics in Temporal metrics instance func (tm *Temporal) BaseMetrics() *Base { if tm == nil { return nil diff --git a/v3/metric/temporal_test.go b/v3/metric/temporal_test.go index 44565c1..16d0d50 100644 --- a/v3/metric/temporal_test.go +++ b/v3/metric/temporal_test.go @@ -18,6 +18,7 @@ func TestTemporalScore(t *testing.T) { {vector: "CVSS:1.0/S:U/AV:N/AC:L/PR:H/UI:N/C:L/I:L/A:N", err: cvsserr.ErrNotSupportVer, score: 0, sav: SeverityNone}, {vector: "CVSS:3.0/AV:N/AC:L/PR:H/UI:N/C:L/I:L/A:N", err: cvsserr.ErrInvalidVector, score: 0, sav: SeverityNone}, {vector: "CVSS:3.0/S:U/AV:N/AC:L/PR:H/UI:N/C:L/I:L/X:N", err: cvsserr.ErrNotSupportMetric, score: 0, sav: SeverityNone}, + {vector: "CVSS:3.0/S:U/AV:N/AC:L/PR:H/UI:N/C:L/I:L/RC:", err: cvsserr.ErrInvalidVector, score: 0, sav: SeverityNone}, {vector: "CVSS:3.0/S:U/AV:N/AC:L/PR:H/UI:N/C:L/I:L/A:N", err: nil, score: 3.8, sav: SeverityLow}, {vector: "CVSS:3.1/S:U/AV:N/AC:L/PR:H/UI:N/C:L/I:L/A:N", err: nil, score: 3.8, sav: SeverityLow}, {vector: "CVSS:3.1/S:U/AV:N/AC:L/PR:H/UI:N/C:L/I:L/A:N/E:F", err: nil, score: 3.7, sav: SeverityLow},