From dbb0b63187ba07cefb8981e83bc781be894ca874 Mon Sep 17 00:00:00 2001 From: Niels Lohmann Date: Wed, 17 Oct 2018 12:15:58 +0200 Subject: [PATCH] :wheelchair: improved error messages for binary formats #1288 This commit is the equivalent of #1282 for CBOR, MessagePack, and UBJSON. --- .../nlohmann/detail/input/binary_reader.hpp | 215 ++++++++++------- .../nlohmann/detail/output/binary_writer.hpp | 4 +- single_include/nlohmann/json.hpp | 219 +++++++++++------- test/src/unit-cbor.cpp | 62 ++--- test/src/unit-msgpack.cpp | 48 ++-- test/src/unit-regression.cpp | 36 +-- test/src/unit-ubjson.cpp | 62 ++--- 7 files changed, 364 insertions(+), 282 deletions(-) diff --git a/include/nlohmann/detail/input/binary_reader.hpp b/include/nlohmann/detail/input/binary_reader.hpp index bb0c982b8..57889644e 100644 --- a/include/nlohmann/detail/input/binary_reader.hpp +++ b/include/nlohmann/detail/input/binary_reader.hpp @@ -100,7 +100,8 @@ class binary_reader if (JSON_UNLIKELY(current != std::char_traits::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 case std::char_traits::eof(): - return unexpect_eof(); + return unexpect_eof(input_format_t::cbor, "value"); // Integer 0x00..0x17 (0..23) case 0x00: @@ -165,25 +166,25 @@ class binary_reader case 0x18: // Unsigned integer (one-byte uint8_t follows) { 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) { 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) { 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) { 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) @@ -216,25 +217,25 @@ class binary_reader case 0x38: // Negative integer (one-byte uint8_t follows) { uint8_t number; - return get_number(number) and sax->number_integer(static_cast(-1) - number); + return get_number(input_format_t::cbor, number) and sax->number_integer(static_cast(-1) - number); } case 0x39: // Negative integer -1-n (two-byte uint16_t follows) { uint16_t number; - return get_number(number) and sax->number_integer(static_cast(-1) - number); + return get_number(input_format_t::cbor, number) and sax->number_integer(static_cast(-1) - number); } case 0x3A: // Negative integer -1-n (four-byte uint32_t follows) { uint32_t number; - return get_number(number) and sax->number_integer(static_cast(-1) - number); + return get_number(input_format_t::cbor, number) and sax->number_integer(static_cast(-1) - number); } case 0x3B: // Negative integer -1-n (eight-byte uint64_t follows) { uint64_t number; - return get_number(number) and sax->number_integer(static_cast(-1) + return get_number(input_format_t::cbor, number) and sax->number_integer(static_cast(-1) - static_cast(number)); } @@ -303,25 +304,25 @@ class binary_reader case 0x98: // array (one-byte uint8_t for n follows) { uint8_t len; - return get_number(len) and get_cbor_array(static_cast(len)); + return get_number(input_format_t::cbor, len) and get_cbor_array(static_cast(len)); } case 0x99: // array (two-byte uint16_t for n follow) { uint16_t len; - return get_number(len) and get_cbor_array(static_cast(len)); + return get_number(input_format_t::cbor, len) and get_cbor_array(static_cast(len)); } case 0x9A: // array (four-byte uint32_t for n follow) { uint32_t len; - return get_number(len) and get_cbor_array(static_cast(len)); + return get_number(input_format_t::cbor, len) and get_cbor_array(static_cast(len)); } case 0x9B: // array (eight-byte uint64_t for n follow) { uint64_t len; - return get_number(len) and get_cbor_array(static_cast(len)); + return get_number(input_format_t::cbor, len) and get_cbor_array(static_cast(len)); } case 0x9F: // array (indefinite length) @@ -357,25 +358,25 @@ class binary_reader case 0xB8: // map (one-byte uint8_t for n follows) { uint8_t len; - return get_number(len) and get_cbor_object(static_cast(len)); + return get_number(input_format_t::cbor, len) and get_cbor_object(static_cast(len)); } case 0xB9: // map (two-byte uint16_t for n follow) { uint16_t len; - return get_number(len) and get_cbor_object(static_cast(len)); + return get_number(input_format_t::cbor, len) and get_cbor_object(static_cast(len)); } case 0xBA: // map (four-byte uint32_t for n follow) { uint32_t len; - return get_number(len) and get_cbor_object(static_cast(len)); + return get_number(input_format_t::cbor, len) and get_cbor_object(static_cast(len)); } case 0xBB: // map (eight-byte uint64_t for n follow) { uint64_t len; - return get_number(len) and get_cbor_object(static_cast(len)); + return get_number(input_format_t::cbor, len) and get_cbor_object(static_cast(len)); } case 0xBF: // map (indefinite length) @@ -393,12 +394,12 @@ class binary_reader case 0xF9: // Half-Precision Float (two-byte IEEE 754) { const int byte1_raw = get(); - if (JSON_UNLIKELY(not unexpect_eof())) + if (JSON_UNLIKELY(not unexpect_eof(input_format_t::cbor, "number"))) { return false; } const int byte2_raw = get(); - if (JSON_UNLIKELY(not unexpect_eof())) + if (JSON_UNLIKELY(not unexpect_eof(input_format_t::cbor, "number"))) { return false; } @@ -441,19 +442,19 @@ class binary_reader case 0xFA: // Single-Precision Float (four-byte IEEE 754) { float number; - return get_number(number) and sax->number_float(static_cast(number), ""); + return get_number(input_format_t::cbor, number) and sax->number_float(static_cast(number), ""); } case 0xFB: // Double-Precision Float (eight-byte IEEE 754) { double number; - return get_number(number) and sax->number_float(static_cast(number), ""); + return get_number(input_format_t::cbor, number) and sax->number_float(static_cast(number), ""); } default: // anything else (0xFF is handled inside the other types) { 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 case std::char_traits::eof(): - return unexpect_eof(); + return unexpect_eof(input_format_t::msgpack, "value"); // positive fixint case 0x00: @@ -688,61 +689,61 @@ class binary_reader case 0xCA: // float 32 { float number; - return get_number(number) and sax->number_float(static_cast(number), ""); + return get_number(input_format_t::msgpack, number) and sax->number_float(static_cast(number), ""); } case 0xCB: // float 64 { double number; - return get_number(number) and sax->number_float(static_cast(number), ""); + return get_number(input_format_t::msgpack, number) and sax->number_float(static_cast(number), ""); } case 0xCC: // uint 8 { 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 { 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 { 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 { 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 { 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 { 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 { 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 { 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 @@ -756,25 +757,25 @@ class binary_reader case 0xDC: // array 16 { uint16_t len; - return get_number(len) and get_msgpack_array(static_cast(len)); + return get_number(input_format_t::msgpack, len) and get_msgpack_array(static_cast(len)); } case 0xDD: // array 32 { uint32_t len; - return get_number(len) and get_msgpack_array(static_cast(len)); + return get_number(input_format_t::msgpack, len) and get_msgpack_array(static_cast(len)); } case 0xDE: // map 16 { uint16_t len; - return get_number(len) and get_msgpack_object(static_cast(len)); + return get_number(input_format_t::msgpack, len) and get_msgpack_object(static_cast(len)); } case 0xDF: // map 32 { uint32_t len; - return get_number(len) and get_msgpack_object(static_cast(len)); + return get_number(input_format_t::msgpack, len) and get_msgpack_object(static_cast(len)); } // negative fixint @@ -815,7 +816,7 @@ class binary_reader default: // anything else { 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 @tparam NumberType the type of the number + @param[in] format the current format (for diagnostics) @param[out] result number of type @a NumberType @return whether conversion completed @@ -874,14 +876,14 @@ class binary_reader (big endian) and therefore need reordering on little endian systems. */ template - 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 std::array vec; for (std::size_t i = 0; i < sizeof(NumberType); ++i) { get(); - if (JSON_UNLIKELY(not unexpect_eof())) + if (JSON_UNLIKELY(not unexpect_eof(format, "number"))) { return false; } @@ -906,8 +908,9 @@ class binary_reader @brief create a string by reading characters from the input @tparam NumberType the type of the number + @param[in] format the current format (for diagnostics) @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 @@ -916,13 +919,13 @@ class binary_reader the input before we run out of string memory. */ template - 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; - std::generate_n(std::back_inserter(result), len, [this, &success]() + std::generate_n(std::back_inserter(result), len, [this, &success, &format]() { get(); - if (JSON_UNLIKELY(not unexpect_eof())) + if (JSON_UNLIKELY(not unexpect_eof(format, "string"))) { success = false; } @@ -944,7 +947,7 @@ class binary_reader */ 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; } @@ -977,31 +980,31 @@ class binary_reader case 0x76: 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) { 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) { 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) { 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) { 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) @@ -1021,7 +1024,7 @@ class binary_reader default: { 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) { - if (JSON_UNLIKELY(not unexpect_eof())) + if (JSON_UNLIKELY(not unexpect_eof(input_format_t::msgpack, "string"))) { return false; } @@ -1165,31 +1168,31 @@ class binary_reader case 0xBE: case 0xBF: { - return get_string(current & 0x1F, result); + return get_string(input_format_t::msgpack, current & 0x1F, result); } case 0xD9: // str 8 { 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 { 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 { 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: { 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? } - if (JSON_UNLIKELY(not unexpect_eof())) + if (JSON_UNLIKELY(not unexpect_eof(input_format_t::ubjson, "value"))) { return false; } @@ -1277,36 +1280,36 @@ class binary_reader case 'U': { 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': { 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': { 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': { 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': { 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: 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': { uint8_t number; - if (JSON_UNLIKELY(not get_number(number))) + if (JSON_UNLIKELY(not get_number(input_format_t::ubjson, number))) { return false; } @@ -1332,7 +1335,7 @@ class binary_reader case 'i': { int8_t number; - if (JSON_UNLIKELY(not get_number(number))) + if (JSON_UNLIKELY(not get_number(input_format_t::ubjson, number))) { return false; } @@ -1343,7 +1346,7 @@ class binary_reader case 'I': { int16_t number; - if (JSON_UNLIKELY(not get_number(number))) + if (JSON_UNLIKELY(not get_number(input_format_t::ubjson, number))) { return false; } @@ -1354,7 +1357,7 @@ class binary_reader case 'l': { int32_t number; - if (JSON_UNLIKELY(not get_number(number))) + if (JSON_UNLIKELY(not get_number(input_format_t::ubjson, number))) { return false; } @@ -1365,7 +1368,7 @@ class binary_reader case 'L': { int64_t number; - if (JSON_UNLIKELY(not get_number(number))) + if (JSON_UNLIKELY(not get_number(input_format_t::ubjson, number))) { return false; } @@ -1376,7 +1379,7 @@ class binary_reader default: { 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 == '$') { 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; } @@ -1409,12 +1412,12 @@ class binary_reader get_ignore_noop(); if (JSON_UNLIKELY(current != '#')) { - if (JSON_UNLIKELY(not unexpect_eof())) + if (JSON_UNLIKELY(not unexpect_eof(input_format_t::ubjson, "value"))) { return false; } 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); @@ -1435,7 +1438,7 @@ class binary_reader switch (prefix) { case std::char_traits::eof(): // EOF - return unexpect_eof(); + return unexpect_eof(input_format_t::ubjson, "value"); case 'T': // true return sax->boolean(true); @@ -1448,56 +1451,56 @@ class binary_reader case 'U': { 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': { 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': { 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': { 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': { 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': { float number; - return get_number(number) and sax->number_float(static_cast(number), ""); + return get_number(input_format_t::ubjson, number) and sax->number_float(static_cast(number), ""); } case 'D': { double number; - return get_number(number) and sax->number_float(static_cast(number), ""); + return get_number(input_format_t::ubjson, number) and sax->number_float(static_cast(number), ""); } case 'C': // char { get(); - if (JSON_UNLIKELY(not unexpect_eof())) + if (JSON_UNLIKELY(not unexpect_eof(input_format_t::ubjson, "char"))) { return false; } if (JSON_UNLIKELY(current > 127)) { 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(current)); return sax->string(s); @@ -1518,7 +1521,7 @@ class binary_reader default: // anything else { 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 */ - bool unexpect_eof() const + bool unexpect_eof(const input_format_t format, const char* context) const { if (JSON_UNLIKELY(current == std::char_traits::eof())) { - return sax->parse_error(chars_read, "", parse_error::create(110, chars_read, "unexpected end of input")); + return sax->parse_error(chars_read, "", + parse_error::create(110, chars_read, exception_message(format, "unexpected end of input", context))); } return true; } @@ -1683,6 +1689,41 @@ class binary_reader } 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_t ia = nullptr; diff --git a/include/nlohmann/detail/output/binary_writer.hpp b/include/nlohmann/detail/output/binary_writer.hpp index b93dc6a3c..d4b5e98f9 100644 --- a/include/nlohmann/detail/output/binary_writer.hpp +++ b/include/nlohmann/detail/output/binary_writer.hpp @@ -767,7 +767,7 @@ class binary_writer } 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 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 } diff --git a/single_include/nlohmann/json.hpp b/single_include/nlohmann/json.hpp index dc206d301..f744366c8 100644 --- a/single_include/nlohmann/json.hpp +++ b/single_include/nlohmann/json.hpp @@ -6297,7 +6297,8 @@ class binary_reader if (JSON_UNLIKELY(current != std::char_traits::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 case std::char_traits::eof(): - return unexpect_eof(); + return unexpect_eof(input_format_t::cbor, "value"); // Integer 0x00..0x17 (0..23) case 0x00: @@ -6362,25 +6363,25 @@ class binary_reader case 0x18: // Unsigned integer (one-byte uint8_t follows) { 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) { 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) { 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) { 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) @@ -6413,25 +6414,25 @@ class binary_reader case 0x38: // Negative integer (one-byte uint8_t follows) { uint8_t number; - return get_number(number) and sax->number_integer(static_cast(-1) - number); + return get_number(input_format_t::cbor, number) and sax->number_integer(static_cast(-1) - number); } case 0x39: // Negative integer -1-n (two-byte uint16_t follows) { uint16_t number; - return get_number(number) and sax->number_integer(static_cast(-1) - number); + return get_number(input_format_t::cbor, number) and sax->number_integer(static_cast(-1) - number); } case 0x3A: // Negative integer -1-n (four-byte uint32_t follows) { uint32_t number; - return get_number(number) and sax->number_integer(static_cast(-1) - number); + return get_number(input_format_t::cbor, number) and sax->number_integer(static_cast(-1) - number); } case 0x3B: // Negative integer -1-n (eight-byte uint64_t follows) { uint64_t number; - return get_number(number) and sax->number_integer(static_cast(-1) + return get_number(input_format_t::cbor, number) and sax->number_integer(static_cast(-1) - static_cast(number)); } @@ -6500,25 +6501,25 @@ class binary_reader case 0x98: // array (one-byte uint8_t for n follows) { uint8_t len; - return get_number(len) and get_cbor_array(static_cast(len)); + return get_number(input_format_t::cbor, len) and get_cbor_array(static_cast(len)); } case 0x99: // array (two-byte uint16_t for n follow) { uint16_t len; - return get_number(len) and get_cbor_array(static_cast(len)); + return get_number(input_format_t::cbor, len) and get_cbor_array(static_cast(len)); } case 0x9A: // array (four-byte uint32_t for n follow) { uint32_t len; - return get_number(len) and get_cbor_array(static_cast(len)); + return get_number(input_format_t::cbor, len) and get_cbor_array(static_cast(len)); } case 0x9B: // array (eight-byte uint64_t for n follow) { uint64_t len; - return get_number(len) and get_cbor_array(static_cast(len)); + return get_number(input_format_t::cbor, len) and get_cbor_array(static_cast(len)); } case 0x9F: // array (indefinite length) @@ -6554,25 +6555,25 @@ class binary_reader case 0xB8: // map (one-byte uint8_t for n follows) { uint8_t len; - return get_number(len) and get_cbor_object(static_cast(len)); + return get_number(input_format_t::cbor, len) and get_cbor_object(static_cast(len)); } case 0xB9: // map (two-byte uint16_t for n follow) { uint16_t len; - return get_number(len) and get_cbor_object(static_cast(len)); + return get_number(input_format_t::cbor, len) and get_cbor_object(static_cast(len)); } case 0xBA: // map (four-byte uint32_t for n follow) { uint32_t len; - return get_number(len) and get_cbor_object(static_cast(len)); + return get_number(input_format_t::cbor, len) and get_cbor_object(static_cast(len)); } case 0xBB: // map (eight-byte uint64_t for n follow) { uint64_t len; - return get_number(len) and get_cbor_object(static_cast(len)); + return get_number(input_format_t::cbor, len) and get_cbor_object(static_cast(len)); } case 0xBF: // map (indefinite length) @@ -6590,12 +6591,12 @@ class binary_reader case 0xF9: // Half-Precision Float (two-byte IEEE 754) { const int byte1_raw = get(); - if (JSON_UNLIKELY(not unexpect_eof())) + if (JSON_UNLIKELY(not unexpect_eof(input_format_t::cbor, "number"))) { return false; } const int byte2_raw = get(); - if (JSON_UNLIKELY(not unexpect_eof())) + if (JSON_UNLIKELY(not unexpect_eof(input_format_t::cbor, "number"))) { return false; } @@ -6638,19 +6639,19 @@ class binary_reader case 0xFA: // Single-Precision Float (four-byte IEEE 754) { float number; - return get_number(number) and sax->number_float(static_cast(number), ""); + return get_number(input_format_t::cbor, number) and sax->number_float(static_cast(number), ""); } case 0xFB: // Double-Precision Float (eight-byte IEEE 754) { double number; - return get_number(number) and sax->number_float(static_cast(number), ""); + return get_number(input_format_t::cbor, number) and sax->number_float(static_cast(number), ""); } default: // anything else (0xFF is handled inside the other types) { 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 case std::char_traits::eof(): - return unexpect_eof(); + return unexpect_eof(input_format_t::msgpack, "value"); // positive fixint case 0x00: @@ -6885,61 +6886,61 @@ class binary_reader case 0xCA: // float 32 { float number; - return get_number(number) and sax->number_float(static_cast(number), ""); + return get_number(input_format_t::msgpack, number) and sax->number_float(static_cast(number), ""); } case 0xCB: // float 64 { double number; - return get_number(number) and sax->number_float(static_cast(number), ""); + return get_number(input_format_t::msgpack, number) and sax->number_float(static_cast(number), ""); } case 0xCC: // uint 8 { 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 { 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 { 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 { 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 { 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 { 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 { 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 { 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 @@ -6953,25 +6954,25 @@ class binary_reader case 0xDC: // array 16 { uint16_t len; - return get_number(len) and get_msgpack_array(static_cast(len)); + return get_number(input_format_t::msgpack, len) and get_msgpack_array(static_cast(len)); } case 0xDD: // array 32 { uint32_t len; - return get_number(len) and get_msgpack_array(static_cast(len)); + return get_number(input_format_t::msgpack, len) and get_msgpack_array(static_cast(len)); } case 0xDE: // map 16 { uint16_t len; - return get_number(len) and get_msgpack_object(static_cast(len)); + return get_number(input_format_t::msgpack, len) and get_msgpack_object(static_cast(len)); } case 0xDF: // map 32 { uint32_t len; - return get_number(len) and get_msgpack_object(static_cast(len)); + return get_number(input_format_t::msgpack, len) and get_msgpack_object(static_cast(len)); } // negative fixint @@ -7012,7 +7013,7 @@ class binary_reader default: // anything else { 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 @tparam NumberType the type of the number + @param[in] format the current format (for diagnostics) @param[out] result number of type @a NumberType @return whether conversion completed @@ -7071,14 +7073,14 @@ class binary_reader (big endian) and therefore need reordering on little endian systems. */ template - 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 std::array vec; for (std::size_t i = 0; i < sizeof(NumberType); ++i) { get(); - if (JSON_UNLIKELY(not unexpect_eof())) + if (JSON_UNLIKELY(not unexpect_eof(format, "number"))) { return false; } @@ -7103,8 +7105,9 @@ class binary_reader @brief create a string by reading characters from the input @tparam NumberType the type of the number + @param[in] format the current format (for diagnostics) @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 @@ -7113,13 +7116,13 @@ class binary_reader the input before we run out of string memory. */ template - 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; - std::generate_n(std::back_inserter(result), len, [this, &success]() + std::generate_n(std::back_inserter(result), len, [this, &success, &format]() { get(); - if (JSON_UNLIKELY(not unexpect_eof())) + if (JSON_UNLIKELY(not unexpect_eof(format, "string"))) { success = false; } @@ -7141,7 +7144,7 @@ class binary_reader */ 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; } @@ -7174,31 +7177,31 @@ class binary_reader case 0x76: 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) { 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) { 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) { 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) { 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) @@ -7218,7 +7221,7 @@ class binary_reader default: { 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) { - if (JSON_UNLIKELY(not unexpect_eof())) + if (JSON_UNLIKELY(not unexpect_eof(input_format_t::msgpack, "string"))) { return false; } @@ -7362,31 +7365,31 @@ class binary_reader case 0xBE: case 0xBF: { - return get_string(current & 0x1F, result); + return get_string(input_format_t::msgpack, current & 0x1F, result); } case 0xD9: // str 8 { 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 { 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 { 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: { 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? } - if (JSON_UNLIKELY(not unexpect_eof())) + if (JSON_UNLIKELY(not unexpect_eof(input_format_t::ubjson, "value"))) { return false; } @@ -7474,36 +7477,36 @@ class binary_reader case 'U': { 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': { 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': { 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': { 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': { 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: 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': { uint8_t number; - if (JSON_UNLIKELY(not get_number(number))) + if (JSON_UNLIKELY(not get_number(input_format_t::ubjson, number))) { return false; } @@ -7529,7 +7532,7 @@ class binary_reader case 'i': { int8_t number; - if (JSON_UNLIKELY(not get_number(number))) + if (JSON_UNLIKELY(not get_number(input_format_t::ubjson, number))) { return false; } @@ -7540,7 +7543,7 @@ class binary_reader case 'I': { int16_t number; - if (JSON_UNLIKELY(not get_number(number))) + if (JSON_UNLIKELY(not get_number(input_format_t::ubjson, number))) { return false; } @@ -7551,7 +7554,7 @@ class binary_reader case 'l': { int32_t number; - if (JSON_UNLIKELY(not get_number(number))) + if (JSON_UNLIKELY(not get_number(input_format_t::ubjson, number))) { return false; } @@ -7562,7 +7565,7 @@ class binary_reader case 'L': { int64_t number; - if (JSON_UNLIKELY(not get_number(number))) + if (JSON_UNLIKELY(not get_number(input_format_t::ubjson, number))) { return false; } @@ -7573,7 +7576,7 @@ class binary_reader default: { 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 == '$') { 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; } @@ -7606,12 +7609,12 @@ class binary_reader get_ignore_noop(); if (JSON_UNLIKELY(current != '#')) { - if (JSON_UNLIKELY(not unexpect_eof())) + if (JSON_UNLIKELY(not unexpect_eof(input_format_t::ubjson, "value"))) { return false; } 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); @@ -7632,7 +7635,7 @@ class binary_reader switch (prefix) { case std::char_traits::eof(): // EOF - return unexpect_eof(); + return unexpect_eof(input_format_t::ubjson, "value"); case 'T': // true return sax->boolean(true); @@ -7645,56 +7648,56 @@ class binary_reader case 'U': { 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': { 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': { 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': { 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': { 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': { float number; - return get_number(number) and sax->number_float(static_cast(number), ""); + return get_number(input_format_t::ubjson, number) and sax->number_float(static_cast(number), ""); } case 'D': { double number; - return get_number(number) and sax->number_float(static_cast(number), ""); + return get_number(input_format_t::ubjson, number) and sax->number_float(static_cast(number), ""); } case 'C': // char { get(); - if (JSON_UNLIKELY(not unexpect_eof())) + if (JSON_UNLIKELY(not unexpect_eof(input_format_t::ubjson, "char"))) { return false; } if (JSON_UNLIKELY(current > 127)) { 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(current)); return sax->string(s); @@ -7715,7 +7718,7 @@ class binary_reader default: // anything else { 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 */ - bool unexpect_eof() const + bool unexpect_eof(const input_format_t format, const char* context) const { if (JSON_UNLIKELY(current == std::char_traits::eof())) { - return sax->parse_error(chars_read, "", parse_error::create(110, chars_read, "unexpected end of input")); + return sax->parse_error(chars_read, "", + parse_error::create(110, chars_read, exception_message(format, "unexpected end of input", context))); } return true; } @@ -7880,6 +7886,41 @@ class binary_reader } 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_t ia = nullptr; @@ -8670,7 +8711,7 @@ class binary_writer } 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 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 } diff --git a/test/src/unit-cbor.cpp b/test/src/unit-cbor.cpp index 62520a0ba..d7f52ed86 100644 --- a/test/src/unit-cbor.cpp +++ b/test/src/unit-cbor.cpp @@ -831,14 +831,14 @@ TEST_CASE("CBOR") { CHECK_THROWS_AS(json::from_cbor(std::vector({0xf9})), json::parse_error&); CHECK_THROWS_WITH(json::from_cbor(std::vector({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({0xf9}), true, false).is_discarded()); } SECTION("only one byte follows") { CHECK_THROWS_AS(json::from_cbor(std::vector({0xf9, 0x7c})), json::parse_error&); CHECK_THROWS_WITH(json::from_cbor(std::vector({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({0xf9, 0x7c}), true, false).is_discarded()); } } @@ -1314,7 +1314,7 @@ TEST_CASE("CBOR") { CHECK_THROWS_AS(json::from_cbor(std::vector()), json::parse_error&); CHECK_THROWS_WITH(json::from_cbor(std::vector()), - "[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(), true, false).is_discarded()); } @@ -1346,53 +1346,53 @@ TEST_CASE("CBOR") CHECK_THROWS_AS(json::from_cbor(std::vector({0xBF, 0x61, 0X61})), json::parse_error&); CHECK_THROWS_WITH(json::from_cbor(std::vector({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({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({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({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({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({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({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({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({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({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({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({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({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({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({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({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({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({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({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({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({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({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({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({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({0x18}), true, false).is_discarded()); CHECK(json::from_cbor(std::vector({0x19}), true, false).is_discarded()); @@ -1426,12 +1426,12 @@ TEST_CASE("CBOR") { CHECK_THROWS_AS(json::from_cbor(std::vector({0x1c})), json::parse_error&); CHECK_THROWS_WITH(json::from_cbor(std::vector({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({0x1c}), true, false).is_discarded()); CHECK_THROWS_AS(json::from_cbor(std::vector({0xf8})), json::parse_error&); CHECK_THROWS_WITH(json::from_cbor(std::vector({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({0xf8}), true, false).is_discarded()); } @@ -1491,7 +1491,7 @@ TEST_CASE("CBOR") { CHECK_THROWS_AS(json::from_cbor(std::vector({0xa1, 0xff, 0x01})), json::parse_error&); CHECK_THROWS_WITH(json::from_cbor(std::vector({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({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_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()); } } diff --git a/test/src/unit-msgpack.cpp b/test/src/unit-msgpack.cpp index f75cedce9..26d079631 100644 --- a/test/src/unit-msgpack.cpp +++ b/test/src/unit-msgpack.cpp @@ -1124,7 +1124,7 @@ TEST_CASE("MessagePack") { CHECK_THROWS_AS(json::from_msgpack(std::vector()), json::parse_error&); CHECK_THROWS_WITH(json::from_msgpack(std::vector()), - "[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(), true, false).is_discarded()); } @@ -1151,43 +1151,43 @@ TEST_CASE("MessagePack") CHECK_THROWS_AS(json::from_msgpack(std::vector({0x81, 0xa1, 0x61})), json::parse_error&); CHECK_THROWS_WITH(json::from_msgpack(std::vector({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({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({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({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({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({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({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({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({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({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({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({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({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({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({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({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({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({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({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({0x87}), true, false).is_discarded()); CHECK(json::from_msgpack(std::vector({0xcc}), true, false).is_discarded()); @@ -1216,12 +1216,12 @@ TEST_CASE("MessagePack") { CHECK_THROWS_AS(json::from_msgpack(std::vector({0xc1})), json::parse_error&); CHECK_THROWS_WITH(json::from_msgpack(std::vector({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({0xc6}), true, false).is_discarded()); CHECK_THROWS_AS(json::from_msgpack(std::vector({0xc6})), json::parse_error&); CHECK_THROWS_WITH(json::from_msgpack(std::vector({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({0xc6}), true, false).is_discarded()); } @@ -1249,7 +1249,7 @@ TEST_CASE("MessagePack") { CHECK_THROWS_AS(json::from_msgpack(std::vector({0x81, 0xff, 0x01})), json::parse_error&); CHECK_THROWS_WITH(json::from_msgpack(std::vector({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({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_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()); } } diff --git a/test/src/unit-regression.cpp b/test/src/unit-regression.cpp index 98a53a507..259377aa8 100644 --- a/test/src/unit-regression.cpp +++ b/test/src/unit-regression.cpp @@ -930,7 +930,7 @@ TEST_CASE("regression tests") std::vector vec {0x65, 0xf5, 0x0a, 0x48, 0x21}; CHECK_THROWS_AS(json::from_cbor(vec), json::parse_error&); CHECK_THROWS_WITH(json::from_cbor(vec), - "[json.exception.parse_error.110] parse error at 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)") @@ -939,31 +939,31 @@ TEST_CASE("regression tests") std::vector vec1 {0xcb, 0x8f, 0x0a}; CHECK_THROWS_AS(json::from_msgpack(vec1), json::parse_error&); CHECK_THROWS_WITH(json::from_msgpack(vec1), - "[json.exception.parse_error.110] parse error at 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 std::vector vec2 {0xca, 0x8f, 0x0a}; CHECK_THROWS_AS(json::from_msgpack(vec2), json::parse_error&); CHECK_THROWS_WITH(json::from_msgpack(vec2), - "[json.exception.parse_error.110] parse error at 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) std::vector vec3 {0xf9, 0x8f}; CHECK_THROWS_AS(json::from_cbor(vec3), json::parse_error&); CHECK_THROWS_WITH(json::from_cbor(vec3), - "[json.exception.parse_error.110] parse error at 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) std::vector vec4 {0xfa, 0x8f, 0x0a}; CHECK_THROWS_AS(json::from_cbor(vec4), json::parse_error&); CHECK_THROWS_WITH(json::from_cbor(vec4), - "[json.exception.parse_error.110] parse error at 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) std::vector vec5 {0xfb, 0x8f, 0x0a}; CHECK_THROWS_AS(json::from_cbor(vec5), json::parse_error&); CHECK_THROWS_WITH(json::from_cbor(vec5), - "[json.exception.parse_error.110] parse error at 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)") @@ -972,7 +972,7 @@ TEST_CASE("regression tests") std::vector vec1 {0x87}; CHECK_THROWS_AS(json::from_msgpack(vec1), json::parse_error&); CHECK_THROWS_WITH(json::from_msgpack(vec1), - "[json.exception.parse_error.110] parse error at 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 for (auto b : @@ -1006,10 +1006,10 @@ TEST_CASE("regression tests") std::vector vec2; CHECK_THROWS_AS(json::from_cbor(vec2), json::parse_error&); CHECK_THROWS_WITH(json::from_cbor(vec2), - "[json.exception.parse_error.110] parse error at 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_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)") @@ -1018,19 +1018,19 @@ TEST_CASE("regression tests") std::vector vec1 {0x7f}; CHECK_THROWS_AS(json::from_cbor(vec1), json::parse_error&); CHECK_THROWS_WITH(json::from_cbor(vec1), - "[json.exception.parse_error.110] parse error at 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) std::vector vec2 {0x9f}; CHECK_THROWS_AS(json::from_cbor(vec2), json::parse_error&); CHECK_THROWS_WITH(json::from_cbor(vec2), - "[json.exception.parse_error.110] parse error at 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) std::vector vec3 {0xbf}; CHECK_THROWS_AS(json::from_cbor(vec3), json::parse_error&); CHECK_THROWS_WITH(json::from_cbor(vec3), - "[json.exception.parse_error.110] parse error at 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)") @@ -1058,25 +1058,25 @@ TEST_CASE("regression tests") }; CHECK_THROWS_AS(json::from_cbor(vec), json::parse_error&); CHECK_THROWS_WITH(json::from_cbor(vec), - "[json.exception.parse_error.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) std::vector vec1 {0x7f, 0x61, 0x61}; CHECK_THROWS_AS(json::from_cbor(vec1), json::parse_error&); CHECK_THROWS_WITH(json::from_cbor(vec1), - "[json.exception.parse_error.110] parse error at 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) std::vector vec2 {0x9f, 0x01}; CHECK_THROWS_AS(json::from_cbor(vec2), json::parse_error&); CHECK_THROWS_WITH(json::from_cbor(vec2), - "[json.exception.parse_error.110] parse error at 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) std::vector vec3 {0xbf, 0x61, 0x61, 0x01}; CHECK_THROWS_AS(json::from_cbor(vec3), json::parse_error&); CHECK_THROWS_WITH(json::from_cbor(vec3), - "[json.exception.parse_error.110] parse error at 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)") @@ -1111,7 +1111,7 @@ TEST_CASE("regression tests") }; CHECK_THROWS_AS(json::from_cbor(vec1), json::parse_error&); CHECK_THROWS_WITH(json::from_cbor(vec1), - "[json.exception.parse_error.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 std::vector vec2 @@ -1125,7 +1125,7 @@ TEST_CASE("regression tests") }; CHECK_THROWS_AS(json::from_cbor(vec2), json::parse_error&); CHECK_THROWS_WITH(json::from_cbor(vec2), - "[json.exception.parse_error.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)") diff --git a/test/src/unit-ubjson.cpp b/test/src/unit-ubjson.cpp index d2410ff6b..ba0d23da5 100644 --- a/test/src/unit-ubjson.cpp +++ b/test/src/unit-ubjson.cpp @@ -1299,7 +1299,7 @@ TEST_CASE("UBJSON") { CHECK_THROWS_AS(json::from_ubjson(vec), json::parse_error&); 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 json j = 9223372036854775808llu; 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") @@ -1529,7 +1529,7 @@ TEST_CASE("UBJSON") { CHECK_THROWS_AS(json::from_ubjson(std::vector()), json::parse_error&); CHECK_THROWS_WITH(json::from_ubjson(std::vector()), - "[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") @@ -1538,14 +1538,14 @@ TEST_CASE("UBJSON") { std::vector v = {'C'}; 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") { std::vector v = {'C', 130}; 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 v = {'S'}; 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") { std::vector v = {'S', '1', 'a'}; 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 v = {'[', '$', 'i', 2}; 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 vS = {'S'}; 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()); std::vector v = {'S', 'i', '2', 'a'}; 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()); std::vector vC = {'C'}; 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()); } @@ -1598,32 +1598,32 @@ TEST_CASE("UBJSON") { std::vector vU = {'[', '#', 'U'}; 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()); std::vector vi = {'[', '#', 'i'}; 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()); std::vector vI = {'[', '#', 'I'}; 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()); std::vector vl = {'[', '#', 'l'}; 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()); std::vector vL = {'[', '#', 'L'}; 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()); std::vector v0 = {'[', '#', 'T', ']'}; 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()); } @@ -1631,17 +1631,17 @@ TEST_CASE("UBJSON") { std::vector v0 = {'[', '$'}; 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()); std::vector vi = {'[', '$', '#'}; 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()); std::vector vT = {'[', '$', 'T'}; 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()); } @@ -1649,17 +1649,17 @@ TEST_CASE("UBJSON") { std::vector vST = {'[', '$', 'i', '#', 'i', 2, 1}; 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()); std::vector vS = {'[', '#', 'i', 2, 'i', 1}; 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()); std::vector v = {'[', 'i', 2, 'i', 1}; 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()); } @@ -1667,42 +1667,42 @@ TEST_CASE("UBJSON") { std::vector vST = {'{', '$', 'i', '#', 'i', 2, 'i', 1, 'a', 1}; 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()); std::vector vT = {'{', '$', 'i', 'i', 1, 'a', 1}; 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()); std::vector vS = {'{', '#', 'i', 2, 'i', 1, 'a', 'i', 1}; 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()); std::vector v = {'{', 'i', 1, 'a', 'i', 1}; 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()); std::vector v2 = {'{', 'i', 1, 'a', 'i', 1, 'i'}; 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()); std::vector v3 = {'{', 'i', 1, 'a'}; 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()); std::vector vST1 = {'{', '$', 'd', '#', 'i', 2, 'i', 1, 'a'}; 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()); std::vector vST2 = {'{', '#', 'i', 2, 'i', 1, 'a'}; 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()); } }