Bump github.com/fxamacker/cbor/v2 to v2.6.0.

This commit is contained in:
Ben Luddy 2024-02-12 15:46:17 -05:00
parent 015e76aa24
commit aac43dc96f
No known key found for this signature in database
GPG Key ID: A6551E73A5974C30
43 changed files with 1179 additions and 407 deletions

2
go.mod
View File

@ -152,7 +152,7 @@ require (
github.com/fatih/camelcase v1.0.0 // indirect
github.com/felixge/httpsnoop v1.0.3 // indirect
github.com/fvbommel/sortorder v1.1.0 // indirect
github.com/fxamacker/cbor/v2 v2.5.0 // indirect
github.com/fxamacker/cbor/v2 v2.6.0 // indirect
github.com/go-errors/errors v1.4.2 // indirect
github.com/go-logr/stdr v1.2.2 // indirect
github.com/go-logr/zapr v1.3.0 // indirect

4
go.sum
View File

@ -337,8 +337,8 @@ github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nos
github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM=
github.com/fvbommel/sortorder v1.1.0 h1:fUmoe+HLsBTctBDoaBwpQo5N+nrCp8g/BjKb/6ZQmYw=
github.com/fvbommel/sortorder v1.1.0/go.mod h1:uk88iVf1ovNn1iLfgUVU2F9o5eO30ui720w+kxuqRs0=
github.com/fxamacker/cbor/v2 v2.5.0 h1:oHsG0V/Q6E/wqTS2O1Cozzsy69nqCiguo5Q1a1ADivE=
github.com/fxamacker/cbor/v2 v2.5.0/go.mod h1:TA1xS00nchWmaBnEIxPSE5oHLuJBAVvqrtAnWBwBCVo=
github.com/fxamacker/cbor/v2 v2.6.0 h1:sU6J2usfADwWlYDAFhZBQ6TnLFBHxgesMrQfQgk1tWA=
github.com/fxamacker/cbor/v2 v2.6.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ=
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/go-errors/errors v1.4.2 h1:J6MZopCL4uSllY1OfXM374weqZFFItUbrImctkmUxIA=
github.com/go-errors/errors v1.4.2/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3BopGUQ5a5Og=

View File

@ -4,7 +4,7 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/evanphx/json-patch v4.12.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
github.com/fxamacker/cbor/v2 v2.5.0/go.mod h1:TA1xS00nchWmaBnEIxPSE5oHLuJBAVvqrtAnWBwBCVo=
github.com/fxamacker/cbor/v2 v2.6.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ=
github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ=
github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs=

View File

@ -178,7 +178,7 @@ github.com/felixge/httpsnoop v1.0.3 h1:s/nj+GCswXYzN5v2DpNMuMQYe+0DDwt5WVCU6CWBd
github.com/felixge/httpsnoop v1.0.3/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA=
github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM=
github.com/fxamacker/cbor/v2 v2.5.0/go.mod h1:TA1xS00nchWmaBnEIxPSE5oHLuJBAVvqrtAnWBwBCVo=
github.com/fxamacker/cbor/v2 v2.6.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ=
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
github.com/go-kit/log v0.2.1/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0=

View File

@ -8,7 +8,7 @@ require (
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5
github.com/davecgh/go-spew v1.1.1
github.com/evanphx/json-patch v4.12.0+incompatible
github.com/fxamacker/cbor/v2 v2.5.0
github.com/fxamacker/cbor/v2 v2.6.0
github.com/gogo/protobuf v1.3.2
github.com/golang/protobuf v1.5.3
github.com/google/gnostic-models v0.6.8

View File

@ -12,8 +12,8 @@ github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs
github.com/emicklei/go-restful/v3 v3.8.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc=
github.com/evanphx/json-patch v4.12.0+incompatible h1:4onqiflcdA9EOZ4RxV643DvftH5pOlLGNtQ5lPWQu84=
github.com/evanphx/json-patch v4.12.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
github.com/fxamacker/cbor/v2 v2.5.0 h1:oHsG0V/Q6E/wqTS2O1Cozzsy69nqCiguo5Q1a1ADivE=
github.com/fxamacker/cbor/v2 v2.5.0/go.mod h1:TA1xS00nchWmaBnEIxPSE5oHLuJBAVvqrtAnWBwBCVo=
github.com/fxamacker/cbor/v2 v2.6.0 h1:sU6J2usfADwWlYDAFhZBQ6TnLFBHxgesMrQfQgk1tWA=
github.com/fxamacker/cbor/v2 v2.6.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ=
github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ=
github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
github.com/go-openapi/jsonpointer v0.19.6 h1:eCs3fxoIi3Wh6vtgmLTOjdhSpiqphQ+DaPn38N2ZdrE=

View File

@ -179,7 +179,7 @@ github.com/felixge/httpsnoop v1.0.3 h1:s/nj+GCswXYzN5v2DpNMuMQYe+0DDwt5WVCU6CWBd
github.com/felixge/httpsnoop v1.0.3/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA=
github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM=
github.com/fxamacker/cbor/v2 v2.5.0/go.mod h1:TA1xS00nchWmaBnEIxPSE5oHLuJBAVvqrtAnWBwBCVo=
github.com/fxamacker/cbor/v2 v2.6.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ=
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
github.com/go-kit/log v0.2.1/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0=

View File

@ -25,7 +25,7 @@ github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.m
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/evanphx/json-patch v4.12.0+incompatible h1:4onqiflcdA9EOZ4RxV643DvftH5pOlLGNtQ5lPWQu84=
github.com/evanphx/json-patch v4.12.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
github.com/fxamacker/cbor/v2 v2.5.0/go.mod h1:TA1xS00nchWmaBnEIxPSE5oHLuJBAVvqrtAnWBwBCVo=
github.com/fxamacker/cbor/v2 v2.6.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ=
github.com/go-errors/errors v1.4.2 h1:J6MZopCL4uSllY1OfXM374weqZFFItUbrImctkmUxIA=
github.com/go-errors/errors v1.4.2/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3BopGUQ5a5Og=
github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ=

View File

@ -12,7 +12,7 @@ github.com/emicklei/go-restful/v3 v3.11.0 h1:rAQeMHw1c7zTmncogyy8VvRZwtkmkZ4FxER
github.com/emicklei/go-restful/v3 v3.11.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc=
github.com/evanphx/json-patch v4.12.0+incompatible h1:4onqiflcdA9EOZ4RxV643DvftH5pOlLGNtQ5lPWQu84=
github.com/evanphx/json-patch v4.12.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
github.com/fxamacker/cbor/v2 v2.5.0/go.mod h1:TA1xS00nchWmaBnEIxPSE5oHLuJBAVvqrtAnWBwBCVo=
github.com/fxamacker/cbor/v2 v2.6.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ=
github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ=
github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
github.com/go-openapi/jsonpointer v0.19.6 h1:eCs3fxoIi3Wh6vtgmLTOjdhSpiqphQ+DaPn38N2ZdrE=

View File

@ -167,7 +167,7 @@ github.com/felixge/httpsnoop v1.0.3 h1:s/nj+GCswXYzN5v2DpNMuMQYe+0DDwt5WVCU6CWBd
github.com/felixge/httpsnoop v1.0.3/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA=
github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM=
github.com/fxamacker/cbor/v2 v2.5.0/go.mod h1:TA1xS00nchWmaBnEIxPSE5oHLuJBAVvqrtAnWBwBCVo=
github.com/fxamacker/cbor/v2 v2.6.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ=
github.com/go-kit/log v0.2.1/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0=
github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs=
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=

View File

@ -3,7 +3,7 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/evanphx/json-patch v4.12.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
github.com/fxamacker/cbor/v2 v2.5.0/go.mod h1:TA1xS00nchWmaBnEIxPSE5oHLuJBAVvqrtAnWBwBCVo=
github.com/fxamacker/cbor/v2 v2.6.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ=
github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ=
github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs=

View File

@ -34,7 +34,7 @@ github.com/evanphx/json-patch v4.12.0+incompatible h1:4onqiflcdA9EOZ4RxV643DvftH
github.com/evanphx/json-patch v4.12.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
github.com/felixge/httpsnoop v1.0.3 h1:s/nj+GCswXYzN5v2DpNMuMQYe+0DDwt5WVCU6CWBdXk=
github.com/felixge/httpsnoop v1.0.3/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
github.com/fxamacker/cbor/v2 v2.5.0/go.mod h1:TA1xS00nchWmaBnEIxPSE5oHLuJBAVvqrtAnWBwBCVo=
github.com/fxamacker/cbor/v2 v2.6.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ=
github.com/go-kit/log v0.2.1/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0=
github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs=
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=

View File

@ -11,7 +11,7 @@ github.com/emicklei/go-restful/v3 v3.11.0 h1:rAQeMHw1c7zTmncogyy8VvRZwtkmkZ4FxER
github.com/emicklei/go-restful/v3 v3.11.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc=
github.com/evanphx/json-patch v4.12.0+incompatible h1:4onqiflcdA9EOZ4RxV643DvftH5pOlLGNtQ5lPWQu84=
github.com/evanphx/json-patch v4.12.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
github.com/fxamacker/cbor/v2 v2.5.0/go.mod h1:TA1xS00nchWmaBnEIxPSE5oHLuJBAVvqrtAnWBwBCVo=
github.com/fxamacker/cbor/v2 v2.6.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ=
github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ=
github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
github.com/go-openapi/jsonpointer v0.19.6 h1:eCs3fxoIi3Wh6vtgmLTOjdhSpiqphQ+DaPn38N2ZdrE=

View File

@ -164,7 +164,7 @@ github.com/felixge/httpsnoop v1.0.3 h1:s/nj+GCswXYzN5v2DpNMuMQYe+0DDwt5WVCU6CWBd
github.com/felixge/httpsnoop v1.0.3/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA=
github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM=
github.com/fxamacker/cbor/v2 v2.5.0/go.mod h1:TA1xS00nchWmaBnEIxPSE5oHLuJBAVvqrtAnWBwBCVo=
github.com/fxamacker/cbor/v2 v2.6.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ=
github.com/go-kit/log v0.2.1/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0=
github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs=
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=

View File

@ -3,7 +3,7 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/evanphx/json-patch v4.12.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
github.com/fxamacker/cbor/v2 v2.5.0/go.mod h1:TA1xS00nchWmaBnEIxPSE5oHLuJBAVvqrtAnWBwBCVo=
github.com/fxamacker/cbor/v2 v2.6.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ=
github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ=
github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs=

View File

@ -19,7 +19,7 @@ github.com/envoyproxy/go-control-plane v0.11.1/go.mod h1:uhMcXKCQMEJHiAb0w+YGefQ
github.com/envoyproxy/protoc-gen-validate v1.0.2/go.mod h1:GpiZQP3dDbg4JouG/NNS7QWXpgx6x8QiMKdmN72jogE=
github.com/evanphx/json-patch v4.12.0+incompatible h1:4onqiflcdA9EOZ4RxV643DvftH5pOlLGNtQ5lPWQu84=
github.com/evanphx/json-patch v4.12.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
github.com/fxamacker/cbor/v2 v2.5.0/go.mod h1:TA1xS00nchWmaBnEIxPSE5oHLuJBAVvqrtAnWBwBCVo=
github.com/fxamacker/cbor/v2 v2.6.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ=
github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ=
github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
github.com/go-openapi/jsonpointer v0.19.6 h1:eCs3fxoIi3Wh6vtgmLTOjdhSpiqphQ+DaPn38N2ZdrE=

View File

@ -22,7 +22,7 @@ github.com/emicklei/go-restful/v3 v3.11.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRr
github.com/evanphx/json-patch v4.12.0+incompatible h1:4onqiflcdA9EOZ4RxV643DvftH5pOlLGNtQ5lPWQu84=
github.com/evanphx/json-patch v4.12.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
github.com/felixge/httpsnoop v1.0.3/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
github.com/fxamacker/cbor/v2 v2.5.0/go.mod h1:TA1xS00nchWmaBnEIxPSE5oHLuJBAVvqrtAnWBwBCVo=
github.com/fxamacker/cbor/v2 v2.6.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ=
github.com/go-kit/log v0.2.1/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0=
github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs=
github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ=

View File

@ -165,7 +165,7 @@ github.com/felixge/httpsnoop v1.0.3 h1:s/nj+GCswXYzN5v2DpNMuMQYe+0DDwt5WVCU6CWBd
github.com/felixge/httpsnoop v1.0.3/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA=
github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM=
github.com/fxamacker/cbor/v2 v2.5.0/go.mod h1:TA1xS00nchWmaBnEIxPSE5oHLuJBAVvqrtAnWBwBCVo=
github.com/fxamacker/cbor/v2 v2.6.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ=
github.com/go-kit/log v0.2.1/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0=
github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs=
github.com/go-logr/logr v0.2.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU=

View File

@ -17,7 +17,7 @@ github.com/emicklei/go-restful/v3 v3.11.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRr
github.com/evanphx/json-patch v4.12.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
github.com/felixge/httpsnoop v1.0.3/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM=
github.com/fxamacker/cbor/v2 v2.5.0/go.mod h1:TA1xS00nchWmaBnEIxPSE5oHLuJBAVvqrtAnWBwBCVo=
github.com/fxamacker/cbor/v2 v2.6.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ=
github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ=
github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=

View File

@ -17,7 +17,7 @@ github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs
github.com/emicklei/go-restful/v3 v3.11.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc=
github.com/evanphx/json-patch v4.12.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
github.com/felixge/httpsnoop v1.0.3/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
github.com/fxamacker/cbor/v2 v2.5.0/go.mod h1:TA1xS00nchWmaBnEIxPSE5oHLuJBAVvqrtAnWBwBCVo=
github.com/fxamacker/cbor/v2 v2.6.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ=
github.com/go-kit/log v0.2.1/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0=
github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs=
github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ=

View File

@ -10,7 +10,7 @@ github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs
github.com/emicklei/go-restful/v3 v3.11.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc=
github.com/evanphx/json-patch v4.12.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
github.com/felixge/httpsnoop v1.0.3/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
github.com/fxamacker/cbor/v2 v2.5.0/go.mod h1:TA1xS00nchWmaBnEIxPSE5oHLuJBAVvqrtAnWBwBCVo=
github.com/fxamacker/cbor/v2 v2.6.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ=
github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ=
github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=

View File

@ -45,7 +45,7 @@ github.com/fatih/camelcase v1.0.0/go.mod h1:yN2Sb0lFhZJUdVvtELVWefmrXpuZESvPmqwo
github.com/felixge/httpsnoop v1.0.3/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
github.com/fvbommel/sortorder v1.1.0 h1:fUmoe+HLsBTctBDoaBwpQo5N+nrCp8g/BjKb/6ZQmYw=
github.com/fvbommel/sortorder v1.1.0/go.mod h1:uk88iVf1ovNn1iLfgUVU2F9o5eO30ui720w+kxuqRs0=
github.com/fxamacker/cbor/v2 v2.5.0/go.mod h1:TA1xS00nchWmaBnEIxPSE5oHLuJBAVvqrtAnWBwBCVo=
github.com/fxamacker/cbor/v2 v2.6.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ=
github.com/go-errors/errors v1.4.2 h1:J6MZopCL4uSllY1OfXM374weqZFFItUbrImctkmUxIA=
github.com/go-errors/errors v1.4.2/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3BopGUQ5a5Og=
github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ=

View File

@ -33,7 +33,7 @@ github.com/envoyproxy/protoc-gen-validate v1.0.2/go.mod h1:GpiZQP3dDbg4JouG/NNS7
github.com/evanphx/json-patch v4.12.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
github.com/felixge/httpsnoop v1.0.3/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM=
github.com/fxamacker/cbor/v2 v2.5.0/go.mod h1:TA1xS00nchWmaBnEIxPSE5oHLuJBAVvqrtAnWBwBCVo=
github.com/fxamacker/cbor/v2 v2.6.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ=
github.com/go-kit/log v0.2.1/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0=
github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs=
github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ=

View File

@ -103,7 +103,7 @@ github.com/evanphx/json-patch v4.12.0+incompatible h1:4onqiflcdA9EOZ4RxV643DvftH
github.com/evanphx/json-patch v4.12.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
github.com/felixge/httpsnoop v1.0.3/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM=
github.com/fxamacker/cbor/v2 v2.5.0/go.mod h1:TA1xS00nchWmaBnEIxPSE5oHLuJBAVvqrtAnWBwBCVo=
github.com/fxamacker/cbor/v2 v2.6.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ=
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=

View File

@ -11,7 +11,7 @@ github.com/emicklei/go-restful/v3 v3.11.0 h1:rAQeMHw1c7zTmncogyy8VvRZwtkmkZ4FxER
github.com/emicklei/go-restful/v3 v3.11.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc=
github.com/evanphx/json-patch v4.12.0+incompatible h1:4onqiflcdA9EOZ4RxV643DvftH5pOlLGNtQ5lPWQu84=
github.com/evanphx/json-patch v4.12.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
github.com/fxamacker/cbor/v2 v2.5.0/go.mod h1:TA1xS00nchWmaBnEIxPSE5oHLuJBAVvqrtAnWBwBCVo=
github.com/fxamacker/cbor/v2 v2.6.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ=
github.com/go-logr/logr v0.2.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU=
github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ=
github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=

View File

@ -164,7 +164,7 @@ github.com/felixge/httpsnoop v1.0.3 h1:s/nj+GCswXYzN5v2DpNMuMQYe+0DDwt5WVCU6CWBd
github.com/felixge/httpsnoop v1.0.3/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA=
github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM=
github.com/fxamacker/cbor/v2 v2.5.0/go.mod h1:TA1xS00nchWmaBnEIxPSE5oHLuJBAVvqrtAnWBwBCVo=
github.com/fxamacker/cbor/v2 v2.6.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ=
github.com/go-kit/log v0.2.1/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0=
github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs=
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=

View File

@ -164,7 +164,7 @@ github.com/felixge/httpsnoop v1.0.3 h1:s/nj+GCswXYzN5v2DpNMuMQYe+0DDwt5WVCU6CWBd
github.com/felixge/httpsnoop v1.0.3/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA=
github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM=
github.com/fxamacker/cbor/v2 v2.5.0/go.mod h1:TA1xS00nchWmaBnEIxPSE5oHLuJBAVvqrtAnWBwBCVo=
github.com/fxamacker/cbor/v2 v2.6.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ=
github.com/go-kit/log v0.2.1/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0=
github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs=
github.com/go-logr/logr v0.2.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU=

View File

@ -25,7 +25,7 @@ github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.m
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/evanphx/json-patch v4.12.0+incompatible h1:4onqiflcdA9EOZ4RxV643DvftH5pOlLGNtQ5lPWQu84=
github.com/evanphx/json-patch v4.12.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
github.com/fxamacker/cbor/v2 v2.5.0/go.mod h1:TA1xS00nchWmaBnEIxPSE5oHLuJBAVvqrtAnWBwBCVo=
github.com/fxamacker/cbor/v2 v2.6.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ=
github.com/go-errors/errors v1.4.2 h1:J6MZopCL4uSllY1OfXM374weqZFFItUbrImctkmUxIA=
github.com/go-errors/errors v1.4.2/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3BopGUQ5a5Og=
github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ=

View File

@ -11,7 +11,7 @@ github.com/emicklei/go-restful/v3 v3.11.0 h1:rAQeMHw1c7zTmncogyy8VvRZwtkmkZ4FxER
github.com/emicklei/go-restful/v3 v3.11.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc=
github.com/evanphx/json-patch v4.12.0+incompatible h1:4onqiflcdA9EOZ4RxV643DvftH5pOlLGNtQ5lPWQu84=
github.com/evanphx/json-patch v4.12.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
github.com/fxamacker/cbor/v2 v2.5.0/go.mod h1:TA1xS00nchWmaBnEIxPSE5oHLuJBAVvqrtAnWBwBCVo=
github.com/fxamacker/cbor/v2 v2.6.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ=
github.com/go-logr/logr v0.2.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU=
github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ=
github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=

View File

@ -41,16 +41,17 @@ linters-settings:
linters:
disable-all: true
enable:
- bidichk
- errcheck
- goconst
- gocyclo
# - gofmt # handled by safer-golangci-lint.yml
# - goimports # handled by safer-golangci-lint.yml
- gofmt
- goimports
- gosec
- govet
- ineffassign
- misspell
# - revive # temporarily disabled to reduce noise in golangci-lint 1.52.2
- revive
- staticcheck
- typecheck
- unconvert

View File

@ -6,9 +6,9 @@
CBOR is a [trusted alternative](https://www.rfc-editor.org/rfc/rfc8949.html#name-comparison-of-other-binary-) to JSON, MessagePack, Protocol Buffers, etc.  CBOR is an Internet Standard defined by [IETF STD 94 (RFC 8949)](https://www.rfc-editor.org/info/std94) and is designed to be relevant for decades.
`fxamacker/cbor` is used in projects by Arm Ltd., Cisco, Dapper Labs, EdgeX Foundry, Fraunhofer‑AISEC, Linux Foundation, Microsoft, Mozilla, Oasis Protocol, Tailscale, Teleport, [and others](https://github.com/fxamacker/cbor#who-uses-fxamackercbor).
`fxamacker/cbor` is used in projects by Arm Ltd., Cisco, Dapper Labs, EdgeX Foundry, Fraunhofer‑AISEC, Let's Encrypt (ISRG), Linux Foundation, Microsoft, Mozilla, Oasis Protocol, Tailscale, Teleport, [and others](https://github.com/fxamacker/cbor#who-uses-fxamackercbor).
See [Quick Start](#quick-start).
See [Quick Start](#quick-start) and [Releases](https://github.com/fxamacker/cbor/releases/). 🆕 `UnmarshalFirst` and `DiagnoseFirst` can decode CBOR Sequences.
## fxamacker/cbor
@ -23,48 +23,7 @@ See [Quick Start](#quick-start).
Features include full support for CBOR tags, [Core Deterministic Encoding](https://www.rfc-editor.org/rfc/rfc8949.html#name-core-deterministic-encoding), duplicate map key detection, etc.
Struct tags (`toarray`, `keyasint`, `omitempty`) reduce encoded size of structs.
![alt text](https://github.com/fxamacker/images/raw/master/cbor/v2.3.0/cbor_struct_tags_api.svg?sanitize=1 "CBOR API and Go Struct Tags")
API is mostly same as `encoding/json`, plus interfaces that simplify concurrency for CBOR options.
#### CBOR Security
Configurable limits help defend against malicious inputs.
Decoding 10 bytes of malicious data directly into `[]byte` is efficiently rejected.
| Codec | Speed (ns/op) | Memory | Allocs |
| :---- | ------------: | -----: | -----: |
| fxamacker/cbor 2.5.0 | 43.95n ± 5% | 32 B/op | 2 allocs/op |
| ugorji/go 1.2.11 | 5353261.00n ± 4% | 67111321 B/op | 13 allocs/op |
<details><summary>More Details and Prior Comparions</summary><p/>
Latest comparison used:
- Input: `[]byte{0x9B, 0x00, 0x00, 0x42, 0xFA, 0x42, 0xFA, 0x42, 0xFA, 0x42}`
- go1.19.10, linux/amd64, i5-13600K (disabled all e-cores, DDR4 @2933)
- go test -bench=. -benchmem -count=20
#### Prior comparisons
| Codec | Speed (ns/op) | Memory | Allocs |
| :---- | ------------: | -----: | -----: |
| fxamacker/cbor 2.5.0-beta2 | 44.33 ± 2% | 32 B/op | 2 allocs/op |
| fxamacker/cbor 0.1.0 - 2.4.0 | ~44.68 ± 6% | 32 B/op | 2 allocs/op |
| ugorji/go 1.2.10 | 5524792.50 ± 3% | 67110491 B/op | 12 allocs/op |
| ugorji/go 1.1.0 - 1.2.6 | 💥 runtime: | out of memory: | cannot allocate |
- Input: `[]byte{0x9B, 0x00, 0x00, 0x42, 0xFA, 0x42, 0xFA, 0x42, 0xFA, 0x42}`
- go1.19.6, linux/amd64, i5-13600K (DDR4)
- go test -bench=. -benchmem -count=20
</details>
#### Design and Feature Highlights
Design balances tradeoffs between speed, security, memory, encoded data size, usability, etc.
Design balances trade-offs between security, speed, concurrency, encoded data size, usability, etc.
<details><summary>Highlights</summary><p/>
@ -92,34 +51,215 @@ __📆&nbsp; Extensibility__
Features include CBOR [extension points](https://www.rfc-editor.org/rfc/rfc8949.html#section-7.1) (e.g. CBOR tags) and extensive settings. API has interfaces that allow users to create custom encoding and decoding without modifying this library.
<hr/>
</details>
### Secure Decoding with Configurable Settings
`fxamacker/cbor` has configurable limits, etc. that defend against malicious CBOR data.
By contrast, `encoding/gob` is [not designed to be hardened against adversarial inputs](https://pkg.go.dev/encoding/gob#hdr-Security).
<details><summary>Example decoding with encoding/gob 💥 fatal error (out of memory)</summary><p/>
```Go
// Example of encoding/gob having "fatal error: runtime: out of memory"
// while decoding 181 bytes.
package main
import (
"bytes"
"encoding/gob"
"encoding/hex"
"fmt"
)
// Example data is from https://github.com/golang/go/issues/24446
// (shortened to 181 bytes).
const data = "4dffb503010102303001ff30000109010130010800010130010800010130" +
"01ffb80001014a01ffb60001014b01ff860001013001ff860001013001ff" +
"860001013001ff860001013001ffb80000001eff850401010e3030303030" +
"30303030303030303001ff3000010c0104000016ffb70201010830303030" +
"3030303001ff3000010c000030ffb6040405fcff00303030303030303030" +
"303030303030303030303030303030303030303030303030303030303030" +
"30"
type X struct {
J *X
K map[string]int
}
func main() {
raw, _ := hex.DecodeString(data)
decoder := gob.NewDecoder(bytes.NewReader(raw))
var x X
decoder.Decode(&x) // fatal error: runtime: out of memory
fmt.Println("Decoding finished.")
}
```
<hr/>
</details>
`fxamacker/cbor` is fast at rejecting malformed CBOR data. E.g. attempts to
decode 10 bytes of malicious CBOR data to `[]byte` (with default settings):
| Codec | Speed (ns/op) | Memory | Allocs |
| :---- | ------------: | -----: | -----: |
| fxamacker/cbor 2.5.0 | 44 ± 5% | 32 B/op | 2 allocs/op |
| ugorji/go 1.2.11 | 5353261 ± 4% | 67111321 B/op | 13 allocs/op |
<details><summary>Benchmark details</summary><p/>
Latest comparison used:
- Input: `[]byte{0x9B, 0x00, 0x00, 0x42, 0xFA, 0x42, 0xFA, 0x42, 0xFA, 0x42}`
- go1.19.10, linux/amd64, i5-13600K (disabled all e-cores, DDR4 @2933)
- go test -bench=. -benchmem -count=20
#### Prior comparisons
| Codec | Speed (ns/op) | Memory | Allocs |
| :---- | ------------: | -----: | -----: |
| fxamacker/cbor 2.5.0-beta2 | 44.33 ± 2% | 32 B/op | 2 allocs/op |
| fxamacker/cbor 0.1.0 - 2.4.0 | ~44.68 ± 6% | 32 B/op | 2 allocs/op |
| ugorji/go 1.2.10 | 5524792.50 ± 3% | 67110491 B/op | 12 allocs/op |
| ugorji/go 1.1.0 - 1.2.6 | 💥 runtime: | out of memory: | cannot allocate |
- Input: `[]byte{0x9B, 0x00, 0x00, 0x42, 0xFA, 0x42, 0xFA, 0x42, 0xFA, 0x42}`
- go1.19.6, linux/amd64, i5-13600K (DDR4)
- go test -bench=. -benchmem -count=20
<hr/>
</details>
### Smaller Encodings with Struct Tags
Struct tags (`toarray`, `keyasint`, `omitempty`) reduce encoded size of structs.
<details><summary>Example encoding 3-level nested Go struct to 1 byte CBOR</summary><p/>
https://go.dev/play/p/YxwvfPdFQG2
```Go
// Example encoding nested struct (with omitempty tag)
// - encoding/json: 18 byte JSON
// - fxamacker/cbor: 1 byte CBOR
package main
import (
"encoding/hex"
"encoding/json"
"fmt"
"github.com/fxamacker/cbor/v2"
)
type GrandChild struct {
Quux int `json:",omitempty"`
}
type Child struct {
Baz int `json:",omitempty"`
Qux GrandChild `json:",omitempty"`
}
type Parent struct {
Foo Child `json:",omitempty"`
Bar int `json:",omitempty"`
}
func cb() {
results, _ := cbor.Marshal(Parent{})
fmt.Println("hex(CBOR): " + hex.EncodeToString(results))
text, _ := cbor.Diagnose(results) // Diagnostic Notation
fmt.Println("DN: " + text)
}
func js() {
results, _ := json.Marshal(Parent{})
fmt.Println("hex(JSON): " + hex.EncodeToString(results))
text := string(results) // JSON
fmt.Println("JSON: " + text)
}
func main() {
cb()
fmt.Println("-------------")
js()
}
```
Output (DN is Diagnostic Notation):
```
hex(CBOR): a0
DN: {}
-------------
hex(JSON): 7b22466f6f223a7b22517578223a7b7d7d7d
JSON: {"Foo":{"Qux":{}}}
```
<hr/>
</details>
Example using different struct tags together:
![alt text](https://github.com/fxamacker/images/raw/master/cbor/v2.3.0/cbor_struct_tags_api.svg?sanitize=1 "CBOR API and Go Struct Tags")
API is mostly same as `encoding/json`, plus interfaces that simplify concurrency for CBOR options.
## Quick Start
__Install__: `go get github.com/fxamacker/cbor/v2` and `import "github.com/fxamacker/cbor/v2"`.
### Key Points
This library can encode and decode CBOR (RFC 8949) and CBOR Sequences (RFC 8742).
- __CBOR data item__ is a single piece of CBOR data and its structure may contain zero, one, or more nested data items.
- __CBOR sequence__ is a concatenation of 0 or more encoded CBOR data items.
Configurable limits and options can be used to balance trade-offs.
- Encoding and decoding modes are created from options (settings).
- Modes can be created at startup and reused.
- Modes are safe for concurrent use.
### Default Mode
Package level functions only use default settings.
Package level functions only use this library's default settings.
They provide the "default mode" of encoding and decoding.
```go
// API matches encoding/json.
b, err := cbor.Marshal(v) // encode v to []byte b
err := cbor.Unmarshal(b, &v) // decode []byte b to v
encoder := cbor.NewEncoder(w) // create encoder with io.Writer w
decoder := cbor.NewDecoder(r) // create decoder with io.Reader r
// API matches encoding/json for Marshal, Unmarshal, Encode, Decode, etc.
b, err = cbor.Marshal(v) // encode v to []byte b
err = cbor.Unmarshal(b, &v) // decode []byte b to v
decoder = cbor.NewDecoder(r) // create decoder with io.Reader r
err = decoder.Decode(&v) // decode a CBOR data item to v
// v2.5.0 added new functions that return remaining bytes.
// UnmarshalFirst decodes first CBOR data item and returns remaining bytes.
rest, err = cbor.UnmarshalFirst(b, &v) // decode []byte b to v
// DiagnoseFirst translates first CBOR data item to text and returns remaining bytes.
text, rest, err = cbor.DiagnoseFirst(b) // decode []byte b to Diagnostic Notation text
// NOTE: Unmarshal returns ExtraneousDataError if there are remaining bytes,
// but new funcs UnmarshalFirst and DiagnoseFirst do not.
```
Some CBOR-based formats or protocols may require non-default settings.
__IMPORTANT__: 👉 CBOR settings allow trade-offs between speed, security, encoding size, etc.
For example, WebAuthn uses "CTAP2 Canonical CBOR" settings. It is available as a preset.
- Different CBOR libraries may use different default settings.
- CBOR-based formats or protocols usually require specific settings.
For example, WebAuthn uses "CTAP2 Canonical CBOR" which is available as a preset.
### Presets
@ -161,7 +301,75 @@ Default mode and custom modes automatically apply struct tags.
Struct tags (`toarray`, `keyasint`, `omitempty`) reduce encoded size of structs.
<details><summary>Example using struct tags</summary><p/>
<details><summary>Example encoding 3-level nested Go struct to 1 byte CBOR</summary><p/>
https://go.dev/play/p/YxwvfPdFQG2
```Go
// Example encoding nested struct (with omitempty tag)
// - encoding/json: 18 byte JSON
// - fxamacker/cbor: 1 byte CBOR
package main
import (
"encoding/hex"
"encoding/json"
"fmt"
"github.com/fxamacker/cbor/v2"
)
type GrandChild struct {
Quux int `json:",omitempty"`
}
type Child struct {
Baz int `json:",omitempty"`
Qux GrandChild `json:",omitempty"`
}
type Parent struct {
Foo Child `json:",omitempty"`
Bar int `json:",omitempty"`
}
func cb() {
results, _ := cbor.Marshal(Parent{})
fmt.Println("hex(CBOR): " + hex.EncodeToString(results))
text, _ := cbor.Diagnose(results) // Diagnostic Notation
fmt.Println("DN: " + text)
}
func js() {
results, _ := json.Marshal(Parent{})
fmt.Println("hex(JSON): " + hex.EncodeToString(results))
text := string(results) // JSON
fmt.Println("JSON: " + text)
}
func main() {
cb()
fmt.Println("-------------")
js()
}
```
Output (DN is Diagnostic Notation):
```
hex(CBOR): a0
DN: {}
-------------
hex(JSON): 7b22466f6f223a7b22517578223a7b7d7d7d
JSON: {"Foo":{"Qux":{}}}
```
<hr/>
</details>
<details><summary>Example using several struct tags</summary><p/>
![alt text](https://github.com/fxamacker/images/raw/master/cbor/v2.3.0/cbor_struct_tags_api.svg?sanitize=1 "CBOR API and Go Struct Tags")
@ -251,11 +459,19 @@ Default limits may need to be increased for systems handling very large data (e.
## Status
v2.5.0 was released on Sunday, August 13, 2023. It is fuzz tested and production quality.
v2.6.0 (February 2024) adds important new features, optimizations, and bug fixes. It is especially useful to systems that need to convert data between CBOR and JSON. New options and optimizations improve handling of bignum, integers, maps, and strings.
__IMPORTANT__: Before upgrading from prior release, please read the notable changes highlighted in the release notes.
For more details, see [release notes](https://github.com/fxamacker/cbor/releases).
See latest [releases](https://github.com/fxamacker/cbor/releases) and [v2.5.0 release notes](https://github.com/fxamacker/cbor/releases/tag/v2.5.0) for list of new features and improvements.
### Prior Release
v2.5.0 was released on Sunday, August 13, 2023 with new features and important bug fixes. It is fuzz tested and production quality after extended beta [v2.5.0-beta](https://github.com/fxamacker/cbor/releases/tag/v2.5.0-beta) (Dec 2022) -> [v2.5.0](https://github.com/fxamacker/cbor/releases/tag/v2.5.0) (Aug 2023).
__IMPORTANT__: 👉 Before upgrading from v2.4 or older release, please read the notable changes highlighted in the release notes. v2.5.0 is a large release with bug fixes to error handling for extraneous data in `Unmarshal`, etc. that should be reviewed before upgrading.
See [v2.5.0 release notes](https://github.com/fxamacker/cbor/releases/tag/v2.5.0) for list of new features, improvements, and bug fixes.
See ["Version and API Changes"](https://github.com/fxamacker/cbor#versions-and-api-changes) section for more info about version numbering, etc.
<!--
<details><summary>👉 Benchmark Comparison: v2.4.0 vs v2.5.0</summary><p/>
@ -318,14 +534,15 @@ geomean 2.782
## Who uses fxamacker/cbor
`fxamacker/cbor` is used in projects by Arm Ltd., Berlin Institute of Health at Charité, Chainlink, Cisco, Confidential Computing Consortium, ConsenSys, Dapper&nbsp;Labs, EdgeX&nbsp;Foundry, F5, Fraunhofer&#8209;AISEC, Linux&nbsp;Foundation, Microsoft, Mozilla, National&nbsp;Cybersecurity&nbsp;Agency&nbsp;of&nbsp;France (govt), Netherlands (govt), Oasis Protocol, Smallstep, Tailscale, Taurus SA, Teleport, TIBCO, and others.
Although GitHub only reports around 200 repos depend on this library, that is for v1 (old version). For v2 (current version), GitHub reports [2000+ repositories](https://github.com/fxamacker/cbor/network/dependents?package_id=UGFja2FnZS0yMjcwNDY1OTQ4) depend on fxamacker/cbor.
`fxamacker/cbor` is used in projects by Arm Ltd., Berlin Institute of Health at Charité, Chainlink, Cisco, Confidential Computing Consortium, ConsenSys, Dapper&nbsp;Labs, EdgeX&nbsp;Foundry, F5, FIDO Alliance, Fraunhofer&#8209;AISEC, Let's Encrypt (ISRG), Linux&nbsp;Foundation, Matrix.org, Microsoft, Mozilla, National&nbsp;Cybersecurity&nbsp;Agency&nbsp;of&nbsp;France (govt), Netherlands (govt), Oasis Protocol, Smallstep, Tailscale, Taurus SA, Teleport, TIBCO, and others.
`fxamacker/cbor` passed multiple confidential security assessments. A [nonconfidential security assessment](https://github.com/veraison/go-cose/blob/v1.0.0-rc.1/reports/NCC_Microsoft-go-cose-Report_2022-05-26_v1.0.pdf) (prepared by NCC Group for Microsoft Corporation) includes a subset of fxamacker/cbor v2.4.0 in its scope.
## Standards
This library is a full-featured generic CBOR [(RFC 8949)](https://tools.ietf.org/html/rfc8949) encoder and decoder. Notable CBOR features include:
`fxamacker/cbor` is a CBOR codec in full conformance with [IETF STD&nbsp;94 (RFC&nbsp;8949)](https://www.rfc-editor.org/info/std94). It also supports CBOR Sequences ([RFC&nbsp;8742](https://www.rfc-editor.org/rfc/rfc8742.html)) and Extended Diagnostic Notation ([Appendix G of RFC&nbsp;8610](https://www.rfc-editor.org/rfc/rfc8610.html#appendix-G)).
Notable CBOR features include:
| CBOR Feature | Description |
| :--- | :--- |
@ -397,7 +614,7 @@ If any of these limitations prevent you from using this library, please open an
## Fuzzing and Code Coverage
__Code coverage__ must not fall below 95% when tagging a release. Code coverage is above 96% (`go test -cover`) for fxamacker/cbor v2.5.
__Code coverage__ is always 95% or higher (with `go test -cover`) when tagging a release.
__Coverage-guided fuzzing__ must pass billions of execs using before tagging a release. Fuzzing is done using nonpublic code which may eventually get merged into this project. Until then, reports like OpenSSF&nbsp;Scorecard can't detect fuzz tests being used by this project.
@ -406,13 +623,15 @@ __Coverage-guided fuzzing__ must pass billions of execs using before tagging a r
## Versions and API Changes
This project uses [Semantic Versioning](https://semver.org), so the API is always backwards compatible unless the major version number changes.
These functions have signatures identical to encoding/json and they will likely never change even after major new releases:
These functions have signatures identical to encoding/json and their API will continue to match `encoding/json` even after major new releases:
`Marshal`, `Unmarshal`, `NewEncoder`, `NewDecoder`, `(*Encoder).Encode`, and `(*Decoder).Decode`.
Exclusions from SemVer:
- Newly added API documented as "subject to change".
- Newly added API in the master branch that has never been release tagged.
- Bug fixes that change behavior (e.g. return error that was missed in prior version) if function parameters are unchanged. We try to highlight these in the release notes.
- Newly added API in the master branch that has never been tagged in non-beta release.
- If function parameters are unchanged, bug fixes that change behavior (e.g. return error for edge case was missed in prior version). We try to highlight these in the release notes and add extended beta period. E.g. [v2.5.0-beta](https://github.com/fxamacker/cbor/releases/tag/v2.5.0-beta) (Dec 2022) -> [v2.5.0](https://github.com/fxamacker/cbor/releases/tag/v2.5.0) (Aug 2023).
This project avoids breaking changes to behavior of encoding and decoding functions unless required to improve conformance with supported RFCs (e.g. RFC 8949, RFC 8742, etc.) Visible changes that don't improve conformance to standards are typically made available as new opt-in settings or new functions.
## Code of Conduct
@ -442,11 +661,14 @@ This library clearly wouldn't be possible without Carsten Bormann authoring CBOR
Special thanks to Laurence Lundblade and Jeffrey Yasskin for their help on IETF mailing list or at [7049bis](https://github.com/cbor-wg/CBORbis).
This library uses `x448/float16` which used to be included. Now as a standalone package, `x448/float16` is useful to other projects as well.
Huge thanks to The Go Authors for creating a fun and practical programming language with batteries included!
## License
Copyright © 2019-2023 [Faye Amacker](https://github.com/fxamacker).
This library uses `x448/float16` which used to be included. As a standalone package, `x448/float16` is useful to other projects as well.
fxamacker/cbor is licensed under the MIT License. See [LICENSE](LICENSE) for the full license text.
## License
Copyright © 2019-2024 [Faye Amacker](https://github.com/fxamacker).
fxamacker/cbor is licensed under the MIT License. See [LICENSE](LICENSE) for the full license text.
<hr>

View File

@ -57,6 +57,7 @@ func (bs *ByteString) UnmarshalCBOR(data []byte) error {
return &UnmarshalTypeError{CBORType: typ.String(), GoType: typeByteString.String()}
}
*bs = ByteString(d.parseByteString())
b, _ := d.parseByteString()
*bs = ByteString(b)
return nil
}

View File

@ -224,6 +224,15 @@ func getEncodingStructType(t reflect.Type) (*encodingStructType, error) {
copy(flds[i].cborName[n:], flds[i].name)
e.Reset()
// If cborName contains a text string, then cborNameByteString contains a
// string that has the byte string major type but is otherwise identical to
// cborName.
flds[i].cborNameByteString = make([]byte, len(flds[i].cborName))
copy(flds[i].cborNameByteString, flds[i].cborName)
// Reset encoded CBOR type to byte string, preserving the "additional
// information" bits:
flds[i].cborNameByteString[0] = byte(cborTypeByteString) | (flds[i].cborNameByteString[0] & 0x1f)
hasKeyAsStr = true
}

View File

@ -51,6 +51,7 @@ import (
// CBOR null and undefined values decode to nil.
// CBOR times (tag 0 and 1) decode to time.Time.
// CBOR bignums (tag 2 and 3) decode to big.Int.
// CBOR tags with an unrecognized number decode to cbor.Tag
//
// To unmarshal a CBOR array into a slice, Unmarshal allocates a new slice
// if the CBOR array is empty or slice capacity is less than CBOR array length.
@ -226,7 +227,7 @@ const (
)
func (dmkm DupMapKeyMode) valid() bool {
return dmkm < maxDupMapKeyMode
return dmkm >= 0 && dmkm < maxDupMapKeyMode
}
// IndefLengthMode specifies whether to allow indefinite length items.
@ -243,7 +244,7 @@ const (
)
func (m IndefLengthMode) valid() bool {
return m < maxIndefLengthMode
return m >= 0 && m < maxIndefLengthMode
}
// TagsMode specifies whether to allow CBOR tags.
@ -260,29 +261,48 @@ const (
)
func (tm TagsMode) valid() bool {
return tm < maxTagsMode
return tm >= 0 && tm < maxTagsMode
}
// IntDecMode specifies which Go int type (int64 or uint64) should
// be used when decoding CBOR int (major type 0 and 1) to Go interface{}.
// IntDecMode specifies which Go type (int64, uint64, or big.Int) should
// be used when decoding CBOR integers (major type 0 and 1) to Go interface{}.
type IntDecMode int
const (
// IntDecConvertNone affects how CBOR int (major type 0 and 1) decodes to Go interface{}.
// It makes CBOR positive int (major type 0) decode to uint64 value, and
// CBOR negative int (major type 1) decode to int64 value.
// IntDecConvertNone affects how CBOR integers (major type 0 and 1) decode to Go interface{}.
// It decodes CBOR unsigned integer (major type 0) to:
// - uint64
// It decodes CBOR negative integer (major type 1) to:
// - int64 if value fits
// - big.Int or *big.Int (see BigIntDecMode) if value doesn't fit into int64
IntDecConvertNone IntDecMode = iota
// IntDecConvertSigned affects how CBOR int (major type 0 and 1) decodes to Go interface{}.
// It makes CBOR positive/negative int (major type 0 and 1) decode to int64 value.
// If value overflows int64, UnmarshalTypeError is returned.
// IntDecConvertSigned affects how CBOR integers (major type 0 and 1) decode to Go interface{}.
// It decodes CBOR integers (major type 0 and 1) to:
// - int64 if value fits
// - big.Int or *big.Int (see BigIntDecMode) if value < math.MinInt64
// - return UnmarshalTypeError if value > math.MaxInt64
// Deprecated: IntDecConvertSigned should not be used.
// Please use other options, such as IntDecConvertSignedOrError, IntDecConvertSignedOrBigInt, IntDecConvertNone.
IntDecConvertSigned
// IntDecConvertSignedOrFail affects how CBOR integers (major type 0 and 1) decode to Go interface{}.
// It decodes CBOR integers (major type 0 and 1) to:
// - int64 if value fits
// - return UnmarshalTypeError if value doesn't fit into int64
IntDecConvertSignedOrFail
// IntDecConvertSigned affects how CBOR integers (major type 0 and 1) decode to Go interface{}.
// It makes CBOR integers (major type 0 and 1) decode to:
// - int64 if value fits
// - big.Int or *big.Int (see BigIntDecMode) if value doesn't fit into int64
IntDecConvertSignedOrBigInt
maxIntDec
)
func (idm IntDecMode) valid() bool {
return idm < maxIntDec
return idm >= 0 && idm < maxIntDec
}
// MapKeyByteStringMode specifies how to decode CBOR byte string (major type 2)
@ -312,7 +332,7 @@ const (
)
func (mkbsm MapKeyByteStringMode) valid() bool {
return mkbsm < maxMapKeyByteStringMode
return mkbsm >= 0 && mkbsm < maxMapKeyByteStringMode
}
// ExtraDecErrorCond specifies extra conditions that should be treated as errors.
@ -350,7 +370,100 @@ const (
)
func (um UTF8Mode) valid() bool {
return um < maxUTF8Mode
return um >= 0 && um < maxUTF8Mode
}
// FieldNameMatchingMode specifies how string keys in CBOR maps are matched to Go struct field names.
type FieldNameMatchingMode int
const (
// FieldNameMatchingPreferCaseSensitive prefers to decode map items into struct fields whose names (or tag
// names) exactly match the item's key. If there is no such field, a map item will be decoded into a field whose
// name is a case-insensitive match for the item's key.
FieldNameMatchingPreferCaseSensitive FieldNameMatchingMode = iota
// FieldNameMatchingCaseSensitive decodes map items only into a struct field whose name (or tag name) is an
// exact match for the item's key.
FieldNameMatchingCaseSensitive
maxFieldNameMatchingMode
)
func (fnmm FieldNameMatchingMode) valid() bool {
return fnmm >= 0 && fnmm < maxFieldNameMatchingMode
}
// BigIntDecMode specifies how to decode CBOR bignum to Go interface{}.
type BigIntDecMode int
const (
// BigIntDecodeValue makes CBOR bignum decode to big.Int (instead of *big.Int)
// when unmarshalling into a Go interface{}.
BigIntDecodeValue BigIntDecMode = iota
// BigIntDecodePointer makes CBOR bignum decode to *big.Int when
// unmarshalling into a Go interface{}.
BigIntDecodePointer
maxBigIntDecMode
)
func (bidm BigIntDecMode) valid() bool {
return bidm >= 0 && bidm < maxBigIntDecMode
}
// ByteStringToStringMode specifies the behavior when decoding a CBOR byte string into a Go string.
type ByteStringToStringMode int
const (
// ByteStringToStringForbidden generates an error on an attempt to decode a CBOR byte string into a Go string.
ByteStringToStringForbidden ByteStringToStringMode = iota
// ByteStringToStringAllowed permits decoding a CBOR byte string into a Go string.
ByteStringToStringAllowed
maxByteStringToStringMode
)
func (bstsm ByteStringToStringMode) valid() bool {
return bstsm >= 0 && bstsm < maxByteStringToStringMode
}
// FieldNameByteStringMode specifies the behavior when decoding a CBOR byte string map key as a Go struct field name.
type FieldNameByteStringMode int
const (
// FieldNameByteStringForbidden generates an error on an attempt to decode a CBOR byte string map key as a Go struct field name.
FieldNameByteStringForbidden FieldNameByteStringMode = iota
// FieldNameByteStringAllowed permits CBOR byte string map keys to be recognized as Go struct field names.
FieldNameByteStringAllowed
maxFieldNameByteStringMode
)
func (fnbsm FieldNameByteStringMode) valid() bool {
return fnbsm >= 0 && fnbsm < maxFieldNameByteStringMode
}
// UnrecognizedTagToAnyMode specifies how to decode unrecognized CBOR tag into an empty interface (any).
// Currently, recognized CBOR tag numbers are 0, 1, 2, 3, or registered by TagSet.
type UnrecognizedTagToAnyMode int
const (
// UnrecognizedTagNumAndContentToAny decodes CBOR tag number and tag content to cbor.Tag
// when decoding unrecognized CBOR tag into an empty interface.
UnrecognizedTagNumAndContentToAny UnrecognizedTagToAnyMode = iota
// UnrecognizedTagContentToAny decodes only CBOR tag content (into its default type)
// when decoding unrecognized CBOR tag into an empty interface.
UnrecognizedTagContentToAny
maxUnrecognizedTagToAny
)
func (uttam UnrecognizedTagToAnyMode) valid() bool {
return uttam >= 0 && uttam < maxUnrecognizedTagToAny
}
// DecOptions specifies decoding options.
@ -402,6 +515,29 @@ type DecOptions struct {
// UTF8 specifies if decoder should decode CBOR Text containing invalid UTF-8.
// By default, unmarshal rejects CBOR text containing invalid UTF-8.
UTF8 UTF8Mode
// FieldNameMatching specifies how string keys in CBOR maps are matched to Go struct field names.
FieldNameMatching FieldNameMatchingMode
// BigIntDec specifies how to decode CBOR bignum to Go interface{}.
BigIntDec BigIntDecMode
// DefaultByteStringType is the Go type that should be produced when decoding a CBOR byte
// string into an empty interface value. Types to which a []byte is convertible are valid
// for this option, except for array and pointer-to-array types. If nil, the default is
// []byte.
DefaultByteStringType reflect.Type
// ByteStringToString specifies the behavior when decoding a CBOR byte string into a Go string.
ByteStringToString ByteStringToStringMode
// FieldNameByteString specifies the behavior when decoding a CBOR byte string map key as a
// Go struct field name.
FieldNameByteString FieldNameByteStringMode
// UnrecognizedTagToAny specifies how to decode unrecognized CBOR tag into an empty interface.
// Currently, recognized CBOR tag numbers are 0, 1, 2, 3, or registered by TagSet.
UnrecognizedTagToAny UnrecognizedTagToAnyMode
}
// DecMode returns DecMode with immutable options and no tags (safe for concurrency).
@ -510,19 +646,43 @@ func (opts DecOptions) decMode() (*decMode, error) {
if !opts.UTF8.valid() {
return nil, errors.New("cbor: invalid UTF8 " + strconv.Itoa(int(opts.UTF8)))
}
if !opts.FieldNameMatching.valid() {
return nil, errors.New("cbor: invalid FieldNameMatching " + strconv.Itoa(int(opts.FieldNameMatching)))
}
if !opts.BigIntDec.valid() {
return nil, errors.New("cbor: invalid BigIntDec " + strconv.Itoa(int(opts.BigIntDec)))
}
if opts.DefaultByteStringType != nil && opts.DefaultByteStringType.Kind() != reflect.String && (opts.DefaultByteStringType.Kind() != reflect.Slice || opts.DefaultByteStringType.Elem().Kind() != reflect.Uint8) {
return nil, fmt.Errorf("cbor: invalid DefaultByteStringType: %s is not of kind string or []uint8", opts.DefaultByteStringType)
}
if !opts.ByteStringToString.valid() {
return nil, errors.New("cbor: invalid ByteStringToString " + strconv.Itoa(int(opts.ByteStringToString)))
}
if !opts.FieldNameByteString.valid() {
return nil, errors.New("cbor: invalid FieldNameByteString " + strconv.Itoa(int(opts.FieldNameByteString)))
}
if !opts.UnrecognizedTagToAny.valid() {
return nil, errors.New("cbor: invalid UnrecognizedTagToAnyMode " + strconv.Itoa(int(opts.UnrecognizedTagToAny)))
}
dm := decMode{
dupMapKey: opts.DupMapKey,
timeTag: opts.TimeTag,
maxNestedLevels: opts.MaxNestedLevels,
maxArrayElements: opts.MaxArrayElements,
maxMapPairs: opts.MaxMapPairs,
indefLength: opts.IndefLength,
tagsMd: opts.TagsMd,
intDec: opts.IntDec,
mapKeyByteString: opts.MapKeyByteString,
extraReturnErrors: opts.ExtraReturnErrors,
defaultMapType: opts.DefaultMapType,
utf8: opts.UTF8,
dupMapKey: opts.DupMapKey,
timeTag: opts.TimeTag,
maxNestedLevels: opts.MaxNestedLevels,
maxArrayElements: opts.MaxArrayElements,
maxMapPairs: opts.MaxMapPairs,
indefLength: opts.IndefLength,
tagsMd: opts.TagsMd,
intDec: opts.IntDec,
mapKeyByteString: opts.MapKeyByteString,
extraReturnErrors: opts.ExtraReturnErrors,
defaultMapType: opts.DefaultMapType,
utf8: opts.UTF8,
fieldNameMatching: opts.FieldNameMatching,
bigIntDec: opts.BigIntDec,
defaultByteStringType: opts.DefaultByteStringType,
byteStringToString: opts.ByteStringToString,
fieldNameByteString: opts.FieldNameByteString,
unrecognizedTagToAny: opts.UnrecognizedTagToAny,
}
return &dm, nil
}
@ -574,19 +734,25 @@ type DecMode interface {
}
type decMode struct {
tags tagProvider
dupMapKey DupMapKeyMode
timeTag DecTagMode
maxNestedLevels int
maxArrayElements int
maxMapPairs int
indefLength IndefLengthMode
tagsMd TagsMode
intDec IntDecMode
mapKeyByteString MapKeyByteStringMode
extraReturnErrors ExtraDecErrorCond
defaultMapType reflect.Type
utf8 UTF8Mode
tags tagProvider
dupMapKey DupMapKeyMode
timeTag DecTagMode
maxNestedLevels int
maxArrayElements int
maxMapPairs int
indefLength IndefLengthMode
tagsMd TagsMode
intDec IntDecMode
mapKeyByteString MapKeyByteStringMode
extraReturnErrors ExtraDecErrorCond
defaultMapType reflect.Type
utf8 UTF8Mode
fieldNameMatching FieldNameMatchingMode
bigIntDec BigIntDecMode
defaultByteStringType reflect.Type
byteStringToString ByteStringToStringMode
fieldNameByteString FieldNameByteStringMode
unrecognizedTagToAny UnrecognizedTagToAnyMode
}
var defaultDecMode, _ = DecOptions{}.decMode()
@ -594,17 +760,24 @@ var defaultDecMode, _ = DecOptions{}.decMode()
// DecOptions returns user specified options used to create this DecMode.
func (dm *decMode) DecOptions() DecOptions {
return DecOptions{
DupMapKey: dm.dupMapKey,
TimeTag: dm.timeTag,
MaxNestedLevels: dm.maxNestedLevels,
MaxArrayElements: dm.maxArrayElements,
MaxMapPairs: dm.maxMapPairs,
IndefLength: dm.indefLength,
TagsMd: dm.tagsMd,
IntDec: dm.intDec,
MapKeyByteString: dm.mapKeyByteString,
ExtraReturnErrors: dm.extraReturnErrors,
UTF8: dm.utf8,
DupMapKey: dm.dupMapKey,
TimeTag: dm.timeTag,
MaxNestedLevels: dm.maxNestedLevels,
MaxArrayElements: dm.maxArrayElements,
MaxMapPairs: dm.maxMapPairs,
IndefLength: dm.indefLength,
TagsMd: dm.tagsMd,
IntDec: dm.intDec,
MapKeyByteString: dm.mapKeyByteString,
ExtraReturnErrors: dm.extraReturnErrors,
DefaultMapType: dm.defaultMapType,
UTF8: dm.utf8,
FieldNameMatching: dm.fieldNameMatching,
BigIntDec: dm.bigIntDec,
DefaultByteStringType: dm.defaultByteStringType,
ByteStringToString: dm.byteStringToString,
FieldNameByteString: dm.fieldNameByteString,
UnrecognizedTagToAny: dm.unrecognizedTagToAny,
}
}
@ -757,6 +930,13 @@ const (
// and does not perform bounds checking.
func (d *decoder) parseToValue(v reflect.Value, tInfo *typeInfo) error { //nolint:gocyclo
// Decode CBOR nil or CBOR undefined to pointer value by setting pointer value to nil.
if d.nextCBORNil() && v.Kind() == reflect.Ptr {
d.skip()
v.Set(reflect.Zero(v.Type()))
return nil
}
if tInfo.spclType == specialTypeIface {
if !v.IsNil() {
// Use value type
@ -787,18 +967,17 @@ func (d *decoder) parseToValue(v reflect.Value, tInfo *typeInfo) error { //nolin
}
}
// Create new value for the pointer v to point to if CBOR value is not nil/undefined.
if !d.nextCBORNil() {
for v.Kind() == reflect.Ptr {
if v.IsNil() {
if !v.CanSet() {
d.skip()
return errors.New("cbor: cannot set new value for " + v.Type().String())
}
v.Set(reflect.New(v.Type().Elem()))
// Create new value for the pointer v to point to.
// At this point, CBOR value is not nil/undefined if v is a pointer.
for v.Kind() == reflect.Ptr {
if v.IsNil() {
if !v.CanSet() {
d.skip()
return errors.New("cbor: cannot set new value for " + v.Type().String())
}
v = v.Elem()
v.Set(reflect.New(v.Type().Elem()))
}
v = v.Elem()
}
// Strip self-described CBOR tag number.
@ -872,6 +1051,7 @@ func (d *decoder) parseToValue(v reflect.Value, tInfo *typeInfo) error { //nolin
case cborTypePositiveInt:
_, _, val := d.getHead()
return fillPositiveInt(t, val, v)
case cborTypeNegativeInt:
_, _, val := d.getHead()
if val > math.MaxInt64 {
@ -893,15 +1073,18 @@ func (d *decoder) parseToValue(v reflect.Value, tInfo *typeInfo) error { //nolin
}
nValue := int64(-1) ^ int64(val)
return fillNegativeInt(t, nValue, v)
case cborTypeByteString:
b := d.parseByteString()
return fillByteString(t, b, v)
b, copied := d.parseByteString()
return fillByteString(t, b, !copied, v, d.dm.byteStringToString)
case cborTypeTextString:
b, err := d.parseTextString()
if err != nil {
return err
}
return fillTextString(t, b, v)
case cborTypePrimitives:
_, ai, val := d.getHead()
switch ai {
@ -915,11 +1098,6 @@ func (d *decoder) parseToValue(v reflect.Value, tInfo *typeInfo) error { //nolin
f := math.Float64frombits(val)
return fillFloat(t, f, v)
default: // ai <= 24
// Decode simple values (including false, true, null, and undefined)
if tInfo.nonPtrType == typeSimpleValue {
v.SetUint(val)
return nil
}
switch ai {
case 20, 21:
return fillBool(t, ai == 21, v)
@ -935,7 +1113,7 @@ func (d *decoder) parseToValue(v reflect.Value, tInfo *typeInfo) error { //nolin
switch tagNum {
case 2:
// Bignum (tag 2) can be decoded to uint, int, float, slice, array, or big.Int.
b := d.parseByteString()
b, copied := d.parseByteString()
bi := new(big.Int).SetBytes(b)
if tInfo.nonPtrType == typeBigInt {
@ -943,7 +1121,7 @@ func (d *decoder) parseToValue(v reflect.Value, tInfo *typeInfo) error { //nolin
return nil
}
if tInfo.nonPtrKind == reflect.Slice || tInfo.nonPtrKind == reflect.Array {
return fillByteString(t, b, v)
return fillByteString(t, b, !copied, v, ByteStringToStringForbidden)
}
if bi.IsUint64() {
return fillPositiveInt(t, bi.Uint64(), v)
@ -955,7 +1133,7 @@ func (d *decoder) parseToValue(v reflect.Value, tInfo *typeInfo) error { //nolin
}
case 3:
// Bignum (tag 3) can be decoded to int, float, slice, array, or big.Int.
b := d.parseByteString()
b, copied := d.parseByteString()
bi := new(big.Int).SetBytes(b)
bi.Add(bi, big.NewInt(1))
bi.Neg(bi)
@ -965,7 +1143,7 @@ func (d *decoder) parseToValue(v reflect.Value, tInfo *typeInfo) error { //nolin
return nil
}
if tInfo.nonPtrKind == reflect.Slice || tInfo.nonPtrKind == reflect.Array {
return fillByteString(t, b, v)
return fillByteString(t, b, !copied, v, ByteStringToStringForbidden)
}
if bi.IsInt64() {
return fillNegativeInt(t, bi.Int64(), v)
@ -977,6 +1155,7 @@ func (d *decoder) parseToValue(v reflect.Value, tInfo *typeInfo) error { //nolin
}
}
return d.parseToValue(v, tInfo)
case cborTypeArray:
if tInfo.nonPtrKind == reflect.Slice {
return d.parseArrayToSlice(v, tInfo)
@ -987,6 +1166,7 @@ func (d *decoder) parseToValue(v reflect.Value, tInfo *typeInfo) error { //nolin
}
d.skip()
return &UnmarshalTypeError{CBORType: t.String(), GoType: tInfo.nonPtrType.String()}
case cborTypeMap:
if tInfo.nonPtrKind == reflect.Struct {
return d.parseMapToStruct(v, tInfo)
@ -996,6 +1176,7 @@ func (d *decoder) parseToValue(v reflect.Value, tInfo *typeInfo) error { //nolin
d.skip()
return &UnmarshalTypeError{CBORType: t.String(), GoType: tInfo.nonPtrType.String()}
}
return nil
}
@ -1136,30 +1317,87 @@ func (d *decoder) parse(skipSelfDescribedTag bool) (interface{}, error) { //noli
switch t {
case cborTypePositiveInt:
_, _, val := d.getHead()
if d.dm.intDec == IntDecConvertNone {
switch d.dm.intDec {
case IntDecConvertNone:
return val, nil
}
if val > math.MaxInt64 {
return nil, &UnmarshalTypeError{
CBORType: t.String(),
GoType: reflect.TypeOf(int64(0)).String(),
errorMsg: strconv.FormatUint(val, 10) + " overflows Go's int64",
case IntDecConvertSigned, IntDecConvertSignedOrFail:
if val > math.MaxInt64 {
return nil, &UnmarshalTypeError{
CBORType: t.String(),
GoType: reflect.TypeOf(int64(0)).String(),
errorMsg: strconv.FormatUint(val, 10) + " overflows Go's int64",
}
}
return int64(val), nil
case IntDecConvertSignedOrBigInt:
if val > math.MaxInt64 {
bi := new(big.Int).SetUint64(val)
if d.dm.bigIntDec == BigIntDecodePointer {
return bi, nil
}
return *bi, nil
}
return int64(val), nil
default:
// not reachable
}
return int64(val), nil
case cborTypeNegativeInt:
_, _, val := d.getHead()
if val > math.MaxInt64 {
// CBOR negative integer value overflows Go int64, use big.Int instead.
bi := new(big.Int).SetUint64(val)
bi.Add(bi, big.NewInt(1))
bi.Neg(bi)
if d.dm.intDec == IntDecConvertSignedOrFail {
return nil, &UnmarshalTypeError{
CBORType: t.String(),
GoType: reflect.TypeOf(int64(0)).String(),
errorMsg: bi.String() + " overflows Go's int64",
}
}
if d.dm.bigIntDec == BigIntDecodePointer {
return bi, nil
}
return *bi, nil
}
nValue := int64(-1) ^ int64(val)
return nValue, nil
case cborTypeByteString:
return d.parseByteString(), nil
switch d.dm.defaultByteStringType {
case nil, typeByteSlice:
b, copied := d.parseByteString()
if copied {
return b, nil
}
clone := make([]byte, len(b))
copy(clone, b)
return clone, nil
case typeString:
b, _ := d.parseByteString()
return string(b), nil
default:
b, copied := d.parseByteString()
if copied || d.dm.defaultByteStringType.Kind() == reflect.String {
// Avoid an unnecessary copy since the conversion to string must
// copy the underlying bytes.
return reflect.ValueOf(b).Convert(d.dm.defaultByteStringType).Interface(), nil
}
clone := make([]byte, len(b))
copy(clone, b)
return reflect.ValueOf(clone).Convert(d.dm.defaultByteStringType).Interface(), nil
}
case cborTypeTextString:
b, err := d.parseTextString()
if err != nil {
@ -1176,14 +1414,22 @@ func (d *decoder) parse(skipSelfDescribedTag bool) (interface{}, error) { //noli
d.off = tagOff
return d.parseToTime()
case 2:
b := d.parseByteString()
b, _ := d.parseByteString()
bi := new(big.Int).SetBytes(b)
if d.dm.bigIntDec == BigIntDecodePointer {
return bi, nil
}
return *bi, nil
case 3:
b := d.parseByteString()
b, _ := d.parseByteString()
bi := new(big.Int).SetBytes(b)
bi.Add(bi, big.NewInt(1))
bi.Neg(bi)
if d.dm.bigIntDec == BigIntDecodePointer {
return bi, nil
}
return *bi, nil
}
@ -1211,6 +1457,9 @@ func (d *decoder) parse(skipSelfDescribedTag bool) (interface{}, error) { //noli
if err != nil {
return nil, err
}
if d.dm.unrecognizedTagToAny == UnrecognizedTagContentToAny {
return content, nil
}
return Tag{tagNum, content}, nil
case cborTypePrimitives:
_, ai, val := d.getHead()
@ -1248,15 +1497,16 @@ func (d *decoder) parse(skipSelfDescribedTag bool) (interface{}, error) { //noli
return nil, nil
}
// parseByteString parses CBOR encoded byte string. It returns a byte slice
// pointing to a copy of parsed data.
func (d *decoder) parseByteString() []byte {
// parseByteString parses a CBOR encoded byte string. The returned byte slice
// may be backed directly by the input. The second return value will be true if
// and only if the slice is backed by a copy of the input. Callers are
// responsible for making a copy if necessary.
func (d *decoder) parseByteString() ([]byte, bool) {
_, ai, val := d.getHead()
if ai != 31 {
b := make([]byte, int(val))
copy(b, d.data[d.off:d.off+int(val)])
b := d.data[d.off : d.off+int(val)]
d.off += int(val)
return b
return b, false
}
// Process indefinite length string chunks.
b := []byte{}
@ -1265,7 +1515,7 @@ func (d *decoder) parseByteString() []byte {
b = append(b, d.data[d.off:d.off+int(val)]...)
d.off += int(val)
}
return b
return b, true
}
// parseTextString parses CBOR encoded text string. It returns a byte slice
@ -1659,15 +1909,19 @@ func (d *decoder) parseMapToStruct(v reflect.Value, tInfo *typeInfo) error { //n
var k interface{} // Used by duplicate map key detection
t := d.nextCBORType()
if t == cborTypeTextString {
if t == cborTypeTextString || (t == cborTypeByteString && d.dm.fieldNameByteString == FieldNameByteStringAllowed) {
var keyBytes []byte
keyBytes, lastErr = d.parseTextString()
if lastErr != nil {
if err == nil {
err = lastErr
if t == cborTypeTextString {
keyBytes, lastErr = d.parseTextString()
if lastErr != nil {
if err == nil {
err = lastErr
}
d.skip() // skip value
continue
}
d.skip() // skip value
continue
} else { // cborTypeByteString
keyBytes, _ = d.parseByteString()
}
keyLen := len(keyBytes)
@ -1681,7 +1935,7 @@ func (d *decoder) parseMapToStruct(v reflect.Value, tInfo *typeInfo) error { //n
}
}
// Find field with case-insensitive match
if f == nil {
if f == nil && d.dm.fieldNameMatching == FieldNameMatchingPreferCaseSensitive {
keyString := string(keyBytes)
for i := 0; i < len(structType.fields); i++ {
fld := structType.fields[i]
@ -1954,9 +2208,11 @@ var (
typeBigInt = reflect.TypeOf(big.Int{})
typeUnmarshaler = reflect.TypeOf((*Unmarshaler)(nil)).Elem()
typeBinaryUnmarshaler = reflect.TypeOf((*encoding.BinaryUnmarshaler)(nil)).Elem()
typeString = reflect.TypeOf("")
typeByteSlice = reflect.TypeOf([]byte(nil))
)
func fillNil(t cborType, v reflect.Value) error {
func fillNil(_ cborType, v reflect.Value) error {
switch v.Kind() {
case reflect.Slice, reflect.Map, reflect.Interface, reflect.Ptr:
v.Set(reflect.Zero(v.Type()))
@ -2056,18 +2312,31 @@ func fillFloat(t cborType, val float64, v reflect.Value) error {
return &UnmarshalTypeError{CBORType: t.String(), GoType: v.Type().String()}
}
func fillByteString(t cborType, val []byte, v reflect.Value) error {
func fillByteString(t cborType, val []byte, shared bool, v reflect.Value, bsts ByteStringToStringMode) error {
if reflect.PtrTo(v.Type()).Implements(typeBinaryUnmarshaler) {
if v.CanAddr() {
v = v.Addr()
if u, ok := v.Interface().(encoding.BinaryUnmarshaler); ok {
// The contract of BinaryUnmarshaler forbids
// retaining the input bytes, so no copying is
// required even if val is shared.
return u.UnmarshalBinary(val)
}
}
return errors.New("cbor: cannot set new value for " + v.Type().String())
}
if bsts == ByteStringToStringAllowed && v.Kind() == reflect.String {
v.SetString(string(val))
return nil
}
if v.Kind() == reflect.Slice && v.Type().Elem().Kind() == reflect.Uint8 {
v.SetBytes(val)
src := val
if shared {
// SetBytes shares the underlying bytes of the source slice.
src = make([]byte, len(val))
copy(src, val)
}
v.SetBytes(src)
return nil
}
if v.Kind() == reflect.Array && v.Type().Elem().Kind() == reflect.Uint8 {

View File

@ -354,7 +354,7 @@ func (di *diagnose) item() error { //nolint:gocyclo
return di.writeString(strconv.FormatInt(nValue, 10))
case cborTypeByteString:
b := di.d.parseByteString()
b, _ := di.d.parseByteString()
return di.encodeByteString(b)
case cborTypeTextString:
@ -418,7 +418,7 @@ func (di *diagnose) item() error { //nolint:gocyclo
return errors.New("cbor: tag number 2 must be followed by byte string, got " + nt.String())
}
b := di.d.parseByteString()
b, _ := di.d.parseByteString()
bi := new(big.Int).SetBytes(b)
return di.writeString(bi.String())
@ -427,7 +427,7 @@ func (di *diagnose) item() error { //nolint:gocyclo
return errors.New("cbor: tag number 3 must be followed by byte string, got " + nt.String())
}
b := di.d.parseByteString()
b, _ := di.d.parseByteString()
bi := new(big.Int).SetBytes(b)
bi.Add(bi, big.NewInt(1))
bi.Neg(bi)

View File

@ -17,17 +17,17 @@ For example, "toarray" tag makes struct fields encode to CBOR array elements. A
Latest docs can be viewed at https://github.com/fxamacker/cbor#cbor-library-in-go
Basics
# Basics
The Quick Start guide is at https://github.com/fxamacker/cbor#quick-start
Function signatures identical to encoding/json include:
Marshal, Unmarshal, NewEncoder, NewDecoder, (*Encoder).Encode, (*Decoder).Decode.
Marshal, Unmarshal, NewEncoder, NewDecoder, (*Encoder).Encode, (*Decoder).Decode.
Standard interfaces include:
BinaryMarshaler, BinaryUnmarshaler, Marshaler, and Unmarshaler.
BinaryMarshaler, BinaryUnmarshaler, Marshaler, and Unmarshaler.
Custom encoding and decoding is possible by implementing standard interfaces for
user-defined Go types.
@ -39,9 +39,9 @@ creating modes from options at runtime.
EncMode and DecMode interfaces are created from EncOptions or DecOptions structs.
em, err := cbor.EncOptions{...}.EncMode()
em, err := cbor.CanonicalEncOptions().EncMode()
em, err := cbor.CTAP2EncOptions().EncMode()
em, err := cbor.EncOptions{...}.EncMode()
em, err := cbor.CanonicalEncOptions().EncMode()
em, err := cbor.CTAP2EncOptions().EncMode()
Modes use immutable options to avoid side-effects and simplify concurrency. Behavior of
modes won't accidentally change at runtime after they're created.
@ -50,55 +50,55 @@ Modes are intended to be reused and are safe for concurrent use.
EncMode and DecMode Interfaces
// EncMode interface uses immutable options and is safe for concurrent use.
type EncMode interface {
Marshal(v interface{}) ([]byte, error)
NewEncoder(w io.Writer) *Encoder
EncOptions() EncOptions // returns copy of options
}
// EncMode interface uses immutable options and is safe for concurrent use.
type EncMode interface {
Marshal(v interface{}) ([]byte, error)
NewEncoder(w io.Writer) *Encoder
EncOptions() EncOptions // returns copy of options
}
// DecMode interface uses immutable options and is safe for concurrent use.
type DecMode interface {
Unmarshal(data []byte, v interface{}) error
NewDecoder(r io.Reader) *Decoder
DecOptions() DecOptions // returns copy of options
}
// DecMode interface uses immutable options and is safe for concurrent use.
type DecMode interface {
Unmarshal(data []byte, v interface{}) error
NewDecoder(r io.Reader) *Decoder
DecOptions() DecOptions // returns copy of options
}
Using Default Encoding Mode
b, err := cbor.Marshal(v)
b, err := cbor.Marshal(v)
encoder := cbor.NewEncoder(w)
err = encoder.Encode(v)
encoder := cbor.NewEncoder(w)
err = encoder.Encode(v)
Using Default Decoding Mode
err := cbor.Unmarshal(b, &v)
err := cbor.Unmarshal(b, &v)
decoder := cbor.NewDecoder(r)
err = decoder.Decode(&v)
decoder := cbor.NewDecoder(r)
err = decoder.Decode(&v)
Creating and Using Encoding Modes
// Create EncOptions using either struct literal or a function.
opts := cbor.CanonicalEncOptions()
// Create EncOptions using either struct literal or a function.
opts := cbor.CanonicalEncOptions()
// If needed, modify encoding options
opts.Time = cbor.TimeUnix
// If needed, modify encoding options
opts.Time = cbor.TimeUnix
// Create reusable EncMode interface with immutable options, safe for concurrent use.
em, err := opts.EncMode()
// Create reusable EncMode interface with immutable options, safe for concurrent use.
em, err := opts.EncMode()
// Use EncMode like encoding/json, with same function signatures.
b, err := em.Marshal(v)
// or
encoder := em.NewEncoder(w)
err := encoder.Encode(v)
// Use EncMode like encoding/json, with same function signatures.
b, err := em.Marshal(v)
// or
encoder := em.NewEncoder(w)
err := encoder.Encode(v)
// NOTE: Both em.Marshal(v) and encoder.Encode(v) use encoding options
// specified during creation of em (encoding mode).
// NOTE: Both em.Marshal(v) and encoder.Encode(v) use encoding options
// specified during creation of em (encoding mode).
CBOR Options
# CBOR Options
Predefined Encoding Options: https://github.com/fxamacker/cbor#predefined-encoding-options
@ -106,7 +106,7 @@ Encoding Options: https://github.com/fxamacker/cbor#encoding-options
Decoding Options: https://github.com/fxamacker/cbor#decoding-options
Struct Tags
# Struct Tags
Struct tags like `cbor:"name,omitempty"` and `json:"name,omitempty"` work as expected.
If both struct tags are specified then `cbor` is used.
@ -121,9 +121,9 @@ https://raw.githubusercontent.com/fxamacker/images/master/cbor/v2.0.0/cbor_easy_
Struct tags are listed at https://github.com/fxamacker/cbor#struct-tags-1
Tests and Fuzzing
# Tests and Fuzzing
Over 375 tests are included in this package. Cover-guided fuzzing is handled by
fxamacker/cbor-fuzz.
a private fuzzer that replaced fxamacker/cbor-fuzz years ago.
*/
package cbor

View File

@ -110,6 +110,16 @@ func (e *UnsupportedTypeError) Error() string {
return "cbor: unsupported type: " + e.Type.String()
}
// UnsupportedValueError is returned by Marshal when attempting to encode an
// unsupported value.
type UnsupportedValueError struct {
msg string
}
func (e *UnsupportedValueError) Error() string {
return "cbor: unsupported value: " + e.msg
}
// SortMode identifies supported sorting order.
type SortMode int
@ -143,7 +153,28 @@ const (
)
func (sm SortMode) valid() bool {
return sm < maxSortMode
return sm >= 0 && sm < maxSortMode
}
// StringMode specifies how to encode Go string values.
type StringMode int
const (
// StringToTextString encodes Go string to CBOR text string (major type 3).
StringToTextString StringMode = iota
// StringToByteString encodes Go string to CBOR byte string (major type 2).
StringToByteString
)
func (st StringMode) cborType() (cborType, error) {
switch st {
case StringToTextString:
return cborTypeTextString, nil
case StringToByteString:
return cborTypeByteString, nil
}
return 0, errors.New("cbor: invalid StringType " + strconv.Itoa(int(st)))
}
// ShortestFloatMode specifies which floating-point format should
@ -168,7 +199,7 @@ const (
)
func (sfm ShortestFloatMode) valid() bool {
return sfm < maxShortestFloat
return sfm >= 0 && sfm < maxShortestFloat
}
// NaNConvertMode specifies how to encode NaN and overrides ShortestFloatMode.
@ -196,7 +227,7 @@ const (
)
func (ncm NaNConvertMode) valid() bool {
return ncm < maxNaNConvert
return ncm >= 0 && ncm < maxNaNConvert
}
// InfConvertMode specifies how to encode Infinity and overrides ShortestFloatMode.
@ -214,7 +245,7 @@ const (
)
func (icm InfConvertMode) valid() bool {
return icm < maxInfConvert
return icm >= 0 && icm < maxInfConvert
}
// TimeMode specifies how to encode time.Time values.
@ -241,7 +272,7 @@ const (
)
func (tm TimeMode) valid() bool {
return tm < maxTimeMode
return tm >= 0 && tm < maxTimeMode
}
// BigIntConvertMode specifies how to encode big.Int values.
@ -261,7 +292,7 @@ const (
)
func (bim BigIntConvertMode) valid() bool {
return bim < maxBigIntConvert
return bim >= 0 && bim < maxBigIntConvert
}
// NilContainersMode specifies how to encode nil slices and maps.
@ -280,7 +311,50 @@ const (
)
func (m NilContainersMode) valid() bool {
return m < maxNilContainersMode
return m >= 0 && m < maxNilContainersMode
}
// OmitEmptyMode specifies how to encode struct fields with omitempty tag.
// The default behavior omits if field value would encode as empty CBOR value.
type OmitEmptyMode int
const (
// OmitEmptyCBORValue specifies that struct fields tagged with "omitempty"
// should be omitted from encoding if the field would be encoded as an empty
// CBOR value, such as CBOR false, 0, 0.0, nil, empty byte, empty string,
// empty array, or empty map.
OmitEmptyCBORValue OmitEmptyMode = iota
// OmitEmptyGoValue specifies that struct fields tagged with "omitempty"
// should be omitted from encoding if the field has an empty Go value,
// defined as false, 0, 0.0, a nil pointer, a nil interface value, and
// any empty array, slice, map, or string.
// This behavior is the same as the current (aka v1) encoding/json package
// included in Go.
OmitEmptyGoValue
maxOmitEmptyMode
)
func (om OmitEmptyMode) valid() bool {
return om >= 0 && om < maxOmitEmptyMode
}
// FieldNameMode specifies the CBOR type to use when encoding struct field names.
type FieldNameMode int
const (
// FieldNameToTextString encodes struct fields to CBOR text string (major type 3).
FieldNameToTextString FieldNameMode = iota
// FieldNameToTextString encodes struct fields to CBOR byte string (major type 2).
FieldNameToByteString
maxFieldNameMode
)
func (fnm FieldNameMode) valid() bool {
return fnm >= 0 && fnm < maxFieldNameMode
}
// EncOptions specifies encoding options.
@ -316,24 +390,34 @@ type EncOptions struct {
// TagsMd specifies whether to allow CBOR tags (major type 6).
TagsMd TagsMode
// OmitEmptyMode specifies how to encode struct fields with omitempty tag.
OmitEmpty OmitEmptyMode
// String specifies which CBOR type to use when encoding Go strings.
// - CBOR text string (major type 3) is default
// - CBOR byte string (major type 2)
String StringMode
// FieldName specifies the CBOR type to use when encoding struct field names.
FieldName FieldNameMode
}
// CanonicalEncOptions returns EncOptions for "Canonical CBOR" encoding,
// defined in RFC 7049 Section 3.9 with the following rules:
//
// 1. "Integers must be as small as possible."
// 2. "The expression of lengths in major types 2 through 5 must be as short as possible."
// 3. The keys in every map must be sorted in length-first sorting order.
// See SortLengthFirst for details.
// 4. "Indefinite-length items must be made into definite-length items."
// 5. "If a protocol allows for IEEE floats, then additional canonicalization rules might
// need to be added. One example rule might be to have all floats start as a 64-bit
// float, then do a test conversion to a 32-bit float; if the result is the same numeric
// value, use the shorter value and repeat the process with a test conversion to a
// 16-bit float. (This rule selects 16-bit float for positive and negative Infinity
// as well.) Also, there are many representations for NaN. If NaN is an allowed value,
// it must always be represented as 0xf97e00."
//
// 1. "Integers must be as small as possible."
// 2. "The expression of lengths in major types 2 through 5 must be as short as possible."
// 3. The keys in every map must be sorted in length-first sorting order.
// See SortLengthFirst for details.
// 4. "Indefinite-length items must be made into definite-length items."
// 5. "If a protocol allows for IEEE floats, then additional canonicalization rules might
// need to be added. One example rule might be to have all floats start as a 64-bit
// float, then do a test conversion to a 32-bit float; if the result is the same numeric
// value, use the shorter value and repeat the process with a test conversion to a
// 16-bit float. (This rule selects 16-bit float for positive and negative Infinity
// as well.) Also, there are many representations for NaN. If NaN is an allowed value,
// it must always be represented as 0xf97e00."
func CanonicalEncOptions() EncOptions {
return EncOptions{
Sort: SortCanonical,
@ -347,14 +431,13 @@ func CanonicalEncOptions() EncOptions {
// CTAP2EncOptions returns EncOptions for "CTAP2 Canonical CBOR" encoding,
// defined in CTAP specification, with the following rules:
//
// 1. "Integers must be encoded as small as possible."
// 2. "The representations of any floating-point values are not changed."
// 3. "The expression of lengths in major types 2 through 5 must be as short as possible."
// 4. "Indefinite-length items must be made into definite-length items.""
// 5. The keys in every map must be sorted in bytewise lexicographic order.
// See SortBytewiseLexical for details.
// 6. "Tags as defined in Section 2.4 in [RFC7049] MUST NOT be present."
//
// 1. "Integers must be encoded as small as possible."
// 2. "The representations of any floating-point values are not changed."
// 3. "The expression of lengths in major types 2 through 5 must be as short as possible."
// 4. "Indefinite-length items must be made into definite-length items.""
// 5. The keys in every map must be sorted in bytewise lexicographic order.
// See SortBytewiseLexical for details.
// 6. "Tags as defined in Section 2.4 in [RFC7049] MUST NOT be present."
func CTAP2EncOptions() EncOptions {
return EncOptions{
Sort: SortCTAP2,
@ -369,14 +452,13 @@ func CTAP2EncOptions() EncOptions {
// CoreDetEncOptions returns EncOptions for "Core Deterministic" encoding,
// defined in RFC 7049bis with the following rules:
//
// 1. "Preferred serialization MUST be used. In particular, this means that arguments
// (see Section 3) for integers, lengths in major types 2 through 5, and tags MUST
// be as short as possible"
// "Floating point values also MUST use the shortest form that preserves the value"
// 2. "Indefinite-length items MUST NOT appear."
// 3. "The keys in every map MUST be sorted in the bytewise lexicographic order of
// their deterministic encodings."
//
// 1. "Preferred serialization MUST be used. In particular, this means that arguments
// (see Section 3) for integers, lengths in major types 2 through 5, and tags MUST
// be as short as possible"
// "Floating point values also MUST use the shortest form that preserves the value"
// 2. "Indefinite-length items MUST NOT appear."
// 3. "The keys in every map MUST be sorted in the bytewise lexicographic order of
// their deterministic encodings."
func CoreDetEncOptions() EncOptions {
return EncOptions{
Sort: SortCoreDeterministic,
@ -390,19 +472,18 @@ func CoreDetEncOptions() EncOptions {
// PreferredUnsortedEncOptions returns EncOptions for "Preferred Serialization" encoding,
// defined in RFC 7049bis with the following rules:
//
// 1. "The preferred serialization always uses the shortest form of representing the argument
// (Section 3);"
// 2. "it also uses the shortest floating-point encoding that preserves the value being
// encoded (see Section 5.5)."
// "The preferred encoding for a floating-point value is the shortest floating-point encoding
// that preserves its value, e.g., 0xf94580 for the number 5.5, and 0xfa45ad9c00 for the
// number 5555.5, unless the CBOR-based protocol specifically excludes the use of the shorter
// floating-point encodings. For NaN values, a shorter encoding is preferred if zero-padding
// the shorter significand towards the right reconstitutes the original NaN value (for many
// applications, the single NaN encoding 0xf97e00 will suffice)."
// 3. "Definite length encoding is preferred whenever the length is known at the time the
// serialization of the item starts."
//
// 1. "The preferred serialization always uses the shortest form of representing the argument
// (Section 3);"
// 2. "it also uses the shortest floating-point encoding that preserves the value being
// encoded (see Section 5.5)."
// "The preferred encoding for a floating-point value is the shortest floating-point encoding
// that preserves its value, e.g., 0xf94580 for the number 5.5, and 0xfa45ad9c00 for the
// number 5555.5, unless the CBOR-based protocol specifically excludes the use of the shorter
// floating-point encodings. For NaN values, a shorter encoding is preferred if zero-padding
// the shorter significand towards the right reconstitutes the original NaN value (for many
// applications, the single NaN encoding 0xf97e00 will suffice)."
// 3. "Definite length encoding is preferred whenever the length is known at the time the
// serialization of the item starts."
func PreferredUnsortedEncOptions() EncOptions {
return EncOptions{
Sort: SortNone,
@ -495,17 +576,31 @@ func (opts EncOptions) encMode() (*encMode, error) {
if opts.TagsMd == TagsForbidden && opts.TimeTag == EncTagRequired {
return nil, errors.New("cbor: cannot set TagsMd to TagsForbidden when TimeTag is EncTagRequired")
}
if !opts.OmitEmpty.valid() {
return nil, errors.New("cbor: invalid OmitEmpty " + strconv.Itoa(int(opts.OmitEmpty)))
}
stringMajorType, err := opts.String.cborType()
if err != nil {
return nil, err
}
if !opts.FieldName.valid() {
return nil, errors.New("cbor: invalid FieldName " + strconv.Itoa(int(opts.FieldName)))
}
em := encMode{
sort: opts.Sort,
shortestFloat: opts.ShortestFloat,
nanConvert: opts.NaNConvert,
infConvert: opts.InfConvert,
bigIntConvert: opts.BigIntConvert,
time: opts.Time,
timeTag: opts.TimeTag,
indefLength: opts.IndefLength,
nilContainers: opts.NilContainers,
tagsMd: opts.TagsMd,
sort: opts.Sort,
shortestFloat: opts.ShortestFloat,
nanConvert: opts.NaNConvert,
infConvert: opts.InfConvert,
bigIntConvert: opts.BigIntConvert,
time: opts.Time,
timeTag: opts.TimeTag,
indefLength: opts.IndefLength,
nilContainers: opts.NilContainers,
tagsMd: opts.TagsMd,
omitEmpty: opts.OmitEmpty,
stringType: opts.String,
stringMajorType: stringMajorType,
fieldName: opts.FieldName,
}
return &em, nil
}
@ -518,20 +613,24 @@ type EncMode interface {
}
type encMode struct {
tags tagProvider
sort SortMode
shortestFloat ShortestFloatMode
nanConvert NaNConvertMode
infConvert InfConvertMode
bigIntConvert BigIntConvertMode
time TimeMode
timeTag EncTagMode
indefLength IndefLengthMode
nilContainers NilContainersMode
tagsMd TagsMode
tags tagProvider
sort SortMode
shortestFloat ShortestFloatMode
nanConvert NaNConvertMode
infConvert InfConvertMode
bigIntConvert BigIntConvertMode
time TimeMode
timeTag EncTagMode
indefLength IndefLengthMode
nilContainers NilContainersMode
tagsMd TagsMode
omitEmpty OmitEmptyMode
stringType StringMode
stringMajorType cborType
fieldName FieldNameMode
}
var defaultEncMode = &encMode{}
var defaultEncMode, _ = EncOptions{}.encMode()
// EncOptions returns user specified options used to create this EncMode.
func (em *encMode) EncOptions() EncOptions {
@ -544,7 +643,11 @@ func (em *encMode) EncOptions() EncOptions {
Time: em.time,
TimeTag: em.timeTag,
IndefLength: em.indefLength,
NilContainers: em.nilContainers,
TagsMd: em.tagsMd,
OmitEmpty: em.omitEmpty,
String: em.stringType,
FieldName: em.fieldName,
}
}
@ -604,7 +707,7 @@ func putEncoderBuffer(e *encoderBuffer) {
}
type encodeFunc func(e *encoderBuffer, em *encMode, v reflect.Value) error
type isEmptyFunc func(v reflect.Value) (empty bool, err error)
type isEmptyFunc func(em *encMode, v reflect.Value) (empty bool, err error)
var (
cborFalse = []byte{0xf4}
@ -841,7 +944,7 @@ func encodeString(e *encoderBuffer, em *encMode, v reflect.Value) error {
e.Write(b)
}
s := v.String()
encodeHead(e, byte(cborTypeTextString), uint64(len(s)))
encodeHead(e, byte(em.stringMajorType), uint64(len(s)))
e.WriteString(s)
return nil
}
@ -871,8 +974,13 @@ func (ae arrayEncodeFunc) encode(e *encoderBuffer, em *encMode, v reflect.Value)
return nil
}
// encodeKeyValueFunc encodes key/value pairs in map (v).
// If kvs is provided (having the same length as v), length of encoded key and value are stored in kvs.
// kvs is used for canonical encoding of map.
type encodeKeyValueFunc func(e *encoderBuffer, em *encMode, v reflect.Value, kvs []keyValue) error
type mapEncodeFunc struct {
kf, ef encodeFunc
e encodeKeyValueFunc
}
func (me mapEncodeFunc) encode(e *encoderBuffer, em *encMode, v reflect.Value) error {
@ -891,16 +999,8 @@ func (me mapEncodeFunc) encode(e *encoderBuffer, em *encMode, v reflect.Value) e
return me.encodeCanonical(e, em, v)
}
encodeHead(e, byte(cborTypeMap), uint64(mlen))
iter := v.MapRange()
for iter.Next() {
if err := me.kf(e, em, iter.Key()); err != nil {
return err
}
if err := me.ef(e, em, iter.Value()); err != nil {
return err
}
}
return nil
return me.e(e, em, v, nil)
}
type keyValue struct {
@ -969,26 +1069,17 @@ func putKeyValues(x *[]keyValue) {
}
func (me mapEncodeFunc) encodeCanonical(e *encoderBuffer, em *encMode, v reflect.Value) error {
kve := getEncoderBuffer() // accumulated cbor encoded key-values
kve := getEncoderBuffer() // accumulated cbor encoded key-values
defer putEncoderBuffer(kve)
kvsp := getKeyValues(v.Len()) // for sorting keys
defer putKeyValues(kvsp)
kvs := *kvsp
iter := v.MapRange()
for i := 0; iter.Next(); i++ {
off := kve.Len()
if err := me.kf(kve, em, iter.Key()); err != nil {
putEncoderBuffer(kve)
putKeyValues(kvsp)
return err
}
n1 := kve.Len() - off
if err := me.ef(kve, em, iter.Value()); err != nil {
putEncoderBuffer(kve)
putKeyValues(kvsp)
return err
}
n2 := kve.Len() - off
// Save key and keyvalue length to create slice later.
kvs[i] = keyValue{keyLen: n1, keyValueLen: n2}
err := me.e(kve, em, v, kvs)
if err != nil {
return err
}
b := kve.Bytes()
@ -1009,8 +1100,6 @@ func (me mapEncodeFunc) encodeCanonical(e *encoderBuffer, em *encMode, v reflect
e.Write(kvs[i].keyValueCBORData)
}
putEncoderBuffer(kve)
putKeyValues(kvsp)
return nil
}
@ -1061,7 +1150,11 @@ func encodeFixedLengthStruct(e *encoderBuffer, em *encMode, v reflect.Value, fld
for i := 0; i < len(flds); i++ {
f := flds[i]
e.Write(f.cborName)
if !f.keyAsInt && em.fieldName == FieldNameToByteString {
e.Write(f.cborNameByteString)
} else { // int or text string
e.Write(f.cborName)
}
fv := v.Field(f.idx[0])
if err := f.ef(e, em, fv); err != nil {
@ -1102,9 +1195,8 @@ func encodeStruct(e *encoderBuffer, em *encMode, v reflect.Value) (err error) {
continue
}
}
if f.omitEmpty {
empty, err := f.ief(fv)
empty, err := f.ief(em, fv)
if err != nil {
putEncoderBuffer(kve)
return err
@ -1114,7 +1206,11 @@ func encodeStruct(e *encoderBuffer, em *encMode, v reflect.Value) (err error) {
}
}
kve.Write(f.cborName)
if !f.keyAsInt && em.fieldName == FieldNameToByteString {
kve.Write(f.cborNameByteString)
} else { // int or text string
kve.Write(f.cborName)
}
if err := f.ef(kve, em, fv); err != nil {
putEncoderBuffer(kve)
@ -1270,19 +1366,7 @@ func encodeTag(e *encoderBuffer, em *encMode, v reflect.Value) error {
encodeHead(e, byte(cborTypeTag), t.Number)
// Marshal tag content
if err := encode(e, em, reflect.ValueOf(t.Content)); err != nil {
return err
}
return nil
}
func encodeSimpleValue(e *encoderBuffer, em *encMode, v reflect.Value) error {
if b := em.encTagBytes(v.Type()); b != nil {
e.Write(b)
}
encodeHead(e, byte(cborTypePrimitives), v.Uint())
return nil
return encode(e, em, reflect.ValueOf(t.Content))
}
func encodeHead(e *encoderBuffer, t byte, n uint64) {
@ -1327,7 +1411,7 @@ func getEncodeFuncInternal(t reflect.Type) (encodeFunc, isEmptyFunc) {
}
switch t {
case typeSimpleValue:
return encodeSimpleValue, isEmptyUint
return encodeMarshalerType, isEmptyUint
case typeTag:
return encodeTag, alwaysNotEmpty
case typeTime:
@ -1366,12 +1450,11 @@ func getEncodeFuncInternal(t reflect.Type) (encodeFunc, isEmptyFunc) {
}
return arrayEncodeFunc{f: f}.encode, isEmptySlice
case reflect.Map:
kf, _ := getEncodeFunc(t.Key())
ef, _ := getEncodeFunc(t.Elem())
if kf == nil || ef == nil {
f := getEncodeMapFunc(t)
if f == nil {
return nil, nil
}
return mapEncodeFunc{kf: kf, ef: ef}.encode, isEmptyMap
return f, isEmptyMap
case reflect.Struct:
// Get struct's special field "_" tag options
if f, ok := t.FieldByName("_"); ok {
@ -1409,52 +1492,56 @@ func getEncodeIndirectValueFunc(t reflect.Type) encodeFunc {
}
}
func alwaysNotEmpty(v reflect.Value) (empty bool, err error) {
func alwaysNotEmpty(_ *encMode, _ reflect.Value) (empty bool, err error) {
return false, nil
}
func isEmptyBool(v reflect.Value) (bool, error) {
func isEmptyBool(_ *encMode, v reflect.Value) (bool, error) {
return !v.Bool(), nil
}
func isEmptyInt(v reflect.Value) (bool, error) {
func isEmptyInt(_ *encMode, v reflect.Value) (bool, error) {
return v.Int() == 0, nil
}
func isEmptyUint(v reflect.Value) (bool, error) {
func isEmptyUint(_ *encMode, v reflect.Value) (bool, error) {
return v.Uint() == 0, nil
}
func isEmptyFloat(v reflect.Value) (bool, error) {
func isEmptyFloat(_ *encMode, v reflect.Value) (bool, error) {
return v.Float() == 0.0, nil
}
func isEmptyString(v reflect.Value) (bool, error) {
func isEmptyString(_ *encMode, v reflect.Value) (bool, error) {
return v.Len() == 0, nil
}
func isEmptySlice(v reflect.Value) (bool, error) {
func isEmptySlice(_ *encMode, v reflect.Value) (bool, error) {
return v.Len() == 0, nil
}
func isEmptyMap(v reflect.Value) (bool, error) {
func isEmptyMap(_ *encMode, v reflect.Value) (bool, error) {
return v.Len() == 0, nil
}
func isEmptyPtr(v reflect.Value) (bool, error) {
func isEmptyPtr(_ *encMode, v reflect.Value) (bool, error) {
return v.IsNil(), nil
}
func isEmptyIntf(v reflect.Value) (bool, error) {
func isEmptyIntf(_ *encMode, v reflect.Value) (bool, error) {
return v.IsNil(), nil
}
func isEmptyStruct(v reflect.Value) (bool, error) {
func isEmptyStruct(em *encMode, v reflect.Value) (bool, error) {
structType, err := getEncodingStructType(v.Type())
if err != nil {
return false, err
}
if em.omitEmpty == OmitEmptyGoValue {
return false, nil
}
if structType.toArray {
return len(structType.fields) == 0, nil
}
@ -1481,7 +1568,7 @@ func isEmptyStruct(v reflect.Value) (bool, error) {
}
}
empty, err := f.ief(fv)
empty, err := f.ief(em, fv)
if err != nil {
return false, err
}
@ -1492,7 +1579,7 @@ func isEmptyStruct(v reflect.Value) (bool, error) {
return true, nil
}
func isEmptyBinaryMarshaler(v reflect.Value) (bool, error) {
func isEmptyBinaryMarshaler(_ *encMode, v reflect.Value) (bool, error) {
m, ok := v.Interface().(encoding.BinaryMarshaler)
if !ok {
pv := reflect.New(v.Type())

79
vendor/github.com/fxamacker/cbor/v2/encode_map.go generated vendored Normal file
View File

@ -0,0 +1,79 @@
// Copyright (c) Faye Amacker. All rights reserved.
// Licensed under the MIT License. See LICENSE in the project root for license information.
//go:build go1.20
package cbor
import (
"reflect"
"sync"
)
type mapKeyValueEncodeFunc struct {
kf, ef encodeFunc
kpool, vpool sync.Pool
}
func (me *mapKeyValueEncodeFunc) encodeKeyValues(e *encoderBuffer, em *encMode, v reflect.Value, kvs []keyValue) error {
trackKeyValueLength := len(kvs) == v.Len()
iterk := me.kpool.Get().(*reflect.Value)
defer func() {
iterk.SetZero()
me.kpool.Put(iterk)
}()
iterv := me.vpool.Get().(*reflect.Value)
defer func() {
iterv.SetZero()
me.vpool.Put(iterv)
}()
iter := v.MapRange()
for i := 0; iter.Next(); i++ {
off := e.Len()
iterk.SetIterKey(iter)
iterv.SetIterValue(iter)
if err := me.kf(e, em, *iterk); err != nil {
return err
}
if trackKeyValueLength {
kvs[i].keyLen = e.Len() - off
}
if err := me.ef(e, em, *iterv); err != nil {
return err
}
if trackKeyValueLength {
kvs[i].keyValueLen = e.Len() - off
}
}
return nil
}
func getEncodeMapFunc(t reflect.Type) encodeFunc {
kf, _ := getEncodeFunc(t.Key())
ef, _ := getEncodeFunc(t.Elem())
if kf == nil || ef == nil {
return nil
}
mkv := &mapKeyValueEncodeFunc{
kf: kf,
ef: ef,
kpool: sync.Pool{
New: func() interface{} {
rk := reflect.New(t.Key()).Elem()
return &rk
},
},
vpool: sync.Pool{
New: func() interface{} {
rv := reflect.New(t.Elem()).Elem()
return &rv
},
},
}
return mapEncodeFunc{
e: mkv.encodeKeyValues,
}.encode
}

View File

@ -0,0 +1,51 @@
// Copyright (c) Faye Amacker. All rights reserved.
// Licensed under the MIT License. See LICENSE in the project root for license information.
//go:build !go1.20
package cbor
import (
"reflect"
)
type mapKeyValueEncodeFunc struct {
kf, ef encodeFunc
}
func (me *mapKeyValueEncodeFunc) encodeKeyValues(e *encoderBuffer, em *encMode, v reflect.Value, kvs []keyValue) error {
trackKeyValueLength := len(kvs) == v.Len()
iter := v.MapRange()
for i := 0; iter.Next(); i++ {
off := e.Len()
if err := me.kf(e, em, iter.Key()); err != nil {
return err
}
if trackKeyValueLength {
kvs[i].keyLen = e.Len() - off
}
if err := me.ef(e, em, iter.Value()); err != nil {
return err
}
if trackKeyValueLength {
kvs[i].keyValueLen = e.Len() - off
}
}
return nil
}
func getEncodeMapFunc(t reflect.Type) encodeFunc {
kf, _ := getEncodeFunc(t.Key())
ef, _ := getEncodeFunc(t.Elem())
if kf == nil || ef == nil {
return nil
}
mkv := &mapKeyValueEncodeFunc{kf: kf, ef: ef}
return mapEncodeFunc{
e: mkv.encodeKeyValues,
}.encode
}

View File

@ -1,13 +1,18 @@
package cbor
import "reflect"
import (
"errors"
"fmt"
"reflect"
)
// SimpleValue represents CBOR simple value.
// CBOR simple value is:
// * an extension point like CBOR tag.
// * a subset of CBOR major type 7 that isn't floating-point.
// * "identified by a number between 0 and 255, but distinct from that number itself".
// For example, "a simple value 2 is not equivalent to an integer 2" as a CBOR map key.
// - an extension point like CBOR tag.
// - a subset of CBOR major type 7 that isn't floating-point.
// - "identified by a number between 0 and 255, but distinct from that number itself".
// For example, "a simple value 2 is not equivalent to an integer 2" as a CBOR map key.
//
// CBOR simple values identified by 20..23 are: "false", "true" , "null", and "undefined".
// Other CBOR simple values are currently unassigned/reserved by IANA.
type SimpleValue uint8
@ -15,3 +20,50 @@ type SimpleValue uint8
var (
typeSimpleValue = reflect.TypeOf(SimpleValue(0))
)
// MarshalCBOR encodes SimpleValue as CBOR simple value (major type 7).
func (sv SimpleValue) MarshalCBOR() ([]byte, error) {
// RFC 8949 3.3. Floating-Point Numbers and Values with No Content says:
// "An encoder MUST NOT issue two-byte sequences that start with 0xf8
// (major type 7, additional information 24) and continue with a byte
// less than 0x20 (32 decimal). Such sequences are not well-formed.
// (This implies that an encoder cannot encode false, true, null, or
// undefined in two-byte sequences and that only the one-byte variants
// of these are well-formed; more generally speaking, each simple value
// only has a single representation variant)."
switch {
case sv <= 23:
return []byte{byte(cborTypePrimitives) | byte(sv)}, nil
case sv >= 32:
return []byte{byte(cborTypePrimitives) | byte(24), byte(sv)}, nil
default:
return nil, &UnsupportedValueError{msg: fmt.Sprintf("SimpleValue(%d)", sv)}
}
}
// UnmarshalCBOR decodes CBOR simple value (major type 7) to SimpleValue.
func (sv *SimpleValue) UnmarshalCBOR(data []byte) error {
if sv == nil {
return errors.New("cbor.SimpleValue: UnmarshalCBOR on nil pointer")
}
d := decoder{data: data, dm: defaultDecMode}
typ, ai, val := d.getHead()
if typ != cborTypePrimitives {
return &UnmarshalTypeError{CBORType: typ.String(), GoType: "SimpleValue"}
}
if ai > 24 {
return &UnmarshalTypeError{CBORType: typ.String(), GoType: "SimpleValue", errorMsg: "not simple values"}
}
// It is safe to cast val to uint8 here because
// - data is already verified to be well-formed CBOR simple value and
// - val is <= math.MaxUint8.
*sv = SimpleValue(val)
return nil
}

View File

@ -10,17 +10,18 @@ import (
)
type field struct {
name string
nameAsInt int64 // used to decoder to match field name with CBOR int
cborName []byte
idx []int
typ reflect.Type
ef encodeFunc
ief isEmptyFunc
typInfo *typeInfo // used to decoder to reuse type info
tagged bool // used to choose dominant field (at the same level tagged fields dominate untagged fields)
omitEmpty bool // used to skip empty field
keyAsInt bool // used to encode/decode field name as int
name string
nameAsInt int64 // used to decoder to match field name with CBOR int
cborName []byte
cborNameByteString []byte // major type 2 name encoding iff cborName has major type 3
idx []int
typ reflect.Type
ef encodeFunc
ief isEmptyFunc
typInfo *typeInfo // used to decoder to reuse type info
tagged bool // used to choose dominant field (at the same level tagged fields dominate untagged fields)
omitEmpty bool // used to skip empty field
keyAsInt bool // used to encode/decode field name as int
}
type fields []*field
@ -129,7 +130,7 @@ func getFields(t reflect.Type) (flds fields, structOptions string) {
}
// Skip fields with the same field name.
for i++; i < len(flds) && name == flds[i].name; i++ {
for i++; i < len(flds) && name == flds[i].name; i++ { //nolint:revive
}
}
if j != len(flds) {

View File

@ -90,7 +90,7 @@ const (
)
func (dtm DecTagMode) valid() bool {
return dtm < maxDecTagMode
return dtm >= 0 && dtm < maxDecTagMode
}
// EncTagMode specifies how encoder handles tag number.
@ -107,7 +107,7 @@ const (
)
func (etm EncTagMode) valid() bool {
return etm < maxEncTagMode
return etm >= 0 && etm < maxEncTagMode
}
// TagOptions specifies how encoder and decoder handle tag number.

4
vendor/modules.txt vendored
View File

@ -181,8 +181,8 @@ github.com/fsnotify/fsnotify
# github.com/fvbommel/sortorder v1.1.0
## explicit; go 1.13
github.com/fvbommel/sortorder
# github.com/fxamacker/cbor/v2 v2.5.0
## explicit; go 1.12
# github.com/fxamacker/cbor/v2 v2.6.0
## explicit; go 1.17
github.com/fxamacker/cbor/v2
# github.com/go-errors/errors v1.4.2
## explicit; go 1.14