From 411b2ee7311c9e9b56bdf3d86b486397d90b4c54 Mon Sep 17 00:00:00 2001 From: Paul Duncan Date: Thu, 3 Feb 2022 08:35:20 -0500 Subject: internal/cpe: mv binding v23binding --- internal/cpe/binding.go | 119 ------------------------------------ internal/cpe/binding_test.go | 132 ---------------------------------------- internal/cpe/v23binding.go | 119 ++++++++++++++++++++++++++++++++++++ internal/cpe/v23binding_test.go | 132 ++++++++++++++++++++++++++++++++++++++++ 4 files changed, 251 insertions(+), 251 deletions(-) delete mode 100644 internal/cpe/binding.go delete mode 100644 internal/cpe/binding_test.go create mode 100644 internal/cpe/v23binding.go create mode 100644 internal/cpe/v23binding_test.go diff --git a/internal/cpe/binding.go b/internal/cpe/binding.go deleted file mode 100644 index 24fb7b2..0000000 --- a/internal/cpe/binding.go +++ /dev/null @@ -1,119 +0,0 @@ -package cpe - -import ( - "encoding/json" - "errors" - "fmt" - "strings" -) - -// CPE 2.3 binding. -type V23Binding struct { - Part Part // Part attribute (NISTIR7695 5.3.3.1). - Vendor AvString // Vendor attribute (NISTIR7695 5.3.3.2). - Product AvString // Product attribute (NISTIR7695 5.3.3.3). - Version AvString // Version attribute (NISTIR7695 5.3.3.4). - Update AvString // Update attribute (NISTIR7695 5.3.3.5). - Edition AvString // Edition attribute (NISTIR7695 5.3.3.6). - SwEdition AvString // Software edition attribute (NISTIR7695 5.3.3.7). - TargetSw AvString // Target software attribute (NISTIR7695 5.3.3.8). - TargetHw AvString // Target hardware attribute (NISTIR7695 5.3.3.9). - Lang AvString // Language attribute (NISTIR7695 5.3.3.10). - Other AvString // Other attribute (NISTIR7695 5.3.3.11). -} - -// formatted string prefix -var cpe23Prefix = "cpe:2.3:" - -// missing prefix error -var missingPrefix = errors.New("missing CPE 2.3 prefix") - -// Create binding from CPE 2.3 formatted string. -func NewV23Binding(s string) (V23Binding, error) { - // check prefix - if s[0:len(cpe23Prefix)] != cpe23Prefix { - return V23Binding{}, missingPrefix - } - - // tokenize string, check for error - toks, err := tokenize([]byte(s[len(cpe23Prefix):])) - if err != nil { - return V23Binding{}, err - } - - // check token count - if len(toks) != 11 { - err = fmt.Errorf("invalid attribute count: %d != 11", len(toks)) - return V23Binding{}, err - } - - // create part - part, err := newPart(toks[0]) - if err != nil { - return V23Binding{}, err - } - - // parse tokens into strings - strs := make([]AvString, len(toks) - 1) - for i, t := range(toks[1:]) { - if strs[i], err = newAvString(t); err != nil { - return V23Binding{}, err - } - } - - // build and return result - return V23Binding { - Part: part, - Vendor: strs[0], - Product: strs[1], - Version: strs[2], - Update: strs[3], - Edition: strs[4], - Lang: strs[5], - SwEdition: strs[6], - TargetSw: strs[7], - TargetHw: strs[8], - Other: strs[9], - }, nil -} - -// Serialize CPE 2.3 binding as formatted string. -func (v V23Binding) String() string { - return cpe23Prefix + strings.Join([]string { - v.Part.String(), - v.Vendor.String(), - v.Product.String(), - v.Version.String(), - v.Update.String(), - v.Edition.String(), - v.Lang.String(), - v.SwEdition.String(), - v.TargetSw.String(), - v.TargetHw.String(), - v.Other.String(), - }, ":") -} - -// Unmarshal CPE 2.3 binding from JSON string. -func (me *V23Binding) UnmarshalJSON(b []byte) error { - // decode json string - var s string - if err := json.Unmarshal(b, &s); err != nil { - return err - } - - // create binding - binding, err := NewV23Binding(s) - if err != nil { - return err - } - - // save result, return success - *me = binding - return nil -} - -// Marshal CPE binding as JSON string. -func (v V23Binding) MarshalJSON() ([]byte, error) { - return json.Marshal(v.String()) -} diff --git a/internal/cpe/binding_test.go b/internal/cpe/binding_test.go deleted file mode 100644 index 4fa46bb..0000000 --- a/internal/cpe/binding_test.go +++ /dev/null @@ -1,132 +0,0 @@ -package cpe - -import ( - "encoding/json" - "testing" -) - -func TestNewV23Binding(t *testing.T) { - passTests := []string { - "cpe:2.3:o:intel:ethernet_controller_e810_firmware:*:*:*:*:*:*:*:*", - } - - for _, val := range(passTests) { - t.Run(val, func(t *testing.T) { - if _, err := NewV23Binding(val); err != nil { - t.Error(err) - } - }) - } - - failTests := []struct { - val string - exp string - } {{ - val: "o:intel:ethernet_controller_e810_firmware:*:*:*:*:*:*:*:*", - exp: "missing CPE 2.3 prefix", - }, { - val: "cpe:2.3:\n", - exp: "invalid byte: 0x0a", - }, { - val: "cpe:2.3:o:intel:ethernet_controller_e810_firmware:*:*:*:*:*:*:*", - exp: "invalid attribute count: 10 != 11", - }, { - val: "cpe:2.3:foo:intel:ethernet_controller_e810_firmware:*:*:*:*:*:*:*:*", - exp: "unknown part: \"foo\"", - }} - - for _, test := range(failTests) { - t.Run(test.val, func(t *testing.T) { - got, err := NewV23Binding(test.val) - 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) - } - }) - } -} - -func TestV23BindingString(t *testing.T) { - tests := []string { - "cpe:2.3:o:intel:ethernet_controller_e810_firmware:*:*:*:*:*:*:*:*", - } - - for _, val := range(tests) { - t.Run(val, func(t *testing.T) { - if got, err := NewV23Binding(val); err != nil { - t.Error(err) - } else if got.String() != val { - t.Errorf("got \"%s\", exp \"%s\"", got.String(), val) - } - }) - } -} - -func TestV23BindingUnmarshalJSON(t *testing.T) { - passTests := []string { - `"cpe:2.3:o:intel:ethernet_controller_e810_firmware:*:*:*:*:*:*:*:*"`, - } - - for _, val := range(passTests) { - t.Run(val, func(t *testing.T) { - var b V23Binding - if err := json.Unmarshal([]byte(val), &b); err != nil { - t.Error(err) - } - }) - } - - failTests := []struct { - val string - exp string - } {{ - val: `"o:intel:ethernet_controller_e810_firmware:*:*:*:*:*:*:*:*`, - exp: "unexpected end of JSON input", - }, { - val: `"o:intel:ethernet_controller_e810_firmware:*:*:*:*:*:*:*:*"`, - exp: "missing CPE 2.3 prefix", - }} - - for _, test := range(failTests) { - t.Run(test.val, func(t *testing.T) { - var got V23Binding - 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) - } - }) - } -} - -func TestV23BindingMarshalJSON(t *testing.T) { - tests := []string { - "cpe:2.3:o:intel:ethernet_controller_e810_firmware:*:*:*:*:*:*:*:*", - } - - for _, val := range(tests) { - t.Run(val, func(t *testing.T) { - // create binding, check for error - b, err := NewV23Binding(val) - if err != nil { - t.Error(err) - return - } - - // marshal json, check for error - got, err := json.Marshal(b) - if err != nil { - t.Error(err) - return - } - - // build/check expected value - exp := "\"" + val + "\"" - if string(got) != exp { - t.Errorf("got \"%s\", exp \"%s\"", string(got), exp) - return - } - }) - } -} diff --git a/internal/cpe/v23binding.go b/internal/cpe/v23binding.go new file mode 100644 index 0000000..24fb7b2 --- /dev/null +++ b/internal/cpe/v23binding.go @@ -0,0 +1,119 @@ +package cpe + +import ( + "encoding/json" + "errors" + "fmt" + "strings" +) + +// CPE 2.3 binding. +type V23Binding struct { + Part Part // Part attribute (NISTIR7695 5.3.3.1). + Vendor AvString // Vendor attribute (NISTIR7695 5.3.3.2). + Product AvString // Product attribute (NISTIR7695 5.3.3.3). + Version AvString // Version attribute (NISTIR7695 5.3.3.4). + Update AvString // Update attribute (NISTIR7695 5.3.3.5). + Edition AvString // Edition attribute (NISTIR7695 5.3.3.6). + SwEdition AvString // Software edition attribute (NISTIR7695 5.3.3.7). + TargetSw AvString // Target software attribute (NISTIR7695 5.3.3.8). + TargetHw AvString // Target hardware attribute (NISTIR7695 5.3.3.9). + Lang AvString // Language attribute (NISTIR7695 5.3.3.10). + Other AvString // Other attribute (NISTIR7695 5.3.3.11). +} + +// formatted string prefix +var cpe23Prefix = "cpe:2.3:" + +// missing prefix error +var missingPrefix = errors.New("missing CPE 2.3 prefix") + +// Create binding from CPE 2.3 formatted string. +func NewV23Binding(s string) (V23Binding, error) { + // check prefix + if s[0:len(cpe23Prefix)] != cpe23Prefix { + return V23Binding{}, missingPrefix + } + + // tokenize string, check for error + toks, err := tokenize([]byte(s[len(cpe23Prefix):])) + if err != nil { + return V23Binding{}, err + } + + // check token count + if len(toks) != 11 { + err = fmt.Errorf("invalid attribute count: %d != 11", len(toks)) + return V23Binding{}, err + } + + // create part + part, err := newPart(toks[0]) + if err != nil { + return V23Binding{}, err + } + + // parse tokens into strings + strs := make([]AvString, len(toks) - 1) + for i, t := range(toks[1:]) { + if strs[i], err = newAvString(t); err != nil { + return V23Binding{}, err + } + } + + // build and return result + return V23Binding { + Part: part, + Vendor: strs[0], + Product: strs[1], + Version: strs[2], + Update: strs[3], + Edition: strs[4], + Lang: strs[5], + SwEdition: strs[6], + TargetSw: strs[7], + TargetHw: strs[8], + Other: strs[9], + }, nil +} + +// Serialize CPE 2.3 binding as formatted string. +func (v V23Binding) String() string { + return cpe23Prefix + strings.Join([]string { + v.Part.String(), + v.Vendor.String(), + v.Product.String(), + v.Version.String(), + v.Update.String(), + v.Edition.String(), + v.Lang.String(), + v.SwEdition.String(), + v.TargetSw.String(), + v.TargetHw.String(), + v.Other.String(), + }, ":") +} + +// Unmarshal CPE 2.3 binding from JSON string. +func (me *V23Binding) UnmarshalJSON(b []byte) error { + // decode json string + var s string + if err := json.Unmarshal(b, &s); err != nil { + return err + } + + // create binding + binding, err := NewV23Binding(s) + if err != nil { + return err + } + + // save result, return success + *me = binding + return nil +} + +// Marshal CPE binding as JSON string. +func (v V23Binding) MarshalJSON() ([]byte, error) { + return json.Marshal(v.String()) +} diff --git a/internal/cpe/v23binding_test.go b/internal/cpe/v23binding_test.go new file mode 100644 index 0000000..4fa46bb --- /dev/null +++ b/internal/cpe/v23binding_test.go @@ -0,0 +1,132 @@ +package cpe + +import ( + "encoding/json" + "testing" +) + +func TestNewV23Binding(t *testing.T) { + passTests := []string { + "cpe:2.3:o:intel:ethernet_controller_e810_firmware:*:*:*:*:*:*:*:*", + } + + for _, val := range(passTests) { + t.Run(val, func(t *testing.T) { + if _, err := NewV23Binding(val); err != nil { + t.Error(err) + } + }) + } + + failTests := []struct { + val string + exp string + } {{ + val: "o:intel:ethernet_controller_e810_firmware:*:*:*:*:*:*:*:*", + exp: "missing CPE 2.3 prefix", + }, { + val: "cpe:2.3:\n", + exp: "invalid byte: 0x0a", + }, { + val: "cpe:2.3:o:intel:ethernet_controller_e810_firmware:*:*:*:*:*:*:*", + exp: "invalid attribute count: 10 != 11", + }, { + val: "cpe:2.3:foo:intel:ethernet_controller_e810_firmware:*:*:*:*:*:*:*:*", + exp: "unknown part: \"foo\"", + }} + + for _, test := range(failTests) { + t.Run(test.val, func(t *testing.T) { + got, err := NewV23Binding(test.val) + 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) + } + }) + } +} + +func TestV23BindingString(t *testing.T) { + tests := []string { + "cpe:2.3:o:intel:ethernet_controller_e810_firmware:*:*:*:*:*:*:*:*", + } + + for _, val := range(tests) { + t.Run(val, func(t *testing.T) { + if got, err := NewV23Binding(val); err != nil { + t.Error(err) + } else if got.String() != val { + t.Errorf("got \"%s\", exp \"%s\"", got.String(), val) + } + }) + } +} + +func TestV23BindingUnmarshalJSON(t *testing.T) { + passTests := []string { + `"cpe:2.3:o:intel:ethernet_controller_e810_firmware:*:*:*:*:*:*:*:*"`, + } + + for _, val := range(passTests) { + t.Run(val, func(t *testing.T) { + var b V23Binding + if err := json.Unmarshal([]byte(val), &b); err != nil { + t.Error(err) + } + }) + } + + failTests := []struct { + val string + exp string + } {{ + val: `"o:intel:ethernet_controller_e810_firmware:*:*:*:*:*:*:*:*`, + exp: "unexpected end of JSON input", + }, { + val: `"o:intel:ethernet_controller_e810_firmware:*:*:*:*:*:*:*:*"`, + exp: "missing CPE 2.3 prefix", + }} + + for _, test := range(failTests) { + t.Run(test.val, func(t *testing.T) { + var got V23Binding + 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) + } + }) + } +} + +func TestV23BindingMarshalJSON(t *testing.T) { + tests := []string { + "cpe:2.3:o:intel:ethernet_controller_e810_firmware:*:*:*:*:*:*:*:*", + } + + for _, val := range(tests) { + t.Run(val, func(t *testing.T) { + // create binding, check for error + b, err := NewV23Binding(val) + if err != nil { + t.Error(err) + return + } + + // marshal json, check for error + got, err := json.Marshal(b) + if err != nil { + t.Error(err) + return + } + + // build/check expected value + exp := "\"" + val + "\"" + if string(got) != exp { + t.Errorf("got \"%s\", exp \"%s\"", string(got), exp) + return + } + }) + } +} -- cgit v1.2.3