mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-08-09 12:07:47 +00:00
Add duplicate key and field case-sensitivity CBOR decode tests.
1. Decoding map with duplicate keys into struct or map produces error. 2. Decoding a map into a Go struct matches json field tag names case-sensitively. 3. When decoding a map into a Go struct, a case-insensitive match between a key and a json field tag name is treated the same as no match. Signed-off-by: Vu Dinh <vudinh@outlook.com>
This commit is contained in:
parent
57fc5d2401
commit
4fe78a17dd
@ -45,6 +45,177 @@ func TestDecode(t *testing.T) {
|
||||
want interface{}
|
||||
assertOnError func(t *testing.T, e error)
|
||||
}{
|
||||
{
|
||||
name: "reject duplicate negative int keys into struct",
|
||||
modes: []cbor.DecMode{modes.DecodeLax},
|
||||
in: hex("a220012002"), // {-1: 1, -1: 2}
|
||||
into: struct{}{},
|
||||
assertOnError: assertIdenticalError(&cbor.DupMapKeyError{Key: int64(-1), Index: 1}),
|
||||
},
|
||||
{
|
||||
name: "reject duplicate negative int keys into map",
|
||||
in: hex("a220012002"), // {-1: 1, -1: 2}
|
||||
into: map[int64]interface{}{},
|
||||
assertOnError: assertIdenticalError(&cbor.DupMapKeyError{Key: int64(-1), Index: 1}),
|
||||
},
|
||||
{
|
||||
name: "reject duplicate positive int keys into struct",
|
||||
modes: []cbor.DecMode{modes.DecodeLax},
|
||||
in: hex("a201010102"), // {1: 1, 1: 2}
|
||||
into: struct{}{},
|
||||
assertOnError: assertIdenticalError(&cbor.DupMapKeyError{Key: int64(1), Index: 1}),
|
||||
},
|
||||
{
|
||||
name: "reject duplicate positive int keys into map",
|
||||
in: hex("a201010102"), // {1: 1, 1: 2}
|
||||
into: map[int64]interface{}{},
|
||||
assertOnError: assertIdenticalError(&cbor.DupMapKeyError{Key: int64(1), Index: 1}),
|
||||
},
|
||||
{
|
||||
name: "reject duplicate text string keys into struct",
|
||||
in: hex("a2614101614102"), // {"A": 1, "A": 2}
|
||||
into: struct {
|
||||
A int `json:"A"`
|
||||
}{},
|
||||
assertOnError: assertIdenticalError(&cbor.DupMapKeyError{Key: string("A"), Index: 1}),
|
||||
},
|
||||
{
|
||||
name: "reject duplicate text string keys into map",
|
||||
in: hex("a2614101614102"), // {"A": 1, "A": 2}
|
||||
into: map[string]interface{}{},
|
||||
assertOnError: assertIdenticalError(&cbor.DupMapKeyError{Key: string("A"), Index: 1}),
|
||||
},
|
||||
{
|
||||
name: "reject duplicate byte string keys into map",
|
||||
in: hex("a2414101414102"), // {'A': 1, 'A': 2}
|
||||
into: map[string]interface{}{},
|
||||
assertOnError: assertIdenticalError(&cbor.DupMapKeyError{Key: string("A"), Index: 1}),
|
||||
},
|
||||
{
|
||||
name: "reject duplicate byte string keys into struct",
|
||||
in: hex("a2414101414102"), // {'A': 1, 'A': 2}
|
||||
into: struct {
|
||||
A int `json:"A"`
|
||||
}{},
|
||||
assertOnError: assertIdenticalError(&cbor.DupMapKeyError{Key: string("A"), Index: 1}),
|
||||
},
|
||||
{
|
||||
name: "reject duplicate byte string and text string keys into map",
|
||||
in: hex("a2414101614102"), // {'A': 1, "A": 2}
|
||||
into: map[string]interface{}{},
|
||||
assertOnError: assertIdenticalError(&cbor.DupMapKeyError{Key: string("A"), Index: 1}),
|
||||
},
|
||||
{
|
||||
name: "reject duplicate byte string and text string keys into struct",
|
||||
in: hex("a2414101614102"), // {'A': 1, "A": 2}
|
||||
into: struct {
|
||||
A int `json:"A"`
|
||||
}{},
|
||||
assertOnError: assertIdenticalError(&cbor.DupMapKeyError{Key: string("A"), Index: 1}),
|
||||
},
|
||||
{
|
||||
name: "reject two identical indefinite-length byte string keys split into chunks differently into struct",
|
||||
in: hex("a25f426865436c6c6fff015f416844656c6c6fff02"), // {(_ 'he', 'llo'): 1, (_ 'h', 'ello'): 2}
|
||||
into: struct {
|
||||
Hello int `json:"hello"`
|
||||
}{},
|
||||
assertOnError: assertIdenticalError(&cbor.DupMapKeyError{Key: string("hello"), Index: 1}),
|
||||
},
|
||||
{
|
||||
name: "reject two identical indefinite-length byte string keys split into chunks differently into map",
|
||||
in: hex("a25f426865436c6c6fff015f416844656c6c6fff02"), // {(_ 'he', 'llo'): 1, (_ 'h', 'ello'): 2}
|
||||
into: map[string]interface{}{},
|
||||
assertOnError: assertIdenticalError(&cbor.DupMapKeyError{Key: string("hello"), Index: 1}),
|
||||
},
|
||||
{
|
||||
name: "reject two identical indefinite-length text string keys split into chunks differently into struct",
|
||||
in: hex("a27f626865636c6c6fff017f616864656c6c6fff02"), // {(_ "he", "llo"): 1, (_ "h", "ello"): 2}
|
||||
into: struct {
|
||||
Hello int `json:"hello"`
|
||||
}{},
|
||||
assertOnError: assertIdenticalError(&cbor.DupMapKeyError{Key: string("hello"), Index: 1}),
|
||||
},
|
||||
{
|
||||
name: "reject two identical indefinite-length text string keys split into chunks differently into map",
|
||||
modes: []cbor.DecMode{modes.DecodeLax},
|
||||
in: hex("a27f626865636c6c6fff017f616864656c6c6fff02"), // {(_ "he", "llo"): 1, (_ "h", "ello"): 2}
|
||||
into: map[string]interface{}{},
|
||||
assertOnError: assertIdenticalError(&cbor.DupMapKeyError{Key: string("hello"), Index: 1}),
|
||||
},
|
||||
{
|
||||
name: "case-insensitive match treated as unknown field",
|
||||
modes: []cbor.DecMode{modes.Decode},
|
||||
in: hex("a1614101"), // {"A": 1}
|
||||
into: struct {
|
||||
A int `json:"a"`
|
||||
}{},
|
||||
assertOnError: assertIdenticalError(&cbor.UnknownFieldError{Index: 0}),
|
||||
},
|
||||
{
|
||||
name: "case-insensitive match ignored in lax mode",
|
||||
modes: []cbor.DecMode{modes.DecodeLax},
|
||||
in: hex("a1614101"), // {"A": 1}
|
||||
into: struct {
|
||||
A int `json:"a"`
|
||||
}{},
|
||||
want: struct {
|
||||
A int `json:"a"`
|
||||
}{
|
||||
A: 0,
|
||||
},
|
||||
assertOnError: assertNilError,
|
||||
},
|
||||
{
|
||||
name: "case-insensitive match after exact match treated as unknown field",
|
||||
modes: []cbor.DecMode{modes.Decode},
|
||||
in: hex("a2616101614102"), // {"a": 1, "A": 2}
|
||||
into: struct {
|
||||
A int `json:"a"`
|
||||
}{},
|
||||
want: struct {
|
||||
A int `json:"a"`
|
||||
}{
|
||||
A: 1,
|
||||
},
|
||||
assertOnError: assertIdenticalError(&cbor.UnknownFieldError{Index: 1}),
|
||||
},
|
||||
{
|
||||
name: "case-insensitive match after exact match ignored in lax mode",
|
||||
modes: []cbor.DecMode{modes.DecodeLax},
|
||||
in: hex("a2616101614102"), // {"a": 1, "A": 2}
|
||||
into: struct {
|
||||
A int `json:"a"`
|
||||
}{},
|
||||
want: struct {
|
||||
A int `json:"a"`
|
||||
}{
|
||||
A: 1,
|
||||
},
|
||||
assertOnError: assertNilError,
|
||||
},
|
||||
{
|
||||
name: "case-insensitive match before exact match treated as unknown field",
|
||||
modes: []cbor.DecMode{modes.Decode},
|
||||
in: hex("a2614101616102"), // {"A": 1, "a": 2}
|
||||
into: struct {
|
||||
A int `json:"a"`
|
||||
}{},
|
||||
assertOnError: assertIdenticalError(&cbor.UnknownFieldError{Index: 0}),
|
||||
},
|
||||
{
|
||||
name: "case-insensitive match before exact match ignored in lax mode",
|
||||
modes: []cbor.DecMode{modes.DecodeLax},
|
||||
in: hex("a2614101616102"), // {"A": 1, "a": 2}
|
||||
into: struct {
|
||||
A int `json:"a"`
|
||||
}{},
|
||||
want: struct {
|
||||
A int `json:"a"`
|
||||
}{
|
||||
A: 2,
|
||||
},
|
||||
assertOnError: assertNilError,
|
||||
},
|
||||
{
|
||||
name: "reject text string containing invalid utf-8 sequence",
|
||||
in: hex("6180"), // text string beginning with continuation byte 0x80
|
||||
|
@ -21,6 +21,7 @@ import (
|
||||
"testing"
|
||||
|
||||
"github.com/fxamacker/cbor/v2"
|
||||
"github.com/google/go-cmp/cmp"
|
||||
"k8s.io/apimachinery/pkg/runtime/serializer/cbor/internal/modes"
|
||||
)
|
||||
|
||||
@ -60,3 +61,11 @@ func assertOnConcreteError[E error](fn func(*testing.T, E)) func(t *testing.T, e
|
||||
fn(t, ec)
|
||||
}
|
||||
}
|
||||
|
||||
func assertIdenticalError[E error](expected E) func(*testing.T, error) {
|
||||
return assertOnConcreteError(func(t *testing.T, actual E) {
|
||||
if diff := cmp.Diff(expected, actual); diff != "" {
|
||||
t.Errorf("diff between actual error and expected error:\n%s", diff)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user