From 01d611882884c8cd94b576342b1f7733f397c5b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Th=C3=A9o=20DELRIEU?= Date: Mon, 12 Feb 2018 10:47:17 +0100 Subject: [PATCH] Fix constraints on from_json(CompatibleArrayType) Fixes #924 --- .../nlohmann/detail/conversions/from_json.hpp | 16 +++++++++----- single_include/nlohmann/json.hpp | 16 +++++++++----- test/src/unit-inspection.cpp | 4 ++-- test/src/unit-udt.cpp | 22 +++++++++++++++++++ 4 files changed, 46 insertions(+), 12 deletions(-) diff --git a/include/nlohmann/detail/conversions/from_json.hpp b/include/nlohmann/detail/conversions/from_json.hpp index 8ea0284a..eccc04f1 100644 --- a/include/nlohmann/detail/conversions/from_json.hpp +++ b/include/nlohmann/detail/conversions/from_json.hpp @@ -177,15 +177,21 @@ void from_json_array_impl(const BasicJsonType& j, std::array& arr, priorit } } -template::value and - std::is_convertible::value and - not std::is_same::value, int> = 0> +template < + typename BasicJsonType, typename CompatibleArrayType, + enable_if_t < + is_compatible_array_type::value and + not std::is_same::value and + std::is_constructible < + BasicJsonType, typename CompatibleArrayType::value_type >::value, + int > = 0 > void from_json(const BasicJsonType& j, CompatibleArrayType& arr) { if (JSON_UNLIKELY(not j.is_array())) { - JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name()))); + JSON_THROW(type_error::create(302, "type must be array, but is " + + std::string(j.type_name()))); } from_json_array_impl(j, arr, priority_tag<2> {}); diff --git a/single_include/nlohmann/json.hpp b/single_include/nlohmann/json.hpp index a7c009c0..c7530586 100644 --- a/single_include/nlohmann/json.hpp +++ b/single_include/nlohmann/json.hpp @@ -1084,15 +1084,21 @@ void from_json_array_impl(const BasicJsonType& j, std::array& arr, priorit } } -template::value and - std::is_convertible::value and - not std::is_same::value, int> = 0> +template < + typename BasicJsonType, typename CompatibleArrayType, + enable_if_t < + is_compatible_array_type::value and + not std::is_same::value and + std::is_constructible < + BasicJsonType, typename CompatibleArrayType::value_type >::value, + int > = 0 > void from_json(const BasicJsonType& j, CompatibleArrayType& arr) { if (JSON_UNLIKELY(not j.is_array())) { - JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name()))); + JSON_THROW(type_error::create(302, "type must be array, but is " + + std::string(j.type_name()))); } from_json_array_impl(j, arr, priority_tag<2> {}); diff --git a/test/src/unit-inspection.cpp b/test/src/unit-inspection.cpp index 5facb116..4bee80d1 100644 --- a/test/src/unit-inspection.cpp +++ b/test/src/unit-inspection.cpp @@ -316,8 +316,8 @@ TEST_CASE("object inspection") SECTION("round trips") { for (const auto& s : - {"3.141592653589793", "1000000000000000010E5" - }) + {"3.141592653589793", "1000000000000000010E5" + }) { json j1 = json::parse(s); std::string s1 = j1.dump(); diff --git a/test/src/unit-udt.cpp b/test/src/unit-udt.cpp index 17baf4e5..65ca788a 100644 --- a/test/src/unit-udt.cpp +++ b/test/src/unit-udt.cpp @@ -711,3 +711,25 @@ TEST_CASE("an incomplete type does not trigger a compiler error in non-evaluated { static_assert(not is_constructible_patched::value, ""); } + +namespace +{ +class Evil +{ + public: + Evil() = default; + template + Evil(T) {} +}; + +void from_json(const json&, Evil&) {} +} + +TEST_CASE("Issue #924") +{ + // Prevent get>() to throw + auto j = json::array(); + + (void) j.get(); + (void) j.get>(); +}