improved error messages for binary formats #1288

This commit is the equivalent of #1282 for CBOR, MessagePack, and UBJSON.
This commit is contained in:
Niels Lohmann 2018-10-17 12:15:58 +02:00
parent dd672939a0
commit dbb0b63187
No known key found for this signature in database
GPG key ID: 7F3CEA63AE251B69
7 changed files with 364 additions and 282 deletions

View file

@ -100,7 +100,8 @@ class binary_reader
if (JSON_UNLIKELY(current != std::char_traits<char>::eof())) if (JSON_UNLIKELY(current != std::char_traits<char>::eof()))
{ {
return sax->parse_error(chars_read, get_token_string(), parse_error::create(110, chars_read, "expected end of input")); return sax->parse_error(chars_read, get_token_string(),
parse_error::create(110, chars_read, exception_message(format, "expected end of input; last byte: 0x" + get_token_string(), "value")));
} }
} }
@ -133,7 +134,7 @@ class binary_reader
{ {
// EOF // EOF
case std::char_traits<char>::eof(): case std::char_traits<char>::eof():
return unexpect_eof(); return unexpect_eof(input_format_t::cbor, "value");
// Integer 0x00..0x17 (0..23) // Integer 0x00..0x17 (0..23)
case 0x00: case 0x00:
@ -165,25 +166,25 @@ class binary_reader
case 0x18: // Unsigned integer (one-byte uint8_t follows) case 0x18: // Unsigned integer (one-byte uint8_t follows)
{ {
uint8_t number; uint8_t number;
return get_number(number) and sax->number_unsigned(number); return get_number(input_format_t::cbor, number) and sax->number_unsigned(number);
} }
case 0x19: // Unsigned integer (two-byte uint16_t follows) case 0x19: // Unsigned integer (two-byte uint16_t follows)
{ {
uint16_t number; uint16_t number;
return get_number(number) and sax->number_unsigned(number); return get_number(input_format_t::cbor, number) and sax->number_unsigned(number);
} }
case 0x1A: // Unsigned integer (four-byte uint32_t follows) case 0x1A: // Unsigned integer (four-byte uint32_t follows)
{ {
uint32_t number; uint32_t number;
return get_number(number) and sax->number_unsigned(number); return get_number(input_format_t::cbor, number) and sax->number_unsigned(number);
} }
case 0x1B: // Unsigned integer (eight-byte uint64_t follows) case 0x1B: // Unsigned integer (eight-byte uint64_t follows)
{ {
uint64_t number; uint64_t number;
return get_number(number) and sax->number_unsigned(number); return get_number(input_format_t::cbor, number) and sax->number_unsigned(number);
} }
// Negative integer -1-0x00..-1-0x17 (-1..-24) // Negative integer -1-0x00..-1-0x17 (-1..-24)
@ -216,25 +217,25 @@ class binary_reader
case 0x38: // Negative integer (one-byte uint8_t follows) case 0x38: // Negative integer (one-byte uint8_t follows)
{ {
uint8_t number; uint8_t number;
return get_number(number) and sax->number_integer(static_cast<number_integer_t>(-1) - number); return get_number(input_format_t::cbor, number) and sax->number_integer(static_cast<number_integer_t>(-1) - number);
} }
case 0x39: // Negative integer -1-n (two-byte uint16_t follows) case 0x39: // Negative integer -1-n (two-byte uint16_t follows)
{ {
uint16_t number; uint16_t number;
return get_number(number) and sax->number_integer(static_cast<number_integer_t>(-1) - number); return get_number(input_format_t::cbor, number) and sax->number_integer(static_cast<number_integer_t>(-1) - number);
} }
case 0x3A: // Negative integer -1-n (four-byte uint32_t follows) case 0x3A: // Negative integer -1-n (four-byte uint32_t follows)
{ {
uint32_t number; uint32_t number;
return get_number(number) and sax->number_integer(static_cast<number_integer_t>(-1) - number); return get_number(input_format_t::cbor, number) and sax->number_integer(static_cast<number_integer_t>(-1) - number);
} }
case 0x3B: // Negative integer -1-n (eight-byte uint64_t follows) case 0x3B: // Negative integer -1-n (eight-byte uint64_t follows)
{ {
uint64_t number; uint64_t number;
return get_number(number) and sax->number_integer(static_cast<number_integer_t>(-1) return get_number(input_format_t::cbor, number) and sax->number_integer(static_cast<number_integer_t>(-1)
- static_cast<number_integer_t>(number)); - static_cast<number_integer_t>(number));
} }
@ -303,25 +304,25 @@ class binary_reader
case 0x98: // array (one-byte uint8_t for n follows) case 0x98: // array (one-byte uint8_t for n follows)
{ {
uint8_t len; uint8_t len;
return get_number(len) and get_cbor_array(static_cast<std::size_t>(len)); return get_number(input_format_t::cbor, len) and get_cbor_array(static_cast<std::size_t>(len));
} }
case 0x99: // array (two-byte uint16_t for n follow) case 0x99: // array (two-byte uint16_t for n follow)
{ {
uint16_t len; uint16_t len;
return get_number(len) and get_cbor_array(static_cast<std::size_t>(len)); return get_number(input_format_t::cbor, len) and get_cbor_array(static_cast<std::size_t>(len));
} }
case 0x9A: // array (four-byte uint32_t for n follow) case 0x9A: // array (four-byte uint32_t for n follow)
{ {
uint32_t len; uint32_t len;
return get_number(len) and get_cbor_array(static_cast<std::size_t>(len)); return get_number(input_format_t::cbor, len) and get_cbor_array(static_cast<std::size_t>(len));
} }
case 0x9B: // array (eight-byte uint64_t for n follow) case 0x9B: // array (eight-byte uint64_t for n follow)
{ {
uint64_t len; uint64_t len;
return get_number(len) and get_cbor_array(static_cast<std::size_t>(len)); return get_number(input_format_t::cbor, len) and get_cbor_array(static_cast<std::size_t>(len));
} }
case 0x9F: // array (indefinite length) case 0x9F: // array (indefinite length)
@ -357,25 +358,25 @@ class binary_reader
case 0xB8: // map (one-byte uint8_t for n follows) case 0xB8: // map (one-byte uint8_t for n follows)
{ {
uint8_t len; uint8_t len;
return get_number(len) and get_cbor_object(static_cast<std::size_t>(len)); return get_number(input_format_t::cbor, len) and get_cbor_object(static_cast<std::size_t>(len));
} }
case 0xB9: // map (two-byte uint16_t for n follow) case 0xB9: // map (two-byte uint16_t for n follow)
{ {
uint16_t len; uint16_t len;
return get_number(len) and get_cbor_object(static_cast<std::size_t>(len)); return get_number(input_format_t::cbor, len) and get_cbor_object(static_cast<std::size_t>(len));
} }
case 0xBA: // map (four-byte uint32_t for n follow) case 0xBA: // map (four-byte uint32_t for n follow)
{ {
uint32_t len; uint32_t len;
return get_number(len) and get_cbor_object(static_cast<std::size_t>(len)); return get_number(input_format_t::cbor, len) and get_cbor_object(static_cast<std::size_t>(len));
} }
case 0xBB: // map (eight-byte uint64_t for n follow) case 0xBB: // map (eight-byte uint64_t for n follow)
{ {
uint64_t len; uint64_t len;
return get_number(len) and get_cbor_object(static_cast<std::size_t>(len)); return get_number(input_format_t::cbor, len) and get_cbor_object(static_cast<std::size_t>(len));
} }
case 0xBF: // map (indefinite length) case 0xBF: // map (indefinite length)
@ -393,12 +394,12 @@ class binary_reader
case 0xF9: // Half-Precision Float (two-byte IEEE 754) case 0xF9: // Half-Precision Float (two-byte IEEE 754)
{ {
const int byte1_raw = get(); const int byte1_raw = get();
if (JSON_UNLIKELY(not unexpect_eof())) if (JSON_UNLIKELY(not unexpect_eof(input_format_t::cbor, "number")))
{ {
return false; return false;
} }
const int byte2_raw = get(); const int byte2_raw = get();
if (JSON_UNLIKELY(not unexpect_eof())) if (JSON_UNLIKELY(not unexpect_eof(input_format_t::cbor, "number")))
{ {
return false; return false;
} }
@ -441,19 +442,19 @@ class binary_reader
case 0xFA: // Single-Precision Float (four-byte IEEE 754) case 0xFA: // Single-Precision Float (four-byte IEEE 754)
{ {
float number; float number;
return get_number(number) and sax->number_float(static_cast<number_float_t>(number), ""); return get_number(input_format_t::cbor, number) and sax->number_float(static_cast<number_float_t>(number), "");
} }
case 0xFB: // Double-Precision Float (eight-byte IEEE 754) case 0xFB: // Double-Precision Float (eight-byte IEEE 754)
{ {
double number; double number;
return get_number(number) and sax->number_float(static_cast<number_float_t>(number), ""); return get_number(input_format_t::cbor, number) and sax->number_float(static_cast<number_float_t>(number), "");
} }
default: // anything else (0xFF is handled inside the other types) default: // anything else (0xFF is handled inside the other types)
{ {
auto last_token = get_token_string(); auto last_token = get_token_string();
return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, "error reading CBOR; last byte: 0x" + last_token)); return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::cbor, "invalid byte: 0x" + last_token, "value")));
} }
} }
} }
@ -467,7 +468,7 @@ class binary_reader
{ {
// EOF // EOF
case std::char_traits<char>::eof(): case std::char_traits<char>::eof():
return unexpect_eof(); return unexpect_eof(input_format_t::msgpack, "value");
// positive fixint // positive fixint
case 0x00: case 0x00:
@ -688,61 +689,61 @@ class binary_reader
case 0xCA: // float 32 case 0xCA: // float 32
{ {
float number; float number;
return get_number(number) and sax->number_float(static_cast<number_float_t>(number), ""); return get_number(input_format_t::msgpack, number) and sax->number_float(static_cast<number_float_t>(number), "");
} }
case 0xCB: // float 64 case 0xCB: // float 64
{ {
double number; double number;
return get_number(number) and sax->number_float(static_cast<number_float_t>(number), ""); return get_number(input_format_t::msgpack, number) and sax->number_float(static_cast<number_float_t>(number), "");
} }
case 0xCC: // uint 8 case 0xCC: // uint 8
{ {
uint8_t number; uint8_t number;
return get_number(number) and sax->number_unsigned(number); return get_number(input_format_t::msgpack, number) and sax->number_unsigned(number);
} }
case 0xCD: // uint 16 case 0xCD: // uint 16
{ {
uint16_t number; uint16_t number;
return get_number(number) and sax->number_unsigned(number); return get_number(input_format_t::msgpack, number) and sax->number_unsigned(number);
} }
case 0xCE: // uint 32 case 0xCE: // uint 32
{ {
uint32_t number; uint32_t number;
return get_number(number) and sax->number_unsigned(number); return get_number(input_format_t::msgpack, number) and sax->number_unsigned(number);
} }
case 0xCF: // uint 64 case 0xCF: // uint 64
{ {
uint64_t number; uint64_t number;
return get_number(number) and sax->number_unsigned(number); return get_number(input_format_t::msgpack, number) and sax->number_unsigned(number);
} }
case 0xD0: // int 8 case 0xD0: // int 8
{ {
int8_t number; int8_t number;
return get_number(number) and sax->number_integer(number); return get_number(input_format_t::msgpack, number) and sax->number_integer(number);
} }
case 0xD1: // int 16 case 0xD1: // int 16
{ {
int16_t number; int16_t number;
return get_number(number) and sax->number_integer(number); return get_number(input_format_t::msgpack, number) and sax->number_integer(number);
} }
case 0xD2: // int 32 case 0xD2: // int 32
{ {
int32_t number; int32_t number;
return get_number(number) and sax->number_integer(number); return get_number(input_format_t::msgpack, number) and sax->number_integer(number);
} }
case 0xD3: // int 64 case 0xD3: // int 64
{ {
int64_t number; int64_t number;
return get_number(number) and sax->number_integer(number); return get_number(input_format_t::msgpack, number) and sax->number_integer(number);
} }
case 0xD9: // str 8 case 0xD9: // str 8
@ -756,25 +757,25 @@ class binary_reader
case 0xDC: // array 16 case 0xDC: // array 16
{ {
uint16_t len; uint16_t len;
return get_number(len) and get_msgpack_array(static_cast<std::size_t>(len)); return get_number(input_format_t::msgpack, len) and get_msgpack_array(static_cast<std::size_t>(len));
} }
case 0xDD: // array 32 case 0xDD: // array 32
{ {
uint32_t len; uint32_t len;
return get_number(len) and get_msgpack_array(static_cast<std::size_t>(len)); return get_number(input_format_t::msgpack, len) and get_msgpack_array(static_cast<std::size_t>(len));
} }
case 0xDE: // map 16 case 0xDE: // map 16
{ {
uint16_t len; uint16_t len;
return get_number(len) and get_msgpack_object(static_cast<std::size_t>(len)); return get_number(input_format_t::msgpack, len) and get_msgpack_object(static_cast<std::size_t>(len));
} }
case 0xDF: // map 32 case 0xDF: // map 32
{ {
uint32_t len; uint32_t len;
return get_number(len) and get_msgpack_object(static_cast<std::size_t>(len)); return get_number(input_format_t::msgpack, len) and get_msgpack_object(static_cast<std::size_t>(len));
} }
// negative fixint // negative fixint
@ -815,7 +816,7 @@ class binary_reader
default: // anything else default: // anything else
{ {
auto last_token = get_token_string(); auto last_token = get_token_string();
return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, "error reading MessagePack; last byte: 0x" + last_token)); return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::msgpack, "invalid byte: 0x" + last_token, "value")));
} }
} }
} }
@ -865,6 +866,7 @@ class binary_reader
@brief read a number from the input @brief read a number from the input
@tparam NumberType the type of the number @tparam NumberType the type of the number
@param[in] format the current format (for diagnostics)
@param[out] result number of type @a NumberType @param[out] result number of type @a NumberType
@return whether conversion completed @return whether conversion completed
@ -874,14 +876,14 @@ class binary_reader
(big endian) and therefore need reordering on little endian systems. (big endian) and therefore need reordering on little endian systems.
*/ */
template<typename NumberType> template<typename NumberType>
bool get_number(NumberType& result) bool get_number(const input_format_t format, NumberType& result)
{ {
// step 1: read input into array with system's byte order // step 1: read input into array with system's byte order
std::array<uint8_t, sizeof(NumberType)> vec; std::array<uint8_t, sizeof(NumberType)> vec;
for (std::size_t i = 0; i < sizeof(NumberType); ++i) for (std::size_t i = 0; i < sizeof(NumberType); ++i)
{ {
get(); get();
if (JSON_UNLIKELY(not unexpect_eof())) if (JSON_UNLIKELY(not unexpect_eof(format, "number")))
{ {
return false; return false;
} }
@ -906,8 +908,9 @@ class binary_reader
@brief create a string by reading characters from the input @brief create a string by reading characters from the input
@tparam NumberType the type of the number @tparam NumberType the type of the number
@param[in] format the current format (for diagnostics)
@param[in] len number of characters to read @param[in] len number of characters to read
@param[out] string created by reading @a len bytes @param[out] result string created by reading @a len bytes
@return whether string creation completed @return whether string creation completed
@ -916,13 +919,13 @@ class binary_reader
the input before we run out of string memory. the input before we run out of string memory.
*/ */
template<typename NumberType> template<typename NumberType>
bool get_string(const NumberType len, string_t& result) bool get_string(const input_format_t format, const NumberType len, string_t& result)
{ {
bool success = true; bool success = true;
std::generate_n(std::back_inserter(result), len, [this, &success]() std::generate_n(std::back_inserter(result), len, [this, &success, &format]()
{ {
get(); get();
if (JSON_UNLIKELY(not unexpect_eof())) if (JSON_UNLIKELY(not unexpect_eof(format, "string")))
{ {
success = false; success = false;
} }
@ -944,7 +947,7 @@ class binary_reader
*/ */
bool get_cbor_string(string_t& result) bool get_cbor_string(string_t& result)
{ {
if (JSON_UNLIKELY(not unexpect_eof())) if (JSON_UNLIKELY(not unexpect_eof(input_format_t::cbor, "string")))
{ {
return false; return false;
} }
@ -977,31 +980,31 @@ class binary_reader
case 0x76: case 0x76:
case 0x77: case 0x77:
{ {
return get_string(current & 0x1F, result); return get_string(input_format_t::cbor, current & 0x1F, result);
} }
case 0x78: // UTF-8 string (one-byte uint8_t for n follows) case 0x78: // UTF-8 string (one-byte uint8_t for n follows)
{ {
uint8_t len; uint8_t len;
return get_number(len) and get_string(len, result); return get_number(input_format_t::cbor, len) and get_string(input_format_t::cbor, len, result);
} }
case 0x79: // UTF-8 string (two-byte uint16_t for n follow) case 0x79: // UTF-8 string (two-byte uint16_t for n follow)
{ {
uint16_t len; uint16_t len;
return get_number(len) and get_string(len, result); return get_number(input_format_t::cbor, len) and get_string(input_format_t::cbor, len, result);
} }
case 0x7A: // UTF-8 string (four-byte uint32_t for n follow) case 0x7A: // UTF-8 string (four-byte uint32_t for n follow)
{ {
uint32_t len; uint32_t len;
return get_number(len) and get_string(len, result); return get_number(input_format_t::cbor, len) and get_string(input_format_t::cbor, len, result);
} }
case 0x7B: // UTF-8 string (eight-byte uint64_t for n follow) case 0x7B: // UTF-8 string (eight-byte uint64_t for n follow)
{ {
uint64_t len; uint64_t len;
return get_number(len) and get_string(len, result); return get_number(input_format_t::cbor, len) and get_string(input_format_t::cbor, len, result);
} }
case 0x7F: // UTF-8 string (indefinite length) case 0x7F: // UTF-8 string (indefinite length)
@ -1021,7 +1024,7 @@ class binary_reader
default: default:
{ {
auto last_token = get_token_string(); auto last_token = get_token_string();
return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, "expected a CBOR string; last byte: 0x" + last_token)); return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format_t::cbor, "expected length specification (0x60-0x7B) or indefinite string type (0x7F); last byte: 0x" + last_token, "string")));
} }
} }
} }
@ -1124,7 +1127,7 @@ class binary_reader
*/ */
bool get_msgpack_string(string_t& result) bool get_msgpack_string(string_t& result)
{ {
if (JSON_UNLIKELY(not unexpect_eof())) if (JSON_UNLIKELY(not unexpect_eof(input_format_t::msgpack, "string")))
{ {
return false; return false;
} }
@ -1165,31 +1168,31 @@ class binary_reader
case 0xBE: case 0xBE:
case 0xBF: case 0xBF:
{ {
return get_string(current & 0x1F, result); return get_string(input_format_t::msgpack, current & 0x1F, result);
} }
case 0xD9: // str 8 case 0xD9: // str 8
{ {
uint8_t len; uint8_t len;
return get_number(len) and get_string(len, result); return get_number(input_format_t::msgpack, len) and get_string(input_format_t::msgpack, len, result);
} }
case 0xDA: // str 16 case 0xDA: // str 16
{ {
uint16_t len; uint16_t len;
return get_number(len) and get_string(len, result); return get_number(input_format_t::msgpack, len) and get_string(input_format_t::msgpack, len, result);
} }
case 0xDB: // str 32 case 0xDB: // str 32
{ {
uint32_t len; uint32_t len;
return get_number(len) and get_string(len, result); return get_number(input_format_t::msgpack, len) and get_string(input_format_t::msgpack, len, result);
} }
default: default:
{ {
auto last_token = get_token_string(); auto last_token = get_token_string();
return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, "expected a MessagePack string; last byte: 0x" + last_token)); return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format_t::msgpack, "expected length specification (0xA0-0xBF, 0xD9-0xDB); last byte: 0x" + last_token, "string")));
} }
} }
} }
@ -1267,7 +1270,7 @@ class binary_reader
get(); // TODO: may we ignore N here? get(); // TODO: may we ignore N here?
} }
if (JSON_UNLIKELY(not unexpect_eof())) if (JSON_UNLIKELY(not unexpect_eof(input_format_t::ubjson, "value")))
{ {
return false; return false;
} }
@ -1277,36 +1280,36 @@ class binary_reader
case 'U': case 'U':
{ {
uint8_t len; uint8_t len;
return get_number(len) and get_string(len, result); return get_number(input_format_t::ubjson, len) and get_string(input_format_t::ubjson, len, result);
} }
case 'i': case 'i':
{ {
int8_t len; int8_t len;
return get_number(len) and get_string(len, result); return get_number(input_format_t::ubjson, len) and get_string(input_format_t::ubjson, len, result);
} }
case 'I': case 'I':
{ {
int16_t len; int16_t len;
return get_number(len) and get_string(len, result); return get_number(input_format_t::ubjson, len) and get_string(input_format_t::ubjson, len, result);
} }
case 'l': case 'l':
{ {
int32_t len; int32_t len;
return get_number(len) and get_string(len, result); return get_number(input_format_t::ubjson, len) and get_string(input_format_t::ubjson, len, result);
} }
case 'L': case 'L':
{ {
int64_t len; int64_t len;
return get_number(len) and get_string(len, result); return get_number(input_format_t::ubjson, len) and get_string(input_format_t::ubjson, len, result);
} }
default: default:
auto last_token = get_token_string(); auto last_token = get_token_string();
return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, "expected a UBJSON string; last byte: 0x" + last_token)); return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format_t::ubjson, "expected length type specification (U, i, I, l, L); last byte: 0x" + last_token, "string")));
} }
} }
@ -1321,7 +1324,7 @@ class binary_reader
case 'U': case 'U':
{ {
uint8_t number; uint8_t number;
if (JSON_UNLIKELY(not get_number(number))) if (JSON_UNLIKELY(not get_number(input_format_t::ubjson, number)))
{ {
return false; return false;
} }
@ -1332,7 +1335,7 @@ class binary_reader
case 'i': case 'i':
{ {
int8_t number; int8_t number;
if (JSON_UNLIKELY(not get_number(number))) if (JSON_UNLIKELY(not get_number(input_format_t::ubjson, number)))
{ {
return false; return false;
} }
@ -1343,7 +1346,7 @@ class binary_reader
case 'I': case 'I':
{ {
int16_t number; int16_t number;
if (JSON_UNLIKELY(not get_number(number))) if (JSON_UNLIKELY(not get_number(input_format_t::ubjson, number)))
{ {
return false; return false;
} }
@ -1354,7 +1357,7 @@ class binary_reader
case 'l': case 'l':
{ {
int32_t number; int32_t number;
if (JSON_UNLIKELY(not get_number(number))) if (JSON_UNLIKELY(not get_number(input_format_t::ubjson, number)))
{ {
return false; return false;
} }
@ -1365,7 +1368,7 @@ class binary_reader
case 'L': case 'L':
{ {
int64_t number; int64_t number;
if (JSON_UNLIKELY(not get_number(number))) if (JSON_UNLIKELY(not get_number(input_format_t::ubjson, number)))
{ {
return false; return false;
} }
@ -1376,7 +1379,7 @@ class binary_reader
default: default:
{ {
auto last_token = get_token_string(); auto last_token = get_token_string();
return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, "byte after '#' must denote a number type; last byte: 0x" + last_token)); return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format_t::ubjson, "expected length type specification (U, i, I, l, L) after '#'; last byte: 0x" + last_token, "size")));
} }
} }
} }
@ -1401,7 +1404,7 @@ class binary_reader
if (current == '$') if (current == '$')
{ {
result.second = get(); // must not ignore 'N', because 'N' maybe the type result.second = get(); // must not ignore 'N', because 'N' maybe the type
if (JSON_UNLIKELY(not unexpect_eof())) if (JSON_UNLIKELY(not unexpect_eof(input_format_t::ubjson, "type")))
{ {
return false; return false;
} }
@ -1409,12 +1412,12 @@ class binary_reader
get_ignore_noop(); get_ignore_noop();
if (JSON_UNLIKELY(current != '#')) if (JSON_UNLIKELY(current != '#'))
{ {
if (JSON_UNLIKELY(not unexpect_eof())) if (JSON_UNLIKELY(not unexpect_eof(input_format_t::ubjson, "value")))
{ {
return false; return false;
} }
auto last_token = get_token_string(); auto last_token = get_token_string();
return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, "expected '#' after UBJSON type information; last byte: 0x" + last_token)); return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::ubjson, "expected '#' after type information; last byte: 0x" + last_token, "size")));
} }
return get_ubjson_size_value(result.first); return get_ubjson_size_value(result.first);
@ -1435,7 +1438,7 @@ class binary_reader
switch (prefix) switch (prefix)
{ {
case std::char_traits<char>::eof(): // EOF case std::char_traits<char>::eof(): // EOF
return unexpect_eof(); return unexpect_eof(input_format_t::ubjson, "value");
case 'T': // true case 'T': // true
return sax->boolean(true); return sax->boolean(true);
@ -1448,56 +1451,56 @@ class binary_reader
case 'U': case 'U':
{ {
uint8_t number; uint8_t number;
return get_number(number) and sax->number_unsigned(number); return get_number(input_format_t::ubjson, number) and sax->number_unsigned(number);
} }
case 'i': case 'i':
{ {
int8_t number; int8_t number;
return get_number(number) and sax->number_integer(number); return get_number(input_format_t::ubjson, number) and sax->number_integer(number);
} }
case 'I': case 'I':
{ {
int16_t number; int16_t number;
return get_number(number) and sax->number_integer(number); return get_number(input_format_t::ubjson, number) and sax->number_integer(number);
} }
case 'l': case 'l':
{ {
int32_t number; int32_t number;
return get_number(number) and sax->number_integer(number); return get_number(input_format_t::ubjson, number) and sax->number_integer(number);
} }
case 'L': case 'L':
{ {
int64_t number; int64_t number;
return get_number(number) and sax->number_integer(number); return get_number(input_format_t::ubjson, number) and sax->number_integer(number);
} }
case 'd': case 'd':
{ {
float number; float number;
return get_number(number) and sax->number_float(static_cast<number_float_t>(number), ""); return get_number(input_format_t::ubjson, number) and sax->number_float(static_cast<number_float_t>(number), "");
} }
case 'D': case 'D':
{ {
double number; double number;
return get_number(number) and sax->number_float(static_cast<number_float_t>(number), ""); return get_number(input_format_t::ubjson, number) and sax->number_float(static_cast<number_float_t>(number), "");
} }
case 'C': // char case 'C': // char
{ {
get(); get();
if (JSON_UNLIKELY(not unexpect_eof())) if (JSON_UNLIKELY(not unexpect_eof(input_format_t::ubjson, "char")))
{ {
return false; return false;
} }
if (JSON_UNLIKELY(current > 127)) if (JSON_UNLIKELY(current > 127))
{ {
auto last_token = get_token_string(); auto last_token = get_token_string();
return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, "byte after 'C' must be in range 0x00..0x7F; last byte: 0x" + last_token)); return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format_t::ubjson, "byte after 'C' must be in range 0x00..0x7F; last byte: 0x" + last_token, "char")));
} }
string_t s(1, static_cast<char>(current)); string_t s(1, static_cast<char>(current));
return sax->string(s); return sax->string(s);
@ -1518,7 +1521,7 @@ class binary_reader
default: // anything else default: // anything else
{ {
auto last_token = get_token_string(); auto last_token = get_token_string();
return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, "error reading UBJSON; last byte: 0x" + last_token)); return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::ubjson, "invalid byte: 0x" + last_token, "value")));
} }
} }
} }
@ -1661,13 +1664,16 @@ class binary_reader
} }
/*! /*!
@param[in] format the current format (for diagnostics)
@param[in] context further context information (for diagnostics)
@return whether the last read character is not EOF @return whether the last read character is not EOF
*/ */
bool unexpect_eof() const bool unexpect_eof(const input_format_t format, const char* context) const
{ {
if (JSON_UNLIKELY(current == std::char_traits<char>::eof())) if (JSON_UNLIKELY(current == std::char_traits<char>::eof()))
{ {
return sax->parse_error(chars_read, "<end of file>", parse_error::create(110, chars_read, "unexpected end of input")); return sax->parse_error(chars_read, "<end of file>",
parse_error::create(110, chars_read, exception_message(format, "unexpected end of input", context)));
} }
return true; return true;
} }
@ -1683,6 +1689,41 @@ class binary_reader
} }
private: private:
/*!
@param[in] format the current format
@param[in] detail a detailed error message
@param[in] context further contect information
@return a message string to use in the parse_error exceptions
*/
std::string exception_message(const input_format_t format,
const std::string& detail,
const std::string& context) const
{
std::string error_msg = "syntax error while parsing ";
switch (format)
{
case input_format_t::cbor:
error_msg += "CBOR";
break;
case input_format_t::msgpack:
error_msg += "MessagePack";
break;
case input_format_t::ubjson:
error_msg += "UBJSON";
break;
// LCOV_EXCL_START
default:
assert(false);
// LCOV_EXCL_STOP
}
return error_msg + " " + context + ": " + detail;
}
/// input adapter /// input adapter
input_adapter_t ia = nullptr; input_adapter_t ia = nullptr;

View file

@ -767,7 +767,7 @@ class binary_writer
} }
else else
{ {
JSON_THROW(out_of_range::create(407, "number overflow serializing " + std::to_string(n))); JSON_THROW(out_of_range::create(407, "integer number " + std::to_string(n) + " cannot be represented by UBJSON as it does not fit int64"));
} }
} }
@ -821,7 +821,7 @@ class binary_writer
// LCOV_EXCL_START // LCOV_EXCL_START
else else
{ {
JSON_THROW(out_of_range::create(407, "number overflow serializing " + std::to_string(n))); JSON_THROW(out_of_range::create(407, "integer number " + std::to_string(n) + " cannot be represented by UBJSON as it does not fit int64"));
} }
// LCOV_EXCL_STOP // LCOV_EXCL_STOP
} }

View file

@ -6297,7 +6297,8 @@ class binary_reader
if (JSON_UNLIKELY(current != std::char_traits<char>::eof())) if (JSON_UNLIKELY(current != std::char_traits<char>::eof()))
{ {
return sax->parse_error(chars_read, get_token_string(), parse_error::create(110, chars_read, "expected end of input")); return sax->parse_error(chars_read, get_token_string(),
parse_error::create(110, chars_read, exception_message(format, "expected end of input; last byte: 0x" + get_token_string(), "value")));
} }
} }
@ -6330,7 +6331,7 @@ class binary_reader
{ {
// EOF // EOF
case std::char_traits<char>::eof(): case std::char_traits<char>::eof():
return unexpect_eof(); return unexpect_eof(input_format_t::cbor, "value");
// Integer 0x00..0x17 (0..23) // Integer 0x00..0x17 (0..23)
case 0x00: case 0x00:
@ -6362,25 +6363,25 @@ class binary_reader
case 0x18: // Unsigned integer (one-byte uint8_t follows) case 0x18: // Unsigned integer (one-byte uint8_t follows)
{ {
uint8_t number; uint8_t number;
return get_number(number) and sax->number_unsigned(number); return get_number(input_format_t::cbor, number) and sax->number_unsigned(number);
} }
case 0x19: // Unsigned integer (two-byte uint16_t follows) case 0x19: // Unsigned integer (two-byte uint16_t follows)
{ {
uint16_t number; uint16_t number;
return get_number(number) and sax->number_unsigned(number); return get_number(input_format_t::cbor, number) and sax->number_unsigned(number);
} }
case 0x1A: // Unsigned integer (four-byte uint32_t follows) case 0x1A: // Unsigned integer (four-byte uint32_t follows)
{ {
uint32_t number; uint32_t number;
return get_number(number) and sax->number_unsigned(number); return get_number(input_format_t::cbor, number) and sax->number_unsigned(number);
} }
case 0x1B: // Unsigned integer (eight-byte uint64_t follows) case 0x1B: // Unsigned integer (eight-byte uint64_t follows)
{ {
uint64_t number; uint64_t number;
return get_number(number) and sax->number_unsigned(number); return get_number(input_format_t::cbor, number) and sax->number_unsigned(number);
} }
// Negative integer -1-0x00..-1-0x17 (-1..-24) // Negative integer -1-0x00..-1-0x17 (-1..-24)
@ -6413,25 +6414,25 @@ class binary_reader
case 0x38: // Negative integer (one-byte uint8_t follows) case 0x38: // Negative integer (one-byte uint8_t follows)
{ {
uint8_t number; uint8_t number;
return get_number(number) and sax->number_integer(static_cast<number_integer_t>(-1) - number); return get_number(input_format_t::cbor, number) and sax->number_integer(static_cast<number_integer_t>(-1) - number);
} }
case 0x39: // Negative integer -1-n (two-byte uint16_t follows) case 0x39: // Negative integer -1-n (two-byte uint16_t follows)
{ {
uint16_t number; uint16_t number;
return get_number(number) and sax->number_integer(static_cast<number_integer_t>(-1) - number); return get_number(input_format_t::cbor, number) and sax->number_integer(static_cast<number_integer_t>(-1) - number);
} }
case 0x3A: // Negative integer -1-n (four-byte uint32_t follows) case 0x3A: // Negative integer -1-n (four-byte uint32_t follows)
{ {
uint32_t number; uint32_t number;
return get_number(number) and sax->number_integer(static_cast<number_integer_t>(-1) - number); return get_number(input_format_t::cbor, number) and sax->number_integer(static_cast<number_integer_t>(-1) - number);
} }
case 0x3B: // Negative integer -1-n (eight-byte uint64_t follows) case 0x3B: // Negative integer -1-n (eight-byte uint64_t follows)
{ {
uint64_t number; uint64_t number;
return get_number(number) and sax->number_integer(static_cast<number_integer_t>(-1) return get_number(input_format_t::cbor, number) and sax->number_integer(static_cast<number_integer_t>(-1)
- static_cast<number_integer_t>(number)); - static_cast<number_integer_t>(number));
} }
@ -6500,25 +6501,25 @@ class binary_reader
case 0x98: // array (one-byte uint8_t for n follows) case 0x98: // array (one-byte uint8_t for n follows)
{ {
uint8_t len; uint8_t len;
return get_number(len) and get_cbor_array(static_cast<std::size_t>(len)); return get_number(input_format_t::cbor, len) and get_cbor_array(static_cast<std::size_t>(len));
} }
case 0x99: // array (two-byte uint16_t for n follow) case 0x99: // array (two-byte uint16_t for n follow)
{ {
uint16_t len; uint16_t len;
return get_number(len) and get_cbor_array(static_cast<std::size_t>(len)); return get_number(input_format_t::cbor, len) and get_cbor_array(static_cast<std::size_t>(len));
} }
case 0x9A: // array (four-byte uint32_t for n follow) case 0x9A: // array (four-byte uint32_t for n follow)
{ {
uint32_t len; uint32_t len;
return get_number(len) and get_cbor_array(static_cast<std::size_t>(len)); return get_number(input_format_t::cbor, len) and get_cbor_array(static_cast<std::size_t>(len));
} }
case 0x9B: // array (eight-byte uint64_t for n follow) case 0x9B: // array (eight-byte uint64_t for n follow)
{ {
uint64_t len; uint64_t len;
return get_number(len) and get_cbor_array(static_cast<std::size_t>(len)); return get_number(input_format_t::cbor, len) and get_cbor_array(static_cast<std::size_t>(len));
} }
case 0x9F: // array (indefinite length) case 0x9F: // array (indefinite length)
@ -6554,25 +6555,25 @@ class binary_reader
case 0xB8: // map (one-byte uint8_t for n follows) case 0xB8: // map (one-byte uint8_t for n follows)
{ {
uint8_t len; uint8_t len;
return get_number(len) and get_cbor_object(static_cast<std::size_t>(len)); return get_number(input_format_t::cbor, len) and get_cbor_object(static_cast<std::size_t>(len));
} }
case 0xB9: // map (two-byte uint16_t for n follow) case 0xB9: // map (two-byte uint16_t for n follow)
{ {
uint16_t len; uint16_t len;
return get_number(len) and get_cbor_object(static_cast<std::size_t>(len)); return get_number(input_format_t::cbor, len) and get_cbor_object(static_cast<std::size_t>(len));
} }
case 0xBA: // map (four-byte uint32_t for n follow) case 0xBA: // map (four-byte uint32_t for n follow)
{ {
uint32_t len; uint32_t len;
return get_number(len) and get_cbor_object(static_cast<std::size_t>(len)); return get_number(input_format_t::cbor, len) and get_cbor_object(static_cast<std::size_t>(len));
} }
case 0xBB: // map (eight-byte uint64_t for n follow) case 0xBB: // map (eight-byte uint64_t for n follow)
{ {
uint64_t len; uint64_t len;
return get_number(len) and get_cbor_object(static_cast<std::size_t>(len)); return get_number(input_format_t::cbor, len) and get_cbor_object(static_cast<std::size_t>(len));
} }
case 0xBF: // map (indefinite length) case 0xBF: // map (indefinite length)
@ -6590,12 +6591,12 @@ class binary_reader
case 0xF9: // Half-Precision Float (two-byte IEEE 754) case 0xF9: // Half-Precision Float (two-byte IEEE 754)
{ {
const int byte1_raw = get(); const int byte1_raw = get();
if (JSON_UNLIKELY(not unexpect_eof())) if (JSON_UNLIKELY(not unexpect_eof(input_format_t::cbor, "number")))
{ {
return false; return false;
} }
const int byte2_raw = get(); const int byte2_raw = get();
if (JSON_UNLIKELY(not unexpect_eof())) if (JSON_UNLIKELY(not unexpect_eof(input_format_t::cbor, "number")))
{ {
return false; return false;
} }
@ -6638,19 +6639,19 @@ class binary_reader
case 0xFA: // Single-Precision Float (four-byte IEEE 754) case 0xFA: // Single-Precision Float (four-byte IEEE 754)
{ {
float number; float number;
return get_number(number) and sax->number_float(static_cast<number_float_t>(number), ""); return get_number(input_format_t::cbor, number) and sax->number_float(static_cast<number_float_t>(number), "");
} }
case 0xFB: // Double-Precision Float (eight-byte IEEE 754) case 0xFB: // Double-Precision Float (eight-byte IEEE 754)
{ {
double number; double number;
return get_number(number) and sax->number_float(static_cast<number_float_t>(number), ""); return get_number(input_format_t::cbor, number) and sax->number_float(static_cast<number_float_t>(number), "");
} }
default: // anything else (0xFF is handled inside the other types) default: // anything else (0xFF is handled inside the other types)
{ {
auto last_token = get_token_string(); auto last_token = get_token_string();
return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, "error reading CBOR; last byte: 0x" + last_token)); return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::cbor, "invalid byte: 0x" + last_token, "value")));
} }
} }
} }
@ -6664,7 +6665,7 @@ class binary_reader
{ {
// EOF // EOF
case std::char_traits<char>::eof(): case std::char_traits<char>::eof():
return unexpect_eof(); return unexpect_eof(input_format_t::msgpack, "value");
// positive fixint // positive fixint
case 0x00: case 0x00:
@ -6885,61 +6886,61 @@ class binary_reader
case 0xCA: // float 32 case 0xCA: // float 32
{ {
float number; float number;
return get_number(number) and sax->number_float(static_cast<number_float_t>(number), ""); return get_number(input_format_t::msgpack, number) and sax->number_float(static_cast<number_float_t>(number), "");
} }
case 0xCB: // float 64 case 0xCB: // float 64
{ {
double number; double number;
return get_number(number) and sax->number_float(static_cast<number_float_t>(number), ""); return get_number(input_format_t::msgpack, number) and sax->number_float(static_cast<number_float_t>(number), "");
} }
case 0xCC: // uint 8 case 0xCC: // uint 8
{ {
uint8_t number; uint8_t number;
return get_number(number) and sax->number_unsigned(number); return get_number(input_format_t::msgpack, number) and sax->number_unsigned(number);
} }
case 0xCD: // uint 16 case 0xCD: // uint 16
{ {
uint16_t number; uint16_t number;
return get_number(number) and sax->number_unsigned(number); return get_number(input_format_t::msgpack, number) and sax->number_unsigned(number);
} }
case 0xCE: // uint 32 case 0xCE: // uint 32
{ {
uint32_t number; uint32_t number;
return get_number(number) and sax->number_unsigned(number); return get_number(input_format_t::msgpack, number) and sax->number_unsigned(number);
} }
case 0xCF: // uint 64 case 0xCF: // uint 64
{ {
uint64_t number; uint64_t number;
return get_number(number) and sax->number_unsigned(number); return get_number(input_format_t::msgpack, number) and sax->number_unsigned(number);
} }
case 0xD0: // int 8 case 0xD0: // int 8
{ {
int8_t number; int8_t number;
return get_number(number) and sax->number_integer(number); return get_number(input_format_t::msgpack, number) and sax->number_integer(number);
} }
case 0xD1: // int 16 case 0xD1: // int 16
{ {
int16_t number; int16_t number;
return get_number(number) and sax->number_integer(number); return get_number(input_format_t::msgpack, number) and sax->number_integer(number);
} }
case 0xD2: // int 32 case 0xD2: // int 32
{ {
int32_t number; int32_t number;
return get_number(number) and sax->number_integer(number); return get_number(input_format_t::msgpack, number) and sax->number_integer(number);
} }
case 0xD3: // int 64 case 0xD3: // int 64
{ {
int64_t number; int64_t number;
return get_number(number) and sax->number_integer(number); return get_number(input_format_t::msgpack, number) and sax->number_integer(number);
} }
case 0xD9: // str 8 case 0xD9: // str 8
@ -6953,25 +6954,25 @@ class binary_reader
case 0xDC: // array 16 case 0xDC: // array 16
{ {
uint16_t len; uint16_t len;
return get_number(len) and get_msgpack_array(static_cast<std::size_t>(len)); return get_number(input_format_t::msgpack, len) and get_msgpack_array(static_cast<std::size_t>(len));
} }
case 0xDD: // array 32 case 0xDD: // array 32
{ {
uint32_t len; uint32_t len;
return get_number(len) and get_msgpack_array(static_cast<std::size_t>(len)); return get_number(input_format_t::msgpack, len) and get_msgpack_array(static_cast<std::size_t>(len));
} }
case 0xDE: // map 16 case 0xDE: // map 16
{ {
uint16_t len; uint16_t len;
return get_number(len) and get_msgpack_object(static_cast<std::size_t>(len)); return get_number(input_format_t::msgpack, len) and get_msgpack_object(static_cast<std::size_t>(len));
} }
case 0xDF: // map 32 case 0xDF: // map 32
{ {
uint32_t len; uint32_t len;
return get_number(len) and get_msgpack_object(static_cast<std::size_t>(len)); return get_number(input_format_t::msgpack, len) and get_msgpack_object(static_cast<std::size_t>(len));
} }
// negative fixint // negative fixint
@ -7012,7 +7013,7 @@ class binary_reader
default: // anything else default: // anything else
{ {
auto last_token = get_token_string(); auto last_token = get_token_string();
return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, "error reading MessagePack; last byte: 0x" + last_token)); return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::msgpack, "invalid byte: 0x" + last_token, "value")));
} }
} }
} }
@ -7062,6 +7063,7 @@ class binary_reader
@brief read a number from the input @brief read a number from the input
@tparam NumberType the type of the number @tparam NumberType the type of the number
@param[in] format the current format (for diagnostics)
@param[out] result number of type @a NumberType @param[out] result number of type @a NumberType
@return whether conversion completed @return whether conversion completed
@ -7071,14 +7073,14 @@ class binary_reader
(big endian) and therefore need reordering on little endian systems. (big endian) and therefore need reordering on little endian systems.
*/ */
template<typename NumberType> template<typename NumberType>
bool get_number(NumberType& result) bool get_number(const input_format_t format, NumberType& result)
{ {
// step 1: read input into array with system's byte order // step 1: read input into array with system's byte order
std::array<uint8_t, sizeof(NumberType)> vec; std::array<uint8_t, sizeof(NumberType)> vec;
for (std::size_t i = 0; i < sizeof(NumberType); ++i) for (std::size_t i = 0; i < sizeof(NumberType); ++i)
{ {
get(); get();
if (JSON_UNLIKELY(not unexpect_eof())) if (JSON_UNLIKELY(not unexpect_eof(format, "number")))
{ {
return false; return false;
} }
@ -7103,8 +7105,9 @@ class binary_reader
@brief create a string by reading characters from the input @brief create a string by reading characters from the input
@tparam NumberType the type of the number @tparam NumberType the type of the number
@param[in] format the current format (for diagnostics)
@param[in] len number of characters to read @param[in] len number of characters to read
@param[out] string created by reading @a len bytes @param[out] result string created by reading @a len bytes
@return whether string creation completed @return whether string creation completed
@ -7113,13 +7116,13 @@ class binary_reader
the input before we run out of string memory. the input before we run out of string memory.
*/ */
template<typename NumberType> template<typename NumberType>
bool get_string(const NumberType len, string_t& result) bool get_string(const input_format_t format, const NumberType len, string_t& result)
{ {
bool success = true; bool success = true;
std::generate_n(std::back_inserter(result), len, [this, &success]() std::generate_n(std::back_inserter(result), len, [this, &success, &format]()
{ {
get(); get();
if (JSON_UNLIKELY(not unexpect_eof())) if (JSON_UNLIKELY(not unexpect_eof(format, "string")))
{ {
success = false; success = false;
} }
@ -7141,7 +7144,7 @@ class binary_reader
*/ */
bool get_cbor_string(string_t& result) bool get_cbor_string(string_t& result)
{ {
if (JSON_UNLIKELY(not unexpect_eof())) if (JSON_UNLIKELY(not unexpect_eof(input_format_t::cbor, "string")))
{ {
return false; return false;
} }
@ -7174,31 +7177,31 @@ class binary_reader
case 0x76: case 0x76:
case 0x77: case 0x77:
{ {
return get_string(current & 0x1F, result); return get_string(input_format_t::cbor, current & 0x1F, result);
} }
case 0x78: // UTF-8 string (one-byte uint8_t for n follows) case 0x78: // UTF-8 string (one-byte uint8_t for n follows)
{ {
uint8_t len; uint8_t len;
return get_number(len) and get_string(len, result); return get_number(input_format_t::cbor, len) and get_string(input_format_t::cbor, len, result);
} }
case 0x79: // UTF-8 string (two-byte uint16_t for n follow) case 0x79: // UTF-8 string (two-byte uint16_t for n follow)
{ {
uint16_t len; uint16_t len;
return get_number(len) and get_string(len, result); return get_number(input_format_t::cbor, len) and get_string(input_format_t::cbor, len, result);
} }
case 0x7A: // UTF-8 string (four-byte uint32_t for n follow) case 0x7A: // UTF-8 string (four-byte uint32_t for n follow)
{ {
uint32_t len; uint32_t len;
return get_number(len) and get_string(len, result); return get_number(input_format_t::cbor, len) and get_string(input_format_t::cbor, len, result);
} }
case 0x7B: // UTF-8 string (eight-byte uint64_t for n follow) case 0x7B: // UTF-8 string (eight-byte uint64_t for n follow)
{ {
uint64_t len; uint64_t len;
return get_number(len) and get_string(len, result); return get_number(input_format_t::cbor, len) and get_string(input_format_t::cbor, len, result);
} }
case 0x7F: // UTF-8 string (indefinite length) case 0x7F: // UTF-8 string (indefinite length)
@ -7218,7 +7221,7 @@ class binary_reader
default: default:
{ {
auto last_token = get_token_string(); auto last_token = get_token_string();
return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, "expected a CBOR string; last byte: 0x" + last_token)); return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format_t::cbor, "expected length specification (0x60-0x7B) or indefinite string type (0x7F); last byte: 0x" + last_token, "string")));
} }
} }
} }
@ -7321,7 +7324,7 @@ class binary_reader
*/ */
bool get_msgpack_string(string_t& result) bool get_msgpack_string(string_t& result)
{ {
if (JSON_UNLIKELY(not unexpect_eof())) if (JSON_UNLIKELY(not unexpect_eof(input_format_t::msgpack, "string")))
{ {
return false; return false;
} }
@ -7362,31 +7365,31 @@ class binary_reader
case 0xBE: case 0xBE:
case 0xBF: case 0xBF:
{ {
return get_string(current & 0x1F, result); return get_string(input_format_t::msgpack, current & 0x1F, result);
} }
case 0xD9: // str 8 case 0xD9: // str 8
{ {
uint8_t len; uint8_t len;
return get_number(len) and get_string(len, result); return get_number(input_format_t::msgpack, len) and get_string(input_format_t::msgpack, len, result);
} }
case 0xDA: // str 16 case 0xDA: // str 16
{ {
uint16_t len; uint16_t len;
return get_number(len) and get_string(len, result); return get_number(input_format_t::msgpack, len) and get_string(input_format_t::msgpack, len, result);
} }
case 0xDB: // str 32 case 0xDB: // str 32
{ {
uint32_t len; uint32_t len;
return get_number(len) and get_string(len, result); return get_number(input_format_t::msgpack, len) and get_string(input_format_t::msgpack, len, result);
} }
default: default:
{ {
auto last_token = get_token_string(); auto last_token = get_token_string();
return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, "expected a MessagePack string; last byte: 0x" + last_token)); return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format_t::msgpack, "expected length specification (0xA0-0xBF, 0xD9-0xDB); last byte: 0x" + last_token, "string")));
} }
} }
} }
@ -7464,7 +7467,7 @@ class binary_reader
get(); // TODO: may we ignore N here? get(); // TODO: may we ignore N here?
} }
if (JSON_UNLIKELY(not unexpect_eof())) if (JSON_UNLIKELY(not unexpect_eof(input_format_t::ubjson, "value")))
{ {
return false; return false;
} }
@ -7474,36 +7477,36 @@ class binary_reader
case 'U': case 'U':
{ {
uint8_t len; uint8_t len;
return get_number(len) and get_string(len, result); return get_number(input_format_t::ubjson, len) and get_string(input_format_t::ubjson, len, result);
} }
case 'i': case 'i':
{ {
int8_t len; int8_t len;
return get_number(len) and get_string(len, result); return get_number(input_format_t::ubjson, len) and get_string(input_format_t::ubjson, len, result);
} }
case 'I': case 'I':
{ {
int16_t len; int16_t len;
return get_number(len) and get_string(len, result); return get_number(input_format_t::ubjson, len) and get_string(input_format_t::ubjson, len, result);
} }
case 'l': case 'l':
{ {
int32_t len; int32_t len;
return get_number(len) and get_string(len, result); return get_number(input_format_t::ubjson, len) and get_string(input_format_t::ubjson, len, result);
} }
case 'L': case 'L':
{ {
int64_t len; int64_t len;
return get_number(len) and get_string(len, result); return get_number(input_format_t::ubjson, len) and get_string(input_format_t::ubjson, len, result);
} }
default: default:
auto last_token = get_token_string(); auto last_token = get_token_string();
return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, "expected a UBJSON string; last byte: 0x" + last_token)); return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format_t::ubjson, "expected length type specification (U, i, I, l, L); last byte: 0x" + last_token, "string")));
} }
} }
@ -7518,7 +7521,7 @@ class binary_reader
case 'U': case 'U':
{ {
uint8_t number; uint8_t number;
if (JSON_UNLIKELY(not get_number(number))) if (JSON_UNLIKELY(not get_number(input_format_t::ubjson, number)))
{ {
return false; return false;
} }
@ -7529,7 +7532,7 @@ class binary_reader
case 'i': case 'i':
{ {
int8_t number; int8_t number;
if (JSON_UNLIKELY(not get_number(number))) if (JSON_UNLIKELY(not get_number(input_format_t::ubjson, number)))
{ {
return false; return false;
} }
@ -7540,7 +7543,7 @@ class binary_reader
case 'I': case 'I':
{ {
int16_t number; int16_t number;
if (JSON_UNLIKELY(not get_number(number))) if (JSON_UNLIKELY(not get_number(input_format_t::ubjson, number)))
{ {
return false; return false;
} }
@ -7551,7 +7554,7 @@ class binary_reader
case 'l': case 'l':
{ {
int32_t number; int32_t number;
if (JSON_UNLIKELY(not get_number(number))) if (JSON_UNLIKELY(not get_number(input_format_t::ubjson, number)))
{ {
return false; return false;
} }
@ -7562,7 +7565,7 @@ class binary_reader
case 'L': case 'L':
{ {
int64_t number; int64_t number;
if (JSON_UNLIKELY(not get_number(number))) if (JSON_UNLIKELY(not get_number(input_format_t::ubjson, number)))
{ {
return false; return false;
} }
@ -7573,7 +7576,7 @@ class binary_reader
default: default:
{ {
auto last_token = get_token_string(); auto last_token = get_token_string();
return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, "byte after '#' must denote a number type; last byte: 0x" + last_token)); return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format_t::ubjson, "expected length type specification (U, i, I, l, L) after '#'; last byte: 0x" + last_token, "size")));
} }
} }
} }
@ -7598,7 +7601,7 @@ class binary_reader
if (current == '$') if (current == '$')
{ {
result.second = get(); // must not ignore 'N', because 'N' maybe the type result.second = get(); // must not ignore 'N', because 'N' maybe the type
if (JSON_UNLIKELY(not unexpect_eof())) if (JSON_UNLIKELY(not unexpect_eof(input_format_t::ubjson, "type")))
{ {
return false; return false;
} }
@ -7606,12 +7609,12 @@ class binary_reader
get_ignore_noop(); get_ignore_noop();
if (JSON_UNLIKELY(current != '#')) if (JSON_UNLIKELY(current != '#'))
{ {
if (JSON_UNLIKELY(not unexpect_eof())) if (JSON_UNLIKELY(not unexpect_eof(input_format_t::ubjson, "value")))
{ {
return false; return false;
} }
auto last_token = get_token_string(); auto last_token = get_token_string();
return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, "expected '#' after UBJSON type information; last byte: 0x" + last_token)); return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::ubjson, "expected '#' after type information; last byte: 0x" + last_token, "size")));
} }
return get_ubjson_size_value(result.first); return get_ubjson_size_value(result.first);
@ -7632,7 +7635,7 @@ class binary_reader
switch (prefix) switch (prefix)
{ {
case std::char_traits<char>::eof(): // EOF case std::char_traits<char>::eof(): // EOF
return unexpect_eof(); return unexpect_eof(input_format_t::ubjson, "value");
case 'T': // true case 'T': // true
return sax->boolean(true); return sax->boolean(true);
@ -7645,56 +7648,56 @@ class binary_reader
case 'U': case 'U':
{ {
uint8_t number; uint8_t number;
return get_number(number) and sax->number_unsigned(number); return get_number(input_format_t::ubjson, number) and sax->number_unsigned(number);
} }
case 'i': case 'i':
{ {
int8_t number; int8_t number;
return get_number(number) and sax->number_integer(number); return get_number(input_format_t::ubjson, number) and sax->number_integer(number);
} }
case 'I': case 'I':
{ {
int16_t number; int16_t number;
return get_number(number) and sax->number_integer(number); return get_number(input_format_t::ubjson, number) and sax->number_integer(number);
} }
case 'l': case 'l':
{ {
int32_t number; int32_t number;
return get_number(number) and sax->number_integer(number); return get_number(input_format_t::ubjson, number) and sax->number_integer(number);
} }
case 'L': case 'L':
{ {
int64_t number; int64_t number;
return get_number(number) and sax->number_integer(number); return get_number(input_format_t::ubjson, number) and sax->number_integer(number);
} }
case 'd': case 'd':
{ {
float number; float number;
return get_number(number) and sax->number_float(static_cast<number_float_t>(number), ""); return get_number(input_format_t::ubjson, number) and sax->number_float(static_cast<number_float_t>(number), "");
} }
case 'D': case 'D':
{ {
double number; double number;
return get_number(number) and sax->number_float(static_cast<number_float_t>(number), ""); return get_number(input_format_t::ubjson, number) and sax->number_float(static_cast<number_float_t>(number), "");
} }
case 'C': // char case 'C': // char
{ {
get(); get();
if (JSON_UNLIKELY(not unexpect_eof())) if (JSON_UNLIKELY(not unexpect_eof(input_format_t::ubjson, "char")))
{ {
return false; return false;
} }
if (JSON_UNLIKELY(current > 127)) if (JSON_UNLIKELY(current > 127))
{ {
auto last_token = get_token_string(); auto last_token = get_token_string();
return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, "byte after 'C' must be in range 0x00..0x7F; last byte: 0x" + last_token)); return sax->parse_error(chars_read, last_token, parse_error::create(113, chars_read, exception_message(input_format_t::ubjson, "byte after 'C' must be in range 0x00..0x7F; last byte: 0x" + last_token, "char")));
} }
string_t s(1, static_cast<char>(current)); string_t s(1, static_cast<char>(current));
return sax->string(s); return sax->string(s);
@ -7715,7 +7718,7 @@ class binary_reader
default: // anything else default: // anything else
{ {
auto last_token = get_token_string(); auto last_token = get_token_string();
return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, "error reading UBJSON; last byte: 0x" + last_token)); return sax->parse_error(chars_read, last_token, parse_error::create(112, chars_read, exception_message(input_format_t::ubjson, "invalid byte: 0x" + last_token, "value")));
} }
} }
} }
@ -7858,13 +7861,16 @@ class binary_reader
} }
/*! /*!
@param[in] format the current format (for diagnostics)
@param[in] context further context information (for diagnostics)
@return whether the last read character is not EOF @return whether the last read character is not EOF
*/ */
bool unexpect_eof() const bool unexpect_eof(const input_format_t format, const char* context) const
{ {
if (JSON_UNLIKELY(current == std::char_traits<char>::eof())) if (JSON_UNLIKELY(current == std::char_traits<char>::eof()))
{ {
return sax->parse_error(chars_read, "<end of file>", parse_error::create(110, chars_read, "unexpected end of input")); return sax->parse_error(chars_read, "<end of file>",
parse_error::create(110, chars_read, exception_message(format, "unexpected end of input", context)));
} }
return true; return true;
} }
@ -7880,6 +7886,41 @@ class binary_reader
} }
private: private:
/*!
@param[in] format the current format
@param[in] detail a detailed error message
@param[in] context further contect information
@return a message string to use in the parse_error exceptions
*/
std::string exception_message(const input_format_t format,
const std::string& detail,
const std::string& context) const
{
std::string error_msg = "syntax error while parsing ";
switch (format)
{
case input_format_t::cbor:
error_msg += "CBOR";
break;
case input_format_t::msgpack:
error_msg += "MessagePack";
break;
case input_format_t::ubjson:
error_msg += "UBJSON";
break;
// LCOV_EXCL_START
default:
assert(false);
// LCOV_EXCL_STOP
}
return error_msg + " " + context + ": " + detail;
}
/// input adapter /// input adapter
input_adapter_t ia = nullptr; input_adapter_t ia = nullptr;
@ -8670,7 +8711,7 @@ class binary_writer
} }
else else
{ {
JSON_THROW(out_of_range::create(407, "number overflow serializing " + std::to_string(n))); JSON_THROW(out_of_range::create(407, "integer number " + std::to_string(n) + " cannot be represented by UBJSON as it does not fit int64"));
} }
} }
@ -8724,7 +8765,7 @@ class binary_writer
// LCOV_EXCL_START // LCOV_EXCL_START
else else
{ {
JSON_THROW(out_of_range::create(407, "number overflow serializing " + std::to_string(n))); JSON_THROW(out_of_range::create(407, "integer number " + std::to_string(n) + " cannot be represented by UBJSON as it does not fit int64"));
} }
// LCOV_EXCL_STOP // LCOV_EXCL_STOP
} }

View file

@ -831,14 +831,14 @@ TEST_CASE("CBOR")
{ {
CHECK_THROWS_AS(json::from_cbor(std::vector<uint8_t>({0xf9})), json::parse_error&); CHECK_THROWS_AS(json::from_cbor(std::vector<uint8_t>({0xf9})), json::parse_error&);
CHECK_THROWS_WITH(json::from_cbor(std::vector<uint8_t>({0xf9})), CHECK_THROWS_WITH(json::from_cbor(std::vector<uint8_t>({0xf9})),
"[json.exception.parse_error.110] parse error at byte 2: unexpected end of input"); "[json.exception.parse_error.110] parse error at byte 2: syntax error while parsing CBOR number: unexpected end of input");
CHECK(json::from_cbor(std::vector<uint8_t>({0xf9}), true, false).is_discarded()); CHECK(json::from_cbor(std::vector<uint8_t>({0xf9}), true, false).is_discarded());
} }
SECTION("only one byte follows") SECTION("only one byte follows")
{ {
CHECK_THROWS_AS(json::from_cbor(std::vector<uint8_t>({0xf9, 0x7c})), json::parse_error&); CHECK_THROWS_AS(json::from_cbor(std::vector<uint8_t>({0xf9, 0x7c})), json::parse_error&);
CHECK_THROWS_WITH(json::from_cbor(std::vector<uint8_t>({0xf9, 0x7c})), CHECK_THROWS_WITH(json::from_cbor(std::vector<uint8_t>({0xf9, 0x7c})),
"[json.exception.parse_error.110] parse error at byte 3: unexpected end of input"); "[json.exception.parse_error.110] parse error at byte 3: syntax error while parsing CBOR number: unexpected end of input");
CHECK(json::from_cbor(std::vector<uint8_t>({0xf9, 0x7c}), true, false).is_discarded()); CHECK(json::from_cbor(std::vector<uint8_t>({0xf9, 0x7c}), true, false).is_discarded());
} }
} }
@ -1314,7 +1314,7 @@ TEST_CASE("CBOR")
{ {
CHECK_THROWS_AS(json::from_cbor(std::vector<uint8_t>()), json::parse_error&); CHECK_THROWS_AS(json::from_cbor(std::vector<uint8_t>()), json::parse_error&);
CHECK_THROWS_WITH(json::from_cbor(std::vector<uint8_t>()), CHECK_THROWS_WITH(json::from_cbor(std::vector<uint8_t>()),
"[json.exception.parse_error.110] parse error at byte 1: unexpected end of input"); "[json.exception.parse_error.110] parse error at byte 1: syntax error while parsing CBOR value: unexpected end of input");
CHECK(json::from_cbor(std::vector<uint8_t>(), true, false).is_discarded()); CHECK(json::from_cbor(std::vector<uint8_t>(), true, false).is_discarded());
} }
@ -1346,53 +1346,53 @@ TEST_CASE("CBOR")
CHECK_THROWS_AS(json::from_cbor(std::vector<uint8_t>({0xBF, 0x61, 0X61})), json::parse_error&); CHECK_THROWS_AS(json::from_cbor(std::vector<uint8_t>({0xBF, 0x61, 0X61})), json::parse_error&);
CHECK_THROWS_WITH(json::from_cbor(std::vector<uint8_t>({0x18})), CHECK_THROWS_WITH(json::from_cbor(std::vector<uint8_t>({0x18})),
"[json.exception.parse_error.110] parse error at byte 2: unexpected end of input"); "[json.exception.parse_error.110] parse error at byte 2: syntax error while parsing CBOR number: unexpected end of input");
CHECK_THROWS_WITH(json::from_cbor(std::vector<uint8_t>({0x19})), CHECK_THROWS_WITH(json::from_cbor(std::vector<uint8_t>({0x19})),
"[json.exception.parse_error.110] parse error at byte 2: unexpected end of input"); "[json.exception.parse_error.110] parse error at byte 2: syntax error while parsing CBOR number: unexpected end of input");
CHECK_THROWS_WITH(json::from_cbor(std::vector<uint8_t>({0x19, 0x00})), CHECK_THROWS_WITH(json::from_cbor(std::vector<uint8_t>({0x19, 0x00})),
"[json.exception.parse_error.110] parse error at byte 3: unexpected end of input"); "[json.exception.parse_error.110] parse error at byte 3: syntax error while parsing CBOR number: unexpected end of input");
CHECK_THROWS_WITH(json::from_cbor(std::vector<uint8_t>({0x1a})), CHECK_THROWS_WITH(json::from_cbor(std::vector<uint8_t>({0x1a})),
"[json.exception.parse_error.110] parse error at byte 2: unexpected end of input"); "[json.exception.parse_error.110] parse error at byte 2: syntax error while parsing CBOR number: unexpected end of input");
CHECK_THROWS_WITH(json::from_cbor(std::vector<uint8_t>({0x1a, 0x00})), CHECK_THROWS_WITH(json::from_cbor(std::vector<uint8_t>({0x1a, 0x00})),
"[json.exception.parse_error.110] parse error at byte 3: unexpected end of input"); "[json.exception.parse_error.110] parse error at byte 3: syntax error while parsing CBOR number: unexpected end of input");
CHECK_THROWS_WITH(json::from_cbor(std::vector<uint8_t>({0x1a, 0x00, 0x00})), CHECK_THROWS_WITH(json::from_cbor(std::vector<uint8_t>({0x1a, 0x00, 0x00})),
"[json.exception.parse_error.110] parse error at byte 4: unexpected end of input"); "[json.exception.parse_error.110] parse error at byte 4: syntax error while parsing CBOR number: unexpected end of input");
CHECK_THROWS_WITH(json::from_cbor(std::vector<uint8_t>({0x1a, 0x00, 0x00, 0x00})), CHECK_THROWS_WITH(json::from_cbor(std::vector<uint8_t>({0x1a, 0x00, 0x00, 0x00})),
"[json.exception.parse_error.110] parse error at byte 5: unexpected end of input"); "[json.exception.parse_error.110] parse error at byte 5: syntax error while parsing CBOR number: unexpected end of input");
CHECK_THROWS_WITH(json::from_cbor(std::vector<uint8_t>({0x1b})), CHECK_THROWS_WITH(json::from_cbor(std::vector<uint8_t>({0x1b})),
"[json.exception.parse_error.110] parse error at byte 2: unexpected end of input"); "[json.exception.parse_error.110] parse error at byte 2: syntax error while parsing CBOR number: unexpected end of input");
CHECK_THROWS_WITH(json::from_cbor(std::vector<uint8_t>({0x1b, 0x00})), CHECK_THROWS_WITH(json::from_cbor(std::vector<uint8_t>({0x1b, 0x00})),
"[json.exception.parse_error.110] parse error at byte 3: unexpected end of input"); "[json.exception.parse_error.110] parse error at byte 3: syntax error while parsing CBOR number: unexpected end of input");
CHECK_THROWS_WITH(json::from_cbor(std::vector<uint8_t>({0x1b, 0x00, 0x00})), CHECK_THROWS_WITH(json::from_cbor(std::vector<uint8_t>({0x1b, 0x00, 0x00})),
"[json.exception.parse_error.110] parse error at byte 4: unexpected end of input"); "[json.exception.parse_error.110] parse error at byte 4: syntax error while parsing CBOR number: unexpected end of input");
CHECK_THROWS_WITH(json::from_cbor(std::vector<uint8_t>({0x1b, 0x00, 0x00, 0x00})), CHECK_THROWS_WITH(json::from_cbor(std::vector<uint8_t>({0x1b, 0x00, 0x00, 0x00})),
"[json.exception.parse_error.110] parse error at byte 5: unexpected end of input"); "[json.exception.parse_error.110] parse error at byte 5: syntax error while parsing CBOR number: unexpected end of input");
CHECK_THROWS_WITH(json::from_cbor(std::vector<uint8_t>({0x1b, 0x00, 0x00, 0x00, 0x00})), CHECK_THROWS_WITH(json::from_cbor(std::vector<uint8_t>({0x1b, 0x00, 0x00, 0x00, 0x00})),
"[json.exception.parse_error.110] parse error at byte 6: unexpected end of input"); "[json.exception.parse_error.110] parse error at byte 6: syntax error while parsing CBOR number: unexpected end of input");
CHECK_THROWS_WITH(json::from_cbor(std::vector<uint8_t>({0x1b, 0x00, 0x00, 0x00, 0x00, 0x00})), CHECK_THROWS_WITH(json::from_cbor(std::vector<uint8_t>({0x1b, 0x00, 0x00, 0x00, 0x00, 0x00})),
"[json.exception.parse_error.110] parse error at byte 7: unexpected end of input"); "[json.exception.parse_error.110] parse error at byte 7: syntax error while parsing CBOR number: unexpected end of input");
CHECK_THROWS_WITH(json::from_cbor(std::vector<uint8_t>({0x1b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00})), CHECK_THROWS_WITH(json::from_cbor(std::vector<uint8_t>({0x1b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00})),
"[json.exception.parse_error.110] parse error at byte 8: unexpected end of input"); "[json.exception.parse_error.110] parse error at byte 8: syntax error while parsing CBOR number: unexpected end of input");
CHECK_THROWS_WITH(json::from_cbor(std::vector<uint8_t>({0x1b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00})), CHECK_THROWS_WITH(json::from_cbor(std::vector<uint8_t>({0x1b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00})),
"[json.exception.parse_error.110] parse error at byte 9: unexpected end of input"); "[json.exception.parse_error.110] parse error at byte 9: syntax error while parsing CBOR number: unexpected end of input");
CHECK_THROWS_WITH(json::from_cbor(std::vector<uint8_t>({0x62})), CHECK_THROWS_WITH(json::from_cbor(std::vector<uint8_t>({0x62})),
"[json.exception.parse_error.110] parse error at byte 2: unexpected end of input"); "[json.exception.parse_error.110] parse error at byte 2: syntax error while parsing CBOR string: unexpected end of input");
CHECK_THROWS_WITH(json::from_cbor(std::vector<uint8_t>({0x62, 0x60})), CHECK_THROWS_WITH(json::from_cbor(std::vector<uint8_t>({0x62, 0x60})),
"[json.exception.parse_error.110] parse error at byte 3: unexpected end of input"); "[json.exception.parse_error.110] parse error at byte 3: syntax error while parsing CBOR string: unexpected end of input");
CHECK_THROWS_WITH(json::from_cbor(std::vector<uint8_t>({0x7F})), CHECK_THROWS_WITH(json::from_cbor(std::vector<uint8_t>({0x7F})),
"[json.exception.parse_error.110] parse error at byte 2: unexpected end of input"); "[json.exception.parse_error.110] parse error at byte 2: syntax error while parsing CBOR string: unexpected end of input");
CHECK_THROWS_WITH(json::from_cbor(std::vector<uint8_t>({0x7F, 0x60})), CHECK_THROWS_WITH(json::from_cbor(std::vector<uint8_t>({0x7F, 0x60})),
"[json.exception.parse_error.110] parse error at byte 3: unexpected end of input"); "[json.exception.parse_error.110] parse error at byte 3: syntax error while parsing CBOR string: unexpected end of input");
CHECK_THROWS_WITH(json::from_cbor(std::vector<uint8_t>({0x82, 0x01})), CHECK_THROWS_WITH(json::from_cbor(std::vector<uint8_t>({0x82, 0x01})),
"[json.exception.parse_error.110] parse error at byte 3: unexpected end of input"); "[json.exception.parse_error.110] parse error at byte 3: syntax error while parsing CBOR value: unexpected end of input");
CHECK_THROWS_WITH(json::from_cbor(std::vector<uint8_t>({0x9F, 0x01})), CHECK_THROWS_WITH(json::from_cbor(std::vector<uint8_t>({0x9F, 0x01})),
"[json.exception.parse_error.110] parse error at byte 3: unexpected end of input"); "[json.exception.parse_error.110] parse error at byte 3: syntax error while parsing CBOR value: unexpected end of input");
CHECK_THROWS_WITH(json::from_cbor(std::vector<uint8_t>({0xBF, 0x61, 0x61, 0xF5})), CHECK_THROWS_WITH(json::from_cbor(std::vector<uint8_t>({0xBF, 0x61, 0x61, 0xF5})),
"[json.exception.parse_error.110] parse error at byte 5: unexpected end of input"); "[json.exception.parse_error.110] parse error at byte 5: syntax error while parsing CBOR string: unexpected end of input");
CHECK_THROWS_WITH(json::from_cbor(std::vector<uint8_t>({0xA1, 0x61, 0x61})), CHECK_THROWS_WITH(json::from_cbor(std::vector<uint8_t>({0xA1, 0x61, 0x61})),
"[json.exception.parse_error.110] parse error at byte 4: unexpected end of input"); "[json.exception.parse_error.110] parse error at byte 4: syntax error while parsing CBOR value: unexpected end of input");
CHECK_THROWS_WITH(json::from_cbor(std::vector<uint8_t>({0xBF, 0x61, 0x61})), CHECK_THROWS_WITH(json::from_cbor(std::vector<uint8_t>({0xBF, 0x61, 0x61})),
"[json.exception.parse_error.110] parse error at byte 4: unexpected end of input"); "[json.exception.parse_error.110] parse error at byte 4: syntax error while parsing CBOR value: unexpected end of input");
CHECK(json::from_cbor(std::vector<uint8_t>({0x18}), true, false).is_discarded()); CHECK(json::from_cbor(std::vector<uint8_t>({0x18}), true, false).is_discarded());
CHECK(json::from_cbor(std::vector<uint8_t>({0x19}), true, false).is_discarded()); CHECK(json::from_cbor(std::vector<uint8_t>({0x19}), true, false).is_discarded());
@ -1426,12 +1426,12 @@ TEST_CASE("CBOR")
{ {
CHECK_THROWS_AS(json::from_cbor(std::vector<uint8_t>({0x1c})), json::parse_error&); CHECK_THROWS_AS(json::from_cbor(std::vector<uint8_t>({0x1c})), json::parse_error&);
CHECK_THROWS_WITH(json::from_cbor(std::vector<uint8_t>({0x1c})), CHECK_THROWS_WITH(json::from_cbor(std::vector<uint8_t>({0x1c})),
"[json.exception.parse_error.112] parse error at byte 1: error reading CBOR; last byte: 0x1C"); "[json.exception.parse_error.112] parse error at byte 1: syntax error while parsing CBOR value: invalid byte: 0x1C");
CHECK(json::from_cbor(std::vector<uint8_t>({0x1c}), true, false).is_discarded()); CHECK(json::from_cbor(std::vector<uint8_t>({0x1c}), true, false).is_discarded());
CHECK_THROWS_AS(json::from_cbor(std::vector<uint8_t>({0xf8})), json::parse_error&); CHECK_THROWS_AS(json::from_cbor(std::vector<uint8_t>({0xf8})), json::parse_error&);
CHECK_THROWS_WITH(json::from_cbor(std::vector<uint8_t>({0xf8})), CHECK_THROWS_WITH(json::from_cbor(std::vector<uint8_t>({0xf8})),
"[json.exception.parse_error.112] parse error at byte 1: error reading CBOR; last byte: 0xF8"); "[json.exception.parse_error.112] parse error at byte 1: syntax error while parsing CBOR value: invalid byte: 0xF8");
CHECK(json::from_cbor(std::vector<uint8_t>({0xf8}), true, false).is_discarded()); CHECK(json::from_cbor(std::vector<uint8_t>({0xf8}), true, false).is_discarded());
} }
@ -1491,7 +1491,7 @@ TEST_CASE("CBOR")
{ {
CHECK_THROWS_AS(json::from_cbor(std::vector<uint8_t>({0xa1, 0xff, 0x01})), json::parse_error&); CHECK_THROWS_AS(json::from_cbor(std::vector<uint8_t>({0xa1, 0xff, 0x01})), json::parse_error&);
CHECK_THROWS_WITH(json::from_cbor(std::vector<uint8_t>({0xa1, 0xff, 0x01})), CHECK_THROWS_WITH(json::from_cbor(std::vector<uint8_t>({0xa1, 0xff, 0x01})),
"[json.exception.parse_error.113] parse error at byte 2: expected a CBOR string; last byte: 0xFF"); "[json.exception.parse_error.113] parse error at byte 2: syntax error while parsing CBOR string: expected length specification (0x60-0x7B) or indefinite string type (0x7F); last byte: 0xFF");
CHECK(json::from_cbor(std::vector<uint8_t>({0xa1, 0xff, 0x01}), true, false).is_discarded()); CHECK(json::from_cbor(std::vector<uint8_t>({0xa1, 0xff, 0x01}), true, false).is_discarded());
} }
@ -1509,7 +1509,7 @@ TEST_CASE("CBOR")
{ {
CHECK_THROWS_AS(json::from_cbor(vec), json::parse_error&); CHECK_THROWS_AS(json::from_cbor(vec), json::parse_error&);
CHECK_THROWS_WITH(json::from_cbor(vec), CHECK_THROWS_WITH(json::from_cbor(vec),
"[json.exception.parse_error.110] parse error at byte 2: expected end of input"); "[json.exception.parse_error.110] parse error at byte 2: syntax error while parsing CBOR value: expected end of input; last byte: 0xF6");
CHECK(json::from_cbor(vec, true, false).is_discarded()); CHECK(json::from_cbor(vec, true, false).is_discarded());
} }
} }

View file

@ -1124,7 +1124,7 @@ TEST_CASE("MessagePack")
{ {
CHECK_THROWS_AS(json::from_msgpack(std::vector<uint8_t>()), json::parse_error&); CHECK_THROWS_AS(json::from_msgpack(std::vector<uint8_t>()), json::parse_error&);
CHECK_THROWS_WITH(json::from_msgpack(std::vector<uint8_t>()), CHECK_THROWS_WITH(json::from_msgpack(std::vector<uint8_t>()),
"[json.exception.parse_error.110] parse error at byte 1: unexpected end of input"); "[json.exception.parse_error.110] parse error at byte 1: syntax error while parsing MessagePack value: unexpected end of input");
CHECK(json::from_msgpack(std::vector<uint8_t>(), true, false).is_discarded()); CHECK(json::from_msgpack(std::vector<uint8_t>(), true, false).is_discarded());
} }
@ -1151,43 +1151,43 @@ TEST_CASE("MessagePack")
CHECK_THROWS_AS(json::from_msgpack(std::vector<uint8_t>({0x81, 0xa1, 0x61})), json::parse_error&); CHECK_THROWS_AS(json::from_msgpack(std::vector<uint8_t>({0x81, 0xa1, 0x61})), json::parse_error&);
CHECK_THROWS_WITH(json::from_msgpack(std::vector<uint8_t>({0x87})), CHECK_THROWS_WITH(json::from_msgpack(std::vector<uint8_t>({0x87})),
"[json.exception.parse_error.110] parse error at byte 2: unexpected end of input"); "[json.exception.parse_error.110] parse error at byte 2: syntax error while parsing MessagePack string: unexpected end of input");
CHECK_THROWS_WITH(json::from_msgpack(std::vector<uint8_t>({0xcc})), CHECK_THROWS_WITH(json::from_msgpack(std::vector<uint8_t>({0xcc})),
"[json.exception.parse_error.110] parse error at byte 2: unexpected end of input"); "[json.exception.parse_error.110] parse error at byte 2: syntax error while parsing MessagePack number: unexpected end of input");
CHECK_THROWS_WITH(json::from_msgpack(std::vector<uint8_t>({0xcd})), CHECK_THROWS_WITH(json::from_msgpack(std::vector<uint8_t>({0xcd})),
"[json.exception.parse_error.110] parse error at byte 2: unexpected end of input"); "[json.exception.parse_error.110] parse error at byte 2: syntax error while parsing MessagePack number: unexpected end of input");
CHECK_THROWS_WITH(json::from_msgpack(std::vector<uint8_t>({0xcd, 0x00})), CHECK_THROWS_WITH(json::from_msgpack(std::vector<uint8_t>({0xcd, 0x00})),
"[json.exception.parse_error.110] parse error at byte 3: unexpected end of input"); "[json.exception.parse_error.110] parse error at byte 3: syntax error while parsing MessagePack number: unexpected end of input");
CHECK_THROWS_WITH(json::from_msgpack(std::vector<uint8_t>({0xce})), CHECK_THROWS_WITH(json::from_msgpack(std::vector<uint8_t>({0xce})),
"[json.exception.parse_error.110] parse error at byte 2: unexpected end of input"); "[json.exception.parse_error.110] parse error at byte 2: syntax error while parsing MessagePack number: unexpected end of input");
CHECK_THROWS_WITH(json::from_msgpack(std::vector<uint8_t>({0xce, 0x00})), CHECK_THROWS_WITH(json::from_msgpack(std::vector<uint8_t>({0xce, 0x00})),
"[json.exception.parse_error.110] parse error at byte 3: unexpected end of input"); "[json.exception.parse_error.110] parse error at byte 3: syntax error while parsing MessagePack number: unexpected end of input");
CHECK_THROWS_WITH(json::from_msgpack(std::vector<uint8_t>({0xce, 0x00, 0x00})), CHECK_THROWS_WITH(json::from_msgpack(std::vector<uint8_t>({0xce, 0x00, 0x00})),
"[json.exception.parse_error.110] parse error at byte 4: unexpected end of input"); "[json.exception.parse_error.110] parse error at byte 4: syntax error while parsing MessagePack number: unexpected end of input");
CHECK_THROWS_WITH(json::from_msgpack(std::vector<uint8_t>({0xce, 0x00, 0x00, 0x00})), CHECK_THROWS_WITH(json::from_msgpack(std::vector<uint8_t>({0xce, 0x00, 0x00, 0x00})),
"[json.exception.parse_error.110] parse error at byte 5: unexpected end of input"); "[json.exception.parse_error.110] parse error at byte 5: syntax error while parsing MessagePack number: unexpected end of input");
CHECK_THROWS_WITH(json::from_msgpack(std::vector<uint8_t>({0xcf})), CHECK_THROWS_WITH(json::from_msgpack(std::vector<uint8_t>({0xcf})),
"[json.exception.parse_error.110] parse error at byte 2: unexpected end of input"); "[json.exception.parse_error.110] parse error at byte 2: syntax error while parsing MessagePack number: unexpected end of input");
CHECK_THROWS_WITH(json::from_msgpack(std::vector<uint8_t>({0xcf, 0x00})), CHECK_THROWS_WITH(json::from_msgpack(std::vector<uint8_t>({0xcf, 0x00})),
"[json.exception.parse_error.110] parse error at byte 3: unexpected end of input"); "[json.exception.parse_error.110] parse error at byte 3: syntax error while parsing MessagePack number: unexpected end of input");
CHECK_THROWS_WITH(json::from_msgpack(std::vector<uint8_t>({0xcf, 0x00, 0x00})), CHECK_THROWS_WITH(json::from_msgpack(std::vector<uint8_t>({0xcf, 0x00, 0x00})),
"[json.exception.parse_error.110] parse error at byte 4: unexpected end of input"); "[json.exception.parse_error.110] parse error at byte 4: syntax error while parsing MessagePack number: unexpected end of input");
CHECK_THROWS_WITH(json::from_msgpack(std::vector<uint8_t>({0xcf, 0x00, 0x00, 0x00})), CHECK_THROWS_WITH(json::from_msgpack(std::vector<uint8_t>({0xcf, 0x00, 0x00, 0x00})),
"[json.exception.parse_error.110] parse error at byte 5: unexpected end of input"); "[json.exception.parse_error.110] parse error at byte 5: syntax error while parsing MessagePack number: unexpected end of input");
CHECK_THROWS_WITH(json::from_msgpack(std::vector<uint8_t>({0xcf, 0x00, 0x00, 0x00, 0x00})), CHECK_THROWS_WITH(json::from_msgpack(std::vector<uint8_t>({0xcf, 0x00, 0x00, 0x00, 0x00})),
"[json.exception.parse_error.110] parse error at byte 6: unexpected end of input"); "[json.exception.parse_error.110] parse error at byte 6: syntax error while parsing MessagePack number: unexpected end of input");
CHECK_THROWS_WITH(json::from_msgpack(std::vector<uint8_t>({0xcf, 0x00, 0x00, 0x00, 0x00, 0x00})), CHECK_THROWS_WITH(json::from_msgpack(std::vector<uint8_t>({0xcf, 0x00, 0x00, 0x00, 0x00, 0x00})),
"[json.exception.parse_error.110] parse error at byte 7: unexpected end of input"); "[json.exception.parse_error.110] parse error at byte 7: syntax error while parsing MessagePack number: unexpected end of input");
CHECK_THROWS_WITH(json::from_msgpack(std::vector<uint8_t>({0xcf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00})), CHECK_THROWS_WITH(json::from_msgpack(std::vector<uint8_t>({0xcf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00})),
"[json.exception.parse_error.110] parse error at byte 8: unexpected end of input"); "[json.exception.parse_error.110] parse error at byte 8: syntax error while parsing MessagePack number: unexpected end of input");
CHECK_THROWS_WITH(json::from_msgpack(std::vector<uint8_t>({0xcf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00})), CHECK_THROWS_WITH(json::from_msgpack(std::vector<uint8_t>({0xcf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00})),
"[json.exception.parse_error.110] parse error at byte 9: unexpected end of input"); "[json.exception.parse_error.110] parse error at byte 9: syntax error while parsing MessagePack number: unexpected end of input");
CHECK_THROWS_WITH(json::from_msgpack(std::vector<uint8_t>({0xa5, 0x68, 0x65})), CHECK_THROWS_WITH(json::from_msgpack(std::vector<uint8_t>({0xa5, 0x68, 0x65})),
"[json.exception.parse_error.110] parse error at byte 4: unexpected end of input"); "[json.exception.parse_error.110] parse error at byte 4: syntax error while parsing MessagePack string: unexpected end of input");
CHECK_THROWS_WITH(json::from_msgpack(std::vector<uint8_t>({0x92, 0x01})), CHECK_THROWS_WITH(json::from_msgpack(std::vector<uint8_t>({0x92, 0x01})),
"[json.exception.parse_error.110] parse error at byte 3: unexpected end of input"); "[json.exception.parse_error.110] parse error at byte 3: syntax error while parsing MessagePack value: unexpected end of input");
CHECK_THROWS_WITH(json::from_msgpack(std::vector<uint8_t>({0x81, 0xa1, 0x61})), CHECK_THROWS_WITH(json::from_msgpack(std::vector<uint8_t>({0x81, 0xa1, 0x61})),
"[json.exception.parse_error.110] parse error at byte 4: unexpected end of input"); "[json.exception.parse_error.110] parse error at byte 4: syntax error while parsing MessagePack value: unexpected end of input");
CHECK(json::from_msgpack(std::vector<uint8_t>({0x87}), true, false).is_discarded()); CHECK(json::from_msgpack(std::vector<uint8_t>({0x87}), true, false).is_discarded());
CHECK(json::from_msgpack(std::vector<uint8_t>({0xcc}), true, false).is_discarded()); CHECK(json::from_msgpack(std::vector<uint8_t>({0xcc}), true, false).is_discarded());
@ -1216,12 +1216,12 @@ TEST_CASE("MessagePack")
{ {
CHECK_THROWS_AS(json::from_msgpack(std::vector<uint8_t>({0xc1})), json::parse_error&); CHECK_THROWS_AS(json::from_msgpack(std::vector<uint8_t>({0xc1})), json::parse_error&);
CHECK_THROWS_WITH(json::from_msgpack(std::vector<uint8_t>({0xc1})), CHECK_THROWS_WITH(json::from_msgpack(std::vector<uint8_t>({0xc1})),
"[json.exception.parse_error.112] parse error at byte 1: error reading MessagePack; last byte: 0xC1"); "[json.exception.parse_error.112] parse error at byte 1: syntax error while parsing MessagePack value: invalid byte: 0xC1");
CHECK(json::from_msgpack(std::vector<uint8_t>({0xc6}), true, false).is_discarded()); CHECK(json::from_msgpack(std::vector<uint8_t>({0xc6}), true, false).is_discarded());
CHECK_THROWS_AS(json::from_msgpack(std::vector<uint8_t>({0xc6})), json::parse_error&); CHECK_THROWS_AS(json::from_msgpack(std::vector<uint8_t>({0xc6})), json::parse_error&);
CHECK_THROWS_WITH(json::from_msgpack(std::vector<uint8_t>({0xc6})), CHECK_THROWS_WITH(json::from_msgpack(std::vector<uint8_t>({0xc6})),
"[json.exception.parse_error.112] parse error at byte 1: error reading MessagePack; last byte: 0xC6"); "[json.exception.parse_error.112] parse error at byte 1: syntax error while parsing MessagePack value: invalid byte: 0xC6");
CHECK(json::from_msgpack(std::vector<uint8_t>({0xc6}), true, false).is_discarded()); CHECK(json::from_msgpack(std::vector<uint8_t>({0xc6}), true, false).is_discarded());
} }
@ -1249,7 +1249,7 @@ TEST_CASE("MessagePack")
{ {
CHECK_THROWS_AS(json::from_msgpack(std::vector<uint8_t>({0x81, 0xff, 0x01})), json::parse_error&); CHECK_THROWS_AS(json::from_msgpack(std::vector<uint8_t>({0x81, 0xff, 0x01})), json::parse_error&);
CHECK_THROWS_WITH(json::from_msgpack(std::vector<uint8_t>({0x81, 0xff, 0x01})), CHECK_THROWS_WITH(json::from_msgpack(std::vector<uint8_t>({0x81, 0xff, 0x01})),
"[json.exception.parse_error.113] parse error at byte 2: expected a MessagePack string; last byte: 0xFF"); "[json.exception.parse_error.113] parse error at byte 2: syntax error while parsing MessagePack string: expected length specification (0xA0-0xBF, 0xD9-0xDB); last byte: 0xFF");
CHECK(json::from_msgpack(std::vector<uint8_t>({0x81, 0xff, 0x01}), true, false).is_discarded()); CHECK(json::from_msgpack(std::vector<uint8_t>({0x81, 0xff, 0x01}), true, false).is_discarded());
} }
@ -1266,7 +1266,7 @@ TEST_CASE("MessagePack")
{ {
CHECK_THROWS_AS(json::from_msgpack(vec), json::parse_error&); CHECK_THROWS_AS(json::from_msgpack(vec), json::parse_error&);
CHECK_THROWS_WITH(json::from_msgpack(vec), CHECK_THROWS_WITH(json::from_msgpack(vec),
"[json.exception.parse_error.110] parse error at byte 2: expected end of input"); "[json.exception.parse_error.110] parse error at byte 2: syntax error while parsing MessagePack value: expected end of input; last byte: 0xC0");
CHECK(json::from_msgpack(vec, true, false).is_discarded()); CHECK(json::from_msgpack(vec, true, false).is_discarded());
} }
} }

View file

@ -930,7 +930,7 @@ TEST_CASE("regression tests")
std::vector<uint8_t> vec {0x65, 0xf5, 0x0a, 0x48, 0x21}; std::vector<uint8_t> vec {0x65, 0xf5, 0x0a, 0x48, 0x21};
CHECK_THROWS_AS(json::from_cbor(vec), json::parse_error&); CHECK_THROWS_AS(json::from_cbor(vec), json::parse_error&);
CHECK_THROWS_WITH(json::from_cbor(vec), CHECK_THROWS_WITH(json::from_cbor(vec),
"[json.exception.parse_error.110] parse error at byte 6: unexpected end of input"); "[json.exception.parse_error.110] parse error at byte 6: syntax error while parsing CBOR string: unexpected end of input");
} }
SECTION("issue #407 - Heap-buffer-overflow (OSS-Fuzz issue 343)") SECTION("issue #407 - Heap-buffer-overflow (OSS-Fuzz issue 343)")
@ -939,31 +939,31 @@ TEST_CASE("regression tests")
std::vector<uint8_t> vec1 {0xcb, 0x8f, 0x0a}; std::vector<uint8_t> vec1 {0xcb, 0x8f, 0x0a};
CHECK_THROWS_AS(json::from_msgpack(vec1), json::parse_error&); CHECK_THROWS_AS(json::from_msgpack(vec1), json::parse_error&);
CHECK_THROWS_WITH(json::from_msgpack(vec1), CHECK_THROWS_WITH(json::from_msgpack(vec1),
"[json.exception.parse_error.110] parse error at byte 4: unexpected end of input"); "[json.exception.parse_error.110] parse error at byte 4: syntax error while parsing MessagePack number: unexpected end of input");
// related test case: incomplete float32 // related test case: incomplete float32
std::vector<uint8_t> vec2 {0xca, 0x8f, 0x0a}; std::vector<uint8_t> vec2 {0xca, 0x8f, 0x0a};
CHECK_THROWS_AS(json::from_msgpack(vec2), json::parse_error&); CHECK_THROWS_AS(json::from_msgpack(vec2), json::parse_error&);
CHECK_THROWS_WITH(json::from_msgpack(vec2), CHECK_THROWS_WITH(json::from_msgpack(vec2),
"[json.exception.parse_error.110] parse error at byte 4: unexpected end of input"); "[json.exception.parse_error.110] parse error at byte 4: syntax error while parsing MessagePack number: unexpected end of input");
// related test case: incomplete Half-Precision Float (CBOR) // related test case: incomplete Half-Precision Float (CBOR)
std::vector<uint8_t> vec3 {0xf9, 0x8f}; std::vector<uint8_t> vec3 {0xf9, 0x8f};
CHECK_THROWS_AS(json::from_cbor(vec3), json::parse_error&); CHECK_THROWS_AS(json::from_cbor(vec3), json::parse_error&);
CHECK_THROWS_WITH(json::from_cbor(vec3), CHECK_THROWS_WITH(json::from_cbor(vec3),
"[json.exception.parse_error.110] parse error at byte 3: unexpected end of input"); "[json.exception.parse_error.110] parse error at byte 3: syntax error while parsing CBOR number: unexpected end of input");
// related test case: incomplete Single-Precision Float (CBOR) // related test case: incomplete Single-Precision Float (CBOR)
std::vector<uint8_t> vec4 {0xfa, 0x8f, 0x0a}; std::vector<uint8_t> vec4 {0xfa, 0x8f, 0x0a};
CHECK_THROWS_AS(json::from_cbor(vec4), json::parse_error&); CHECK_THROWS_AS(json::from_cbor(vec4), json::parse_error&);
CHECK_THROWS_WITH(json::from_cbor(vec4), CHECK_THROWS_WITH(json::from_cbor(vec4),
"[json.exception.parse_error.110] parse error at byte 4: unexpected end of input"); "[json.exception.parse_error.110] parse error at byte 4: syntax error while parsing CBOR number: unexpected end of input");
// related test case: incomplete Double-Precision Float (CBOR) // related test case: incomplete Double-Precision Float (CBOR)
std::vector<uint8_t> vec5 {0xfb, 0x8f, 0x0a}; std::vector<uint8_t> vec5 {0xfb, 0x8f, 0x0a};
CHECK_THROWS_AS(json::from_cbor(vec5), json::parse_error&); CHECK_THROWS_AS(json::from_cbor(vec5), json::parse_error&);
CHECK_THROWS_WITH(json::from_cbor(vec5), CHECK_THROWS_WITH(json::from_cbor(vec5),
"[json.exception.parse_error.110] parse error at byte 4: unexpected end of input"); "[json.exception.parse_error.110] parse error at byte 4: syntax error while parsing CBOR number: unexpected end of input");
} }
SECTION("issue #408 - Heap-buffer-overflow (OSS-Fuzz issue 344)") SECTION("issue #408 - Heap-buffer-overflow (OSS-Fuzz issue 344)")
@ -972,7 +972,7 @@ TEST_CASE("regression tests")
std::vector<uint8_t> vec1 {0x87}; std::vector<uint8_t> vec1 {0x87};
CHECK_THROWS_AS(json::from_msgpack(vec1), json::parse_error&); CHECK_THROWS_AS(json::from_msgpack(vec1), json::parse_error&);
CHECK_THROWS_WITH(json::from_msgpack(vec1), CHECK_THROWS_WITH(json::from_msgpack(vec1),
"[json.exception.parse_error.110] parse error at byte 2: unexpected end of input"); "[json.exception.parse_error.110] parse error at byte 2: syntax error while parsing MessagePack string: unexpected end of input");
// more test cases for MessagePack // more test cases for MessagePack
for (auto b : for (auto b :
@ -1006,10 +1006,10 @@ TEST_CASE("regression tests")
std::vector<uint8_t> vec2; std::vector<uint8_t> vec2;
CHECK_THROWS_AS(json::from_cbor(vec2), json::parse_error&); CHECK_THROWS_AS(json::from_cbor(vec2), json::parse_error&);
CHECK_THROWS_WITH(json::from_cbor(vec2), CHECK_THROWS_WITH(json::from_cbor(vec2),
"[json.exception.parse_error.110] parse error at byte 1: unexpected end of input"); "[json.exception.parse_error.110] parse error at byte 1: syntax error while parsing CBOR value: unexpected end of input");
CHECK_THROWS_AS(json::from_msgpack(vec2), json::parse_error&); CHECK_THROWS_AS(json::from_msgpack(vec2), json::parse_error&);
CHECK_THROWS_WITH(json::from_msgpack(vec2), CHECK_THROWS_WITH(json::from_msgpack(vec2),
"[json.exception.parse_error.110] parse error at byte 1: unexpected end of input"); "[json.exception.parse_error.110] parse error at byte 1: syntax error while parsing MessagePack value: unexpected end of input");
} }
SECTION("issue #411 - Heap-buffer-overflow (OSS-Fuzz issue 366)") SECTION("issue #411 - Heap-buffer-overflow (OSS-Fuzz issue 366)")
@ -1018,19 +1018,19 @@ TEST_CASE("regression tests")
std::vector<uint8_t> vec1 {0x7f}; std::vector<uint8_t> vec1 {0x7f};
CHECK_THROWS_AS(json::from_cbor(vec1), json::parse_error&); CHECK_THROWS_AS(json::from_cbor(vec1), json::parse_error&);
CHECK_THROWS_WITH(json::from_cbor(vec1), CHECK_THROWS_WITH(json::from_cbor(vec1),
"[json.exception.parse_error.110] parse error at byte 2: unexpected end of input"); "[json.exception.parse_error.110] parse error at byte 2: syntax error while parsing CBOR string: unexpected end of input");
// related test case: empty array (indefinite length) // related test case: empty array (indefinite length)
std::vector<uint8_t> vec2 {0x9f}; std::vector<uint8_t> vec2 {0x9f};
CHECK_THROWS_AS(json::from_cbor(vec2), json::parse_error&); CHECK_THROWS_AS(json::from_cbor(vec2), json::parse_error&);
CHECK_THROWS_WITH(json::from_cbor(vec2), CHECK_THROWS_WITH(json::from_cbor(vec2),
"[json.exception.parse_error.110] parse error at byte 2: unexpected end of input"); "[json.exception.parse_error.110] parse error at byte 2: syntax error while parsing CBOR value: unexpected end of input");
// related test case: empty map (indefinite length) // related test case: empty map (indefinite length)
std::vector<uint8_t> vec3 {0xbf}; std::vector<uint8_t> vec3 {0xbf};
CHECK_THROWS_AS(json::from_cbor(vec3), json::parse_error&); CHECK_THROWS_AS(json::from_cbor(vec3), json::parse_error&);
CHECK_THROWS_WITH(json::from_cbor(vec3), CHECK_THROWS_WITH(json::from_cbor(vec3),
"[json.exception.parse_error.110] parse error at byte 2: unexpected end of input"); "[json.exception.parse_error.110] parse error at byte 2: syntax error while parsing CBOR string: unexpected end of input");
} }
SECTION("issue #412 - Heap-buffer-overflow (OSS-Fuzz issue 367)") SECTION("issue #412 - Heap-buffer-overflow (OSS-Fuzz issue 367)")
@ -1058,25 +1058,25 @@ TEST_CASE("regression tests")
}; };
CHECK_THROWS_AS(json::from_cbor(vec), json::parse_error&); CHECK_THROWS_AS(json::from_cbor(vec), json::parse_error&);
CHECK_THROWS_WITH(json::from_cbor(vec), CHECK_THROWS_WITH(json::from_cbor(vec),
"[json.exception.parse_error.113] parse error at byte 2: expected a CBOR string; last byte: 0x98"); "[json.exception.parse_error.113] parse error at byte 2: syntax error while parsing CBOR string: expected length specification (0x60-0x7B) or indefinite string type (0x7F); last byte: 0x98");
// related test case: nonempty UTF-8 string (indefinite length) // related test case: nonempty UTF-8 string (indefinite length)
std::vector<uint8_t> vec1 {0x7f, 0x61, 0x61}; std::vector<uint8_t> vec1 {0x7f, 0x61, 0x61};
CHECK_THROWS_AS(json::from_cbor(vec1), json::parse_error&); CHECK_THROWS_AS(json::from_cbor(vec1), json::parse_error&);
CHECK_THROWS_WITH(json::from_cbor(vec1), CHECK_THROWS_WITH(json::from_cbor(vec1),
"[json.exception.parse_error.110] parse error at byte 4: unexpected end of input"); "[json.exception.parse_error.110] parse error at byte 4: syntax error while parsing CBOR string: unexpected end of input");
// related test case: nonempty array (indefinite length) // related test case: nonempty array (indefinite length)
std::vector<uint8_t> vec2 {0x9f, 0x01}; std::vector<uint8_t> vec2 {0x9f, 0x01};
CHECK_THROWS_AS(json::from_cbor(vec2), json::parse_error&); CHECK_THROWS_AS(json::from_cbor(vec2), json::parse_error&);
CHECK_THROWS_WITH(json::from_cbor(vec2), CHECK_THROWS_WITH(json::from_cbor(vec2),
"[json.exception.parse_error.110] parse error at byte 3: unexpected end of input"); "[json.exception.parse_error.110] parse error at byte 3: syntax error while parsing CBOR value: unexpected end of input");
// related test case: nonempty map (indefinite length) // related test case: nonempty map (indefinite length)
std::vector<uint8_t> vec3 {0xbf, 0x61, 0x61, 0x01}; std::vector<uint8_t> vec3 {0xbf, 0x61, 0x61, 0x01};
CHECK_THROWS_AS(json::from_cbor(vec3), json::parse_error&); CHECK_THROWS_AS(json::from_cbor(vec3), json::parse_error&);
CHECK_THROWS_WITH(json::from_cbor(vec3), CHECK_THROWS_WITH(json::from_cbor(vec3),
"[json.exception.parse_error.110] parse error at byte 5: unexpected end of input"); "[json.exception.parse_error.110] parse error at byte 5: syntax error while parsing CBOR string: unexpected end of input");
} }
SECTION("issue #414 - compare with literal 0)") SECTION("issue #414 - compare with literal 0)")
@ -1111,7 +1111,7 @@ TEST_CASE("regression tests")
}; };
CHECK_THROWS_AS(json::from_cbor(vec1), json::parse_error&); CHECK_THROWS_AS(json::from_cbor(vec1), json::parse_error&);
CHECK_THROWS_WITH(json::from_cbor(vec1), CHECK_THROWS_WITH(json::from_cbor(vec1),
"[json.exception.parse_error.113] parse error at byte 13: expected a CBOR string; last byte: 0xB4"); "[json.exception.parse_error.113] parse error at byte 13: syntax error while parsing CBOR string: expected length specification (0x60-0x7B) or indefinite string type (0x7F); last byte: 0xB4");
// related test case: double-precision // related test case: double-precision
std::vector<uint8_t> vec2 std::vector<uint8_t> vec2
@ -1125,7 +1125,7 @@ TEST_CASE("regression tests")
}; };
CHECK_THROWS_AS(json::from_cbor(vec2), json::parse_error&); CHECK_THROWS_AS(json::from_cbor(vec2), json::parse_error&);
CHECK_THROWS_WITH(json::from_cbor(vec2), CHECK_THROWS_WITH(json::from_cbor(vec2),
"[json.exception.parse_error.113] parse error at byte 13: expected a CBOR string; last byte: 0xB4"); "[json.exception.parse_error.113] parse error at byte 13: syntax error while parsing CBOR string: expected length specification (0x60-0x7B) or indefinite string type (0x7F); last byte: 0xB4");
} }
SECTION("issue #452 - Heap-buffer-overflow (OSS-Fuzz issue 585)") SECTION("issue #452 - Heap-buffer-overflow (OSS-Fuzz issue 585)")

View file

@ -1299,7 +1299,7 @@ TEST_CASE("UBJSON")
{ {
CHECK_THROWS_AS(json::from_ubjson(vec), json::parse_error&); CHECK_THROWS_AS(json::from_ubjson(vec), json::parse_error&);
CHECK_THROWS_WITH(json::from_ubjson(vec), CHECK_THROWS_WITH(json::from_ubjson(vec),
"[json.exception.parse_error.110] parse error at byte 2: expected end of input"); "[json.exception.parse_error.110] parse error at byte 2: syntax error while parsing UBJSON value: expected end of input; last byte: 0x5A");
} }
} }
@ -1308,7 +1308,7 @@ TEST_CASE("UBJSON")
// larger than max int64 // larger than max int64
json j = 9223372036854775808llu; json j = 9223372036854775808llu;
CHECK_THROWS_AS(json::to_ubjson(j), json::out_of_range&); CHECK_THROWS_AS(json::to_ubjson(j), json::out_of_range&);
CHECK_THROWS_WITH(json::to_ubjson(j), "[json.exception.out_of_range.407] number overflow serializing 9223372036854775808"); CHECK_THROWS_WITH(json::to_ubjson(j), "[json.exception.out_of_range.407] integer number 9223372036854775808 cannot be represented by UBJSON as it does not fit int64");
} }
SECTION("excessive size") SECTION("excessive size")
@ -1529,7 +1529,7 @@ TEST_CASE("UBJSON")
{ {
CHECK_THROWS_AS(json::from_ubjson(std::vector<uint8_t>()), json::parse_error&); CHECK_THROWS_AS(json::from_ubjson(std::vector<uint8_t>()), json::parse_error&);
CHECK_THROWS_WITH(json::from_ubjson(std::vector<uint8_t>()), CHECK_THROWS_WITH(json::from_ubjson(std::vector<uint8_t>()),
"[json.exception.parse_error.110] parse error at byte 1: unexpected end of input"); "[json.exception.parse_error.110] parse error at byte 1: syntax error while parsing UBJSON value: unexpected end of input");
} }
SECTION("char") SECTION("char")
@ -1538,14 +1538,14 @@ TEST_CASE("UBJSON")
{ {
std::vector<uint8_t> v = {'C'}; std::vector<uint8_t> v = {'C'};
CHECK_THROWS_AS(json::from_ubjson(v), json::parse_error&); CHECK_THROWS_AS(json::from_ubjson(v), json::parse_error&);
CHECK_THROWS_WITH(json::from_ubjson(v), "[json.exception.parse_error.110] parse error at byte 2: unexpected end of input"); CHECK_THROWS_WITH(json::from_ubjson(v), "[json.exception.parse_error.110] parse error at byte 2: syntax error while parsing UBJSON char: unexpected end of input");
} }
SECTION("byte out of range") SECTION("byte out of range")
{ {
std::vector<uint8_t> v = {'C', 130}; std::vector<uint8_t> v = {'C', 130};
CHECK_THROWS_AS(json::from_ubjson(v), json::parse_error&); CHECK_THROWS_AS(json::from_ubjson(v), json::parse_error&);
CHECK_THROWS_WITH(json::from_ubjson(v), "[json.exception.parse_error.113] parse error at byte 2: byte after 'C' must be in range 0x00..0x7F; last byte: 0x82"); CHECK_THROWS_WITH(json::from_ubjson(v), "[json.exception.parse_error.113] parse error at byte 2: syntax error while parsing UBJSON char: byte after 'C' must be in range 0x00..0x7F; last byte: 0x82");
} }
} }
@ -1555,14 +1555,14 @@ TEST_CASE("UBJSON")
{ {
std::vector<uint8_t> v = {'S'}; std::vector<uint8_t> v = {'S'};
CHECK_THROWS_AS(json::from_ubjson(v), json::parse_error&); CHECK_THROWS_AS(json::from_ubjson(v), json::parse_error&);
CHECK_THROWS_WITH(json::from_ubjson(v), "[json.exception.parse_error.110] parse error at byte 2: unexpected end of input"); CHECK_THROWS_WITH(json::from_ubjson(v), "[json.exception.parse_error.110] parse error at byte 2: syntax error while parsing UBJSON value: unexpected end of input");
} }
SECTION("invalid byte") SECTION("invalid byte")
{ {
std::vector<uint8_t> v = {'S', '1', 'a'}; std::vector<uint8_t> v = {'S', '1', 'a'};
CHECK_THROWS_AS(json::from_ubjson(v), json::parse_error&); CHECK_THROWS_AS(json::from_ubjson(v), json::parse_error&);
CHECK_THROWS_WITH(json::from_ubjson(v), "[json.exception.parse_error.113] parse error at byte 2: expected a UBJSON string; last byte: 0x31"); CHECK_THROWS_WITH(json::from_ubjson(v), "[json.exception.parse_error.113] parse error at byte 2: syntax error while parsing UBJSON string: expected length type specification (U, i, I, l, L); last byte: 0x31");
} }
} }
@ -1572,7 +1572,7 @@ TEST_CASE("UBJSON")
{ {
std::vector<uint8_t> v = {'[', '$', 'i', 2}; std::vector<uint8_t> v = {'[', '$', 'i', 2};
CHECK_THROWS_AS(json::from_ubjson(v), json::parse_error&); CHECK_THROWS_AS(json::from_ubjson(v), json::parse_error&);
CHECK_THROWS_WITH(json::from_ubjson(v), "[json.exception.parse_error.112] parse error at byte 4: expected '#' after UBJSON type information; last byte: 0x02"); CHECK_THROWS_WITH(json::from_ubjson(v), "[json.exception.parse_error.112] parse error at byte 4: syntax error while parsing UBJSON size: expected '#' after type information; last byte: 0x02");
} }
} }
@ -1580,17 +1580,17 @@ TEST_CASE("UBJSON")
{ {
std::vector<uint8_t> vS = {'S'}; std::vector<uint8_t> vS = {'S'};
CHECK_THROWS_AS(json::from_ubjson(vS), json::parse_error&); CHECK_THROWS_AS(json::from_ubjson(vS), json::parse_error&);
CHECK_THROWS_WITH(json::from_ubjson(vS), "[json.exception.parse_error.110] parse error at byte 2: unexpected end of input"); CHECK_THROWS_WITH(json::from_ubjson(vS), "[json.exception.parse_error.110] parse error at byte 2: syntax error while parsing UBJSON value: unexpected end of input");
CHECK(json::from_ubjson(vS, true, false).is_discarded()); CHECK(json::from_ubjson(vS, true, false).is_discarded());
std::vector<uint8_t> v = {'S', 'i', '2', 'a'}; std::vector<uint8_t> v = {'S', 'i', '2', 'a'};
CHECK_THROWS_AS(json::from_ubjson(v), json::parse_error&); CHECK_THROWS_AS(json::from_ubjson(v), json::parse_error&);
CHECK_THROWS_WITH(json::from_ubjson(v), "[json.exception.parse_error.110] parse error at byte 5: unexpected end of input"); CHECK_THROWS_WITH(json::from_ubjson(v), "[json.exception.parse_error.110] parse error at byte 5: syntax error while parsing UBJSON string: unexpected end of input");
CHECK(json::from_ubjson(v, true, false).is_discarded()); CHECK(json::from_ubjson(v, true, false).is_discarded());
std::vector<uint8_t> vC = {'C'}; std::vector<uint8_t> vC = {'C'};
CHECK_THROWS_AS(json::from_ubjson(vC), json::parse_error&); CHECK_THROWS_AS(json::from_ubjson(vC), json::parse_error&);
CHECK_THROWS_WITH(json::from_ubjson(vC), "[json.exception.parse_error.110] parse error at byte 2: unexpected end of input"); CHECK_THROWS_WITH(json::from_ubjson(vC), "[json.exception.parse_error.110] parse error at byte 2: syntax error while parsing UBJSON char: unexpected end of input");
CHECK(json::from_ubjson(vC, true, false).is_discarded()); CHECK(json::from_ubjson(vC, true, false).is_discarded());
} }
@ -1598,32 +1598,32 @@ TEST_CASE("UBJSON")
{ {
std::vector<uint8_t> vU = {'[', '#', 'U'}; std::vector<uint8_t> vU = {'[', '#', 'U'};
CHECK_THROWS_AS(json::from_ubjson(vU), json::parse_error&); CHECK_THROWS_AS(json::from_ubjson(vU), json::parse_error&);
CHECK_THROWS_WITH(json::from_ubjson(vU), "[json.exception.parse_error.110] parse error at byte 4: unexpected end of input"); CHECK_THROWS_WITH(json::from_ubjson(vU), "[json.exception.parse_error.110] parse error at byte 4: syntax error while parsing UBJSON number: unexpected end of input");
CHECK(json::from_ubjson(vU, true, false).is_discarded()); CHECK(json::from_ubjson(vU, true, false).is_discarded());
std::vector<uint8_t> vi = {'[', '#', 'i'}; std::vector<uint8_t> vi = {'[', '#', 'i'};
CHECK_THROWS_AS(json::from_ubjson(vi), json::parse_error&); CHECK_THROWS_AS(json::from_ubjson(vi), json::parse_error&);
CHECK_THROWS_WITH(json::from_ubjson(vi), "[json.exception.parse_error.110] parse error at byte 4: unexpected end of input"); CHECK_THROWS_WITH(json::from_ubjson(vi), "[json.exception.parse_error.110] parse error at byte 4: syntax error while parsing UBJSON number: unexpected end of input");
CHECK(json::from_ubjson(vi, true, false).is_discarded()); CHECK(json::from_ubjson(vi, true, false).is_discarded());
std::vector<uint8_t> vI = {'[', '#', 'I'}; std::vector<uint8_t> vI = {'[', '#', 'I'};
CHECK_THROWS_AS(json::from_ubjson(vI), json::parse_error&); CHECK_THROWS_AS(json::from_ubjson(vI), json::parse_error&);
CHECK_THROWS_WITH(json::from_ubjson(vI), "[json.exception.parse_error.110] parse error at byte 4: unexpected end of input"); CHECK_THROWS_WITH(json::from_ubjson(vI), "[json.exception.parse_error.110] parse error at byte 4: syntax error while parsing UBJSON number: unexpected end of input");
CHECK(json::from_ubjson(vI, true, false).is_discarded()); CHECK(json::from_ubjson(vI, true, false).is_discarded());
std::vector<uint8_t> vl = {'[', '#', 'l'}; std::vector<uint8_t> vl = {'[', '#', 'l'};
CHECK_THROWS_AS(json::from_ubjson(vl), json::parse_error&); CHECK_THROWS_AS(json::from_ubjson(vl), json::parse_error&);
CHECK_THROWS_WITH(json::from_ubjson(vl), "[json.exception.parse_error.110] parse error at byte 4: unexpected end of input"); CHECK_THROWS_WITH(json::from_ubjson(vl), "[json.exception.parse_error.110] parse error at byte 4: syntax error while parsing UBJSON number: unexpected end of input");
CHECK(json::from_ubjson(vl, true, false).is_discarded()); CHECK(json::from_ubjson(vl, true, false).is_discarded());
std::vector<uint8_t> vL = {'[', '#', 'L'}; std::vector<uint8_t> vL = {'[', '#', 'L'};
CHECK_THROWS_AS(json::from_ubjson(vL), json::parse_error&); CHECK_THROWS_AS(json::from_ubjson(vL), json::parse_error&);
CHECK_THROWS_WITH(json::from_ubjson(vL), "[json.exception.parse_error.110] parse error at byte 4: unexpected end of input"); CHECK_THROWS_WITH(json::from_ubjson(vL), "[json.exception.parse_error.110] parse error at byte 4: syntax error while parsing UBJSON number: unexpected end of input");
CHECK(json::from_ubjson(vL, true, false).is_discarded()); CHECK(json::from_ubjson(vL, true, false).is_discarded());
std::vector<uint8_t> v0 = {'[', '#', 'T', ']'}; std::vector<uint8_t> v0 = {'[', '#', 'T', ']'};
CHECK_THROWS_AS(json::from_ubjson(v0), json::parse_error&); CHECK_THROWS_AS(json::from_ubjson(v0), json::parse_error&);
CHECK_THROWS_WITH(json::from_ubjson(v0), "[json.exception.parse_error.113] parse error at byte 3: byte after '#' must denote a number type; last byte: 0x54"); CHECK_THROWS_WITH(json::from_ubjson(v0), "[json.exception.parse_error.113] parse error at byte 3: syntax error while parsing UBJSON size: expected length type specification (U, i, I, l, L) after '#'; last byte: 0x54");
CHECK(json::from_ubjson(v0, true, false).is_discarded()); CHECK(json::from_ubjson(v0, true, false).is_discarded());
} }
@ -1631,17 +1631,17 @@ TEST_CASE("UBJSON")
{ {
std::vector<uint8_t> v0 = {'[', '$'}; std::vector<uint8_t> v0 = {'[', '$'};
CHECK_THROWS_AS(json::from_ubjson(v0), json::parse_error&); CHECK_THROWS_AS(json::from_ubjson(v0), json::parse_error&);
CHECK_THROWS_WITH(json::from_ubjson(v0), "[json.exception.parse_error.110] parse error at byte 3: unexpected end of input"); CHECK_THROWS_WITH(json::from_ubjson(v0), "[json.exception.parse_error.110] parse error at byte 3: syntax error while parsing UBJSON type: unexpected end of input");
CHECK(json::from_ubjson(v0, true, false).is_discarded()); CHECK(json::from_ubjson(v0, true, false).is_discarded());
std::vector<uint8_t> vi = {'[', '$', '#'}; std::vector<uint8_t> vi = {'[', '$', '#'};
CHECK_THROWS_AS(json::from_ubjson(vi), json::parse_error&); CHECK_THROWS_AS(json::from_ubjson(vi), json::parse_error&);
CHECK_THROWS_WITH(json::from_ubjson(vi), "[json.exception.parse_error.110] parse error at byte 4: unexpected end of input"); CHECK_THROWS_WITH(json::from_ubjson(vi), "[json.exception.parse_error.110] parse error at byte 4: syntax error while parsing UBJSON value: unexpected end of input");
CHECK(json::from_ubjson(vi, true, false).is_discarded()); CHECK(json::from_ubjson(vi, true, false).is_discarded());
std::vector<uint8_t> vT = {'[', '$', 'T'}; std::vector<uint8_t> vT = {'[', '$', 'T'};
CHECK_THROWS_AS(json::from_ubjson(vT), json::parse_error&); CHECK_THROWS_AS(json::from_ubjson(vT), json::parse_error&);
CHECK_THROWS_WITH(json::from_ubjson(vT), "[json.exception.parse_error.110] parse error at byte 4: unexpected end of input"); CHECK_THROWS_WITH(json::from_ubjson(vT), "[json.exception.parse_error.110] parse error at byte 4: syntax error while parsing UBJSON value: unexpected end of input");
CHECK(json::from_ubjson(vT, true, false).is_discarded()); CHECK(json::from_ubjson(vT, true, false).is_discarded());
} }
@ -1649,17 +1649,17 @@ TEST_CASE("UBJSON")
{ {
std::vector<uint8_t> vST = {'[', '$', 'i', '#', 'i', 2, 1}; std::vector<uint8_t> vST = {'[', '$', 'i', '#', 'i', 2, 1};
CHECK_THROWS_AS(json::from_ubjson(vST), json::parse_error&); CHECK_THROWS_AS(json::from_ubjson(vST), json::parse_error&);
CHECK_THROWS_WITH(json::from_ubjson(vST), "[json.exception.parse_error.110] parse error at byte 8: unexpected end of input"); CHECK_THROWS_WITH(json::from_ubjson(vST), "[json.exception.parse_error.110] parse error at byte 8: syntax error while parsing UBJSON number: unexpected end of input");
CHECK(json::from_ubjson(vST, true, false).is_discarded()); CHECK(json::from_ubjson(vST, true, false).is_discarded());
std::vector<uint8_t> vS = {'[', '#', 'i', 2, 'i', 1}; std::vector<uint8_t> vS = {'[', '#', 'i', 2, 'i', 1};
CHECK_THROWS_AS(json::from_ubjson(vS), json::parse_error&); CHECK_THROWS_AS(json::from_ubjson(vS), json::parse_error&);
CHECK_THROWS_WITH(json::from_ubjson(vS), "[json.exception.parse_error.110] parse error at byte 7: unexpected end of input"); CHECK_THROWS_WITH(json::from_ubjson(vS), "[json.exception.parse_error.110] parse error at byte 7: syntax error while parsing UBJSON value: unexpected end of input");
CHECK(json::from_ubjson(vS, true, false).is_discarded()); CHECK(json::from_ubjson(vS, true, false).is_discarded());
std::vector<uint8_t> v = {'[', 'i', 2, 'i', 1}; std::vector<uint8_t> v = {'[', 'i', 2, 'i', 1};
CHECK_THROWS_AS(json::from_ubjson(v), json::parse_error&); CHECK_THROWS_AS(json::from_ubjson(v), json::parse_error&);
CHECK_THROWS_WITH(json::from_ubjson(v), "[json.exception.parse_error.110] parse error at byte 6: unexpected end of input"); CHECK_THROWS_WITH(json::from_ubjson(v), "[json.exception.parse_error.110] parse error at byte 6: syntax error while parsing UBJSON value: unexpected end of input");
CHECK(json::from_ubjson(v, true, false).is_discarded()); CHECK(json::from_ubjson(v, true, false).is_discarded());
} }
@ -1667,42 +1667,42 @@ TEST_CASE("UBJSON")
{ {
std::vector<uint8_t> vST = {'{', '$', 'i', '#', 'i', 2, 'i', 1, 'a', 1}; std::vector<uint8_t> vST = {'{', '$', 'i', '#', 'i', 2, 'i', 1, 'a', 1};
CHECK_THROWS_AS(json::from_ubjson(vST), json::parse_error&); CHECK_THROWS_AS(json::from_ubjson(vST), json::parse_error&);
CHECK_THROWS_WITH(json::from_ubjson(vST), "[json.exception.parse_error.110] parse error at byte 11: unexpected end of input"); CHECK_THROWS_WITH(json::from_ubjson(vST), "[json.exception.parse_error.110] parse error at byte 11: syntax error while parsing UBJSON value: unexpected end of input");
CHECK(json::from_ubjson(vST, true, false).is_discarded()); CHECK(json::from_ubjson(vST, true, false).is_discarded());
std::vector<uint8_t> vT = {'{', '$', 'i', 'i', 1, 'a', 1}; std::vector<uint8_t> vT = {'{', '$', 'i', 'i', 1, 'a', 1};
CHECK_THROWS_AS(json::from_ubjson(vT), json::parse_error&); CHECK_THROWS_AS(json::from_ubjson(vT), json::parse_error&);
CHECK_THROWS_WITH(json::from_ubjson(vT), "[json.exception.parse_error.112] parse error at byte 4: expected '#' after UBJSON type information; last byte: 0x69"); CHECK_THROWS_WITH(json::from_ubjson(vT), "[json.exception.parse_error.112] parse error at byte 4: syntax error while parsing UBJSON size: expected '#' after type information; last byte: 0x69");
CHECK(json::from_ubjson(vT, true, false).is_discarded()); CHECK(json::from_ubjson(vT, true, false).is_discarded());
std::vector<uint8_t> vS = {'{', '#', 'i', 2, 'i', 1, 'a', 'i', 1}; std::vector<uint8_t> vS = {'{', '#', 'i', 2, 'i', 1, 'a', 'i', 1};
CHECK_THROWS_AS(json::from_ubjson(vS), json::parse_error&); CHECK_THROWS_AS(json::from_ubjson(vS), json::parse_error&);
CHECK_THROWS_WITH(json::from_ubjson(vS), "[json.exception.parse_error.110] parse error at byte 10: unexpected end of input"); CHECK_THROWS_WITH(json::from_ubjson(vS), "[json.exception.parse_error.110] parse error at byte 10: syntax error while parsing UBJSON value: unexpected end of input");
CHECK(json::from_ubjson(vS, true, false).is_discarded()); CHECK(json::from_ubjson(vS, true, false).is_discarded());
std::vector<uint8_t> v = {'{', 'i', 1, 'a', 'i', 1}; std::vector<uint8_t> v = {'{', 'i', 1, 'a', 'i', 1};
CHECK_THROWS_AS(json::from_ubjson(v), json::parse_error&); CHECK_THROWS_AS(json::from_ubjson(v), json::parse_error&);
CHECK_THROWS_WITH(json::from_ubjson(v), "[json.exception.parse_error.110] parse error at byte 7: unexpected end of input"); CHECK_THROWS_WITH(json::from_ubjson(v), "[json.exception.parse_error.110] parse error at byte 7: syntax error while parsing UBJSON value: unexpected end of input");
CHECK(json::from_ubjson(v, true, false).is_discarded()); CHECK(json::from_ubjson(v, true, false).is_discarded());
std::vector<uint8_t> v2 = {'{', 'i', 1, 'a', 'i', 1, 'i'}; std::vector<uint8_t> v2 = {'{', 'i', 1, 'a', 'i', 1, 'i'};
CHECK_THROWS_AS(json::from_ubjson(v2), json::parse_error&); CHECK_THROWS_AS(json::from_ubjson(v2), json::parse_error&);
CHECK_THROWS_WITH(json::from_ubjson(v2), "[json.exception.parse_error.110] parse error at byte 8: unexpected end of input"); CHECK_THROWS_WITH(json::from_ubjson(v2), "[json.exception.parse_error.110] parse error at byte 8: syntax error while parsing UBJSON number: unexpected end of input");
CHECK(json::from_ubjson(v2, true, false).is_discarded()); CHECK(json::from_ubjson(v2, true, false).is_discarded());
std::vector<uint8_t> v3 = {'{', 'i', 1, 'a'}; std::vector<uint8_t> v3 = {'{', 'i', 1, 'a'};
CHECK_THROWS_AS(json::from_ubjson(v3), json::parse_error&); CHECK_THROWS_AS(json::from_ubjson(v3), json::parse_error&);
CHECK_THROWS_WITH(json::from_ubjson(v3), "[json.exception.parse_error.110] parse error at byte 5: unexpected end of input"); CHECK_THROWS_WITH(json::from_ubjson(v3), "[json.exception.parse_error.110] parse error at byte 5: syntax error while parsing UBJSON value: unexpected end of input");
CHECK(json::from_ubjson(v3, true, false).is_discarded()); CHECK(json::from_ubjson(v3, true, false).is_discarded());
std::vector<uint8_t> vST1 = {'{', '$', 'd', '#', 'i', 2, 'i', 1, 'a'}; std::vector<uint8_t> vST1 = {'{', '$', 'd', '#', 'i', 2, 'i', 1, 'a'};
CHECK_THROWS_AS(json::from_ubjson(vST1), json::parse_error&); CHECK_THROWS_AS(json::from_ubjson(vST1), json::parse_error&);
CHECK_THROWS_WITH(json::from_ubjson(vST1), "[json.exception.parse_error.110] parse error at byte 10: unexpected end of input"); CHECK_THROWS_WITH(json::from_ubjson(vST1), "[json.exception.parse_error.110] parse error at byte 10: syntax error while parsing UBJSON number: unexpected end of input");
CHECK(json::from_ubjson(vST1, true, false).is_discarded()); CHECK(json::from_ubjson(vST1, true, false).is_discarded());
std::vector<uint8_t> vST2 = {'{', '#', 'i', 2, 'i', 1, 'a'}; std::vector<uint8_t> vST2 = {'{', '#', 'i', 2, 'i', 1, 'a'};
CHECK_THROWS_AS(json::from_ubjson(vST2), json::parse_error&); CHECK_THROWS_AS(json::from_ubjson(vST2), json::parse_error&);
CHECK_THROWS_WITH(json::from_ubjson(vST2), "[json.exception.parse_error.110] parse error at byte 8: unexpected end of input"); CHECK_THROWS_WITH(json::from_ubjson(vST2), "[json.exception.parse_error.110] parse error at byte 8: syntax error while parsing UBJSON value: unexpected end of input");
CHECK(json::from_ubjson(vST2, true, false).is_discarded()); CHECK(json::from_ubjson(vST2, true, false).is_discarded());
} }
} }