🚧 a lot of minor changes

- Removed unused headers.
- Added override where needed.
- Added description for parse_error.113 exception.
- Fixed some conversion warnings.
- Integrated cbor_expect_string function for CBOR maps.
- Added documentation on the supported CBOR/MessagePack features.
- Added test to check all initial bytes for CBOR input.
parent 483a58f6
This diff is collapsed.
This diff is collapsed.
......@@ -130,14 +130,14 @@ TEST_CASE("CBOR")
// check individual bytes
CHECK(result[0] == 0x3b);
uint64_t restored = static_cast<uint64_t>((static_cast<uint64_t>(result[1]) << 070) +
uint64_t restored = (static_cast<uint64_t>(result[1]) << 070) +
(static_cast<uint64_t>(result[2]) << 060) +
(static_cast<uint64_t>(result[3]) << 050) +
(static_cast<uint64_t>(result[4]) << 040) +
(static_cast<uint64_t>(result[5]) << 030) +
(static_cast<uint64_t>(result[6]) << 020) +
(static_cast<uint64_t>(result[7]) << 010) +
static_cast<uint64_t>(result[8]));
static_cast<uint64_t>(result[8]);
CHECK(restored == positive);
CHECK(-1 - static_cast<int64_t>(restored) == i);
......@@ -182,10 +182,10 @@ TEST_CASE("CBOR")
// check individual bytes
CHECK(result[0] == 0x3a);
uint32_t restored = static_cast<uint32_t>((static_cast<uint32_t>(result[1]) << 030) +
uint32_t restored = (static_cast<uint32_t>(result[1]) << 030) +
(static_cast<uint32_t>(result[2]) << 020) +
(static_cast<uint32_t>(result[3]) << 010) +
static_cast<uint32_t>(result[4]));
static_cast<uint32_t>(result[4]);
CHECK(restored == positive);
CHECK(-1ll - restored == i);
......@@ -220,7 +220,7 @@ TEST_CASE("CBOR")
// check individual bytes
CHECK(result[0] == 0x39);
uint16_t restored = static_cast<uint8_t>(result[1]) * 256 + static_cast<uint8_t>(result[2]);
uint16_t restored = static_cast<uint16_t>(static_cast<uint8_t>(result[1]) * 256 + static_cast<uint8_t>(result[2]));
CHECK(restored == positive);
CHECK(-1 - restored == i);
......@@ -289,7 +289,7 @@ TEST_CASE("CBOR")
// create expected byte vector
std::vector<uint8_t> expected;
expected.push_back(0x20 - 1 - static_cast<uint8_t>(i));
expected.push_back(static_cast<uint8_t>(0x20 - 1 - static_cast<uint8_t>(i)));
// compare result + size
const auto result = json::to_cbor(j);
......@@ -392,7 +392,7 @@ TEST_CASE("CBOR")
// check individual bytes
CHECK(result[0] == 0x19);
uint16_t restored = static_cast<uint8_t>(result[1]) * 256 + static_cast<uint8_t>(result[2]);
uint16_t restored = static_cast<uint16_t>(static_cast<uint8_t>(result[1]) * 256 + static_cast<uint8_t>(result[2]));
CHECK(restored == i);
// roundtrip
......@@ -431,10 +431,10 @@ TEST_CASE("CBOR")
// check individual bytes
CHECK(result[0] == 0x1a);
uint32_t restored = static_cast<uint32_t>((static_cast<uint32_t>(result[1]) << 030) +
uint32_t restored = (static_cast<uint32_t>(result[1]) << 030) +
(static_cast<uint32_t>(result[2]) << 020) +
(static_cast<uint32_t>(result[3]) << 010) +
static_cast<uint32_t>(result[4]));
static_cast<uint32_t>(result[4]);
CHECK(restored == i);
// roundtrip
......@@ -477,14 +477,14 @@ TEST_CASE("CBOR")
// check individual bytes
CHECK(result[0] == 0x1b);
uint64_t restored = static_cast<uint64_t>((static_cast<uint64_t>(result[1]) << 070) +
uint64_t restored = (static_cast<uint64_t>(result[1]) << 070) +
(static_cast<uint64_t>(result[2]) << 060) +
(static_cast<uint64_t>(result[3]) << 050) +
(static_cast<uint64_t>(result[4]) << 040) +
(static_cast<uint64_t>(result[5]) << 030) +
(static_cast<uint64_t>(result[6]) << 020) +
(static_cast<uint64_t>(result[7]) << 010) +
static_cast<uint64_t>(result[8]));
static_cast<uint64_t>(result[8]);
CHECK(restored == i);
// roundtrip
......@@ -616,7 +616,7 @@ TEST_CASE("CBOR")
// check individual bytes
CHECK(result[0] == 0x19);
uint16_t restored = static_cast<uint8_t>(result[1]) * 256 + static_cast<uint8_t>(result[2]);
uint16_t restored = static_cast<uint16_t>(static_cast<uint8_t>(result[1]) * 256 + static_cast<uint8_t>(result[2]));
CHECK(restored == i);
// roundtrip
......@@ -654,10 +654,10 @@ TEST_CASE("CBOR")
// check individual bytes
CHECK(result[0] == 0x1a);
uint32_t restored = static_cast<uint32_t>((static_cast<uint32_t>(result[1]) << 030) +
uint32_t restored = (static_cast<uint32_t>(result[1]) << 030) +
(static_cast<uint32_t>(result[2]) << 020) +
(static_cast<uint32_t>(result[3]) << 010) +
static_cast<uint32_t>(result[4]));
static_cast<uint32_t>(result[4]);
CHECK(restored == i);
// roundtrip
......@@ -699,14 +699,14 @@ TEST_CASE("CBOR")
// check individual bytes
CHECK(result[0] == 0x1b);
uint64_t restored = static_cast<uint64_t>((static_cast<uint64_t>(result[1]) << 070) +
uint64_t restored = (static_cast<uint64_t>(result[1]) << 070) +
(static_cast<uint64_t>(result[2]) << 060) +
(static_cast<uint64_t>(result[3]) << 050) +
(static_cast<uint64_t>(result[4]) << 040) +
(static_cast<uint64_t>(result[5]) << 030) +
(static_cast<uint64_t>(result[6]) << 020) +
(static_cast<uint64_t>(result[7]) << 010) +
static_cast<uint64_t>(result[8]));
static_cast<uint64_t>(result[8]);
CHECK(restored == i);
// roundtrip
......@@ -1538,6 +1538,83 @@ TEST_CASE("CBOR roundtrips", "[hide]")
}
}
TEST_CASE("all first bytes", "[!throws]")
{
// these bytes will fail immediately with exception parse_error.112
std::set<uint8_t> unsupported =
{
//// types not supported by this library
// byte strings
0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
// byte strings
0x58, 0x59, 0x5a, 0x5b, 0x5f,
// date/time
0xc0, 0xc1,
// bignum
0xc2, 0xc3,
// decimal fracion
0xc4,
// bigfloat
0xc5,
// tagged item
0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd,
0xce, 0xcf, 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd8,
0xd9, 0xda, 0xdb,
// expected conversion
0xd5, 0xd6, 0xd7,
// simple value
0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xef, 0xf0,
0xf1, 0xf2, 0xf3,
0xf8,
// undefined
0xf7,
//// bytes not specified by CBOR
0x1c, 0x1d, 0x1e, 0x1f,
0x3c, 0x3d, 0x3e, 0x3f,
0x5c, 0x5d, 0x5e,
0x7c, 0x7d, 0x7e,
0x9c, 0x9d, 0x9e,
0xbc, 0xbd, 0xbe,
0xdc, 0xdd, 0xde, 0xdf,
0xee,
0xfc, 0xfe, 0xfd,
/// break cannot be the first byte
0xff
};
for (auto i = 0; i < 256; ++i)
{
const auto byte = static_cast<uint8_t>(i);
try
{
json::from_cbor({byte});
}
catch (const json::parse_error& e)
{
// check that parse_error.112 is only thrown if the
// first byte is in the unsupported set
CAPTURE(e.what());
if (std::find(unsupported.begin(), unsupported.end(), byte) != unsupported.end())
{
CHECK(e.id == 112);
}
else
{
CHECK(e.id != 112);
}
}
}
}
TEST_CASE("examples from RFC 7049 Appendix A")
{
SECTION("numbers")
......
......@@ -139,7 +139,7 @@ TEST_CASE("lexer class")
for (int c = 1; c < 128; ++c)
{
// create string from the ASCII code
const auto s = std::string(1, c);
const auto s = std::string(1, static_cast<char>(c));
// store scan() result
const auto res = json::lexer(reinterpret_cast<const json::lexer::lexer_char_t*>(s.c_str()),
1).scan();
......
......@@ -494,7 +494,7 @@ TEST_CASE("parser class")
// invalid escapes
for (int c = 1; c < 128; ++c)
{
auto s = std::string("\"\\") + std::string(1, c) + "\"";
auto s = std::string("\"\\") + std::string(1, static_cast<char>(c)) + "\"";
switch (c)
{
......@@ -574,10 +574,10 @@ TEST_CASE("parser class")
std::string s = "\"\\u";
// create a string with the iterated character at each position
auto s1 = s + "000" + std::string(1, c) + "\"";
auto s2 = s + "00" + std::string(1, c) + "0\"";
auto s3 = s + "0" + std::string(1, c) + "00\"";
auto s4 = s + std::string(1, c) + "000\"";
auto s1 = s + "000" + std::string(1, static_cast<char>(c)) + "\"";
auto s2 = s + "00" + std::string(1, static_cast<char>(c)) + "0\"";
auto s3 = s + "0" + std::string(1, static_cast<char>(c)) + "00\"";
auto s4 = s + std::string(1, static_cast<char>(c)) + "000\"";
if (valid(c))
{
......
......@@ -72,8 +72,8 @@ TEST_CASE("concepts")
// X::size_type must return an unsigned integer
CHECK((std::is_unsigned<json::size_type>::value));
// X::size_type can represent any non-negative value of X::difference_type
CHECK(static_cast<size_t>(std::numeric_limits<json::difference_type>::max()) <=
static_cast<size_t>(std::numeric_limits<json::size_type>::max()));
CHECK(static_cast<json::size_type>(std::numeric_limits<json::difference_type>::max()) <=
std::numeric_limits<json::size_type>::max());
// the expression "X u" has the post-condition "u.empty()"
{
......
......@@ -48,7 +48,7 @@ TEST_CASE("element access 1")
CHECK(j.at(3) == json(nullptr));
CHECK(j.at(4) == json("string"));
CHECK(j.at(5) == json(42.23));
CHECK(j.at(6) == json(json::object()));
CHECK(j.at(6) == json::object());
CHECK(j.at(7) == json({1, 2, 3}));
CHECK(j_const.at(0) == json(1));
......@@ -57,7 +57,7 @@ TEST_CASE("element access 1")
CHECK(j_const.at(3) == json(nullptr));
CHECK(j_const.at(4) == json("string"));
CHECK(j_const.at(5) == json(42.23));
CHECK(j_const.at(6) == json(json::object()));
CHECK(j_const.at(6) == json::object());
CHECK(j_const.at(7) == json({1, 2, 3}));
}
......@@ -171,7 +171,7 @@ TEST_CASE("element access 1")
CHECK(j[3] == json(nullptr));
CHECK(j[4] == json("string"));
CHECK(j[5] == json(42.23));
CHECK(j[6] == json(json::object()));
CHECK(j[6] == json::object());
CHECK(j[7] == json({1, 2, 3}));
CHECK(j_const[0] == json(1));
......@@ -180,7 +180,7 @@ TEST_CASE("element access 1")
CHECK(j_const[3] == json(nullptr));
CHECK(j_const[4] == json("string"));
CHECK(j_const[5] == json(42.23));
CHECK(j_const[6] == json(json::object()));
CHECK(j_const[6] == json::object());
CHECK(j_const[7] == json({1, 2, 3}));
}
......
......@@ -48,7 +48,7 @@ TEST_CASE("element access 2")
CHECK(j.at("null") == json(nullptr));
CHECK(j.at("string") == json("hello world"));
CHECK(j.at("floating") == json(42.23));
CHECK(j.at("object") == json(json::object()));
CHECK(j.at("object") == json::object());
CHECK(j.at("array") == json({1, 2, 3}));
CHECK(j_const.at("integer") == json(1));
......@@ -57,7 +57,7 @@ TEST_CASE("element access 2")
CHECK(j_const.at("null") == json(nullptr));
CHECK(j_const.at("string") == json("hello world"));
CHECK(j_const.at("floating") == json(42.23));
CHECK(j_const.at("object") == json(json::object()));
CHECK(j_const.at("object") == json::object());
CHECK(j_const.at("array") == json({1, 2, 3}));
}
......@@ -161,7 +161,7 @@ TEST_CASE("element access 2")
CHECK(j.value("string", std::string("bar")) == "hello world");
CHECK(j.value("floating", 12.34) == Approx(42.23));
CHECK(j.value("floating", 12) == 42);
CHECK(j.value("object", json({{"foo", "bar"}})) == json(json::object()));
CHECK(j.value("object", json({{"foo", "bar"}})) == json::object());
CHECK(j.value("array", json({10, 100})) == json({1, 2, 3}));
CHECK(j_const.value("integer", 2) == 1);
......@@ -173,7 +173,7 @@ TEST_CASE("element access 2")
CHECK(j_const.value("string", std::string("bar")) == "hello world");
CHECK(j_const.value("floating", 12.34) == Approx(42.23));
CHECK(j_const.value("floating", 12) == 42);
CHECK(j_const.value("object", json({{"foo", "bar"}})) == json(json::object()));
CHECK(j_const.value("object", json({{"foo", "bar"}})) == json::object());
CHECK(j_const.value("array", json({10, 100})) == json({1, 2, 3}));
}
......@@ -298,7 +298,7 @@ TEST_CASE("element access 2")
CHECK(j.value("/string"_json_pointer, std::string("bar")) == "hello world");
CHECK(j.value("/floating"_json_pointer, 12.34) == Approx(42.23));
CHECK(j.value("/floating"_json_pointer, 12) == 42);
CHECK(j.value("/object"_json_pointer, json({{"foo", "bar"}})) == json(json::object()));
CHECK(j.value("/object"_json_pointer, json({{"foo", "bar"}})) == json::object());
CHECK(j.value("/array"_json_pointer, json({10, 100})) == json({1, 2, 3}));
CHECK(j_const.value("/integer"_json_pointer, 2) == 1);
......@@ -310,7 +310,7 @@ TEST_CASE("element access 2")
CHECK(j_const.value("/string"_json_pointer, std::string("bar")) == "hello world");
CHECK(j_const.value("/floating"_json_pointer, 12.34) == Approx(42.23));
CHECK(j_const.value("/floating"_json_pointer, 12) == 42);
CHECK(j_const.value("/object"_json_pointer, json({{"foo", "bar"}})) == json(json::object()));
CHECK(j_const.value("/object"_json_pointer, json({{"foo", "bar"}})) == json::object());
CHECK(j_const.value("/array"_json_pointer, json({10, 100})) == json({1, 2, 3}));
}
......@@ -435,7 +435,7 @@ TEST_CASE("element access 2")
CHECK(j["floating"] == json(42.23));
CHECK(j[json::object_t::key_type("floating")] == j["floating"]);
CHECK(j["object"] == json(json::object()));
CHECK(j["object"] == json::object());
CHECK(j[json::object_t::key_type("object")] == j["object"]);
CHECK(j["array"] == json({1, 2, 3}));
......@@ -456,7 +456,7 @@ TEST_CASE("element access 2")
CHECK(j_const["floating"] == json(42.23));
CHECK(j_const[json::object_t::key_type("floating")] == j["floating"]);
CHECK(j_const["object"] == json(json::object()));
CHECK(j_const["object"] == json::object());
CHECK(j_const[json::object_t::key_type("object")] == j["object"]);
CHECK(j_const["array"] == json({1, 2, 3}));
......
......@@ -203,7 +203,7 @@ TEST_CASE("MessagePack")
// check individual bytes
CHECK(result[0] == 0xcd);
uint16_t restored = static_cast<uint8_t>(result[1]) * 256 + static_cast<uint8_t>(result[2]);
uint16_t restored = static_cast<uint16_t>(static_cast<uint8_t>(result[1]) * 256 + static_cast<uint8_t>(result[2]));
CHECK(restored == i);
// roundtrip
......@@ -242,10 +242,10 @@ TEST_CASE("MessagePack")
// check individual bytes
CHECK(result[0] == 0xce);
uint32_t restored = static_cast<uint32_t>((static_cast<uint32_t>(result[1]) << 030) +
uint32_t restored = (static_cast<uint32_t>(result[1]) << 030) +
(static_cast<uint32_t>(result[2]) << 020) +
(static_cast<uint32_t>(result[3]) << 010) +
static_cast<uint32_t>(result[4]));
static_cast<uint32_t>(result[4]);
CHECK(restored == i);
// roundtrip
......@@ -288,14 +288,14 @@ TEST_CASE("MessagePack")
// check individual bytes
CHECK(result[0] == 0xcf);
uint64_t restored = static_cast<uint64_t>((static_cast<uint64_t>(result[1]) << 070) +
uint64_t restored = (static_cast<uint64_t>(result[1]) << 070) +
(static_cast<uint64_t>(result[2]) << 060) +
(static_cast<uint64_t>(result[3]) << 050) +
(static_cast<uint64_t>(result[4]) << 040) +
(static_cast<uint64_t>(result[5]) << 030) +
(static_cast<uint64_t>(result[6]) << 020) +
(static_cast<uint64_t>(result[7]) << 010) +
static_cast<uint64_t>(result[8]));
static_cast<uint64_t>(result[8]);
CHECK(restored == i);
// roundtrip
......@@ -415,10 +415,10 @@ TEST_CASE("MessagePack")
// check individual bytes
CHECK(result[0] == 0xd2);
uint32_t restored = static_cast<uint32_t>((static_cast<uint32_t>(result[1]) << 030) +
uint32_t restored = (static_cast<uint32_t>(result[1]) << 030) +
(static_cast<uint32_t>(result[2]) << 020) +
(static_cast<uint32_t>(result[3]) << 010) +
static_cast<uint32_t>(result[4]));
static_cast<uint32_t>(result[4]);
CHECK(restored == i);
// roundtrip
......@@ -460,14 +460,14 @@ TEST_CASE("MessagePack")
// check individual bytes
CHECK(result[0] == 0xd3);
int64_t restored = static_cast<int64_t>((static_cast<int64_t>(result[1]) << 070) +
(static_cast<int64_t>(result[2]) << 060) +
(static_cast<int64_t>(result[3]) << 050) +
(static_cast<int64_t>(result[4]) << 040) +
(static_cast<int64_t>(result[5]) << 030) +
(static_cast<int64_t>(result[6]) << 020) +
(static_cast<int64_t>(result[7]) << 010) +
static_cast<int64_t>(result[8]));
int64_t restored = (static_cast<int64_t>(result[1]) << 070) +
(static_cast<int64_t>(result[2]) << 060) +
(static_cast<int64_t>(result[3]) << 050) +
(static_cast<int64_t>(result[4]) << 040) +
(static_cast<int64_t>(result[5]) << 030) +
(static_cast<int64_t>(result[6]) << 020) +
(static_cast<int64_t>(result[7]) << 010) +
static_cast<int64_t>(result[8]);
CHECK(restored == i);
// roundtrip
......@@ -564,7 +564,7 @@ TEST_CASE("MessagePack")
// check individual bytes
CHECK(result[0] == 0xcd);
uint16_t restored = static_cast<uint8_t>(result[1]) * 256 + static_cast<uint8_t>(result[2]);
uint16_t restored = static_cast<uint16_t>(static_cast<uint8_t>(result[1]) * 256 + static_cast<uint8_t>(result[2]));
CHECK(restored == i);
// roundtrip
......@@ -602,10 +602,10 @@ TEST_CASE("MessagePack")
// check individual bytes
CHECK(result[0] == 0xce);
uint32_t restored = static_cast<uint32_t>((static_cast<uint32_t>(result[1]) << 030) +
uint32_t restored = (static_cast<uint32_t>(result[1]) << 030) +
(static_cast<uint32_t>(result[2]) << 020) +
(static_cast<uint32_t>(result[3]) << 010) +
static_cast<uint32_t>(result[4]));
static_cast<uint32_t>(result[4]);
CHECK(restored == i);
// roundtrip
......@@ -647,14 +647,14 @@ TEST_CASE("MessagePack")
// check individual bytes
CHECK(result[0] == 0xcf);
uint64_t restored = static_cast<uint64_t>((static_cast<uint64_t>(result[1]) << 070) +
uint64_t restored = (static_cast<uint64_t>(result[1]) << 070) +
(static_cast<uint64_t>(result[2]) << 060) +
(static_cast<uint64_t>(result[3]) << 050) +
(static_cast<uint64_t>(result[4]) << 040) +
(static_cast<uint64_t>(result[5]) << 030) +
(static_cast<uint64_t>(result[6]) << 020) +
(static_cast<uint64_t>(result[7]) << 010) +
static_cast<uint64_t>(result[8]));
static_cast<uint64_t>(result[8]);
CHECK(restored == i);
// roundtrip
......
......@@ -412,17 +412,17 @@ TEST_CASE("regression tests")
class CommaDecimalSeparator : public std::numpunct<char>
{
protected:
char do_decimal_point() const
char do_decimal_point() const override
{
return ',';
}
char do_thousands_sep() const
char do_thousands_sep() const override
{
return '.';
}
std::string do_grouping() const
std::string do_grouping() const override
{
return "\03";
}
......@@ -755,7 +755,7 @@ TEST_CASE("regression tests")
};
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");
"[json.exception.parse_error.113] parse error at 2: expected a CBOR string; last byte: 0x98");
// related test case: nonempty UTF-8 string (indefinite length)
std::vector<uint8_t> vec1 {0x7f, 0x61, 0x61};
......@@ -808,7 +808,7 @@ TEST_CASE("regression tests")
};
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");
"[json.exception.parse_error.113] parse error at 13: expected a CBOR string; last byte: 0xb4");
// related test case: double-precision
std::vector<uint8_t> vec2
......@@ -822,7 +822,7 @@ TEST_CASE("regression tests")
};
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");
"[json.exception.parse_error.113] parse error at 13: expected a CBOR string; last byte: 0xb4");
}
SECTION("issue #452 - Heap-buffer-overflow (OSS-Fuzz issue 585)")
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment