mirror of
https://github.com/nlohmann/json.git
synced 2025-07-22 15:21:52 +03:00
🔨 changed call from "not good()" to "fail()" #493
Also merged develop into this feature branch.
This commit is contained in:
@ -33,6 +33,7 @@ SOFTWARE.
|
||||
using nlohmann::json;
|
||||
|
||||
#include <fstream>
|
||||
#include <list>
|
||||
|
||||
TEST_CASE("regression tests")
|
||||
{
|
||||
@ -49,6 +50,7 @@ TEST_CASE("regression tests")
|
||||
|
||||
SECTION("issue #70 - Handle infinity and NaN cases")
|
||||
{
|
||||
/*
|
||||
SECTION("NAN value")
|
||||
{
|
||||
CHECK(json(NAN) == json());
|
||||
@ -60,6 +62,36 @@ TEST_CASE("regression tests")
|
||||
CHECK(json(INFINITY) == json());
|
||||
CHECK(json(json::number_float_t(INFINITY)) == json());
|
||||
}
|
||||
*/
|
||||
|
||||
// With 3.0.0, the semantics of this changed: NAN and infinity are
|
||||
// stored properly inside the JSON value (no exception or conversion
|
||||
// to null), but are serialized as null.
|
||||
SECTION("NAN value")
|
||||
{
|
||||
json j1 = NAN;
|
||||
CHECK(j1.is_number_float());
|
||||
json::number_float_t f1 = j1;
|
||||
CHECK(std::isnan(f1));
|
||||
|
||||
json j2 = json::number_float_t(NAN);
|
||||
CHECK(j2.is_number_float());
|
||||
json::number_float_t f2 = j2;
|
||||
CHECK(std::isnan(f2));
|
||||
}
|
||||
|
||||
SECTION("infinity")
|
||||
{
|
||||
json j1 = INFINITY;
|
||||
CHECK(j1.is_number_float());
|
||||
json::number_float_t f1 = j1;
|
||||
CHECK(not std::isfinite(f1));
|
||||
|
||||
json j2 = json::number_float_t(INFINITY);
|
||||
CHECK(j2.is_number_float());
|
||||
json::number_float_t f2 = j2;
|
||||
CHECK(not std::isfinite(f2));
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("pull request #71 - handle enum type")
|
||||
@ -429,16 +461,6 @@ TEST_CASE("regression tests")
|
||||
{
|
||||
setlocale(LC_NUMERIC, "de_DE.UTF-8");
|
||||
|
||||
// Verify that snprintf uses special decimal and grouping characters.
|
||||
// Disabled, because can't trigger locale-specific behavior in AppVeyor
|
||||
#ifndef _MSC_VER
|
||||
{
|
||||
std::array<char, 64> buf;
|
||||
std::snprintf(buf.data(), buf.size(), "%.2f", 12345.67);
|
||||
CHECK(strcmp(buf.data(), "12345,67") == 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
// verify that dumped correctly with '.' and no grouping
|
||||
const json j1 = 12345.67;
|
||||
CHECK(json(12345.67).dump() == "12345.67");
|
||||
@ -449,18 +471,6 @@ TEST_CASE("regression tests")
|
||||
{
|
||||
setlocale(LC_NUMERIC, "de_DE.UTF-8");
|
||||
|
||||
// disabled, because locale-specific beharivor is not
|
||||
// triggered in AppVeyor for some reason
|
||||
#ifndef _MSC_VER
|
||||
{
|
||||
// verify that strtod now uses commas as decimal-separator
|
||||
CHECK(std::strtod("3,14", nullptr) == 3.14);
|
||||
|
||||
// verify that strtod does not understand dots as decimal separator
|
||||
CHECK(std::strtod("3.14", nullptr) == 3);
|
||||
}
|
||||
#endif
|
||||
|
||||
// verify that parsed correctly despite using strtod internally
|
||||
CHECK(json::parse("3.14").get<double>() == 3.14);
|
||||
|
||||
@ -559,14 +569,16 @@ TEST_CASE("regression tests")
|
||||
|
||||
SECTION("issue #329 - serialized value not always can be parsed")
|
||||
{
|
||||
json j = json::parse("22e2222");
|
||||
CHECK(j == json());
|
||||
CHECK_THROWS_AS(json::parse("22e2222"), json::out_of_range);
|
||||
CHECK_THROWS_WITH(json::parse("22e2222"),
|
||||
"[json.exception.out_of_range.406] number overflow parsing '22e2222'");
|
||||
}
|
||||
|
||||
SECTION("issue #366 - json::parse on failed stream gets stuck")
|
||||
{
|
||||
std::ifstream f("file_not_found.json");
|
||||
CHECK_THROWS_AS(json::parse(f), std::invalid_argument);
|
||||
CHECK_THROWS_AS(json::parse(f), json::parse_error);
|
||||
CHECK_THROWS_WITH(json::parse(f), "[json.exception.parse_error.111] parse error: bad input stream");
|
||||
}
|
||||
|
||||
SECTION("issue #367 - calling stream at EOF")
|
||||
@ -580,8 +592,9 @@ TEST_CASE("regression tests")
|
||||
// ss is not at EOF; this yielded an error before the fix
|
||||
// (threw basic_string::append). No, it should just throw
|
||||
// a parse error because of the EOF.
|
||||
CHECK_THROWS_AS(j << ss, std::invalid_argument);
|
||||
CHECK_THROWS_WITH(j << ss, "parse error - unexpected end of input");
|
||||
CHECK_THROWS_AS(j << ss, json::parse_error);
|
||||
CHECK_THROWS_WITH(j << ss,
|
||||
"[json.exception.parse_error.101] parse error at 1: parse error - unexpected end of input");
|
||||
}
|
||||
|
||||
SECTION("issue #389 - Integer-overflow (OSS-Fuzz issue 267)")
|
||||
@ -612,37 +625,51 @@ TEST_CASE("regression tests")
|
||||
{
|
||||
// original test case
|
||||
std::vector<uint8_t> vec {0x65, 0xf5, 0x0a, 0x48, 0x21};
|
||||
CHECK_THROWS_AS(json::from_cbor(vec), std::out_of_range);
|
||||
CHECK_THROWS_AS(json::from_cbor(vec), json::parse_error);
|
||||
CHECK_THROWS_WITH(json::from_cbor(vec),
|
||||
"[json.exception.parse_error.110] parse error at 2: cannot read 5 bytes from vector");
|
||||
}
|
||||
|
||||
SECTION("issue #407 - Heap-buffer-overflow (OSS-Fuzz issue 343)")
|
||||
{
|
||||
// original test case: incomplete float64
|
||||
std::vector<uint8_t> vec1 {0xcb, 0x8f, 0x0a};
|
||||
CHECK_THROWS_AS(json::from_msgpack(vec1), std::out_of_range);
|
||||
CHECK_THROWS_AS(json::from_msgpack(vec1), json::parse_error);
|
||||
CHECK_THROWS_WITH(json::from_msgpack(vec1),
|
||||
"[json.exception.parse_error.110] parse error at 2: cannot read 8 bytes from vector");
|
||||
|
||||
// related test case: incomplete float32
|
||||
std::vector<uint8_t> vec2 {0xca, 0x8f, 0x0a};
|
||||
CHECK_THROWS_AS(json::from_msgpack(vec2), std::out_of_range);
|
||||
CHECK_THROWS_AS(json::from_msgpack(vec2), json::parse_error);
|
||||
CHECK_THROWS_WITH(json::from_msgpack(vec2),
|
||||
"[json.exception.parse_error.110] parse error at 2: cannot read 4 bytes from vector");
|
||||
|
||||
// related test case: incomplete Half-Precision Float (CBOR)
|
||||
std::vector<uint8_t> vec3 {0xf9, 0x8f};
|
||||
CHECK_THROWS_AS(json::from_cbor(vec3), std::out_of_range);
|
||||
CHECK_THROWS_AS(json::from_cbor(vec3), json::parse_error);
|
||||
CHECK_THROWS_WITH(json::from_cbor(vec3),
|
||||
"[json.exception.parse_error.110] parse error at 2: cannot read 2 bytes from vector");
|
||||
|
||||
// related test case: incomplete Single-Precision Float (CBOR)
|
||||
std::vector<uint8_t> vec4 {0xfa, 0x8f, 0x0a};
|
||||
CHECK_THROWS_AS(json::from_cbor(vec4), std::out_of_range);
|
||||
CHECK_THROWS_AS(json::from_cbor(vec4), json::parse_error);
|
||||
CHECK_THROWS_WITH(json::from_cbor(vec4),
|
||||
"[json.exception.parse_error.110] parse error at 2: cannot read 4 bytes from vector");
|
||||
|
||||
// related test case: incomplete Double-Precision Float (CBOR)
|
||||
std::vector<uint8_t> vec5 {0xfb, 0x8f, 0x0a};
|
||||
CHECK_THROWS_AS(json::from_cbor(vec5), std::out_of_range);
|
||||
CHECK_THROWS_AS(json::from_cbor(vec5), json::parse_error);
|
||||
CHECK_THROWS_WITH(json::from_cbor(vec5),
|
||||
"[json.exception.parse_error.110] parse error at 2: cannot read 8 bytes from vector");
|
||||
}
|
||||
|
||||
SECTION("issue #408 - Heap-buffer-overflow (OSS-Fuzz issue 344)")
|
||||
{
|
||||
// original test case
|
||||
std::vector<uint8_t> vec1 {0x87};
|
||||
CHECK_THROWS_AS(json::from_msgpack(vec1), std::out_of_range);
|
||||
CHECK_THROWS_AS(json::from_msgpack(vec1), json::parse_error);
|
||||
CHECK_THROWS_WITH(json::from_msgpack(vec1),
|
||||
"[json.exception.parse_error.110] parse error at 2: cannot read 1 bytes from vector");
|
||||
|
||||
// more test cases for MessagePack
|
||||
for (auto b :
|
||||
@ -654,7 +681,7 @@ TEST_CASE("regression tests")
|
||||
})
|
||||
{
|
||||
std::vector<uint8_t> vec(1, static_cast<uint8_t>(b));
|
||||
CHECK_THROWS_AS(json::from_msgpack(vec), std::out_of_range);
|
||||
CHECK_THROWS_AS(json::from_msgpack(vec), json::parse_error);
|
||||
}
|
||||
|
||||
// more test cases for CBOR
|
||||
@ -669,28 +696,38 @@ TEST_CASE("regression tests")
|
||||
})
|
||||
{
|
||||
std::vector<uint8_t> vec(1, static_cast<uint8_t>(b));
|
||||
CHECK_THROWS_AS(json::from_cbor(vec), std::out_of_range);
|
||||
CHECK_THROWS_AS(json::from_cbor(vec), json::parse_error);
|
||||
}
|
||||
|
||||
// special case: empty input
|
||||
std::vector<uint8_t> vec2;
|
||||
CHECK_THROWS_AS(json::from_cbor(vec2), std::out_of_range);
|
||||
CHECK_THROWS_AS(json::from_msgpack(vec2), std::out_of_range);
|
||||
CHECK_THROWS_AS(json::from_cbor(vec2), json::parse_error);
|
||||
CHECK_THROWS_WITH(json::from_cbor(vec2),
|
||||
"[json.exception.parse_error.110] parse error at 1: cannot read 1 bytes from vector");
|
||||
CHECK_THROWS_AS(json::from_msgpack(vec2), json::parse_error);
|
||||
CHECK_THROWS_WITH(json::from_msgpack(vec2),
|
||||
"[json.exception.parse_error.110] parse error at 1: cannot read 1 bytes from vector");
|
||||
}
|
||||
|
||||
SECTION("issue #411 - Heap-buffer-overflow (OSS-Fuzz issue 366)")
|
||||
{
|
||||
// original test case: empty UTF-8 string (indefinite length)
|
||||
std::vector<uint8_t> vec1 {0x7f};
|
||||
CHECK_THROWS_AS(json::from_cbor(vec1), std::out_of_range);
|
||||
CHECK_THROWS_AS(json::from_cbor(vec1), json::parse_error);
|
||||
CHECK_THROWS_WITH(json::from_cbor(vec1),
|
||||
"[json.exception.parse_error.110] parse error at 2: cannot read 1 bytes from vector");
|
||||
|
||||
// related test case: empty array (indefinite length)
|
||||
std::vector<uint8_t> vec2 {0x9f};
|
||||
CHECK_THROWS_AS(json::from_cbor(vec2), std::out_of_range);
|
||||
CHECK_THROWS_AS(json::from_cbor(vec2), json::parse_error);
|
||||
CHECK_THROWS_WITH(json::from_cbor(vec2),
|
||||
"[json.exception.parse_error.110] parse error at 2: cannot read 1 bytes from vector");
|
||||
|
||||
// related test case: empty map (indefinite length)
|
||||
std::vector<uint8_t> vec3 {0xbf};
|
||||
CHECK_THROWS_AS(json::from_cbor(vec3), std::out_of_range);
|
||||
CHECK_THROWS_AS(json::from_cbor(vec3), json::parse_error);
|
||||
CHECK_THROWS_WITH(json::from_cbor(vec3),
|
||||
"[json.exception.parse_error.110] parse error at 2: cannot read 1 bytes from vector");
|
||||
}
|
||||
|
||||
SECTION("issue #412 - Heap-buffer-overflow (OSS-Fuzz issue 367)")
|
||||
@ -716,19 +753,27 @@ TEST_CASE("regression tests")
|
||||
0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60,
|
||||
0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60
|
||||
};
|
||||
CHECK_THROWS_AS(json::from_cbor(vec), std::out_of_range);
|
||||
CHECK_THROWS_AS(json::from_cbor(vec), json::parse_error);
|
||||
CHECK_THROWS_WITH(json::from_cbor(vec),
|
||||
"[json.exception.parse_error.110] parse error at 137: cannot read 1 bytes from vector");
|
||||
|
||||
// related test case: nonempty UTF-8 string (indefinite length)
|
||||
std::vector<uint8_t> vec1 {0x7f, 0x61, 0x61};
|
||||
CHECK_THROWS_AS(json::from_cbor(vec1), std::out_of_range);
|
||||
CHECK_THROWS_AS(json::from_cbor(vec1), json::parse_error);
|
||||
CHECK_THROWS_WITH(json::from_cbor(vec1),
|
||||
"[json.exception.parse_error.110] parse error at 4: cannot read 1 bytes from vector");
|
||||
|
||||
// related test case: nonempty array (indefinite length)
|
||||
std::vector<uint8_t> vec2 {0x9f, 0x01};
|
||||
CHECK_THROWS_AS(json::from_cbor(vec2), std::out_of_range);
|
||||
CHECK_THROWS_AS(json::from_cbor(vec2), json::parse_error);
|
||||
CHECK_THROWS_WITH(json::from_cbor(vec2),
|
||||
"[json.exception.parse_error.110] parse error at 3: cannot read 1 bytes from vector");
|
||||
|
||||
// related test case: nonempty map (indefinite length)
|
||||
std::vector<uint8_t> vec3 {0xbf, 0x61, 0x61, 0x01};
|
||||
CHECK_THROWS_AS(json::from_cbor(vec3), std::out_of_range);
|
||||
CHECK_THROWS_AS(json::from_cbor(vec3), json::parse_error);
|
||||
CHECK_THROWS_WITH(json::from_cbor(vec3),
|
||||
"[json.exception.parse_error.110] parse error at 5: cannot read 1 bytes from vector");
|
||||
}
|
||||
|
||||
SECTION("issue #414 - compare with literal 0)")
|
||||
@ -761,7 +806,9 @@ TEST_CASE("regression tests")
|
||||
0x96, 0x96, 0xb4, 0xb4, 0xfa, 0x94, 0x94, 0x61,
|
||||
0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0xfa
|
||||
};
|
||||
CHECK_THROWS_AS(json::from_cbor(vec1), std::out_of_range);
|
||||
CHECK_THROWS_AS(json::from_cbor(vec1), json::parse_error);
|
||||
CHECK_THROWS_WITH(json::from_cbor(vec1),
|
||||
"[json.exception.parse_error.110] parse error at 49: cannot read 4 bytes from vector");
|
||||
|
||||
// related test case: double-precision
|
||||
std::vector<uint8_t> vec2
|
||||
@ -773,13 +820,15 @@ TEST_CASE("regression tests")
|
||||
0x96, 0x96, 0xb4, 0xb4, 0xfa, 0x94, 0x94, 0x61,
|
||||
0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0xfb
|
||||
};
|
||||
CHECK_THROWS_AS(json::from_cbor(vec2), std::out_of_range);
|
||||
CHECK_THROWS_AS(json::from_cbor(vec2), json::parse_error);
|
||||
CHECK_THROWS_WITH(json::from_cbor(vec2),
|
||||
"[json.exception.parse_error.110] parse error at 49: cannot read 8 bytes from vector");
|
||||
}
|
||||
|
||||
SECTION("issue #452 - Heap-buffer-overflow (OSS-Fuzz issue 585)")
|
||||
{
|
||||
std::vector<uint8_t> vec = {'-', '0', '1', '2', '2', '7', '4'};
|
||||
CHECK_THROWS_AS(json::parse(vec), std::invalid_argument);
|
||||
CHECK_THROWS_AS(json::parse(vec), json::parse_error);
|
||||
}
|
||||
|
||||
SECTION("issue #454 - doubles are printed as integers")
|
||||
@ -797,6 +846,62 @@ TEST_CASE("regression tests")
|
||||
CHECK(s1 == s2);
|
||||
}
|
||||
|
||||
SECTION("issue #473 - inconsistent behavior in conversion to array type")
|
||||
{
|
||||
json j_array = {1, 2, 3, 4};
|
||||
json j_number = 42;
|
||||
json j_null = nullptr;
|
||||
|
||||
SECTION("std::vector")
|
||||
{
|
||||
auto create = [](const json & j)
|
||||
{
|
||||
std::vector<int> v = j;
|
||||
};
|
||||
|
||||
CHECK_NOTHROW(create(j_array));
|
||||
CHECK_THROWS_AS(create(j_number), json::type_error);
|
||||
CHECK_THROWS_WITH(create(j_number), "[json.exception.type_error.302] type must be array, but is number");
|
||||
CHECK_THROWS_AS(create(j_null), json::type_error);
|
||||
CHECK_THROWS_WITH(create(j_null), "[json.exception.type_error.302] type must be array, but is null");
|
||||
}
|
||||
|
||||
SECTION("std::list")
|
||||
{
|
||||
auto create = [](const json & j)
|
||||
{
|
||||
std::list<int> v = j;
|
||||
};
|
||||
|
||||
CHECK_NOTHROW(create(j_array));
|
||||
CHECK_THROWS_AS(create(j_number), json::type_error);
|
||||
CHECK_THROWS_WITH(create(j_number), "[json.exception.type_error.302] type must be array, but is number");
|
||||
CHECK_THROWS_AS(create(j_null), json::type_error);
|
||||
CHECK_THROWS_WITH(create(j_null), "[json.exception.type_error.302] type must be array, but is null");
|
||||
}
|
||||
|
||||
SECTION("std::forward_list")
|
||||
{
|
||||
auto create = [](const json & j)
|
||||
{
|
||||
std::forward_list<int> v = j;
|
||||
};
|
||||
|
||||
CHECK_NOTHROW(create(j_array));
|
||||
CHECK_THROWS_AS(create(j_number), json::type_error);
|
||||
CHECK_THROWS_WITH(create(j_number), "[json.exception.type_error.302] type must be array, but is number");
|
||||
CHECK_THROWS_AS(create(j_null), json::type_error);
|
||||
CHECK_THROWS_WITH(create(j_null), "[json.exception.type_error.302] type must be array, but is null");
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("issue #486 - json::value_t can't be a map's key type in VC++ 2015")
|
||||
{
|
||||
// the code below must compile with MSVC
|
||||
std::map<json::value_t, std::string> jsonTypes ;
|
||||
jsonTypes[json::value_t::array] = "array";
|
||||
}
|
||||
|
||||
SECTION("issue #494 - conversion from vector<bool> to json fails to build")
|
||||
{
|
||||
std::vector<bool> boolVector = {false, true, false, false};
|
||||
@ -836,4 +941,24 @@ TEST_CASE("regression tests")
|
||||
CHECK_THROWS_AS(l.fill_line_buffer(), std::invalid_argument);
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("issue #504 - assertion error (OSS-Fuzz 856)")
|
||||
{
|
||||
std::vector<uint8_t> vec1 = {0xf9, 0xff, 0xff, 0x4a, 0x3a, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01, 0x37, 0x02, 0x38};
|
||||
json j1 = json::from_cbor(vec1);
|
||||
|
||||
// step 2: round trip
|
||||
std::vector<uint8_t> vec2 = json::to_cbor(j1);
|
||||
|
||||
// parse serialization
|
||||
json j2 = json::from_cbor(vec2);
|
||||
|
||||
// NaN is dumped to "null"
|
||||
CHECK(j2.is_number_float());
|
||||
CHECK(std::isnan(j2.get<json::number_float_t>()));
|
||||
CHECK(j2.dump() == "null");
|
||||
|
||||
// check if serializations match
|
||||
CHECK(json::to_cbor(j2) == vec2);
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user