1c5f01b2fSopenharmony_ci//     __ _____ _____ _____
2c5f01b2fSopenharmony_ci//  __|  |   __|     |   | |  JSON for Modern C++ (supporting code)
3c5f01b2fSopenharmony_ci// |  |  |__   |  |  | | | |  version 3.11.2
4c5f01b2fSopenharmony_ci// |_____|_____|_____|_|___|  https://github.com/nlohmann/json
5c5f01b2fSopenharmony_ci//
6c5f01b2fSopenharmony_ci// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
7c5f01b2fSopenharmony_ci// SPDX-License-Identifier: MIT
8c5f01b2fSopenharmony_ci
9c5f01b2fSopenharmony_ci#include "doctest_compatibility.h"
10c5f01b2fSopenharmony_ci
11c5f01b2fSopenharmony_ci// for some reason including this after the json header leads to linker errors with VS 2017...
12c5f01b2fSopenharmony_ci#include <locale>
13c5f01b2fSopenharmony_ci
14c5f01b2fSopenharmony_ci#define JSON_TESTS_PRIVATE
15c5f01b2fSopenharmony_ci#include <nlohmann/json.hpp>
16c5f01b2fSopenharmony_ciusing nlohmann::json;
17c5f01b2fSopenharmony_ci#ifdef JSON_TEST_NO_GLOBAL_UDLS
18c5f01b2fSopenharmony_ci    using namespace nlohmann::literals; // NOLINT(google-build-using-namespace)
19c5f01b2fSopenharmony_ci#endif
20c5f01b2fSopenharmony_ci
21c5f01b2fSopenharmony_ci#include <fstream>
22c5f01b2fSopenharmony_ci#include <sstream>
23c5f01b2fSopenharmony_ci#include <list>
24c5f01b2fSopenharmony_ci#include <cstdio>
25c5f01b2fSopenharmony_ci#include "make_test_data_available.hpp"
26c5f01b2fSopenharmony_ci
27c5f01b2fSopenharmony_ci#ifdef JSON_HAS_CPP_17
28c5f01b2fSopenharmony_ci    #include <variant>
29c5f01b2fSopenharmony_ci#endif
30c5f01b2fSopenharmony_ci
31c5f01b2fSopenharmony_ci#include "fifo_map.hpp"
32c5f01b2fSopenharmony_ci
33c5f01b2fSopenharmony_ci/////////////////////////////////////////////////////////////////////
34c5f01b2fSopenharmony_ci// for #972
35c5f01b2fSopenharmony_ci/////////////////////////////////////////////////////////////////////
36c5f01b2fSopenharmony_ci
37c5f01b2fSopenharmony_citemplate<class K, class V, class dummy_compare, class A>
38c5f01b2fSopenharmony_ciusing my_workaround_fifo_map = nlohmann::fifo_map<K, V, nlohmann::fifo_map_compare<K>, A>;
39c5f01b2fSopenharmony_ciusing my_json = nlohmann::basic_json<my_workaround_fifo_map>;
40c5f01b2fSopenharmony_ci
41c5f01b2fSopenharmony_ci/////////////////////////////////////////////////////////////////////
42c5f01b2fSopenharmony_ci// for #977
43c5f01b2fSopenharmony_ci/////////////////////////////////////////////////////////////////////
44c5f01b2fSopenharmony_ci
45c5f01b2fSopenharmony_cinamespace ns
46c5f01b2fSopenharmony_ci{
47c5f01b2fSopenharmony_cistruct foo
48c5f01b2fSopenharmony_ci{
49c5f01b2fSopenharmony_ci    int x;
50c5f01b2fSopenharmony_ci};
51c5f01b2fSopenharmony_ci
52c5f01b2fSopenharmony_citemplate <typename, typename SFINAE = void>
53c5f01b2fSopenharmony_cistruct foo_serializer;
54c5f01b2fSopenharmony_ci
55c5f01b2fSopenharmony_citemplate<typename T>
56c5f01b2fSopenharmony_cistruct foo_serializer<T, typename std::enable_if<std::is_same<foo, T>::value>::type>
57c5f01b2fSopenharmony_ci{
58c5f01b2fSopenharmony_ci    template <typename BasicJsonType>
59c5f01b2fSopenharmony_ci    static void to_json(BasicJsonType& j, const T& value)
60c5f01b2fSopenharmony_ci    {
61c5f01b2fSopenharmony_ci        j = BasicJsonType{{"x", value.x}};
62c5f01b2fSopenharmony_ci    }
63c5f01b2fSopenharmony_ci    template <typename BasicJsonType>
64c5f01b2fSopenharmony_ci    static void from_json(const BasicJsonType& j, T& value)     // !!!
65c5f01b2fSopenharmony_ci    {
66c5f01b2fSopenharmony_ci        nlohmann::from_json(j.at("x"), value.x);
67c5f01b2fSopenharmony_ci    }
68c5f01b2fSopenharmony_ci};
69c5f01b2fSopenharmony_ci
70c5f01b2fSopenharmony_citemplate<typename T>
71c5f01b2fSopenharmony_cistruct foo_serializer < T, typename std::enable_if < !std::is_same<foo, T>::value >::type >
72c5f01b2fSopenharmony_ci{
73c5f01b2fSopenharmony_ci    template <typename BasicJsonType>
74c5f01b2fSopenharmony_ci    static void to_json(BasicJsonType& j, const T& value) noexcept // NOLINT(bugprone-exception-escape)
75c5f01b2fSopenharmony_ci    {
76c5f01b2fSopenharmony_ci        ::nlohmann::to_json(j, value);
77c5f01b2fSopenharmony_ci    }
78c5f01b2fSopenharmony_ci    template <typename BasicJsonType>
79c5f01b2fSopenharmony_ci    static void from_json(const BasicJsonType& j, T& value)   //!!!
80c5f01b2fSopenharmony_ci    {
81c5f01b2fSopenharmony_ci        ::nlohmann::from_json(j, value);
82c5f01b2fSopenharmony_ci    }
83c5f01b2fSopenharmony_ci};
84c5f01b2fSopenharmony_ci} // namespace ns
85c5f01b2fSopenharmony_ci
86c5f01b2fSopenharmony_ciusing foo_json = nlohmann::basic_json<std::map, std::vector, std::string, bool, std::int64_t,
87c5f01b2fSopenharmony_ci      std::uint64_t, double, std::allocator, ns::foo_serializer, std::vector<std::uint8_t>>;
88c5f01b2fSopenharmony_ci
89c5f01b2fSopenharmony_ci/////////////////////////////////////////////////////////////////////
90c5f01b2fSopenharmony_ci// for #805
91c5f01b2fSopenharmony_ci/////////////////////////////////////////////////////////////////////
92c5f01b2fSopenharmony_ci
93c5f01b2fSopenharmony_cinamespace
94c5f01b2fSopenharmony_ci{
95c5f01b2fSopenharmony_cistruct nocopy // NOLINT(cppcoreguidelines-special-member-functions,hicpp-special-member-functions)
96c5f01b2fSopenharmony_ci{
97c5f01b2fSopenharmony_ci    nocopy() = default;
98c5f01b2fSopenharmony_ci    nocopy(const nocopy&) = delete;
99c5f01b2fSopenharmony_ci    nocopy(nocopy&&) = delete;
100c5f01b2fSopenharmony_ci    nocopy& operator=(const nocopy&) = delete;
101c5f01b2fSopenharmony_ci    nocopy& operator=(nocopy&&) = delete;
102c5f01b2fSopenharmony_ci
103c5f01b2fSopenharmony_ci    int val = 0;
104c5f01b2fSopenharmony_ci
105c5f01b2fSopenharmony_ci    friend void to_json(json& j, const nocopy& n)
106c5f01b2fSopenharmony_ci    {
107c5f01b2fSopenharmony_ci        j = {{"val", n.val}};
108c5f01b2fSopenharmony_ci    }
109c5f01b2fSopenharmony_ci};
110c5f01b2fSopenharmony_ci} // namespace
111c5f01b2fSopenharmony_ci
112c5f01b2fSopenharmony_ciTEST_CASE("regression tests 1")
113c5f01b2fSopenharmony_ci{
114c5f01b2fSopenharmony_ci    SECTION("issue #60 - Double quotation mark is not parsed correctly")
115c5f01b2fSopenharmony_ci    {
116c5f01b2fSopenharmony_ci        SECTION("escape_doublequote")
117c5f01b2fSopenharmony_ci        {
118c5f01b2fSopenharmony_ci            const auto* s = R"(["\"foo\""])";
119c5f01b2fSopenharmony_ci            json j = json::parse(s);
120c5f01b2fSopenharmony_ci            auto expected = R"(["\"foo\""])"_json;
121c5f01b2fSopenharmony_ci            CHECK(j == expected);
122c5f01b2fSopenharmony_ci        }
123c5f01b2fSopenharmony_ci    }
124c5f01b2fSopenharmony_ci
125c5f01b2fSopenharmony_ci    SECTION("issue #70 - Handle infinity and NaN cases")
126c5f01b2fSopenharmony_ci    {
127c5f01b2fSopenharmony_ci        // previously, NAN/INFINITY created a null value; now, the values are
128c5f01b2fSopenharmony_ci        // properly stored, but are dumped as "null"
129c5f01b2fSopenharmony_ci        SECTION("NAN value")
130c5f01b2fSopenharmony_ci        {
131c5f01b2fSopenharmony_ci            CHECK(json(NAN).dump() == "null");
132c5f01b2fSopenharmony_ci            CHECK(json(json::number_float_t(NAN)).dump() == "null");
133c5f01b2fSopenharmony_ci        }
134c5f01b2fSopenharmony_ci
135c5f01b2fSopenharmony_ci        SECTION("infinity")
136c5f01b2fSopenharmony_ci        {
137c5f01b2fSopenharmony_ci            CHECK(json(INFINITY).dump() == "null");
138c5f01b2fSopenharmony_ci            CHECK(json(json::number_float_t(INFINITY)).dump() == "null");
139c5f01b2fSopenharmony_ci        }
140c5f01b2fSopenharmony_ci
141c5f01b2fSopenharmony_ci        // With 3.0.0, the semantics of this changed: NAN and infinity are
142c5f01b2fSopenharmony_ci        // stored properly inside the JSON value (no exception or conversion
143c5f01b2fSopenharmony_ci        // to null), but are serialized as null.
144c5f01b2fSopenharmony_ci        SECTION("NAN value")
145c5f01b2fSopenharmony_ci        {
146c5f01b2fSopenharmony_ci            json j1 = NAN;
147c5f01b2fSopenharmony_ci            CHECK(j1.is_number_float());
148c5f01b2fSopenharmony_ci            json::number_float_t f1{j1};
149c5f01b2fSopenharmony_ci            CHECK(std::isnan(f1));
150c5f01b2fSopenharmony_ci
151c5f01b2fSopenharmony_ci            json j2 = static_cast<json::number_float_t>(NAN);
152c5f01b2fSopenharmony_ci            CHECK(j2.is_number_float());
153c5f01b2fSopenharmony_ci            json::number_float_t f2{j2};
154c5f01b2fSopenharmony_ci            CHECK(std::isnan(f2));
155c5f01b2fSopenharmony_ci        }
156c5f01b2fSopenharmony_ci
157c5f01b2fSopenharmony_ci        SECTION("infinity")
158c5f01b2fSopenharmony_ci        {
159c5f01b2fSopenharmony_ci            json j1 = INFINITY;
160c5f01b2fSopenharmony_ci            CHECK(j1.is_number_float());
161c5f01b2fSopenharmony_ci            json::number_float_t f1{j1};
162c5f01b2fSopenharmony_ci            CHECK(!std::isfinite(f1));
163c5f01b2fSopenharmony_ci
164c5f01b2fSopenharmony_ci            json j2 = static_cast<json::number_float_t>(INFINITY);
165c5f01b2fSopenharmony_ci            CHECK(j2.is_number_float());
166c5f01b2fSopenharmony_ci            json::number_float_t f2{j2};
167c5f01b2fSopenharmony_ci            CHECK(!std::isfinite(f2));
168c5f01b2fSopenharmony_ci        }
169c5f01b2fSopenharmony_ci    }
170c5f01b2fSopenharmony_ci
171c5f01b2fSopenharmony_ci    SECTION("pull request #71 - handle enum type")
172c5f01b2fSopenharmony_ci    {
173c5f01b2fSopenharmony_ci        enum { t = 0, u = 102};
174c5f01b2fSopenharmony_ci        json j = json::array();
175c5f01b2fSopenharmony_ci        j.push_back(t);
176c5f01b2fSopenharmony_ci
177c5f01b2fSopenharmony_ci        // maybe this is not the place to test this?
178c5f01b2fSopenharmony_ci        json j2 = u;
179c5f01b2fSopenharmony_ci
180c5f01b2fSopenharmony_ci        auto anon_enum_value = j2.get<decltype(u)>();
181c5f01b2fSopenharmony_ci        CHECK(u == anon_enum_value);
182c5f01b2fSopenharmony_ci
183c5f01b2fSopenharmony_ci        // check if the actual value was stored
184c5f01b2fSopenharmony_ci        CHECK(j2 == 102);
185c5f01b2fSopenharmony_ci
186c5f01b2fSopenharmony_ci        static_assert(std::is_same<decltype(anon_enum_value), decltype(u)>::value, "types must be the same");
187c5f01b2fSopenharmony_ci
188c5f01b2fSopenharmony_ci        j.push_back(json::object(
189c5f01b2fSopenharmony_ci        {
190c5f01b2fSopenharmony_ci            {"game_type", t}
191c5f01b2fSopenharmony_ci        }));
192c5f01b2fSopenharmony_ci    }
193c5f01b2fSopenharmony_ci
194c5f01b2fSopenharmony_ci    SECTION("issue #76 - dump() / parse() not idempotent")
195c5f01b2fSopenharmony_ci    {
196c5f01b2fSopenharmony_ci        // create JSON object
197c5f01b2fSopenharmony_ci        json fields;
198c5f01b2fSopenharmony_ci        fields["one"] = std::string("one");
199c5f01b2fSopenharmony_ci        fields["two"] = std::string("two three");
200c5f01b2fSopenharmony_ci        fields["three"] = std::string("three \"four\"");
201c5f01b2fSopenharmony_ci
202c5f01b2fSopenharmony_ci        // create another JSON object by deserializing the serialization
203c5f01b2fSopenharmony_ci        std::string payload = fields.dump();
204c5f01b2fSopenharmony_ci        json parsed_fields = json::parse(payload);
205c5f01b2fSopenharmony_ci
206c5f01b2fSopenharmony_ci        // check individual fields to match both objects
207c5f01b2fSopenharmony_ci        CHECK(parsed_fields["one"] == fields["one"]);
208c5f01b2fSopenharmony_ci        CHECK(parsed_fields["two"] == fields["two"]);
209c5f01b2fSopenharmony_ci        CHECK(parsed_fields["three"] == fields["three"]);
210c5f01b2fSopenharmony_ci
211c5f01b2fSopenharmony_ci        // check individual fields to match original input
212c5f01b2fSopenharmony_ci        CHECK(parsed_fields["one"] == std::string("one"));
213c5f01b2fSopenharmony_ci        CHECK(parsed_fields["two"] == std::string("two three"));
214c5f01b2fSopenharmony_ci        CHECK(parsed_fields["three"] == std::string("three \"four\""));
215c5f01b2fSopenharmony_ci
216c5f01b2fSopenharmony_ci        // check equality of the objects
217c5f01b2fSopenharmony_ci        CHECK(parsed_fields == fields);
218c5f01b2fSopenharmony_ci
219c5f01b2fSopenharmony_ci        // check equality of the serialized objects
220c5f01b2fSopenharmony_ci        CHECK(fields.dump() == parsed_fields.dump());
221c5f01b2fSopenharmony_ci
222c5f01b2fSopenharmony_ci        // check everything in one line
223c5f01b2fSopenharmony_ci        CHECK(fields == json::parse(fields.dump()));
224c5f01b2fSopenharmony_ci    }
225c5f01b2fSopenharmony_ci
226c5f01b2fSopenharmony_ci    SECTION("issue #82 - lexer::get_number return NAN")
227c5f01b2fSopenharmony_ci    {
228c5f01b2fSopenharmony_ci        const auto* const content = R"(
229c5f01b2fSopenharmony_ci        {
230c5f01b2fSopenharmony_ci            "Test":"Test1",
231c5f01b2fSopenharmony_ci            "Number":100,
232c5f01b2fSopenharmony_ci            "Foo":42.42
233c5f01b2fSopenharmony_ci        })";
234c5f01b2fSopenharmony_ci
235c5f01b2fSopenharmony_ci        std::stringstream ss;
236c5f01b2fSopenharmony_ci        ss << content;
237c5f01b2fSopenharmony_ci        json j;
238c5f01b2fSopenharmony_ci        ss >> j;
239c5f01b2fSopenharmony_ci
240c5f01b2fSopenharmony_ci        auto test = j["Test"].get<std::string>();
241c5f01b2fSopenharmony_ci        CHECK(test == "Test1");
242c5f01b2fSopenharmony_ci        int number{j["Number"]};
243c5f01b2fSopenharmony_ci        CHECK(number == 100);
244c5f01b2fSopenharmony_ci        float foo{j["Foo"]};
245c5f01b2fSopenharmony_ci        CHECK(static_cast<double>(foo) == Approx(42.42));
246c5f01b2fSopenharmony_ci    }
247c5f01b2fSopenharmony_ci
248c5f01b2fSopenharmony_ci    SECTION("issue #89 - nonstandard integer type")
249c5f01b2fSopenharmony_ci    {
250c5f01b2fSopenharmony_ci        // create JSON class with nonstandard integer number type
251c5f01b2fSopenharmony_ci        using custom_json =
252c5f01b2fSopenharmony_ci            nlohmann::basic_json<std::map, std::vector, std::string, bool, int32_t, uint32_t, float>;
253c5f01b2fSopenharmony_ci        custom_json j;
254c5f01b2fSopenharmony_ci        j["int_1"] = 1;
255c5f01b2fSopenharmony_ci        CHECK(j["int_1"] == 1);
256c5f01b2fSopenharmony_ci
257c5f01b2fSopenharmony_ci        // tests for correct handling of non-standard integers that overflow the type selected by the user
258c5f01b2fSopenharmony_ci
259c5f01b2fSopenharmony_ci        // unsigned integer object creation - expected to wrap and still be stored as an integer
260c5f01b2fSopenharmony_ci        j = 4294967296U; // 2^32
261c5f01b2fSopenharmony_ci        CHECK(static_cast<int>(j.type()) == static_cast<int>(custom_json::value_t::number_unsigned));
262c5f01b2fSopenharmony_ci        CHECK(j.get<uint32_t>() == 0);  // Wrap
263c5f01b2fSopenharmony_ci
264c5f01b2fSopenharmony_ci        // unsigned integer parsing - expected to overflow and be stored as a float
265c5f01b2fSopenharmony_ci        j = custom_json::parse("4294967296"); // 2^32
266c5f01b2fSopenharmony_ci        CHECK(static_cast<int>(j.type()) == static_cast<int>(custom_json::value_t::number_float));
267c5f01b2fSopenharmony_ci        CHECK(j.get<float>() == 4294967296.0f);
268c5f01b2fSopenharmony_ci
269c5f01b2fSopenharmony_ci        // integer object creation - expected to wrap and still be stored as an integer
270c5f01b2fSopenharmony_ci        j = -2147483649LL; // -2^31-1
271c5f01b2fSopenharmony_ci        CHECK(static_cast<int>(j.type()) == static_cast<int>(custom_json::value_t::number_integer));
272c5f01b2fSopenharmony_ci        CHECK(j.get<int32_t>() == 2147483647);  // Wrap
273c5f01b2fSopenharmony_ci
274c5f01b2fSopenharmony_ci        // integer parsing - expected to overflow and be stored as a float with rounding
275c5f01b2fSopenharmony_ci        j = custom_json::parse("-2147483649"); // -2^31
276c5f01b2fSopenharmony_ci        CHECK(static_cast<int>(j.type()) == static_cast<int>(custom_json::value_t::number_float));
277c5f01b2fSopenharmony_ci        CHECK(j.get<float>() == -2147483650.0f);
278c5f01b2fSopenharmony_ci    }
279c5f01b2fSopenharmony_ci
280c5f01b2fSopenharmony_ci    SECTION("issue #93 reverse_iterator operator inheritance problem")
281c5f01b2fSopenharmony_ci    {
282c5f01b2fSopenharmony_ci        {
283c5f01b2fSopenharmony_ci            json a = {1, 2, 3};
284c5f01b2fSopenharmony_ci            json::reverse_iterator rit = a.rbegin();
285c5f01b2fSopenharmony_ci            ++rit;
286c5f01b2fSopenharmony_ci            CHECK(*rit == json(2));
287c5f01b2fSopenharmony_ci            CHECK(rit.value() == json(2));
288c5f01b2fSopenharmony_ci        }
289c5f01b2fSopenharmony_ci        {
290c5f01b2fSopenharmony_ci            json a = {1, 2, 3};
291c5f01b2fSopenharmony_ci            json::reverse_iterator rit = ++a.rbegin();
292c5f01b2fSopenharmony_ci            CHECK(*rit == json(2));
293c5f01b2fSopenharmony_ci            CHECK(rit.value() == json(2));
294c5f01b2fSopenharmony_ci        }
295c5f01b2fSopenharmony_ci        {
296c5f01b2fSopenharmony_ci            json a = {1, 2, 3};
297c5f01b2fSopenharmony_ci            json::reverse_iterator rit = a.rbegin();
298c5f01b2fSopenharmony_ci            ++rit;
299c5f01b2fSopenharmony_ci            json b = {0, 0, 0};
300c5f01b2fSopenharmony_ci            std::transform(rit, a.rend(), b.rbegin(), [](json el)
301c5f01b2fSopenharmony_ci            {
302c5f01b2fSopenharmony_ci                return el;
303c5f01b2fSopenharmony_ci            });
304c5f01b2fSopenharmony_ci            CHECK(b == json({0, 1, 2}));
305c5f01b2fSopenharmony_ci        }
306c5f01b2fSopenharmony_ci        {
307c5f01b2fSopenharmony_ci            json a = {1, 2, 3};
308c5f01b2fSopenharmony_ci            json b = {0, 0, 0};
309c5f01b2fSopenharmony_ci            std::transform(++a.rbegin(), a.rend(), b.rbegin(), [](json el)
310c5f01b2fSopenharmony_ci            {
311c5f01b2fSopenharmony_ci                return el;
312c5f01b2fSopenharmony_ci            });
313c5f01b2fSopenharmony_ci            CHECK(b == json({0, 1, 2}));
314c5f01b2fSopenharmony_ci        }
315c5f01b2fSopenharmony_ci    }
316c5f01b2fSopenharmony_ci
317c5f01b2fSopenharmony_ci    SECTION("issue #100 - failed to iterator json object with reverse_iterator")
318c5f01b2fSopenharmony_ci    {
319c5f01b2fSopenharmony_ci        json config =
320c5f01b2fSopenharmony_ci        {
321c5f01b2fSopenharmony_ci            { "111", 111 },
322c5f01b2fSopenharmony_ci            { "112", 112 },
323c5f01b2fSopenharmony_ci            { "113", 113 }
324c5f01b2fSopenharmony_ci        };
325c5f01b2fSopenharmony_ci
326c5f01b2fSopenharmony_ci        std::stringstream ss;
327c5f01b2fSopenharmony_ci
328c5f01b2fSopenharmony_ci        for (auto it = config.begin(); it != config.end(); ++it)
329c5f01b2fSopenharmony_ci        {
330c5f01b2fSopenharmony_ci            ss << it.key() << ": " << it.value() << '\n';
331c5f01b2fSopenharmony_ci        }
332c5f01b2fSopenharmony_ci
333c5f01b2fSopenharmony_ci        for (auto it = config.rbegin(); it != config.rend(); ++it)
334c5f01b2fSopenharmony_ci        {
335c5f01b2fSopenharmony_ci            ss << it.key() << ": " << it.value() << '\n';
336c5f01b2fSopenharmony_ci        }
337c5f01b2fSopenharmony_ci
338c5f01b2fSopenharmony_ci        CHECK(ss.str() == "111: 111\n112: 112\n113: 113\n113: 113\n112: 112\n111: 111\n");
339c5f01b2fSopenharmony_ci    }
340c5f01b2fSopenharmony_ci
341c5f01b2fSopenharmony_ci    SECTION("issue #101 - binary string causes numbers to be dumped as hex")
342c5f01b2fSopenharmony_ci    {
343c5f01b2fSopenharmony_ci        int64_t number = 10;
344c5f01b2fSopenharmony_ci        std::string bytes{"\x00" "asdf\n", 6};
345c5f01b2fSopenharmony_ci        json j;
346c5f01b2fSopenharmony_ci        j["int64"] = number;
347c5f01b2fSopenharmony_ci        j["binary string"] = bytes;
348c5f01b2fSopenharmony_ci        // make sure the number is really printed as decimal "10" and not as
349c5f01b2fSopenharmony_ci        // hexadecimal "a"
350c5f01b2fSopenharmony_ci        CHECK(j.dump() == "{\"binary string\":\"\\u0000asdf\\n\",\"int64\":10}");
351c5f01b2fSopenharmony_ci    }
352c5f01b2fSopenharmony_ci
353c5f01b2fSopenharmony_ci    SECTION("issue #111 - subsequent unicode chars")
354c5f01b2fSopenharmony_ci    {
355c5f01b2fSopenharmony_ci        std::string bytes{0x7, 0x7};
356c5f01b2fSopenharmony_ci        json j;
357c5f01b2fSopenharmony_ci        j["string"] = bytes;
358c5f01b2fSopenharmony_ci        CHECK(j["string"] == "\u0007\u0007");
359c5f01b2fSopenharmony_ci    }
360c5f01b2fSopenharmony_ci
361c5f01b2fSopenharmony_ci#if JSON_USE_IMPLICIT_CONVERSIONS
362c5f01b2fSopenharmony_ci    SECTION("issue #144 - implicit assignment to std::string fails")
363c5f01b2fSopenharmony_ci    {
364c5f01b2fSopenharmony_ci        json o = {{"name", "value"}};
365c5f01b2fSopenharmony_ci
366c5f01b2fSopenharmony_ci        std::string s1 = o["name"];
367c5f01b2fSopenharmony_ci        CHECK(s1 == "value");
368c5f01b2fSopenharmony_ci
369c5f01b2fSopenharmony_ci        std::string s2;
370c5f01b2fSopenharmony_ci        s2 = o["name"];
371c5f01b2fSopenharmony_ci
372c5f01b2fSopenharmony_ci        CHECK(s2 == "value");
373c5f01b2fSopenharmony_ci
374c5f01b2fSopenharmony_ci        // improve coverage
375c5f01b2fSopenharmony_ci        o["int"] = 1;
376c5f01b2fSopenharmony_ci#if JSON_DIAGNOSTICS
377c5f01b2fSopenharmony_ci        CHECK_THROWS_WITH_AS(s2 = o["int"], "[json.exception.type_error.302] (/int) type must be string, but is number", json::type_error);
378c5f01b2fSopenharmony_ci#else
379c5f01b2fSopenharmony_ci        CHECK_THROWS_WITH_AS(s2 = o["int"], "[json.exception.type_error.302] type must be string, but is number", json::type_error);
380c5f01b2fSopenharmony_ci#endif
381c5f01b2fSopenharmony_ci    }
382c5f01b2fSopenharmony_ci#endif
383c5f01b2fSopenharmony_ci
384c5f01b2fSopenharmony_ci    SECTION("issue #146 - character following a surrogate pair is skipped")
385c5f01b2fSopenharmony_ci    {
386c5f01b2fSopenharmony_ci        CHECK(json::parse("\"\\ud80c\\udc60abc\"").get<json::string_t>() == "\xf0\x93\x81\xa0\x61\x62\x63");
387c5f01b2fSopenharmony_ci    }
388c5f01b2fSopenharmony_ci
389c5f01b2fSopenharmony_ci    SECTION("issue #171 - Cannot index by key of type static constexpr const char*")
390c5f01b2fSopenharmony_ci    {
391c5f01b2fSopenharmony_ci        json j;
392c5f01b2fSopenharmony_ci
393c5f01b2fSopenharmony_ci        // Non-const access with key as "char []"
394c5f01b2fSopenharmony_ci        char array_key[] = "Key1"; // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
395c5f01b2fSopenharmony_ci        CHECK_NOTHROW(j[array_key] = 1);
396c5f01b2fSopenharmony_ci        CHECK(j[array_key] == json(1));
397c5f01b2fSopenharmony_ci
398c5f01b2fSopenharmony_ci        // Non-const access with key as "const char[]"
399c5f01b2fSopenharmony_ci        const char const_array_key[] = "Key2"; // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
400c5f01b2fSopenharmony_ci        CHECK_NOTHROW(j[const_array_key] = 2);
401c5f01b2fSopenharmony_ci        CHECK(j[const_array_key] == json(2));
402c5f01b2fSopenharmony_ci
403c5f01b2fSopenharmony_ci        // Non-const access with key as "char *"
404c5f01b2fSopenharmony_ci        char _ptr_key[] = "Key3"; // NOLINT(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
405c5f01b2fSopenharmony_ci        char* ptr_key = &_ptr_key[0]; // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg)
406c5f01b2fSopenharmony_ci        CHECK_NOTHROW(j[ptr_key] = 3);
407c5f01b2fSopenharmony_ci        CHECK(j[ptr_key] == json(3));
408c5f01b2fSopenharmony_ci
409c5f01b2fSopenharmony_ci        // Non-const access with key as "const char *"
410c5f01b2fSopenharmony_ci        const char* const_ptr_key = "Key4";
411c5f01b2fSopenharmony_ci        CHECK_NOTHROW(j[const_ptr_key] = 4);
412c5f01b2fSopenharmony_ci        CHECK(j[const_ptr_key] == json(4));
413c5f01b2fSopenharmony_ci
414c5f01b2fSopenharmony_ci        // Non-const access with key as "static constexpr const char *"
415c5f01b2fSopenharmony_ci        static constexpr const char* constexpr_ptr_key = "Key5";
416c5f01b2fSopenharmony_ci        CHECK_NOTHROW(j[constexpr_ptr_key] = 5);
417c5f01b2fSopenharmony_ci        CHECK(j[constexpr_ptr_key] == json(5));
418c5f01b2fSopenharmony_ci
419c5f01b2fSopenharmony_ci        const json j_const = j;
420c5f01b2fSopenharmony_ci
421c5f01b2fSopenharmony_ci        // Const access with key as "char []"
422c5f01b2fSopenharmony_ci        CHECK(j_const[array_key] == json(1));
423c5f01b2fSopenharmony_ci
424c5f01b2fSopenharmony_ci        // Const access with key as "const char[]"
425c5f01b2fSopenharmony_ci        CHECK(j_const[const_array_key] == json(2));
426c5f01b2fSopenharmony_ci
427c5f01b2fSopenharmony_ci        // Const access with key as "char *"
428c5f01b2fSopenharmony_ci        CHECK(j_const[ptr_key] == json(3));
429c5f01b2fSopenharmony_ci
430c5f01b2fSopenharmony_ci        // Const access with key as "const char *"
431c5f01b2fSopenharmony_ci        CHECK(j_const[const_ptr_key] == json(4));
432c5f01b2fSopenharmony_ci
433c5f01b2fSopenharmony_ci        // Const access with key as "static constexpr const char *"
434c5f01b2fSopenharmony_ci        CHECK(j_const[constexpr_ptr_key] == json(5));
435c5f01b2fSopenharmony_ci    }
436c5f01b2fSopenharmony_ci
437c5f01b2fSopenharmony_ci    SECTION("issue #186 miloyip/nativejson-benchmark: floating-point parsing")
438c5f01b2fSopenharmony_ci    {
439c5f01b2fSopenharmony_ci        json j;
440c5f01b2fSopenharmony_ci
441c5f01b2fSopenharmony_ci        j = json::parse("-0.0");
442c5f01b2fSopenharmony_ci        CHECK(j.get<double>() == -0.0);
443c5f01b2fSopenharmony_ci
444c5f01b2fSopenharmony_ci        j = json::parse("2.22507385850720113605740979670913197593481954635164564e-308");
445c5f01b2fSopenharmony_ci        CHECK(j.get<double>() == 2.2250738585072009e-308);
446c5f01b2fSopenharmony_ci
447c5f01b2fSopenharmony_ci        j = json::parse("0.999999999999999944488848768742172978818416595458984374");
448c5f01b2fSopenharmony_ci        CHECK(j.get<double>() == 0.99999999999999989);
449c5f01b2fSopenharmony_ci
450c5f01b2fSopenharmony_ci        j = json::parse("1.00000000000000011102230246251565404236316680908203126");
451c5f01b2fSopenharmony_ci        CHECK(j.get<double>() == 1.00000000000000022);
452c5f01b2fSopenharmony_ci
453c5f01b2fSopenharmony_ci        j = json::parse("7205759403792793199999e-5");
454c5f01b2fSopenharmony_ci        CHECK(j.get<double>() == 72057594037927928.0);
455c5f01b2fSopenharmony_ci
456c5f01b2fSopenharmony_ci        j = json::parse("922337203685477529599999e-5");
457c5f01b2fSopenharmony_ci        CHECK(j.get<double>() == 9223372036854774784.0);
458c5f01b2fSopenharmony_ci
459c5f01b2fSopenharmony_ci        j = json::parse("1014120480182583464902367222169599999e-5");
460c5f01b2fSopenharmony_ci        CHECK(j.get<double>() == 10141204801825834086073718800384.0);
461c5f01b2fSopenharmony_ci
462c5f01b2fSopenharmony_ci        j = json::parse("5708990770823839207320493820740630171355185151999e-3");
463c5f01b2fSopenharmony_ci        CHECK(j.get<double>() == 5708990770823838890407843763683279797179383808.0);
464c5f01b2fSopenharmony_ci
465c5f01b2fSopenharmony_ci        // create JSON class with nonstandard float number type
466c5f01b2fSopenharmony_ci
467c5f01b2fSopenharmony_ci        // float
468c5f01b2fSopenharmony_ci        nlohmann::basic_json<std::map, std::vector, std::string, bool, int32_t, uint32_t, float> j_float =
469c5f01b2fSopenharmony_ci            1.23e25f;
470c5f01b2fSopenharmony_ci        CHECK(j_float.get<float>() == 1.23e25f);
471c5f01b2fSopenharmony_ci
472c5f01b2fSopenharmony_ci        // double
473c5f01b2fSopenharmony_ci        nlohmann::basic_json<std::map, std::vector, std::string, bool, int64_t, uint64_t, double> j_double =
474c5f01b2fSopenharmony_ci            1.23e35;
475c5f01b2fSopenharmony_ci        CHECK(j_double.get<double>() == 1.23e35);
476c5f01b2fSopenharmony_ci
477c5f01b2fSopenharmony_ci        // long double
478c5f01b2fSopenharmony_ci        nlohmann::basic_json<std::map, std::vector, std::string, bool, int64_t, uint64_t, long double>
479c5f01b2fSopenharmony_ci        j_long_double = 1.23e45L;
480c5f01b2fSopenharmony_ci        CHECK(j_long_double.get<long double>() == 1.23e45L);
481c5f01b2fSopenharmony_ci    }
482c5f01b2fSopenharmony_ci
483c5f01b2fSopenharmony_ci    SECTION("issue #228 - double values are serialized with commas as decimal points")
484c5f01b2fSopenharmony_ci    {
485c5f01b2fSopenharmony_ci        json j1a = 2312.42;
486c5f01b2fSopenharmony_ci        json j1b = json::parse("2312.42");
487c5f01b2fSopenharmony_ci
488c5f01b2fSopenharmony_ci        json j2a = 2342e-2;
489c5f01b2fSopenharmony_ci        //issue #230
490c5f01b2fSopenharmony_ci        //json j2b = json::parse("2342e-2");
491c5f01b2fSopenharmony_ci
492c5f01b2fSopenharmony_ci        json j3a = 10E3;
493c5f01b2fSopenharmony_ci        json j3b = json::parse("10E3");
494c5f01b2fSopenharmony_ci        json j3c = json::parse("10e3");
495c5f01b2fSopenharmony_ci
496c5f01b2fSopenharmony_ci        // class to create a locale that would use a comma for decimals
497c5f01b2fSopenharmony_ci        class CommaDecimalSeparator : public std::numpunct<char>
498c5f01b2fSopenharmony_ci        {
499c5f01b2fSopenharmony_ci          protected:
500c5f01b2fSopenharmony_ci            char do_decimal_point() const override
501c5f01b2fSopenharmony_ci            {
502c5f01b2fSopenharmony_ci                return ',';
503c5f01b2fSopenharmony_ci            }
504c5f01b2fSopenharmony_ci
505c5f01b2fSopenharmony_ci            char do_thousands_sep() const override
506c5f01b2fSopenharmony_ci            {
507c5f01b2fSopenharmony_ci                return '.';
508c5f01b2fSopenharmony_ci            }
509c5f01b2fSopenharmony_ci
510c5f01b2fSopenharmony_ci            std::string do_grouping() const override
511c5f01b2fSopenharmony_ci            {
512c5f01b2fSopenharmony_ci                return "\03";
513c5f01b2fSopenharmony_ci            }
514c5f01b2fSopenharmony_ci        };
515c5f01b2fSopenharmony_ci
516c5f01b2fSopenharmony_ci        // change locale to mess with decimal points
517c5f01b2fSopenharmony_ci        auto orig_locale = std::locale::global(std::locale(std::locale(), new CommaDecimalSeparator));
518c5f01b2fSopenharmony_ci
519c5f01b2fSopenharmony_ci        CHECK(j1a.dump() == "2312.42");
520c5f01b2fSopenharmony_ci        CHECK(j1b.dump() == "2312.42");
521c5f01b2fSopenharmony_ci
522c5f01b2fSopenharmony_ci        // check if locale is properly reset
523c5f01b2fSopenharmony_ci        std::stringstream ss;
524c5f01b2fSopenharmony_ci        ss.imbue(std::locale(std::locale(), new CommaDecimalSeparator));
525c5f01b2fSopenharmony_ci        ss << 4712.11;
526c5f01b2fSopenharmony_ci        CHECK(ss.str() == "4.712,11");
527c5f01b2fSopenharmony_ci        ss << j1a;
528c5f01b2fSopenharmony_ci        CHECK(ss.str() == "4.712,112312.42");
529c5f01b2fSopenharmony_ci        ss << 47.11;
530c5f01b2fSopenharmony_ci        CHECK(ss.str() == "4.712,112312.4247,11");
531c5f01b2fSopenharmony_ci
532c5f01b2fSopenharmony_ci        CHECK(j2a.dump() == "23.42");
533c5f01b2fSopenharmony_ci        //issue #230
534c5f01b2fSopenharmony_ci        //CHECK(j2b.dump() == "23.42");
535c5f01b2fSopenharmony_ci
536c5f01b2fSopenharmony_ci        CHECK(j3a.dump() == "10000.0");
537c5f01b2fSopenharmony_ci        CHECK(j3b.dump() == "10000.0");
538c5f01b2fSopenharmony_ci        CHECK(j3c.dump() == "10000.0");
539c5f01b2fSopenharmony_ci        //CHECK(j3b.dump() == "1E04"); // roundtrip error
540c5f01b2fSopenharmony_ci        //CHECK(j3c.dump() == "1e04"); // roundtrip error
541c5f01b2fSopenharmony_ci
542c5f01b2fSopenharmony_ci        std::locale::global(orig_locale);
543c5f01b2fSopenharmony_ci    }
544c5f01b2fSopenharmony_ci
545c5f01b2fSopenharmony_ci    SECTION("issue #378 - locale-independent num-to-str")
546c5f01b2fSopenharmony_ci    {
547c5f01b2fSopenharmony_ci        static_cast<void>(setlocale(LC_NUMERIC, "de_DE.UTF-8"));
548c5f01b2fSopenharmony_ci
549c5f01b2fSopenharmony_ci        // verify that dumped correctly with '.' and no grouping
550c5f01b2fSopenharmony_ci        const json j1 = 12345.67;
551c5f01b2fSopenharmony_ci        CHECK(json(12345.67).dump() == "12345.67");
552c5f01b2fSopenharmony_ci        static_cast<void>(setlocale(LC_NUMERIC, "C"));
553c5f01b2fSopenharmony_ci    }
554c5f01b2fSopenharmony_ci
555c5f01b2fSopenharmony_ci    SECTION("issue #379 - locale-independent str-to-num")
556c5f01b2fSopenharmony_ci    {
557c5f01b2fSopenharmony_ci        static_cast<void>(setlocale(LC_NUMERIC, "de_DE.UTF-8"));
558c5f01b2fSopenharmony_ci
559c5f01b2fSopenharmony_ci        // verify that parsed correctly despite using strtod internally
560c5f01b2fSopenharmony_ci        CHECK(json::parse("3.14").get<double>() == 3.14);
561c5f01b2fSopenharmony_ci
562c5f01b2fSopenharmony_ci        // check a different code path
563c5f01b2fSopenharmony_ci        CHECK(json::parse("1.000000000000000000000000000000000000000000000000000000000000000000000000").get<double>() == 1.0);
564c5f01b2fSopenharmony_ci    }
565c5f01b2fSopenharmony_ci
566c5f01b2fSopenharmony_ci    SECTION("issue #233 - Can't use basic_json::iterator as a base iterator for std::move_iterator")
567c5f01b2fSopenharmony_ci    {
568c5f01b2fSopenharmony_ci        json source = {"a", "b", "c"};
569c5f01b2fSopenharmony_ci        json expected = {"a", "b"};
570c5f01b2fSopenharmony_ci        json dest;
571c5f01b2fSopenharmony_ci
572c5f01b2fSopenharmony_ci        std::copy_n(std::make_move_iterator(source.begin()), 2, std::back_inserter(dest));
573c5f01b2fSopenharmony_ci
574c5f01b2fSopenharmony_ci        CHECK(dest == expected);
575c5f01b2fSopenharmony_ci    }
576c5f01b2fSopenharmony_ci
577c5f01b2fSopenharmony_ci    SECTION("issue #235 - ambiguous overload for 'push_back' and 'operator+='")
578c5f01b2fSopenharmony_ci    {
579c5f01b2fSopenharmony_ci        json data = {{"key", "value"}};
580c5f01b2fSopenharmony_ci        data.push_back({"key2", "value2"});
581c5f01b2fSopenharmony_ci        data += {"key3", "value3"};
582c5f01b2fSopenharmony_ci
583c5f01b2fSopenharmony_ci        CHECK(data == json({{"key", "value"}, {"key2", "value2"}, {"key3", "value3"}}));
584c5f01b2fSopenharmony_ci    }
585c5f01b2fSopenharmony_ci
586c5f01b2fSopenharmony_ci    SECTION("issue #269 - diff generates incorrect patch when removing multiple array elements")
587c5f01b2fSopenharmony_ci    {
588c5f01b2fSopenharmony_ci        json doc = R"( { "arr1": [1, 2, 3, 4] } )"_json;
589c5f01b2fSopenharmony_ci        json expected = R"( { "arr1": [1, 2] } )"_json;
590c5f01b2fSopenharmony_ci
591c5f01b2fSopenharmony_ci        // check roundtrip
592c5f01b2fSopenharmony_ci        CHECK(doc.patch(json::diff(doc, expected)) == expected);
593c5f01b2fSopenharmony_ci    }
594c5f01b2fSopenharmony_ci
595c5f01b2fSopenharmony_ci    SECTION("issue #283 - value() does not work with _json_pointer types")
596c5f01b2fSopenharmony_ci    {
597c5f01b2fSopenharmony_ci        json j =
598c5f01b2fSopenharmony_ci        {
599c5f01b2fSopenharmony_ci            {"object", {{"key1", 1}, {"key2", 2}}},
600c5f01b2fSopenharmony_ci        };
601c5f01b2fSopenharmony_ci
602c5f01b2fSopenharmony_ci        int at_integer{j.at("/object/key2"_json_pointer)};
603c5f01b2fSopenharmony_ci        int val_integer = j.value("/object/key2"_json_pointer, 0);
604c5f01b2fSopenharmony_ci
605c5f01b2fSopenharmony_ci        CHECK(at_integer == val_integer);
606c5f01b2fSopenharmony_ci    }
607c5f01b2fSopenharmony_ci
608c5f01b2fSopenharmony_ci    SECTION("issue #304 - Unused variable warning")
609c5f01b2fSopenharmony_ci    {
610c5f01b2fSopenharmony_ci        // code triggered a "warning: unused variable" warning and is left
611c5f01b2fSopenharmony_ci        // here to avoid the warning in the future
612c5f01b2fSopenharmony_ci        json object;
613c5f01b2fSopenharmony_ci        json patch = json::array();
614c5f01b2fSopenharmony_ci        object = object.patch(patch);
615c5f01b2fSopenharmony_ci    }
616c5f01b2fSopenharmony_ci
617c5f01b2fSopenharmony_ci    SECTION("issue #306 - Parsing fails without space at end of file")
618c5f01b2fSopenharmony_ci    {
619c5f01b2fSopenharmony_ci        for (const auto* filename :
620c5f01b2fSopenharmony_ci                {
621c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/regression/broken_file.json",
622c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/regression/working_file.json"
623c5f01b2fSopenharmony_ci                })
624c5f01b2fSopenharmony_ci        {
625c5f01b2fSopenharmony_ci            CAPTURE(filename)
626c5f01b2fSopenharmony_ci            json j;
627c5f01b2fSopenharmony_ci            std::ifstream f(filename);
628c5f01b2fSopenharmony_ci            CHECK_NOTHROW(f >> j);
629c5f01b2fSopenharmony_ci        }
630c5f01b2fSopenharmony_ci    }
631c5f01b2fSopenharmony_ci
632c5f01b2fSopenharmony_ci    SECTION("issue #310 - make json_benchmarks no longer working in 2.0.4")
633c5f01b2fSopenharmony_ci    {
634c5f01b2fSopenharmony_ci        for (const auto* filename :
635c5f01b2fSopenharmony_ci                {
636c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/regression/floats.json",
637c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/regression/signed_ints.json",
638c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/regression/unsigned_ints.json",
639c5f01b2fSopenharmony_ci                    TEST_DATA_DIRECTORY "/regression/small_signed_ints.json"
640c5f01b2fSopenharmony_ci                })
641c5f01b2fSopenharmony_ci        {
642c5f01b2fSopenharmony_ci            CAPTURE(filename)
643c5f01b2fSopenharmony_ci            json j;
644c5f01b2fSopenharmony_ci            std::ifstream f(filename);
645c5f01b2fSopenharmony_ci            CHECK_NOTHROW(f >> j);
646c5f01b2fSopenharmony_ci        }
647c5f01b2fSopenharmony_ci    }
648c5f01b2fSopenharmony_ci
649c5f01b2fSopenharmony_ci    SECTION("issue #323 - add nested object capabilities to pointers")
650c5f01b2fSopenharmony_ci    {
651c5f01b2fSopenharmony_ci        json j;
652c5f01b2fSopenharmony_ci        j["/this/that/2"_json_pointer] = 27;
653c5f01b2fSopenharmony_ci        CHECK(j == json({{"this", {{"that", {nullptr, nullptr, 27}}}}}));
654c5f01b2fSopenharmony_ci    }
655c5f01b2fSopenharmony_ci
656c5f01b2fSopenharmony_ci    SECTION("issue #329 - serialized value not always can be parsed")
657c5f01b2fSopenharmony_ci    {
658c5f01b2fSopenharmony_ci        json _;
659c5f01b2fSopenharmony_ci        CHECK_THROWS_WITH_AS(_ = json::parse("22e2222"), "[json.exception.out_of_range.406] number overflow parsing '22e2222'", json::out_of_range&);
660c5f01b2fSopenharmony_ci    }
661c5f01b2fSopenharmony_ci
662c5f01b2fSopenharmony_ci    SECTION("issue #360 - Loss of precision when serializing <double>")
663c5f01b2fSopenharmony_ci    {
664c5f01b2fSopenharmony_ci        auto check_roundtrip = [](double number)
665c5f01b2fSopenharmony_ci        {
666c5f01b2fSopenharmony_ci            CAPTURE(number)
667c5f01b2fSopenharmony_ci
668c5f01b2fSopenharmony_ci            json j = number;
669c5f01b2fSopenharmony_ci            CHECK(j.is_number_float());
670c5f01b2fSopenharmony_ci
671c5f01b2fSopenharmony_ci            std::stringstream ss;
672c5f01b2fSopenharmony_ci            ss << j;
673c5f01b2fSopenharmony_ci
674c5f01b2fSopenharmony_ci            CHECK_NOTHROW(ss >> j);
675c5f01b2fSopenharmony_ci            CHECK(j.is_number_float());
676c5f01b2fSopenharmony_ci            CHECK(j.get<json::number_float_t>() == number);
677c5f01b2fSopenharmony_ci        };
678c5f01b2fSopenharmony_ci
679c5f01b2fSopenharmony_ci        check_roundtrip(100000000000.1236);
680c5f01b2fSopenharmony_ci        check_roundtrip((std::numeric_limits<json::number_float_t>::max)());
681c5f01b2fSopenharmony_ci
682c5f01b2fSopenharmony_ci        // Some more numbers which fail to roundtrip when serialized with digits10 significand digits (instead of max_digits10)
683c5f01b2fSopenharmony_ci        check_roundtrip(1.541888611948064e-17);
684c5f01b2fSopenharmony_ci        check_roundtrip(5.418771028591015e-16);
685c5f01b2fSopenharmony_ci        check_roundtrip(9.398685592608595e-15);
686c5f01b2fSopenharmony_ci        check_roundtrip(8.826843952762347e-14);
687c5f01b2fSopenharmony_ci        check_roundtrip(8.143291313475335e-13);
688c5f01b2fSopenharmony_ci        check_roundtrip(4.851328172762508e-12);
689c5f01b2fSopenharmony_ci        check_roundtrip(6.677850998084358e-11);
690c5f01b2fSopenharmony_ci        check_roundtrip(3.995398518174525e-10);
691c5f01b2fSopenharmony_ci        check_roundtrip(1.960452605645124e-9);
692c5f01b2fSopenharmony_ci        check_roundtrip(3.551812586302883e-8);
693c5f01b2fSopenharmony_ci        check_roundtrip(2.947988411689261e-7);
694c5f01b2fSopenharmony_ci        check_roundtrip(8.210166748056192e-6);
695c5f01b2fSopenharmony_ci        check_roundtrip(6.104889704266753e-5);
696c5f01b2fSopenharmony_ci        check_roundtrip(0.0008629954631330876);
697c5f01b2fSopenharmony_ci        check_roundtrip(0.004936993881051611);
698c5f01b2fSopenharmony_ci        check_roundtrip(0.08309725102608073);
699c5f01b2fSopenharmony_ci        check_roundtrip(0.5210494268499783);
700c5f01b2fSopenharmony_ci        check_roundtrip(6.382927930939767);
701c5f01b2fSopenharmony_ci        check_roundtrip(59.94947245358671);
702c5f01b2fSopenharmony_ci        check_roundtrip(361.0838651266122);
703c5f01b2fSopenharmony_ci        check_roundtrip(4678.354596181877);
704c5f01b2fSopenharmony_ci        check_roundtrip(61412.17658956043);
705c5f01b2fSopenharmony_ci        check_roundtrip(725696.0799057782);
706c5f01b2fSopenharmony_ci        check_roundtrip(2811732.583399828);
707c5f01b2fSopenharmony_ci        check_roundtrip(30178351.07533605);
708c5f01b2fSopenharmony_ci        check_roundtrip(689684880.3235844);
709c5f01b2fSopenharmony_ci        check_roundtrip(5714887673.555147);
710c5f01b2fSopenharmony_ci        check_roundtrip(84652038821.18808);
711c5f01b2fSopenharmony_ci        check_roundtrip(156510583431.7721);
712c5f01b2fSopenharmony_ci        check_roundtrip(5938450569021.732);
713c5f01b2fSopenharmony_ci        check_roundtrip(83623297654460.33);
714c5f01b2fSopenharmony_ci        check_roundtrip(701466573254773.6);
715c5f01b2fSopenharmony_ci        check_roundtrip(1369013370304513);
716c5f01b2fSopenharmony_ci        check_roundtrip(96963648023094720); // NOLINT(bugprone-narrowing-conversions,cppcoreguidelines-narrowing-conversions)
717c5f01b2fSopenharmony_ci        check_roundtrip(3.478237409280108e+17);
718c5f01b2fSopenharmony_ci    }
719c5f01b2fSopenharmony_ci
720c5f01b2fSopenharmony_ci    SECTION("issue #366 - json::parse on failed stream gets stuck")
721c5f01b2fSopenharmony_ci    {
722c5f01b2fSopenharmony_ci        std::ifstream f("file_not_found.json");
723c5f01b2fSopenharmony_ci        json _;
724c5f01b2fSopenharmony_ci        CHECK_THROWS_WITH_AS(_ = json::parse(f), "[json.exception.parse_error.101] parse error at line 1, column 1: syntax error while parsing value - unexpected end of input; expected '[', '{', or a literal", json::parse_error&);
725c5f01b2fSopenharmony_ci    }
726c5f01b2fSopenharmony_ci
727c5f01b2fSopenharmony_ci    SECTION("issue #367 - calling stream at EOF")
728c5f01b2fSopenharmony_ci    {
729c5f01b2fSopenharmony_ci        std::stringstream ss;
730c5f01b2fSopenharmony_ci        json j;
731c5f01b2fSopenharmony_ci        ss << "123";
732c5f01b2fSopenharmony_ci        CHECK_NOTHROW(ss >> j);
733c5f01b2fSopenharmony_ci
734c5f01b2fSopenharmony_ci        // see https://github.com/nlohmann/json/issues/367#issuecomment-262841893:
735c5f01b2fSopenharmony_ci        // ss is not at EOF; this yielded an error before the fix
736c5f01b2fSopenharmony_ci        // (threw basic_string::append). No, it should just throw
737c5f01b2fSopenharmony_ci        // a parse error because of the EOF.
738c5f01b2fSopenharmony_ci        CHECK_THROWS_WITH_AS(ss >> j, "[json.exception.parse_error.101] parse error at line 1, column 1: syntax error while parsing value - unexpected end of input; expected '[', '{', or a literal", json::parse_error&);
739c5f01b2fSopenharmony_ci    }
740c5f01b2fSopenharmony_ci
741c5f01b2fSopenharmony_ci    SECTION("issue #367 - behavior of operator>> should more closely resemble that of built-in overloads")
742c5f01b2fSopenharmony_ci    {
743c5f01b2fSopenharmony_ci        SECTION("(empty)")
744c5f01b2fSopenharmony_ci        {
745c5f01b2fSopenharmony_ci            std::stringstream ss;
746c5f01b2fSopenharmony_ci            json j;
747c5f01b2fSopenharmony_ci            CHECK_THROWS_WITH_AS(ss >> j, "[json.exception.parse_error.101] parse error at line 1, column 1: syntax error while parsing value - unexpected end of input; expected '[', '{', or a literal", json::parse_error&);
748c5f01b2fSopenharmony_ci        }
749c5f01b2fSopenharmony_ci
750c5f01b2fSopenharmony_ci        SECTION("(whitespace)")
751c5f01b2fSopenharmony_ci        {
752c5f01b2fSopenharmony_ci            std::stringstream ss;
753c5f01b2fSopenharmony_ci            ss << "   ";
754c5f01b2fSopenharmony_ci            json j;
755c5f01b2fSopenharmony_ci            CHECK_THROWS_WITH_AS(ss >> j,
756c5f01b2fSopenharmony_ci                                 "[json.exception.parse_error.101] parse error at line 1, column 4: syntax error while parsing value - unexpected end of input; expected '[', '{', or a literal", json::parse_error&);
757c5f01b2fSopenharmony_ci        }
758c5f01b2fSopenharmony_ci
759c5f01b2fSopenharmony_ci        SECTION("one value")
760c5f01b2fSopenharmony_ci        {
761c5f01b2fSopenharmony_ci            std::stringstream ss;
762c5f01b2fSopenharmony_ci            ss << "111";
763c5f01b2fSopenharmony_ci            json j;
764c5f01b2fSopenharmony_ci            CHECK_NOTHROW(ss >> j);
765c5f01b2fSopenharmony_ci            CHECK(j == 111);
766c5f01b2fSopenharmony_ci
767c5f01b2fSopenharmony_ci            CHECK_THROWS_WITH_AS(ss >> j, "[json.exception.parse_error.101] parse error at line 1, column 1: syntax error while parsing value - unexpected end of input; expected '[', '{', or a literal", json::parse_error&);
768c5f01b2fSopenharmony_ci        }
769c5f01b2fSopenharmony_ci
770c5f01b2fSopenharmony_ci        SECTION("one value + whitespace")
771c5f01b2fSopenharmony_ci        {
772c5f01b2fSopenharmony_ci            std::stringstream ss;
773c5f01b2fSopenharmony_ci            ss << "222 \t\n";
774c5f01b2fSopenharmony_ci            json j;
775c5f01b2fSopenharmony_ci            CHECK_NOTHROW(ss >> j);
776c5f01b2fSopenharmony_ci            CHECK(j == 222);
777c5f01b2fSopenharmony_ci
778c5f01b2fSopenharmony_ci            CHECK_THROWS_WITH_AS(ss >> j,
779c5f01b2fSopenharmony_ci                                 "[json.exception.parse_error.101] parse error at line 2, column 1: syntax error while parsing value - unexpected end of input; expected '[', '{', or a literal", json::parse_error&);
780c5f01b2fSopenharmony_ci        }
781c5f01b2fSopenharmony_ci
782c5f01b2fSopenharmony_ci        SECTION("whitespace + one value")
783c5f01b2fSopenharmony_ci        {
784c5f01b2fSopenharmony_ci            std::stringstream ss;
785c5f01b2fSopenharmony_ci            ss << "\n\t 333";
786c5f01b2fSopenharmony_ci            json j;
787c5f01b2fSopenharmony_ci            CHECK_NOTHROW(ss >> j);
788c5f01b2fSopenharmony_ci            CHECK(j == 333);
789c5f01b2fSopenharmony_ci
790c5f01b2fSopenharmony_ci            CHECK_THROWS_WITH_AS(ss >> j, "[json.exception.parse_error.101] parse error at line 1, column 1: syntax error while parsing value - unexpected end of input; expected '[', '{', or a literal", json::parse_error&);
791c5f01b2fSopenharmony_ci        }
792c5f01b2fSopenharmony_ci
793c5f01b2fSopenharmony_ci        SECTION("three values")
794c5f01b2fSopenharmony_ci        {
795c5f01b2fSopenharmony_ci            std::stringstream ss;
796c5f01b2fSopenharmony_ci            ss << " 111 \n222\n \n  333";
797c5f01b2fSopenharmony_ci            json j;
798c5f01b2fSopenharmony_ci            CHECK_NOTHROW(ss >> j);
799c5f01b2fSopenharmony_ci            CHECK(j == 111);
800c5f01b2fSopenharmony_ci            CHECK_NOTHROW(ss >> j);
801c5f01b2fSopenharmony_ci            CHECK(j == 222);
802c5f01b2fSopenharmony_ci            CHECK_NOTHROW(ss >> j);
803c5f01b2fSopenharmony_ci            CHECK(j == 333);
804c5f01b2fSopenharmony_ci
805c5f01b2fSopenharmony_ci            CHECK_THROWS_WITH_AS(ss >> j, "[json.exception.parse_error.101] parse error at line 1, column 1: syntax error while parsing value - unexpected end of input; expected '[', '{', or a literal", json::parse_error&);
806c5f01b2fSopenharmony_ci        }
807c5f01b2fSopenharmony_ci
808c5f01b2fSopenharmony_ci        SECTION("literals without whitespace")
809c5f01b2fSopenharmony_ci        {
810c5f01b2fSopenharmony_ci            std::stringstream ss;
811c5f01b2fSopenharmony_ci            ss << "truefalsenull\"\"";
812c5f01b2fSopenharmony_ci            json j;
813c5f01b2fSopenharmony_ci            CHECK_NOTHROW(ss >> j);
814c5f01b2fSopenharmony_ci            CHECK(j == true);
815c5f01b2fSopenharmony_ci            CHECK_NOTHROW(ss >> j);
816c5f01b2fSopenharmony_ci            CHECK(j == false);
817c5f01b2fSopenharmony_ci            CHECK_NOTHROW(ss >> j);
818c5f01b2fSopenharmony_ci            CHECK(j == nullptr);
819c5f01b2fSopenharmony_ci            CHECK_NOTHROW(ss >> j);
820c5f01b2fSopenharmony_ci            CHECK(j == "");
821c5f01b2fSopenharmony_ci
822c5f01b2fSopenharmony_ci            CHECK_THROWS_WITH_AS(ss >> j, "[json.exception.parse_error.101] parse error at line 1, column 1: syntax error while parsing value - unexpected end of input; expected '[', '{', or a literal", json::parse_error&);
823c5f01b2fSopenharmony_ci        }
824c5f01b2fSopenharmony_ci
825c5f01b2fSopenharmony_ci        SECTION("example from #529")
826c5f01b2fSopenharmony_ci        {
827c5f01b2fSopenharmony_ci            std::stringstream ss;
828c5f01b2fSopenharmony_ci            ss << "{\n    \"one\"   : 1,\n    \"two\"   : 2\n}\n{\n    \"three\" : 3\n}";
829c5f01b2fSopenharmony_ci            json j;
830c5f01b2fSopenharmony_ci            CHECK_NOTHROW(ss >> j);
831c5f01b2fSopenharmony_ci            CHECK(j == json({{"one", 1}, {"two", 2}}));
832c5f01b2fSopenharmony_ci            CHECK_NOTHROW(ss >> j);
833c5f01b2fSopenharmony_ci            CHECK(j == json({{"three", 3}}));
834c5f01b2fSopenharmony_ci
835c5f01b2fSopenharmony_ci            CHECK_THROWS_WITH_AS(ss >> j, "[json.exception.parse_error.101] parse error at line 1, column 1: syntax error while parsing value - unexpected end of input; expected '[', '{', or a literal", json::parse_error&);
836c5f01b2fSopenharmony_ci        }
837c5f01b2fSopenharmony_ci
838c5f01b2fSopenharmony_ci        SECTION("second example from #529")
839c5f01b2fSopenharmony_ci        {
840c5f01b2fSopenharmony_ci            std::string str = "{\n\"one\"   : 1,\n\"two\"   : 2\n}\n{\n\"three\" : 3\n}";
841c5f01b2fSopenharmony_ci
842c5f01b2fSopenharmony_ci            {
843c5f01b2fSopenharmony_ci                std::ofstream file("test.json");
844c5f01b2fSopenharmony_ci                file << str;
845c5f01b2fSopenharmony_ci            }
846c5f01b2fSopenharmony_ci
847c5f01b2fSopenharmony_ci            std::ifstream stream("test.json", std::ifstream::in);
848c5f01b2fSopenharmony_ci            json val;
849c5f01b2fSopenharmony_ci
850c5f01b2fSopenharmony_ci            size_t i = 0;
851c5f01b2fSopenharmony_ci            while (stream.peek() != EOF)
852c5f01b2fSopenharmony_ci            {
853c5f01b2fSopenharmony_ci                CAPTURE(i)
854c5f01b2fSopenharmony_ci                CHECK_NOTHROW(stream >> val);
855c5f01b2fSopenharmony_ci
856c5f01b2fSopenharmony_ci                CHECK(i < 2);
857c5f01b2fSopenharmony_ci
858c5f01b2fSopenharmony_ci                if (i == 0)
859c5f01b2fSopenharmony_ci                {
860c5f01b2fSopenharmony_ci                    CHECK(val == json({{"one", 1}, {"two", 2}}));
861c5f01b2fSopenharmony_ci                }
862c5f01b2fSopenharmony_ci
863c5f01b2fSopenharmony_ci                if (i == 1)
864c5f01b2fSopenharmony_ci                {
865c5f01b2fSopenharmony_ci                    CHECK(val == json({{"three", 3}}));
866c5f01b2fSopenharmony_ci                }
867c5f01b2fSopenharmony_ci
868c5f01b2fSopenharmony_ci                ++i;
869c5f01b2fSopenharmony_ci            }
870c5f01b2fSopenharmony_ci
871c5f01b2fSopenharmony_ci            static_cast<void>(std::remove("test.json"));
872c5f01b2fSopenharmony_ci        }
873c5f01b2fSopenharmony_ci    }
874c5f01b2fSopenharmony_ci
875c5f01b2fSopenharmony_ci    SECTION("issue #389 - Integer-overflow (OSS-Fuzz issue 267)")
876c5f01b2fSopenharmony_ci    {
877c5f01b2fSopenharmony_ci        // original test case
878c5f01b2fSopenharmony_ci        json j1 = json::parse("-9223372036854775808");
879c5f01b2fSopenharmony_ci        CHECK(j1.is_number_integer());
880c5f01b2fSopenharmony_ci        CHECK(j1.get<json::number_integer_t>() == INT64_MIN);
881c5f01b2fSopenharmony_ci
882c5f01b2fSopenharmony_ci        // edge case (+1; still an integer)
883c5f01b2fSopenharmony_ci        json j2 = json::parse("-9223372036854775807");
884c5f01b2fSopenharmony_ci        CHECK(j2.is_number_integer());
885c5f01b2fSopenharmony_ci        CHECK(j2.get<json::number_integer_t>() == INT64_MIN + 1);
886c5f01b2fSopenharmony_ci
887c5f01b2fSopenharmony_ci        // edge case (-1; overflow -> floats)
888c5f01b2fSopenharmony_ci        json j3 = json::parse("-9223372036854775809");
889c5f01b2fSopenharmony_ci        CHECK(j3.is_number_float());
890c5f01b2fSopenharmony_ci    }
891c5f01b2fSopenharmony_ci
892c5f01b2fSopenharmony_ci    SECTION("issue #380 - bug in overflow detection when parsing integers")
893c5f01b2fSopenharmony_ci    {
894c5f01b2fSopenharmony_ci        json j = json::parse("166020696663385964490");
895c5f01b2fSopenharmony_ci        CHECK(j.is_number_float());
896c5f01b2fSopenharmony_ci        CHECK(j.get<json::number_float_t>() == 166020696663385964490.0);
897c5f01b2fSopenharmony_ci    }
898c5f01b2fSopenharmony_ci
899c5f01b2fSopenharmony_ci    SECTION("issue #405 - Heap-buffer-overflow (OSS-Fuzz issue 342)")
900c5f01b2fSopenharmony_ci    {
901c5f01b2fSopenharmony_ci        // original test case
902c5f01b2fSopenharmony_ci        std::vector<uint8_t> vec {0x65, 0xf5, 0x0a, 0x48, 0x21};
903c5f01b2fSopenharmony_ci        json _;
904c5f01b2fSopenharmony_ci        CHECK_THROWS_WITH_AS(_ = json::from_cbor(vec), "[json.exception.parse_error.110] parse error at byte 6: syntax error while parsing CBOR string: unexpected end of input", json::parse_error&);
905c5f01b2fSopenharmony_ci    }
906c5f01b2fSopenharmony_ci
907c5f01b2fSopenharmony_ci    SECTION("issue #407 - Heap-buffer-overflow (OSS-Fuzz issue 343)")
908c5f01b2fSopenharmony_ci    {
909c5f01b2fSopenharmony_ci        json _;
910c5f01b2fSopenharmony_ci
911c5f01b2fSopenharmony_ci        // original test case: incomplete float64
912c5f01b2fSopenharmony_ci        std::vector<uint8_t> vec1 {0xcb, 0x8f, 0x0a};
913c5f01b2fSopenharmony_ci        CHECK_THROWS_WITH_AS(_ = json::from_msgpack(vec1), "[json.exception.parse_error.110] parse error at byte 4: syntax error while parsing MessagePack number: unexpected end of input", json::parse_error&);
914c5f01b2fSopenharmony_ci
915c5f01b2fSopenharmony_ci        // related test case: incomplete float32
916c5f01b2fSopenharmony_ci        std::vector<uint8_t> vec2 {0xca, 0x8f, 0x0a};
917c5f01b2fSopenharmony_ci        CHECK_THROWS_WITH_AS(_ = json::from_msgpack(vec2), "[json.exception.parse_error.110] parse error at byte 4: syntax error while parsing MessagePack number: unexpected end of input", json::parse_error&);
918c5f01b2fSopenharmony_ci
919c5f01b2fSopenharmony_ci        // related test case: incomplete Half-Precision Float (CBOR)
920c5f01b2fSopenharmony_ci        std::vector<uint8_t> vec3 {0xf9, 0x8f};
921c5f01b2fSopenharmony_ci        CHECK_THROWS_WITH_AS(_ = json::from_cbor(vec3), "[json.exception.parse_error.110] parse error at byte 3: syntax error while parsing CBOR number: unexpected end of input", json::parse_error&);
922c5f01b2fSopenharmony_ci
923c5f01b2fSopenharmony_ci        // related test case: incomplete Single-Precision Float (CBOR)
924c5f01b2fSopenharmony_ci        std::vector<uint8_t> vec4 {0xfa, 0x8f, 0x0a};
925c5f01b2fSopenharmony_ci        CHECK_THROWS_WITH_AS(_ = json::from_cbor(vec4), "[json.exception.parse_error.110] parse error at byte 4: syntax error while parsing CBOR number: unexpected end of input", json::parse_error&);
926c5f01b2fSopenharmony_ci
927c5f01b2fSopenharmony_ci        // related test case: incomplete Double-Precision Float (CBOR)
928c5f01b2fSopenharmony_ci        std::vector<uint8_t> vec5 {0xfb, 0x8f, 0x0a};
929c5f01b2fSopenharmony_ci        CHECK_THROWS_WITH_AS(_ = json::from_cbor(vec5), "[json.exception.parse_error.110] parse error at byte 4: syntax error while parsing CBOR number: unexpected end of input", json::parse_error&);
930c5f01b2fSopenharmony_ci    }
931c5f01b2fSopenharmony_ci
932c5f01b2fSopenharmony_ci    SECTION("issue #408 - Heap-buffer-overflow (OSS-Fuzz issue 344)")
933c5f01b2fSopenharmony_ci    {
934c5f01b2fSopenharmony_ci        json _;
935c5f01b2fSopenharmony_ci
936c5f01b2fSopenharmony_ci        // original test case
937c5f01b2fSopenharmony_ci        std::vector<uint8_t> vec1 {0x87};
938c5f01b2fSopenharmony_ci        CHECK_THROWS_WITH_AS(_ = json::from_msgpack(vec1), "[json.exception.parse_error.110] parse error at byte 2: syntax error while parsing MessagePack string: unexpected end of input", json::parse_error&);
939c5f01b2fSopenharmony_ci
940c5f01b2fSopenharmony_ci        // more test cases for MessagePack
941c5f01b2fSopenharmony_ci        for (auto b :
942c5f01b2fSopenharmony_ci                {
943c5f01b2fSopenharmony_ci                    0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, // fixmap
944c5f01b2fSopenharmony_ci                    0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, // fixarray
945c5f01b2fSopenharmony_ci                    0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, // fixstr
946c5f01b2fSopenharmony_ci                    0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf
947c5f01b2fSopenharmony_ci                })
948c5f01b2fSopenharmony_ci        {
949c5f01b2fSopenharmony_ci            std::vector<uint8_t> vec(1, static_cast<uint8_t>(b));
950c5f01b2fSopenharmony_ci            CHECK_THROWS_AS(_ = json::from_msgpack(vec), json::parse_error&);
951c5f01b2fSopenharmony_ci        }
952c5f01b2fSopenharmony_ci
953c5f01b2fSopenharmony_ci        // more test cases for CBOR
954c5f01b2fSopenharmony_ci        for (auto b :
955c5f01b2fSopenharmony_ci                {
956c5f01b2fSopenharmony_ci                    0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
957c5f01b2fSopenharmony_ci                    0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, // UTF-8 string
958c5f01b2fSopenharmony_ci                    0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
959c5f01b2fSopenharmony_ci                    0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, // array
960c5f01b2fSopenharmony_ci                    0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
961c5f01b2fSopenharmony_ci                    0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7 // map
962c5f01b2fSopenharmony_ci                })
963c5f01b2fSopenharmony_ci        {
964c5f01b2fSopenharmony_ci            std::vector<uint8_t> vec(1, static_cast<uint8_t>(b));
965c5f01b2fSopenharmony_ci            CHECK_THROWS_AS(_ = json::from_cbor(vec), json::parse_error&);
966c5f01b2fSopenharmony_ci        }
967c5f01b2fSopenharmony_ci
968c5f01b2fSopenharmony_ci        // special case: empty input
969c5f01b2fSopenharmony_ci        std::vector<uint8_t> vec2;
970c5f01b2fSopenharmony_ci        CHECK_THROWS_WITH_AS(_ = json::from_cbor(vec2), "[json.exception.parse_error.110] parse error at byte 1: syntax error while parsing CBOR value: unexpected end of input", json::parse_error&);
971c5f01b2fSopenharmony_ci        CHECK_THROWS_WITH_AS(_ = json::from_msgpack(vec2), "[json.exception.parse_error.110] parse error at byte 1: syntax error while parsing MessagePack value: unexpected end of input", json::parse_error&);
972c5f01b2fSopenharmony_ci    }
973c5f01b2fSopenharmony_ci
974c5f01b2fSopenharmony_ci    SECTION("issue #411 - Heap-buffer-overflow (OSS-Fuzz issue 366)")
975c5f01b2fSopenharmony_ci    {
976c5f01b2fSopenharmony_ci        json _;
977c5f01b2fSopenharmony_ci
978c5f01b2fSopenharmony_ci        // original test case: empty UTF-8 string (indefinite length)
979c5f01b2fSopenharmony_ci        std::vector<uint8_t> vec1 {0x7f};
980c5f01b2fSopenharmony_ci        CHECK_THROWS_WITH_AS(_ = json::from_cbor(vec1), "[json.exception.parse_error.110] parse error at byte 2: syntax error while parsing CBOR string: unexpected end of input", json::parse_error&);
981c5f01b2fSopenharmony_ci
982c5f01b2fSopenharmony_ci        // related test case: empty array (indefinite length)
983c5f01b2fSopenharmony_ci        std::vector<uint8_t> vec2 {0x9f};
984c5f01b2fSopenharmony_ci        CHECK_THROWS_WITH_AS(_ = json::from_cbor(vec2), "[json.exception.parse_error.110] parse error at byte 2: syntax error while parsing CBOR value: unexpected end of input", json::parse_error&);
985c5f01b2fSopenharmony_ci
986c5f01b2fSopenharmony_ci        // related test case: empty map (indefinite length)
987c5f01b2fSopenharmony_ci        std::vector<uint8_t> vec3 {0xbf};
988c5f01b2fSopenharmony_ci        CHECK_THROWS_WITH_AS(_ = json::from_cbor(vec3), "[json.exception.parse_error.110] parse error at byte 2: syntax error while parsing CBOR string: unexpected end of input", json::parse_error&);
989c5f01b2fSopenharmony_ci    }
990c5f01b2fSopenharmony_ci
991c5f01b2fSopenharmony_ci    SECTION("issue #412 - Heap-buffer-overflow (OSS-Fuzz issue 367)")
992c5f01b2fSopenharmony_ci    {
993c5f01b2fSopenharmony_ci        // original test case
994c5f01b2fSopenharmony_ci        std::vector<uint8_t> vec
995c5f01b2fSopenharmony_ci        {
996c5f01b2fSopenharmony_ci            0xab, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98,
997c5f01b2fSopenharmony_ci            0x98, 0x98, 0x98, 0x98, 0x98, 0x00, 0x00, 0x00,
998c5f01b2fSopenharmony_ci            0x60, 0xab, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98,
999c5f01b2fSopenharmony_ci            0x98, 0x98, 0x98, 0x98, 0x98, 0x00, 0x00, 0x00,
1000c5f01b2fSopenharmony_ci            0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60,
1001c5f01b2fSopenharmony_ci            0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60,
1002c5f01b2fSopenharmony_ci            0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60,
1003c5f01b2fSopenharmony_ci            0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60,
1004c5f01b2fSopenharmony_ci            0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60,
1005c5f01b2fSopenharmony_ci            0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60,
1006c5f01b2fSopenharmony_ci            0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0xa0, 0x9f,
1007c5f01b2fSopenharmony_ci            0x9f, 0x97, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60,
1008c5f01b2fSopenharmony_ci            0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60,
1009c5f01b2fSopenharmony_ci            0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60,
1010c5f01b2fSopenharmony_ci            0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60,
1011c5f01b2fSopenharmony_ci            0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60,
1012c5f01b2fSopenharmony_ci            0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60
1013c5f01b2fSopenharmony_ci        };
1014c5f01b2fSopenharmony_ci
1015c5f01b2fSopenharmony_ci        json _;
1016c5f01b2fSopenharmony_ci        CHECK_THROWS_WITH_AS(_ = json::from_cbor(vec), "[json.exception.parse_error.113] parse error at byte 2: syntax error while parsing CBOR string: expected length specification (0x60-0x7B) or indefinite string type (0x7F); last byte: 0x98", json::parse_error&);
1017c5f01b2fSopenharmony_ci
1018c5f01b2fSopenharmony_ci        // related test case: nonempty UTF-8 string (indefinite length)
1019c5f01b2fSopenharmony_ci        std::vector<uint8_t> vec1 {0x7f, 0x61, 0x61};
1020c5f01b2fSopenharmony_ci        CHECK_THROWS_WITH_AS(_ = json::from_cbor(vec1), "[json.exception.parse_error.110] parse error at byte 4: syntax error while parsing CBOR string: unexpected end of input", json::parse_error&);
1021c5f01b2fSopenharmony_ci
1022c5f01b2fSopenharmony_ci        // related test case: nonempty array (indefinite length)
1023c5f01b2fSopenharmony_ci        std::vector<uint8_t> vec2 {0x9f, 0x01};
1024c5f01b2fSopenharmony_ci        CHECK_THROWS_WITH_AS(_ = json::from_cbor(vec2), "[json.exception.parse_error.110] parse error at byte 3: syntax error while parsing CBOR value: unexpected end of input", json::parse_error&);
1025c5f01b2fSopenharmony_ci
1026c5f01b2fSopenharmony_ci        // related test case: nonempty map (indefinite length)
1027c5f01b2fSopenharmony_ci        std::vector<uint8_t> vec3 {0xbf, 0x61, 0x61, 0x01};
1028c5f01b2fSopenharmony_ci        CHECK_THROWS_WITH_AS(_ = json::from_cbor(vec3), "[json.exception.parse_error.110] parse error at byte 5: syntax error while parsing CBOR string: unexpected end of input", json::parse_error&);
1029c5f01b2fSopenharmony_ci    }
1030c5f01b2fSopenharmony_ci
1031c5f01b2fSopenharmony_ci    SECTION("issue #414 - compare with literal 0)")
1032c5f01b2fSopenharmony_ci    {
1033c5f01b2fSopenharmony_ci#define CHECK_TYPE(v) \
1034c5f01b2fSopenharmony_ci    CHECK((json(v) == (v)));\
1035c5f01b2fSopenharmony_ci    CHECK(((v) == json(v)));\
1036c5f01b2fSopenharmony_ci    CHECK_FALSE((json(v) != (v)));\
1037c5f01b2fSopenharmony_ci    CHECK_FALSE(((v) != json(v)));
1038c5f01b2fSopenharmony_ci
1039c5f01b2fSopenharmony_ci        CHECK_TYPE(nullptr)
1040c5f01b2fSopenharmony_ci        CHECK_TYPE(0)
1041c5f01b2fSopenharmony_ci        CHECK_TYPE(0u)
1042c5f01b2fSopenharmony_ci        CHECK_TYPE(0L)
1043c5f01b2fSopenharmony_ci        CHECK_TYPE(0.0)
1044c5f01b2fSopenharmony_ci        CHECK_TYPE("") // NOLINT(readability-container-size-empty)
1045c5f01b2fSopenharmony_ci
1046c5f01b2fSopenharmony_ci#undef CHECK_TYPE
1047c5f01b2fSopenharmony_ci    }
1048c5f01b2fSopenharmony_ci
1049c5f01b2fSopenharmony_ci    SECTION("issue #416 - Use-of-uninitialized-value (OSS-Fuzz issue 377)")
1050c5f01b2fSopenharmony_ci    {
1051c5f01b2fSopenharmony_ci        // original test case
1052c5f01b2fSopenharmony_ci        std::vector<uint8_t> vec1
1053c5f01b2fSopenharmony_ci        {
1054c5f01b2fSopenharmony_ci            0x94, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa,
1055c5f01b2fSopenharmony_ci            0x3a, 0x96, 0x96, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4,
1056c5f01b2fSopenharmony_ci            0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0x71,
1057c5f01b2fSopenharmony_ci            0xb4, 0xb4, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0x3a,
1058c5f01b2fSopenharmony_ci            0x96, 0x96, 0xb4, 0xb4, 0xfa, 0x94, 0x94, 0x61,
1059c5f01b2fSopenharmony_ci            0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0xfa
1060c5f01b2fSopenharmony_ci        };
1061c5f01b2fSopenharmony_ci
1062c5f01b2fSopenharmony_ci        json _;
1063c5f01b2fSopenharmony_ci        CHECK_THROWS_WITH_AS(_ = json::from_cbor(vec1), "[json.exception.parse_error.113] parse error at byte 13: syntax error while parsing CBOR string: expected length specification (0x60-0x7B) or indefinite string type (0x7F); last byte: 0xB4", json::parse_error&);
1064c5f01b2fSopenharmony_ci
1065c5f01b2fSopenharmony_ci        // related test case: double-precision
1066c5f01b2fSopenharmony_ci        std::vector<uint8_t> vec2
1067c5f01b2fSopenharmony_ci        {
1068c5f01b2fSopenharmony_ci            0x94, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa,
1069c5f01b2fSopenharmony_ci            0x3a, 0x96, 0x96, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4,
1070c5f01b2fSopenharmony_ci            0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0x71,
1071c5f01b2fSopenharmony_ci            0xb4, 0xb4, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0x3a,
1072c5f01b2fSopenharmony_ci            0x96, 0x96, 0xb4, 0xb4, 0xfa, 0x94, 0x94, 0x61,
1073c5f01b2fSopenharmony_ci            0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0xfb
1074c5f01b2fSopenharmony_ci        };
1075c5f01b2fSopenharmony_ci        CHECK_THROWS_WITH_AS(_ = json::from_cbor(vec2), "[json.exception.parse_error.113] parse error at byte 13: syntax error while parsing CBOR string: expected length specification (0x60-0x7B) or indefinite string type (0x7F); last byte: 0xB4", json::parse_error&);
1076c5f01b2fSopenharmony_ci    }
1077c5f01b2fSopenharmony_ci
1078c5f01b2fSopenharmony_ci    SECTION("issue #452 - Heap-buffer-overflow (OSS-Fuzz issue 585)")
1079c5f01b2fSopenharmony_ci    {
1080c5f01b2fSopenharmony_ci        std::vector<uint8_t> vec = {'-', '0', '1', '2', '2', '7', '4'};
1081c5f01b2fSopenharmony_ci        json _;
1082c5f01b2fSopenharmony_ci        CHECK_THROWS_AS(_ = json::parse(vec), json::parse_error&);
1083c5f01b2fSopenharmony_ci    }
1084c5f01b2fSopenharmony_ci
1085c5f01b2fSopenharmony_ci    SECTION("issue #454 - doubles are printed as integers")
1086c5f01b2fSopenharmony_ci    {
1087c5f01b2fSopenharmony_ci        json j = R"({"bool_value":true,"double_value":2.0,"int_value":10,"level1":{"list_value":[3,"hi",false],"tmp":5.0},"string_value":"hello"})"_json;
1088c5f01b2fSopenharmony_ci        CHECK(j["double_value"].is_number_float());
1089c5f01b2fSopenharmony_ci    }
1090c5f01b2fSopenharmony_ci
1091c5f01b2fSopenharmony_ci#if JSON_USE_IMPLICIT_CONVERSIONS
1092c5f01b2fSopenharmony_ci    SECTION("issue #464 - VS2017 implicit to std::string conversion fix")
1093c5f01b2fSopenharmony_ci    {
1094c5f01b2fSopenharmony_ci        json v = "test";
1095c5f01b2fSopenharmony_ci        std::string test;
1096c5f01b2fSopenharmony_ci        test = v;
1097c5f01b2fSopenharmony_ci        CHECK(v == "test");
1098c5f01b2fSopenharmony_ci    }
1099c5f01b2fSopenharmony_ci#endif
1100c5f01b2fSopenharmony_ci
1101c5f01b2fSopenharmony_ci    SECTION("issue #465 - roundtrip error while parsing 1000000000000000010E5")
1102c5f01b2fSopenharmony_ci    {
1103c5f01b2fSopenharmony_ci        json j1 = json::parse("1000000000000000010E5");
1104c5f01b2fSopenharmony_ci        std::string s1 = j1.dump();
1105c5f01b2fSopenharmony_ci        json j2 = json::parse(s1);
1106c5f01b2fSopenharmony_ci        std::string s2 = j2.dump();
1107c5f01b2fSopenharmony_ci        CHECK(s1 == s2);
1108c5f01b2fSopenharmony_ci    }
1109c5f01b2fSopenharmony_ci
1110c5f01b2fSopenharmony_ci#if JSON_USE_IMPLICIT_CONVERSIONS
1111c5f01b2fSopenharmony_ci    SECTION("issue #473 - inconsistent behavior in conversion to array type")
1112c5f01b2fSopenharmony_ci    {
1113c5f01b2fSopenharmony_ci        json j_array = {1, 2, 3, 4};
1114c5f01b2fSopenharmony_ci        json j_number = 42;
1115c5f01b2fSopenharmony_ci        json j_null = nullptr;
1116c5f01b2fSopenharmony_ci
1117c5f01b2fSopenharmony_ci        SECTION("std::vector")
1118c5f01b2fSopenharmony_ci        {
1119c5f01b2fSopenharmony_ci            auto create = [](const json & j)
1120c5f01b2fSopenharmony_ci            {
1121c5f01b2fSopenharmony_ci                std::vector<int> v = j;
1122c5f01b2fSopenharmony_ci            };
1123c5f01b2fSopenharmony_ci
1124c5f01b2fSopenharmony_ci            CHECK_NOTHROW(create(j_array));
1125c5f01b2fSopenharmony_ci            CHECK_THROWS_WITH_AS(create(j_number), "[json.exception.type_error.302] type must be array, but is number", json::type_error&);
1126c5f01b2fSopenharmony_ci            CHECK_THROWS_WITH_AS(create(j_null), "[json.exception.type_error.302] type must be array, but is null", json::type_error&);
1127c5f01b2fSopenharmony_ci        }
1128c5f01b2fSopenharmony_ci
1129c5f01b2fSopenharmony_ci        SECTION("std::list")
1130c5f01b2fSopenharmony_ci        {
1131c5f01b2fSopenharmony_ci            auto create = [](const json & j)
1132c5f01b2fSopenharmony_ci            {
1133c5f01b2fSopenharmony_ci                std::list<int> v = j;
1134c5f01b2fSopenharmony_ci            };
1135c5f01b2fSopenharmony_ci
1136c5f01b2fSopenharmony_ci            CHECK_NOTHROW(create(j_array));
1137c5f01b2fSopenharmony_ci            CHECK_THROWS_WITH_AS(create(j_number), "[json.exception.type_error.302] type must be array, but is number", json::type_error&);
1138c5f01b2fSopenharmony_ci            CHECK_THROWS_WITH_AS(create(j_null), "[json.exception.type_error.302] type must be array, but is null", json::type_error&);
1139c5f01b2fSopenharmony_ci        }
1140c5f01b2fSopenharmony_ci
1141c5f01b2fSopenharmony_ci        SECTION("std::forward_list")
1142c5f01b2fSopenharmony_ci        {
1143c5f01b2fSopenharmony_ci            auto create = [](const json & j)
1144c5f01b2fSopenharmony_ci            {
1145c5f01b2fSopenharmony_ci                std::forward_list<int> v = j;
1146c5f01b2fSopenharmony_ci            };
1147c5f01b2fSopenharmony_ci
1148c5f01b2fSopenharmony_ci            CHECK_NOTHROW(create(j_array));
1149c5f01b2fSopenharmony_ci            CHECK_THROWS_WITH_AS(create(j_number), "[json.exception.type_error.302] type must be array, but is number", json::type_error&);
1150c5f01b2fSopenharmony_ci            CHECK_THROWS_WITH_AS(create(j_null), "[json.exception.type_error.302] type must be array, but is null", json::type_error&);
1151c5f01b2fSopenharmony_ci        }
1152c5f01b2fSopenharmony_ci    }
1153c5f01b2fSopenharmony_ci#endif
1154c5f01b2fSopenharmony_ci
1155c5f01b2fSopenharmony_ci    SECTION("issue #486 - json::value_t can't be a map's key type in VC++ 2015")
1156c5f01b2fSopenharmony_ci    {
1157c5f01b2fSopenharmony_ci        // the code below must compile with MSVC
1158c5f01b2fSopenharmony_ci        std::map<json::value_t, std::string> jsonTypes ;
1159c5f01b2fSopenharmony_ci        jsonTypes[json::value_t::array] = "array";
1160c5f01b2fSopenharmony_ci    }
1161c5f01b2fSopenharmony_ci
1162c5f01b2fSopenharmony_ci    SECTION("issue #494 - conversion from vector<bool> to json fails to build")
1163c5f01b2fSopenharmony_ci    {
1164c5f01b2fSopenharmony_ci        std::vector<bool> boolVector = {false, true, false, false};
1165c5f01b2fSopenharmony_ci        json j;
1166c5f01b2fSopenharmony_ci        j["bool_vector"] = boolVector;
1167c5f01b2fSopenharmony_ci
1168c5f01b2fSopenharmony_ci        CHECK(j["bool_vector"].dump() == "[false,true,false,false]");
1169c5f01b2fSopenharmony_ci    }
1170c5f01b2fSopenharmony_ci
1171c5f01b2fSopenharmony_ci    SECTION("issue #504 - assertion error (OSS-Fuzz 856)")
1172c5f01b2fSopenharmony_ci    {
1173c5f01b2fSopenharmony_ci        std::vector<uint8_t> vec1 = {0xf9, 0xff, 0xff, 0x4a, 0x3a, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01, 0x37, 0x02, 0x38};
1174c5f01b2fSopenharmony_ci        json j1 = json::from_cbor(vec1, false);
1175c5f01b2fSopenharmony_ci
1176c5f01b2fSopenharmony_ci        // step 2: round trip
1177c5f01b2fSopenharmony_ci        std::vector<uint8_t> vec2 = json::to_cbor(j1);
1178c5f01b2fSopenharmony_ci
1179c5f01b2fSopenharmony_ci        // parse serialization
1180c5f01b2fSopenharmony_ci        json j2 = json::from_cbor(vec2);
1181c5f01b2fSopenharmony_ci
1182c5f01b2fSopenharmony_ci        // NaN is dumped to "null"
1183c5f01b2fSopenharmony_ci        CHECK(j2.is_number_float());
1184c5f01b2fSopenharmony_ci        CHECK(std::isnan(j2.get<json::number_float_t>()));
1185c5f01b2fSopenharmony_ci        CHECK(j2.dump() == "null");
1186c5f01b2fSopenharmony_ci
1187c5f01b2fSopenharmony_ci        // check if serializations match
1188c5f01b2fSopenharmony_ci        CHECK(json::to_cbor(j2) == vec2);
1189c5f01b2fSopenharmony_ci    }
1190c5f01b2fSopenharmony_ci
1191c5f01b2fSopenharmony_ci    SECTION("issue #512 - use of overloaded operator '<=' is ambiguous")
1192c5f01b2fSopenharmony_ci    {
1193c5f01b2fSopenharmony_ci        json j;
1194c5f01b2fSopenharmony_ci        j["a"] = 5;
1195c5f01b2fSopenharmony_ci
1196c5f01b2fSopenharmony_ci        // json op scalar
1197c5f01b2fSopenharmony_ci        CHECK(j["a"] == 5);
1198c5f01b2fSopenharmony_ci        CHECK(j["a"] != 4);
1199c5f01b2fSopenharmony_ci
1200c5f01b2fSopenharmony_ci        CHECK(j["a"] <= 7);
1201c5f01b2fSopenharmony_ci        CHECK(j["a"] <  7);
1202c5f01b2fSopenharmony_ci        CHECK(j["a"] >= 3);
1203c5f01b2fSopenharmony_ci        CHECK(j["a"] >  3);
1204c5f01b2fSopenharmony_ci
1205c5f01b2fSopenharmony_ci
1206c5f01b2fSopenharmony_ci        CHECK(!(j["a"] <= 4));
1207c5f01b2fSopenharmony_ci        CHECK(!(j["a"] <  4));
1208c5f01b2fSopenharmony_ci        CHECK(!(j["a"] >= 6));
1209c5f01b2fSopenharmony_ci        CHECK(!(j["a"] >  6));
1210c5f01b2fSopenharmony_ci
1211c5f01b2fSopenharmony_ci        // scalar op json
1212c5f01b2fSopenharmony_ci        CHECK(5 == j["a"]);
1213c5f01b2fSopenharmony_ci        CHECK(4 != j["a"]);
1214c5f01b2fSopenharmony_ci
1215c5f01b2fSopenharmony_ci        CHECK(7 >= j["a"]);
1216c5f01b2fSopenharmony_ci        CHECK(7 >  j["a"]);
1217c5f01b2fSopenharmony_ci        CHECK(3 <= j["a"]);
1218c5f01b2fSopenharmony_ci        CHECK(3 <  j["a"]);
1219c5f01b2fSopenharmony_ci
1220c5f01b2fSopenharmony_ci        CHECK(!(4 >= j["a"]));
1221c5f01b2fSopenharmony_ci        CHECK(!(4 >  j["a"]));
1222c5f01b2fSopenharmony_ci        CHECK(!(6 <= j["a"]));
1223c5f01b2fSopenharmony_ci        CHECK(!(6 <  j["a"]));
1224c5f01b2fSopenharmony_ci    }
1225c5f01b2fSopenharmony_ci
1226c5f01b2fSopenharmony_ci    SECTION("issue #575 - heap-buffer-overflow (OSS-Fuzz 1400)")
1227c5f01b2fSopenharmony_ci    {
1228c5f01b2fSopenharmony_ci        json _;
1229c5f01b2fSopenharmony_ci        std::vector<uint8_t> vec = {'"', '\\', '"', 'X', '"', '"'};
1230c5f01b2fSopenharmony_ci        CHECK_THROWS_AS(_ = json::parse(vec), json::parse_error&);
1231c5f01b2fSopenharmony_ci    }
1232c5f01b2fSopenharmony_ci
1233c5f01b2fSopenharmony_ci#if JSON_USE_IMPLICIT_CONVERSIONS
1234c5f01b2fSopenharmony_ci    SECTION("issue #600 - how does one convert a map in Json back to std::map?")
1235c5f01b2fSopenharmony_ci    {
1236c5f01b2fSopenharmony_ci        SECTION("example 1")
1237c5f01b2fSopenharmony_ci        {
1238c5f01b2fSopenharmony_ci            // create a map
1239c5f01b2fSopenharmony_ci            std::map<std::string, int> m1 {{"key", 1}};
1240c5f01b2fSopenharmony_ci
1241c5f01b2fSopenharmony_ci            // create and print a JSON from the map
1242c5f01b2fSopenharmony_ci            json j = m1;
1243c5f01b2fSopenharmony_ci
1244c5f01b2fSopenharmony_ci            // get the map out of JSON
1245c5f01b2fSopenharmony_ci            std::map<std::string, int> m2 = j;
1246c5f01b2fSopenharmony_ci
1247c5f01b2fSopenharmony_ci            // make sure the roundtrip succeeds
1248c5f01b2fSopenharmony_ci            CHECK(m1 == m2);
1249c5f01b2fSopenharmony_ci        }
1250c5f01b2fSopenharmony_ci
1251c5f01b2fSopenharmony_ci        SECTION("example 2")
1252c5f01b2fSopenharmony_ci        {
1253c5f01b2fSopenharmony_ci            // create a map
1254c5f01b2fSopenharmony_ci            std::map<std::string, std::string> m1 {{"key", "val"}};
1255c5f01b2fSopenharmony_ci
1256c5f01b2fSopenharmony_ci            // create and print a JSON from the map
1257c5f01b2fSopenharmony_ci            json j = m1;
1258c5f01b2fSopenharmony_ci
1259c5f01b2fSopenharmony_ci            // get the map out of JSON
1260c5f01b2fSopenharmony_ci            std::map<std::string, std::string> m2 = j;
1261c5f01b2fSopenharmony_ci
1262c5f01b2fSopenharmony_ci            // make sure the roundtrip succeeds
1263c5f01b2fSopenharmony_ci            CHECK(m1 == m2);
1264c5f01b2fSopenharmony_ci        }
1265c5f01b2fSopenharmony_ci    }
1266c5f01b2fSopenharmony_ci#endif
1267c5f01b2fSopenharmony_ci
1268c5f01b2fSopenharmony_ci    SECTION("issue #602 - BOM not skipped when using json:parse(iterator)")
1269c5f01b2fSopenharmony_ci    {
1270c5f01b2fSopenharmony_ci        std::string i = "\xef\xbb\xbf{\n   \"foo\": true\n}";
1271c5f01b2fSopenharmony_ci        json _;
1272c5f01b2fSopenharmony_ci        CHECK_NOTHROW(_ = json::parse(i.begin(), i.end()));
1273c5f01b2fSopenharmony_ci    }
1274c5f01b2fSopenharmony_ci
1275c5f01b2fSopenharmony_ci#if JSON_USE_IMPLICIT_CONVERSIONS
1276c5f01b2fSopenharmony_ci    SECTION("issue #702 - conversion from valarray<double> to json fails to build")
1277c5f01b2fSopenharmony_ci    {
1278c5f01b2fSopenharmony_ci        SECTION("original example")
1279c5f01b2fSopenharmony_ci        {
1280c5f01b2fSopenharmony_ci            std::valarray<double> v;
1281c5f01b2fSopenharmony_ci            nlohmann::json j;
1282c5f01b2fSopenharmony_ci            j["test"] = v;
1283c5f01b2fSopenharmony_ci        }
1284c5f01b2fSopenharmony_ci
1285c5f01b2fSopenharmony_ci        SECTION("full example")
1286c5f01b2fSopenharmony_ci        {
1287c5f01b2fSopenharmony_ci            std::valarray<double> v = {1.2, 2.3, 3.4, 4.5};
1288c5f01b2fSopenharmony_ci            json j = v;
1289c5f01b2fSopenharmony_ci            std::valarray<double> vj = j;
1290c5f01b2fSopenharmony_ci
1291c5f01b2fSopenharmony_ci            CHECK(j == json(vj));
1292c5f01b2fSopenharmony_ci            CHECK(v.size() == vj.size());
1293c5f01b2fSopenharmony_ci            for (size_t i = 0; i < v.size(); ++i)
1294c5f01b2fSopenharmony_ci            {
1295c5f01b2fSopenharmony_ci                CHECK(v[i] == vj[i]);
1296c5f01b2fSopenharmony_ci                CHECK(v[i] == j[i]);
1297c5f01b2fSopenharmony_ci            }
1298c5f01b2fSopenharmony_ci
1299c5f01b2fSopenharmony_ci            CHECK_THROWS_WITH_AS(json().get<std::valarray<double>>(), "[json.exception.type_error.302] type must be array, but is null", json::type_error&);
1300c5f01b2fSopenharmony_ci        }
1301c5f01b2fSopenharmony_ci    }
1302c5f01b2fSopenharmony_ci#endif
1303c5f01b2fSopenharmony_ci
1304c5f01b2fSopenharmony_ci    SECTION("issue #367 - Behavior of operator>> should more closely resemble that of built-in overloads.")
1305c5f01b2fSopenharmony_ci    {
1306c5f01b2fSopenharmony_ci        SECTION("example 1")
1307c5f01b2fSopenharmony_ci        {
1308c5f01b2fSopenharmony_ci            std::istringstream i1_2_3( R"({"first": "one" }{"second": "two"}3)" );
1309c5f01b2fSopenharmony_ci            json j1;
1310c5f01b2fSopenharmony_ci            json j2;
1311c5f01b2fSopenharmony_ci            json j3;
1312c5f01b2fSopenharmony_ci            i1_2_3 >> j1;
1313c5f01b2fSopenharmony_ci            i1_2_3 >> j2;
1314c5f01b2fSopenharmony_ci            i1_2_3 >> j3;
1315c5f01b2fSopenharmony_ci
1316c5f01b2fSopenharmony_ci            auto m1 = j1.get<std::map<std::string, std::string>>();
1317c5f01b2fSopenharmony_ci            auto m2 = j2.get<std::map<std::string, std::string>>();
1318c5f01b2fSopenharmony_ci            int i3{j3};
1319c5f01b2fSopenharmony_ci
1320c5f01b2fSopenharmony_ci            CHECK( m1 == ( std::map<std::string, std::string> {{ "first",  "one" }} ));
1321c5f01b2fSopenharmony_ci            CHECK( m2 == ( std::map<std::string, std::string> {{ "second", "two" }} ));
1322c5f01b2fSopenharmony_ci            CHECK( i3 == 3 );
1323c5f01b2fSopenharmony_ci        }
1324c5f01b2fSopenharmony_ci    }
1325c5f01b2fSopenharmony_ci
1326c5f01b2fSopenharmony_ci    SECTION("issue #714 - throw std::ios_base::failure exception when failbit set to true")
1327c5f01b2fSopenharmony_ci    {
1328c5f01b2fSopenharmony_ci        {
1329c5f01b2fSopenharmony_ci            std::ifstream is;
1330c5f01b2fSopenharmony_ci            is.exceptions(
1331c5f01b2fSopenharmony_ci                is.exceptions()
1332c5f01b2fSopenharmony_ci                | std::ios_base::failbit
1333c5f01b2fSopenharmony_ci                | std::ios_base::badbit
1334c5f01b2fSopenharmony_ci            ); // handle different exceptions as 'file not found', 'permission denied'
1335c5f01b2fSopenharmony_ci
1336c5f01b2fSopenharmony_ci            is.open(TEST_DATA_DIRECTORY "/regression/working_file.json");
1337c5f01b2fSopenharmony_ci            json _;
1338c5f01b2fSopenharmony_ci            CHECK_NOTHROW(_ = nlohmann::json::parse(is));
1339c5f01b2fSopenharmony_ci        }
1340c5f01b2fSopenharmony_ci
1341c5f01b2fSopenharmony_ci        {
1342c5f01b2fSopenharmony_ci            std::ifstream is;
1343c5f01b2fSopenharmony_ci            is.exceptions(
1344c5f01b2fSopenharmony_ci                is.exceptions()
1345c5f01b2fSopenharmony_ci                | std::ios_base::failbit
1346c5f01b2fSopenharmony_ci                | std::ios_base::badbit
1347c5f01b2fSopenharmony_ci            ); // handle different exceptions as 'file not found', 'permission denied'
1348c5f01b2fSopenharmony_ci
1349c5f01b2fSopenharmony_ci            is.open(TEST_DATA_DIRECTORY "/json_nlohmann_tests/all_unicode.json.cbor",
1350c5f01b2fSopenharmony_ci                    std::ios_base::in | std::ios_base::binary);
1351c5f01b2fSopenharmony_ci            json _;
1352c5f01b2fSopenharmony_ci            CHECK_NOTHROW(_ = nlohmann::json::from_cbor(is));
1353c5f01b2fSopenharmony_ci        }
1354c5f01b2fSopenharmony_ci    }
1355c5f01b2fSopenharmony_ci
1356c5f01b2fSopenharmony_ci    SECTION("issue #805 - copy constructor is used with std::initializer_list constructor.")
1357c5f01b2fSopenharmony_ci    {
1358c5f01b2fSopenharmony_ci        nocopy n;
1359c5f01b2fSopenharmony_ci        json j;
1360c5f01b2fSopenharmony_ci        j = {{"nocopy", n}};
1361c5f01b2fSopenharmony_ci        CHECK(j["nocopy"]["val"] == 0);
1362c5f01b2fSopenharmony_ci    }
1363c5f01b2fSopenharmony_ci
1364c5f01b2fSopenharmony_ci    SECTION("issue #838 - incorrect parse error with binary data in keys")
1365c5f01b2fSopenharmony_ci    {
1366c5f01b2fSopenharmony_ci        std::array<uint8_t, 28> key1 = {{ 103, 92, 117, 48, 48, 48, 55, 92, 114, 215, 126, 214, 95, 92, 34, 174, 40, 71, 38, 174, 40, 71, 38, 223, 134, 247, 127, 0 }};
1367c5f01b2fSopenharmony_ci        std::string key1_str(reinterpret_cast<char*>(key1.data()));
1368c5f01b2fSopenharmony_ci        json j = key1_str;
1369c5f01b2fSopenharmony_ci        CHECK_THROWS_WITH_AS(j.dump(), "[json.exception.type_error.316] invalid UTF-8 byte at index 10: 0x7E", json::type_error&);
1370c5f01b2fSopenharmony_ci    }
1371c5f01b2fSopenharmony_ci
1372c5f01b2fSopenharmony_ci#if JSON_USE_IMPLICIT_CONVERSIONS
1373c5f01b2fSopenharmony_ci    SECTION("issue #843 - converting to array not working")
1374c5f01b2fSopenharmony_ci    {
1375c5f01b2fSopenharmony_ci        json j;
1376c5f01b2fSopenharmony_ci        std::array<int, 4> ar = {{1, 1, 1, 1}};
1377c5f01b2fSopenharmony_ci        j = ar;
1378c5f01b2fSopenharmony_ci        ar = j;
1379c5f01b2fSopenharmony_ci    }
1380c5f01b2fSopenharmony_ci#endif
1381c5f01b2fSopenharmony_ci
1382c5f01b2fSopenharmony_ci    SECTION("issue #894 - invalid RFC6902 copy operation succeeds")
1383c5f01b2fSopenharmony_ci    {
1384c5f01b2fSopenharmony_ci        auto model = R"({
1385c5f01b2fSopenharmony_ci            "one": {
1386c5f01b2fSopenharmony_ci                "two": {
1387c5f01b2fSopenharmony_ci                    "three": "hello",
1388c5f01b2fSopenharmony_ci                    "four": 42
1389c5f01b2fSopenharmony_ci                }
1390c5f01b2fSopenharmony_ci            }
1391c5f01b2fSopenharmony_ci        })"_json;
1392c5f01b2fSopenharmony_ci
1393c5f01b2fSopenharmony_ci        auto p1 = R"([{"op": "move",
1394c5f01b2fSopenharmony_ci                       "from": "/one/two/three",
1395c5f01b2fSopenharmony_ci                       "path": "/a/b/c"}])"_json;
1396c5f01b2fSopenharmony_ci        CHECK_THROWS_WITH_AS(model.patch(p1),
1397c5f01b2fSopenharmony_ci                             "[json.exception.out_of_range.403] key 'a' not found", json::out_of_range&);
1398c5f01b2fSopenharmony_ci
1399c5f01b2fSopenharmony_ci        auto p2 = R"([{"op": "copy",
1400c5f01b2fSopenharmony_ci                       "from": "/one/two/three",
1401c5f01b2fSopenharmony_ci                       "path": "/a/b/c"}])"_json;
1402c5f01b2fSopenharmony_ci        CHECK_THROWS_WITH_AS(model.patch(p2),
1403c5f01b2fSopenharmony_ci                             "[json.exception.out_of_range.403] key 'a' not found", json::out_of_range&);
1404c5f01b2fSopenharmony_ci    }
1405c5f01b2fSopenharmony_ci
1406c5f01b2fSopenharmony_ci    SECTION("issue #961 - incorrect parsing of indefinite length CBOR strings")
1407c5f01b2fSopenharmony_ci    {
1408c5f01b2fSopenharmony_ci        std::vector<uint8_t> v_cbor =
1409c5f01b2fSopenharmony_ci        {
1410c5f01b2fSopenharmony_ci            0x7F,
1411c5f01b2fSopenharmony_ci            0x64,
1412c5f01b2fSopenharmony_ci            'a', 'b', 'c', 'd',
1413c5f01b2fSopenharmony_ci            0x63,
1414c5f01b2fSopenharmony_ci            '1', '2', '3',
1415c5f01b2fSopenharmony_ci            0xFF
1416c5f01b2fSopenharmony_ci        };
1417c5f01b2fSopenharmony_ci        json j = json::from_cbor(v_cbor);
1418c5f01b2fSopenharmony_ci        CHECK(j == "abcd123");
1419c5f01b2fSopenharmony_ci    }
1420c5f01b2fSopenharmony_ci
1421c5f01b2fSopenharmony_ci    SECTION("issue #962 - Timeout (OSS-Fuzz 6034)")
1422c5f01b2fSopenharmony_ci    {
1423c5f01b2fSopenharmony_ci        json _;
1424c5f01b2fSopenharmony_ci        std::vector<uint8_t> v_ubjson = {'[', '$', 'Z', '#', 'L', 0x78, 0x28, 0x00, 0x68, 0x28, 0x69, 0x69, 0x17};
1425c5f01b2fSopenharmony_ci        CHECK_THROWS_AS(_ = json::from_ubjson(v_ubjson), json::out_of_range&);
1426c5f01b2fSopenharmony_ci        //CHECK_THROWS_WITH(json::from_ubjson(v_ubjson),
1427c5f01b2fSopenharmony_ci        //                  "[json.exception.out_of_range.408] excessive array size: 8658170730974374167");
1428c5f01b2fSopenharmony_ci
1429c5f01b2fSopenharmony_ci        v_ubjson[0] = '{';
1430c5f01b2fSopenharmony_ci        CHECK_THROWS_AS(_ = json::from_ubjson(v_ubjson), json::out_of_range&);
1431c5f01b2fSopenharmony_ci        //CHECK_THROWS_WITH(json::from_ubjson(v_ubjson),
1432c5f01b2fSopenharmony_ci        //                  "[json.exception.out_of_range.408] excessive object size: 8658170730974374167");
1433c5f01b2fSopenharmony_ci    }
1434c5f01b2fSopenharmony_ci
1435c5f01b2fSopenharmony_ci    SECTION("issue #971 - Add a SAX parser - late bug")
1436c5f01b2fSopenharmony_ci    {
1437c5f01b2fSopenharmony_ci        // a JSON text
1438c5f01b2fSopenharmony_ci        const auto* text = R"(
1439c5f01b2fSopenharmony_ci    {
1440c5f01b2fSopenharmony_ci        "Image": {
1441c5f01b2fSopenharmony_ci            "Width":  800,
1442c5f01b2fSopenharmony_ci            "Height": 600,
1443c5f01b2fSopenharmony_ci            "Title":  "View from 15th Floor",
1444c5f01b2fSopenharmony_ci            "Thumbnail": {
1445c5f01b2fSopenharmony_ci                "Url":    "http://www.example.com/image/481989943",
1446c5f01b2fSopenharmony_ci                "Height": 125,
1447c5f01b2fSopenharmony_ci                "Width":  100
1448c5f01b2fSopenharmony_ci            },
1449c5f01b2fSopenharmony_ci            "Animated" : false,
1450c5f01b2fSopenharmony_ci            "IDs": [116, 943, 234, 38793]
1451c5f01b2fSopenharmony_ci        }
1452c5f01b2fSopenharmony_ci    }
1453c5f01b2fSopenharmony_ci    )";
1454c5f01b2fSopenharmony_ci
1455c5f01b2fSopenharmony_ci        // define parser callback
1456c5f01b2fSopenharmony_ci        json::parser_callback_t cb = [](int /*depth*/, json::parse_event_t event, json & parsed)
1457c5f01b2fSopenharmony_ci        {
1458c5f01b2fSopenharmony_ci            // skip object elements with key "Thumbnail"
1459c5f01b2fSopenharmony_ci            return !(event == json::parse_event_t::key && parsed == json("Thumbnail"));
1460c5f01b2fSopenharmony_ci        };
1461c5f01b2fSopenharmony_ci
1462c5f01b2fSopenharmony_ci        // parse (with callback) and serialize JSON
1463c5f01b2fSopenharmony_ci        json j_filtered = json::parse(text, cb);
1464c5f01b2fSopenharmony_ci
1465c5f01b2fSopenharmony_ci        CHECK(j_filtered == R"({"Image":{"Animated":false,"Height":600,"IDs":[116,943,234,38793], "Title":"View from 15th Floor","Width":800}})"_json);
1466c5f01b2fSopenharmony_ci    }
1467c5f01b2fSopenharmony_ci
1468c5f01b2fSopenharmony_ci    SECTION("issue #972 - Segmentation fault on G++ when trying to assign json string literal to custom json type")
1469c5f01b2fSopenharmony_ci    {
1470c5f01b2fSopenharmony_ci        my_json foo = R"([1, 2, 3])"_json;
1471c5f01b2fSopenharmony_ci    }
1472c5f01b2fSopenharmony_ci
1473c5f01b2fSopenharmony_ci    SECTION("issue #977 - Assigning between different json types")
1474c5f01b2fSopenharmony_ci    {
1475c5f01b2fSopenharmony_ci        foo_json lj = ns::foo{3};
1476c5f01b2fSopenharmony_ci        ns::foo ff(lj);
1477c5f01b2fSopenharmony_ci        CHECK(lj.is_object());
1478c5f01b2fSopenharmony_ci        CHECK(lj.size() == 1);
1479c5f01b2fSopenharmony_ci        CHECK(lj["x"] == 3);
1480c5f01b2fSopenharmony_ci        CHECK(ff.x == 3);
1481c5f01b2fSopenharmony_ci        nlohmann::json nj = lj;                // This line works as expected
1482c5f01b2fSopenharmony_ci    }
1483c5f01b2fSopenharmony_ci}
1484c5f01b2fSopenharmony_ci
1485c5f01b2fSopenharmony_ci#if !defined(JSON_NOEXCEPTION)
1486c5f01b2fSopenharmony_ciTEST_CASE("regression tests, exceptions dependent")
1487c5f01b2fSopenharmony_ci{
1488c5f01b2fSopenharmony_ci    SECTION("issue #1340 - eof not set on exhausted input stream")
1489c5f01b2fSopenharmony_ci    {
1490c5f01b2fSopenharmony_ci        std::stringstream s("{}{}");
1491c5f01b2fSopenharmony_ci        json j;
1492c5f01b2fSopenharmony_ci        s >> j;
1493c5f01b2fSopenharmony_ci        s >> j;
1494c5f01b2fSopenharmony_ci        CHECK_THROWS_AS(s >> j, json::parse_error const&);
1495c5f01b2fSopenharmony_ci        CHECK(s.eof());
1496c5f01b2fSopenharmony_ci    }
1497c5f01b2fSopenharmony_ci}
1498c5f01b2fSopenharmony_ci#endif
1499c5f01b2fSopenharmony_ci
1500c5f01b2fSopenharmony_ci/////////////////////////////////////////////////////////////////////
1501c5f01b2fSopenharmony_ci// for #1642
1502c5f01b2fSopenharmony_ci/////////////////////////////////////////////////////////////////////
1503c5f01b2fSopenharmony_ci
1504c5f01b2fSopenharmony_ci// the code below fails with Clang on Windows, so we need to exclude it there
1505c5f01b2fSopenharmony_ci#if DOCTEST_CLANG && (defined(WIN32) || defined(_WIN32) || defined(__WIN32) && !defined(__CYGWIN__))
1506c5f01b2fSopenharmony_ci#else
1507c5f01b2fSopenharmony_citemplate <typename T> class array {};
1508c5f01b2fSopenharmony_citemplate <typename T> class object {};
1509c5f01b2fSopenharmony_citemplate <typename T> class string {};
1510c5f01b2fSopenharmony_citemplate <typename T> class number_integer {};
1511c5f01b2fSopenharmony_citemplate <typename T> class number_unsigned {};
1512c5f01b2fSopenharmony_citemplate <typename T> class number_float {};
1513c5f01b2fSopenharmony_ci#endif
1514