diff --git a/include/nlohmann/detail/iterators/iter_impl.hpp b/include/nlohmann/detail/iterators/iter_impl.hpp index b7c1df24a..120c1b893 100644 --- a/include/nlohmann/detail/iterators/iter_impl.hpp +++ b/include/nlohmann/detail/iterators/iter_impl.hpp @@ -680,12 +680,12 @@ class iter_impl // NOLINT(cppcoreguidelines-special-member-functions,hicpp-speci { JSON_ASSERT(m_object != nullptr); - if (JSON_HEDLEY_LIKELY(m_object->is_object())) + if (JSON_HEDLEY_UNLIKELY(!m_object->is_object())) { - return m_it.object_iterator->first; + throw_literal(exception_id::iterator_key_not_object, "cannot use key() for non-object iterators", m_object); } - throw_literal(exception_id::iterator_key_not_object, "cannot use key() for non-object iterators", m_object); + return m_it.object_iterator->first; } /*! diff --git a/include/nlohmann/json.hpp b/include/nlohmann/json.hpp index bc6988a20..a05071e9d 100644 --- a/include/nlohmann/json.hpp +++ b/include/nlohmann/json.hpp @@ -4895,19 +4895,19 @@ public: iterator insert(const_iterator pos, const basic_json& val) // NOLINT(performance-unnecessary-value-param) { // insert only works for arrays - if (JSON_HEDLEY_LIKELY(is_array())) + if (JSON_HEDLEY_UNLIKELY(!is_array())) { - // check if iterator pos fits to this JSON value - if (JSON_HEDLEY_UNLIKELY(pos.m_object != this)) - { - detail::throw_literal(detail::exception_id::iterator_from_other_value, "iterator does not fit current value", this); - } - - // insert to array and return iterator - return insert_iterator(pos, val); + detail::throw_cannot_use_with(detail::exception_id::insert_wrong_type, "insert()", *this); } - detail::throw_cannot_use_with(detail::exception_id::insert_wrong_type, "insert()", *this); + // check if iterator pos fits to this JSON value + if (JSON_HEDLEY_UNLIKELY(pos.m_object != this)) + { + detail::throw_literal(detail::exception_id::iterator_from_other_value, "iterator does not fit current value", this); + } + + // insert to array and return iterator + return insert_iterator(pos, val); } /// @brief inserts element into array @@ -4915,21 +4915,21 @@ public: iterator insert(const_iterator pos, basic_json&& val) // NOLINT(performance-unnecessary-value-param) { // insert only works for arrays - if (JSON_HEDLEY_LIKELY(is_array())) + if (JSON_HEDLEY_UNLIKELY(!is_array())) { - // check if iterator pos fits to this JSON value - if (JSON_HEDLEY_UNLIKELY(pos.m_object != this)) - { - detail::throw_literal(detail::exception_id::iterator_from_other_value, "iterator does not fit current value", this); - } - - // moving into a local first keeps this safe even if val aliases - // an element of this array - basic_json tmp(std::move(val)); - return insert_iterator(pos, std::move(tmp)); + detail::throw_cannot_use_with(detail::exception_id::insert_wrong_type, "insert()", *this); } - detail::throw_cannot_use_with(detail::exception_id::insert_wrong_type, "insert()", *this); + // check if iterator pos fits to this JSON value + if (JSON_HEDLEY_UNLIKELY(pos.m_object != this)) + { + detail::throw_literal(detail::exception_id::iterator_from_other_value, "iterator does not fit current value", this); + } + + // moving into a local first keeps this safe even if val aliases + // an element of this array + basic_json tmp(std::move(val)); + return insert_iterator(pos, std::move(tmp)); } /// @brief inserts copies of element into array @@ -4937,19 +4937,19 @@ public: iterator insert(const_iterator pos, size_type cnt, const basic_json& val) // NOLINT(performance-unnecessary-value-param) { // insert only works for arrays - if (JSON_HEDLEY_LIKELY(is_array())) + if (JSON_HEDLEY_UNLIKELY(!is_array())) { - // check if iterator pos fits to this JSON value - if (JSON_HEDLEY_UNLIKELY(pos.m_object != this)) - { - detail::throw_literal(detail::exception_id::iterator_from_other_value, "iterator does not fit current value", this); - } - - // insert to array and return iterator - return insert_iterator(pos, cnt, val); + detail::throw_cannot_use_with(detail::exception_id::insert_wrong_type, "insert()", *this); } - detail::throw_cannot_use_with(detail::exception_id::insert_wrong_type, "insert()", *this); + // check if iterator pos fits to this JSON value + if (JSON_HEDLEY_UNLIKELY(pos.m_object != this)) + { + detail::throw_literal(detail::exception_id::iterator_from_other_value, "iterator does not fit current value", this); + } + + // insert to array and return iterator + return insert_iterator(pos, cnt, val); } /// @brief inserts range of elements into array diff --git a/include/nlohmann/ordered_map.hpp b/include/nlohmann/ordered_map.hpp index 10fc764ea..e5f9164f6 100644 --- a/include/nlohmann/ordered_map.hpp +++ b/include/nlohmann/ordered_map.hpp @@ -23,6 +23,7 @@ #include #include #include +#include NLOHMANN_JSON_NAMESPACE_BEGIN diff --git a/single_include/nlohmann/json.hpp b/single_include/nlohmann/json.hpp index 3dcebc881..cae524061 100644 --- a/single_include/nlohmann/json.hpp +++ b/single_include/nlohmann/json.hpp @@ -20745,12 +20745,12 @@ class iter_impl // NOLINT(cppcoreguidelines-special-member-functions,hicpp-speci { JSON_ASSERT(m_object != nullptr); - if (JSON_HEDLEY_LIKELY(m_object->is_object())) + if (JSON_HEDLEY_UNLIKELY(!m_object->is_object())) { - return m_it.object_iterator->first; + throw_literal(exception_id::iterator_key_not_object, "cannot use key() for non-object iterators", m_object); } - throw_literal(exception_id::iterator_key_not_object, "cannot use key() for non-object iterators", m_object); + return m_it.object_iterator->first; } /*! @@ -29734,6 +29734,8 @@ NLOHMANN_JSON_NAMESPACE_END // #include +// #include + NLOHMANN_JSON_NAMESPACE_BEGIN @@ -34958,19 +34960,19 @@ public: iterator insert(const_iterator pos, const basic_json& val) // NOLINT(performance-unnecessary-value-param) { // insert only works for arrays - if (JSON_HEDLEY_LIKELY(is_array())) + if (JSON_HEDLEY_UNLIKELY(!is_array())) { - // check if iterator pos fits to this JSON value - if (JSON_HEDLEY_UNLIKELY(pos.m_object != this)) - { - detail::throw_literal(detail::exception_id::iterator_from_other_value, "iterator does not fit current value", this); - } - - // insert to array and return iterator - return insert_iterator(pos, val); + detail::throw_cannot_use_with(detail::exception_id::insert_wrong_type, "insert()", *this); } - detail::throw_cannot_use_with(detail::exception_id::insert_wrong_type, "insert()", *this); + // check if iterator pos fits to this JSON value + if (JSON_HEDLEY_UNLIKELY(pos.m_object != this)) + { + detail::throw_literal(detail::exception_id::iterator_from_other_value, "iterator does not fit current value", this); + } + + // insert to array and return iterator + return insert_iterator(pos, val); } /// @brief inserts element into array @@ -34978,21 +34980,21 @@ public: iterator insert(const_iterator pos, basic_json&& val) // NOLINT(performance-unnecessary-value-param) { // insert only works for arrays - if (JSON_HEDLEY_LIKELY(is_array())) + if (JSON_HEDLEY_UNLIKELY(!is_array())) { - // check if iterator pos fits to this JSON value - if (JSON_HEDLEY_UNLIKELY(pos.m_object != this)) - { - detail::throw_literal(detail::exception_id::iterator_from_other_value, "iterator does not fit current value", this); - } - - // moving into a local first keeps this safe even if val aliases - // an element of this array - basic_json tmp(std::move(val)); - return insert_iterator(pos, std::move(tmp)); + detail::throw_cannot_use_with(detail::exception_id::insert_wrong_type, "insert()", *this); } - detail::throw_cannot_use_with(detail::exception_id::insert_wrong_type, "insert()", *this); + // check if iterator pos fits to this JSON value + if (JSON_HEDLEY_UNLIKELY(pos.m_object != this)) + { + detail::throw_literal(detail::exception_id::iterator_from_other_value, "iterator does not fit current value", this); + } + + // moving into a local first keeps this safe even if val aliases + // an element of this array + basic_json tmp(std::move(val)); + return insert_iterator(pos, std::move(tmp)); } /// @brief inserts copies of element into array @@ -35000,19 +35002,19 @@ public: iterator insert(const_iterator pos, size_type cnt, const basic_json& val) // NOLINT(performance-unnecessary-value-param) { // insert only works for arrays - if (JSON_HEDLEY_LIKELY(is_array())) + if (JSON_HEDLEY_UNLIKELY(!is_array())) { - // check if iterator pos fits to this JSON value - if (JSON_HEDLEY_UNLIKELY(pos.m_object != this)) - { - detail::throw_literal(detail::exception_id::iterator_from_other_value, "iterator does not fit current value", this); - } - - // insert to array and return iterator - return insert_iterator(pos, cnt, val); + detail::throw_cannot_use_with(detail::exception_id::insert_wrong_type, "insert()", *this); } - detail::throw_cannot_use_with(detail::exception_id::insert_wrong_type, "insert()", *this); + // check if iterator pos fits to this JSON value + if (JSON_HEDLEY_UNLIKELY(pos.m_object != this)) + { + detail::throw_literal(detail::exception_id::iterator_from_other_value, "iterator does not fit current value", this); + } + + // insert to array and return iterator + return insert_iterator(pos, cnt, val); } /// @brief inserts range of elements into array diff --git a/tests/src/unit-constructor2.cpp b/tests/src/unit-constructor2.cpp index 5f5a5df9a..9b2fb3df6 100644 --- a/tests/src/unit-constructor2.cpp +++ b/tests/src/unit-constructor2.cpp @@ -305,7 +305,7 @@ TEST_CASE("copy constructor and destructor across value types") // mutating the copy leaves the original alone copy[5] = "changed"; copy[6].push_back(1); - CHECK(copy != v); + CHECK((copy != v)); CHECK(v[5] == std::string(5, 'x')); CHECK(v[6].size() == 3); diff --git a/tests/src/unit-serialization.cpp b/tests/src/unit-serialization.cpp index 3315d5852..2ad4f2eda 100644 --- a/tests/src/unit-serialization.cpp +++ b/tests/src/unit-serialization.cpp @@ -1374,7 +1374,13 @@ void check_dump_against_reference(const std::string& s, const bool with_strict = }; for (const auto error_handler : error_handlers) { +#if defined(JSON_NOEXCEPTION) + // a strict dump of invalid UTF-8 calls std::abort() instead of throwing + static_cast(with_strict); + if (error_handler == json::error_handler_t::strict) +#else if (!with_strict && error_handler == json::error_handler_t::strict) +#endif { continue; } diff --git a/tests/src/unit-throw_messages.cpp b/tests/src/unit-throw_messages.cpp index 5babe2901..f9f8a5445 100644 --- a/tests/src/unit-throw_messages.cpp +++ b/tests/src/unit-throw_messages.cpp @@ -94,6 +94,7 @@ TEST_CASE("exception messages of out-of-line throw sites") CHECK_MSG(obj.update(arr.begin(), arr2.end()), "[json.exception.invalid_iterator.210] iterators do not fit"); } +#if !defined(JSON_NOEXCEPTION) // patch_msg() catches the exceptions, which JSON_NOEXCEPTION turns into std::abort() SECTION("patch") { const auto patch_msg = [](const char* doc, const char* patch) @@ -138,4 +139,5 @@ TEST_CASE("exception messages of out-of-line throw sites") CHECK(patch_msg("{\"a\":1}", "[{\"op\":\"test\",\"path\":\"/a\",\"value\":2}]") == "[json.exception.other_error.501] unsuccessful: {\"op\":\"test\",\"path\":\"/a\",\"value\":2}"); CHECK(patch_msg("{\"a\":1}", "[{\"op\":\"move\",\"path\":\"/a\"}]") == "[json.exception.parse_error.105] parse error: operation 'move' must have member 'from'"); } +#endif }