mirror of
https://github.com/nlohmann/json.git
synced 2026-11-03 19:29:22 +00:00
* Fix the build of develop: tests from #5997 and #5991 - unit-msgpack-cpp17: assign the result of json::parse in CHECK_THROWS_WITH_AS (GCC -Werror=unused-result) - unit-json_view: failing_allocator::allocate is [[noreturn]] (clang -Wmissing-noreturn) - unit-class_lexer: build the quoted string once (clang-tidy performance-inefficient-string-concatenation) - unit-allocator: sweep_allocator provides pointer, reference and size typedefs, which GCC 4.8's std::map takes from the allocator - unit-allocator: skip the "sax_parse into an existing value" sweep with iterator debugging, like the parser callback sweep: MSVC's std::vector default constructor is noexcept but allocates its debug proxy through the allocator, so a failing allocation in create<array_t>() terminates Signed-off-by: Niels Lohmann <mail@nlohmann.me> * Fix the remaining CI failures of the tests from #5997 and #5991 - unit-custom-object-key-type: drop the redundant member initializer and return a braced init list (clang-tidy); direct-initialize the converted value, as copy-initialization makes GCC 4.8 instantiate the copy constructor, which needs a range constructor strict_object lacks - unit-stream-bulk-scan: pick the claimed get area size by tag dispatch instead of a constant condition (MSVC C4127) - unit-allocator: skip the parser callback and sax_parse sweeps with Clang 3.4 and 3.5, which leak memory when an element constructor throws inside a libstdc++ std::map copy or std::vector reallocation Signed-off-by: Niels Lohmann <mail@nlohmann.me> * Fix the CI failures that the first failing TU of each job hid - unit-stream-bulk-scan: compute the claimed size without a condition; the tag-dispatched template was unused with a 64-bit std::size_t (-Wunused-template) - unit-json_view: give failing_allocator the typedefs, rebind and members that GCC 4.8's std::map takes from the allocator directly - clang-tidy hits in the tests from #5997: raw string literals (unit-json_view), redundant c_str() and a NOLINT for &text[0] (unit-locale-cpp), reserve() before a loop (unit-ordered_json), and a NOLINT for a return that a braced list would turn into an array (unit-regression1) Signed-off-by: Niels Lohmann <mail@nlohmann.me> * Skip the 3 GiB get-area test with a 32-bit std::size_t in the preprocessor The claimed size was a constant 0 on Win32, so `claimed == 0 || ...` was a constant condition and MSVC reported C4127. Guard the section with `#if SIZE_MAX > UINT32_MAX` instead, as unit-msgpack-custom-types.cpp does. Signed-off-by: Niels Lohmann <mail@nlohmann.me> * Silence modernize-use-transparent-functors for failing_map in unit-json_view std::less<> needs C++14, and the test is also built as C++11. Signed-off-by: Niels Lohmann <mail@nlohmann.me> --------- Signed-off-by: Niels Lohmann <mail@nlohmann.me>
131 lines
4.3 KiB
C++
131 lines
4.3 KiB
C++
// __ _____ _____ _____
|
|
// __| | __| | | | JSON for Modern C++ (supporting code)
|
|
// | | |__ | | | | | | version 3.12.0
|
|
// |_____|_____|_____|_|___| https://github.com/nlohmann/json
|
|
//
|
|
// SPDX-FileCopyrightText: 2013-2026 Niels Lohmann <https://nlohmann.me>
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
// This file contains the C++17-only part of unit-msgpack.cpp (std::byte
|
|
// input). It is kept in a separate translation unit so the (much larger)
|
|
// unit-msgpack.cpp does not need to be compiled and run a second time just
|
|
// for this one test case (#5418).
|
|
|
|
#include "doctest_compatibility.h"
|
|
|
|
#include <nlohmann/json.hpp>
|
|
using nlohmann::json;
|
|
|
|
#ifdef JSON_HAS_CPP_17
|
|
#include <cstddef>
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
// Test suite for verifying MessagePack handling with std::byte input
|
|
TEST_CASE("MessagePack with std::byte")
|
|
{
|
|
|
|
SECTION("std::byte compatibility")
|
|
{
|
|
SECTION("vector roundtrip")
|
|
{
|
|
json original =
|
|
{
|
|
{"name", "test"},
|
|
{"value", 42},
|
|
{"array", {1, 2, 3}}
|
|
};
|
|
|
|
std::vector<uint8_t> temp = json::to_msgpack(original);
|
|
// Convert the uint8_t vector to std::byte vector
|
|
std::vector<std::byte> msgpack_data(temp.size());
|
|
for (size_t i = 0; i < temp.size(); ++i)
|
|
{
|
|
msgpack_data[i] = std::byte(temp[i]);
|
|
}
|
|
// Deserialize from std::byte vector back to JSON
|
|
json from_bytes;
|
|
CHECK_NOTHROW(from_bytes = json::from_msgpack(msgpack_data));
|
|
|
|
CHECK(from_bytes == original);
|
|
}
|
|
|
|
SECTION("empty vector")
|
|
{
|
|
const std::vector<std::byte> empty_data;
|
|
CHECK_THROWS_WITH_AS([&]()
|
|
{
|
|
[[maybe_unused]] auto result = json::from_msgpack(empty_data);
|
|
return true;
|
|
}
|
|
(),
|
|
"[json.exception.parse_error.110] parse error at byte 1: syntax error while parsing MessagePack value: unexpected end of input",
|
|
json::parse_error&);
|
|
}
|
|
|
|
SECTION("comparison with workaround")
|
|
{
|
|
json original =
|
|
{
|
|
{"string", "hello"},
|
|
{"integer", 42},
|
|
{"float", 3.14},
|
|
{"boolean", true},
|
|
{"null", nullptr},
|
|
{"array", {1, 2, 3}},
|
|
{"object", {{"key", "value"}}}
|
|
};
|
|
|
|
std::vector<uint8_t> temp = json::to_msgpack(original);
|
|
|
|
std::vector<std::byte> msgpack_data(temp.size());
|
|
for (size_t i = 0; i < temp.size(); ++i)
|
|
{
|
|
msgpack_data[i] = std::byte(temp[i]);
|
|
}
|
|
// Attempt direct deserialization using std::byte input
|
|
const json direct_result = json::from_msgpack(msgpack_data);
|
|
|
|
// Test the workaround approach: reinterpret as unsigned char* and use iterator range
|
|
const auto* const char_start = reinterpret_cast<unsigned char const*>(msgpack_data.data());
|
|
const auto* const char_end = char_start + msgpack_data.size();
|
|
json workaround_result = json::from_msgpack(char_start, char_end);
|
|
|
|
// Verify that the final deserialized JSON matches the original JSON
|
|
CHECK(direct_result == workaround_result);
|
|
CHECK(direct_result == original);
|
|
}
|
|
}
|
|
}
|
|
|
|
// JSON text (not MessagePack) as std::byte input: the error position is
|
|
// computed from the bytes consumed so far
|
|
TEST_CASE("JSON text with std::byte")
|
|
{
|
|
const auto to_bytes = [](const std::string & text)
|
|
{
|
|
std::vector<std::byte> bytes;
|
|
for (const char c : text)
|
|
{
|
|
bytes.push_back(static_cast<std::byte>(c));
|
|
}
|
|
return bytes;
|
|
};
|
|
|
|
SECTION("valid text")
|
|
{
|
|
const json j = json::parse(to_bytes("[1,\n2]"));
|
|
CHECK(j == json({1, 2}));
|
|
CHECK(json::accept(to_bytes("[1,\n2]")));
|
|
}
|
|
|
|
SECTION("invalid text")
|
|
{
|
|
CHECK_FALSE(json::accept(to_bytes("[1,\n2,")));
|
|
json _;
|
|
CHECK_THROWS_WITH_AS(_ = json::parse(to_bytes("[1,\n2,")),
|
|
"[json.exception.parse_error.101] parse error at line 2, column 3: syntax error while parsing value - unexpected end of input; expected '[', '{', or a literal", json::parse_error&);
|
|
}
|
|
}
|
|
#endif
|