mirror of
https://github.com/nlohmann/json.git
synced 2026-09-30 03:30:31 +00:00
Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
af394fca9c |
@@ -167,13 +167,9 @@ template<typename BasicJsonType, typename EnumType,
|
||||
enable_if_t<std::is_enum<EnumType>::value, int> = 0>
|
||||
inline void from_json(const BasicJsonType& j, EnumType& e)
|
||||
{
|
||||
using underlying_type = typename std::underlying_type<EnumType>::type;
|
||||
// get_arithmetic_value() does not accept boolean_t; read the number that to_json() wrote instead
|
||||
using value_type = typename std::conditional<std::is_same<underlying_type, typename BasicJsonType::boolean_t>::value,
|
||||
typename BasicJsonType::number_unsigned_t, underlying_type>::type;
|
||||
value_type val;
|
||||
typename std::underlying_type<EnumType>::type val;
|
||||
get_arithmetic_value(j, val);
|
||||
e = static_cast<EnumType>(static_cast<underlying_type>(val));
|
||||
e = static_cast<EnumType>(val);
|
||||
}
|
||||
#endif // JSON_DISABLE_ENUM_SERIALIZATION
|
||||
|
||||
|
||||
@@ -19,11 +19,17 @@ namespace detail
|
||||
/*!
|
||||
@brief the number of nesting levels an operation recurses into
|
||||
|
||||
Operations that walk a value (serializing, hashing, merging, ...) recurse once
|
||||
Operations that walk a value (copying, comparing, serializing, hashing, merging,
|
||||
...) recurse once
|
||||
per nesting level, which is fastest, but a value nested deeply enough would
|
||||
exhaust the call stack. So they recurse only this many levels deep and finish
|
||||
whatever lies below with an explicit stack. All of them share this limit.
|
||||
|
||||
Most of them pass the depth down as an argument. The copy constructor and the
|
||||
comparison operators cannot, as their signatures are fixed, so they count it
|
||||
in basic_json::nesting_depth() instead, a byte per thread; the limit must
|
||||
therefore stay below 255.
|
||||
|
||||
@sa https://github.com/nlohmann/json/issues/5387
|
||||
*/
|
||||
constexpr std::size_t recursion_depth_limit() noexcept
|
||||
|
||||
@@ -898,12 +898,8 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
}
|
||||
|
||||
#ifndef JSON_NO_THREAD_LOCAL
|
||||
/// the number of levels an operation descends into before it finishes the
|
||||
/// value below it without the call stack
|
||||
static constexpr std::uint8_t nesting_depth_limit()
|
||||
{
|
||||
return 128;
|
||||
}
|
||||
// nesting_depth() is a byte and may exceed the limit by one level
|
||||
static_assert(detail::recursion_depth_limit() < 255, "the nesting depth count must fit in a byte");
|
||||
|
||||
/*!
|
||||
@brief how many levels the operation going on in this thread has descended into
|
||||
@@ -945,7 +941,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
static_cast<void>(may_descend);
|
||||
return true;
|
||||
#else
|
||||
return !may_descend || nesting_depth() >= nesting_depth_limit();
|
||||
return !may_descend || nesting_depth() >= detail::recursion_depth_limit();
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -969,7 +965,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
#ifdef JSON_NO_THREAD_LOCAL
|
||||
: m_okay(false)
|
||||
#else
|
||||
: m_okay(nesting_depth() < nesting_depth_limit())
|
||||
: m_okay(nesting_depth() < detail::recursion_depth_limit())
|
||||
#endif
|
||||
{
|
||||
#ifndef JSON_NO_THREAD_LOCAL
|
||||
@@ -1173,7 +1169,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
|
||||
The values whose copy has not been created yet are kept on an explicit
|
||||
worklist rather than on the call stack. This is only reached for values
|
||||
nested deeper than @ref nesting_depth_limit levels, which is why it copies
|
||||
nested deeper than @ref detail::recursion_depth_limit levels, which is why it copies
|
||||
every container by hand instead of letting the container do it: the fast
|
||||
ways of doing so would descend into the elements and defeat the purpose.
|
||||
*/
|
||||
@@ -1239,7 +1235,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
|
||||
Copying a container copies its elements, so a value nested deeply enough
|
||||
used to exhaust the call stack. The descent is bounded here: the first
|
||||
@ref nesting_depth_limit levels are copied by the containers themselves, just
|
||||
@ref detail::recursion_depth_limit levels are copied by the containers themselves, just
|
||||
as they always were, and anything below that is copied without the call
|
||||
stack by @ref copy_iteratively. Copying a value can therefore no longer
|
||||
exhaust the stack, however deeply it is nested, just like destroying one
|
||||
@@ -1377,7 +1373,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
/*!
|
||||
@brief compare @a lhs and @a rhs without descending into them
|
||||
|
||||
Reached once a comparison has descended @ref nesting_depth_limit levels, so
|
||||
Reached once a comparison has descended @ref detail::recursion_depth_limit levels, so
|
||||
that comparing values cannot exhaust the call stack however deeply they are
|
||||
nested. The two values are walked in lockstep on an explicit stack and
|
||||
compared lexicographically, element by element in the order the containers
|
||||
|
||||
@@ -5664,13 +5664,9 @@ template<typename BasicJsonType, typename EnumType,
|
||||
enable_if_t<std::is_enum<EnumType>::value, int> = 0>
|
||||
inline void from_json(const BasicJsonType& j, EnumType& e)
|
||||
{
|
||||
using underlying_type = typename std::underlying_type<EnumType>::type;
|
||||
// get_arithmetic_value() does not accept boolean_t; read the number that to_json() wrote instead
|
||||
using value_type = typename std::conditional<std::is_same<underlying_type, typename BasicJsonType::boolean_t>::value,
|
||||
typename BasicJsonType::number_unsigned_t, underlying_type>::type;
|
||||
value_type val;
|
||||
typename std::underlying_type<EnumType>::type val;
|
||||
get_arithmetic_value(j, val);
|
||||
e = static_cast<EnumType>(static_cast<underlying_type>(val));
|
||||
e = static_cast<EnumType>(val);
|
||||
}
|
||||
#endif // JSON_DISABLE_ENUM_SERIALIZATION
|
||||
|
||||
@@ -7285,11 +7281,17 @@ namespace detail
|
||||
/*!
|
||||
@brief the number of nesting levels an operation recurses into
|
||||
|
||||
Operations that walk a value (serializing, hashing, merging, ...) recurse once
|
||||
Operations that walk a value (copying, comparing, serializing, hashing, merging,
|
||||
...) recurse once
|
||||
per nesting level, which is fastest, but a value nested deeply enough would
|
||||
exhaust the call stack. So they recurse only this many levels deep and finish
|
||||
whatever lies below with an explicit stack. All of them share this limit.
|
||||
|
||||
Most of them pass the depth down as an argument. The copy constructor and the
|
||||
comparison operators cannot, as their signatures are fixed, so they count it
|
||||
in basic_json::nesting_depth() instead, a byte per thread; the limit must
|
||||
therefore stay below 255.
|
||||
|
||||
@sa https://github.com/nlohmann/json/issues/5387
|
||||
*/
|
||||
constexpr std::size_t recursion_depth_limit() noexcept
|
||||
@@ -26983,12 +26985,8 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
}
|
||||
|
||||
#ifndef JSON_NO_THREAD_LOCAL
|
||||
/// the number of levels an operation descends into before it finishes the
|
||||
/// value below it without the call stack
|
||||
static constexpr std::uint8_t nesting_depth_limit()
|
||||
{
|
||||
return 128;
|
||||
}
|
||||
// nesting_depth() is a byte and may exceed the limit by one level
|
||||
static_assert(detail::recursion_depth_limit() < 255, "the nesting depth count must fit in a byte");
|
||||
|
||||
/*!
|
||||
@brief how many levels the operation going on in this thread has descended into
|
||||
@@ -27030,7 +27028,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
static_cast<void>(may_descend);
|
||||
return true;
|
||||
#else
|
||||
return !may_descend || nesting_depth() >= nesting_depth_limit();
|
||||
return !may_descend || nesting_depth() >= detail::recursion_depth_limit();
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -27054,7 +27052,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
#ifdef JSON_NO_THREAD_LOCAL
|
||||
: m_okay(false)
|
||||
#else
|
||||
: m_okay(nesting_depth() < nesting_depth_limit())
|
||||
: m_okay(nesting_depth() < detail::recursion_depth_limit())
|
||||
#endif
|
||||
{
|
||||
#ifndef JSON_NO_THREAD_LOCAL
|
||||
@@ -27258,7 +27256,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
|
||||
The values whose copy has not been created yet are kept on an explicit
|
||||
worklist rather than on the call stack. This is only reached for values
|
||||
nested deeper than @ref nesting_depth_limit levels, which is why it copies
|
||||
nested deeper than @ref detail::recursion_depth_limit levels, which is why it copies
|
||||
every container by hand instead of letting the container do it: the fast
|
||||
ways of doing so would descend into the elements and defeat the purpose.
|
||||
*/
|
||||
@@ -27324,7 +27322,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
|
||||
Copying a container copies its elements, so a value nested deeply enough
|
||||
used to exhaust the call stack. The descent is bounded here: the first
|
||||
@ref nesting_depth_limit levels are copied by the containers themselves, just
|
||||
@ref detail::recursion_depth_limit levels are copied by the containers themselves, just
|
||||
as they always were, and anything below that is copied without the call
|
||||
stack by @ref copy_iteratively. Copying a value can therefore no longer
|
||||
exhaust the stack, however deeply it is nested, just like destroying one
|
||||
@@ -27462,7 +27460,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
||||
/*!
|
||||
@brief compare @a lhs and @a rhs without descending into them
|
||||
|
||||
Reached once a comparison has descended @ref nesting_depth_limit levels, so
|
||||
Reached once a comparison has descended @ref detail::recursion_depth_limit levels, so
|
||||
that comparing values cannot exhaust the call stack however deeply they are
|
||||
nested. The two values are walked in lockstep on an explicit stack and
|
||||
compared lexicographically, element by element in the order the containers
|
||||
|
||||
@@ -1358,14 +1358,6 @@ TEST_CASE("value conversion")
|
||||
CHECK(json(value_1).get<c_enum>() == value_1);
|
||||
CHECK(json(cpp_enum::value_1).get<cpp_enum>() == cpp_enum::value_1);
|
||||
}
|
||||
|
||||
SECTION("get an enum with underlying type bool (#5671)")
|
||||
{
|
||||
enum class bool_enum : bool { off, on };
|
||||
|
||||
CHECK(json(bool_enum::off).get<bool_enum>() == bool_enum::off);
|
||||
CHECK(json(bool_enum::on).get<bool_enum>() == bool_enum::on);
|
||||
}
|
||||
#endif
|
||||
|
||||
SECTION("more involved conversions")
|
||||
|
||||
Reference in New Issue
Block a user