diff options
author | Paul Duncan <pabs@pablotron.org> | 2022-02-03 08:35:20 -0500 |
---|---|---|
committer | Paul Duncan <pabs@pablotron.org> | 2022-02-03 08:35:20 -0500 |
commit | 411b2ee7311c9e9b56bdf3d86b486397d90b4c54 (patch) | |
tree | b933b4064720be3fd0318662a938fa33aaaf75d2 /internal/cpe/v23binding.go | |
parent | 2580300f01b30ce7ec99df4986e9c9489f7c5d9b (diff) | |
download | cvez-411b2ee7311c9e9b56bdf3d86b486397d90b4c54.tar.bz2 cvez-411b2ee7311c9e9b56bdf3d86b486397d90b4c54.zip |
internal/cpe: mv binding v23binding
Diffstat (limited to 'internal/cpe/v23binding.go')
-rw-r--r-- | internal/cpe/v23binding.go | 119 |
1 files changed, 119 insertions, 0 deletions
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()) +} |