From 509c07041f4f35daa52f5cc48c9041eda69b84bf Mon Sep 17 00:00:00 2001 From: Niels Lohmann Date: Sun, 27 Sep 2026 17:50:19 +0200 Subject: [PATCH 1/4] Fix CI: clang-tidy and clang/libstdc++ 10 in the MessagePack size tests (#5599) The tests added by #5515 fail two ways on develop: - clang-tidy reports the size() overrides of huge_string and huge_binary (readability-convert-member-functions-to-static) and the non-const test value (misc-const-correctness); mark them like the #5584 types - clang with libstdc++ 10 cannot compile the file for C++17: the std::filesystem::path conversion considered for huge_string, a class derived from std::string, is ambiguous. Guard it with JSON_TEST_BEYOND_UINT32_STRING, which #5584 introduced for the same reason, and define that macro before both test blocks. Signed-off-by: Niels Lohmann --- tests/src/unit-msgpack.cpp | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/tests/src/unit-msgpack.cpp b/tests/src/unit-msgpack.cpp index e7616b27f..077073052 100644 --- a/tests/src/unit-msgpack.cpp +++ b/tests/src/unit-msgpack.cpp @@ -2165,6 +2165,13 @@ TEST_CASE("MessagePack with std::byte") #endif // the fake sizes below do not fit into a 32-bit std::size_t +// with clang and libstdc++ 10, the std::filesystem::path conversion that +// C++17 builds consider for every string type is ambiguous for a class +// derived from std::string, so the string case is not tested there +#if !(defined(__clang__) && defined(_GLIBCXX_RELEASE) && _GLIBCXX_RELEASE < 11) + #define JSON_TEST_BEYOND_UINT32_STRING 1 +#endif + #if SIZE_MAX > UINT32_MAX template> struct huge_array : std::vector @@ -2262,11 +2269,12 @@ TEST_CASE("MessagePack Size above uint32 for object") object.fake_size = false; } +#ifdef JSON_TEST_BEYOND_UINT32_STRING struct huge_string : std::string { using std::string::string; - std::size_t size() const noexcept + std::size_t size() const noexcept // NOLINT(readability-convert-member-functions-to-static) { return static_cast(UINT32_MAX) + 1ULL; } @@ -2287,20 +2295,20 @@ using huge_string_json = nlohmann::basic_json < TEST_CASE("MessagePack Size above uint32 for string") { - - huge_string_json j = "hello"; + const huge_string_json j = "hello"; CHECK_THROWS_WITH_AS( huge_string_json::to_msgpack(j), "[json.exception.out_of_range.412] MessagePack length 4294967296 exceeds maximum of 4294967295", json::out_of_range&); } +#endif struct huge_binary : std::vector { using std::vector::vector; - std::size_t size() const noexcept + std::size_t size() const noexcept // NOLINT(readability-convert-member-functions-to-static) { return static_cast(UINT32_MAX) + 1ULL; } @@ -2355,13 +2363,6 @@ class beyond_uint32_binary_t : public std::vector } }; -// with clang and libstdc++ 10, the std::filesystem::path conversion that -// C++17 builds consider for every string type is ambiguous for a class -// derived from std::string, so the string case is not tested there -#if !(defined(__clang__) && defined(_GLIBCXX_RELEASE) && _GLIBCXX_RELEASE < 11) - #define JSON_TEST_BEYOND_UINT32_STRING 1 -#endif - #ifdef JSON_TEST_BEYOND_UINT32_STRING class beyond_uint32_string_t : public std::string { From 56ddcb65f018e06709472fa8b962cc60195e6d56 Mon Sep 17 00:00:00 2001 From: Niels Lohmann Date: Sun, 27 Sep 2026 20:40:13 +0200 Subject: [PATCH 2/4] Fix documentation style check: wrap long line in cbor_tag_handler_t.md (#5603) The line added in #5559 exceeded the 160-character limit enforced by docs/mkdocs/scripts/check_structure.py, breaking the documentation build. Signed-off-by: Niels Lohmann --- docs/mkdocs/docs/api/basic_json/cbor_tag_handler_t.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/mkdocs/docs/api/basic_json/cbor_tag_handler_t.md b/docs/mkdocs/docs/api/basic_json/cbor_tag_handler_t.md index cea009e4e..28bd99535 100644 --- a/docs/mkdocs/docs/api/basic_json/cbor_tag_handler_t.md +++ b/docs/mkdocs/docs/api/basic_json/cbor_tag_handler_t.md @@ -18,7 +18,8 @@ ignore : ignore tags store -: store tagged byte strings (for bytes 0xd8..0xdb) as binary values with the tag as subtype; other tagged values are read as if the tag were ignored. If several tags precede a byte string, only the innermost one is stored. +: store tagged byte strings (for bytes 0xd8..0xdb) as binary values with the tag as subtype; other tagged values are + read as if the tag were ignored. If several tags precede a byte string, only the innermost one is stored. ## Examples From de6acd651ec5c6849b6b4460abd031f6fbcc42fd Mon Sep 17 00:00:00 2001 From: Niels Lohmann Date: Sun, 27 Sep 2026 20:40:33 +0200 Subject: [PATCH 3/4] Fix CI: wrap an overlong line in the cbor_tag_handler_t documentation (#5602) #5559 added a 224-character line to cbor_tag_handler_t.md; the documentation style check allows at most 160. Signed-off-by: Niels Lohmann From 373005f7accebb2eff11d2837c468094e3116b38 Mon Sep 17 00:00:00 2001 From: Niels Lohmann Date: Sun, 27 Sep 2026 20:57:16 +0200 Subject: [PATCH 4/4] Fix MSVC: avoid reserving by faked size in MessagePack size tests (#5604) The "Size above uint32" tests for arrays and objects fake a container size of 2^32 and expect to_msgpack() to throw out_of_range.412. But to_msgpack(j) first reserves binary_reserve_hint(j) bytes, which is size + 1 for arrays and 2 * size + 1 for objects, i.e. 4 or 8 GiB. Linux and macOS overcommit, so the reservation succeeds; on Windows it throws std::bad_alloc before the size check is reached (seen with msvc-vs2026 Debug x64 on the object test). Write into a caller-owned vector instead, so nothing is reserved. Signed-off-by: Niels Lohmann --- tests/src/unit-msgpack.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/tests/src/unit-msgpack.cpp b/tests/src/unit-msgpack.cpp index 077073052..de4255b4a 100644 --- a/tests/src/unit-msgpack.cpp +++ b/tests/src/unit-msgpack.cpp @@ -2208,8 +2208,11 @@ TEST_CASE("MessagePack Size above uint32 for array") auto& array = j.get_ref(); array.fake_size = true; + // write into a caller-owned vector: to_msgpack(j) reserves space based on + // the (faked) element count, which fails with bad_alloc on Windows + std::vector result; CHECK_THROWS_WITH_AS( - huge_array_json::to_msgpack(j), + huge_array_json::to_msgpack(j, result), "[json.exception.out_of_range.412] MessagePack length 4294967296 exceeds maximum of 4294967295", json::out_of_range&); @@ -2261,8 +2264,11 @@ TEST_CASE("MessagePack Size above uint32 for object") auto& object = j.get_ref(); object.fake_size = true; + // write into a caller-owned vector: to_msgpack(j) reserves space based on + // the (faked) element count, which fails with bad_alloc on Windows + std::vector result; CHECK_THROWS_WITH_AS( - huge_object_json::to_msgpack(j), + huge_object_json::to_msgpack(j, result), "[json.exception.out_of_range.412] MessagePack length 4294967296 exceeds maximum of 4294967295", json::out_of_range&);