Skip to content

Fix CBOR tag handlers not recognizing tags 0-5 and 21-23 - #5331

Open
sahilkamate03 wants to merge 1 commit into
nlohmann:developfrom
fork-of-sahil:fix/issue-5315-cbor-ignore-tags
Open

Fix CBOR tag handlers not recognizing tags 0-5 and 21-23#5331
sahilkamate03 wants to merge 1 commit into
nlohmann:developfrom
fork-of-sahil:fix/issue-5315-cbor-ignore-tags

Conversation

@sahilkamate03

Copy link
Copy Markdown

Fixes #5315.

What changed

  • Added the missing case 0xC0-0xC5 and case 0xD5-0xD7 labels to the tagged-item switch in binary_reader::parse_cbor_internal() (include/nlohmann/detail/input/binary_reader.hpp), so the full 0xC0-0xDB` tag-header range is handled the same way.
  • Extended the "Tagged values" test in tests/src/unit-cbor.cpp to cover 0xC0-0xD7 (previously only 0xC6-0xD4 was tested) under error, ignore, and store handlers.
  • Updated docs/mkdocs/docs/features/binary_formats/cbor.md to state the tagged-item range as 0xC0..0xDB instead of leaving it unspecified.
  • Regenerated single_include/nlohmann/json.hpp via make amalgamate.

Why

  • CBOR tags 0-5 (0xC0-0xC5: RFC 3339 date/time, epoch time, bignum, decimal, bigfloat) and tags 21-23 (0xD5-0xD7: base64url, base64, base16 conversion hints) are valid major-type-6 tags per RFC 8949, but the switch statement only recognized 0xC6-0xD4 and 0xD8-0xDB.
  • The gap made these bytes fall through to the default case and throw parse_error.112 ("invalid byte"), even under cbor_tag_handler_t::ignore and ::store — handlers that are documented to accept any tag. This broke interop with compliant ncoders that use preferred (shortest) serialization, since e.g. tag 23 is encoded as the single byte 0xD7.

Checklist

  • The changes are described in detail, both the what and why.
  • Code coverage remains at 100% — full suite passes 109/109.
  • Documentation updated.
  • Source amalgamated via make amalgamate (verified: diff matches the include/nlohmann source change exactly).

Test plan

  • cmake -S. -B build && cmake --build build -j10 && ctest --test-dir build -j10 → 100% tests passed, 0 failed out of 109
  • test-cbor_cpp11 covers the new 0xC0-0xD7 tag range under error, ignore, and store handlers

The tagged-item switch in binary_reader::parse_cbor_internal() only handled
head bytes 0xC6-0xD4 and 0xD8-0xDB. Bytes 0xC0-0xC5 (tags 0-5: date/time,
epoch, bignum, decimal, bigfloat) and 0xD5-0xD7 (tags 21-23: base64url,
base64, base16 conversion hints) fell through to the default case and were
reported as invalid bytes, even under cbor_tag_handler_t::ignore and ::store,
despite being valid CBOR major-type-6 tags per RFC 8949.

Add the missing case labels so the full 0xC0-0xDB range is handled
uniformly. Extend the "Tagged values" test in unit-cbor.cpp to cover
0xC0-0xD7, and update the CBOR docs to state the corrected tag range.

Fixes nlohmann#5315

Signed-off-by: sahilkamate03 <45514385+sahilkamate03@users.noreply.github.com>
@sahilkamate03
sahilkamate03 force-pushed the fix/issue-5315-cbor-ignore-tags branch from 96e9fb4 to 4d41812 Compare July 29, 2026 08:16
Comment thread tests/src/unit-cbor.cpp
Comment on lines +2532 to +2538
SECTION("0xC0..0xD7")
{
for (const auto b : std::vector<std::uint8_t>
{
0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF, 0xD0, 0xD1, 0xD2, 0xD3, 0xD4
0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5,
0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF, 0xD0, 0xD1, 0xD2, 0xD3, 0xD4,
0xD5, 0xD6, 0xD7

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The tests only wrap a string value for each new tag byte. Might be worth a case wrapping a binary payload under cbor_tag_handler_t::store to confirm 0xC0-0xC5/0xD5-0xD7 take the same "unwrap, don't treat as subtype" path as 0xC6-0xD4 already do.

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The "Incomplete mapping" warning still lists date/time (0xC0..0xC1), bignum (0xC2..0xC3), decimal fraction (0xC4), bigfloat (0xC5), and expected conversions (0xD5..0xD7) as types that "are not supported and will yield parse errors." That's now only true for the default error handler — under ignore/store these parse fine, same as 0xC6..0xD4/0xD8..0xDB, which were already correctly omitted from this list. Since the PR already updates the "Tagged items" warning just below to say the full 0xC0..0xDB range is tag-handler-dependent, these five bullets should be deleted from the "Incomplete mapping" box to avoid the two warnings contradicting each other.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

CBOR: cbor_tag_handler_t::ignore does not ignore tags 0-5 and 21-23 (head bytes 0xC0-0xC5, 0xD5-0xD7)

2 participants