mirror of
https://github.com/boostorg/json.git
synced 2026-02-11 11:52:17 +00:00
limits tests
This commit is contained in:
@@ -13,12 +13,6 @@ source_group (TREE ${PROJECT_SOURCE_DIR}/include/boost/json PREFIX json FILES ${
|
||||
|
||||
GroupSources(test "/")
|
||||
|
||||
#add_definitions(
|
||||
# -DBOOST_JSON_MAX_STRING_SIZE=1000
|
||||
# -DBOOST_JSON_MAX_OBJECT_SIZE=30
|
||||
# -DBOOST_JSON_MAX_ARRAY_SIZE=100
|
||||
# )
|
||||
|
||||
add_executable (json-tests
|
||||
${BEAST_FILES}
|
||||
${PROJECT_FILES}
|
||||
@@ -38,6 +32,7 @@ add_executable (json-tests
|
||||
error.cpp
|
||||
json.cpp
|
||||
kind.cpp
|
||||
limits.cpp
|
||||
number.cpp
|
||||
object.cpp
|
||||
parser.cpp
|
||||
|
||||
12
test/Jamfile
12
test/Jamfile
@@ -11,6 +11,7 @@ import testing ;
|
||||
import ../../config/checks/config : requires ;
|
||||
|
||||
local SOURCES =
|
||||
array.cpp
|
||||
assign_string.cpp
|
||||
assign_vector.cpp
|
||||
basic_parser.cpp
|
||||
@@ -19,20 +20,20 @@ local SOURCES =
|
||||
json.cpp
|
||||
kind.cpp
|
||||
number.cpp
|
||||
object.cpp
|
||||
parser.cpp
|
||||
serializer.cpp
|
||||
storage.cpp
|
||||
storage_ptr.cpp
|
||||
string.cpp
|
||||
value.cpp
|
||||
ryu/d2s_intrinsics_test.cpp
|
||||
ryu/d2s_table_test.cpp
|
||||
ryu/d2s_test.cpp
|
||||
;
|
||||
|
||||
local MOD_SOURCES =
|
||||
array.cpp
|
||||
object.cpp
|
||||
string.cpp
|
||||
local LIMIT_SOURCES =
|
||||
limits.cpp
|
||||
;
|
||||
|
||||
local RUN_TESTS ;
|
||||
@@ -45,13 +46,14 @@ for local f in $(SOURCES)
|
||||
] ;
|
||||
}
|
||||
|
||||
for local f in $(MOD_SOURCES)
|
||||
for local f in $(LIMIT_SOURCES)
|
||||
{
|
||||
RUN_TESTS += [
|
||||
run $(f) main.cpp ../src/src.cpp : : :
|
||||
<define>BOOST_JSON_MAX_STRING_SIZE=1000
|
||||
<define>BOOST_JSON_MAX_OBJECT_SIZE=30
|
||||
<define>BOOST_JSON_MAX_ARRAY_SIZE=100
|
||||
<define>BOOST_JSON_MAX_STACK_SIZE=1024
|
||||
] ;
|
||||
}
|
||||
|
||||
|
||||
@@ -280,6 +280,15 @@ public:
|
||||
check_storage(a1, storage_ptr{});
|
||||
check_storage(a2, sp);
|
||||
});
|
||||
|
||||
// self-assign
|
||||
{
|
||||
array a({1, true, str_});
|
||||
auto& a1 = a;
|
||||
auto& a2 = a;
|
||||
a1 = a2;
|
||||
check(a);
|
||||
}
|
||||
}
|
||||
|
||||
// operator=(array&&)
|
||||
|
||||
196
test/limits.cpp
Normal file
196
test/limits.cpp
Normal file
@@ -0,0 +1,196 @@
|
||||
//
|
||||
// Copyright (c) 2018-2019 Vinnie Falco (vinnie dot falco at gmail dot com)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// Official repository: https://github.com/vinniefalco/json
|
||||
//
|
||||
|
||||
#include <boost/json/array.hpp>
|
||||
#include <boost/json/object.hpp>
|
||||
#include <boost/json/string.hpp>
|
||||
#include <boost/json/value.hpp>
|
||||
#include <boost/json/parser.hpp>
|
||||
|
||||
#include <boost/beast/_experimental/unit_test/suite.hpp>
|
||||
#include "test.hpp"
|
||||
#include <vector>
|
||||
|
||||
namespace boost {
|
||||
namespace json {
|
||||
|
||||
/*
|
||||
This translation unit exercises code paths
|
||||
related to library limits such as max string
|
||||
length.
|
||||
*/
|
||||
|
||||
class limits_test : public beast::unit_test::suite
|
||||
{
|
||||
public:
|
||||
void
|
||||
testObject()
|
||||
{
|
||||
// max size
|
||||
{
|
||||
BEAST_THROWS(
|
||||
object(object::max_size()+1),
|
||||
std::length_error);
|
||||
}
|
||||
|
||||
// max size
|
||||
{
|
||||
std::initializer_list<std::pair<
|
||||
string_view, value>> init = {
|
||||
{ "1", 1},{ "2", 2},{ "3", 3},{ "4", 4},{ "5", 5},
|
||||
{ "6", 6},{ "7", 7},{ "8", 8},{ "9", 9},{"10",10},
|
||||
{"11",11},{"12",12},{"13",13},{"14",14},{"15",15},
|
||||
{"16",16},{"17",17},{"18",18},{"19",19},{"10",10},
|
||||
{"21",21},{"22",22},{"23",23},{"24",24},{"25",25},
|
||||
{"26",26},{"27",27},{"28",28},{"29",29},{"30",30},
|
||||
{"31",31}};
|
||||
BEAST_EXPECT(init.size() > object::max_size());
|
||||
BEAST_THROWS(
|
||||
object(init.begin(), init.end()),
|
||||
std::length_error);
|
||||
BEAST_THROWS(
|
||||
object(
|
||||
make_input_iterator(init.begin()),
|
||||
make_input_iterator(init.end())),
|
||||
std::length_error);
|
||||
}
|
||||
|
||||
// max key size
|
||||
{
|
||||
std::string const big(
|
||||
string::max_size() + 1, '*');
|
||||
BEAST_THROWS(
|
||||
object({ {big, nullptr} }),
|
||||
std::length_error);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
testArray()
|
||||
{
|
||||
// max size
|
||||
{
|
||||
BEAST_THROWS(
|
||||
array(
|
||||
array::max_size()+1,
|
||||
value(nullptr)),
|
||||
std::length_error);
|
||||
}
|
||||
|
||||
// max size
|
||||
{
|
||||
std::vector<int> v(
|
||||
array::max_size()+1, 42);
|
||||
BEAST_THROWS(
|
||||
array(v.begin(), v.end()),
|
||||
std::length_error);
|
||||
}
|
||||
|
||||
// max size
|
||||
{
|
||||
array a;
|
||||
BEAST_THROWS(
|
||||
a.insert(a.begin(),
|
||||
array::max_size() + 1,
|
||||
nullptr),
|
||||
std::length_error);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
testString()
|
||||
{
|
||||
// exceed max size
|
||||
{
|
||||
{
|
||||
string s;
|
||||
BEAST_THROWS(
|
||||
(s.resize(s.max_size() + 1)),
|
||||
std::length_error);
|
||||
}
|
||||
|
||||
{
|
||||
string s;
|
||||
s.resize(100);
|
||||
BEAST_THROWS(
|
||||
(s.append(s.max_size() - 1, '*')),
|
||||
std::length_error);
|
||||
}
|
||||
|
||||
#if 0
|
||||
{
|
||||
// VFALCO tsan doesn't like this
|
||||
string s;
|
||||
try
|
||||
{
|
||||
s.resize(s.max_size() - 1);
|
||||
}
|
||||
catch(std::exception const&)
|
||||
{
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
testParser()
|
||||
{
|
||||
// max raw_stack
|
||||
{
|
||||
std::string big;
|
||||
BEAST_THROWS(
|
||||
parse(
|
||||
"[1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,"
|
||||
"1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,"
|
||||
"1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,"
|
||||
"1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,"
|
||||
"1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,"
|
||||
"1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,"
|
||||
"1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,"
|
||||
"1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,"
|
||||
"1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,"
|
||||
"1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,"
|
||||
"1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,"
|
||||
"1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,"
|
||||
"1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,"
|
||||
"1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,"
|
||||
"1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,"
|
||||
"1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0]"),
|
||||
std::length_error);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
run() override
|
||||
{
|
||||
#ifndef BOOST_JSON_NO_MAX_OBJECT_SIZE
|
||||
testObject();
|
||||
#endif
|
||||
|
||||
#ifndef BOOST_JSON_NO_MAX_ARRAY_SIZE
|
||||
testArray();
|
||||
#endif
|
||||
|
||||
#ifndef BOOST_JSON_NO_MAX_STRING_SIZE
|
||||
testString();
|
||||
#endif
|
||||
|
||||
#ifndef BOOST_JSON_NO_MAX_STACK_SIZE
|
||||
testParser();
|
||||
#endif
|
||||
|
||||
pass();
|
||||
}
|
||||
};
|
||||
|
||||
BEAST_DEFINE_TESTSUITE(boost,json,limits);
|
||||
|
||||
} // json
|
||||
} // boost
|
||||
@@ -160,14 +160,6 @@ public:
|
||||
BEAST_EXPECT(o.size() == 0);
|
||||
BEAST_EXPECT(o.capacity() >= 10);
|
||||
});
|
||||
|
||||
#ifndef BOOST_JSON_NO_MAX_ARRAY_SIZE
|
||||
{
|
||||
BEAST_THROWS(
|
||||
object(object::max_size()+1),
|
||||
std::length_error);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// object(InputIt, InputIt, size_type, storage_ptr)
|
||||
@@ -224,28 +216,6 @@ public:
|
||||
check(o, 7);
|
||||
check_storage(o, sp);
|
||||
});
|
||||
#ifndef BOOST_JSON_NO_MAX_ARRAY_SIZE
|
||||
{
|
||||
std::initializer_list<std::pair<
|
||||
string_view, value>> init = {
|
||||
{ "1", 1},{ "2", 2},{ "3", 3},{ "4", 4},{ "5", 5},
|
||||
{ "6", 6},{ "7", 7},{ "8", 8},{ "9", 9},{"10",10},
|
||||
{"11",11},{"12",12},{"13",13},{"14",14},{"15",15},
|
||||
{"16",16},{"17",17},{"18",18},{"19",19},{"10",10},
|
||||
{"21",21},{"22",22},{"23",23},{"24",24},{"25",25},
|
||||
{"26",26},{"27",27},{"28",28},{"29",29},{"30",30},
|
||||
{"31",31}};
|
||||
BEAST_EXPECT(init.size() > object::max_size());
|
||||
BEAST_THROWS(
|
||||
object(init.begin(), init.end()),
|
||||
std::length_error);
|
||||
BEAST_THROWS(
|
||||
object(
|
||||
make_input_iterator(init.begin()),
|
||||
make_input_iterator(init.end())),
|
||||
std::length_error);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// object(object&&)
|
||||
@@ -705,15 +675,28 @@ public:
|
||||
}
|
||||
|
||||
// insert(initializer_list)
|
||||
fail_loop([&](storage_ptr const& sp)
|
||||
{
|
||||
object o(sp);
|
||||
o.emplace("a", 1);
|
||||
o.insert({
|
||||
{ "b", true },
|
||||
{ "c", "hello" }});
|
||||
check(o, 3);
|
||||
});
|
||||
fail_loop([&](storage_ptr const& sp)
|
||||
{
|
||||
object o(sp);
|
||||
o.emplace("a", 1);
|
||||
o.insert({
|
||||
{ "b", true },
|
||||
{ "c", "hello" }});
|
||||
check(o, 3);
|
||||
});
|
||||
|
||||
// do rollback in ~undo_insert
|
||||
fail_loop([&](storage_ptr const& sp)
|
||||
{
|
||||
std::string const big(
|
||||
string().capacity() + 1, '*');
|
||||
string_view const sv(big);
|
||||
object o(sp);
|
||||
o.insert({
|
||||
{ "a", { 1, 2, 3, 4 } } });
|
||||
});
|
||||
}
|
||||
|
||||
// insert_or_assign(key, o);
|
||||
{
|
||||
|
||||
@@ -87,6 +87,7 @@ public:
|
||||
{
|
||||
scoped_storage<
|
||||
fail_storage> ss;
|
||||
ss->fail_max = 0;
|
||||
parser p;
|
||||
error_code ec;
|
||||
p.start(ss);
|
||||
@@ -284,6 +285,12 @@ R"xx({
|
||||
ec == error::need_start,
|
||||
ec.message());
|
||||
}
|
||||
|
||||
// destroy after start
|
||||
{
|
||||
parser p;
|
||||
p.start();
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------
|
||||
|
||||
@@ -13,8 +13,8 @@
|
||||
#include <boost/json/parser.hpp>
|
||||
#include <boost/beast/_experimental/unit_test/suite.hpp>
|
||||
#include "parse-vectors.hpp"
|
||||
|
||||
#include "test.hpp"
|
||||
#include <iostream>
|
||||
|
||||
namespace boost {
|
||||
namespace json {
|
||||
@@ -56,21 +56,37 @@ public:
|
||||
value const& jv,
|
||||
string_view name = {})
|
||||
{
|
||||
error_code ec;
|
||||
auto const s1 = to_string(jv);
|
||||
auto const jv2 = parse(s1, ec);
|
||||
if(! BEAST_EXPECT(equal(jv, jv2)))
|
||||
{
|
||||
if(name.empty())
|
||||
log <<
|
||||
" " << s << "\n"
|
||||
" " << s1 <<
|
||||
std::endl;
|
||||
else
|
||||
log << name << ":\n"
|
||||
" " << s << "\n"
|
||||
" " << s1 <<
|
||||
std::endl;
|
||||
error_code ec;
|
||||
auto const s1 = to_string(jv);
|
||||
auto const jv2 = parse(s1, ec);
|
||||
if(! BEAST_EXPECT(equal(jv, jv2)))
|
||||
{
|
||||
if(name.empty())
|
||||
log <<
|
||||
" " << s << "\n"
|
||||
" " << s1 <<
|
||||
std::endl;
|
||||
else
|
||||
log << name << ":\n"
|
||||
" " << s << "\n"
|
||||
" " << s1 <<
|
||||
std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
// large buffer
|
||||
{
|
||||
error_code ec;
|
||||
serializer sr(jv);
|
||||
string js;
|
||||
js.reserve(4096);
|
||||
js.grow(sr.read(
|
||||
js.data(), js.size()));
|
||||
|
||||
auto const s1 = to_string(jv);
|
||||
auto const jv2 = parse(s1, ec);
|
||||
BEAST_EXPECT(equal(jv, jv2));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -391,6 +407,33 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
testOstream()
|
||||
{
|
||||
std::string js =
|
||||
"{\"1\":{},\"2\":[],\"3\":\"x\",\"4\":1,"
|
||||
"\"5\":-1,\"6\":144.0,\"7\":false,\"8\":null}";
|
||||
error_code ec;
|
||||
auto const jv1 = parse(js, ec);
|
||||
if(! BEAST_EXPECTS(! ec,
|
||||
ec.message()))
|
||||
return;
|
||||
std::stringstream ss;
|
||||
ss << jv1;
|
||||
auto const jv2 =
|
||||
parse(ss.str(), ec);
|
||||
if(! BEAST_EXPECTS(! ec,
|
||||
ec.message()))
|
||||
return;
|
||||
if(! BEAST_EXPECT(equal(jv1, jv2)))
|
||||
log <<
|
||||
" " << js << "\n"
|
||||
" " << jv1 << "\n"
|
||||
" " << jv2 <<
|
||||
std::endl;
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
run()
|
||||
{
|
||||
@@ -401,6 +444,7 @@ public:
|
||||
testNumber();
|
||||
testScalar();
|
||||
testVectors();
|
||||
//testOstream();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -2632,44 +2632,6 @@ public:
|
||||
BEAST_EXPECT(ss.str() == s);
|
||||
}
|
||||
|
||||
void
|
||||
testImpl()
|
||||
{
|
||||
// exceed max size
|
||||
#ifndef BOOST_JSON_NO_MAX_STRING_SIZE
|
||||
{
|
||||
{
|
||||
string s;
|
||||
BEAST_THROWS(
|
||||
(s.resize(s.max_size() + 1)),
|
||||
std::length_error);
|
||||
}
|
||||
|
||||
{
|
||||
string s;
|
||||
s.resize(100);
|
||||
BEAST_THROWS(
|
||||
(s.append(s.max_size() - 1, '*')),
|
||||
std::length_error);
|
||||
}
|
||||
|
||||
#if 0
|
||||
{
|
||||
// VFALCO tsan doesn't like this
|
||||
string s;
|
||||
try
|
||||
{
|
||||
s.resize(s.max_size() - 1);
|
||||
}
|
||||
catch(std::exception const&)
|
||||
{
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
run() override
|
||||
{
|
||||
@@ -2702,8 +2664,6 @@ public:
|
||||
testFindNotLastOf(); //
|
||||
|
||||
testNonMembers();
|
||||
|
||||
testImpl();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -54,8 +54,7 @@ struct fail_storage
|
||||
return true;
|
||||
}
|
||||
|
||||
std::size_t fail_max =
|
||||
std::size_t(-1);
|
||||
std::size_t fail_max = 0;
|
||||
std::size_t fail = 0;
|
||||
std::size_t nalloc = 0;
|
||||
|
||||
@@ -97,6 +96,7 @@ void
|
||||
fail_loop(F&& f)
|
||||
{
|
||||
scoped_storage<fail_storage> ss;
|
||||
ss->fail_max = 1;
|
||||
while(ss->fail < 200)
|
||||
{
|
||||
try
|
||||
|
||||
Reference in New Issue
Block a user