Skip to content

Packed CBOR decoding support for shared items#93

Draft
mguetschow wants to merge 44 commits into
bergzand:masterfrom
mguetschow:packed-cbor
Draft

Packed CBOR decoding support for shared items#93
mguetschow wants to merge 44 commits into
bergzand:masterfrom
mguetschow:packed-cbor

Conversation

@mguetschow

@mguetschow mguetschow commented Feb 29, 2024

Copy link
Copy Markdown
Collaborator

This PR adds support for packed CBOR shared items to NanoCBOR, handling them (mostly) transparently to the user.

The following is supported for now:

All additional functionality specific to packed CBOR support is guarded behind the configuration define NANOCBOR_DECODE_PACKED_ENABLED and should thus lead to (almost) no overhead compared to current master when packed CBOR support is disabled (todo: check actual binary size difference).

Even if packed CBOR support is enabled at compile-time, it needs to be explicitly requested by using nanocbor_decoder_init_packed* instead of nanocbor_decoder_init.

Implementation Details

  • nanocbor_value_t is extended to additionally hold information about the active set of packing tables. The maximal nesting supported is determined by the compile-time configuration NANOCBOR_DECODE_PACKED_NESTED_TABLES_MAX (currently set to 3). For each table, its start and length (in bytes) are stored.
  • For every API-facing function (starting with nanocbor_, except nanocbor_get_subcbor, cf. below), NanoCBOR first tries to handle any potential packed CBOR item (simple value below 16, tag 6, or tag 113). If at least one (or several nested) such packed CBOR items are found, they are (recursively) handled. To avoid code-duplication, the macro family _PACKED_HANDLE_* is used for this repeated logic. Recursion is bound by NANOCBOR_MAX_RECURSION, which is decremented for every definition of a nanocbor_value_t.
  • When a table definition (tag 113) is encountered, the start and the length of the packing table is saved in the current nanocbor_value_t. If the maximum nesting level of table definitions is reached, the error value NANOCBOR_ERR_PACKED_MEMORY is returned to the user.
  • When a shared item reference (simple value 0-15 or tag 6) is encountered, the packing tables are checked, starting from the one that was last defined. If the reference is larger than the sum of the length of all currently active packing tables, NANOCBOR_ERR_PACKED_UNDEFINED_REFERENCE is returned.
  • If the content of tag 113 or tag 6 has an unexpected format, NANOCBOR_ERR_PACKED_FORMAT is returned.

Testing

ninja -C build && build/tests/automated/test_automated runs an extensive test suite for packed CBOR decoding iff NANOCBOR_DECODE_PACKED_ENABLED == 1.

Open Questions

  • How should nanocbor_get_subcbor() behave? If called on a packed CBOR data item (table setup or reference), right now it would simply return the unhandled packed CBOR data item. For successful later processing, the context (aka the active set of packing tables) would need to be saved / restored somehow. A partly fix could be to handle the packed CBOR data item (handle the table or follow the reference). This would however still break if the resulting item itself still contains shared item references (can happen if it is an array, a map or a tag).

Remarks

Note that this only concerns the decoder, encoding packed CBOR is expected to be done manually be the application (needs #88).

Builds on top of (and thus includes) #90, #91, #92.

I could try to rewrite the commit history if that would help for the review.

Edit 2024-04-17: The implementation has been simplified by recursing only over the _packed_* functions, instead of the API-facing functions.

Edit 2024-08-23: The macro implementation was changed to fix a bug where the decoder context was forwarded even if the wrong getter function has been used.

@mguetschow mguetschow changed the title Packed CBOR support for item sharing Packed CBOR decoding support for item sharing Feb 29, 2024
@mguetschow mguetschow changed the title Packed CBOR decoding support for item sharing Packed CBOR decoding support for shared items Feb 29, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant