2
0
mirror of https://github.com/boostorg/json.git synced 2026-02-11 11:52:17 +00:00

limits tests

This commit is contained in:
Vinnie Falco
2019-11-11 20:40:31 -08:00
parent 68f3df0403
commit 9da2877b28
24 changed files with 403 additions and 337 deletions

View File

@@ -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

View File

@@ -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
] ;
}

View File

@@ -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
View 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

View File

@@ -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);
{

View File

@@ -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();
}
}
//------------------------------------------------------

View File

@@ -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();
}
};

View File

@@ -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();
}
};

View File

@@ -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