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