diff options
| author | Paul Duncan <pabs@pablotron.org> | 2022-02-04 00:35:31 -0500 | 
|---|---|---|
| committer | Paul Duncan <pabs@pablotron.org> | 2022-02-04 00:35:31 -0500 | 
| commit | 9c17b97cd0f83be3fff9fa4e87fd1d29052ea616 (patch) | |
| tree | 0d97030a0d0c3ad983be281ce89f80571338887f /internal/cpe | |
| parent | 92400d731546557d110c9c3cc3906d700f83dda8 (diff) | |
| download | cvez-9c17b97cd0f83be3fff9fa4e87fd1d29052ea616.tar.xz cvez-9c17b97cd0f83be3fff9fa4e87fd1d29052ea616.zip  | |
rename to github.com/pablotron/cvez, remove internal libs
Diffstat (limited to 'internal/cpe')
| -rw-r--r-- | internal/cpe/avstring.go | 54 | ||||
| -rw-r--r-- | internal/cpe/avstring_test.go | 95 | ||||
| -rw-r--r-- | internal/cpe/avstringtype_string.go | 25 | ||||
| -rw-r--r-- | internal/cpe/cpe.go | 5 | ||||
| -rw-r--r-- | internal/cpe/part.go | 41 | ||||
| -rw-r--r-- | internal/cpe/part_string.go | 41 | ||||
| -rw-r--r-- | internal/cpe/part_test.go | 108 | ||||
| -rw-r--r-- | internal/cpe/token.go | 99 | ||||
| -rw-r--r-- | internal/cpe/token_test.go | 149 | ||||
| -rw-r--r-- | internal/cpe/tokentype_string.go | 25 | ||||
| -rw-r--r-- | internal/cpe/v23binding.go | 119 | ||||
| -rw-r--r-- | internal/cpe/v23binding_test.go | 132 | 
12 files changed, 0 insertions, 893 deletions
diff --git a/internal/cpe/avstring.go b/internal/cpe/avstring.go deleted file mode 100644 index 46e16cf..0000000 --- a/internal/cpe/avstring.go +++ /dev/null @@ -1,54 +0,0 @@ -package cpe - -//go:generate stringer -linecomment -type=AvStringType - -import ( -  "fmt" -) - -// type of avstring. -type AvStringType byte - -const ( -  AnyString AvStringType = iota // any -  NaString // na -  ValString // val -) - -// String value (NISTIR 7695, CPE 2.3 spec, Figure 6-3) -type AvString struct { -  Type AvStringType // value type -  Val  string // value -} - -// token type to avstring type map -var avTypes = map[tokenType]AvStringType { -  anyToken: AnyString, -  naToken: NaString, -  valToken: ValString, -} - -// create new AvString from token. -func newAvString(t token) (AvString, error) { -  if at, ok := avTypes[t.Type]; ok { -    return AvString { at, t.Val }, nil -  } else { -    err := fmt.Errorf("invalid token type: 0x%02x", byte(t.Type)) -    return AvString { 0, "" }, err -  } -} - -// Serialize as string. -func (s AvString) String() string { -  switch s.Type { -  case AnyString: -    return "*" -  case NaString: -    return "-" -  case ValString: -    return s.Val -  default: -    // not sure what to return here -    return "" -  } -} diff --git a/internal/cpe/avstring_test.go b/internal/cpe/avstring_test.go deleted file mode 100644 index 8cbb14b..0000000 --- a/internal/cpe/avstring_test.go +++ /dev/null @@ -1,95 +0,0 @@ -package cpe - -import ( -  "testing" -) - -func TestNewAvString(t *testing.T) { -  passTests := []struct { -    name string -    val token -    exp AvString -  } { -    { "any", token { Type: anyToken }, AvString { Type: AnyString } }, -    { "na", token { Type: naToken }, AvString { Type: NaString } }, -    { "empty", token { Type: valToken }, AvString { ValString, "" } }, -    { "foo", token { valToken, "foo" }, AvString { ValString, "foo" } }, -  } - -  for _, test := range(passTests) { -    t.Run(test.name, func(t *testing.T) { -      got, err := newAvString(test.val) -      if err != nil { -        t.Error(err) -      } else if got.Type != test.exp.Type { -        t.Errorf("token: got %s, exp %s", got.Type, test.exp.Type) -      } else if got.Type == ValString && got.Val != test.exp.Val { -        t.Errorf("value: got \"%s\", exp \"%s\"", got.Val, test.exp.Val) -      } -    }) -  } - -  failTests := []struct { -    name string -    val token -    exp string -  } {{ -    name: "invalid token", -    val:  token { Type: tokenType(127), Val: "foo" }, -    exp:  "invalid token type: 0x7f", -  }} - -  for _, test := range(failTests) { -    t.Run(test.name, func(t *testing.T) { -      got, err := newAvString(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 TestAvStringString(t *testing.T) { -  tests := []struct { -    name string -    val AvString -    exp string -  } { -    { "any", AvString { AnyString, "" }, "*" }, -    { "na", AvString { NaString, "" }, "-" }, -    { "foo", AvString { ValString, "foo" }, "foo" }, -    { "junk", AvString { AvStringType(255), "foo" }, "" }, -  } - -  for _, test := range(tests) { -    t.Run(test.name, func(t *testing.T) { -      got := test.val.String() -      if got != test.exp { -        t.Errorf("value: got \"%s\", exp \"%s\"", got, test.exp) -      } -    }) -  } -} - -func TestAvStringTypeString(t *testing.T) { -  tests := []struct { -    val AvStringType -    exp string -  } { -    { AnyString, "any" }, -    { NaString, "na" }, -    { ValString, "val" }, -    { AvStringType(255), "AvStringType(255)" }, -  } - -  for _, test := range(tests) { -    t.Run(test.exp, func(t *testing.T) { -      got := test.val.String() -      if got != test.exp { -        t.Errorf("got \"%s\", exp \"%s\"", got, test.exp) -      } -    }) -  } -} diff --git a/internal/cpe/avstringtype_string.go b/internal/cpe/avstringtype_string.go deleted file mode 100644 index 6fb88e1..0000000 --- a/internal/cpe/avstringtype_string.go +++ /dev/null @@ -1,25 +0,0 @@ -// Code generated by "stringer -linecomment -type=AvStringType"; DO NOT EDIT. - -package cpe - -import "strconv" - -func _() { -	// An "invalid array index" compiler error signifies that the constant values have changed. -	// Re-run the stringer command to generate them again. -	var x [1]struct{} -	_ = x[AnyString-0] -	_ = x[NaString-1] -	_ = x[ValString-2] -} - -const _AvStringType_name = "anynaval" - -var _AvStringType_index = [...]uint8{0, 3, 5, 8} - -func (i AvStringType) String() string { -	if i >= AvStringType(len(_AvStringType_index)-1) { -		return "AvStringType(" + strconv.FormatInt(int64(i), 10) + ")" -	} -	return _AvStringType_name[_AvStringType_index[i]:_AvStringType_index[i+1]] -} diff --git a/internal/cpe/cpe.go b/internal/cpe/cpe.go deleted file mode 100644 index dc38419..0000000 --- a/internal/cpe/cpe.go +++ /dev/null @@ -1,5 +0,0 @@ -// CPE 2.3 formatted string parser. -// -// Source: NISTIR 7695, figure 6-3: -// https://nvlpubs.nist.gov/nistpubs/Legacy/IR/nistir7695.pdf -package cpe diff --git a/internal/cpe/part.go b/internal/cpe/part.go deleted file mode 100644 index ef91f7c..0000000 --- a/internal/cpe/part.go +++ /dev/null @@ -1,41 +0,0 @@ -package cpe - -//go:generate stringer -linecomment -type=Part - -import ( -  "fmt" -) - -// CPE part -type Part byte - -const ( -  ApplicationPart Part = 'a' // a -  OperatingSystemPart Part = 'o' // o -  HardwarePart Part = 'h' // h -  AnyPart Part = '*' // * -  NAPart Part = '-' // - -) - -// create new part from token -func newPart(t token) (Part, error) { -  switch t.Type { -  case anyToken: -    return AnyPart, nil -  case naToken: -    return NAPart, nil -  case valToken: -    switch t.Val { -    case "a": -      return ApplicationPart, nil -    case "o": -      return OperatingSystemPart, nil -    case "h": -      return HardwarePart, nil -    default: -      return 0, fmt.Errorf("unknown part: \"%s\"", t.Val) -    } -  default: -    return 0, fmt.Errorf("unknown token type: 0x%02x", byte(t.Type)) -  } -} diff --git a/internal/cpe/part_string.go b/internal/cpe/part_string.go deleted file mode 100644 index 98b9fd3..0000000 --- a/internal/cpe/part_string.go +++ /dev/null @@ -1,41 +0,0 @@ -// Code generated by "stringer -linecomment -type=Part"; DO NOT EDIT. - -package cpe - -import "strconv" - -func _() { -	// An "invalid array index" compiler error signifies that the constant values have changed. -	// Re-run the stringer command to generate them again. -	var x [1]struct{} -	_ = x[ApplicationPart-97] -	_ = x[OperatingSystemPart-111] -	_ = x[HardwarePart-104] -	_ = x[AnyPart-42] -	_ = x[NAPart-45] -} - -const ( -	_Part_name_0 = "*" -	_Part_name_1 = "-" -	_Part_name_2 = "a" -	_Part_name_3 = "h" -	_Part_name_4 = "o" -) - -func (i Part) String() string { -	switch { -	case i == 42: -		return _Part_name_0 -	case i == 45: -		return _Part_name_1 -	case i == 97: -		return _Part_name_2 -	case i == 104: -		return _Part_name_3 -	case i == 111: -		return _Part_name_4 -	default: -		return "Part(" + strconv.FormatInt(int64(i), 10) + ")" -	} -} diff --git a/internal/cpe/part_test.go b/internal/cpe/part_test.go deleted file mode 100644 index 269d16e..0000000 --- a/internal/cpe/part_test.go +++ /dev/null @@ -1,108 +0,0 @@ -package cpe - -import ( -  "testing" -) - -func TestNewPart(t *testing.T) { -  passTests := []struct { -    name string -    val token -    exp Part -  } {{ -    name: "any", -    val:  token { Type: anyToken }, -    exp:  AnyPart, -  }, { -    name: "na", -    val:  token { Type: naToken }, -    exp:  NAPart, -  }, { -    name: "a", -    val:  token { Type: valToken, Val: "a" }, -    exp:  ApplicationPart, -  }, { -    name: "h", -    val:  token { Type: valToken, Val: "h" }, -    exp:  HardwarePart, -  }, { -    name: "o", -    val:  token { Type: valToken, Val: "o" }, -    exp:  OperatingSystemPart, -  }} - -  for _, test := range(passTests) { -    t.Run(test.name, func(t *testing.T) { -      if got, err := newPart(test.val); err != nil { -        t.Error(err) -      } else if got != test.exp { -        t.Errorf("got %s, exp %s", got, test.exp) -      } -    }) -  } - -  failTests := []struct { -    name string -    val token -    exp string -  } {{ -    name: "invalid token", -    val:  token { Type: valToken, Val: "foo" }, -    exp:  "unknown part: \"foo\"", -  }, { -    name: "empty token", -    val:  token { Type: valToken }, -    exp:  "unknown part: \"\"", -  }, { -    name: "unknown token type", -    val:  token { Type: tokenType(255) }, -    exp:  "unknown token type: 0xff", -  }} - -  for _, test := range(failTests) { -    t.Run(test.name, func(t *testing.T) { -      // tokenize, check for error -      got, err := newPart(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 TestPartString(t *testing.T) { -  tests := []struct { -    val Part -    exp string -  } {{ -    val:  AnyPart, -    exp:  "*", -  }, { -    val:  NAPart, -    exp:  "-", -  }, { -    val:  ApplicationPart, -    exp:  "a", -  }, { -    val:  HardwarePart, -    exp:  "h", -  }, { -    val:  OperatingSystemPart, -    exp:  "o", -  }, { -    val:  Part(255), -    exp:  "Part(255)", -  }} - -  for _, test := range(tests) { -    t.Run(test.exp, func(t *testing.T) { -      got := test.val.String() - -      if got != test.exp { -        t.Errorf("got \"%s\", exp \"%s\"", got, test.exp) -      } -    }) -  } -} diff --git a/internal/cpe/token.go b/internal/cpe/token.go deleted file mode 100644 index d88e773..0000000 --- a/internal/cpe/token.go +++ /dev/null @@ -1,99 +0,0 @@ -package cpe - -//go:generate stringer -linecomment -type=tokenType - -import ( -  "errors" -  "fmt" -) - -// token type -type tokenType byte - -const ( -  anyToken tokenType = iota // any -  naToken // na -  valToken // val -) - -// token -type token struct { -  Type tokenType // token type -  Val string // token value -} - -// parse buffer into token. -func newToken(val []byte) token { -  if len(val) > 0 { -    switch val[0] { -    case '*': -      return token { Type: anyToken } -    case '-': -      return token { Type: naToken } -    default: -      return token { Type: valToken, Val: string(val) } -    } -  } else { -    // empty value -    return token { Type: valToken } -  } -} - -// unterminated escape error -var unterminatedEsc = errors.New("unterminated escape at end of buffer") - -// Parse buffer into list of tokens. -func tokenize(buf []byte) ([]token, error) { -  // build result -  var r []token - -  // current token and escape state -  var curr []byte -  esc := false - -  // build result -  for _, b := range(buf) { -    if esc { -      switch b { -      // valid escaped characters -      case '\\', '*', '-', '!', '"', '#', '$', '%', '&', '\'', '(', ')', -           '+', ',', '/', ':', ';', '<', '=', '>', '@', '[', ']', '^', '`', -           '{', '|', '}', '~': -        curr = append(curr, b) -        esc = false -      default: -        return r, fmt.Errorf("invalid escape byte: 0x%02x", b) -      } -    } else { -      switch b { -      case '\\': -        esc = true -      case ':': -        // push token, clear buffer -        r = append(r, newToken(curr)) -        curr = nil -      case 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', -           'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', -           'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', -           '-', '.', '_', '*', '?': -        curr = append(curr, b) -      default: -        return r, fmt.Errorf("invalid byte: 0x%02x", b) -      } -    } -  } - -  // check for unterminated escape -  if esc { -    return r, unterminatedEsc -  } - -  if len(curr) > 0 { -    // push token, clear buffer -    r = append(r, newToken(curr)) -    curr = nil -  } - -  // return success -  return r, nil -} diff --git a/internal/cpe/token_test.go b/internal/cpe/token_test.go deleted file mode 100644 index 595df2c..0000000 --- a/internal/cpe/token_test.go +++ /dev/null @@ -1,149 +0,0 @@ -package cpe - -import ( -  "reflect" -  "testing" -) - -func TestTokenTypeString(t *testing.T) { -  tests := []struct { -    val tokenType -    exp string -  } { -    { anyToken, "any" }, -    { naToken, "na" }, -    { valToken, "val" }, -    { tokenType(255), "tokenType(255)" }, -  } - -  for _, test := range(tests) { -    t.Run(test.exp, func(t *testing.T) { -      got := test.val.String() -      if got != test.exp { -        t.Errorf("got \"%s\", exp \"%s\"", got, test.exp) -      } -    }) -  } -} - -func TestNewToken(t *testing.T) { -  passTests := []struct { -    name string -    val string -    exp token -  } { -    { "any", "*", token { Type: anyToken } }, -    { "na", "-", token { Type: naToken } }, -    { "empty", "", token { Type: valToken } }, -    { "foo", "foo", token { Type: valToken, Val: "foo" } }, -  } - -  for _, test := range(passTests) { -    t.Run(test.name, func(t *testing.T) { -      got := newToken([]byte(test.val)) -      if got.Type != test.exp.Type { -        t.Errorf("token: got %s, exp %s", got.Type, test.exp.Type) -      } else if got.Type == valToken && got.Val != test.exp.Val { -        t.Errorf("value: got \"%s\", exp \"%s\"", got.Val, test.exp.Val) -      } -    }) -  } -} - -func TestTokenize(t *testing.T) { -  passTests := []struct { -    val string -    exp []token -  } {{ -    val: "foo", -    exp: []token { token { Type: valToken, Val: "foo" } }, -  }, { -    val: "foo:bar", -    exp: []token { -      token { Type: valToken, Val: "foo" }, -      token { Type: valToken, Val: "bar" }, -    }, -  }, { -    val: "*", -    exp: []token { token { Type: anyToken } }, -  }, { -    val: "-", -    exp: []token { token { Type: naToken } }, -  }, { -    val: "*:bar", -    exp: []token { -      token { Type: anyToken }, -      token { Type: valToken, Val: "bar" }, -    }, -  }, { -    val: "foo:*", -    exp: []token { -      token { Type: valToken, Val: "foo" }, -      token { Type: anyToken }, -    }, -  }, { -    val: "-:bar", -    exp: []token { -      token { Type: naToken }, -      token { Type: valToken, Val: "bar" }, -    }, -  }, { -    val: "foo:-", -    exp: []token { -      token { Type: valToken, Val: "foo" }, -      token { Type: naToken }, -    }, -  }, { -    val: "foo\\*:-", -    exp: []token { -      token { Type: valToken, Val: "foo*" }, -      token { Type: naToken }, -    }, -  }} - -  for _, test := range(passTests) { -    t.Run(test.val, func(t *testing.T) { -      // tokenize, check for error -      got, err := tokenize([]byte(test.val)) -      if err != nil { -        t.Error(err) -        return -      } - -      if !reflect.DeepEqual(got, test.exp) { -        t.Errorf("token: got %v, exp %v", got, test.exp) -        return -      } -    }) -  } - -  failTests := []struct { -    id  string -    val string -    exp string -  } {{ -    id:  "invalid escape", -    val: "foo\\.", -    exp: "invalid escape byte: 0x2e", -  }, { -    id:  "invalid byte", -    val: "\n", -    exp: "invalid byte: 0x0a", -  }, { -    id:  "unterminated escape", -    val: "\\", -    exp: "unterminated escape at end of buffer", -  }} - -  for _, test := range(failTests) { -    t.Run(test.id, func(t *testing.T) { -      // tokenize, check for error -      got, err := tokenize([]byte(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) -      } -    }) -  } -} diff --git a/internal/cpe/tokentype_string.go b/internal/cpe/tokentype_string.go deleted file mode 100644 index 7b53758..0000000 --- a/internal/cpe/tokentype_string.go +++ /dev/null @@ -1,25 +0,0 @@ -// Code generated by "stringer -linecomment -type=tokenType"; DO NOT EDIT. - -package cpe - -import "strconv" - -func _() { -	// An "invalid array index" compiler error signifies that the constant values have changed. -	// Re-run the stringer command to generate them again. -	var x [1]struct{} -	_ = x[anyToken-0] -	_ = x[naToken-1] -	_ = x[valToken-2] -} - -const _tokenType_name = "anynaval" - -var _tokenType_index = [...]uint8{0, 3, 5, 8} - -func (i tokenType) String() string { -	if i >= tokenType(len(_tokenType_index)-1) { -		return "tokenType(" + strconv.FormatInt(int64(i), 10) + ")" -	} -	return _tokenType_name[_tokenType_index[i]:_tokenType_index[i+1]] -} diff --git a/internal/cpe/v23binding.go b/internal/cpe/v23binding.go deleted file mode 100644 index 24fb7b2..0000000 --- a/internal/cpe/v23binding.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/v23binding_test.go b/internal/cpe/v23binding_test.go deleted file mode 100644 index 4fa46bb..0000000 --- a/internal/cpe/v23binding_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 -      } -    }) -  } -}  | 
