You can now pass a boolean "allow_exceptions" to the parse functions. If it is false, no exceptions are thrown in case of a parse error. Instead, parsing is stopped at the first error and a JSON value of type "discarded" (check with is_discarded()) is returned.
This commit is contained in:
parent
669ebf51bc
commit
7d51214045
3 changed files with 170 additions and 23 deletions
93
src/json.hpp
93
src/json.hpp
|
@ -3071,8 +3071,11 @@ class parser
|
||||||
|
|
||||||
/// a parser reading from an input adapter
|
/// a parser reading from an input adapter
|
||||||
explicit parser(detail::input_adapter_t adapter,
|
explicit parser(detail::input_adapter_t adapter,
|
||||||
const parser_callback_t cb = nullptr)
|
const parser_callback_t cb = nullptr,
|
||||||
: callback(cb), m_lexer(adapter) {}
|
const bool allow_exceptions_ = true)
|
||||||
|
: callback(cb), m_lexer(adapter),
|
||||||
|
allow_exceptions(allow_exceptions_)
|
||||||
|
{}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@brief public parser interface
|
@brief public parser interface
|
||||||
|
@ -3092,12 +3095,20 @@ class parser
|
||||||
parse_internal(true, result);
|
parse_internal(true, result);
|
||||||
result.assert_invariant();
|
result.assert_invariant();
|
||||||
|
|
||||||
|
// in strict mode, input must be completely read
|
||||||
if (strict)
|
if (strict)
|
||||||
{
|
{
|
||||||
get_token();
|
get_token();
|
||||||
expect(token_type::end_of_input);
|
expect(token_type::end_of_input);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// in case of an error, return discarded value
|
||||||
|
if (errored)
|
||||||
|
{
|
||||||
|
result = value_t::discarded;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// set top-level value to null if it was discarded by the callback
|
// set top-level value to null if it was discarded by the callback
|
||||||
// function
|
// function
|
||||||
if (result.is_discarded())
|
if (result.is_discarded())
|
||||||
|
@ -3176,7 +3187,10 @@ class parser
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
// store key
|
// store key
|
||||||
expect(token_type::value_string);
|
if (not expect(token_type::value_string))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
const auto key = m_lexer.get_string();
|
const auto key = m_lexer.get_string();
|
||||||
|
|
||||||
bool keep_tag = false;
|
bool keep_tag = false;
|
||||||
|
@ -3195,7 +3209,10 @@ class parser
|
||||||
|
|
||||||
// parse separator (:)
|
// parse separator (:)
|
||||||
get_token();
|
get_token();
|
||||||
expect(token_type::name_separator);
|
if (not expect(token_type::name_separator))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// parse and add value
|
// parse and add value
|
||||||
get_token();
|
get_token();
|
||||||
|
@ -3216,7 +3233,10 @@ class parser
|
||||||
}
|
}
|
||||||
|
|
||||||
// closing }
|
// closing }
|
||||||
expect(token_type::end_object);
|
if (not expect(token_type::end_object))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3273,7 +3293,10 @@ class parser
|
||||||
}
|
}
|
||||||
|
|
||||||
// closing ]
|
// closing ]
|
||||||
expect(token_type::end_array);
|
if (not expect(token_type::end_array))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3334,8 +3357,15 @@ class parser
|
||||||
// throw in case of infinity or NAN
|
// throw in case of infinity or NAN
|
||||||
if (JSON_UNLIKELY(not std::isfinite(result.m_value.number_float)))
|
if (JSON_UNLIKELY(not std::isfinite(result.m_value.number_float)))
|
||||||
{
|
{
|
||||||
JSON_THROW(out_of_range::create(406, "number overflow parsing '" +
|
if (allow_exceptions)
|
||||||
m_lexer.get_token_string() + "'"));
|
{
|
||||||
|
JSON_THROW(out_of_range::create(406, "number overflow parsing '" +
|
||||||
|
m_lexer.get_token_string() + "'"));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
expect(token_type::uninitialized);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -3343,14 +3373,20 @@ class parser
|
||||||
case token_type::parse_error:
|
case token_type::parse_error:
|
||||||
{
|
{
|
||||||
// using "uninitialized" to avoid "expected" message
|
// using "uninitialized" to avoid "expected" message
|
||||||
expect(token_type::uninitialized);
|
if (not expect(token_type::uninitialized))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
break; // LCOV_EXCL_LINE
|
break; // LCOV_EXCL_LINE
|
||||||
}
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
// the last token was unexpected; we expected a value
|
// the last token was unexpected; we expected a value
|
||||||
expect(token_type::literal_or_value);
|
if (not expect(token_type::literal_or_value))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
break; // LCOV_EXCL_LINE
|
break; // LCOV_EXCL_LINE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3455,10 +3491,15 @@ class parser
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case token_type::value_float:
|
||||||
|
{
|
||||||
|
// reject infinity or NAN
|
||||||
|
return std::isfinite(m_lexer.get_number_float());
|
||||||
|
}
|
||||||
|
|
||||||
case token_type::literal_false:
|
case token_type::literal_false:
|
||||||
case token_type::literal_null:
|
case token_type::literal_null:
|
||||||
case token_type::literal_true:
|
case token_type::literal_true:
|
||||||
case token_type::value_float:
|
|
||||||
case token_type::value_integer:
|
case token_type::value_integer:
|
||||||
case token_type::value_string:
|
case token_type::value_string:
|
||||||
case token_type::value_unsigned:
|
case token_type::value_unsigned:
|
||||||
|
@ -3483,14 +3524,23 @@ class parser
|
||||||
/*!
|
/*!
|
||||||
@throw parse_error.101 if expected token did not occur
|
@throw parse_error.101 if expected token did not occur
|
||||||
*/
|
*/
|
||||||
void expect(token_type t)
|
bool expect(token_type t)
|
||||||
{
|
{
|
||||||
if (JSON_UNLIKELY(t != last_token))
|
if (JSON_UNLIKELY(t != last_token))
|
||||||
{
|
{
|
||||||
errored = true;
|
errored = true;
|
||||||
expected = t;
|
expected = t;
|
||||||
throw_exception();
|
if (allow_exceptions)
|
||||||
|
{
|
||||||
|
throw_exception();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
[[noreturn]] void throw_exception() const
|
[[noreturn]] void throw_exception() const
|
||||||
|
@ -3527,6 +3577,8 @@ class parser
|
||||||
bool errored = false;
|
bool errored = false;
|
||||||
/// possible reason for the syntax error
|
/// possible reason for the syntax error
|
||||||
token_type expected = token_type::uninitialized;
|
token_type expected = token_type::uninitialized;
|
||||||
|
/// whether to throw exceptions in case of errors
|
||||||
|
const bool allow_exceptions = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
///////////////
|
///////////////
|
||||||
|
@ -12823,10 +12875,11 @@ class basic_json
|
||||||
@since version 2.0.3 (contiguous containers)
|
@since version 2.0.3 (contiguous containers)
|
||||||
*/
|
*/
|
||||||
static basic_json parse(detail::input_adapter i,
|
static basic_json parse(detail::input_adapter i,
|
||||||
const parser_callback_t cb = nullptr)
|
const parser_callback_t cb = nullptr,
|
||||||
|
const bool allow_exceptions = true)
|
||||||
{
|
{
|
||||||
basic_json result;
|
basic_json result;
|
||||||
parser(i, cb).parse(true, result);
|
parser(i, cb, allow_exceptions).parse(true, result);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -12834,10 +12887,11 @@ class basic_json
|
||||||
@copydoc basic_json parse(detail::input_adapter, const parser_callback_t)
|
@copydoc basic_json parse(detail::input_adapter, const parser_callback_t)
|
||||||
*/
|
*/
|
||||||
static basic_json parse(detail::input_adapter& i,
|
static basic_json parse(detail::input_adapter& i,
|
||||||
const parser_callback_t cb = nullptr)
|
const parser_callback_t cb = nullptr,
|
||||||
|
const bool allow_exceptions = true)
|
||||||
{
|
{
|
||||||
basic_json result;
|
basic_json result;
|
||||||
parser(i, cb).parse(true, result);
|
parser(i, cb, allow_exceptions).parse(true, result);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -12901,10 +12955,11 @@ class basic_json
|
||||||
std::random_access_iterator_tag,
|
std::random_access_iterator_tag,
|
||||||
typename std::iterator_traits<IteratorType>::iterator_category>::value, int>::type = 0>
|
typename std::iterator_traits<IteratorType>::iterator_category>::value, int>::type = 0>
|
||||||
static basic_json parse(IteratorType first, IteratorType last,
|
static basic_json parse(IteratorType first, IteratorType last,
|
||||||
const parser_callback_t cb = nullptr)
|
const parser_callback_t cb = nullptr,
|
||||||
|
const bool allow_exceptions = true)
|
||||||
{
|
{
|
||||||
basic_json result;
|
basic_json result;
|
||||||
parser(detail::input_adapter(first, last), cb).parse(true, result);
|
parser(detail::input_adapter(first, last), cb, allow_exceptions).parse(true, result);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -41,12 +41,31 @@ json parser_helper(const std::string& s)
|
||||||
{
|
{
|
||||||
json j;
|
json j;
|
||||||
json::parser(nlohmann::detail::input_adapter(s)).parse(true, j);
|
json::parser(nlohmann::detail::input_adapter(s)).parse(true, j);
|
||||||
|
|
||||||
|
// if this line was reached, no exception ocurred
|
||||||
|
// -> check if result is the same without exceptions
|
||||||
|
json j_nothrow;
|
||||||
|
CHECK_NOTHROW(json::parser(nlohmann::detail::input_adapter(s), nullptr, false).parse(true, j_nothrow));
|
||||||
|
CHECK(j_nothrow == j);
|
||||||
|
|
||||||
return j;
|
return j;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool accept_helper(const std::string& s)
|
bool accept_helper(const std::string& s)
|
||||||
{
|
{
|
||||||
return json::parser(nlohmann::detail::input_adapter(s)).accept(true);
|
// 1. parse s without exceptions
|
||||||
|
json j;
|
||||||
|
CHECK_NOTHROW(json::parser(nlohmann::detail::input_adapter(s), nullptr, false).parse(true, j));
|
||||||
|
const bool ok_noexcept = not j.is_discarded();
|
||||||
|
|
||||||
|
// 2. accept s
|
||||||
|
const bool ok_accept = json::parser(nlohmann::detail::input_adapter(s)).accept(true);
|
||||||
|
|
||||||
|
// 3. check if both approaches come to the same result
|
||||||
|
CHECK(ok_noexcept == ok_accept);
|
||||||
|
|
||||||
|
// 4. return result
|
||||||
|
return ok_accept;
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("parser class")
|
TEST_CASE("parser class")
|
||||||
|
@ -590,8 +609,8 @@ TEST_CASE("parser class")
|
||||||
|
|
||||||
SECTION("overflow")
|
SECTION("overflow")
|
||||||
{
|
{
|
||||||
// overflows during parsing yield an exception, but is accepted anyway
|
// overflows during parsing
|
||||||
CHECK(accept_helper("1.18973e+4932"));
|
CHECK(not accept_helper("1.18973e+4932"));
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("invalid numbers")
|
SECTION("invalid numbers")
|
||||||
|
|
|
@ -91,14 +91,19 @@ TEST_CASE("deserialization")
|
||||||
{
|
{
|
||||||
SECTION("stream")
|
SECTION("stream")
|
||||||
{
|
{
|
||||||
std::stringstream ss1, ss2, ss3;
|
std::stringstream ss1, ss2, ss3, ss4;
|
||||||
ss1 << "[\"foo\",1,2,3,false,{\"one\":1}";
|
ss1 << "[\"foo\",1,2,3,false,{\"one\":1}";
|
||||||
ss2 << "[\"foo\",1,2,3,false,{\"one\":1}";
|
ss2 << "[\"foo\",1,2,3,false,{\"one\":1}";
|
||||||
ss3 << "[\"foo\",1,2,3,false,{\"one\":1}";
|
ss3 << "[\"foo\",1,2,3,false,{\"one\":1}";
|
||||||
|
ss4 << "[\"foo\",1,2,3,false,{\"one\":1}";
|
||||||
CHECK_THROWS_AS(json::parse(ss1), json::parse_error&);
|
CHECK_THROWS_AS(json::parse(ss1), json::parse_error&);
|
||||||
CHECK_THROWS_WITH(json::parse(ss2),
|
CHECK_THROWS_WITH(json::parse(ss2),
|
||||||
"[json.exception.parse_error.101] parse error at 29: syntax error - unexpected end of input; expected ']'");
|
"[json.exception.parse_error.101] parse error at 29: syntax error - unexpected end of input; expected ']'");
|
||||||
CHECK(not json::accept(ss3));
|
CHECK(not json::accept(ss3));
|
||||||
|
|
||||||
|
json j_error;
|
||||||
|
CHECK_NOTHROW(j_error = json::parse(ss1, nullptr, false));
|
||||||
|
CHECK(j_error.is_discarded());
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("string")
|
SECTION("string")
|
||||||
|
@ -108,6 +113,10 @@ TEST_CASE("deserialization")
|
||||||
CHECK_THROWS_WITH(json::parse(s),
|
CHECK_THROWS_WITH(json::parse(s),
|
||||||
"[json.exception.parse_error.101] parse error at 29: syntax error - unexpected end of input; expected ']'");
|
"[json.exception.parse_error.101] parse error at 29: syntax error - unexpected end of input; expected ']'");
|
||||||
CHECK(not json::accept(s));
|
CHECK(not json::accept(s));
|
||||||
|
|
||||||
|
json j_error;
|
||||||
|
CHECK_NOTHROW(j_error = json::parse(s, nullptr, false));
|
||||||
|
CHECK(j_error.is_discarded());
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("operator<<")
|
SECTION("operator<<")
|
||||||
|
@ -260,6 +269,10 @@ TEST_CASE("deserialization")
|
||||||
uint8_t v[] = {'\"', 'a', 'a', 'a', 'a', 'a', 'a', '\\', 'u'};
|
uint8_t v[] = {'\"', 'a', 'a', 'a', 'a', 'a', 'a', '\\', 'u'};
|
||||||
CHECK_THROWS_AS(json::parse(std::begin(v), std::end(v)), json::parse_error&);
|
CHECK_THROWS_AS(json::parse(std::begin(v), std::end(v)), json::parse_error&);
|
||||||
CHECK(not json::accept(std::begin(v), std::end(v)));
|
CHECK(not json::accept(std::begin(v), std::end(v)));
|
||||||
|
|
||||||
|
json j_error;
|
||||||
|
CHECK_NOTHROW(j_error = json::parse(std::begin(v), std::end(v), nullptr, false));
|
||||||
|
CHECK(j_error.is_discarded());
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("case 2")
|
SECTION("case 2")
|
||||||
|
@ -267,6 +280,10 @@ TEST_CASE("deserialization")
|
||||||
uint8_t v[] = {'\"', 'a', 'a', 'a', 'a', 'a', 'a', '\\', 'u', '1'};
|
uint8_t v[] = {'\"', 'a', 'a', 'a', 'a', 'a', 'a', '\\', 'u', '1'};
|
||||||
CHECK_THROWS_AS(json::parse(std::begin(v), std::end(v)), json::parse_error&);
|
CHECK_THROWS_AS(json::parse(std::begin(v), std::end(v)), json::parse_error&);
|
||||||
CHECK(not json::accept(std::begin(v), std::end(v)));
|
CHECK(not json::accept(std::begin(v), std::end(v)));
|
||||||
|
|
||||||
|
json j_error;
|
||||||
|
CHECK_NOTHROW(j_error = json::parse(std::begin(v), std::end(v), nullptr, false));
|
||||||
|
CHECK(j_error.is_discarded());
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("case 3")
|
SECTION("case 3")
|
||||||
|
@ -274,6 +291,10 @@ TEST_CASE("deserialization")
|
||||||
uint8_t v[] = {'\"', 'a', 'a', 'a', 'a', 'a', 'a', '\\', 'u', '1', '1', '1', '1', '1', '1', '1', '1'};
|
uint8_t v[] = {'\"', 'a', 'a', 'a', 'a', 'a', 'a', '\\', 'u', '1', '1', '1', '1', '1', '1', '1', '1'};
|
||||||
CHECK_THROWS_AS(json::parse(std::begin(v), std::end(v)), json::parse_error&);
|
CHECK_THROWS_AS(json::parse(std::begin(v), std::end(v)), json::parse_error&);
|
||||||
CHECK(not json::accept(std::begin(v), std::end(v)));
|
CHECK(not json::accept(std::begin(v), std::end(v)));
|
||||||
|
|
||||||
|
json j_error;
|
||||||
|
CHECK_NOTHROW(j_error = json::parse(std::begin(v), std::end(v), nullptr, false));
|
||||||
|
CHECK(j_error.is_discarded());
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("case 4")
|
SECTION("case 4")
|
||||||
|
@ -281,6 +302,10 @@ TEST_CASE("deserialization")
|
||||||
uint8_t v[] = {'\"', 'a', 'a', 'a', 'a', 'a', 'a', 'u', '1', '1', '1', '1', '1', '1', '1', '1', '\\'};
|
uint8_t v[] = {'\"', 'a', 'a', 'a', 'a', 'a', 'a', 'u', '1', '1', '1', '1', '1', '1', '1', '1', '\\'};
|
||||||
CHECK_THROWS_AS(json::parse(std::begin(v), std::end(v)), json::parse_error&);
|
CHECK_THROWS_AS(json::parse(std::begin(v), std::end(v)), json::parse_error&);
|
||||||
CHECK(not json::accept(std::begin(v), std::end(v)));
|
CHECK(not json::accept(std::begin(v), std::end(v)));
|
||||||
|
|
||||||
|
json j_error;
|
||||||
|
CHECK_NOTHROW(j_error = json::parse(std::begin(v), std::end(v), nullptr, false));
|
||||||
|
CHECK(j_error.is_discarded());
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("case 5")
|
SECTION("case 5")
|
||||||
|
@ -288,6 +313,10 @@ TEST_CASE("deserialization")
|
||||||
uint8_t v[] = {'\"', 0x7F, 0xC1};
|
uint8_t v[] = {'\"', 0x7F, 0xC1};
|
||||||
CHECK_THROWS_AS(json::parse(std::begin(v), std::end(v)), json::parse_error&);
|
CHECK_THROWS_AS(json::parse(std::begin(v), std::end(v)), json::parse_error&);
|
||||||
CHECK(not json::accept(std::begin(v), std::end(v)));
|
CHECK(not json::accept(std::begin(v), std::end(v)));
|
||||||
|
|
||||||
|
json j_error;
|
||||||
|
CHECK_NOTHROW(j_error = json::parse(std::begin(v), std::end(v), nullptr, false));
|
||||||
|
CHECK(j_error.is_discarded());
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("case 6")
|
SECTION("case 6")
|
||||||
|
@ -295,6 +324,10 @@ TEST_CASE("deserialization")
|
||||||
uint8_t v[] = {'\"', 0x7F, 0xDF, 0x7F};
|
uint8_t v[] = {'\"', 0x7F, 0xDF, 0x7F};
|
||||||
CHECK_THROWS_AS(json::parse(std::begin(v), std::end(v)), json::parse_error&);
|
CHECK_THROWS_AS(json::parse(std::begin(v), std::end(v)), json::parse_error&);
|
||||||
CHECK(not json::accept(std::begin(v), std::end(v)));
|
CHECK(not json::accept(std::begin(v), std::end(v)));
|
||||||
|
|
||||||
|
json j_error;
|
||||||
|
CHECK_NOTHROW(j_error = json::parse(std::begin(v), std::end(v), nullptr, false));
|
||||||
|
CHECK(j_error.is_discarded());
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("case 7")
|
SECTION("case 7")
|
||||||
|
@ -302,6 +335,10 @@ TEST_CASE("deserialization")
|
||||||
uint8_t v[] = {'\"', 0x7F, 0xDF, 0xC0};
|
uint8_t v[] = {'\"', 0x7F, 0xDF, 0xC0};
|
||||||
CHECK_THROWS_AS(json::parse(std::begin(v), std::end(v)), json::parse_error&);
|
CHECK_THROWS_AS(json::parse(std::begin(v), std::end(v)), json::parse_error&);
|
||||||
CHECK(not json::accept(std::begin(v), std::end(v)));
|
CHECK(not json::accept(std::begin(v), std::end(v)));
|
||||||
|
|
||||||
|
json j_error;
|
||||||
|
CHECK_NOTHROW(j_error = json::parse(std::begin(v), std::end(v), nullptr, false));
|
||||||
|
CHECK(j_error.is_discarded());
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("case 8")
|
SECTION("case 8")
|
||||||
|
@ -309,6 +346,10 @@ TEST_CASE("deserialization")
|
||||||
uint8_t v[] = {'\"', 0x7F, 0xE0, 0x9F};
|
uint8_t v[] = {'\"', 0x7F, 0xE0, 0x9F};
|
||||||
CHECK_THROWS_AS(json::parse(std::begin(v), std::end(v)), json::parse_error&);
|
CHECK_THROWS_AS(json::parse(std::begin(v), std::end(v)), json::parse_error&);
|
||||||
CHECK(not json::accept(std::begin(v), std::end(v)));
|
CHECK(not json::accept(std::begin(v), std::end(v)));
|
||||||
|
|
||||||
|
json j_error;
|
||||||
|
CHECK_NOTHROW(j_error = json::parse(std::begin(v), std::end(v), nullptr, false));
|
||||||
|
CHECK(j_error.is_discarded());
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("case 9")
|
SECTION("case 9")
|
||||||
|
@ -316,6 +357,10 @@ TEST_CASE("deserialization")
|
||||||
uint8_t v[] = {'\"', 0x7F, 0xEF, 0xC0};
|
uint8_t v[] = {'\"', 0x7F, 0xEF, 0xC0};
|
||||||
CHECK_THROWS_AS(json::parse(std::begin(v), std::end(v)), json::parse_error&);
|
CHECK_THROWS_AS(json::parse(std::begin(v), std::end(v)), json::parse_error&);
|
||||||
CHECK(not json::accept(std::begin(v), std::end(v)));
|
CHECK(not json::accept(std::begin(v), std::end(v)));
|
||||||
|
|
||||||
|
json j_error;
|
||||||
|
CHECK_NOTHROW(j_error = json::parse(std::begin(v), std::end(v), nullptr, false));
|
||||||
|
CHECK(j_error.is_discarded());
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("case 10")
|
SECTION("case 10")
|
||||||
|
@ -323,6 +368,10 @@ TEST_CASE("deserialization")
|
||||||
uint8_t v[] = {'\"', 0x7F, 0xED, 0x7F};
|
uint8_t v[] = {'\"', 0x7F, 0xED, 0x7F};
|
||||||
CHECK_THROWS_AS(json::parse(std::begin(v), std::end(v)), json::parse_error&);
|
CHECK_THROWS_AS(json::parse(std::begin(v), std::end(v)), json::parse_error&);
|
||||||
CHECK(not json::accept(std::begin(v), std::end(v)));
|
CHECK(not json::accept(std::begin(v), std::end(v)));
|
||||||
|
|
||||||
|
json j_error;
|
||||||
|
CHECK_NOTHROW(j_error = json::parse(std::begin(v), std::end(v), nullptr, false));
|
||||||
|
CHECK(j_error.is_discarded());
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("case 11")
|
SECTION("case 11")
|
||||||
|
@ -330,6 +379,10 @@ TEST_CASE("deserialization")
|
||||||
uint8_t v[] = {'\"', 0x7F, 0xF0, 0x8F};
|
uint8_t v[] = {'\"', 0x7F, 0xF0, 0x8F};
|
||||||
CHECK_THROWS_AS(json::parse(std::begin(v), std::end(v)), json::parse_error&);
|
CHECK_THROWS_AS(json::parse(std::begin(v), std::end(v)), json::parse_error&);
|
||||||
CHECK(not json::accept(std::begin(v), std::end(v)));
|
CHECK(not json::accept(std::begin(v), std::end(v)));
|
||||||
|
|
||||||
|
json j_error;
|
||||||
|
CHECK_NOTHROW(j_error = json::parse(std::begin(v), std::end(v), nullptr, false));
|
||||||
|
CHECK(j_error.is_discarded());
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("case 12")
|
SECTION("case 12")
|
||||||
|
@ -337,6 +390,10 @@ TEST_CASE("deserialization")
|
||||||
uint8_t v[] = {'\"', 0x7F, 0xF0, 0xC0};
|
uint8_t v[] = {'\"', 0x7F, 0xF0, 0xC0};
|
||||||
CHECK_THROWS_AS(json::parse(std::begin(v), std::end(v)), json::parse_error&);
|
CHECK_THROWS_AS(json::parse(std::begin(v), std::end(v)), json::parse_error&);
|
||||||
CHECK(not json::accept(std::begin(v), std::end(v)));
|
CHECK(not json::accept(std::begin(v), std::end(v)));
|
||||||
|
|
||||||
|
json j_error;
|
||||||
|
CHECK_NOTHROW(j_error = json::parse(std::begin(v), std::end(v), nullptr, false));
|
||||||
|
CHECK(j_error.is_discarded());
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("case 13")
|
SECTION("case 13")
|
||||||
|
@ -344,6 +401,10 @@ TEST_CASE("deserialization")
|
||||||
uint8_t v[] = {'\"', 0x7F, 0xF3, 0x7F};
|
uint8_t v[] = {'\"', 0x7F, 0xF3, 0x7F};
|
||||||
CHECK_THROWS_AS(json::parse(std::begin(v), std::end(v)), json::parse_error&);
|
CHECK_THROWS_AS(json::parse(std::begin(v), std::end(v)), json::parse_error&);
|
||||||
CHECK(not json::accept(std::begin(v), std::end(v)));
|
CHECK(not json::accept(std::begin(v), std::end(v)));
|
||||||
|
|
||||||
|
json j_error;
|
||||||
|
CHECK_NOTHROW(j_error = json::parse(std::begin(v), std::end(v), nullptr, false));
|
||||||
|
CHECK(j_error.is_discarded());
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("case 14")
|
SECTION("case 14")
|
||||||
|
@ -351,6 +412,10 @@ TEST_CASE("deserialization")
|
||||||
uint8_t v[] = {'\"', 0x7F, 0xF3, 0xC0};
|
uint8_t v[] = {'\"', 0x7F, 0xF3, 0xC0};
|
||||||
CHECK_THROWS_AS(json::parse(std::begin(v), std::end(v)), json::parse_error&);
|
CHECK_THROWS_AS(json::parse(std::begin(v), std::end(v)), json::parse_error&);
|
||||||
CHECK(not json::accept(std::begin(v), std::end(v)));
|
CHECK(not json::accept(std::begin(v), std::end(v)));
|
||||||
|
|
||||||
|
json j_error;
|
||||||
|
CHECK_NOTHROW(j_error = json::parse(std::begin(v), std::end(v), nullptr, false));
|
||||||
|
CHECK(j_error.is_discarded());
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("case 15")
|
SECTION("case 15")
|
||||||
|
@ -358,6 +423,10 @@ TEST_CASE("deserialization")
|
||||||
uint8_t v[] = {'\"', 0x7F, 0xF4, 0x7F};
|
uint8_t v[] = {'\"', 0x7F, 0xF4, 0x7F};
|
||||||
CHECK_THROWS_AS(json::parse(std::begin(v), std::end(v)), json::parse_error&);
|
CHECK_THROWS_AS(json::parse(std::begin(v), std::end(v)), json::parse_error&);
|
||||||
CHECK(not json::accept(std::begin(v), std::end(v)));
|
CHECK(not json::accept(std::begin(v), std::end(v)));
|
||||||
|
|
||||||
|
json j_error;
|
||||||
|
CHECK_NOTHROW(j_error = json::parse(std::begin(v), std::end(v), nullptr, false));
|
||||||
|
CHECK(j_error.is_discarded());
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("case 16")
|
SECTION("case 16")
|
||||||
|
@ -365,6 +434,10 @@ TEST_CASE("deserialization")
|
||||||
uint8_t v[] = {'{', '\"', '\"', ':', '1', '1'};
|
uint8_t v[] = {'{', '\"', '\"', ':', '1', '1'};
|
||||||
CHECK_THROWS_AS(json::parse(std::begin(v), std::end(v)), json::parse_error&);
|
CHECK_THROWS_AS(json::parse(std::begin(v), std::end(v)), json::parse_error&);
|
||||||
CHECK(not json::accept(std::begin(v), std::end(v)));
|
CHECK(not json::accept(std::begin(v), std::end(v)));
|
||||||
|
|
||||||
|
json j_error;
|
||||||
|
CHECK_NOTHROW(j_error = json::parse(std::begin(v), std::end(v), nullptr, false));
|
||||||
|
CHECK(j_error.is_discarded());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue