🚑 fixed bugs detected by AFL-Fuzz
This commit is contained in:
parent
6e129fbfb7
commit
acb7e0558d
24 changed files with 194 additions and 0 deletions
57
src/json.hpp
57
src/json.hpp
|
@ -6835,6 +6835,44 @@ class basic_json
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
@brief checks if given lengths do not exceed the size of a given vector
|
||||||
|
|
||||||
|
To secure the access to the byte vector during CBOR/MessagePack
|
||||||
|
deserialization, bytes are copied from the vector into buffers. This
|
||||||
|
function checks if the number of bytes to copy (@a len) does not exceed the
|
||||||
|
size @s size of the vector. Additionally, an @a offset is given from where
|
||||||
|
to start reading the bytes.
|
||||||
|
|
||||||
|
This function checks whether reading the bytes is safe; that is, offset is a
|
||||||
|
valid index in the vector, offset+len
|
||||||
|
|
||||||
|
@param[in] size size of the byte vector
|
||||||
|
@param[in] len number of bytes to read
|
||||||
|
@param[in] offset offset where to start reading
|
||||||
|
|
||||||
|
vec: x x x x x X X X X X
|
||||||
|
^ ^ ^
|
||||||
|
0 offset len
|
||||||
|
|
||||||
|
@throws out_of_range if `len > v.size()`
|
||||||
|
*/
|
||||||
|
static void check_length(const size_t size, const size_t len, const size_t offset)
|
||||||
|
{
|
||||||
|
// simple case: requested length is greater than the vector's length
|
||||||
|
if (len > size or offset > size)
|
||||||
|
{
|
||||||
|
throw std::out_of_range("len out of range");
|
||||||
|
}
|
||||||
|
|
||||||
|
// second case: adding offset would result in overflow
|
||||||
|
if ((size > (std::numeric_limits<size_t>::max() - offset)))
|
||||||
|
{
|
||||||
|
throw std::out_of_range("len+offset out of range");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@brief create a JSON value from a given MessagePack vector
|
@brief create a JSON value from a given MessagePack vector
|
||||||
|
|
||||||
|
@ -6886,6 +6924,7 @@ class basic_json
|
||||||
const size_t len = v[current_idx] & 0x1f;
|
const size_t len = v[current_idx] & 0x1f;
|
||||||
const size_t offset = current_idx + 1;
|
const size_t offset = current_idx + 1;
|
||||||
idx += len; // skip content bytes
|
idx += len; // skip content bytes
|
||||||
|
check_length(v.size(), len, offset);
|
||||||
return std::string(reinterpret_cast<const char*>(v.data()) + offset, len);
|
return std::string(reinterpret_cast<const char*>(v.data()) + offset, len);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6989,6 +7028,7 @@ class basic_json
|
||||||
const auto len = static_cast<size_t>(get_from_vector<uint8_t>(v, current_idx));
|
const auto len = static_cast<size_t>(get_from_vector<uint8_t>(v, current_idx));
|
||||||
const size_t offset = current_idx + 2;
|
const size_t offset = current_idx + 2;
|
||||||
idx += len + 1; // skip size byte + content bytes
|
idx += len + 1; // skip size byte + content bytes
|
||||||
|
check_length(v.size(), len, offset);
|
||||||
return std::string(reinterpret_cast<const char*>(v.data()) + offset, len);
|
return std::string(reinterpret_cast<const char*>(v.data()) + offset, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6997,6 +7037,7 @@ class basic_json
|
||||||
const auto len = static_cast<size_t>(get_from_vector<uint16_t>(v, current_idx));
|
const auto len = static_cast<size_t>(get_from_vector<uint16_t>(v, current_idx));
|
||||||
const size_t offset = current_idx + 3;
|
const size_t offset = current_idx + 3;
|
||||||
idx += len + 2; // skip 2 size bytes + content bytes
|
idx += len + 2; // skip 2 size bytes + content bytes
|
||||||
|
check_length(v.size(), len, offset);
|
||||||
return std::string(reinterpret_cast<const char*>(v.data()) + offset, len);
|
return std::string(reinterpret_cast<const char*>(v.data()) + offset, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7005,6 +7046,7 @@ class basic_json
|
||||||
const auto len = static_cast<size_t>(get_from_vector<uint32_t>(v, current_idx));
|
const auto len = static_cast<size_t>(get_from_vector<uint32_t>(v, current_idx));
|
||||||
const size_t offset = current_idx + 5;
|
const size_t offset = current_idx + 5;
|
||||||
idx += len + 4; // skip 4 size bytes + content bytes
|
idx += len + 4; // skip 4 size bytes + content bytes
|
||||||
|
check_length(v.size(), len, offset);
|
||||||
return std::string(reinterpret_cast<const char*>(v.data()) + offset, len);
|
return std::string(reinterpret_cast<const char*>(v.data()) + offset, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7223,6 +7265,7 @@ class basic_json
|
||||||
const auto len = static_cast<size_t>(v[current_idx] - 0x60);
|
const auto len = static_cast<size_t>(v[current_idx] - 0x60);
|
||||||
const size_t offset = current_idx + 1;
|
const size_t offset = current_idx + 1;
|
||||||
idx += len; // skip content bytes
|
idx += len; // skip content bytes
|
||||||
|
check_length(v.size(), len, offset);
|
||||||
return std::string(reinterpret_cast<const char*>(v.data()) + offset, len);
|
return std::string(reinterpret_cast<const char*>(v.data()) + offset, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7231,6 +7274,7 @@ class basic_json
|
||||||
const auto len = static_cast<size_t>(get_from_vector<uint8_t>(v, current_idx));
|
const auto len = static_cast<size_t>(get_from_vector<uint8_t>(v, current_idx));
|
||||||
const size_t offset = current_idx + 2;
|
const size_t offset = current_idx + 2;
|
||||||
idx += len + 1; // skip size byte + content bytes
|
idx += len + 1; // skip size byte + content bytes
|
||||||
|
check_length(v.size(), len, offset);
|
||||||
return std::string(reinterpret_cast<const char*>(v.data()) + offset, len);
|
return std::string(reinterpret_cast<const char*>(v.data()) + offset, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7239,6 +7283,7 @@ class basic_json
|
||||||
const auto len = static_cast<size_t>(get_from_vector<uint16_t>(v, current_idx));
|
const auto len = static_cast<size_t>(get_from_vector<uint16_t>(v, current_idx));
|
||||||
const size_t offset = current_idx + 3;
|
const size_t offset = current_idx + 3;
|
||||||
idx += len + 2; // skip 2 size bytes + content bytes
|
idx += len + 2; // skip 2 size bytes + content bytes
|
||||||
|
check_length(v.size(), len, offset);
|
||||||
return std::string(reinterpret_cast<const char*>(v.data()) + offset, len);
|
return std::string(reinterpret_cast<const char*>(v.data()) + offset, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7247,6 +7292,7 @@ class basic_json
|
||||||
const auto len = static_cast<size_t>(get_from_vector<uint32_t>(v, current_idx));
|
const auto len = static_cast<size_t>(get_from_vector<uint32_t>(v, current_idx));
|
||||||
const size_t offset = current_idx + 5;
|
const size_t offset = current_idx + 5;
|
||||||
idx += len + 4; // skip 4 size bytes + content bytes
|
idx += len + 4; // skip 4 size bytes + content bytes
|
||||||
|
check_length(v.size(), len, offset);
|
||||||
return std::string(reinterpret_cast<const char*>(v.data()) + offset, len);
|
return std::string(reinterpret_cast<const char*>(v.data()) + offset, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7255,6 +7301,7 @@ class basic_json
|
||||||
const auto len = static_cast<size_t>(get_from_vector<uint64_t>(v, current_idx));
|
const auto len = static_cast<size_t>(get_from_vector<uint64_t>(v, current_idx));
|
||||||
const size_t offset = current_idx + 9;
|
const size_t offset = current_idx + 9;
|
||||||
idx += len + 8; // skip 8 size bytes + content bytes
|
idx += len + 8; // skip 8 size bytes + content bytes
|
||||||
|
check_length(v.size(), len, offset);
|
||||||
return std::string(reinterpret_cast<const char*>(v.data()) + offset, len);
|
return std::string(reinterpret_cast<const char*>(v.data()) + offset, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7595,6 +7642,11 @@ class basic_json
|
||||||
*/
|
*/
|
||||||
static basic_json from_msgpack(const std::vector<uint8_t>& v)
|
static basic_json from_msgpack(const std::vector<uint8_t>& v)
|
||||||
{
|
{
|
||||||
|
if (v.empty())
|
||||||
|
{
|
||||||
|
throw std::invalid_argument("empty vector");
|
||||||
|
}
|
||||||
|
|
||||||
size_t i = 0;
|
size_t i = 0;
|
||||||
return from_msgpack_internal(v, i);
|
return from_msgpack_internal(v, i);
|
||||||
}
|
}
|
||||||
|
@ -7652,6 +7704,11 @@ class basic_json
|
||||||
*/
|
*/
|
||||||
static basic_json from_cbor(const std::vector<uint8_t>& v)
|
static basic_json from_cbor(const std::vector<uint8_t>& v)
|
||||||
{
|
{
|
||||||
|
if (v.empty())
|
||||||
|
{
|
||||||
|
throw std::invalid_argument("empty vector");
|
||||||
|
}
|
||||||
|
|
||||||
size_t i = 0;
|
size_t i = 0;
|
||||||
return from_cbor_internal(v, i);
|
return from_cbor_internal(v, i);
|
||||||
}
|
}
|
||||||
|
|
|
@ -6835,6 +6835,44 @@ class basic_json
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
@brief checks if given lengths do not exceed the size of a given vector
|
||||||
|
|
||||||
|
To secure the access to the byte vector during CBOR/MessagePack
|
||||||
|
deserialization, bytes are copied from the vector into buffers. This
|
||||||
|
function checks if the number of bytes to copy (@a len) does not exceed the
|
||||||
|
size @s size of the vector. Additionally, an @a offset is given from where
|
||||||
|
to start reading the bytes.
|
||||||
|
|
||||||
|
This function checks whether reading the bytes is safe; that is, offset is a
|
||||||
|
valid index in the vector, offset+len
|
||||||
|
|
||||||
|
@param[in] size size of the byte vector
|
||||||
|
@param[in] len number of bytes to read
|
||||||
|
@param[in] offset offset where to start reading
|
||||||
|
|
||||||
|
vec: x x x x x X X X X X
|
||||||
|
^ ^ ^
|
||||||
|
0 offset len
|
||||||
|
|
||||||
|
@throws out_of_range if `len > v.size()`
|
||||||
|
*/
|
||||||
|
static void check_length(const size_t size, const size_t len, const size_t offset)
|
||||||
|
{
|
||||||
|
// simple case: requested length is greater than the vector's length
|
||||||
|
if (len > size or offset > size)
|
||||||
|
{
|
||||||
|
throw std::out_of_range("len out of range");
|
||||||
|
}
|
||||||
|
|
||||||
|
// second case: adding offset would result in overflow
|
||||||
|
if ((size > (std::numeric_limits<size_t>::max() - offset)))
|
||||||
|
{
|
||||||
|
throw std::out_of_range("len+offset out of range");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@brief create a JSON value from a given MessagePack vector
|
@brief create a JSON value from a given MessagePack vector
|
||||||
|
|
||||||
|
@ -6886,6 +6924,7 @@ class basic_json
|
||||||
const size_t len = v[current_idx] & 0x1f;
|
const size_t len = v[current_idx] & 0x1f;
|
||||||
const size_t offset = current_idx + 1;
|
const size_t offset = current_idx + 1;
|
||||||
idx += len; // skip content bytes
|
idx += len; // skip content bytes
|
||||||
|
check_length(v.size(), len, offset);
|
||||||
return std::string(reinterpret_cast<const char*>(v.data()) + offset, len);
|
return std::string(reinterpret_cast<const char*>(v.data()) + offset, len);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6989,6 +7028,7 @@ class basic_json
|
||||||
const auto len = static_cast<size_t>(get_from_vector<uint8_t>(v, current_idx));
|
const auto len = static_cast<size_t>(get_from_vector<uint8_t>(v, current_idx));
|
||||||
const size_t offset = current_idx + 2;
|
const size_t offset = current_idx + 2;
|
||||||
idx += len + 1; // skip size byte + content bytes
|
idx += len + 1; // skip size byte + content bytes
|
||||||
|
check_length(v.size(), len, offset);
|
||||||
return std::string(reinterpret_cast<const char*>(v.data()) + offset, len);
|
return std::string(reinterpret_cast<const char*>(v.data()) + offset, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6997,6 +7037,7 @@ class basic_json
|
||||||
const auto len = static_cast<size_t>(get_from_vector<uint16_t>(v, current_idx));
|
const auto len = static_cast<size_t>(get_from_vector<uint16_t>(v, current_idx));
|
||||||
const size_t offset = current_idx + 3;
|
const size_t offset = current_idx + 3;
|
||||||
idx += len + 2; // skip 2 size bytes + content bytes
|
idx += len + 2; // skip 2 size bytes + content bytes
|
||||||
|
check_length(v.size(), len, offset);
|
||||||
return std::string(reinterpret_cast<const char*>(v.data()) + offset, len);
|
return std::string(reinterpret_cast<const char*>(v.data()) + offset, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7005,6 +7046,7 @@ class basic_json
|
||||||
const auto len = static_cast<size_t>(get_from_vector<uint32_t>(v, current_idx));
|
const auto len = static_cast<size_t>(get_from_vector<uint32_t>(v, current_idx));
|
||||||
const size_t offset = current_idx + 5;
|
const size_t offset = current_idx + 5;
|
||||||
idx += len + 4; // skip 4 size bytes + content bytes
|
idx += len + 4; // skip 4 size bytes + content bytes
|
||||||
|
check_length(v.size(), len, offset);
|
||||||
return std::string(reinterpret_cast<const char*>(v.data()) + offset, len);
|
return std::string(reinterpret_cast<const char*>(v.data()) + offset, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7223,6 +7265,7 @@ class basic_json
|
||||||
const auto len = static_cast<size_t>(v[current_idx] - 0x60);
|
const auto len = static_cast<size_t>(v[current_idx] - 0x60);
|
||||||
const size_t offset = current_idx + 1;
|
const size_t offset = current_idx + 1;
|
||||||
idx += len; // skip content bytes
|
idx += len; // skip content bytes
|
||||||
|
check_length(v.size(), len, offset);
|
||||||
return std::string(reinterpret_cast<const char*>(v.data()) + offset, len);
|
return std::string(reinterpret_cast<const char*>(v.data()) + offset, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7231,6 +7274,7 @@ class basic_json
|
||||||
const auto len = static_cast<size_t>(get_from_vector<uint8_t>(v, current_idx));
|
const auto len = static_cast<size_t>(get_from_vector<uint8_t>(v, current_idx));
|
||||||
const size_t offset = current_idx + 2;
|
const size_t offset = current_idx + 2;
|
||||||
idx += len + 1; // skip size byte + content bytes
|
idx += len + 1; // skip size byte + content bytes
|
||||||
|
check_length(v.size(), len, offset);
|
||||||
return std::string(reinterpret_cast<const char*>(v.data()) + offset, len);
|
return std::string(reinterpret_cast<const char*>(v.data()) + offset, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7239,6 +7283,7 @@ class basic_json
|
||||||
const auto len = static_cast<size_t>(get_from_vector<uint16_t>(v, current_idx));
|
const auto len = static_cast<size_t>(get_from_vector<uint16_t>(v, current_idx));
|
||||||
const size_t offset = current_idx + 3;
|
const size_t offset = current_idx + 3;
|
||||||
idx += len + 2; // skip 2 size bytes + content bytes
|
idx += len + 2; // skip 2 size bytes + content bytes
|
||||||
|
check_length(v.size(), len, offset);
|
||||||
return std::string(reinterpret_cast<const char*>(v.data()) + offset, len);
|
return std::string(reinterpret_cast<const char*>(v.data()) + offset, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7247,6 +7292,7 @@ class basic_json
|
||||||
const auto len = static_cast<size_t>(get_from_vector<uint32_t>(v, current_idx));
|
const auto len = static_cast<size_t>(get_from_vector<uint32_t>(v, current_idx));
|
||||||
const size_t offset = current_idx + 5;
|
const size_t offset = current_idx + 5;
|
||||||
idx += len + 4; // skip 4 size bytes + content bytes
|
idx += len + 4; // skip 4 size bytes + content bytes
|
||||||
|
check_length(v.size(), len, offset);
|
||||||
return std::string(reinterpret_cast<const char*>(v.data()) + offset, len);
|
return std::string(reinterpret_cast<const char*>(v.data()) + offset, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7255,6 +7301,7 @@ class basic_json
|
||||||
const auto len = static_cast<size_t>(get_from_vector<uint64_t>(v, current_idx));
|
const auto len = static_cast<size_t>(get_from_vector<uint64_t>(v, current_idx));
|
||||||
const size_t offset = current_idx + 9;
|
const size_t offset = current_idx + 9;
|
||||||
idx += len + 8; // skip 8 size bytes + content bytes
|
idx += len + 8; // skip 8 size bytes + content bytes
|
||||||
|
check_length(v.size(), len, offset);
|
||||||
return std::string(reinterpret_cast<const char*>(v.data()) + offset, len);
|
return std::string(reinterpret_cast<const char*>(v.data()) + offset, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7595,6 +7642,11 @@ class basic_json
|
||||||
*/
|
*/
|
||||||
static basic_json from_msgpack(const std::vector<uint8_t>& v)
|
static basic_json from_msgpack(const std::vector<uint8_t>& v)
|
||||||
{
|
{
|
||||||
|
if (v.empty())
|
||||||
|
{
|
||||||
|
throw std::invalid_argument("empty vector");
|
||||||
|
}
|
||||||
|
|
||||||
size_t i = 0;
|
size_t i = 0;
|
||||||
return from_msgpack_internal(v, i);
|
return from_msgpack_internal(v, i);
|
||||||
}
|
}
|
||||||
|
@ -7652,6 +7704,11 @@ class basic_json
|
||||||
*/
|
*/
|
||||||
static basic_json from_cbor(const std::vector<uint8_t>& v)
|
static basic_json from_cbor(const std::vector<uint8_t>& v)
|
||||||
{
|
{
|
||||||
|
if (v.empty())
|
||||||
|
{
|
||||||
|
throw std::invalid_argument("empty vector");
|
||||||
|
}
|
||||||
|
|
||||||
size_t i = 0;
|
size_t i = 0;
|
||||||
return from_cbor_internal(v, i);
|
return from_cbor_internal(v, i);
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
亄<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1 @@
|
||||||
|
”{˙˙˙˙˙˙˙˙˙’˙˙˙˙˙˙˙˙úúúúúúúúúúúúetú
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -1186,6 +1186,84 @@ TEST_CASE("single CBOR roundtrip")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_CASE("CBOR regressions")
|
||||||
|
{
|
||||||
|
SECTION("fuzz test results")
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
The following test cases were found during a two-day session with
|
||||||
|
AFL-Fuzz. As a result, empty byte vectors and excessive lengths are
|
||||||
|
detected.
|
||||||
|
*/
|
||||||
|
for (std::string filename :
|
||||||
|
{
|
||||||
|
"test/data/cbor_regression/id:000000,sig:06,src:000223+000677,op:splice,rep:2",
|
||||||
|
"test/data/cbor_regression/id:000000,sig:06,src:000787,op:havoc,rep:8",
|
||||||
|
"test/data/cbor_regression/id:000000,sig:06,src:000833,op:havoc,rep:32",
|
||||||
|
"test/data/cbor_regression/id:000000,sig:06,src:000838,op:havoc,rep:64",
|
||||||
|
"test/data/cbor_regression/id:000000,sig:06,src:000846+001064,op:splice,rep:16",
|
||||||
|
"test/data/cbor_regression/id:000000,sig:06,src:000848,op:flip1,pos:0",
|
||||||
|
"test/data/cbor_regression/id:000000,sig:06,src:001435,op:havoc,rep:32",
|
||||||
|
"test/data/cbor_regression/id:000000,sig:06,src:001436,op:havoc,rep:4v",
|
||||||
|
"test/data/cbor_regression/id:000001,sig:06,src:000864+000903,op:splice,rep:2",
|
||||||
|
"test/data/cbor_regression/id:000001,sig:06,src:001310+001138,op:splice,rep:32",
|
||||||
|
"test/data/cbor_regression/id:000001,sig:06,src:001330+000569,op:splice,rep:64",
|
||||||
|
"test/data/cbor_regression/id:000001,sig:06,src:001413,op:havoc,rep:32",
|
||||||
|
"test/data/cbor_regression/id:000001,sig:06,src:001447,op:havoc,rep:4",
|
||||||
|
"test/data/cbor_regression/id:000001,sig:06,src:001465+000325,op:splice,rep:4",
|
||||||
|
"test/data/cbor_regression/id:000002,sig:06,src:000539,op:havoc,rep:8",
|
||||||
|
"test/data/cbor_regression/id:000002,sig:06,src:001301,op:havoc,rep:16",
|
||||||
|
"test/data/cbor_regression/id:000002,sig:06,src:001317+000850,op:splice,rep:8",
|
||||||
|
"test/data/cbor_regression/id:000002,sig:06,src:001382,op:havoc,rep:128",
|
||||||
|
"test/data/cbor_regression/id:000002,sig:06,src:001413+001036,op:splice,rep:4",
|
||||||
|
"test/data/cbor_regression/id:000003,sig:06,src:000846+000155,op:splice,rep:16",
|
||||||
|
"test/data/cbor_regression/id:000004,sig:06,src:001445,op:havoc,rep:128"
|
||||||
|
})
|
||||||
|
{
|
||||||
|
CAPTURE(filename);
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// parse CBOR file
|
||||||
|
std::ifstream f_cbor(filename, std::ios::binary);
|
||||||
|
std::vector<uint8_t> vec1(
|
||||||
|
(std::istreambuf_iterator<char>(f_cbor)),
|
||||||
|
std::istreambuf_iterator<char>());
|
||||||
|
json j1 = json::from_cbor(vec1);
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// step 2: round trip
|
||||||
|
std::vector<uint8_t> vec2 = json::to_cbor(j1);
|
||||||
|
|
||||||
|
// parse serialization
|
||||||
|
json j2 = json::from_cbor(vec2);
|
||||||
|
|
||||||
|
// deserializations must match
|
||||||
|
CHECK(j1 == j2);
|
||||||
|
}
|
||||||
|
catch (const std::invalid_argument&)
|
||||||
|
{
|
||||||
|
// parsing a CBOR serialization must not fail
|
||||||
|
CHECK(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (const std::invalid_argument&)
|
||||||
|
{
|
||||||
|
// parse errors are ok, because input may be random bytes
|
||||||
|
}
|
||||||
|
catch (const std::out_of_range&)
|
||||||
|
{
|
||||||
|
// parse errors are ok, because input may be random bytes
|
||||||
|
}
|
||||||
|
catch (const std::domain_error&)
|
||||||
|
{
|
||||||
|
// parse errors are ok, because input may be random bytes
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
TEST_CASE("CBOR roundtrips", "[hide]")
|
TEST_CASE("CBOR roundtrips", "[hide]")
|
||||||
{
|
{
|
||||||
SECTION("input from flynn")
|
SECTION("input from flynn")
|
||||||
|
|
Loading…
Reference in a new issue