Fix ndarray dimension signedness, fix ndarray length overflow (2); add 32bit unit test
Replaces #3521.

Closes #3519.
{"label": "nlohmann:develop", "ref": "develop", "sha": "b6d00d18974358ab1d55dcc3379d0ee3052deb4e"}
### Description

Given the following [BJData input](https://github.com/nlohmann/json/files/8844158/clusterfuzz-testcase-minimized-parse_bjdata_fuzzer-5159110460440576.zip)


```
00000000: 5b24 4d23 5b49 0020 4d00 0000 0000 0020  [$M#[I. M...... 
00000010: ff5d                                     .]
```

the library can successfully parse it to

```json
{
    "_ArrayData_": [],
    "_ArraySize_": [
        8192,
        -63050394783186944
    ],
    "_ArrayType_": "uint64"
}
```

However, when then serializing this JSON as BJData, the following exception is raised:

```
[json.exception.parse_error.113] parse error at byte 17: syntax error while parsing BJData size: count in an optimized container must be positive
```

The error was found by OSS-Fuzz, and is unrelated to the latest fixes.

- https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=47523&q=label%3AProj-json
- https://oss-fuzz.com/testcase-detail/5159110460440576

### Reproduction steps

```cpp
int main() {
    auto vec = readFile("clusterfuzz-testcase-minimized-parse_bjdata_fuzzer-5159110460440576.bjdata");

    auto j = json::from_bjdata(vec);
    std::vector<uint8_t> vec2 = json::to_bjdata(j, false, false);

    json::from_bjdata(vec2);
}
```

### Expected vs. actual results

- Expected: Either reject the original input or (also) accept the created byte vector.
- Actual: Accepting the input, but rejecting the byte vector.

I would also be fine with adding a note to https://json.nlohmann.me/features/binary_formats/bjdata/, but then we also need to adjust https://github.com/nlohmann/json/blob/develop/tests/src/fuzzer-parse_bjdata.cpp#L65

### Minimal code example

```Shell
See above.
```


### Error messages

```Shell
[json.exception.parse_error.113] parse error at byte 17: syntax error while parsing BJData size: count in an optimized container must be positive
```


### Compiler and operating system

OSS-Fuzz

### Library version

develop

### Validation

- [X] The bug also occurs if the latest version from the [`develop`](https://github.com/nlohmann/json/tree/develop) branch is used.
- [X] I can successfully [compile and run the unit tests](https://github.com/nlohmann/json#execute-unit-tests).
Error when roundtripping BJData
diff --git a/include/nlohmann/detail/input/binary_reader.hpp b/include/nlohmann/detail/input/binary_reader.hpp
index cbcb415889..9332af3e64 100644
--- a/include/nlohmann/detail/input/binary_reader.hpp
+++ b/include/nlohmann/detail/input/binary_reader.hpp
@@ -2079,6 +2079,12 @@ class binary_reader
                     return sax->parse_error(chars_read, get_token_string(), parse_error::create(113, chars_read,
                                             exception_message(input_format, "count in an optimized container must be positive", "size"), nullptr));
                 }
+                if (!value_in_range_of<std::size_t>(number))
+                {
+                    // undo coverage exclusion once the 32bit test is run as part of CI (#3524)
+                    return sax->parse_error(chars_read, get_token_string(), out_of_range::create(408, // LCOV_EXCL_LINE
+                                            exception_message(input_format, "integer value overflow", "size"), nullptr)); // LCOV_EXCL_LINE
+                }
                 result = static_cast<std::size_t>(number);
                 return true;
             }
@@ -2124,6 +2130,12 @@ class binary_reader
                 {
                     return false;
                 }
+                if (!value_in_range_of<std::size_t>(number))
+                {
+                    // undo coverage exclusion once the 32bit test is run as part of CI (#3524)
+                    return sax->parse_error(chars_read, get_token_string(), out_of_range::create(408, // LCOV_EXCL_LINE
+                                            exception_message(input_format, "integer value overflow", "size"), nullptr)); // LCOV_EXCL_LINE
+                }
                 result = detail::conditional_static_cast<std::size_t>(number);
                 return true;
             }
@@ -2168,7 +2180,11 @@ class binary_reader
                     for (auto i : dim)
                     {
                         result *= i;
-                        if (JSON_HEDLEY_UNLIKELY(!sax->number_integer(static_cast<number_integer_t>(i))))
+                        if (result == 0) // because dim elements shall not have zeros, result = 0 means overflow happened
+                        {
+                            return sax->parse_error(chars_read, get_token_string(), out_of_range::create(408, exception_message(input_format, "excessive ndarray size caused overflow", "size"), nullptr));
+                        }
+                        if (JSON_HEDLEY_UNLIKELY(!sax->number_unsigned(static_cast<number_unsigned_t>(i))))
                         {
                             return false;
                         }
diff --git a/include/nlohmann/detail/meta/type_traits.hpp b/include/nlohmann/detail/meta/type_traits.hpp
index 5e3ea37379..0901b71bb5 100644
--- a/include/nlohmann/detail/meta/type_traits.hpp
+++ b/include/nlohmann/detail/meta/type_traits.hpp
@@ -577,5 +577,100 @@ T conditional_static_cast(U value)
     return value;
 }
 
+template<typename... Types>
+using all_integral = conjunction<std::is_integral<Types>...>;
+
+template<typename... Types>
+using all_signed = conjunction<std::is_signed<Types>...>;
+
+template<typename... Types>
+using all_unsigned = conjunction<std::is_unsigned<Types>...>;
+
+// there's a disjunction trait in another PR; replace when merged
+template<typename... Types>
+using same_sign = std::integral_constant < bool,
+      all_signed<Types...>::value || all_unsigned<Types...>::value >;
+
+template<typename OfType, typename T>
+using never_out_of_range = std::integral_constant < bool,
+      (std::is_signed<OfType>::value && (sizeof(T) < sizeof(OfType)))
+      || (same_sign<OfType, T>::value && sizeof(OfType) == sizeof(T)) >;
+
+template<typename OfType, typename T,
+         bool OfTypeSigned = std::is_signed<OfType>::value,
+         bool TSigned = std::is_signed<T>::value>
+struct value_in_range_of_impl2;
+
+template<typename OfType, typename T>
+struct value_in_range_of_impl2<OfType, T, false, false>
+{
+    static constexpr bool test(T val)
+    {
+        using CommonType = typename std::common_type<OfType, T>::type;
+        return static_cast<CommonType>(val) <= static_cast<CommonType>(std::numeric_limits<OfType>::max());
+    }
+};
+
+template<typename OfType, typename T>
+struct value_in_range_of_impl2<OfType, T, true, false>
+{
+    static constexpr bool test(T val)
+    {
+        using CommonType = typename std::common_type<OfType, T>::type;
+        return static_cast<CommonType>(val) <= static_cast<CommonType>(std::numeric_limits<OfType>::max());
+    }
+};
+
+template<typename OfType, typename T>
+struct value_in_range_of_impl2<OfType, T, false, true>
+{
+    static constexpr bool test(T val)
+    {
+        using CommonType = typename std::common_type<OfType, T>::type;
+        return val >= 0 && static_cast<CommonType>(val) <= static_cast<CommonType>(std::numeric_limits<OfType>::max());
+    }
+};
+
+
+template<typename OfType, typename T>
+struct value_in_range_of_impl2<OfType, T, true, true>
+{
+    static constexpr bool test(T val)
+    {
+        using CommonType = typename std::common_type<OfType, T>::type;
+        return static_cast<CommonType>(val) >= static_cast<CommonType>(std::numeric_limits<OfType>::min())
+               && static_cast<CommonType>(val) <= static_cast<CommonType>(std::numeric_limits<OfType>::max());
+    }
+};
+
+template<typename OfType, typename T,
+         bool NeverOutOfRange = never_out_of_range<OfType, T>::value,
+         typename = detail::enable_if_t<all_integral<OfType, T>::value>>
+struct value_in_range_of_impl1;
+
+template<typename OfType, typename T>
+struct value_in_range_of_impl1<OfType, T, false>
+{
+    static constexpr bool test(T val)
+    {
+        return value_in_range_of_impl2<OfType, T>::test(val);
+    }
+};
+
+template<typename OfType, typename T>
+struct value_in_range_of_impl1<OfType, T, true>
+{
+    static constexpr bool test(T /*val*/)
+    {
+        return true;
+    }
+};
+
+template<typename OfType, typename T>
+inline constexpr bool value_in_range_of(T val)
+{
+    return value_in_range_of_impl1<OfType, T>::test(val);
+}
+
 }  // namespace detail
 }  // namespace nlohmann
diff --git a/single_include/nlohmann/json.hpp b/single_include/nlohmann/json.hpp
index 2837e74b9e..3dcd480274 100644
--- a/single_include/nlohmann/json.hpp
+++ b/single_include/nlohmann/json.hpp
@@ -3768,6 +3768,101 @@ T conditional_static_cast(U value)
     return value;
 }
 
+template<typename... Types>
+using all_integral = conjunction<std::is_integral<Types>...>;
+
+template<typename... Types>
+using all_signed = conjunction<std::is_signed<Types>...>;
+
+template<typename... Types>
+using all_unsigned = conjunction<std::is_unsigned<Types>...>;
+
+// there's a disjunction trait in another PR; replace when merged
+template<typename... Types>
+using same_sign = std::integral_constant < bool,
+      all_signed<Types...>::value || all_unsigned<Types...>::value >;
+
+template<typename OfType, typename T>
+using never_out_of_range = std::integral_constant < bool,
+      (std::is_signed<OfType>::value && (sizeof(T) < sizeof(OfType)))
+      || (same_sign<OfType, T>::value && sizeof(OfType) == sizeof(T)) >;
+
+template<typename OfType, typename T,
+         bool OfTypeSigned = std::is_signed<OfType>::value,
+         bool TSigned = std::is_signed<T>::value>
+struct value_in_range_of_impl2;
+
+template<typename OfType, typename T>
+struct value_in_range_of_impl2<OfType, T, false, false>
+{
+    static constexpr bool test(T val)
+    {
+        using CommonType = typename std::common_type<OfType, T>::type;
+        return static_cast<CommonType>(val) <= static_cast<CommonType>(std::numeric_limits<OfType>::max());
+    }
+};
+
+template<typename OfType, typename T>
+struct value_in_range_of_impl2<OfType, T, true, false>
+{
+    static constexpr bool test(T val)
+    {
+        using CommonType = typename std::common_type<OfType, T>::type;
+        return static_cast<CommonType>(val) <= static_cast<CommonType>(std::numeric_limits<OfType>::max());
+    }
+};
+
+template<typename OfType, typename T>
+struct value_in_range_of_impl2<OfType, T, false, true>
+{
+    static constexpr bool test(T val)
+    {
+        using CommonType = typename std::common_type<OfType, T>::type;
+        return val >= 0 && static_cast<CommonType>(val) <= static_cast<CommonType>(std::numeric_limits<OfType>::max());
+    }
+};
+
+
+template<typename OfType, typename T>
+struct value_in_range_of_impl2<OfType, T, true, true>
+{
+    static constexpr bool test(T val)
+    {
+        using CommonType = typename std::common_type<OfType, T>::type;
+        return static_cast<CommonType>(val) >= static_cast<CommonType>(std::numeric_limits<OfType>::min())
+               && static_cast<CommonType>(val) <= static_cast<CommonType>(std::numeric_limits<OfType>::max());
+    }
+};
+
+template<typename OfType, typename T,
+         bool NeverOutOfRange = never_out_of_range<OfType, T>::value,
+         typename = detail::enable_if_t<all_integral<OfType, T>::value>>
+struct value_in_range_of_impl1;
+
+template<typename OfType, typename T>
+struct value_in_range_of_impl1<OfType, T, false>
+{
+    static constexpr bool test(T val)
+    {
+        return value_in_range_of_impl2<OfType, T>::test(val);
+    }
+};
+
+template<typename OfType, typename T>
+struct value_in_range_of_impl1<OfType, T, true>
+{
+    static constexpr bool test(T /*val*/)
+    {
+        return true;
+    }
+};
+
+template<typename OfType, typename T>
+inline constexpr bool value_in_range_of(T val)
+{
+    return value_in_range_of_impl1<OfType, T>::test(val);
+}
+
 }  // namespace detail
 }  // namespace nlohmann
 
@@ -10669,6 +10764,12 @@ class binary_reader
                     return sax->parse_error(chars_read, get_token_string(), parse_error::create(113, chars_read,
                                             exception_message(input_format, "count in an optimized container must be positive", "size"), nullptr));
                 }
+                if (!value_in_range_of<std::size_t>(number))
+                {
+                    // undo coverage exclusion once the 32bit test is run as part of CI (#3524)
+                    return sax->parse_error(chars_read, get_token_string(), out_of_range::create(408, // LCOV_EXCL_LINE
+                                            exception_message(input_format, "integer value overflow", "size"), nullptr)); // LCOV_EXCL_LINE
+                }
                 result = static_cast<std::size_t>(number);
                 return true;
             }
@@ -10714,6 +10815,12 @@ class binary_reader
                 {
                     return false;
                 }
+                if (!value_in_range_of<std::size_t>(number))
+                {
+                    // undo coverage exclusion once the 32bit test is run as part of CI (#3524)
+                    return sax->parse_error(chars_read, get_token_string(), out_of_range::create(408, // LCOV_EXCL_LINE
+                                            exception_message(input_format, "integer value overflow", "size"), nullptr)); // LCOV_EXCL_LINE
+                }
                 result = detail::conditional_static_cast<std::size_t>(number);
                 return true;
             }
@@ -10758,7 +10865,11 @@ class binary_reader
                     for (auto i : dim)
                     {
                         result *= i;
-                        if (JSON_HEDLEY_UNLIKELY(!sax->number_integer(static_cast<number_integer_t>(i))))
+                        if (result == 0) // because dim elements shall not have zeros, result = 0 means overflow happened
+                        {
+                            return sax->parse_error(chars_read, get_token_string(), out_of_range::create(408, exception_message(input_format, "excessive ndarray size caused overflow", "size"), nullptr));
+                        }
+                        if (JSON_HEDLEY_UNLIKELY(!sax->number_unsigned(static_cast<number_unsigned_t>(i))))
                         {
                             return false;
                         }

diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index 010c4950ef..ef87c49092 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -2,6 +2,7 @@ cmake_minimum_required(VERSION 3.13)
 
 option(JSON_Valgrind    "Execute test suite with Valgrind." OFF)
 option(JSON_FastTests   "Skip expensive/slow tests." OFF)
+option(JSON_32bitTest   "Enable the 32bit unit test." OFF)
 
 set(JSON_TestStandards "" CACHE STRING "The list of standards to test explicitly.")
 
@@ -33,35 +34,40 @@ endif()
 # test_main library with shared code to speed up build and common settings
 #############################################################################
 
-add_library(test_main OBJECT src/unit.cpp)
-target_compile_definitions(test_main PUBLIC
+set(test_main_SOURCES src/unit.cpp)
+set(test_main_COMPILE_DEFINITIONS PUBLIC
     DOCTEST_CONFIG_SUPER_FAST_ASSERTS
-    JSON_TEST_KEEP_MACROS
-)
-target_compile_features(test_main PRIVATE cxx_std_11)
-target_compile_options(test_main PUBLIC
-    $<$<CXX_COMPILER_ID:MSVC>:/EHsc;$<$<CONFIG:Release>:/Od>>
-    # MSVC: Force to always compile with W4
-    #       Disable warning C4566: character represented by universal-character-name '\uFF01'
-    #                              cannot be represented in the current code page (1252)
-    #       Disable warning C4996: 'nlohmann::basic_json<...>::operator <<': was declared deprecated
-    $<$<CXX_COMPILER_ID:MSVC>:/W4 /wd4566 /wd4996>
-    # https://github.com/nlohmann/json/issues/1114
-    $<$<CXX_COMPILER_ID:MSVC>:/bigobj> $<$<BOOL:${MINGW}>:-Wa,-mbig-obj>
-
-    # https://github.com/nlohmann/json/pull/3229
-    $<$<CXX_COMPILER_ID:Intel>:-diag-disable=2196>
-
-    $<$<NOT:$<CXX_COMPILER_ID:MSVC>>:-Wno-deprecated;-Wno-float-equal>
-    $<$<CXX_COMPILER_ID:GNU>:-Wno-deprecated-declarations>
-    $<$<CXX_COMPILER_ID:Intel>:-diag-disable=1786>
-)
-target_include_directories(test_main PUBLIC
+    JSON_TEST_KEEP_MACROS)
+set(test_main_COMPILE_FEATURES PRIVATE cxx_std_11)
+set(test_main_COMPILE_OPTIONS
+    PUBLIC
+        $<$<CXX_COMPILER_ID:MSVC>:/EHsc;$<$<CONFIG:Release>:/Od>>
+        # MSVC: Force to always compile with W4
+        #       Disable warning C4566: character represented by universal-character-name '\uFF01'
+        #                              cannot be represented in the current code page (1252)
+        #       Disable warning C4996: 'nlohmann::basic_json<...>::operator <<': was declared deprecated
+        $<$<CXX_COMPILER_ID:MSVC>:/W4 /wd4566 /wd4996>
+        # https://github.com/nlohmann/json/issues/1114
+        $<$<CXX_COMPILER_ID:MSVC>:/bigobj> $<$<BOOL:${MINGW}>:-Wa,-mbig-obj>
+
+        # https://github.com/nlohmann/json/pull/3229
+        $<$<CXX_COMPILER_ID:Intel>:-diag-disable=2196>
+
+        $<$<NOT:$<CXX_COMPILER_ID:MSVC>>:-Wno-deprecated;-Wno-float-equal>
+        $<$<CXX_COMPILER_ID:GNU>:-Wno-deprecated-declarations>
+        $<$<CXX_COMPILER_ID:Intel>:-diag-disable=1786>)
+set(test_main_INCLUDE_DIRECTORIES PUBLIC
     thirdparty/doctest
     thirdparty/fifo_map
-    ${PROJECT_BINARY_DIR}/include
-)
-target_link_libraries(test_main PUBLIC ${NLOHMANN_JSON_TARGET_NAME})
+    ${PROJECT_BINARY_DIR}/include)
+set(test_main_LINK_LIBRARIES PUBLIC ${NLOHMANN_JSON_TARGET_NAME})
+
+add_library(test_main OBJECT ${test_main_SOURCES})
+target_compile_definitions(test_main ${test_main_COMPILE_DEFINITIONS})
+target_compile_features(test_main ${test_main_COMPILE_FEATURES})
+target_compile_options(test_main ${test_main_COMPILE_OPTIONS})
+target_include_directories(test_main ${test_main_INCLUDE_DIRECTORIES})
+target_link_libraries(test_main ${test_main_LINK_LIBRARIES})
 
 #############################################################################
 # define test- and standard-specific build settings
@@ -119,10 +125,24 @@ message(STATUS "${msg}")
 # *DO* use json_test_set_test_options() above this line
 
 file(GLOB files src/unit-*.cpp)
+list(FILTER files EXCLUDE REGEX "src/unit-32bit.cpp")
 foreach(file ${files})
     json_test_add_test_for(${file} MAIN test_main CXX_STANDARDS ${test_cxx_standards} ${test_force})
 endforeach()
 
+if(JSON_32bitTest)
+    add_library(test_main32 OBJECT ${test_main_SOURCES})
+    target_compile_definitions(test_main32 ${test_main_COMPILE_DEFINITIONS})
+    target_compile_features(test_main32 ${test_main_COMPILE_FEATURES})
+    target_compile_options(test_main32 ${test_main_COMPILE_OPTIONS} -m32)
+    target_include_directories(test_main32 ${test_main_INCLUDE_DIRECTORIES})
+    target_link_libraries(test_main32 ${test_main_LINK_LIBRARIES})
+    target_link_options(test_main32 PUBLIC -m32)
+
+    json_test_add_test_for("src/unit-32bit.cpp" MAIN test_main32
+        CXX_STANDARDS ${test_cxx_standards} ${test_force})
+endif()
+
 # test legacy comparison of discarded values
 json_test_set_test_options(test-comparison_legacy
     COMPILE_DEFINITIONS JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON=1
diff --git a/tests/src/unit-32bit.cpp b/tests/src/unit-32bit.cpp
new file mode 100644
index 0000000000..711dda5a0d
--- /dev/null
+++ b/tests/src/unit-32bit.cpp
@@ -0,0 +1,117 @@
+#include "doctest_compatibility.h"
+
+#include <nlohmann/json.hpp>
+using nlohmann::json;
+
+#include <climits> // SIZE_MAX
+#include <limits> // numeric_limits
+
+
+template <typename OfType, typename T, bool MinInRange, bool MaxInRange>
+struct trait_test_arg
+{
+    using of_type = OfType;
+    using type = T;
+    static constexpr bool min_in_range = MinInRange;
+    static constexpr bool max_in_range = MaxInRange;
+};
+
+TEST_CASE_TEMPLATE_DEFINE("value_in_range_of trait", T, value_in_range_of_test)
+{
+    using nlohmann::detail::value_in_range_of;
+
+    using of_type = typename T::of_type;
+    using type = typename T::type;
+    constexpr bool min_in_range = T::min_in_range;
+    constexpr bool max_in_range = T::max_in_range;
+
+    type val_min = std::numeric_limits<type>::min();
+    type val_min2 = val_min + 1;
+    type val_max = std::numeric_limits<type>::max();
+    type val_max2 = val_max - 1;
+
+    REQUIRE(CHAR_BIT == 8);
+
+    std::string of_type_str;
+    if (std::is_unsigned<of_type>::value)
+    {
+        of_type_str += "u";
+    }
+    of_type_str += "int";
+    of_type_str += std::to_string(sizeof(of_type) * 8);
+
+    INFO("of_type := ", of_type_str);
+
+    std::string type_str;
+    if (std::is_unsigned<type>::value)
+    {
+        type_str += "u";
+    }
+    type_str += "int";
+    type_str += std::to_string(sizeof(type) * 8);
+
+    INFO("type := ", type_str);
+
+    CAPTURE(val_min);
+    CAPTURE(min_in_range);
+    CAPTURE(val_max);
+    CAPTURE(max_in_range);
+
+    if (min_in_range)
+    {
+        CHECK(value_in_range_of<of_type>(val_min));
+        CHECK(value_in_range_of<of_type>(val_min2));
+    }
+    else
+    {
+        CHECK_FALSE(value_in_range_of<of_type>(val_min));
+        CHECK_FALSE(value_in_range_of<of_type>(val_min2));
+    }
+
+    if (max_in_range)
+    {
+        CHECK(value_in_range_of<of_type>(val_max));
+        CHECK(value_in_range_of<of_type>(val_max2));
+    }
+    else
+    {
+        CHECK_FALSE(value_in_range_of<of_type>(val_max));
+        CHECK_FALSE(value_in_range_of<of_type>(val_max2));
+    }
+}
+
+
+TEST_CASE("32bit")
+{
+    REQUIRE(SIZE_MAX == 0xffffffff);
+}
+
+TEST_CASE_TEMPLATE_INVOKE(value_in_range_of_test, \
+                          trait_test_arg<std::size_t, std::int32_t, false, true>, \
+                          trait_test_arg<std::size_t, std::uint32_t, true, true>, \
+                          trait_test_arg<std::size_t, std::int64_t, false, false>, \
+                          trait_test_arg<std::size_t, std::uint64_t, true, false>);
+
+TEST_CASE("BJData")
+{
+    SECTION("parse errors")
+    {
+        SECTION("array")
+        {
+            SECTION("optimized array: no size following type")
+            {
+                std::vector<uint8_t> v = {'[', '$', 'i', 2};
+                json _;
+                CHECK_THROWS_WITH_AS(_ = json::from_bjdata(v), "[json.exception.parse_error.112] parse error at byte 4: syntax error while parsing BJData size: expected '#' after type information; last byte: 0x02", json::parse_error&);
+            }
+
+            SECTION("optimized array: negative size")
+            {
+                std::vector<uint8_t> vM = {'[', '$', 'M', '#', '[', 'I', 0x00, 0x20, 'M', 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0xFF, ']'};
+
+                json _;
+                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&);
+            }
+        }
+    }
+}
diff --git a/tests/src/unit-bjdata.cpp b/tests/src/unit-bjdata.cpp
index a2ea7820fe..974ee3a0af 100644
--- a/tests/src/unit-bjdata.cpp
+++ b/tests/src/unit-bjdata.cpp
@@ -29,6 +29,8 @@ SOFTWARE.
 
 #include "doctest_compatibility.h"
 
+#include <climits>
+#include <limits>
 #include <nlohmann/json.hpp>
 using nlohmann::json;
 
@@ -116,6 +118,112 @@ class SaxCountdown
 };
 } // namespace
 
+// at some point in the future, a unit test dedicated to type traits might be a good idea
+template <typename OfType, typename T, bool MinInRange, bool MaxInRange>
+struct trait_test_arg
+{
+    using of_type = OfType;
+    using type = T;
+    static constexpr bool min_in_range = MinInRange;
+    static constexpr bool max_in_range = MaxInRange;
+};
+
+TEST_CASE_TEMPLATE_DEFINE("value_in_range_of trait", T, value_in_range_of_test)
+{
+    using nlohmann::detail::value_in_range_of;
+
+    using of_type = typename T::of_type;
+    using type = typename T::type;
+    constexpr bool min_in_range = T::min_in_range;
+    constexpr bool max_in_range = T::max_in_range;
+
+    type val_min = std::numeric_limits<type>::min();
+    type val_min2 = val_min + 1;
+    type val_max = std::numeric_limits<type>::max();
+    type val_max2 = val_max - 1;
+
+    REQUIRE(CHAR_BIT == 8);
+
+    std::string of_type_str;
+    if (std::is_unsigned<of_type>::value)
+    {
+        of_type_str += "u";
+    }
+    of_type_str += "int";
+    of_type_str += std::to_string(sizeof(of_type) * 8);
+
+    INFO("of_type := ", of_type_str);
+
+    std::string type_str;
+    if (std::is_unsigned<type>::value)
+    {
+        type_str += "u";
+    }
+    type_str += "int";
+    type_str += std::to_string(sizeof(type) * 8);
+
+    INFO("type := ", type_str);
+
+    CAPTURE(val_min);
+    CAPTURE(min_in_range);
+    CAPTURE(val_max);
+    CAPTURE(max_in_range);
+
+    if (min_in_range)
+    {
+        CHECK(value_in_range_of<of_type>(val_min));
+        CHECK(value_in_range_of<of_type>(val_min2));
+    }
+    else
+    {
+        CHECK_FALSE(value_in_range_of<of_type>(val_min));
+        CHECK_FALSE(value_in_range_of<of_type>(val_min2));
+    }
+
+    if (max_in_range)
+    {
+        CHECK(value_in_range_of<of_type>(val_max));
+        CHECK(value_in_range_of<of_type>(val_max2));
+    }
+    else
+    {
+        CHECK_FALSE(value_in_range_of<of_type>(val_max));
+        CHECK_FALSE(value_in_range_of<of_type>(val_max2));
+    }
+}
+
+TEST_CASE_TEMPLATE_INVOKE(value_in_range_of_test, \
+                          trait_test_arg<std::int32_t, std::int32_t, true, true>, \
+                          trait_test_arg<std::int32_t, std::uint32_t, true, false>, \
+                          trait_test_arg<std::uint32_t, std::int32_t, false, true>, \
+                          trait_test_arg<std::uint32_t, std::uint32_t, true, true>, \
+                          trait_test_arg<std::int32_t, std::int64_t, false, false>, \
+                          trait_test_arg<std::int32_t, std::uint64_t, true, false>, \
+                          trait_test_arg<std::uint32_t, std::int64_t, false, false>, \
+                          trait_test_arg<std::uint32_t, std::uint64_t, true, false>, \
+                          trait_test_arg<std::int64_t, std::int32_t, true, true>, \
+                          trait_test_arg<std::int64_t, std::uint32_t, true, true>, \
+                          trait_test_arg<std::uint64_t, std::int32_t, false, true>, \
+                          trait_test_arg<std::uint64_t, std::uint32_t, true, true>, \
+                          trait_test_arg<std::int64_t, std::int64_t, true, true>, \
+                          trait_test_arg<std::int64_t, std::uint64_t, true, false>, \
+                          trait_test_arg<std::uint64_t, std::int64_t, false, true>, \
+                          trait_test_arg<std::uint64_t, std::uint64_t, true, true>);
+
+#if SIZE_MAX == 0xffffffff
+TEST_CASE_TEMPLATE_INVOKE(value_in_range_of_test, \
+                          trait_test_arg<std::size_t, std::int32_t, false, true>, \
+                          trait_test_arg<std::size_t, std::uint32_t, true, true>, \
+                          trait_test_arg<std::size_t, std::int64_t, false, false>, \
+                          trait_test_arg<std::size_t, std::uint64_t, true, false>);
+#else
+TEST_CASE_TEMPLATE_INVOKE(value_in_range_of_test, \
+                          trait_test_arg<std::size_t, std::int32_t, false, true>, \
+                          trait_test_arg<std::size_t, std::uint32_t, true, true>, \
+                          trait_test_arg<std::size_t, std::int64_t, false, true>, \
+                          trait_test_arg<std::size_t, std::uint64_t, true, true>);
+#endif
+
 TEST_CASE("BJData")
 {
     SECTION("individual values")
@@ -2511,6 +2619,7 @@ TEST_CASE("BJData")
                 std::vector<uint8_t> vI = {'[', '#', 'I', 0x00, 0xF1};
                 std::vector<uint8_t> vl = {'[', '#', 'l', 0x00, 0x00, 0x00, 0xF2};
                 std::vector<uint8_t> vL = {'[', '#', 'L', 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF3};
+                std::vector<uint8_t> vM = {'[', '$', 'M', '#', '[', 'I', 0x00, 0x20, 'M', 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0xFF, ']'};
 
                 json _;
                 CHECK_THROWS_WITH_AS(_ = json::from_bjdata(v1), "[json.exception.parse_error.113] parse error at byte 4: syntax error while parsing BJData size: count in an optimized container must be positive", json::parse_error&);
@@ -2535,10 +2644,17 @@ TEST_CASE("BJData")
                 CHECK(json::from_bjdata(vI, true, false).is_discarded());
 
                 CHECK_THROWS_WITH_AS(_ = json::from_bjdata(vl), "[json.exception.parse_error.113] parse error at byte 7: syntax error while parsing BJData size: count in an optimized container must be positive", json::parse_error&);
-                CHECK(json::from_bjdata(vI, true, false).is_discarded());
+                CHECK(json::from_bjdata(vl, true, false).is_discarded());
 
                 CHECK_THROWS_WITH_AS(_ = json::from_bjdata(vL), "[json.exception.parse_error.113] parse error at byte 11: syntax error while parsing BJData size: count in an optimized container must be positive", json::parse_error&);
-                CHECK(json::from_bjdata(vI, true, false).is_discarded());
+                CHECK(json::from_bjdata(vL, true, false).is_discarded());
+
+#if SIZE_MAX == 0xffffffff
+                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&);
+#else
+                CHECK_THROWS_WITH_AS(_ = json::from_bjdata(vM), "[json.exception.out_of_range.408] syntax error while parsing BJData size: excessive ndarray size caused overflow", json::out_of_range&);
+#endif
+                CHECK(json::from_bjdata(vM, true, false).is_discarded());
             }
 
             SECTION("do not accept NTFZ markers in ndarray optimized type (with count)")

{"test-cbor_cpp11": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "test-regression1_cpp17": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "test-regression1_cpp11": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "test-comparison_legacy_cpp20": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "test-testsuites_cpp11": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "test-ubjson_cpp11": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "cmake_import_build": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "test-element_access1_cpp11": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "cmake_fetch_content2_configure": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "test-convenience_cpp11": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "cmake_fetch_content2_build": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "test-conversions_cpp17": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "test-disabled_exceptions_cpp11": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "test-byte_container_with_subtype_cpp11": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "test-large_json_cpp11": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "cmake_import_minver_build": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "test-class_parser_cpp11": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "cmake_add_subdirectory_configure": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "test-bson_cpp11": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "test-comparison_cpp20": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "test-comparison_legacy_cpp11": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "test-udt_cpp11": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "test-class_iterator_cpp11": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "test-binary_formats_cpp11": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "test-meta_cpp11": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "test-items_cpp17": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "test-iterators1_cpp11": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "test-user_defined_input_cpp11": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "cmake_fetch_content_configure": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "test-merge_patch_cpp11": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "test-json_pointer_cpp11": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "test-diagnostics_cpp11": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "test-regression2_cpp20": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "test-pointer_access_cpp11": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "test-iterators2_cpp20": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "test-unicode1_cpp11": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "test-comparison_cpp11": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "test-reference_access_cpp11": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "test-element_access2_cpp11": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "test-iterators2_cpp11": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "cmake_fetch_content_build": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "test-unicode3_cpp11": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "test-ordered_map_cpp11": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "test-element_access2_cpp17": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "download_test_data": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "test-json_patch_cpp11": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "test-alt-string_cpp11": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "test-modifiers_cpp11": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "test-noexcept_cpp11": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "test-conversions_cpp11": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "cmake_target_include_directories_configure": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "test-deserialization_cpp11": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "test-wstring_cpp11": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "test-constructor2_cpp11": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "cmake_import_minver_configure": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "test-msgpack_cpp11": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "test-items_cpp11": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "test-class_lexer_cpp11": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "test-to_chars_cpp11": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "test-class_const_iterator_cpp11": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "cmake_target_include_directories_build": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "test-inspection_cpp11": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "test-unicode5_cpp11": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "test-udt_macro_cpp11": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "test-readme_cpp11": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "test-unicode2_cpp11": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "test-ordered_json_cpp11": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "test-regression2_cpp17": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "test-capacity_cpp11": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "test-hash_cpp11": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "test-allocator_cpp11": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "test-constructor1_cpp11": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "test-bjdata_cpp11": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "test-algorithms_cpp11": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "test-unicode4_cpp11": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "test-regression2_cpp11": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "test-serialization_cpp11": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "cmake_import_configure": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "test-concepts_cpp11": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "test-assert_macro_cpp11": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "cmake_add_subdirectory_build": {"run": "PASS", "test": "NONE", "fix": "PASS"}}
{"test-cbor_cpp11": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "test-regression1_cpp17": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "test-regression1_cpp11": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "test-comparison_legacy_cpp20": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "test-testsuites_cpp11": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "test-ubjson_cpp11": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "cmake_import_build": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "test-element_access1_cpp11": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "cmake_fetch_content2_configure": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "test-convenience_cpp11": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "cmake_fetch_content2_build": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "test-conversions_cpp17": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "test-disabled_exceptions_cpp11": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "test-byte_container_with_subtype_cpp11": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "test-large_json_cpp11": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "cmake_import_minver_build": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "test-class_parser_cpp11": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "cmake_add_subdirectory_configure": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "test-bson_cpp11": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "test-comparison_cpp20": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "test-comparison_legacy_cpp11": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "test-udt_cpp11": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "test-class_iterator_cpp11": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "test-binary_formats_cpp11": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "test-meta_cpp11": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "test-items_cpp17": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "test-iterators1_cpp11": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "test-user_defined_input_cpp11": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "cmake_fetch_content_configure": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "test-merge_patch_cpp11": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "test-json_pointer_cpp11": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "test-diagnostics_cpp11": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "test-regression2_cpp20": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "test-pointer_access_cpp11": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "test-iterators2_cpp20": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "test-unicode1_cpp11": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "test-comparison_cpp11": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "test-reference_access_cpp11": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "test-element_access2_cpp11": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "test-iterators2_cpp11": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "cmake_fetch_content_build": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "test-unicode3_cpp11": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "test-ordered_map_cpp11": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "test-element_access2_cpp17": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "download_test_data": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "test-json_patch_cpp11": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "test-alt-string_cpp11": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "test-modifiers_cpp11": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "test-noexcept_cpp11": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "test-conversions_cpp11": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "cmake_target_include_directories_configure": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "test-deserialization_cpp11": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "test-wstring_cpp11": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "test-constructor2_cpp11": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "cmake_import_minver_configure": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "test-msgpack_cpp11": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "test-items_cpp11": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "test-class_lexer_cpp11": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "test-to_chars_cpp11": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "test-class_const_iterator_cpp11": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "cmake_target_include_directories_build": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "test-inspection_cpp11": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "test-unicode5_cpp11": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "test-udt_macro_cpp11": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "test-readme_cpp11": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "test-unicode2_cpp11": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "test-ordered_json_cpp11": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "test-regression2_cpp17": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "test-capacity_cpp11": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "test-hash_cpp11": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "test-allocator_cpp11": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "test-constructor1_cpp11": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "test-bjdata_cpp11": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "test-algorithms_cpp11": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "test-unicode4_cpp11": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "test-regression2_cpp11": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "test-serialization_cpp11": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "cmake_import_configure": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "test-concepts_cpp11": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "test-assert_macro_cpp11": {"run": "PASS", "test": "NONE", "fix": "PASS"}, "cmake_add_subdirectory_build": {"run": "PASS", "test": "NONE", "fix": "PASS"}}
{"passed_count": 81, "failed_count": 0, "skipped_count": 0, "passed_tests": ["test-comparison_legacy_cpp20", "test-testsuites_cpp11", "test-ubjson_cpp11", "cmake_fetch_content2_configure", "test-convenience_cpp11", "cmake_fetch_content2_build", "test-conversions_cpp17", "test-disabled_exceptions_cpp11", "cmake_import_minver_build", "test-class_parser_cpp11", "cmake_add_subdirectory_configure", "test-bson_cpp11", "test-comparison_cpp20", "test-comparison_legacy_cpp11", "test-udt_cpp11", "test-class_iterator_cpp11", "test-merge_patch_cpp11", "test-diagnostics_cpp11", "test-pointer_access_cpp11", "test-comparison_cpp11", "test-element_access2_cpp11", "cmake_fetch_content_build", "test-element_access2_cpp17", "download_test_data", "test-alt-string_cpp11", "test-wstring_cpp11", "test-constructor2_cpp11", "cmake_import_minver_configure", "test-msgpack_cpp11", "test-items_cpp11", "test-unicode5_cpp11", "test-udt_macro_cpp11", "test-unicode2_cpp11", "test-ordered_json_cpp11", "test-regression2_cpp17", "test-capacity_cpp11", "test-allocator_cpp11", "test-constructor1_cpp11", "test-bjdata_cpp11", "test-regression2_cpp11", "test-serialization_cpp11", "test-concepts_cpp11", "cmake_add_subdirectory_build", "test-cbor_cpp11", "test-regression1_cpp17", "test-regression1_cpp11", "cmake_import_build", "test-element_access1_cpp11", "test-byte_container_with_subtype_cpp11", "test-binary_formats_cpp11", "test-meta_cpp11", "test-items_cpp17", "test-iterators1_cpp11", "test-user_defined_input_cpp11", "cmake_fetch_content_configure", "test-json_pointer_cpp11", "test-regression2_cpp20", "test-iterators2_cpp20", "test-unicode1_cpp11", "test-reference_access_cpp11", "test-iterators2_cpp11", "test-unicode3_cpp11", "test-ordered_map_cpp11", "test-json_patch_cpp11", "test-modifiers_cpp11", "test-noexcept_cpp11", "test-conversions_cpp11", "cmake_target_include_directories_configure", "test-deserialization_cpp11", "test-class_lexer_cpp11", "test-to_chars_cpp11", "test-class_const_iterator_cpp11", "cmake_target_include_directories_build", "test-inspection_cpp11", "test-readme_cpp11", "test-hash_cpp11", "test-algorithms_cpp11", "test-unicode4_cpp11", "cmake_import_configure", "test-assert_macro_cpp11", "test-large_json_cpp11"], "failed_tests": [], "skipped_tests": []}
{"passed_count": 0, "failed_count": 0, "skipped_count": 0, "passed_tests": [], "failed_tests": [], "skipped_tests": []}
{"passed_count": 81, "failed_count": 0, "skipped_count": 0, "passed_tests": ["test-comparison_legacy_cpp20", "test-testsuites_cpp11", "test-ubjson_cpp11", "cmake_fetch_content2_configure", "test-convenience_cpp11", "cmake_fetch_content2_build", "test-conversions_cpp17", "test-disabled_exceptions_cpp11", "cmake_import_minver_build", "test-class_parser_cpp11", "cmake_add_subdirectory_configure", "test-bson_cpp11", "test-comparison_cpp20", "test-comparison_legacy_cpp11", "test-udt_cpp11", "test-class_iterator_cpp11", "test-merge_patch_cpp11", "test-diagnostics_cpp11", "test-pointer_access_cpp11", "test-comparison_cpp11", "test-element_access2_cpp11", "cmake_fetch_content_build", "test-element_access2_cpp17", "download_test_data", "test-alt-string_cpp11", "test-wstring_cpp11", "test-constructor2_cpp11", "cmake_import_minver_configure", "test-msgpack_cpp11", "test-items_cpp11", "test-unicode5_cpp11", "test-udt_macro_cpp11", "test-unicode2_cpp11", "test-ordered_json_cpp11", "test-regression2_cpp17", "test-capacity_cpp11", "test-allocator_cpp11", "test-constructor1_cpp11", "test-bjdata_cpp11", "test-regression2_cpp11", "test-serialization_cpp11", "test-concepts_cpp11", "cmake_add_subdirectory_build", "test-cbor_cpp11", "test-regression1_cpp17", "test-regression1_cpp11", "cmake_import_build", "test-element_access1_cpp11", "test-byte_container_with_subtype_cpp11", "test-binary_formats_cpp11", "test-meta_cpp11", "test-items_cpp17", "test-iterators1_cpp11", "test-user_defined_input_cpp11", "cmake_fetch_content_configure", "test-json_pointer_cpp11", "test-regression2_cpp20", "test-iterators2_cpp20", "test-unicode1_cpp11", "test-reference_access_cpp11", "test-iterators2_cpp11", "test-unicode3_cpp11", "test-ordered_map_cpp11", "test-json_patch_cpp11", "test-modifiers_cpp11", "test-noexcept_cpp11", "test-conversions_cpp11", "cmake_target_include_directories_configure", "test-deserialization_cpp11", "test-class_lexer_cpp11", "test-to_chars_cpp11", "test-class_const_iterator_cpp11", "cmake_target_include_directories_build", "test-inspection_cpp11", "test-readme_cpp11", "test-hash_cpp11", "test-algorithms_cpp11", "test-unicode4_cpp11", "cmake_import_configure", "test-assert_macro_cpp11", "test-large_json_cpp11"], "failed_tests": [], "skipped_tests": []}