diff --git a/include/nlohmann/detail/conversions/from_json.hpp b/include/nlohmann/detail/conversions/from_json.hpp index 5695fbed3..b85a4e3d6 100644 --- a/include/nlohmann/detail/conversions/from_json.hpp +++ b/include/nlohmann/detail/conversions/from_json.hpp @@ -189,10 +189,7 @@ auto from_json_array_impl(const BasicJsonType& j, std::array& arr, priority_tag<2> /*unused*/) -> decltype(j.template get(), void()) { - if (JSON_HEDLEY_UNLIKELY(!j.is_array())) - { - JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name()))); - } + // array type check done in from_json already, only check size if (JSON_HEDLEY_UNLIKELY(j.size() != N)) { JSON_THROW(type_error::create(302, "array size must be " + std::to_string(N) + ", but is " + std::to_string(j.size()))); diff --git a/single_include/nlohmann/json.hpp b/single_include/nlohmann/json.hpp index e374a3e6b..8db2a0eff 100644 --- a/single_include/nlohmann/json.hpp +++ b/single_include/nlohmann/json.hpp @@ -3589,10 +3589,7 @@ auto from_json_array_impl(const BasicJsonType& j, std::array& arr, priority_tag<2> /*unused*/) -> decltype(j.template get(), void()) { - if (JSON_HEDLEY_UNLIKELY(!j.is_array())) - { - JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name()))); - } + // array type check done in from_json already, only check size if (JSON_HEDLEY_UNLIKELY(j.size() != N)) { JSON_THROW(type_error::create(302, "array size must be " + std::to_string(N) + ", but is " + std::to_string(j.size()))); diff --git a/test/src/unit-constructor1.cpp b/test/src/unit-constructor1.cpp index 33bd92c3b..b916a313c 100644 --- a/test/src/unit-constructor1.cpp +++ b/test/src/unit-constructor1.cpp @@ -269,15 +269,6 @@ TEST_CASE("constructors") CHECK(j[1] == std::get<1>(p)); } - SECTION("std::pair with discarded values") - { - json j{1, 2.0, "string"}; - - const auto p = j.get>(); - CHECK(p.first == j[0]); - CHECK(p.second == j[1]); - } - SECTION("std::tuple") { const auto t = std::make_tuple(1.0, std::string{"string"}, 42, std::vector {0, 1}); @@ -293,26 +284,23 @@ TEST_CASE("constructors") CHECK(j[3][1] == 1); } - SECTION("std::tuple with discarded values") - { - json j{1, 2.0, "string", 42}; - - const auto t = j.get>(); - CHECK(std::get<0>(t) == j[0]); - CHECK(std::get<1>(t) == j[1]); - CHECK(std::get<2>(t) == j[2]); - } - SECTION("std::pair/tuple/array failures") { - json j{1}; + json j1{1}; + json j2{1, 2, 3}; - CHECK_THROWS_AS((j.get>()), json::out_of_range&); - CHECK_THROWS_WITH((j.get>()), "[json.exception.out_of_range.401] array index 1 is out of range"); - CHECK_THROWS_AS((j.get>()), json::out_of_range&); - CHECK_THROWS_WITH((j.get>()), "[json.exception.out_of_range.401] array index 1 is out of range"); - CHECK_THROWS_AS((j.get>()), json::out_of_range&); - CHECK_THROWS_WITH((j.get>()), "[json.exception.out_of_range.401] array index 1 is out of range"); + CHECK_THROWS_AS((j1.get>()), json::type_error&); + CHECK_THROWS_WITH((j1.get>()), "[json.exception.type_error.302] array size must be 2, but is 1"); + CHECK_THROWS_AS((j2.get>()), json::type_error&); + CHECK_THROWS_WITH((j2.get>()), "[json.exception.type_error.302] array size must be 2, but is 3"); + CHECK_THROWS_AS((j1.get>()), json::type_error&); + CHECK_THROWS_WITH((j1.get>()), "[json.exception.type_error.302] array size must be 2, but is 1"); + CHECK_THROWS_AS((j2.get>()), json::type_error&); + CHECK_THROWS_WITH((j2.get>()), "[json.exception.type_error.302] array size must be 2, but is 3"); + CHECK_THROWS_AS((j1.get>()), json::type_error&); + CHECK_THROWS_WITH((j1.get>()), "[json.exception.type_error.302] array size must be 3, but is 1"); + CHECK_THROWS_AS((j2.get>()), json::type_error&); + CHECK_THROWS_WITH((j2.get>()), "[json.exception.type_error.302] array size must be 1, but is 3"); } SECTION("std::forward_list") diff --git a/test/src/unit-conversions.cpp b/test/src/unit-conversions.cpp index eb20e832f..48b410fe7 100644 --- a/test/src/unit-conversions.cpp +++ b/test/src/unit-conversions.cpp @@ -400,6 +400,33 @@ TEST_CASE("value conversion") json j2 = nbs; j2.get_to(nbs2); CHECK(std::equal(std::begin(nbs), std::end(nbs), std::begin(nbs2))); + + SECTION("built-in array is larger than JSON") + { + json j1 = {1, 2, 3, 4}; + int arr6[] = {1, 2, 3, 4, 5, 6}; + CHECK_THROWS_AS(j1.get_to(arr6), json::type_error&); + CHECK_THROWS_WITH(j1.get_to(arr6), "[json.exception.type_error.302] " + "array size must be 6, but is 4"); + } + + SECTION("built-in array is smaller than JSON") + { + json j1 = {1, 2, 3, 4}; + int arr2[] = {8, 9}; + CHECK_THROWS_AS(j1.get_to(arr2), json::type_error&); + CHECK_THROWS_WITH(j1.get_to(arr2), "[json.exception.type_error.302] " + "array size must be 2, but is 4"); + } + + SECTION("built-in array from non-array type") + { + json j1; + int arr2[] = {8, 9}; + CHECK_THROWS_AS(j1.get_to(arr2), json::type_error&); + CHECK_THROWS_WITH(j1.get_to(arr2), "[json.exception.type_error.302] " + "type must be array, but is null"); + } } SECTION("std::deque") @@ -1615,8 +1642,10 @@ TEST_CASE("value conversion") { CHECK_THROWS_AS((json().get>()), json::type_error&); CHECK_THROWS_AS((json().get>()), json::type_error&); + CHECK_THROWS_AS((json().get>()), json::type_error&); CHECK_THROWS_AS((json().get>()), json::type_error&); CHECK_THROWS_AS((json().get>()), json::type_error&); + CHECK_THROWS_AS((json().get>()), json::type_error&); CHECK_THROWS_AS((json().get>()), json::type_error&); // does type really must be an array? or it rather must not be null? @@ -1627,12 +1656,18 @@ TEST_CASE("value conversion") CHECK_THROWS_WITH( (json().get>()), "[json.exception.type_error.302] type must be array, but is null"); + CHECK_THROWS_WITH( + (json().get>()), + "[json.exception.type_error.302] type must be array, but is null"); CHECK_THROWS_WITH( (json().get>()), "[json.exception.type_error.302] type must be array, but is null"); CHECK_THROWS_WITH( (json().get>()), "[json.exception.type_error.302] type must be array, but is null"); + CHECK_THROWS_WITH( + (json().get>()), + "[json.exception.type_error.302] type must be array, but is null"); CHECK_THROWS_WITH( (json().get>()), "[json.exception.type_error.302] type must be array, but is null");