Skip to content

Releases: fxamacker/cbor

v2.5.0

Choose a tag to compare

@fxamacker fxamacker released this 14 Aug 03:42
3b32167

This release adds important new features, optimizations, bug fixes, and 8 new contributors. Fuzz tests passed 5+ billion execs for CBOR encoding and decoding functions.

Notable changes are split into 3 categories.

⭐ Notable Changes to Review Before Upgrading

These new features and bug fixes were cherry-picked to highlight for review (for projects using older version).

  • PR 370: Add SimpleValue type to more fully support CBOR Simple Values, including values not assigned by IANA and...
  • PR 376: Add ByteString type to support CBOR maps with byte string keys because Go doesn't allow []byte as map keys and...
  • PR 379: Make Decoder.Decode() return io.ErrUnexpectedEOF instead of io.EOF on EOF if current CBOR data item is incomplete.
  • PR 380: Make Unmarshal() and Valid() return cbor.ExtraneousDataError (instead of ignoring extraneous data if any remain).
  • PR 387: Retry in Decoder if io.Reader's Read() returns 0 bytes read with nil error. Add tests to get 100% code coverage for stream.go.

⭐ More Notable Changes

  • PR 342: Add DecOptions.UTF8 to decode invalid UTF-8. Default is unchanged (reject invalid UTF-8 and return error).
  • PR 355 Allow MaxNestedLevels setting to be configured up to 65535.
  • PR 352, 377: Add EncOptions.NilContainersMode to encode nil Go maps and slices as either CBOR nil (default) or empty container.
  • PR 381: Add Decoder.Skip() to skip CBOR data item in CBOR Sequences (RFC 8742).
  • PR 386 Add functions for Extended Diagnostic Notation (RFC 8610 Appendix G).
  • PR 398 Add UnmarshalFirst() to decode CBOR data item and also return remaining bytes.
  • PR 400 Deprecate Valid and add Wellformed to replace it.
  • PR 402 Add UnmarshalFirst() to DecMode interface.
  • PR 412 Add Decoder.Buffered to return remaining data in buffer.

🚀 Notable Changes Affecting Speed or Memory Use

  • PR 335: Reuse underlying array if RawMessage has sufficient capacity.
  • PR 382: Return buffer to pool in Encode(). It adds a bit of overhead to Encode() but NewEncoder().Encode() is faster and uses less memory.

Benchmark comparison for PR 382 shows significant improvement in speed and memory use.

🚀 (click to expand) 🚀

Benchmarks provided by @x448 for NewEncoder().Encode() optimized in PR 382.

$ benchstat bench-v2.4.0.log bench-f9e6291.log 
goos: linux
goarch: amd64
pkg: github.com/fxamacker/cbor/v2
cpu: 12th Gen Intel(R) Core(TM) i7-12700H
                                                     │ bench-v2.4.0.log │  bench-f9e6291.log                  │
                                                     │      sec/op      │   sec/op     vs base                │
NewEncoderEncode/Go_bool_to_CBOR_bool-20                   236.70n ± 2%   58.04n ± 1%  -75.48% (p=0.000 n=10)
NewEncoderEncode/Go_uint64_to_CBOR_positive_int-20         238.00n ± 2%   63.93n ± 1%  -73.14% (p=0.000 n=10)
NewEncoderEncode/Go_int64_to_CBOR_negative_int-20          238.65n ± 2%   64.88n ± 1%  -72.81% (p=0.000 n=10)
NewEncoderEncode/Go_float64_to_CBOR_float-20               242.00n ± 2%   63.00n ± 1%  -73.97% (p=0.000 n=10)
NewEncoderEncode/Go_[]uint8_to_CBOR_bytes-20               245.60n ± 1%   68.55n ± 1%  -72.09% (p=0.000 n=10)
NewEncoderEncode/Go_string_to_CBOR_text-20                 243.20n ± 3%   68.39n ± 1%  -71.88% (p=0.000 n=10)
NewEncoderEncode/Go_[]int_to_CBOR_array-20                 563.0n ± 2%    378.3n ± 0%  -32.81% (p=0.000 n=10)
NewEncoderEncode/Go_map[string]string_to_CBOR_map-20       2.043µ ± 2%    1.906µ ± 2%   -6.75% (p=0.000 n=10)
geomean                                                    349.7n         122.7n       -64.92%

                                                     │ bench-v2.4.0.log │    bench-f9e6291.log                │
                                                     │       B/op       │    B/op     vs base                 │
NewEncoderEncode/Go_bool_to_CBOR_bool-20                     128.0 ± 0%     0.0 ± 0%  -100.00% (p=0.000 n=10)
NewEncoderEncode/Go_uint64_to_CBOR_positive_int-20           128.0 ± 0%     0.0 ± 0%  -100.00% (p=0.000 n=10)
NewEncoderEncode/Go_int64_to_CBOR_negative_int-20            128.0 ± 0%     0.0 ± 0%  -100.00% (p=0.000 n=10)
NewEncoderEncode/Go_float64_to_CBOR_float-20                 128.0 ± 0%     0.0 ± 0%  -100.00% (p=0.000 n=10)
NewEncoderEncode/Go_[]uint8_to_CBOR_bytes-20                 128.0 ± 0%     0.0 ± 0%  -100.00% (p=0.000 n=10)
NewEncoderEncode/Go_string_to_CBOR_text-20                   128.0 ± 0%     0.0 ± 0%  -100.00% (p=0.000 n=10)
NewEncoderEncode/Go_[]int_to_CBOR_array-20                   128.0 ± 0%     0.0 ± 0%  -100.00% (p=0.000 n=10)
NewEncoderEncode/Go_map[string]string_to_CBOR_map-20         544.0 ± 0%   416.0 ± 0%   -23.53% (p=0.000 n=10)
geomean                                                      153.4                    ?                       ¹ ²
¹ summaries must be >0 to compute geomean
² ratios must be >0 to compute geomean

                                                     │ bench-v2.4.0.log │    bench-f9e6291.log                │
                                                     │    allocs/op     │ allocs/op   vs base                 │
NewEncoderEncode/Go_bool_to_CBOR_bool-20                     2.000 ± 0%   0.000 ± 0%  -100.00% (p=0.000 n=10)
NewEncoderEncode/Go_uint64_to_CBOR_positive_int-20           2.000 ± 0%   0.000 ± 0%  -100.00% (p=0.000 n=10)
NewEncoderEncode/Go_int64_to_CBOR_negative_int-20            2.000 ± 0%   0.000 ± 0%  -100.00% (p=0.000 n=10)
NewEncoderEncode/Go_float64_to_CBOR_float-20                 2.000 ± 0%   0.000 ± 0%  -100.00% (p=0.000 n=10)
NewEncoderEncode/Go_[]uint8_to_CBOR_bytes-20                 2.000 ± 0%   0.000 ± 0%  -100.00% (p=0.000 n=10)
NewEncoderEncode/Go_string_to_CBOR_text-20                   2.000 ± 0%   0.000 ± 0%  -100.00% (p=0.000 n=10)
NewEncoderEncode/Go_[]int_to_CBOR_array-20                   2.000 ± 0%   0.000 ± 0%  -100.00% (p=0.000 n=10)
NewEncoderEncode/Go_map[string]string_to_CBOR_map-20         28.00 ± 0%   26.00 ± 0%    -7.14% (p=0.000 n=10)
geomean                                                      2.782                    ?                       ¹ ²
¹ summaries must be >0 to compute geomean
² ratios must be >0 to compute geomean

What's Changed

All merged pull requests are listed here (including the already highlighted ones).

(click to expand)

Changes to Code

Most coding changes here were already mentioned.

  • Reuse underlying array if RawMessage has sufficient capacity by @zensh in #335
  • Add decoding option to allow invalid UTF-8 by @fxamacker in #342
  • Allow MaxNestedLevels to be up to 65535 by @immesys in #355
  • Add support for unassigned/reserved CBOR simple values by @fxamacker in #370
  • Add ByteString type to support any CBOR byte string by @fxamacker in #376
  • add option to enforce nil container marshaling as empty containers by @dedefer in #352
  • Refactor NilContainersMode option by @fxamacker in #377
  • Make Decoder.Decode() return io.UnexpectedEOF instead of io.EOF if CBOR data item is truncated by @fxamacker in #379
  • Fix handling of extra data in Unmarshal() & Valid() by @fxamacker in #380
  • Add Decoder.Skip() to skip CBOR data item in CBOR Sequences (RFC 8742) by @fxamacker in #381
  • Return buffer to pool when using Encoder by @fxamacker in #382
  • Retry in decoder if Read() returns 0 bytes read with nil error by @fxamacker in #387
  • Deprecate Valid() and add Wellformed() to replace it by @fxamacker in #400
  • Add UnmarshalFirst by @immesys in #398
  • Add UnmarshalFirst to DecMode interface by @fxamacker in #402
  • Add functions for Extended Diagnostic Notation (RFC 8610 Appendix G) by @zensh in #386
  • Add more tests for Diagnose and DiagnoseFirst by @fxamacker in #405
  • Fix Diagnose to return io.EOF error on empty data by @fxamacker in #410
  • Add Decoder.Buffered to return buffered data by @fxamacker in #412
  • Fix Diagnose() to return io.EOF error on empty data by @fxamacker in #410

Changes to CI, Comments, and Docs

Read more

v2.5.0-beta5

Choose a tag to compare

@fxamacker fxamacker released this 26 Jun 04:16
48c838c

v2.5.0-beta5 is fuzz tested and production quality, but docs need to be updated before releasing v2.5.0.
IMPORTANT: Please view these release notes (esp. v2.5.0-beta) before upgrading from v2.4 or earlier:

  • v2.5.0-beta4 - Bugfix for Diagnose to return io.EOF on empty data.
  • v2.5.0-beta3 - Add functions: Diagnose, DiagnoseFirst, UnmarshalFirst, Wellformed.
  • v2.5.0-beta2 - Bugfix to retry in Decoder if io.Reader's Read() returns 0 bytes read with nil error.
  • v2.5.0-beta - Notable improvements, optimizations, bugfixes, and 8 new contributors!

What's Changed since v2.5.0-beta4

Full Changelog: v2.5.0-beta4...v2.5.0-beta5

v2.5.0-beta4

Choose a tag to compare

@fxamacker fxamacker released this 18 Jun 05:40
340a5fb

Features already present in v2.4 are release quality. Newly added functions require more fuzzing and docs.
IMPORTANT: Please view these release notes (esp. v2.5.0-beta) before upgrading from v2.4:

  • v2.5.0-beta3 - Add Diagnose(), DiagnoseFirst(), UnmarshalFirst(), Wellformed().
  • v2.5.0-beta2 - Bugfix and release notes include benchmark comparison of v2.5.0-beta2 vs v2.4.0.
  • v2.5.0-beta - Notable improvements, optimizations, bugfixes, and 8 new contributors!

What's Changed Since v2.5.0-beta3

  • Bump safer-golangci-lint to 1.52.2 by @x448 in #408
  • Fix Diagnose() to return io.EOF error on empty data by @fxamacker in #410
  • Update README.md for cbor v2.5.0-beta4 by @fxamacker in #411

Full Changelog: v2.5.0-beta3...v2.5.0-beta4

v2.5.0-beta3

v2.5.0-beta3 Pre-release
Pre-release

Choose a tag to compare

@fxamacker fxamacker released this 16 May 04:45
a52d9a5

This release adds 4 new functions: UnmarshalFirst, Diagnose, DiagnoseFirst, and Wellformed. In addition Valid function is deprecated (use Wellformed instead).

  • UnmarshalFirst decodes first CBOR data item and returns remaining bytes. This is useful for CBOR Sequences (RFC 8742) and also because Unmarshal was fixed in v2.5.0-beta to return ExtraneousDataError if there are remaining bytes.
  • Diagnose and DiagnoseFirst returns human-readable Extended Diagnostic Notation (RFC 8610 Appendix G) for the given CBOR encoding. These are useful for debugging and allows more user-friendly error logging.

What's Changed (since v2.5.0-beta2)

  • Deprecate Valid() and add Wellformed() to replace it by @fxamacker in #400
  • Add UnmarshalFirst by @immesys in #398
  • Add UnmarshalFirst to DecMode interface by @fxamacker in #402
  • Add functions for Extended Diagnostic Notation (RFC 8610 Appendix G) by @zensh in #386
  • Add more tests for Diagnose and DiagnoseFirst by @fxamacker in #405

Changes to CI and Documentation

Special Thanks

Thank you @immesys, @zensh, and @x448 for your contributions!

Full Changelog: v2.5.0-beta2...v2.5.0-beta3

v2.5.0-beta2

v2.5.0-beta2 Pre-release
Pre-release

Choose a tag to compare

@fxamacker fxamacker released this 21 Feb 00:02
f9e6291

There are fewer changes in v2.5.0-beta2 compared to v2.5.0-beta. Speed and memory improvements since v2.4.0 are from v2.5.0-beta. Tests cover 98.5% and reached 100% coverage for stream.go (e.g. Decoder using the provided io.Reader).

What's Changed Since v2.5.0-beta

  • Retry in Decoder if io.Reader's Read() returns 0 bytes read with nil error by @fxamacker in #387
    • This PR also added more tests so we have 100% coverage for stream.go.
  • Update fxamacker_cbor_banner.png for v2.5 by @x448 in #383
  • bump safer-golangci-lint.yml to 1.51.1 by @x448 in #389

Go language recommends that Read implementations for io.Reader avoid returning 0 with nil error. It also recommends that callers receiving 0 and nil from Read should treat it as if nothing happened. This edge case is handled properly now.

@x448 shared benchmarks comparison of v2.4.0 vs v2.5.0-beta2. Performance improvements are from v2.5.0-beta.

Comparison of v2.5.0-beta2 vs v2.4.0

$ benchstat benchNewEncoderEncode-v2.4.0.log benchNewEncoderEncode-f9e6291.log 
goos: linux
goarch: amd64
pkg: github.com/fxamacker/cbor/v2
cpu: 12th Gen Intel(R) Core(TM) i7-12700H
                                                     │ benchNewEncoderEncode-v2.4.0.log │  benchNewEncoderEncode-f9e6291.log  │
                                                     │              sec/op              │   sec/op     vs base                │
NewEncoderEncode/Go_bool_to_CBOR_bool-20                                   236.70n ± 2%   58.04n ± 1%  -75.48% (p=0.000 n=10)
NewEncoderEncode/Go_uint64_to_CBOR_positive_int-20                         238.00n ± 2%   63.93n ± 1%  -73.14% (p=0.000 n=10)
NewEncoderEncode/Go_int64_to_CBOR_negative_int-20                          238.65n ± 2%   64.88n ± 1%  -72.81% (p=0.000 n=10)
NewEncoderEncode/Go_float64_to_CBOR_float-20                               242.00n ± 2%   63.00n ± 1%  -73.97% (p=0.000 n=10)
NewEncoderEncode/Go_[]uint8_to_CBOR_bytes-20                               245.60n ± 1%   68.55n ± 1%  -72.09% (p=0.000 n=10)
NewEncoderEncode/Go_string_to_CBOR_text-20                                 243.20n ± 3%   68.39n ± 1%  -71.88% (p=0.000 n=10)
NewEncoderEncode/Go_[]int_to_CBOR_array-20                                  563.0n ± 2%   378.3n ± 0%  -32.81% (p=0.000 n=10)
NewEncoderEncode/Go_map[string]string_to_CBOR_map-20                        2.043µ ± 2%   1.906µ ± 2%   -6.75% (p=0.000 n=10)
geomean                                                                     349.7n        122.7n       -64.92%

                                                     │ benchNewEncoderEncode-v2.4.0.log │    benchNewEncoderEncode-f9e6291.log    │
                                                     │               B/op               │    B/op     vs base                     │
NewEncoderEncode/Go_bool_to_CBOR_bool-20                                     128.0 ± 0%     0.0 ± 0%  -100.00% (p=0.000 n=10)
NewEncoderEncode/Go_uint64_to_CBOR_positive_int-20                           128.0 ± 0%     0.0 ± 0%  -100.00% (p=0.000 n=10)
NewEncoderEncode/Go_int64_to_CBOR_negative_int-20                            128.0 ± 0%     0.0 ± 0%  -100.00% (p=0.000 n=10)
NewEncoderEncode/Go_float64_to_CBOR_float-20                                 128.0 ± 0%     0.0 ± 0%  -100.00% (p=0.000 n=10)
NewEncoderEncode/Go_[]uint8_to_CBOR_bytes-20                                 128.0 ± 0%     0.0 ± 0%  -100.00% (p=0.000 n=10)
NewEncoderEncode/Go_string_to_CBOR_text-20                                   128.0 ± 0%     0.0 ± 0%  -100.00% (p=0.000 n=10)
NewEncoderEncode/Go_[]int_to_CBOR_array-20                                   128.0 ± 0%     0.0 ± 0%  -100.00% (p=0.000 n=10)
NewEncoderEncode/Go_map[string]string_to_CBOR_map-20                         544.0 ± 0%   416.0 ± 0%   -23.53% (p=0.000 n=10)
geomean                                                                      153.4                    ?                       ¹ ²
¹ summaries must be >0 to compute geomean
² ratios must be >0 to compute geomean

                                                     │ benchNewEncoderEncode-v2.4.0.log │    benchNewEncoderEncode-f9e6291.log    │
                                                     │            allocs/op             │ allocs/op   vs base                     │
NewEncoderEncode/Go_bool_to_CBOR_bool-20                                     2.000 ± 0%   0.000 ± 0%  -100.00% (p=0.000 n=10)
NewEncoderEncode/Go_uint64_to_CBOR_positive_int-20                           2.000 ± 0%   0.000 ± 0%  -100.00% (p=0.000 n=10)
NewEncoderEncode/Go_int64_to_CBOR_negative_int-20                            2.000 ± 0%   0.000 ± 0%  -100.00% (p=0.000 n=10)
NewEncoderEncode/Go_float64_to_CBOR_float-20                                 2.000 ± 0%   0.000 ± 0%  -100.00% (p=0.000 n=10)
NewEncoderEncode/Go_[]uint8_to_CBOR_bytes-20                                 2.000 ± 0%   0.000 ± 0%  -100.00% (p=0.000 n=10)
NewEncoderEncode/Go_string_to_CBOR_text-20                                   2.000 ± 0%   0.000 ± 0%  -100.00% (p=0.000 n=10)
NewEncoderEncode/Go_[]int_to_CBOR_array-20                                   2.000 ± 0%   0.000 ± 0%  -100.00% (p=0.000 n=10)
NewEncoderEncode/Go_map[string]string_to_CBOR_map-20                         28.00 ± 0%   26.00 ± 0%    -7.14% (p=0.000 n=10)
geomean                                                                      2.782                    ?                       ¹ ²
¹ summaries must be >0 to compute geomean
² ratios must be >0 to compute geomean

Full Changelog: v2.5.0-beta...v2.5.0-beta2

v2.5.0-beta

v2.5.0-beta Pre-release
Pre-release

Choose a tag to compare

@fxamacker fxamacker released this 03 Jan 01:12
9c7f31b

This release is larger than usual because it has been a year since last release. It adds new features, bug fixes, and 8 new contributors.

All unit tests pass (98.4% coverage). Fuzz tests passed hundreds of millions of execs. Fuzzing will continue until v2.5.0 is tagged.

Notable Changes to Review Before Upgrading

These new features and bug fixes were cherry-picked to highlight for review (for projects using older version in production).

  • PR 370: Add SimpleValue type to more fully support CBOR Simple Values, including values not assigned by IANA and...

  • PR 376: Add ByteString type to support CBOR maps with byte string keys because Go doesn't allow []byte as map keys and...

  • PR 379: Make Decoder.Decode() return io.ErrUnexpectedEOF instead of io.EOF on EOF if current CBOR data item is incomplete.

  • PR 380: Make Unmarshal() and Valid() return cbor.ExtraneousDataError (instead of ignoring extraneous data if any remain).

Notable Changes Affecting Speed or Memory Use

  • PR 335: Reuse underlying array if RawMessage has sufficient capacity.

  • PR 382: Return buffer to pool in Encode(). It adds a bit of overhead to Encode() but NewEncoder().Encode() is a lot faster and uses less memory.

Other Notable Changes:

  • PR 342: Add DecOptions.UTF8 to decode invalid UTF-8. Default is unchanged (reject invalid UTF-8 and return error).

  • PR 355 Allow MaxNestedLevels setting to be configured up to 65535.

  • PR 352, 377: Add EncOptions.NilContainersMode to encode nil Go maps and slices as either CBOR nil (default) or empty container.

  • PR 381: Add Decoder.Skip() to skip CBOR data item in CBOR Sequences (RFC 8742).

What's Changed

Most coding changes are already mentioned. Other changes include CI, comments, and docs.

(click to expand)

All Changes to Code

  • Add support for unassigned/reserved CBOR simple values by @fxamacker in #370
  • Add ByteString type to support any CBOR byte string by @fxamacker and @agaffney in #376
  • Make Decoder.Decode() return io.ErrUnexpectedEOF instead of io.EOF on EOF if CBOR data item is truncated by @fxamacker in #379
  • Fix handling of extra data in Unmarshal() & Valid() by @fxamacker in #380
  • Add Decoder.Skip() to skip CBOR data item in CBOR Sequences (RFC 8742) by @fxamacker in #381
  • Reuse underlying array if RawMessage has sufficient capacity by @zensh in #335
  • Return buffer to pool when using Encoder.Encode by @fxamacker in #382
  • Add decoding option to allow invalid UTF-8 by @fxamacker in #342
  • Allow MaxNestedLevels to be up to 65535 by @immesys in #355
  • add option to enforce nil container marshaling as empty containers by @dedefer in #352
  • Refactor NilContainersMode option by @fxamacker in #377

Changes to CI, Comments, and Docs

New Contributors (alphabetically)

Non-coding contibutions were made by opening notable issues that directly or indirectly improved this release.

  • @burdiyan opened issue and followups that led to Encode() returning buffer to pool as default behavior.
  • @espoal opened issue and followups that led to adding Skip() feature for CBOR Sequences (RFC 8742).
  • @qmuntal opened issue and @x448 added feedback that led to improved support for CBOR Simple Values.
  • @x448 opened multiple issues and provided helpful feedback in addition to his merged PR.
  • @zensh opened multiple issues and provided helpful feedback in addition to his merged PR.

Full Changelog: v2.4.0...v2.5.0-beta

v2.4.0 (January 3, 2022)

Choose a tag to compare

@fxamacker fxamacker released this 04 Jan 00:20
6cdde66

This release adds two user-requested features to the decoder. It passed 3+ billion execs fuzzing before being tagged.

What's Changed

  • Add option to specify default Go map type when decoding CBOR map into interface{} by @fxamacker in #316
  • Add support for decoding registered CBOR tag to interface type by @fxamacker in #308
  • Update CBOR docs for v2.4.0 by @x448 in #318

Special Thanks

Full Changelog: v2.3.1...v2.4.0

v2.3.1 (Dec 28, 2021)

Choose a tag to compare

@fxamacker fxamacker released this 28 Dec 23:09
bd3cab7

IMPORTANT:

  • This release fixes an important typo in README and omission in CONTRIBUTING.
  • No changes to code outside _test.go files.
  • Changes to non-test files are limited to comments.
  • Next release (v2.4.0) started fuzz testing and is expected to be tagged within 1-2 weeks.

Changes to v2.3.1 include:

  • Fix typo in docs (example code snippet) that can cause bugs. Thanks @herrjemand!
  • Update CONTRIBUTING to mention signing requirements. Thanks @lukseven and @x448!
  • Update README. Thanks @x448 and @rumpelsepp!
  • Update ci.yml to use Go 1.17.x. Thanks @x448!
  • Add Revive as a lint checker.
  • Cleanup lint messages in _test.go files
  • Cleanup lint messages in non-test files if the changes are limited to comments (no actual coding changes).

Full Changelog: v2.3.0...v2.3.1

v2.3.0 (May 30, 2021)

Choose a tag to compare

@fxamacker fxamacker released this 30 May 21:57
230e12c

Upgrading is recommended: v2.3.0 has bug fixes, is faster, and passed 1+ billion execs fuzzing.

⭐ Features and Improvements

  • Add built-in support for big.Int (#209)
  • Add support for tag 55799 self-describing CBOR (#227)
  • Export valid function (#248)
  • Increase user-configurable CBOR limit for MaxArrayElements and MaxMapPairs (#207)
  • Add decoding option to be more strict than encoding/json: fail on CBOR map if destination struct field is not found (#178)
  • Add option for decoding CBOR pos and neg integer to interface{} to not distinguish between uint and int (#216)

🚀 Performance

fxamacker/cbor 2.3.0 is faster than 2.2.0 by up to 14% (using CWT and COSE example data from RFCs).

name                                 old time/op    new time/op    delta
DecodeCWTClaims-4                      1.34µs ± 0%    1.25µs ± 0%   -6.90%  (p=0.000 n=10+9)
DecodeCOSE/128-Bit_Symmetric_Key-4     1.01µs ± 0%    0.86µs ± 0%  -14.02%  (p=0.000 n=9+9)
DecodeCOSE/256-Bit_Symmetric_Key-4     1.02µs ± 0%    0.88µs ± 0%  -13.60%  (p=0.000 n=9+10)
DecodeCOSE/ECDSA_P256_256-Bit_Key-4    1.69µs ± 0%    1.45µs ± 0%  -14.14%  (p=0.000 n=10+10)
DecodeWebAuthn-4                       1.46µs ± 0%    1.32µs ± 0%   -9.65%  (p=0.000 n=10+10)
EncodeCWTClaims-4                       766ns ± 0%     780ns ± 0%   +1.87%  (p=0.000 n=10+10)
EncodeCOSE/128-Bit_Symmetric_Key-4      910ns ± 0%     908ns ± 0%     ~     (p=0.059 n=9+10)
EncodeCOSE/256-Bit_Symmetric_Key-4      912ns ± 0%     912ns ± 0%     ~     (p=0.909 n=10+10)
EncodeCOSE/ECDSA_P256_256-Bit_Key-4    1.13µs ± 1%    1.14µs ± 0%   +0.61%  (p=0.001 n=9+10)
EncodeWebAuthn-4                        794ns ± 2%     823ns ± 1%   +3.69%  (p=0.000 n=9+10)
fxamacker/cbor 2.3.0 vs ugorji/go 1.2.6

fxamacker/cbor 2.3.0 (not using unsafe) is faster than ugorji/go 1.2.6 (using unsafe).

name                                 old time/op    new time/op    delta
DecodeCWTClaims-4                      2.06µs ± 1%    1.25µs ± 0%  -39.57%  (p=0.000 n=10+9)
DecodeCOSE/128-Bit_Symmetric_Key-4     1.47µs ± 1%    0.86µs ± 0%  -41.25%  (p=0.000 n=9+9)
DecodeCOSE/256-Bit_Symmetric_Key-4     1.50µs ± 2%    0.88µs ± 0%  -41.63%  (p=0.000 n=10+10)
DecodeCOSE/ECDSA_P256_256-Bit_Key-4    2.22µs ± 2%    1.45µs ± 0%  -34.65%  (p=0.000 n=10+10)
DecodeWebAuthn-4                       1.55µs ± 0%    1.32µs ± 0%  -14.97%  (p=0.000 n=9+10)
EncodeCWTClaims-4                      1.46µs ± 0%    0.78µs ± 0%  -46.52%  (p=0.000 n=10+10)
EncodeCOSE/128-Bit_Symmetric_Key-4     1.79µs ± 1%    0.91µs ± 0%  -49.38%  (p=0.000 n=9+10)
EncodeCOSE/256-Bit_Symmetric_Key-4     1.79µs ± 1%    0.91µs ± 0%  -49.15%  (p=0.000 n=10+10)
EncodeCOSE/ECDSA_P256_256-Bit_Key-4    2.09µs ± 1%    1.14µs ± 0%  -45.41%  (p=0.000 n=10+10)
EncodeWebAuthn-4                        981ns ± 0%     823ns ± 1%  -16.05%  (p=0.000 n=10+10)

name                                 old alloc/op   new alloc/op   delta
DecodeCWTClaims-4                        760B ± 0%      176B ± 0%  -76.84%  (p=0.000 n=10+10)
DecodeCOSE/128-Bit_Symmetric_Key-4       800B ± 0%      240B ± 0%  -70.00%  (p=0.000 n=10+10)
DecodeCOSE/256-Bit_Symmetric_Key-4       816B ± 0%      256B ± 0%  -68.63%  (p=0.000 n=10+10)
DecodeCOSE/ECDSA_P256_256-Bit_Key-4      913B ± 0%      352B ± 0%  -61.45%  (p=0.000 n=10+10)
DecodeWebAuthn-4                       1.56kB ± 0%    0.99kB ± 0%  -36.41%  (p=0.000 n=10+10)
EncodeCWTClaims-4                      1.36kB ± 0%    0.18kB ± 0%  -87.06%  (p=0.000 n=10+10)
EncodeCOSE/128-Bit_Symmetric_Key-4     1.97kB ± 0%    0.22kB ± 0%  -88.62%  (p=0.000 n=10+10)
EncodeCOSE/256-Bit_Symmetric_Key-4     1.97kB ± 0%    0.24kB ± 0%  -87.80%  (p=0.000 n=10+10)
EncodeCOSE/ECDSA_P256_256-Bit_Key-4    1.97kB ± 0%    0.32kB ± 0%  -83.74%  (p=0.000 n=10+10)
EncodeWebAuthn-4                       1.31kB ± 0%    1.09kB ± 0%  -17.07%  (p=0.000 n=10+10)

name                                 old allocs/op  new allocs/op  delta
DecodeCWTClaims-4                        6.00 ± 0%      6.00 ± 0%     ~     (all equal)
DecodeCOSE/128-Bit_Symmetric_Key-4       4.00 ± 0%      4.00 ± 0%     ~     (all equal)
DecodeCOSE/256-Bit_Symmetric_Key-4       4.00 ± 0%      4.00 ± 0%     ~     (all equal)
DecodeCOSE/ECDSA_P256_256-Bit_Key-4      7.00 ± 0%      7.00 ± 0%     ~     (all equal)
DecodeWebAuthn-4                         5.00 ± 0%      5.00 ± 0%     ~     (all equal)
EncodeCWTClaims-4                        4.00 ± 0%      2.00 ± 0%  -50.00%  (p=0.000 n=10+10)
EncodeCOSE/128-Bit_Symmetric_Key-4       6.00 ± 0%      2.00 ± 0%  -66.67%  (p=0.000 n=10+10)
EncodeCOSE/256-Bit_Symmetric_Key-4       6.00 ± 0%      2.00 ± 0%  -66.67%  (p=0.000 n=10+10)
EncodeCOSE/ECDSA_P256_256-Bit_Key-4      6.00 ± 0%      2.00 ± 0%  -66.67%  (p=0.000 n=10+10)
EncodeWebAuthn-4                         4.00 ± 0%      2.00 ± 0%  -50.00%  (p=0.000 n=10+10)

Benchmarks used Go 1.15.12 on linux_amd64. Benchmark results are data dependent so run them using your own data.

🐞 Bug Fixes

  • Allow decoding to struct field of interface type (#260, #275)
  • Decoding registered tag to empty interface should return object of registered type (#223)
  • Fix: encoding cbor.RawTag with empty content returns malformed CBOR data (#258)
  • Fix: encoding uninitialized cbor.(Raw)Tag returns malformed CBOR data (#256)
  • Decoding CBOR null to time.Time should have no effect (#254)
  • Fix: decoding CBOR null to cbor.Tag shouldn't return any error (#252)
  • Properly handle empty values for custom types (#232)
  • Decoding should ignore CBOR tag number 55799 when it is a prefix (#228)
  • Validate CBOR tag content type if tag number is 0 or 1, even when TimeTag = DecTagIgnored (#221)
  • Registering tag (TagSet.Add) with already registered tag number should be rejected (#218)
  • DecOptions.ExtraReturnErrors field should be typed #240

📖 Docs

  • Make README more friendly to dark themes (#269)
  • Private member struct tag (json:"-" and cbor:"-") are supported but not documented (#201)
  • TagOptions struct is missing from README.md (#199)
  • Fix go.dev and README compatibility (#173)
  • Replace CBOR "draft RFC" with CBOR "RFC 8949" because it was approved by IETF (#265)

🏗️ Chores

  • Audit library for any missing attribution for code snippets from sources other than Go's stdlib (#237)
  • Audit library for any missing attribution for code snippets from Go's stdlib (encoding/json) (#233)
  • Create pull request template for code contributions (#197)
  • CI: Use safer-golangci-lint.yml GitHub Action Workflow contributed by @x448
  • CI: Bump golangci-lint to 1.40.1
  • CI: Use CodeQL analysis

🧪 Tests and Fuzzing

  • Code coverage remains above 98%.
  • Coverage-guided fuzzing reached 1+ billion execs ~2 days after v2.3.0 release.

👍 Special Thanks

⛈️ Winter Storm Uri Displaced Me (still at a hotel 3+ months later)

  • As of May 30, I'm still displaced due to Winter Storm Uri started causing damage on February 16. Fire sprinklers started leaking, pipes shattered in the ceilings, and water outage lasted 2+ weeks.

v2.2.0 (Feb 24, 2020)

Choose a tag to compare

@fxamacker fxamacker released this 25 Feb 05:55
7f92480

IMPORTANT: This release fixes a bug that affects all prior versions (1.x and 2.x). Please update if you use Go arrays instead of slices with CBOR indef length arrays. Bug was detected by newer fxamacker/cbor-fuzz.

v2.2 is a small release and is the most reliable version currently available.

Changes include:

  • Feat: Support decoding CBOR byte string (major type 2) to Go byte array. (commit 52db071). Thanks @ZenGround0 for requesting this feature.
  • Feat: Add more decoding options (MaxNestedLevels, MaxArrayElements, MaxMapKeyPairs, IndefLength, TagsMd.) (commit cb23445)
  • Feat: Add more encoding options (IndefLength, TagsMd.) (commit cb23445)
  • Fix: Fix potential error when decoding shorter CBOR indef length array to Go array (slice wasn't affected). This bug affects all prior versions of 1.x and 2.x. (commit c7f2cc7)
  • Docs: Replace README.md markdown tables with SVG tables to work around go.dev bugs. Less than half were replaced to avoid delaying this release. Thanks @x448 for working on this!

v2.2 passed 473+ million execs of coverage-guided fuzzing on Feb 24, 2020.
UPDATE: v2.2 passed 3.2+ billion execs of coverage-guided fuzzing on Mar 7, 2020.