mirror of
https://github.com/boostorg/json.git
synced 2026-02-10 23:42:19 +00:00
limits tests
This commit is contained in:
@@ -1688,8 +1688,7 @@ private:
|
||||
value* src,
|
||||
std::size_t n) noexcept;
|
||||
|
||||
class undo_create;
|
||||
class undo_assign;
|
||||
class undo_construct;
|
||||
class undo_insert;
|
||||
|
||||
storage_ptr sp_; // must come first
|
||||
|
||||
@@ -83,6 +83,10 @@
|
||||
# define BOOST_JSON_NO_MAX_STRING_SIZE
|
||||
# define BOOST_JSON_MAX_STRING_SIZE 0x7ffffffe
|
||||
#endif
|
||||
#ifndef BOOST_JSON_MAX_STACK_SIZE
|
||||
# define BOOST_JSON_NO_MAX_STACK_SIZE
|
||||
# define BOOST_JSON_MAX_STACK_SIZE ((std::size_t)(-1))
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
namespace json {
|
||||
|
||||
@@ -16,6 +16,22 @@ namespace boost {
|
||||
namespace json {
|
||||
namespace detail {
|
||||
|
||||
inline
|
||||
std::length_error
|
||||
object_too_large_exception() noexcept
|
||||
{
|
||||
return std::length_error(
|
||||
"object too large");
|
||||
}
|
||||
|
||||
inline
|
||||
std::length_error
|
||||
array_too_large_exception() noexcept
|
||||
{
|
||||
return std::length_error(
|
||||
"array too large");
|
||||
}
|
||||
|
||||
inline
|
||||
std::length_error
|
||||
string_too_large_exception() noexcept
|
||||
@@ -24,6 +40,14 @@ string_too_large_exception() noexcept
|
||||
"string too large");
|
||||
}
|
||||
|
||||
inline
|
||||
std::out_of_range
|
||||
string_pos_too_large() noexcept
|
||||
{
|
||||
return std::out_of_range(
|
||||
"pos > size()");
|
||||
}
|
||||
|
||||
inline
|
||||
std::length_error
|
||||
key_too_large_exception() noexcept
|
||||
@@ -32,14 +56,6 @@ key_too_large_exception() noexcept
|
||||
"key too large");
|
||||
}
|
||||
|
||||
inline
|
||||
std::length_error
|
||||
object_too_large_exception() noexcept
|
||||
{
|
||||
return std::length_error(
|
||||
"object too large");
|
||||
}
|
||||
|
||||
inline
|
||||
std::length_error
|
||||
stack_overflow_exception() noexcept
|
||||
|
||||
@@ -113,7 +113,7 @@ private:
|
||||
std::size_t
|
||||
max_size() noexcept
|
||||
{
|
||||
return std::size_t(-1);
|
||||
return BOOST_JSON_MAX_STACK_SIZE;
|
||||
}
|
||||
|
||||
BOOST_JSON_DECL
|
||||
|
||||
@@ -22,7 +22,7 @@ void
|
||||
raw_stack::
|
||||
grow(std::size_t n)
|
||||
{
|
||||
if(n > max_size() - size_)
|
||||
if(n > max_size() - capacity_)
|
||||
BOOST_JSON_THROW(
|
||||
stack_overflow_exception());
|
||||
auto new_capacity = capacity_ + n;
|
||||
@@ -37,7 +37,7 @@ grow(std::size_t n)
|
||||
if(base_)
|
||||
{
|
||||
std::memcpy(base, base_, size_);
|
||||
sp_->deallocate(base_, size_);
|
||||
sp_->deallocate(base_, capacity_);
|
||||
}
|
||||
base_ = base;
|
||||
capacity_ = new_capacity;
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#define BOOST_JSON_IMPL_ARRAY_HPP
|
||||
|
||||
#include <boost/json/value.hpp>
|
||||
#include <boost/json/detail/except.hpp>
|
||||
#include <algorithm>
|
||||
#include <stdexcept>
|
||||
#include <type_traits>
|
||||
@@ -54,7 +55,7 @@ index_of(value const* pos) const noexcept ->
|
||||
|
||||
//----------------------------------------------------------
|
||||
|
||||
class array::undo_create
|
||||
class array::undo_construct
|
||||
{
|
||||
array& self_;
|
||||
|
||||
@@ -62,10 +63,10 @@ public:
|
||||
bool commit = false;
|
||||
|
||||
BOOST_JSON_DECL
|
||||
~undo_create();
|
||||
~undo_construct();
|
||||
|
||||
explicit
|
||||
undo_create(
|
||||
undo_construct(
|
||||
array& self) noexcept
|
||||
: self_(self)
|
||||
{
|
||||
@@ -74,24 +75,6 @@ public:
|
||||
|
||||
//----------------------------------------------------------
|
||||
|
||||
class array::undo_assign
|
||||
{
|
||||
array& self_;
|
||||
impl_type impl_;
|
||||
|
||||
public:
|
||||
bool commit = false;
|
||||
|
||||
explicit
|
||||
BOOST_JSON_DECL
|
||||
undo_assign(array& self);
|
||||
|
||||
BOOST_JSON_DECL
|
||||
~undo_assign();
|
||||
};
|
||||
|
||||
//----------------------------------------------------------
|
||||
|
||||
class array::undo_insert
|
||||
{
|
||||
array& self_;
|
||||
@@ -404,7 +387,7 @@ array(
|
||||
std::input_iterator_tag)
|
||||
: sp_(std::move(sp))
|
||||
{
|
||||
undo_create u(*this);
|
||||
undo_construct u(*this);
|
||||
while(first != last)
|
||||
{
|
||||
if(impl_.size >= impl_.capacity)
|
||||
@@ -424,14 +407,13 @@ array(
|
||||
std::forward_iterator_tag)
|
||||
: sp_(std::move(sp))
|
||||
{
|
||||
undo_create u(*this);
|
||||
undo_construct u(*this);
|
||||
auto const n =
|
||||
static_cast<std::size_t>(
|
||||
std::distance(first, last));
|
||||
if(n > max_size())
|
||||
BOOST_JSON_THROW(
|
||||
std::length_error(
|
||||
"n > max_size"));
|
||||
detail::array_too_large_exception());
|
||||
reserve(static_cast<std::size_t>(n));
|
||||
while(impl_.size < n)
|
||||
{
|
||||
@@ -481,8 +463,7 @@ insert(
|
||||
std::distance(first, last));
|
||||
if(n > max_size())
|
||||
BOOST_JSON_THROW(
|
||||
std::length_error(
|
||||
"n > max_size"));
|
||||
detail::array_too_large_exception());
|
||||
undo_insert u(pos, static_cast<
|
||||
std::size_t>(n), *this);
|
||||
while(first != last)
|
||||
|
||||
@@ -33,7 +33,7 @@ impl_type(
|
||||
{
|
||||
if(capacity_ > max_size())
|
||||
BOOST_JSON_THROW(
|
||||
detail::object_too_large_exception());
|
||||
detail::array_too_large_exception());
|
||||
if(capacity_ > 0)
|
||||
vec = reinterpret_cast<value*>(
|
||||
sp->allocate(
|
||||
@@ -102,8 +102,8 @@ destroy(
|
||||
//----------------------------------------------------------
|
||||
|
||||
array::
|
||||
undo_create::
|
||||
~undo_create()
|
||||
undo_construct::
|
||||
~undo_construct()
|
||||
{
|
||||
if(! commit)
|
||||
self_.impl_.destroy(self_.sp_);
|
||||
@@ -111,25 +111,6 @@ undo_create::
|
||||
|
||||
//----------------------------------------------------------
|
||||
|
||||
array::
|
||||
undo_assign::
|
||||
undo_assign(array& self)
|
||||
: self_(self)
|
||||
, impl_(std::move(self.impl_))
|
||||
{
|
||||
}
|
||||
|
||||
array::
|
||||
undo_assign::
|
||||
~undo_assign()
|
||||
{
|
||||
if(! commit)
|
||||
impl_.swap(self_.impl_);
|
||||
impl_.destroy(self_.sp_);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------
|
||||
|
||||
array::
|
||||
undo_insert::
|
||||
undo_insert(
|
||||
@@ -142,8 +123,7 @@ undo_insert(
|
||||
{
|
||||
if(n > max_size())
|
||||
BOOST_JSON_THROW(
|
||||
std::length_error(
|
||||
"size > max_size()"));
|
||||
detail::array_too_large_exception());
|
||||
self_.reserve(
|
||||
self_.impl_.size + n_);
|
||||
// (iterators invalidated now)
|
||||
@@ -192,7 +172,7 @@ array(
|
||||
storage_ptr sp)
|
||||
: sp_(std::move(sp))
|
||||
{
|
||||
undo_create u(*this);
|
||||
undo_construct u(*this);
|
||||
reserve(count);
|
||||
while(impl_.size < count)
|
||||
{
|
||||
@@ -210,7 +190,7 @@ array(
|
||||
storage_ptr sp)
|
||||
: sp_(std::move(sp))
|
||||
{
|
||||
undo_create u(*this);
|
||||
undo_construct u(*this);
|
||||
reserve(count);
|
||||
while(impl_.size < count)
|
||||
{
|
||||
@@ -226,7 +206,7 @@ array::
|
||||
array(array const& other)
|
||||
: sp_(other.sp_)
|
||||
{
|
||||
undo_create u(*this);
|
||||
undo_construct u(*this);
|
||||
copy(other);
|
||||
u.commit = true;
|
||||
}
|
||||
@@ -237,7 +217,7 @@ array(
|
||||
storage_ptr sp)
|
||||
: sp_(std::move(sp))
|
||||
{
|
||||
undo_create u(*this);
|
||||
undo_construct u(*this);
|
||||
copy(other);
|
||||
u.commit = true;
|
||||
}
|
||||
@@ -269,7 +249,7 @@ array(
|
||||
}
|
||||
else
|
||||
{
|
||||
undo_create u(*this);
|
||||
undo_construct u(*this);
|
||||
copy(other);
|
||||
u.commit = true;
|
||||
}
|
||||
@@ -281,7 +261,7 @@ array(
|
||||
storage_ptr sp)
|
||||
: sp_(std::move(sp))
|
||||
{
|
||||
undo_create u(*this);
|
||||
undo_construct u(*this);
|
||||
copy(init);
|
||||
u.commit = true;
|
||||
}
|
||||
|
||||
@@ -115,22 +115,19 @@ bucket_begin() const noexcept ->
|
||||
begin() + capacity());
|
||||
}
|
||||
|
||||
auto
|
||||
object::
|
||||
impl_type::
|
||||
bucket_end() const noexcept ->
|
||||
value_type**
|
||||
{
|
||||
return bucket_begin() + buckets();
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------
|
||||
|
||||
struct object::undo_construct
|
||||
{
|
||||
object* self;
|
||||
|
||||
explicit
|
||||
undo_construct(
|
||||
object* self_)
|
||||
: self(self_)
|
||||
{
|
||||
}
|
||||
|
||||
~undo_construct()
|
||||
{
|
||||
if(self)
|
||||
@@ -170,7 +167,7 @@ object(
|
||||
storage_ptr sp)
|
||||
: sp_(std::move(sp))
|
||||
{
|
||||
undo_construct u{this};
|
||||
undo_construct u(this);
|
||||
insert_range(
|
||||
first, last,
|
||||
min_capacity);
|
||||
|
||||
@@ -110,14 +110,13 @@ build() noexcept
|
||||
--end;
|
||||
if(p != end)
|
||||
{
|
||||
auto& head = bucket(end->key());
|
||||
remove(head, end);
|
||||
end->next_ = head;
|
||||
head = p;
|
||||
std::memcpy(
|
||||
reinterpret_cast<void*>(p),
|
||||
reinterpret_cast<void const*>(end),
|
||||
sizeof(*p));
|
||||
auto& head = bucket(p->key());
|
||||
p->next_ = head;
|
||||
head = p;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -234,7 +233,7 @@ object(
|
||||
}
|
||||
else
|
||||
{
|
||||
undo_construct u{this};
|
||||
undo_construct u(this);
|
||||
insert_range(
|
||||
other.begin(),
|
||||
other.end(), 0);
|
||||
@@ -254,7 +253,7 @@ object(
|
||||
object const& other)
|
||||
: sp_(other.sp_)
|
||||
{
|
||||
undo_construct u{this};
|
||||
undo_construct u(this);
|
||||
insert_range(
|
||||
other.begin(),
|
||||
other.end(), 0);
|
||||
@@ -267,7 +266,7 @@ object(
|
||||
storage_ptr sp)
|
||||
: sp_(std::move(sp))
|
||||
{
|
||||
undo_construct u{this};
|
||||
undo_construct u(this);
|
||||
insert_range(
|
||||
other.begin(),
|
||||
other.end(), 0);
|
||||
@@ -281,7 +280,7 @@ object(
|
||||
storage_ptr sp)
|
||||
: sp_(std::move(sp))
|
||||
{
|
||||
undo_construct u{this};
|
||||
undo_construct u(this);
|
||||
insert_range(
|
||||
init.begin(),
|
||||
init.end(),
|
||||
|
||||
@@ -248,21 +248,16 @@ emplace(Args&&... args)
|
||||
~U(){}
|
||||
};
|
||||
U u;
|
||||
// perform stack reallocation up-front
|
||||
// VFALCO This is more than we need
|
||||
rs_.prepare(sizeof(u.v));
|
||||
std::size_t key_size;
|
||||
pop(key_size);
|
||||
// remember the offset in case
|
||||
// the stack is reallocated.
|
||||
auto const offset =
|
||||
rs_.pop(key_size) -
|
||||
rs_.begin();
|
||||
auto const key =
|
||||
pop_chars(key_size);
|
||||
st_ = state::obj;
|
||||
// prevent splits from exceptions
|
||||
rs_.prepare(2 * sizeof(u.v));
|
||||
::new(&u.v) object::value_type(
|
||||
string_view(
|
||||
rs_.begin() + offset,
|
||||
key_size),
|
||||
std::forward<Args>(args)...);
|
||||
key, std::forward<Args>(args)...);
|
||||
rs_.subtract(sizeof(u.v));
|
||||
push(u.v);
|
||||
rs_.add(sizeof(u.v));
|
||||
|
||||
@@ -158,7 +158,7 @@ loop_init:
|
||||
case kind::uint64:
|
||||
if(p1 - p >= detail::max_number_chars)
|
||||
{
|
||||
p += detail::format_int64(
|
||||
p += detail::format_uint64(
|
||||
p, *jv.if_uint64());
|
||||
stack_.pop();
|
||||
goto loop;
|
||||
@@ -370,7 +370,6 @@ loop_str:
|
||||
std::memcpy(p, ss, n);
|
||||
ss = s;
|
||||
p += n;
|
||||
//*p++ = ch;
|
||||
*p++ = '\\';
|
||||
*p++ = c;
|
||||
if(c != 'u')
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#define BOOST_JSON_IMPL_STRING_IPP
|
||||
|
||||
#include <boost/json/detail/assert.hpp>
|
||||
#include <boost/json/detail/except.hpp>
|
||||
#include <algorithm>
|
||||
#include <new>
|
||||
#include <ostream>
|
||||
@@ -54,8 +55,7 @@ growth(
|
||||
{
|
||||
if(new_size > max_size())
|
||||
BOOST_JSON_THROW(
|
||||
std::length_error(
|
||||
"size > max_size()"));
|
||||
detail::string_too_large_exception());
|
||||
new_size |= mask_;
|
||||
if( new_size > max_size())
|
||||
return static_cast<
|
||||
@@ -109,8 +109,7 @@ append(
|
||||
{
|
||||
if(n > max_size() - size)
|
||||
BOOST_JSON_THROW(
|
||||
std::length_error(
|
||||
"size > max_size()"));
|
||||
detail::string_too_large_exception());
|
||||
if(n <= capacity - size)
|
||||
{
|
||||
term(size + n);
|
||||
@@ -136,8 +135,7 @@ insert(
|
||||
{
|
||||
if(pos > size)
|
||||
BOOST_JSON_THROW(
|
||||
std::out_of_range(
|
||||
"pos > size()"));
|
||||
detail::string_pos_too_large());
|
||||
if(n <= capacity - size)
|
||||
{
|
||||
auto const dest =
|
||||
@@ -152,8 +150,7 @@ insert(
|
||||
}
|
||||
if(n > max_size() - size)
|
||||
BOOST_JSON_THROW(
|
||||
std::length_error(
|
||||
"size > max_size()"));
|
||||
detail::string_too_large_exception());
|
||||
impl tmp(growth(
|
||||
size + n, capacity), sp);
|
||||
tmp.size = size + static_cast<
|
||||
@@ -352,10 +349,9 @@ insert(
|
||||
char const* s,
|
||||
size_type count)
|
||||
{
|
||||
if(pos >= impl_.size)
|
||||
if(pos > impl_.size)
|
||||
BOOST_JSON_THROW(
|
||||
std::out_of_range(
|
||||
"pos >= size()"));
|
||||
detail::string_pos_too_large());
|
||||
if(count > impl_.capacity - impl_.size)
|
||||
{
|
||||
traits_type::copy(
|
||||
@@ -412,8 +408,7 @@ erase(
|
||||
{
|
||||
if(pos > impl_.size)
|
||||
BOOST_JSON_THROW(
|
||||
std::out_of_range(
|
||||
"pos > size()"));
|
||||
detail::string_pos_too_large());
|
||||
if( count > impl_.size - pos)
|
||||
count = impl_.size - pos;
|
||||
traits_type::move(
|
||||
|
||||
@@ -184,7 +184,7 @@ value_type(
|
||||
{
|
||||
if(key.size() > BOOST_JSON_MAX_STRING_SIZE)
|
||||
BOOST_JSON_THROW(
|
||||
detail::string_too_large_exception());
|
||||
detail::key_too_large_exception());
|
||||
auto s = reinterpret_cast<
|
||||
char*>(value_.get_storage()->
|
||||
allocate(key.size() + 1));
|
||||
|
||||
@@ -219,10 +219,6 @@ private:
|
||||
inline
|
||||
value_type**
|
||||
bucket_begin() const noexcept;
|
||||
|
||||
inline
|
||||
value_type**
|
||||
bucket_end() const noexcept;
|
||||
};
|
||||
|
||||
struct undo_construct;
|
||||
|
||||
Reference in New Issue
Block a user