Skip to content

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

Open
sahilkamate03 wants to merge 2 commits 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 2 commits 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

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.

@nlohmann

nlohmann commented Aug 7, 2026

Copy link
Copy Markdown
Owner

Apologies for the AI-assisted review here — I don't have time for a deeper pass on this one right now, so this is a quick comparison rather than a full re-review.

We got a second PR for the same issue, #5367, which has the identical code fix (same case 0xC0-0xC5 / 0xD5-0xD7 additions in binary_reader.hpp). It also independently fixes the docs issue flagged above — removing the stale "Incomplete mapping" bullets for tags 0-5/21-23 and adding a cross-reference note — which you could port over here.

The other ask from the review above (a store-mode test with a binary payload, not just a string, to confirm the new tag bytes take the same "unwrap, don't treat as subtype" path as the existing ones) is still outstanding in both PRs.

Given this one already has a clean CI run and is otherwise the more complete PR, it's the better one to land — just needs the docs fix and the extra test case.

— posted by Claude Code on behalf of @nlohmann

sahilkamate03 added a commit to fork-of-sahil/json that referenced this pull request Aug 7, 2026
The "Incomplete mapping" warning still listed tags 0-5 (date/time,
bignum, decimal fraction, bigfloat) and 21-23 (expected conversions)
as unsupported, even though they now parse correctly under
cbor_tag_handler_t::ignore/store, same as 0xC6..0xD4/0xD8..0xDB.
Remove those five bullets and cross-reference the "Tagged items"
warning below, matching the equivalent docs fix landed independently
in PR nlohmann#5367.

Also add a cbor_tag_handler_t::store test that wraps a binary
payload (not just a string) for every byte in 0xC0..0xD7, confirming
these tags are unwrapped the same way as 0xC6..0xD4 rather than
mistaken for the 0xD8..0xDB binary-subtype marker syntax, per review
feedback on nlohmann#5331.

Signed-off-by: sahilkamate03 <45514385+sahilkamate03@users.noreply.github.com>
@github-actions github-actions Bot added L CI CMake and removed M labels Aug 7, 2026
@sahilkamate03
sahilkamate03 force-pushed the fix/issue-5315-cbor-ignore-tags branch from 0114cb1 to ad29f64 Compare August 7, 2026 20:36
sahilkamate03 added a commit to fork-of-sahil/json that referenced this pull request Aug 7, 2026
The "Incomplete mapping" warning still listed tags 0-5 (date/time,
bignum, decimal fraction, bigfloat) and 21-23 (expected conversions)
as unsupported, even though they now parse correctly under
cbor_tag_handler_t::ignore/store, same as 0xC6..0xD4/0xD8..0xDB.
Remove those five bullets and cross-reference the "Tagged items"
warning below, matching the equivalent docs fix landed independently
in PR nlohmann#5367.

Also add a cbor_tag_handler_t::store test that wraps a binary
payload (not just a string) for every byte in 0xC0..0xD7, confirming
these tags are unwrapped the same way as 0xC6..0xD4 rather than
mistaken for the 0xD8..0xDB binary-subtype marker syntax, per review
feedback on nlohmann#5331.

Signed-off-by: sahilkamate03 <45514385+sahilkamate03@users.noreply.github.com>
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 added a commit to fork-of-sahil/json that referenced this pull request Aug 7, 2026
The "Incomplete mapping" warning still listed tags 0-5 (date/time,
bignum, decimal fraction, bigfloat) and 21-23 (expected conversions)
as unsupported, even though they now parse correctly under
cbor_tag_handler_t::ignore/store, same as 0xC6..0xD4/0xD8..0xDB.
Remove those five bullets and cross-reference the "Tagged items"
warning below, matching the equivalent docs fix landed independently
in PR nlohmann#5367.

Also add a cbor_tag_handler_t::store test that wraps a binary
payload (not just a string) for every byte in 0xC0..0xD7, confirming
these tags are unwrapped the same way as 0xC6..0xD4 rather than
mistaken for the 0xD8..0xDB binary-subtype marker syntax, per review
feedback on nlohmann#5331.

Signed-off-by: sahilkamate03 <45514385+sahilkamate03@users.noreply.github.com>
@sahilkamate03
sahilkamate03 force-pushed the fix/issue-5315-cbor-ignore-tags branch from ad29f64 to 2858840 Compare August 7, 2026 20:48
@github-actions github-actions Bot added M and removed L CI CMake labels Aug 7, 2026
The "Incomplete mapping" warning still listed tags 0-5 (date/time,
bignum, decimal fraction, bigfloat) and 21-23 (expected conversions)
as unsupported, even though they now parse correctly under
cbor_tag_handler_t::ignore/store, same as 0xC6..0xD4/0xD8..0xDB.
Remove those five bullets and cross-reference the "Tagged items"
warning below, matching the equivalent docs fix landed independently
in PR nlohmann#5367.

Also add a cbor_tag_handler_t::store test that wraps a binary
payload (not just a string) for every byte in 0xC0..0xD7, confirming
these tags are unwrapped the same way as 0xC6..0xD4 rather than
mistaken for the 0xD8..0xDB binary-subtype marker syntax, per review
feedback on nlohmann#5331.

Signed-off-by: sahilkamate03 <45514385+sahilkamate03@users.noreply.github.com>
@sahilkamate03
sahilkamate03 force-pushed the fix/issue-5315-cbor-ignore-tags branch from 2858840 to 6b54d47 Compare August 10, 2026 14:39
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