From 889a2deea4d6146ef608eb2f01d087cd575b209d Mon Sep 17 00:00:00 2001 From: Spiegel Date: Fri, 3 Feb 2023 08:45:54 +0900 Subject: [PATCH] Fixed that no error when misordered CVSSv2 vector string (issue #31) --- cvsserr/errors.go | 1 + v2/metric/base.go | 9 ++++++++- v2/metric/environmental.go | 12 +++++++++--- v2/metric/metric_test.go | 6 ++++++ v2/metric/temporal.go | 12 +++++++++--- 5 files changed, 33 insertions(+), 7 deletions(-) diff --git a/cvsserr/errors.go b/cvsserr/errors.go index 9b7e071..d926c0d 100644 --- a/cvsserr/errors.go +++ b/cvsserr/errors.go @@ -13,6 +13,7 @@ var ( ErrNoBaseMetrics = errors.New("no Base metrics") ErrNoTemporalMetrics = errors.New("no Temporal metrics") ErrNoEnvironmentalMetrics = errors.New("no Environmental metrics") + ErrMisordered = errors.New("misordered vector string") ) /* Copyright 2018-2023 Spiegel diff --git a/v2/metric/base.go b/v2/metric/base.go index c3759d9..43e9556 100644 --- a/v2/metric/base.go +++ b/v2/metric/base.go @@ -61,7 +61,14 @@ func (m *Base) Decode(vector string) (*Base, error) { if lastErr != nil { return m, lastErr } - return m, m.GetError() + enc, err := m.Encode() + if err != nil { + return m, errs.Wrap(err, errs.WithContext("vector", vector)) + } + if vector != enc { + return m, errs.Wrap(cvsserr.ErrMisordered, errs.WithContext("vector", vector)) + } + return m, nil } func (m *Base) decodeOne(str string) error { diff --git a/v2/metric/environmental.go b/v2/metric/environmental.go index 2aebac6..810d699 100644 --- a/v2/metric/environmental.go +++ b/v2/metric/environmental.go @@ -60,7 +60,14 @@ func (m *Environmental) Decode(vector string) (*Environmental, error) { if lastErr != nil { return m, lastErr } - return m, m.GetError() + enc, err := m.Encode() + if err != nil { + return m, errs.Wrap(err, errs.WithContext("vector", vector)) + } + if vector != enc { + return m, errs.Wrap(cvsserr.ErrMisordered, errs.WithContext("vector", vector)) + } + return m, nil } func (m *Environmental) decodeOne(str string) error { @@ -141,9 +148,8 @@ func (m *Environmental) Encode() (string, error) { if m == nil { return "", errs.Wrap(cvsserr.ErrNoBaseMetrics) } - ts, _ := m.Temporal.Encode() r := &strings.Builder{} - r.WriteString(ts) //Vector of Temporal metrics + r.WriteString(m.Temporal.String()) //Vector of Temporal metrics if m.names[metricCDP] { r.WriteString(fmt.Sprintf("/%s:%v", metricCDP, m.CDP)) // Collateral Damage Potential } diff --git a/v2/metric/metric_test.go b/v2/metric/metric_test.go index 3f6c61f..0959daf 100644 --- a/v2/metric/metric_test.go +++ b/v2/metric/metric_test.go @@ -22,6 +22,7 @@ func TestValidationBase(t *testing.T) { {vec: "AV:N/AC:H/Au:0/C:C/I:N/A:C", err: cvsserr.ErrInvalidValue}, {vec: "AV:N/AC:0/Au:M/C:C/I:N/A:C", err: cvsserr.ErrInvalidValue}, {vec: "AV:0/AC:H/Au:M/C:C/I:N/A:C", err: cvsserr.ErrInvalidValue}, + {vec: "AV:N/AC:H/Au:M/C:C/A:C/I:N", err: cvsserr.ErrMisordered}, {vec: "AV:N/AC:L/Au:N/C:N/I:N/A:C", err: nil}, } @@ -46,6 +47,8 @@ func TestValidationTemporal(t *testing.T) { {vec: "AV:N/AC:H/Au:M/C:C/I:N/A:C/E:0/RL:ND/RC:ND", err: cvsserr.ErrInvalidValue}, {vec: "AV:N/AC:H/Au:M/C:C/I:N/A:C/E:U/RL:ND", err: cvsserr.ErrNoTemporalMetrics}, {vec: "AV:N/AC:L/Au:N/C:N/I:N/E:U/RL:ND/RC:ND", err: cvsserr.ErrNoBaseMetrics}, + {vec: "AV:N/AC:L/Au:N/C:N/A:C/I:N/E:U/RL:ND/RC:ND", err: cvsserr.ErrMisordered}, + {vec: "AV:N/AC:L/Au:N/C:N/I:N/A:C/E:U/RC:ND/RL:ND", err: cvsserr.ErrMisordered}, {vec: "AV:N/AC:L/Au:N/C:N/I:N/A:C/E:U/RL:ND/RC:ND", err: nil}, } @@ -75,6 +78,9 @@ func TestValidationEnvironmental(t *testing.T) { {vec: "AV:N/AC:L/Au:N/C:N/I:N/A:C/E:U/RL:ND/RC:ND/CDP:H/TD:H/CR:M/IR:M", err: cvsserr.ErrNoEnvironmentalMetrics}, {vec: "AV:N/AC:L/Au:N/C:N/I:N/A:C/E:U/RL:ND/CDP:H/TD:H/CR:M/IR:M/AR:H", err: cvsserr.ErrNoTemporalMetrics}, {vec: "AV:N/AC:L/Au:N/C:N/I:N/E:U/RL:ND/RC:ND/CDP:H/TD:H/CR:M/IR:M/AR:H", err: cvsserr.ErrNoBaseMetrics}, + {vec: "AV:N/AC:L/Au:N/C:N/A:C/I:N/E:U/RL:ND/RC:ND/CDP:H/TD:H/CR:M/IR:M/AR:H", err: cvsserr.ErrMisordered}, + {vec: "AV:N/AC:L/Au:N/C:N/I:N/A:C/E:U/RC:ND/RL:ND/CDP:H/TD:H/CR:M/IR:M/AR:H", err: cvsserr.ErrMisordered}, + {vec: "AV:N/AC:L/Au:N/C:N/I:N/A:C/E:U/RL:ND/RC:ND/CDP:H/TD:H/CR:M/AR:H/IR:M", err: cvsserr.ErrMisordered}, {vec: "AV:N/AC:L/Au:N/C:N/I:N/A:C/E:U/RL:ND/RC:ND/CDP:H/TD:H/CR:M/IR:M/AR:H", err: nil}, } diff --git a/v2/metric/temporal.go b/v2/metric/temporal.go index 6dc9cb1..028423c 100644 --- a/v2/metric/temporal.go +++ b/v2/metric/temporal.go @@ -54,7 +54,14 @@ func (m *Temporal) Decode(vector string) (*Temporal, error) { if lastErr != nil { return m, lastErr } - return m, m.GetError() + enc, err := m.Encode() + if err != nil { + return m, errs.Wrap(err, errs.WithContext("vector", vector)) + } + if vector != enc { + return m, errs.Wrap(cvsserr.ErrMisordered, errs.WithContext("vector", vector)) + } + return m, nil } func (m *Temporal) decodeOne(str string) error { @@ -125,9 +132,8 @@ func (m *Temporal) Encode() (string, error) { if m == nil { return "", errs.Wrap(cvsserr.ErrNoBaseMetrics) } - bs, _ := m.Base.Encode() r := &strings.Builder{} - r.WriteString(bs) //Vector of Base metrics + r.WriteString(m.Base.String()) //Vector of Base metrics if m.names[metricE] { r.WriteString(fmt.Sprintf("/%s:%v", metricE, m.E)) // Exploitability }