Skip to content
This repository was archived by the owner on Aug 15, 2021. It is now read-only.

Implement semantic tagging of values #157

@pyfisch

Description

@pyfisch

Support for CBOR tagged values is the most requested feature in serde_cbor (see #3, #56, #129, #151). Tags allow users to "give [a data item] additional semantics while retaining its structure". They enable the definition of common data types and they are needed to correctly implement some specifications that use CBOR (see for example COSE).

There is a hack (with a few variations) commonly suggested to implement tags: Create a struct with a special name and two fields, one for the tag and another for the value. Now use this type to represent tagged values and give it special treatment in the Serializer and Deserializer` to convert tags.

This has two downsides:

  1. If the name of the special struct occurs (or is introduced by an attacker) in a CBOR document the deserialization breaks.
  2. Serde decouples data formats and data types. The hack forces a coupling between the two.
  • If a CBOR deserializer emits a tag but the data type does not expect one the deserialization fails (or produces wrong results).
  • If a data type emits its tag to a serializer other than the CBOR serializer an artifact from the tag is found in the output.

Design criteria

  • The changes made in serde should be small and must be backwards-compatible (that is: not require changes to existing data formats).
  • Do not rely on features not yet available in stable rust (such as specialization).
  • Tagged values must be ignored by data formats and data types alike if they are not supported.
  • The solution should not be limited to CBOR but work for other data formats that use tags as well.
  • Users should be able to:
    • Serialize/Deserialize loosely typed serde_cbor::Values with tags.
    • Serialize custom types with the correct CBOR tag.
    • Deserialize CBOR documents according to the contained tags.

Tasks

  1. Extend the serde::ser::Serializer trait to allow the serialization of tagged values. (branch)
  2. Extend serde::de::Visitor to visit a tagged value and make other necessary changes for deserialization.
    • Get the deserialization changes reviewed and merged into serde.
  3. Implement tagged serialization in serde_cbor. (exprimental branch)
  4. Implement tagged deserialization in serde_cbor.
  5. Add Tagged variant to serde_cbor::Value
    • Implement serialization.
    • Implement deserializaton.
  6. (optional) Create procedural macros to simplify the serialization of tagged values.
  7. (optional) Always serialize common types from third-party crates with the correct tag.
    • url::Url with tag 32
    • standard date/time string with tag 0 (chrono crate?)
    • epoch-based date/time with tag 1 (chrono crate?)
    • bignums?
    • to be extended

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions