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