Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Packed CBOR decoding support for shared items #93

Draft
wants to merge 44 commits into
base: master
Choose a base branch
from

Conversation

mguetschow
Copy link
Contributor

@mguetschow mguetschow commented Feb 29, 2024

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