mirror of
https://github.com/nlohmann/json.git
synced 2026-09-30 11:40:30 +00:00
Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
af394fca9c |
@@ -19,11 +19,17 @@ namespace detail
|
|||||||
/*!
|
/*!
|
||||||
@brief the number of nesting levels an operation recurses into
|
@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
|
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
|
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.
|
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
|
@sa https://github.com/nlohmann/json/issues/5387
|
||||||
*/
|
*/
|
||||||
constexpr std::size_t recursion_depth_limit() noexcept
|
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
|
#ifndef JSON_NO_THREAD_LOCAL
|
||||||
/// the number of levels an operation descends into before it finishes the
|
// nesting_depth() is a byte and may exceed the limit by one level
|
||||||
/// value below it without the call stack
|
static_assert(detail::recursion_depth_limit() < 255, "the nesting depth count must fit in a byte");
|
||||||
static constexpr std::uint8_t nesting_depth_limit()
|
|
||||||
{
|
|
||||||
return 128;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@brief how many levels the operation going on in this thread has descended into
|
@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);
|
static_cast<void>(may_descend);
|
||||||
return true;
|
return true;
|
||||||
#else
|
#else
|
||||||
return !may_descend || nesting_depth() >= nesting_depth_limit();
|
return !may_descend || nesting_depth() >= detail::recursion_depth_limit();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -969,7 +965,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
|||||||
#ifdef JSON_NO_THREAD_LOCAL
|
#ifdef JSON_NO_THREAD_LOCAL
|
||||||
: m_okay(false)
|
: m_okay(false)
|
||||||
#else
|
#else
|
||||||
: m_okay(nesting_depth() < nesting_depth_limit())
|
: m_okay(nesting_depth() < detail::recursion_depth_limit())
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
#ifndef JSON_NO_THREAD_LOCAL
|
#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
|
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
|
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
|
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.
|
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
|
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
|
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
|
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
|
stack by @ref copy_iteratively. Copying a value can therefore no longer
|
||||||
exhaust the stack, however deeply it is nested, just like destroying one
|
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
|
@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
|
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
|
nested. The two values are walked in lockstep on an explicit stack and
|
||||||
compared lexicographically, element by element in the order the containers
|
compared lexicographically, element by element in the order the containers
|
||||||
|
|||||||
@@ -7281,11 +7281,17 @@ namespace detail
|
|||||||
/*!
|
/*!
|
||||||
@brief the number of nesting levels an operation recurses into
|
@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
|
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
|
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.
|
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
|
@sa https://github.com/nlohmann/json/issues/5387
|
||||||
*/
|
*/
|
||||||
constexpr std::size_t recursion_depth_limit() noexcept
|
constexpr std::size_t recursion_depth_limit() noexcept
|
||||||
@@ -26979,12 +26985,8 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifndef JSON_NO_THREAD_LOCAL
|
#ifndef JSON_NO_THREAD_LOCAL
|
||||||
/// the number of levels an operation descends into before it finishes the
|
// nesting_depth() is a byte and may exceed the limit by one level
|
||||||
/// value below it without the call stack
|
static_assert(detail::recursion_depth_limit() < 255, "the nesting depth count must fit in a byte");
|
||||||
static constexpr std::uint8_t nesting_depth_limit()
|
|
||||||
{
|
|
||||||
return 128;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@brief how many levels the operation going on in this thread has descended into
|
@brief how many levels the operation going on in this thread has descended into
|
||||||
@@ -27026,7 +27028,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
|||||||
static_cast<void>(may_descend);
|
static_cast<void>(may_descend);
|
||||||
return true;
|
return true;
|
||||||
#else
|
#else
|
||||||
return !may_descend || nesting_depth() >= nesting_depth_limit();
|
return !may_descend || nesting_depth() >= detail::recursion_depth_limit();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -27050,7 +27052,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
|||||||
#ifdef JSON_NO_THREAD_LOCAL
|
#ifdef JSON_NO_THREAD_LOCAL
|
||||||
: m_okay(false)
|
: m_okay(false)
|
||||||
#else
|
#else
|
||||||
: m_okay(nesting_depth() < nesting_depth_limit())
|
: m_okay(nesting_depth() < detail::recursion_depth_limit())
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
#ifndef JSON_NO_THREAD_LOCAL
|
#ifndef JSON_NO_THREAD_LOCAL
|
||||||
@@ -27254,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
|
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
|
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
|
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.
|
ways of doing so would descend into the elements and defeat the purpose.
|
||||||
*/
|
*/
|
||||||
@@ -27320,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
|
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
|
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
|
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
|
stack by @ref copy_iteratively. Copying a value can therefore no longer
|
||||||
exhaust the stack, however deeply it is nested, just like destroying one
|
exhaust the stack, however deeply it is nested, just like destroying one
|
||||||
@@ -27458,7 +27460,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
|
|||||||
/*!
|
/*!
|
||||||
@brief compare @a lhs and @a rhs without descending into them
|
@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
|
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
|
nested. The two values are walked in lockstep on an explicit stack and
|
||||||
compared lexicographically, element by element in the order the containers
|
compared lexicographically, element by element in the order the containers
|
||||||
|
|||||||
Reference in New Issue
Block a user