Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions bench_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -192,22 +192,22 @@ var decodeBenchmarks = []struct {
decodeToTypes: []reflect.Type{typeIntf, typeFloat64},
}, // float64(-4.1)
{
name: "bytes",
name: "byte string",
data: mustHexDecode("581a0102030405060708090a0b0c0d0e0f101112131415161718191a"),
decodeToTypes: []reflect.Type{typeIntf, typeByteSlice},
}, // []byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26}
{
name: "bytes indef len",
name: "indefinite-length byte string",
data: mustHexDecode("5f410141024103410441054106410741084109410a410b410c410d410e410f4110411141124113411441154116411741184119411aff"),
decodeToTypes: []reflect.Type{typeIntf, typeByteSlice},
}, // []byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26}
{
name: "text",
name: "text string",
data: mustHexDecode("782b54686520717569636b2062726f776e20666f78206a756d7073206f76657220746865206c617a7920646f67"),
decodeToTypes: []reflect.Type{typeIntf, typeString},
}, // "The quick brown fox jumps over the lazy dog"
{
name: "text indef len",
name: "indefinite-length text string",
data: mustHexDecode("7f61546168616561206171617561696163616b612061626172616f6177616e61206166616f61786120616a6175616d617061736120616f61766165617261206174616861656120616c6161617a617961206164616f6167ff"),
decodeToTypes: []reflect.Type{typeIntf, typeString},
}, // "The quick brown fox jumps over the lazy dog"
Expand All @@ -217,7 +217,7 @@ var decodeBenchmarks = []struct {
decodeToTypes: []reflect.Type{typeIntf, typeIntSlice},
}, // []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26}
{
name: "array indef len",
name: "indefinite-length array",
data: mustHexDecode("9f0102030405060708090a0b0c0d0e0f101112131415161718181819181aff"),
decodeToTypes: []reflect.Type{typeIntf, typeIntSlice},
}, // []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26}
Expand All @@ -227,7 +227,7 @@ var decodeBenchmarks = []struct {
decodeToTypes: []reflect.Type{typeIntf, typeMapStringIntf, typeMapStringString},
}, // map[string]string{"a": "A", "b": "B", "c": "C", "d": "D", "e": "E", "f": "F", "g": "G", "h": "H", "i": "I", "j": "J", "l": "L", "m": "M", "n": "N"}}
{
name: "map indef len",
name: "indefinite-length map",
data: mustHexDecode("bf616161416162614261636143616461446165614561666146616761476168614861696149616a614a616b614b616c614c616d614d616e614eff"),
decodeToTypes: []reflect.Type{typeIntf, typeMapStringIntf, typeMapStringString},
}, // map[string]string{"a": "A", "b": "B", "c": "C", "d": "D", "e": "E", "f": "F", "g": "G", "h": "H", "i": "I", "j": "J", "l": "L", "m": "M", "n": "N"}}
Expand Down
121 changes: 77 additions & 44 deletions bytestring_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
package cbor

import (
"bytes"
"io"
"strings"
"testing"
Expand All @@ -26,7 +27,7 @@ func TestByteString(t *testing.T) {
emptybs := ByteString("")
bs := ByteString("\x01\x02\x03\x04")

testCases := []roundTripTest{
testCases := []roundTripTestCase{
{
name: "empty",
obj: emptybs,
Expand Down Expand Up @@ -106,78 +107,78 @@ func TestByteString(t *testing.T) {

func TestUnmarshalByteStringOnBadData(t *testing.T) {
testCases := []struct {
name string
data []byte
errMsg string
name string
data []byte
wantErrorMsg string
}{
// Empty data
{
name: "nil data",
data: nil,
errMsg: io.EOF.Error(),
name: "nil data",
data: nil,
wantErrorMsg: io.EOF.Error(),
},
{
name: "empty data",
data: []byte{},
errMsg: io.EOF.Error(),
name: "empty data",
data: []byte{},
wantErrorMsg: io.EOF.Error(),
},

// Wrong CBOR types
{
name: "uint type",
data: mustHexDecode("01"),
errMsg: "cbor: cannot unmarshal positive integer into Go value of type cbor.ByteString",
name: "uint type",
data: mustHexDecode("01"),
wantErrorMsg: "cbor: cannot unmarshal positive integer into Go value of type cbor.ByteString",
},
{
name: "int type",
data: mustHexDecode("20"),
errMsg: "cbor: cannot unmarshal negative integer into Go value of type cbor.ByteString",
name: "int type",
data: mustHexDecode("20"),
wantErrorMsg: "cbor: cannot unmarshal negative integer into Go value of type cbor.ByteString",
},
{
name: "string type",
data: mustHexDecode("60"),
errMsg: "cbor: cannot unmarshal UTF-8 text string into Go value of type cbor.ByteString",
name: "string type",
data: mustHexDecode("60"),
wantErrorMsg: "cbor: cannot unmarshal UTF-8 text string into Go value of type cbor.ByteString",
},
{
name: "array type",
data: mustHexDecode("80"),
errMsg: "cbor: cannot unmarshal array into Go value of type cbor.ByteString",
name: "array type",
data: mustHexDecode("80"),
wantErrorMsg: "cbor: cannot unmarshal array into Go value of type cbor.ByteString",
},
{
name: "map type",
data: mustHexDecode("a0"),
errMsg: "cbor: cannot unmarshal map into Go value of type cbor.ByteString",
name: "map type",
data: mustHexDecode("a0"),
wantErrorMsg: "cbor: cannot unmarshal map into Go value of type cbor.ByteString",
},
{
name: "tag type",
data: mustHexDecode("c074323031332d30332d32315432303a30343a30305a"),
errMsg: "cbor: cannot unmarshal tag into Go value of type cbor.ByteString",
name: "tag type",
data: mustHexDecode("c074323031332d30332d32315432303a30343a30305a"),
wantErrorMsg: "cbor: cannot unmarshal tag into Go value of type cbor.ByteString",
},
{
name: "float type",
data: mustHexDecode("f90000"),
errMsg: "cbor: cannot unmarshal primitives into Go value of type cbor.ByteString",
name: "float type",
data: mustHexDecode("f90000"),
wantErrorMsg: "cbor: cannot unmarshal primitives into Go value of type cbor.ByteString",
},

// Truncated CBOR data
{
name: "truncated head",
data: mustHexDecode("18"),
errMsg: io.ErrUnexpectedEOF.Error(),
name: "truncated head",
data: mustHexDecode("18"),
wantErrorMsg: io.ErrUnexpectedEOF.Error(),
},

// Truncated CBOR byte string
{
name: "truncated byte string",
data: mustHexDecode("44010203"),
errMsg: io.ErrUnexpectedEOF.Error(),
name: "truncated byte string",
data: mustHexDecode("44010203"),
wantErrorMsg: io.ErrUnexpectedEOF.Error(),
},

// Extraneous CBOR data
{
name: "extraneous data",
data: mustHexDecode("c074323031332d30332d32315432303a30343a30305a00"),
errMsg: "cbor: 1 bytes of extraneous data starting at index 22",
name: "extraneous data",
data: mustHexDecode("c074323031332d30332d32315432303a30343a30305a00"),
wantErrorMsg: "cbor: 1 bytes of extraneous data starting at index 22",
},
}

Expand All @@ -191,8 +192,8 @@ func TestUnmarshalByteStringOnBadData(t *testing.T) {
if err == nil {
t.Errorf("UnmarshalCBOR(%x) didn't return error", tc.data)
}
if !strings.HasPrefix(err.Error(), tc.errMsg) {
t.Errorf("UnmarshalCBOR(%x) returned error %q, want %q", tc.data, err.Error(), tc.errMsg)
if !strings.HasPrefix(err.Error(), tc.wantErrorMsg) {
t.Errorf("UnmarshalCBOR(%x) returned error %q, want %q", tc.data, err.Error(), tc.wantErrorMsg)
}
}
// Test Unmarshal(data, *ByteString), which calls ByteString.unmarshalCBOR() under the hood
Expand All @@ -203,10 +204,42 @@ func TestUnmarshalByteStringOnBadData(t *testing.T) {
if err == nil {
t.Errorf("Unmarshal(%x) didn't return error", tc.data)
}
if !strings.HasPrefix(err.Error(), tc.errMsg) {
t.Errorf("Unmarshal(%x) returned error %q, want %q", tc.data, err.Error(), tc.errMsg)
if !strings.HasPrefix(err.Error(), tc.wantErrorMsg) {
t.Errorf("Unmarshal(%x) returned error %q, want %q", tc.data, err.Error(), tc.wantErrorMsg)
}
}
})
}
}

func TestByteStringBytes(t *testing.T) {
testCases := []struct {
name string
bs ByteString
want []byte
}{
{
name: "empty",
bs: ByteString(""),
want: []byte{},
},
{
name: "non-empty",
bs: ByteString("\x01\x02\x03\x04"),
want: []byte{0x01, 0x02, 0x03, 0x04},
},
{
name: "text content",
bs: ByteString("hello"),
want: []byte("hello"),
},
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
got := tc.bs.Bytes()
if !bytes.Equal(got, tc.want) {
t.Errorf("ByteString(%x).Bytes() = %x, want %x", string(tc.bs), got, tc.want)
}
})
}
}
30 changes: 1 addition & 29 deletions cache.go
Original file line number Diff line number Diff line change
Expand Up @@ -98,21 +98,6 @@ type decodingStructType struct {
toArray bool
}

// The stdlib errors.Join was introduced in Go 1.20, and we still support Go 1.17, so instead,
// here's a very basic implementation of an aggregated error.
type multierror []error

func (m multierror) Error() string {
var sb strings.Builder
for i, err := range m {
sb.WriteString(err.Error())
if i < len(m)-1 {
sb.WriteString(", ")
}
}
return sb.String()
}

func getDecodingStructType(t reflect.Type) *decodingStructType {
if v, _ := decodingStructTypeCache.Load(t); v != nil {
return v.(*decodingStructType)
Expand Down Expand Up @@ -145,20 +130,7 @@ func getDecodingStructType(t reflect.Type) *decodingStructType {
fieldIndicesByName[fld.name] = i
}

var err error
{
var multi multierror
for _, each := range errs {
if each != nil {
multi = append(multi, each)
}
}
if len(multi) == 1 {
err = multi[0]
} else if len(multi) > 1 {
err = multi
}
}
err := errors.Join(errs...)

structType := &decodingStructType{
fields: flds,
Expand Down
24 changes: 12 additions & 12 deletions decode.go
Original file line number Diff line number Diff line change
Expand Up @@ -326,14 +326,14 @@ func (dmkm DupMapKeyMode) valid() bool {
return dmkm >= 0 && dmkm < maxDupMapKeyMode
}

// IndefLengthMode specifies whether to allow indefinite length items.
// IndefLengthMode specifies whether to allow indefinite-length items.
type IndefLengthMode int

const (
// IndefLengthAllowed allows indefinite length items.
// IndefLengthAllowed allows indefinite-length items.
IndefLengthAllowed IndefLengthMode = iota

// IndefLengthForbidden disallows indefinite length items.
// IndefLengthForbidden disallows indefinite-length items.
IndefLengthForbidden

maxIndefLengthMode
Expand Down Expand Up @@ -811,7 +811,7 @@ type DecOptions struct {
// Default is 128*1024=131072 and it can be set to [16, 2147483647]
MaxMapPairs int

// IndefLength specifies whether to allow indefinite length CBOR items.
// IndefLength specifies whether to allow indefinite-length CBOR items.
IndefLength IndefLengthMode

// TagsMd specifies whether to allow CBOR tags (major type 6).
Expand Down Expand Up @@ -1149,8 +1149,8 @@ func (opts DecOptions) decMode() (*decMode, error) { //nolint:gocritic // ignore
unrecognizedTagToAny: opts.UnrecognizedTagToAny,
timeTagToAny: opts.TimeTagToAny,
simpleValues: simpleValues,
nanDec: opts.NaN,
infDec: opts.Inf,
nan: opts.NaN,
inf: opts.Inf,
byteStringToTime: opts.ByteStringToTime,
byteStringExpectedFormat: opts.ByteStringExpectedFormat,
bignumTag: opts.BignumTag,
Expand Down Expand Up @@ -1230,8 +1230,8 @@ type decMode struct {
unrecognizedTagToAny UnrecognizedTagToAnyMode
timeTagToAny TimeTagToAnyMode
simpleValues *SimpleValueRegistry
nanDec NaNMode
infDec InfMode
nan NaNMode
inf InfMode
byteStringToTime ByteStringToTimeMode
byteStringExpectedFormat ByteStringExpectedFormatMode
bignumTag BignumTagMode
Expand Down Expand Up @@ -1272,8 +1272,8 @@ func (dm *decMode) DecOptions() DecOptions {
UnrecognizedTagToAny: dm.unrecognizedTagToAny,
TimeTagToAny: dm.timeTagToAny,
SimpleValues: simpleValues,
NaN: dm.nanDec,
Inf: dm.infDec,
NaN: dm.nan,
Inf: dm.inf,
ByteStringToTime: dm.byteStringToTime,
ByteStringExpectedFormat: dm.byteStringExpectedFormat,
BignumTag: dm.bignumTag,
Expand Down Expand Up @@ -2206,7 +2206,7 @@ func (d *decoder) parseByteString() ([]byte, bool) {
d.off += int(val)
return b, false
}
// Process indefinite length string chunks.
// Process indefinite-length string chunks.
b := []byte{}
for !d.foundBreak() {
_, _, val = d.getHead()
Expand Down Expand Up @@ -2307,7 +2307,7 @@ func (d *decoder) parseTextString() ([]byte, error) {
}
return b, nil
}
// Process indefinite length string chunks.
// Process indefinite-length string chunks.
b := []byte{}
for !d.foundBreak() {
_, _, val = d.getHead()
Expand Down
Loading
Loading