xref: /third_party/json/tests/src/unit-32bit.cpp (revision c5f01b2f)
1//     __ _____ _____ _____
2//  __|  |   __|     |   | |  JSON for Modern C++ (supporting code)
3// |  |  |__   |  |  | | | |  version 3.11.2
4// |_____|_____|_____|_|___|  https://github.com/nlohmann/json
5//
6// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
7// SPDX-License-Identifier: MIT
8
9#include "doctest_compatibility.h"
10
11#include <nlohmann/json.hpp>
12using nlohmann::json;
13
14#include <climits> // SIZE_MAX
15#include <limits> // numeric_limits
16
17
18template <typename OfType, typename T, bool MinInRange, bool MaxInRange>
19struct trait_test_arg
20{
21    using of_type = OfType;
22    using type = T;
23    static constexpr bool min_in_range = MinInRange;
24    static constexpr bool max_in_range = MaxInRange;
25};
26
27TEST_CASE_TEMPLATE_DEFINE("value_in_range_of trait", T, value_in_range_of_test)
28{
29    using nlohmann::detail::value_in_range_of;
30
31    using of_type = typename T::of_type;
32    using type = typename T::type;
33    constexpr bool min_in_range = T::min_in_range;
34    constexpr bool max_in_range = T::max_in_range;
35
36    type val_min = std::numeric_limits<type>::min();
37    type val_min2 = val_min + 1;
38    type val_max = std::numeric_limits<type>::max();
39    type val_max2 = val_max - 1;
40
41    REQUIRE(CHAR_BIT == 8);
42
43    std::string of_type_str;
44    if (std::is_unsigned<of_type>::value)
45    {
46        of_type_str += "u";
47    }
48    of_type_str += "int";
49    of_type_str += std::to_string(sizeof(of_type) * 8);
50
51    INFO("of_type := ", of_type_str);
52
53    std::string type_str;
54    if (std::is_unsigned<type>::value)
55    {
56        type_str += "u";
57    }
58    type_str += "int";
59    type_str += std::to_string(sizeof(type) * 8);
60
61    INFO("type := ", type_str);
62
63    CAPTURE(val_min);
64    CAPTURE(min_in_range);
65    CAPTURE(val_max);
66    CAPTURE(max_in_range);
67
68    if (min_in_range)
69    {
70        CHECK(value_in_range_of<of_type>(val_min));
71        CHECK(value_in_range_of<of_type>(val_min2));
72    }
73    else
74    {
75        CHECK_FALSE(value_in_range_of<of_type>(val_min));
76        CHECK_FALSE(value_in_range_of<of_type>(val_min2));
77    }
78
79    if (max_in_range)
80    {
81        CHECK(value_in_range_of<of_type>(val_max));
82        CHECK(value_in_range_of<of_type>(val_max2));
83    }
84    else
85    {
86        CHECK_FALSE(value_in_range_of<of_type>(val_max));
87        CHECK_FALSE(value_in_range_of<of_type>(val_max2));
88    }
89}
90
91
92TEST_CASE("32bit")
93{
94    REQUIRE(SIZE_MAX == 0xffffffff);
95}
96
97TEST_CASE_TEMPLATE_INVOKE(value_in_range_of_test, \
98                          trait_test_arg<std::size_t, std::int32_t, false, true>, \
99                          trait_test_arg<std::size_t, std::uint32_t, true, true>, \
100                          trait_test_arg<std::size_t, std::int64_t, false, false>, \
101                          trait_test_arg<std::size_t, std::uint64_t, true, false>);
102
103TEST_CASE("BJData")
104{
105    SECTION("parse errors")
106    {
107        SECTION("array")
108        {
109            SECTION("optimized array: negative size")
110            {
111                std::vector<uint8_t> vM = {'[', '$', 'M', '#', '[', 'I', 0x00, 0x20, 'M', 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0xFF, ']'};
112                std::vector<uint8_t> vMX = {'[', '$', 'U', '#', '[', 'M', 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 'U', 0x01, ']'};
113
114                json _;
115                CHECK_THROWS_WITH_AS(_ = json::from_bjdata(vM), "[json.exception.out_of_range.408] syntax error while parsing BJData size: integer value overflow", json::out_of_range&);
116                CHECK(json::from_bjdata(vM, true, false).is_discarded());
117
118                CHECK_THROWS_WITH_AS(_ = json::from_bjdata(vMX), "[json.exception.out_of_range.408] syntax error while parsing BJData size: integer value overflow", json::out_of_range&);
119                CHECK(json::from_bjdata(vMX, true, false).is_discarded());
120            }
121
122            SECTION("optimized array: integer value overflow")
123            {
124                std::vector<uint8_t> vL = {'[', '#', 'L', 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F};
125                std::vector<uint8_t> vM = {'[', '$', 'M', '#', '[', 'I', 0x00, 0x20, 'M', 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0xFF, ']'};
126
127                json _;
128                CHECK_THROWS_WITH_AS(_ = json::from_bjdata(vL), "[json.exception.out_of_range.408] syntax error while parsing BJData size: integer value overflow", json::out_of_range&);
129                CHECK(json::from_bjdata(vL, true, false).is_discarded());
130
131                CHECK_THROWS_WITH_AS(_ = json::from_bjdata(vM), "[json.exception.out_of_range.408] syntax error while parsing BJData size: integer value overflow", json::out_of_range&);
132                CHECK(json::from_bjdata(vM, true, false).is_discarded());
133            }
134        }
135    }
136}
137