From 4d4181246e3e45e7ea4cb115b31cf66aa5d2b6b7 Mon Sep 17 00:00:00 2001 From: sahilkamate03 <45514385+sahilkamate03@users.noreply.github.com> Date: Wed, 29 Jul 2026 13:25:57 +0530 Subject: [PATCH] Fix CBOR tag handlers not recognizing tags 0-5 and 21-23 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 #5315 Signed-off-by: sahilkamate03 <45514385+sahilkamate03@users.noreply.github.com> --- docs/mkdocs/docs/features/binary_formats/cbor.md | 2 +- include/nlohmann/detail/input/binary_reader.hpp | 11 ++++++++++- single_include/nlohmann/json.hpp | 11 ++++++++++- tests/src/unit-cbor.cpp | 6 ++++-- 4 files changed, 25 insertions(+), 5 deletions(-) diff --git a/docs/mkdocs/docs/features/binary_formats/cbor.md b/docs/mkdocs/docs/features/binary_formats/cbor.md index d385c2a4c2..5bf9f912d3 100644 --- a/docs/mkdocs/docs/features/binary_formats/cbor.md +++ b/docs/mkdocs/docs/features/binary_formats/cbor.md @@ -181,7 +181,7 @@ The library maps CBOR types to JSON value types as follows: !!! warning "Tagged items" - Tagged items will throw a parse error by default. They can be ignored by passing `cbor_tag_handler_t::ignore` to function `from_cbor`. They can be stored by passing `cbor_tag_handler_t::store` to function `from_cbor`. + Tagged items (`0xC0`..`0xDB`) will throw a parse error by default. They can be ignored by passing `cbor_tag_handler_t::ignore` to function `from_cbor`. They can be stored by passing `cbor_tag_handler_t::store` to function `from_cbor`. ??? example diff --git a/include/nlohmann/detail/input/binary_reader.hpp b/include/nlohmann/detail/input/binary_reader.hpp index ad862827d0..009db9bcbc 100644 --- a/include/nlohmann/detail/input/binary_reader.hpp +++ b/include/nlohmann/detail/input/binary_reader.hpp @@ -760,7 +760,13 @@ class binary_reader case 0xBF: // map (indefinite length) return get_cbor_object(detail::unknown_size(), tag_handler); - case 0xC6: // tagged item + case 0xC0: // tagged item + case 0xC1: + case 0xC2: + case 0xC3: + case 0xC4: + case 0xC5: + case 0xC6: case 0xC7: case 0xC8: case 0xC9: @@ -775,6 +781,9 @@ class binary_reader case 0xD2: case 0xD3: case 0xD4: + case 0xD5: + case 0xD6: + case 0xD7: case 0xD8: // tagged item (1 byte follows) case 0xD9: // tagged item (2 bytes follow) case 0xDA: // tagged item (4 bytes follow) diff --git a/single_include/nlohmann/json.hpp b/single_include/nlohmann/json.hpp index 5ead5275a3..25698864a8 100644 --- a/single_include/nlohmann/json.hpp +++ b/single_include/nlohmann/json.hpp @@ -11309,7 +11309,13 @@ class binary_reader case 0xBF: // map (indefinite length) return get_cbor_object(detail::unknown_size(), tag_handler); - case 0xC6: // tagged item + case 0xC0: // tagged item + case 0xC1: + case 0xC2: + case 0xC3: + case 0xC4: + case 0xC5: + case 0xC6: case 0xC7: case 0xC8: case 0xC9: @@ -11324,6 +11330,9 @@ class binary_reader case 0xD2: case 0xD3: case 0xD4: + case 0xD5: + case 0xD6: + case 0xD7: case 0xD8: // tagged item (1 byte follows) case 0xD9: // tagged item (2 bytes follow) case 0xDA: // tagged item (4 bytes follow) diff --git a/tests/src/unit-cbor.cpp b/tests/src/unit-cbor.cpp index af73642997..fdaab4e828 100644 --- a/tests/src/unit-cbor.cpp +++ b/tests/src/unit-cbor.cpp @@ -2529,11 +2529,13 @@ TEST_CASE("Tagged values") const json j = "s"; auto v = json::to_cbor(j); - SECTION("0xC6..0xD4") + SECTION("0xC0..0xD7") { for (const auto b : std::vector { - 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 }) { CAPTURE(b);