Name the exception ids and address review comments

Add detail::exception_id, a scoped enum with one named enumerator per
documented exception id, and use it for every id in the library. The
create() functions get an overload for it; the int overloads stay for
user code.

Following the review of #5783: add binary_reader::invalid_byte() and
length_type_error(), basic_json::throw_subscript_wrong_type(), move the
fuzzer includes and the using-declaration into fuzzer_common.hpp, and
rename test_sax.hpp to sax_event_loggers.hpp.

Signed-off-by: Niels Lohmann <mail@nlohmann.me>
This commit is contained in:
Niels Lohmann committed 2026-10-07 19:38:46 +02:00
1 parent c3068e9f95
commit fce8a8949f
24 files changed
+629 -375

No files matched your search

@@ -420,7 +420,7 @@ inline void to_json(BasicJsonType& j, const EnumKeyedMap& map)
auto& key_string = *key.template get_ptr<typename BasicJsonType::string_t*>();
if (JSON_HEDLEY_UNLIKELY(!obj.emplace(key_string, BasicJsonType(p.second)).second))
{
JSON_THROW(type_error::create(318, concat("duplicate object key '", key_string, "'"), &key));
JSON_THROW(type_error::create(exception_id::enum_key_duplicate, concat("duplicate object key '", key_string, "'"), &key));
}
}
external_constructor<value_t::object>::construct(j, std::move(obj));
+117 -3
View File
@@ -45,6 +45,84 @@ namespace detail
// exceptions //
////////////////
/*!
@brief the ids of the exceptions thrown by the library
@note The values are part of the public API: they are the `id` member of the
exceptions and appear in their `what()` messages.
@sa https://json.nlohmann.me/home/exceptions/
*/
enum class exception_id : int
{
// parse_error
syntax_error = 101, ///< unexpected token or invalid literal while parsing JSON
patch_not_an_array = 104, ///< a JSON Patch document is not an array of objects
patch_invalid_operation = 105, ///< a JSON Patch operation is malformed
pointer_index_leading_zero = 106, ///< a JSON Pointer array index has a leading zero
pointer_missing_slash = 107, ///< a JSON Pointer does not start with '/'
pointer_invalid_escape = 108, ///< a JSON Pointer contains an escape other than ~0 and ~1
pointer_index_not_a_number = 109, ///< a JSON Pointer array index is not a number
unexpected_end_of_input = 110, ///< a binary input ends early, or has bytes left at its end
unexpected_byte = 112, ///< a binary input contains an unexpected byte or invalid length
invalid_string_or_size = 113, ///< a binary input contains an invalid string or size specification
bson_unsupported_type = 114, ///< a BSON record type is not supported
invalid_high_precision_number = 115, ///< a UBJSON/BJData high-precision number cannot be parsed
// invalid_iterator
iterators_incompatible = 201, ///< the iterators of a range belong to different values
iterator_from_other_value = 202, ///< an iterator does not belong to the value it is used with
iterator_range_from_other_value = 203, ///< an iterator range does not belong to the value it is used with
iterator_range_out_of_range = 204, ///< an iterator range of a primitive value is not [begin, end)
iterator_out_of_range = 205, ///< an iterator of a primitive value is not begin()
iterator_range_of_null = 206, ///< an iterator range belongs to a null value
iterator_key_not_object = 207, ///< key() is called on an iterator of a non-object
iterator_subscript_on_object = 208, ///< operator[] is called on an iterator of an object
iterator_arithmetic_on_object = 209, ///< an offset operator is used on an iterator of an object
insert_range_incompatible = 210, ///< the iterators of an inserted range belong to different values
insert_range_into_itself = 211, ///< an inserted range belongs to the value it is inserted into
iterators_compare_different_values = 212, ///< iterators of different values are compared
iterator_order_on_object = 213, ///< iterators of an object are compared by order
iterator_value_unavailable = 214, ///< an iterator does not refer to a value
// type_error
object_from_non_pairs = 301, ///< an object is created from an initializer list that is not a list of pairs
type_mismatch = 302, ///< a value has the wrong type for a conversion
incompatible_reference_type = 303, ///< get_ref() is called with a reference type that does not match the value
at_wrong_type = 304, ///< at() is called on a value of the wrong type
subscript_wrong_type = 305, ///< operator[] is called on a value of the wrong type
value_wrong_type = 306, ///< value() is called on a value of the wrong type
erase_wrong_type = 307, ///< erase() is called on a value of the wrong type
push_back_wrong_type = 308, ///< push_back() or operator+= is called on a value of the wrong type
insert_wrong_type = 309, ///< insert() is called on a value of the wrong type
swap_wrong_type = 310, ///< swap() is called on a value of the wrong type
emplace_wrong_type = 311, ///< emplace() or emplace_back() is called on a value of the wrong type
update_wrong_type = 312, ///< update() is called on a value of the wrong type
unflatten_invalid_value = 313, ///< unflatten() finds conflicting paths
unflatten_not_object = 314, ///< unflatten() is called on a non-object
unflatten_value_not_primitive = 315, ///< unflatten() is called on an object with non-primitive values
invalid_utf8 = 316, ///< dump() finds a string that is not valid UTF-8
type_not_serializable = 317, ///< a value cannot be serialized to the requested binary format
enum_key_duplicate = 318, ///< an enum-keyed map has two keys that serialize to the same string
discarded_value_used = 321, ///< a discarded value is used
// out_of_range
array_index_out_of_range = 401, ///< an array index is out of range
pointer_past_the_end_index = 402, ///< a JSON Pointer uses the array index '-'
key_not_found = 403, ///< an object key is not found
pointer_unresolved = 404, ///< a JSON Pointer reference token cannot be resolved
patch_on_root = 405, ///< the root of a value has no parent, e.g. for a JSON Patch 'remove' or 'add' at the root
number_overflow = 406, ///< a number cannot be stored without overflowing to NaN or INF
integer_too_large = 407, ///< an integer cannot be represented in the binary format
container_too_large = 408, ///< the size of a container in a binary input exceeds the maximal capacity
bson_key_with_null = 409, ///< a BSON key contains U+0000
value_out_of_range = 410, ///< an enum value is undefined, or a JSON Pointer array index exceeds size_type
patch_add_parent_not_container = 411, ///< the parent of a JSON Patch 'add' target is not a container
length_too_large = 412, ///< a length does not fit into the length field of a binary format
patch_remove_parent_not_container = 413, ///< the parent of a JSON Patch 'remove' target is not a container
patch_move_into_child = 414, ///< a JSON Patch 'move' moves a value into one of its children
subtype_out_of_range = 415, ///< a binary subtype does not fit into one byte
// other_error
internal_error = 500, ///< unreachable code was reached
patch_test_failed = 501, ///< a JSON Patch 'test' operation failed
size_marker_required = 502 ///< UBJSON/BJData output with type markers requires size markers
};
/// @brief general exception of the @ref basic_json class
/// @sa https://json.nlohmann.me/api/basic_json/exception/
class exception : public std::exception
@@ -195,6 +273,18 @@ class parse_error : public exception
return {id_, byte_, w.c_str()};
}
template<typename BasicJsonContext, enable_if_t<is_basic_json_context<BasicJsonContext>::value, int> = 0>
static parse_error create(exception_id id_, const position_t& pos, const std::string& what_arg, BasicJsonContext context)
{
return create(static_cast<int>(id_), pos, what_arg, context);
}
template<typename BasicJsonContext, enable_if_t<is_basic_json_context<BasicJsonContext>::value, int> = 0>
static parse_error create(exception_id id_, std::size_t byte_, const std::string& what_arg, BasicJsonContext context)
{
return create(static_cast<int>(id_), byte_, what_arg, context);
}
/*!
@brief byte index of the parse error
@@ -229,6 +319,12 @@ class invalid_iterator : public exception
return {id_, w.c_str()};
}
template<typename BasicJsonContext, enable_if_t<is_basic_json_context<BasicJsonContext>::value, int> = 0>
static invalid_iterator create(exception_id id_, const std::string& what_arg, BasicJsonContext context)
{
return create(static_cast<int>(id_), what_arg, context);
}
private:
JSON_HEDLEY_NON_NULL(3)
invalid_iterator(int id_, const char* what_arg)
@@ -247,6 +343,12 @@ class type_error : public exception
return {id_, w.c_str()};
}
template<typename BasicJsonContext, enable_if_t<is_basic_json_context<BasicJsonContext>::value, int> = 0>
static type_error create(exception_id id_, const std::string& what_arg, BasicJsonContext context)
{
return create(static_cast<int>(id_), what_arg, context);
}
private:
JSON_HEDLEY_NON_NULL(3)
type_error(int id_, const char* what_arg) : exception(id_, what_arg) {}
@@ -264,6 +366,12 @@ class out_of_range : public exception
return {id_, w.c_str()};
}
template<typename BasicJsonContext, enable_if_t<is_basic_json_context<BasicJsonContext>::value, int> = 0>
static out_of_range create(exception_id id_, const std::string& what_arg, BasicJsonContext context)
{
return create(static_cast<int>(id_), what_arg, context);
}
private:
JSON_HEDLEY_NON_NULL(3)
out_of_range(int id_, const char* what_arg) : exception(id_, what_arg) {}
@@ -281,6 +389,12 @@ class other_error : public exception
return {id_, w.c_str()};
}
template<typename BasicJsonContext, enable_if_t<is_basic_json_context<BasicJsonContext>::value, int> = 0>
static other_error create(exception_id id_, const std::string& what_arg, BasicJsonContext context)
{
return create(static_cast<int>(id_), what_arg, context);
}
private:
JSON_HEDLEY_NON_NULL(3)
other_error(int id_, const char* what_arg) : exception(id_, what_arg) {}
@@ -318,18 +432,18 @@ JSON_HEDLEY_NO_RETURN inline void throw_type_must_be(const char* expected, const
{
static_cast<void>(expected); // unused when JSON_NOEXCEPTION is defined
static_cast<void>(j);
JSON_THROW(type_error::create(302, concat("type must be ", expected, ", but is ", j.type_name()), &j));
JSON_THROW(type_error::create(exception_id::type_mismatch, concat("type must be ", expected, ", but is ", j.type_name()), &j));
}
/*!
@brief throws because an operation is not supported for the type of @a j
@param[in] id_ the id of the type_error exception (304..312)
@param[in] id_ the id of the type_error exception (at_wrong_type..update_wrong_type)
@param[in] operation the operation, e.g. "erase()"
@param[in] j the value the operation was called on
@throw type_error always
*/
template<typename BasicJsonType>
JSON_HEDLEY_NO_RETURN inline void throw_cannot_use_with(const int id_, const char* operation, const BasicJsonType& j)
JSON_HEDLEY_NO_RETURN inline void throw_cannot_use_with(const exception_id id_, const char* operation, const BasicJsonType& j)
{
static_cast<void>(id_); // unused when JSON_NOEXCEPTION is defined
static_cast<void>(operation);
+68 -51
View File
@@ -195,7 +195,7 @@ class binary_reader
if (JSON_HEDLEY_UNLIKELY(current != char_traits<char_type>::eof()))
{
return last_byte_error(110, concat("expected end of input; last byte: 0x", get_token_string()), "value");
return last_byte_error(exception_id::unexpected_end_of_input, concat("expected end of input; last byte: 0x", get_token_string()), "value");
}
}
@@ -317,7 +317,7 @@ class binary_reader
{
if (JSON_HEDLEY_UNLIKELY(document_size < 0 || static_cast<std::size_t>(document_size) != chars_read - document_start))
{
return last_byte_error(112, concat("document size ", std::to_string(document_size), " does not match the number of bytes read (", std::to_string(chars_read - document_start), ")"), "document");
return last_byte_error(exception_id::unexpected_byte, concat("document size ", std::to_string(document_size), " does not match the number of bytes read (", std::to_string(chars_read - document_start), ")"), "document");
}
return true;
}
@@ -509,7 +509,7 @@ class binary_reader
{
if (JSON_HEDLEY_UNLIKELY(len < 1))
{
return last_byte_error(112, concat("string length must be at least 1, is ", std::to_string(len)), "string");
return last_byte_error(exception_id::unexpected_byte, concat("string length must be at least 1, is ", std::to_string(len)), "string");
}
if (JSON_HEDLEY_UNLIKELY(!get_string(len - static_cast<NumberType>(1), result)))
@@ -519,7 +519,7 @@ class binary_reader
if (JSON_HEDLEY_UNLIKELY(get() != 0x00))
{
return last_byte_error(112, "BSON string is not null-terminated", "string");
return last_byte_error(exception_id::unexpected_byte, "BSON string is not null-terminated", "string");
}
return check_string_utf8(result, "string");
@@ -539,7 +539,7 @@ class binary_reader
{
if (JSON_HEDLEY_UNLIKELY(len < 0))
{
return last_byte_error(112, concat("byte array length cannot be negative, is ", std::to_string(len)), "binary");
return last_byte_error(exception_id::unexpected_byte, concat("byte array length cannot be negative, is ", std::to_string(len)), "binary");
}
// All BSON binary values have a subtype
@@ -631,7 +631,7 @@ class binary_reader
{
const std::string cr_str = hex_byte(static_cast<std::uint8_t>(element_type));
return sax->parse_error(element_type_parse_position, cr_str,
parse_error::create(114, element_type_parse_position, concat("Unsupported BSON record type 0x", cr_str), nullptr));
parse_error::create(exception_id::bson_unsupported_type, element_type_parse_position, concat("Unsupported BSON record type 0x", cr_str), nullptr));
}
}
}
@@ -955,7 +955,7 @@ class binary_reader
{
if (tag_handler == cbor_tag_handler_t::error)
{
return unexpected_byte("invalid byte", "value");
return invalid_byte("value");
}
// ignore and store: the tag value is already in the head, so
@@ -975,7 +975,7 @@ class binary_reader
{
case cbor_tag_handler_t::error:
{
return unexpected_byte("invalid byte", "value");
return invalid_byte("value");
}
case cbor_tag_handler_t::ignore:
@@ -1049,7 +1049,7 @@ class binary_reader
default: // anything else (0xFF is handled inside the other types)
{
return unexpected_byte("invalid byte", "value");
return invalid_byte("value");
}
}
}
@@ -1062,7 +1062,7 @@ class binary_reader
*/
bool cbor_indefinite_string_error(const char* type_name, const char* context)
{
return last_byte_error(113, concat("indefinite-length ", type_name, " is not allowed inside indefinite-length ", type_name, "; last byte: 0x", get_token_string()), context);
return last_byte_error(exception_id::invalid_string_or_size, concat("indefinite-length ", type_name, " is not allowed inside indefinite-length ", type_name, "; last byte: 0x", get_token_string()), context);
}
/*!
@@ -1139,7 +1139,7 @@ class binary_reader
default:
{
return last_byte_error(113, concat("expected length specification (0x60-0x7B)", inside_indefinite ? "" : " or indefinite string type (0x7F)", "; last byte: 0x", get_token_string()), "string");
return last_byte_error(exception_id::invalid_string_or_size, concat("expected length specification (0x60-0x7B)", inside_indefinite ? "" : " or indefinite string type (0x7F)", "; last byte: 0x", get_token_string()), "string");
}
}
}
@@ -1269,7 +1269,7 @@ class binary_reader
break;
}
return last_byte_error(113, concat("only string keys are supported, but found ", found, "; last byte: 0x", get_token_string()), "object key");
return last_byte_error(exception_id::invalid_string_or_size, concat("only string keys are supported, but found ", found, "; last byte: 0x", get_token_string()), "object key");
}
/*!
@@ -1350,7 +1350,7 @@ class binary_reader
default:
{
return last_byte_error(113, concat("expected length specification (0x40-0x5B)", inside_indefinite ? "" : " or indefinite binary array type (0x5F)", "; last byte: 0x", get_token_string()), "binary");
return last_byte_error(exception_id::invalid_string_or_size, concat("expected length specification (0x40-0x5B)", inside_indefinite ? "" : " or indefinite binary array type (0x5F)", "; last byte: 0x", get_token_string()), "binary");
}
}
}
@@ -1496,7 +1496,7 @@ class binary_reader
{
if (JSON_HEDLEY_UNLIKELY(!value_in_range_of<std::size_t>(len) || len == detail::unknown_size()))
{
return sax->parse_error(chars_read, get_token_string(), out_of_range::create(408,
return sax->parse_error(chars_read, get_token_string(), out_of_range::create(exception_id::container_too_large,
exception_message(concat("excessive ", context, " size"), "size"), nullptr));
}
result = conditional_static_cast<std::size_t>(len);
@@ -1984,7 +1984,7 @@ class binary_reader
default: // anything else
{
return unexpected_byte("invalid byte", "value");
return invalid_byte("value");
}
}
}
@@ -2065,7 +2065,7 @@ class binary_reader
default:
{
return last_byte_error(113, concat("expected length specification (0xA0-0xBF, 0xD9-0xDB); last byte: 0x", get_token_string()), "string");
return last_byte_error(exception_id::invalid_string_or_size, concat("expected length specification (0xA0-0xBF, 0xD9-0xDB); last byte: 0x", get_token_string()), "string");
}
}
}
@@ -2157,7 +2157,7 @@ class binary_reader
break;
}
return last_byte_error(113, concat("only string keys are supported, but found ", found, "; last byte: 0x", get_token_string()), "object key");
return last_byte_error(exception_id::invalid_string_or_size, concat("only string keys are supported, but found ", found, "; last byte: 0x", get_token_string()), "object key");
}
/*!
@@ -2466,7 +2466,7 @@ class binary_reader
{
if (JSON_HEDLEY_UNLIKELY(len < 0))
{
return last_byte_error(113, "string length must not be negative", "string");
return last_byte_error(exception_id::invalid_string_or_size, "string length must not be negative", "string");
}
return true;
}
@@ -2566,10 +2566,7 @@ class binary_reader
default:
break;
}
const char* expected = input_format != input_format_t::bjdata
? "expected length type specification (U, i, I, l, L)"
: "expected length type specification (U, i, u, I, m, l, M, L)";
return last_byte_error(113, concat(expected, "; last byte: 0x", get_token_string()), "string");
return length_type_error("", "string");
}
/*!
@@ -2654,11 +2651,11 @@ class binary_reader
}
if (JSON_HEDLEY_UNLIKELY(number < 0))
{
return last_byte_error(113, "count in an optimized container must be positive", "size");
return last_byte_error(exception_id::invalid_string_or_size, "count in an optimized container must be positive", "size");
}
if (JSON_HEDLEY_UNLIKELY(!value_in_range_of<std::size_t>(number)))
{
return sax->parse_error(chars_read, get_token_string(), out_of_range::create(408,
return sax->parse_error(chars_read, get_token_string(), out_of_range::create(exception_id::container_too_large,
exception_message("integer value overflow", "size"), nullptr));
}
result = static_cast<std::size_t>(number); // NOLINT(bugprone-signed-char-misuse,cert-str34-c): number is not a char
@@ -2751,7 +2748,7 @@ class binary_reader
}
if (!value_in_range_of<std::size_t>(number))
{
return sax->parse_error(chars_read, get_token_string(), out_of_range::create(408,
return sax->parse_error(chars_read, get_token_string(), out_of_range::create(exception_id::container_too_large,
exception_message("integer value overflow", "size"), nullptr));
}
result = detail::conditional_static_cast<std::size_t>(number);
@@ -2766,7 +2763,7 @@ class binary_reader
}
if (is_ndarray) // ndarray dimensional vector can only contain integers and cannot embed another array
{
return last_byte_error(113, "ndarray dimensional vector is not allowed", "size");
return last_byte_error(exception_id::invalid_string_or_size, "ndarray dimensional vector is not allowed", "size");
}
std::vector<size_t> dim;
if (JSON_HEDLEY_UNLIKELY(!get_ubjson_ndarray_size(dim)))
@@ -2806,7 +2803,7 @@ class binary_reader
// or SIZE_MAX.
if (JSON_HEDLEY_UNLIKELY(result > (std::numeric_limits<std::size_t>::max)() / i))
{
return sax->parse_error(chars_read, get_token_string(), out_of_range::create(408, exception_message("excessive ndarray size caused overflow", "size"), nullptr));
return sax->parse_error(chars_read, get_token_string(), out_of_range::create(exception_id::container_too_large, exception_message("excessive ndarray size caused overflow", "size"), nullptr));
}
result *= i;
// the pre-check above already rules out result becoming 0
@@ -2815,7 +2812,7 @@ class binary_reader
// unknown-size container (see get_ubjson_size_type())
if (result == npos)
{
return sax->parse_error(chars_read, get_token_string(), out_of_range::create(408, exception_message("excessive ndarray size caused overflow", "size"), nullptr));
return sax->parse_error(chars_read, get_token_string(), out_of_range::create(exception_id::container_too_large, exception_message("excessive ndarray size caused overflow", "size"), nullptr));
}
if (JSON_HEDLEY_UNLIKELY(!emit_unsigned(i)))
{
@@ -2832,10 +2829,7 @@ class binary_reader
default:
break;
}
const char* expected = input_format != input_format_t::bjdata
? "expected length type specification (U, i, I, l, L) after '#'"
: "expected length type specification (U, i, u, I, m, l, M, L) after '#'";
return last_byte_error(113, concat(expected, "; last byte: 0x", get_token_string()), "size");
return length_type_error(" after '#'", "size");
}
/*!
@@ -2868,7 +2862,7 @@ class binary_reader
if (input_format == input_format_t::bjdata
&& JSON_HEDLEY_UNLIKELY(is_bjd_excluded_optimized_type(result.second)))
{
return last_byte_error(112, concat("marker 0x", get_token_string(), " is not a permitted optimized array type"), "type");
return last_byte_error(exception_id::unexpected_byte, concat("marker 0x", get_token_string(), " is not a permitted optimized array type"), "type");
}
if (JSON_HEDLEY_UNLIKELY(!unexpect_eof("type")))
@@ -2883,7 +2877,7 @@ class binary_reader
{
return false;
}
return last_byte_error(112, concat("expected '#' after type information; last byte: 0x", get_token_string()), "size");
return last_byte_error(exception_id::unexpected_byte, concat("expected '#' after type information; last byte: 0x", get_token_string()), "size");
}
const bool is_error = get_ubjson_size_value(result.first, is_ndarray);
@@ -2902,7 +2896,7 @@ class binary_reader
const bool is_error = get_ubjson_size_value(result.first, is_ndarray);
if (input_format == input_format_t::bjdata && is_ndarray && !inside_ndarray)
{
return last_byte_error(112, "ndarray requires both type and size", "size");
return last_byte_error(exception_id::unexpected_byte, "ndarray requires both type and size", "size");
}
return is_error;
}
@@ -3034,7 +3028,7 @@ class binary_reader
}
if (JSON_HEDLEY_UNLIKELY(current > 127))
{
return last_byte_error(113, concat("byte after 'C' must be in range 0x00..0x7F; last byte: 0x", get_token_string()), "char");
return last_byte_error(exception_id::invalid_string_or_size, concat("byte after 'C' must be in range 0x00..0x7F; last byte: 0x", get_token_string()), "char");
}
string_t s(1, static_cast<typename string_t::value_type>(current));
return sax->string(s);
@@ -3055,7 +3049,7 @@ class binary_reader
default: // anything else
break;
}
return unexpected_byte("invalid byte", "value");
return invalid_byte("value");
}
/*!
@@ -3079,7 +3073,7 @@ class binary_reader
string_t key = "_ArrayType_";
if (JSON_HEDLEY_UNLIKELY(type_name == nullptr))
{
return unexpected_byte("invalid byte", "type");
return invalid_byte("type");
}
string_t type = type_name; // sax->string() takes a reference
@@ -3126,7 +3120,7 @@ class binary_reader
if (JSON_HEDLEY_UNLIKELY((size_and_type.second == 'Z' || size_and_type.second == 'T' || size_and_type.second == 'F')
&& size_and_type.first > max_valueless_container_size))
{
return sax->parse_error(chars_read, get_token_string(), out_of_range::create(408,
return sax->parse_error(chars_read, get_token_string(), out_of_range::create(exception_id::container_too_large,
exception_message("excessive array size", "size"), nullptr));
}
@@ -3162,7 +3156,7 @@ class binary_reader
// do not accept ND-array size in objects in BJData
if (input_format == input_format_t::bjdata && size_and_type.first != npos && (size_and_type.second & (1 << 8)) != 0)
{
return last_byte_error(112, "BJData object does not support ND-array size in optimized format", "object");
return last_byte_error(exception_id::unexpected_byte, "BJData object does not support ND-array size in optimized format", "object");
}
if (size_and_type.first != npos)
@@ -3199,7 +3193,7 @@ class binary_reader
// the lexer would stop at a NUL and accept the digits before it
if (JSON_HEDLEY_UNLIKELY(current == '\0'))
{
return sax->parse_error(chars_read, "00", parse_error::create(115, chars_read,
return sax->parse_error(chars_read, "00", parse_error::create(exception_id::invalid_high_precision_number, chars_read,
exception_message("invalid number text; last byte: 0x00", "high-precision number"), nullptr));
}
number_vector.push_back(static_cast<char>(current));
@@ -3216,7 +3210,7 @@ class binary_reader
if (JSON_HEDLEY_UNLIKELY(result_remainder != token_type::end_of_input))
{
return sax->parse_error(chars_read, number_string, parse_error::create(115, chars_read,
return sax->parse_error(chars_read, number_string, parse_error::create(exception_id::invalid_high_precision_number, chars_read,
exception_message(concat("invalid number text: ", number_lexer.get_token_string()), "high-precision number"), nullptr));
}
@@ -3234,7 +3228,7 @@ class binary_reader
return sax->parse_error(
chars_read,
number_string,
out_of_range::create(406, concat("number overflow parsing '", number_string, '\''), nullptr));
out_of_range::create(exception_id::number_overflow, concat("number overflow parsing '", number_string, '\''), nullptr));
}
// number_string is a std::string, while the SAX interface takes a
// string_t; convert explicitly, as the two are only implicitly
@@ -3256,7 +3250,7 @@ class binary_reader
case token_type::end_of_input:
case token_type::literal_or_value:
default:
return sax->parse_error(chars_read, number_string, parse_error::create(115, chars_read,
return sax->parse_error(chars_read, number_string, parse_error::create(exception_id::invalid_high_precision_number, chars_read,
exception_message(concat("invalid number text: ", number_lexer.get_token_string()), "high-precision number"), nullptr));
}
}
@@ -3530,7 +3524,7 @@ class binary_reader
}
// 0xFE: end of container where a value is expected
return unexpected_byte("invalid byte", "value");
return invalid_byte("value");
}
/*!
@@ -3839,7 +3833,7 @@ class binary_reader
{
// in case of failure, advance position by 1 to report the failing location
++chars_read;
sax->parse_error(chars_read, "<end of file>", parse_error::create(110, chars_read, exception_message("unexpected end of input", context), nullptr));
sax->parse_error(chars_read, "<end of file>", parse_error::create(exception_id::unexpected_end_of_input, chars_read, exception_message("unexpected end of input", context), nullptr));
return false;
}
return true;
@@ -3993,7 +3987,7 @@ class binary_reader
if (JSON_HEDLEY_UNLIKELY(std::isfinite(number) && !std::isfinite(result)))
{
return sax->parse_error(chars_read, get_token_string(),
out_of_range::create(406, exception_message("number overflow", "value"), nullptr));
out_of_range::create(exception_id::number_overflow, exception_message("number overflow", "value"), nullptr));
}
return sax->number_float(result, "");
}
@@ -4113,7 +4107,7 @@ class binary_reader
if (error_handler == error_handler_t::strict)
{
return last_byte_error(113, "invalid string: ill-formed UTF-8 byte", context);
return last_byte_error(exception_id::invalid_string_or_size, "invalid string: ill-formed UTF-8 byte", context);
}
result = sanitize_utf8(result, error_handler);
@@ -4209,7 +4203,7 @@ class binary_reader
if (JSON_HEDLEY_UNLIKELY(current == char_traits<char_type>::eof()))
{
return sax->parse_error(chars_read, "<end of file>",
parse_error::create(110, chars_read, exception_message("unexpected end of input", context), nullptr));
parse_error::create(exception_id::unexpected_end_of_input, chars_read, exception_message("unexpected end of input", context), nullptr));
}
return true;
}
@@ -4221,7 +4215,7 @@ class binary_reader
@param[in] context further context information
@return the result of the SAX parser's parse_error()
*/
bool last_byte_error(const int id_, const std::string& detail, const std::string& context) const
bool last_byte_error(const exception_id id_, const std::string& detail, const std::string& context) const
{
return sax->parse_error(chars_read, get_token_string(), parse_error::create(id_, chars_read, exception_message(detail, context), nullptr));
}
@@ -4234,7 +4228,30 @@ class binary_reader
*/
bool unexpected_byte(const char* detail, const std::string& context) const
{
return last_byte_error(112, concat(detail, ": 0x", get_token_string()), context);
return last_byte_error(exception_id::unexpected_byte, concat(detail, ": 0x", get_token_string()), context);
}
/*!
@brief reports the last read byte as invalid (parse_error.112)
@param[in] context further context information
@return the result of the SAX parser's parse_error()
*/
bool invalid_byte(const char* context) const
{
return unexpected_byte("invalid byte", context);
}
/*!
@brief reports that the last read byte is not a UBJSON/BJData length type (parse_error.113)
@param[in] position where the length type was expected, e.g. " after '#'"
@param[in] context further context information
@return the result of the SAX parser's parse_error()
*/
bool length_type_error(const char* position, const char* context) const
{
const char* types = input_format == input_format_t::bjdata ? "U, i, u, I, m, l, M, L" : "U, i, I, l, L";
return last_byte_error(exception_id::invalid_string_or_size,
concat("expected length type specification (", types, ")", position, "; last byte: 0x", get_token_string()), context);
}
/*!
@@ -581,7 +581,7 @@ class wide_string_input_adapter
template<class T>
JSON_HEDLEY_NO_RETURN std::size_t get_elements(T* /*dest*/, std::size_t /*count*/ = 1)
{
JSON_THROW(parse_error::create(112, 1, "wide string type cannot be interpreted as binary data", nullptr));
JSON_THROW(parse_error::create(exception_id::unexpected_byte, 1, "wide string type cannot be interpreted as binary data", nullptr));
}
private:
@@ -793,7 +793,7 @@ inline file_input_adapter input_adapter(std::FILE* file)
{
if (file == nullptr)
{
JSON_THROW(parse_error::create(101, 0, "attempting to parse an empty input; check that your input string or stream contains the expected JSON", nullptr));
JSON_THROW(parse_error::create(exception_id::syntax_error, 0, "attempting to parse an empty input; check that your input string or stream contains the expected JSON", nullptr));
}
return file_input_adapter(file);
}
@@ -802,7 +802,7 @@ inline input_stream_adapter input_adapter(std::istream& stream)
{
if (stream.rdbuf() == nullptr)
{
JSON_THROW(parse_error::create(101, 0, "attempting to parse an empty input; check that your input string or stream contains the expected JSON", nullptr));
JSON_THROW(parse_error::create(exception_id::syntax_error, 0, "attempting to parse an empty input; check that your input string or stream contains the expected JSON", nullptr));
}
return input_stream_adapter(stream);
}
@@ -827,7 +827,7 @@ contiguous_bytes_input_adapter input_adapter(CharT b)
{
if (b == nullptr)
{
JSON_THROW(parse_error::create(101, 0, "attempting to parse an empty input; check that your input string or stream contains the expected JSON", nullptr));
JSON_THROW(parse_error::create(exception_id::syntax_error, 0, "attempting to parse an empty input; check that your input string or stream contains the expected JSON", nullptr));
}
auto length = std::strlen(reinterpret_cast<const char*>(b));
const auto* ptr = reinterpret_cast<const char*>(b);
+1 -1
View File
@@ -192,7 +192,7 @@ bool check_container_size(SAX& sax, std::size_t len, const char* kind, BasicJson
{
if (JSON_HEDLEY_UNLIKELY(len != detail::unknown_size() && len > ref->max_size()))
{
return sax.parse_error(0, "", out_of_range::create(408, concat("excessive ", kind, " size: ", std::to_string(len)), ref));
return sax.parse_error(0, "", out_of_range::create(exception_id::container_too_large, concat("excessive ", kind, " size: ", std::to_string(len)), ref));
}
return true;
}
+2 -2
View File
@@ -298,7 +298,7 @@ class parser
{
return sax->parse_error(m_lexer.get_position(),
m_lexer.get_token_string(),
out_of_range::create(406, concat("number overflow parsing '", m_lexer.get_token_string(), '\''), nullptr));
out_of_range::create(exception_id::number_overflow, concat("number overflow parsing '", m_lexer.get_token_string(), '\''), nullptr));
}
if (JSON_HEDLEY_UNLIKELY(!sax->number_float(res, m_lexer.get_string())))
@@ -519,7 +519,7 @@ class parser
bool syntax_error(SAX& sax, const std::string& message)
{
return sax.parse_error(m_lexer.get_position(), m_lexer.get_token_string(),
parse_error::create(101, m_lexer.get_position(), message, nullptr));
parse_error::create(exception_id::syntax_error, m_lexer.get_position(), message, nullptr));
}
std::string exception_message(const token_type expected, const std::string& context)
@@ -282,7 +282,7 @@ class iter_impl // NOLINT(cppcoreguidelines-special-member-functions,hicpp-speci
/// @throw invalid_iterator.214 always
JSON_HEDLEY_NO_RETURN void throw_cannot_get_value() const
{
JSON_THROW(invalid_iterator::create(214, "cannot get value", m_object));
JSON_THROW(invalid_iterator::create(exception_id::iterator_value_unavailable, "cannot get value", m_object));
}
public:
@@ -484,7 +484,7 @@ class iter_impl // NOLINT(cppcoreguidelines-special-member-functions,hicpp-speci
// if objects are not the same, the comparison is undefined
if (JSON_HEDLEY_UNLIKELY(m_object != other.m_object))
{
JSON_THROW(invalid_iterator::create(212, "cannot compare iterators of different containers", m_object));
JSON_THROW(invalid_iterator::create(exception_id::iterators_compare_different_values, "cannot compare iterators of different containers", m_object));
}
// value-initialized forward iterators can be compared, and must compare equal to other value-initialized iterators of the same type #4493
@@ -533,7 +533,7 @@ class iter_impl // NOLINT(cppcoreguidelines-special-member-functions,hicpp-speci
// if objects are not the same, the comparison is undefined
if (JSON_HEDLEY_UNLIKELY(m_object != other.m_object))
{
JSON_THROW(invalid_iterator::create(212, "cannot compare iterators of different containers", m_object));
JSON_THROW(invalid_iterator::create(exception_id::iterators_compare_different_values, "cannot compare iterators of different containers", m_object));
}
// value-initialized forward iterators can be compared, and must compare equal to other value-initialized iterators of the same type #4493
@@ -546,7 +546,7 @@ class iter_impl // NOLINT(cppcoreguidelines-special-member-functions,hicpp-speci
switch (m_object->m_data.m_type)
{
case value_t::object:
JSON_THROW(invalid_iterator::create(213, "cannot compare order of object iterators", m_object));
JSON_THROW(invalid_iterator::create(exception_id::iterator_order_on_object, "cannot compare order of object iterators", m_object));
case value_t::array:
return (m_it.array_iterator < other.m_it.array_iterator);
@@ -602,7 +602,7 @@ class iter_impl // NOLINT(cppcoreguidelines-special-member-functions,hicpp-speci
switch (m_object->m_data.m_type)
{
case value_t::object:
JSON_THROW(invalid_iterator::create(209, "cannot use offsets with object iterators", m_object));
JSON_THROW(invalid_iterator::create(exception_id::iterator_arithmetic_on_object, "cannot use offsets with object iterators", m_object));
case value_t::array:
{
@@ -681,7 +681,7 @@ class iter_impl // NOLINT(cppcoreguidelines-special-member-functions,hicpp-speci
switch (m_object->m_data.m_type)
{
case value_t::object:
JSON_THROW(invalid_iterator::create(209, "cannot use offsets with object iterators", m_object));
JSON_THROW(invalid_iterator::create(exception_id::iterator_arithmetic_on_object, "cannot use offsets with object iterators", m_object));
case value_t::array:
return m_it.array_iterator - other.m_it.array_iterator;
@@ -710,7 +710,7 @@ class iter_impl // NOLINT(cppcoreguidelines-special-member-functions,hicpp-speci
switch (m_object->m_data.m_type)
{
case value_t::object:
JSON_THROW(invalid_iterator::create(208, "cannot use operator[] for object iterators", m_object));
JSON_THROW(invalid_iterator::create(exception_id::iterator_subscript_on_object, "cannot use operator[] for object iterators", m_object));
case value_t::array:
return *std::next(m_it.array_iterator, n);
@@ -750,7 +750,7 @@ class iter_impl // NOLINT(cppcoreguidelines-special-member-functions,hicpp-speci
return m_it.object_iterator->first;
}
JSON_THROW(invalid_iterator::create(207, "cannot use key() for non-object iterators", m_object));
JSON_THROW(invalid_iterator::create(exception_id::iterator_key_not_object, "cannot use key() for non-object iterators", m_object));
}
/*!
+15 -15
View File
@@ -247,7 +247,7 @@ class json_pointer
/// @throw out_of_range.405 always
JSON_HEDLEY_NO_RETURN static void throw_no_parent()
{
JSON_THROW(detail::out_of_range::create(405, "JSON pointer has no parent", nullptr));
JSON_THROW(detail::out_of_range::create(detail::exception_id::patch_on_root, "JSON pointer has no parent", nullptr));
}
/// @throw out_of_range.404 always
@@ -256,7 +256,7 @@ class json_pointer
{
static_cast<void>(reference_token); // unused when JSON_NOEXCEPTION is defined
static_cast<void>(context);
JSON_THROW(detail::out_of_range::create(404, detail::concat("unresolved reference token '", reference_token, "'"), context));
JSON_THROW(detail::out_of_range::create(detail::exception_id::pointer_unresolved, detail::concat("unresolved reference token '", reference_token, "'"), context));
}
/*!
@@ -344,13 +344,13 @@ class json_pointer
// the branches differ in their messages, not after JSON_THROW's expansion
// NOLINTNEXTLINE(bugprone-branch-clone)
case array_index_status::leading_zero:
JSON_THROW(detail::parse_error::create(106, 0, detail::concat("array index '", s, "' must not begin with '0'"), nullptr));
JSON_THROW(detail::parse_error::create(detail::exception_id::pointer_index_leading_zero, 0, detail::concat("array index '", s, "' must not begin with '0'"), nullptr));
case array_index_status::not_a_number:
JSON_THROW(detail::parse_error::create(109, 0, detail::concat("array index '", s, "' is not a number"), nullptr));
JSON_THROW(detail::parse_error::create(detail::exception_id::pointer_index_not_a_number, 0, detail::concat("array index '", s, "' is not a number"), nullptr));
case array_index_status::unresolved:
throw_unresolved(s, nullptr);
case array_index_status::exceeds_size_type:
JSON_THROW(detail::out_of_range::create(410, detail::concat("array index ", s, " exceeds size_type"), nullptr));
JSON_THROW(detail::out_of_range::create(detail::exception_id::value_out_of_range, detail::concat("array index ", s, " exceeds size_type"), nullptr));
case array_index_status::ok:
default:
break;
@@ -452,7 +452,7 @@ class json_pointer
case detail::value_t::binary:
case detail::value_t::discarded:
default:
JSON_THROW(detail::type_error::create(313, "invalid value to unflatten", &j));
JSON_THROW(detail::type_error::create(detail::exception_id::unflatten_invalid_value, "invalid value to unflatten", &j));
}
prefix.push_back(reference_token);
@@ -567,7 +567,7 @@ class json_pointer
if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
{
// "-" always fails the range check
JSON_THROW(detail::out_of_range::create(402, detail::concat(
JSON_THROW(detail::out_of_range::create(detail::exception_id::pointer_past_the_end_index, detail::concat(
"array index '-' (", std::to_string(ptr->m_data.m_value.array->size()),
") is out of range"), ptr));
}
@@ -576,7 +576,7 @@ class json_pointer
// Bounds check before access to avoid exception with JSON_NOEXCEPTION
if (JSON_HEDLEY_UNLIKELY(idx >= ptr->m_data.m_value.array->size()))
{
JSON_THROW(detail::out_of_range::create(401, detail::concat(
JSON_THROW(detail::out_of_range::create(detail::exception_id::array_index_out_of_range, detail::concat(
"array index ", std::to_string(idx), " is out of range"), ptr));
}
ptr = &ptr->operator[](idx);
@@ -636,7 +636,7 @@ class json_pointer
if (JSON_HEDLEY_UNLIKELY(reference_token == "-"))
{
// "-" cannot be used for const access
JSON_THROW(detail::out_of_range::create(402, detail::concat("array index '-' (", std::to_string(ptr->m_data.m_value.array->size()), ") is out of range"), ptr));
JSON_THROW(detail::out_of_range::create(detail::exception_id::pointer_past_the_end_index, detail::concat("array index '-' (", std::to_string(ptr->m_data.m_value.array->size()), ") is out of range"), ptr));
}
// use unchecked array access; the const operator[]
@@ -709,9 +709,9 @@ class json_pointer
// the branches differ in their messages, not after JSON_THROW's expansion
// NOLINTNEXTLINE(bugprone-branch-clone)
case array_index_status::leading_zero:
JSON_THROW(detail::parse_error::create(106, 0, detail::concat("array index '", reference_token, "' must not begin with '0'"), nullptr));
JSON_THROW(detail::parse_error::create(detail::exception_id::pointer_index_leading_zero, 0, detail::concat("array index '", reference_token, "' must not begin with '0'"), nullptr));
case array_index_status::not_a_number:
JSON_THROW(detail::parse_error::create(109, 0, detail::concat("array index '", reference_token, "' is not a number"), nullptr));
JSON_THROW(detail::parse_error::create(detail::exception_id::pointer_index_not_a_number, 0, detail::concat("array index '", reference_token, "' is not a number"), nullptr));
case array_index_status::unresolved:
case array_index_status::exceeds_size_type:
return nullptr;
@@ -838,7 +838,7 @@ class json_pointer
// check if a nonempty reference string begins with slash
if (JSON_HEDLEY_UNLIKELY(reference_string[0] != '/'))
{
JSON_THROW(detail::parse_error::create(107, 1, detail::concat("JSON pointer must be empty or begin with '/' - was: '", reference_string, "'"), nullptr));
JSON_THROW(detail::parse_error::create(detail::exception_id::pointer_missing_slash, 1, detail::concat("JSON pointer must be empty or begin with '/' - was: '", reference_string, "'"), nullptr));
}
// extract the reference tokens:
@@ -874,7 +874,7 @@ class json_pointer
(reference_token[pos + 1] != '0' &&
reference_token[pos + 1] != '1')))
{
JSON_THROW(detail::parse_error::create(108, 0, "escape character '~' must be followed with '0' or '1'", nullptr));
JSON_THROW(detail::parse_error::create(detail::exception_id::pointer_invalid_escape, 0, "escape character '~' must be followed with '0' or '1'", nullptr));
}
}
@@ -971,7 +971,7 @@ class json_pointer
{
if (JSON_HEDLEY_UNLIKELY(!value.is_object()))
{
JSON_THROW(detail::type_error::create(314, "only objects can be unflattened", &value));
JSON_THROW(detail::type_error::create(detail::exception_id::unflatten_not_object, "only objects can be unflattened", &value));
}
BasicJsonType result;
@@ -999,7 +999,7 @@ class json_pointer
{
if (JSON_HEDLEY_UNLIKELY(!element.second.is_primitive()))
{
JSON_THROW(detail::type_error::create(315, "values in object must be primitive", &element.second));
JSON_THROW(detail::type_error::create(detail::exception_id::unflatten_value_not_primitive, "values in object must be primitive", &element.second));
}
// Assign the value to the reference pointed to by JSON pointer. Note
+2 -2
View File
@@ -312,7 +312,7 @@
return ej_pair.first == e; \
}); \
if (it != std::end(m)) j = it->second; \
else ::nlohmann::detail::templated_json_throw<nlohmann::detail::out_of_range>(nlohmann::detail::out_of_range::create(410,"enum value out of range for " #ENUM_TYPE, nullptr)); \
else ::nlohmann::detail::templated_json_throw<nlohmann::detail::out_of_range>(nlohmann::detail::out_of_range::create(nlohmann::detail::exception_id::value_out_of_range,"enum value out of range for " #ENUM_TYPE, nullptr)); \
} \
template<typename BasicJsonType> \
inline void from_json(const BasicJsonType& j, ENUM_TYPE& e) \
@@ -327,7 +327,7 @@
return ej_pair.second == j; \
}); \
if (it != std::end(m)) e = it->first; \
else ::nlohmann::detail::templated_json_throw<nlohmann::detail::out_of_range>(nlohmann::detail::out_of_range::create(410, nlohmann::detail::concat("enum value out of range for " #ENUM_TYPE ": ", j.dump(-1, ' ', false, nlohmann::detail::error_handler_t::replace)), &j)); \
else ::nlohmann::detail::templated_json_throw<nlohmann::detail::out_of_range>(nlohmann::detail::out_of_range::create(nlohmann::detail::exception_id::value_out_of_range, nlohmann::detail::concat("enum value out of range for " #ENUM_TYPE ": ", j.dump(-1, ' ', false, nlohmann::detail::error_handler_t::replace)), &j)); \
}
// Ugly macros to avoid uglier copy-paste when specializing basic_json. They
@@ -150,7 +150,7 @@ class binary_writer
case value_t::discarded:
default:
{
JSON_THROW(type_error::create(317, concat("to serialize to BSON, top-level type must be object, but is ", j.type_name()), &j));
JSON_THROW(type_error::create(exception_id::type_not_serializable, concat("to serialize to BSON, top-level type must be object, but is ", j.type_name()), &j));
}
}
}
@@ -338,7 +338,7 @@ class binary_writer
{
if (JSON_HEDLEY_UNLIKELY(!value_in_range_of<std::uint32_t>(length)))
{
JSON_THROW(out_of_range::create(412, concat("MessagePack length ", std::to_string(length), " exceeds maximum of ", std::to_string((std::numeric_limits<std::uint32_t>::max)())), &j));
JSON_THROW(out_of_range::create(exception_id::length_too_large, concat("MessagePack length ", std::to_string(length), " exceeds maximum of ", std::to_string((std::numeric_limits<std::uint32_t>::max)())), &j));
}
static_cast<void>(j);
@@ -604,7 +604,7 @@ class binary_writer
{
if (JSON_HEDLEY_UNLIKELY(j.m_data.m_value.binary->subtype() > (std::numeric_limits<std::uint8_t>::max)()))
{
JSON_THROW(out_of_range::create(415, concat("subtype ", std::to_string(j.m_data.m_value.binary->subtype()), " is too large for the MessagePack ext type (max 255)"), &j));
JSON_THROW(out_of_range::create(exception_id::subtype_out_of_range, concat("subtype ", std::to_string(j.m_data.m_value.binary->subtype()), " is too large for the MessagePack ext type (max 255)"), &j));
}
write_number(static_cast<std::int8_t>(j.m_data.m_value.binary->subtype()));
@@ -747,7 +747,7 @@ class binary_writer
{
if (!use_count)
{
JSON_THROW(other_error::create(502, "use_type requires use_size = true", &j));
JSON_THROW(other_error::create(exception_id::size_marker_required, "use_type requires use_size = true", &j));
}
const CharType first_prefix = ubjson_prefix(j.front(), use_bjdata);
const bool same_prefix = std::all_of(j.begin() + 1, j.end(),
@@ -804,7 +804,7 @@ class binary_writer
{
if (!use_count)
{
JSON_THROW(other_error::create(502, "use_type requires use_size = true", &j));
JSON_THROW(other_error::create(exception_id::size_marker_required, "use_type requires use_size = true", &j));
}
oa.write_character(to_char_type('$'));
oa.write_character(bjdata_draft3 ? 'B' : 'U');
@@ -861,7 +861,7 @@ class binary_writer
{
if (!use_count)
{
JSON_THROW(other_error::create(502, "use_type requires use_size = true", &j));
JSON_THROW(other_error::create(exception_id::size_marker_required, "use_type requires use_size = true", &j));
}
const CharType first_prefix = ubjson_prefix(j.front(), use_bjdata);
const bool same_prefix = std::all_of(j.begin(), j.end(),
@@ -933,7 +933,7 @@ class binary_writer
{
static_cast<void>(j); // unused when JSON_NOEXCEPTION is defined
static_cast<void>(format_name);
JSON_THROW(type_error::create(321, concat("cannot serialize discarded value to ", format_name), &j));
JSON_THROW(type_error::create(exception_id::discarded_value_used, concat("cannot serialize discarded value to ", format_name), &j));
}
//////////
@@ -953,7 +953,7 @@ class binary_writer
const auto it = name.find(static_cast<typename string_t::value_type>(0));
if (JSON_HEDLEY_UNLIKELY(it != BasicJsonType::string_t::npos))
{
JSON_THROW(out_of_range::create(409, concat("BSON key cannot contain code point U+0000 (at byte ", std::to_string(it), ")"), &j));
JSON_THROW(out_of_range::create(exception_id::bson_key_with_null, concat("BSON key cannot contain code point U+0000 (at byte ", std::to_string(it), ")"), &j));
}
string_t storage;
@@ -971,7 +971,7 @@ class binary_writer
{
if (JSON_HEDLEY_UNLIKELY(!value_in_range_of<std::int32_t>(size)))
{
JSON_THROW(out_of_range::create(412, concat("BSON length ", std::to_string(size), " exceeds maximum of ", std::to_string((std::numeric_limits<std::int32_t>::max)())), nullptr));
JSON_THROW(out_of_range::create(exception_id::length_too_large, concat("BSON length ", std::to_string(size), " exceeds maximum of ", std::to_string((std::numeric_limits<std::int32_t>::max)())), nullptr));
}
return static_cast<std::int32_t>(size);
@@ -1157,7 +1157,7 @@ class binary_writer
if (value.has_subtype() && JSON_HEDLEY_UNLIKELY(value.subtype() > (std::numeric_limits<std::uint8_t>::max)()))
{
JSON_THROW(out_of_range::create(415, concat("subtype ", std::to_string(value.subtype()), " is too large for the BSON binary subtype (max 255)"), &j));
JSON_THROW(out_of_range::create(exception_id::subtype_out_of_range, concat("subtype ", std::to_string(value.subtype()), " is too large for the BSON binary subtype (max 255)"), &j));
}
return sizeof(std::int32_t) + value.size() + 1ul;
@@ -2092,7 +2092,7 @@ class binary_writer
{
if (j.m_data.m_value.number_unsigned > static_cast<typename BasicJsonType::number_unsigned_t>((std::numeric_limits<std::int64_t>::max)()))
{
JSON_THROW(out_of_range::create(407, concat("integer number ", std::to_string(j.m_data.m_value.number_unsigned), " cannot be represented by BON8 as it does not fit int64"), &j));
JSON_THROW(out_of_range::create(exception_id::integer_too_large, concat("integer number ", std::to_string(j.m_data.m_value.number_unsigned), " cannot be represented by BON8 as it does not fit int64"), &j));
}
write_bon8_integer(static_cast<std::int64_t>(j.m_data.m_value.number_unsigned));
string_open = false;
@@ -2245,7 +2245,7 @@ class binary_writer
const std::size_t valid = valid_utf8_prefix(data, s.size());
if (JSON_HEDLEY_UNLIKELY(valid != s.size()))
{
JSON_THROW(type_error::create(316, concat("invalid UTF-8 byte at index ", std::to_string(valid), ": 0x", detail::hex_byte(data[valid])), &context));
JSON_THROW(type_error::create(exception_id::invalid_utf8, concat("invalid UTF-8 byte at index ", std::to_string(valid), ": 0x", detail::hex_byte(data[valid])), &context));
}
}
@@ -888,7 +888,7 @@ class serializer
{
case error_handler_t::strict:
{
JSON_THROW(type_error::create(316, concat("invalid UTF-8 byte at index ", std::to_string(i), ": 0x", detail::hex_byte(byte)), nullptr));
JSON_THROW(type_error::create(exception_id::invalid_utf8, concat("invalid UTF-8 byte at index ", std::to_string(i), ": 0x", detail::hex_byte(byte)), nullptr));
}
case error_handler_t::ignore:
@@ -1021,7 +1021,7 @@ class serializer
{
case error_handler_t::strict:
{
JSON_THROW(type_error::create(316, concat("incomplete UTF-8 string; last byte: 0x", detail::hex_byte(static_cast<std::uint8_t>(s[s.size() - 1]))), nullptr));
JSON_THROW(type_error::create(exception_id::invalid_utf8, concat("incomplete UTF-8 string; last byte: 0x", detail::hex_byte(static_cast<std::uint8_t>(s[s.size() - 1]))), nullptr));
}
case error_handler_t::ignore:
+78 -69
View File
@@ -639,7 +639,7 @@ class basic_json // NOLINT(cppcoreguidelines-special-member-functions,hicpp-spec
object = nullptr; // silence warning, see #821
if (JSON_HEDLEY_UNLIKELY(t == value_t::null))
{
JSON_THROW(other_error::create(500, "961c151d2e87f2686a955a9be24d316f1362bf21 3.12.0", nullptr)); // LCOV_EXCL_LINE
JSON_THROW(other_error::create(detail::exception_id::internal_error, "961c151d2e87f2686a955a9be24d316f1362bf21 3.12.0", nullptr)); // LCOV_EXCL_LINE
}
break;
}
@@ -2287,7 +2287,7 @@ public:
// if an object is wanted but impossible, throw an exception
if (JSON_HEDLEY_UNLIKELY(manual_type == value_t::object && !is_an_object))
{
JSON_THROW(type_error::create(301, "cannot create object from initializer list", nullptr));
JSON_THROW(type_error::create(detail::exception_id::object_from_non_pairs, "cannot create object from initializer list", nullptr));
}
}
@@ -2407,7 +2407,7 @@ public:
// make sure the iterator fits the current value
if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
{
JSON_THROW(invalid_iterator::create(201, "iterators are not compatible", nullptr));
JSON_THROW(invalid_iterator::create(detail::exception_id::iterators_incompatible, "iterators are not compatible", nullptr));
}
// copy type from the first iterator
@@ -2426,7 +2426,7 @@ public:
if (JSON_HEDLEY_UNLIKELY(!first.m_it.primitive_iterator.is_begin()
|| !last.m_it.primitive_iterator.is_end()))
{
JSON_THROW(invalid_iterator::create(204, "iterators out of range", first.m_object));
JSON_THROW(invalid_iterator::create(detail::exception_id::iterator_range_out_of_range, "iterators out of range", first.m_object));
}
break;
}
@@ -2494,7 +2494,7 @@ public:
case value_t::null:
case value_t::discarded:
default:
JSON_THROW(invalid_iterator::create(206, detail::concat("cannot construct with iterators from ", first.m_object->type_name()), first.m_object));
JSON_THROW(invalid_iterator::create(detail::exception_id::iterator_range_of_null, detail::concat("cannot construct with iterators from ", first.m_object->type_name()), first.m_object));
}
set_parents();
@@ -2882,7 +2882,7 @@ public:
return *ptr;
}
JSON_THROW(type_error::create(303, detail::concat("incompatible ReferenceType for get_ref, actual type is ", obj.type_name()), &obj));
JSON_THROW(type_error::create(detail::exception_id::incompatible_reference_type, detail::concat("incompatible ReferenceType for get_ref, actual type is ", obj.type_name()), &obj));
}
public:
@@ -3320,7 +3320,7 @@ public:
// at only works for objects
if (JSON_HEDLEY_UNLIKELY(!j.is_object()))
{
detail::throw_cannot_use_with(304, "at()", j);
detail::throw_cannot_use_with(detail::exception_id::at_wrong_type, "at()", j);
}
auto it = object_lookup(j, std::forward<KeyType>(key));
@@ -3330,7 +3330,7 @@ public:
// std::map or ordered_map) never moves from its argument, so key is still
// valid here regardless of whether KeyType was deduced as an rvalue reference
// NOLINTNEXTLINE(bugprone-use-after-move,hicpp-invalid-access-moved)
JSON_THROW(out_of_range::create(403, detail::concat("key '", string_t(key), "' not found"), &j));
JSON_THROW(out_of_range::create(detail::exception_id::key_not_found, detail::concat("key '", string_t(key), "' not found"), &j));
}
return it->second;
}
@@ -3345,12 +3345,12 @@ public:
// at only works for arrays
if (JSON_HEDLEY_UNLIKELY(!j.is_array()))
{
detail::throw_cannot_use_with(304, "at()", j);
detail::throw_cannot_use_with(detail::exception_id::at_wrong_type, "at()", j);
}
if (JSON_HEDLEY_UNLIKELY(idx >= j.m_data.m_value.array->size()))
{
JSON_THROW(out_of_range::create(401, detail::concat("array index ", std::to_string(idx), " is out of range"), &j));
JSON_THROW(out_of_range::create(detail::exception_id::array_index_out_of_range, detail::concat("array index ", std::to_string(idx), " is out of range"), &j));
}
return (*j.m_data.m_value.array)[idx];
@@ -3383,6 +3383,15 @@ public:
m_data.m_type = value_t::object;
}
/// @brief throws because operator[] is not supported for the type of this value
/// @param[in] argument the kind of the operator's argument, "numeric" or "string"
/// @throw type_error.305 always
JSON_HEDLEY_NO_RETURN void throw_subscript_wrong_type(const char* argument) const
{
detail::throw_cannot_use_with(detail::exception_id::subscript_wrong_type,
detail::concat("operator[] with a ", argument, " argument").c_str(), *this);
}
public:
////////////////////
// element access //
@@ -3487,7 +3496,7 @@ public:
return m_data.m_value.array->operator[](idx);
}
detail::throw_cannot_use_with(305, "operator[] with a numeric argument", *this);
throw_subscript_wrong_type("numeric");
}
/// @brief access specified array element
@@ -3501,7 +3510,7 @@ public:
return m_data.m_value.array->operator[](idx);
}
detail::throw_cannot_use_with(305, "operator[] with a numeric argument", *this);
throw_subscript_wrong_type("numeric");
}
/// @brief access specified object element
@@ -3521,7 +3530,7 @@ public:
return set_parent(result.first->second);
}
detail::throw_cannot_use_with(305, "operator[] with a string argument", *this);
throw_subscript_wrong_type("string");
}
/// @brief access specified object element
@@ -3536,7 +3545,7 @@ public:
return it->second;
}
detail::throw_cannot_use_with(305, "operator[] with a string argument", *this);
throw_subscript_wrong_type("string");
}
// these two functions resolve a (const) char * ambiguity affecting Clang and MSVC
@@ -3572,7 +3581,7 @@ public:
return set_parent(result.first->second);
}
detail::throw_cannot_use_with(305, "operator[] with a string argument", *this);
throw_subscript_wrong_type("string");
}
/// @brief access specified object element
@@ -3589,7 +3598,7 @@ public:
return it->second;
}
detail::throw_cannot_use_with(305, "operator[] with a string argument", *this);
throw_subscript_wrong_type("string");
}
private:
@@ -3613,7 +3622,7 @@ public:
// value only works for objects
if (JSON_HEDLEY_UNLIKELY(!is_object()))
{
detail::throw_cannot_use_with(306, "value()", *this);
detail::throw_cannot_use_with(detail::exception_id::value_wrong_type, "value()", *this);
}
const auto it = find(std::forward<KeyType>(key));
@@ -3628,7 +3637,7 @@ public:
// value only works for arrays and objects
if (JSON_HEDLEY_UNLIKELY(!is_structured()))
{
detail::throw_cannot_use_with(306, "value()", *this);
detail::throw_cannot_use_with(detail::exception_id::value_wrong_type, "value()", *this);
}
return ptr.get_checked_or_null(this);
@@ -3795,7 +3804,7 @@ public:
// make sure the iterator fits the current value
if (JSON_HEDLEY_UNLIKELY(this != pos.m_object))
{
JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", this));
JSON_THROW(invalid_iterator::create(detail::exception_id::iterator_from_other_value, "iterator does not fit current value", this));
}
IteratorType result = end();
@@ -3811,7 +3820,7 @@ public:
{
if (JSON_HEDLEY_UNLIKELY(!pos.m_it.primitive_iterator.is_begin()))
{
JSON_THROW(invalid_iterator::create(205, "iterator out of range", this));
JSON_THROW(invalid_iterator::create(detail::exception_id::iterator_out_of_range, "iterator out of range", this));
}
m_data.m_value.destroy(m_data.m_type);
@@ -3837,7 +3846,7 @@ public:
case value_t::null:
case value_t::discarded:
default:
detail::throw_cannot_use_with(307, "erase()", *this);
detail::throw_cannot_use_with(detail::exception_id::erase_wrong_type, "erase()", *this);
}
return result;
@@ -3853,7 +3862,7 @@ public:
// make sure the iterator fits the current value
if (JSON_HEDLEY_UNLIKELY(this != first.m_object || this != last.m_object))
{
JSON_THROW(invalid_iterator::create(203, "iterators do not fit current value", this));
JSON_THROW(invalid_iterator::create(detail::exception_id::iterator_range_from_other_value, "iterators do not fit current value", this));
}
IteratorType result = end();
@@ -3870,7 +3879,7 @@ public:
if (JSON_HEDLEY_UNLIKELY(!first.m_it.primitive_iterator.is_begin()
|| !last.m_it.primitive_iterator.is_end()))
{
JSON_THROW(invalid_iterator::create(204, "iterators out of range", this));
JSON_THROW(invalid_iterator::create(detail::exception_id::iterator_range_out_of_range, "iterators out of range", this));
}
m_data.m_value.destroy(m_data.m_type);
@@ -3898,7 +3907,7 @@ public:
case value_t::null:
case value_t::discarded:
default:
detail::throw_cannot_use_with(307, "erase()", *this);
detail::throw_cannot_use_with(detail::exception_id::erase_wrong_type, "erase()", *this);
}
return result;
@@ -3912,7 +3921,7 @@ public:
// this erase only works for objects
if (JSON_HEDLEY_UNLIKELY(!is_object()))
{
detail::throw_cannot_use_with(307, "erase()", *this);
detail::throw_cannot_use_with(detail::exception_id::erase_wrong_type, "erase()", *this);
}
const auto erased = m_data.m_value.object->erase(std::forward<KeyType>(key));
@@ -3927,7 +3936,7 @@ public:
// this erase only works for objects
if (JSON_HEDLEY_UNLIKELY(!is_object()))
{
detail::throw_cannot_use_with(307, "erase()", *this);
detail::throw_cannot_use_with(detail::exception_id::erase_wrong_type, "erase()", *this);
}
const auto it = object_lookup(*this, std::forward<KeyType>(key));
@@ -3969,14 +3978,14 @@ public:
{
if (JSON_HEDLEY_UNLIKELY(idx >= size()))
{
JSON_THROW(out_of_range::create(401, detail::concat("array index ", std::to_string(idx), " is out of range"), this));
JSON_THROW(out_of_range::create(detail::exception_id::array_index_out_of_range, detail::concat("array index ", std::to_string(idx), " is out of range"), this));
}
m_data.m_value.array->erase(m_data.m_value.array->begin() + static_cast<difference_type>(idx));
}
else
{
detail::throw_cannot_use_with(307, "erase()", *this);
detail::throw_cannot_use_with(detail::exception_id::erase_wrong_type, "erase()", *this);
}
}
@@ -4465,7 +4474,7 @@ public:
// push_back only works for null objects or arrays
if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_array())))
{
detail::throw_cannot_use_with(308, "push_back()", *this);
detail::throw_cannot_use_with(detail::exception_id::push_back_wrong_type, "push_back()", *this);
}
// transform a null object into an array
@@ -4496,7 +4505,7 @@ public:
// push_back only works for null objects or arrays
if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_array())))
{
detail::throw_cannot_use_with(308, "push_back()", *this);
detail::throw_cannot_use_with(detail::exception_id::push_back_wrong_type, "push_back()", *this);
}
// transform a null object into an array
@@ -4526,7 +4535,7 @@ public:
// push_back only works for null objects or objects
if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_object())))
{
detail::throw_cannot_use_with(308, "push_back()", *this);
detail::throw_cannot_use_with(detail::exception_id::push_back_wrong_type, "push_back()", *this);
}
// transform a null object into an object
@@ -4580,7 +4589,7 @@ public:
// emplace_back only works for null objects or arrays
if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_array())))
{
detail::throw_cannot_use_with(311, "emplace_back()", *this);
detail::throw_cannot_use_with(detail::exception_id::emplace_wrong_type, "emplace_back()", *this);
}
// transform a null object into an array
@@ -4603,7 +4612,7 @@ public:
// emplace only works for null objects or arrays
if (JSON_HEDLEY_UNLIKELY(!(is_null() || is_object())))
{
detail::throw_cannot_use_with(311, "emplace()", *this);
detail::throw_cannot_use_with(detail::exception_id::emplace_wrong_type, "emplace()", *this);
}
// transform a null object into an object
@@ -4655,14 +4664,14 @@ public:
// check if iterator pos fits to this JSON value
if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
{
JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", this));
JSON_THROW(invalid_iterator::create(detail::exception_id::iterator_from_other_value, "iterator does not fit current value", this));
}
// insert to array and return iterator
return insert_iterator(pos, val);
}
detail::throw_cannot_use_with(309, "insert()", *this);
detail::throw_cannot_use_with(detail::exception_id::insert_wrong_type, "insert()", *this);
}
/// @brief inserts element into array
@@ -4675,7 +4684,7 @@ public:
// check if iterator pos fits to this JSON value
if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
{
JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", this));
JSON_THROW(invalid_iterator::create(detail::exception_id::iterator_from_other_value, "iterator does not fit current value", this));
}
// moving into a local first keeps this safe even if val aliases
@@ -4684,7 +4693,7 @@ public:
return insert_iterator(pos, std::move(tmp));
}
detail::throw_cannot_use_with(309, "insert()", *this);
detail::throw_cannot_use_with(detail::exception_id::insert_wrong_type, "insert()", *this);
}
/// @brief inserts copies of element into array
@@ -4697,14 +4706,14 @@ public:
// check if iterator pos fits to this JSON value
if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
{
JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", this));
JSON_THROW(invalid_iterator::create(detail::exception_id::iterator_from_other_value, "iterator does not fit current value", this));
}
// insert to array and return iterator
return insert_iterator(pos, cnt, val);
}
detail::throw_cannot_use_with(309, "insert()", *this);
detail::throw_cannot_use_with(detail::exception_id::insert_wrong_type, "insert()", *this);
}
/// @brief inserts range of elements into array
@@ -4714,30 +4723,30 @@ public:
// insert only works for arrays
if (JSON_HEDLEY_UNLIKELY(!is_array()))
{
detail::throw_cannot_use_with(309, "insert()", *this);
detail::throw_cannot_use_with(detail::exception_id::insert_wrong_type, "insert()", *this);
}
// check if iterator pos fits to this JSON value
if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
{
JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", this));
JSON_THROW(invalid_iterator::create(detail::exception_id::iterator_from_other_value, "iterator does not fit current value", this));
}
// check if range iterators belong to the same JSON object
if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
{
JSON_THROW(invalid_iterator::create(210, "iterators do not fit", this));
JSON_THROW(invalid_iterator::create(detail::exception_id::insert_range_incompatible, "iterators do not fit", this));
}
if (JSON_HEDLEY_UNLIKELY(first.m_object == this))
{
JSON_THROW(invalid_iterator::create(211, "passed iterators may not belong to container", this));
JSON_THROW(invalid_iterator::create(detail::exception_id::insert_range_into_itself, "passed iterators may not belong to container", this));
}
// passed iterators must belong to arrays
if (JSON_HEDLEY_UNLIKELY(!first.m_object->is_array()))
{
JSON_THROW(invalid_iterator::create(202, "iterators first and last must point to arrays", this));
JSON_THROW(invalid_iterator::create(detail::exception_id::iterator_from_other_value, "iterators first and last must point to arrays", this));
}
// insert to array and return iterator
@@ -4751,13 +4760,13 @@ public:
// insert only works for arrays
if (JSON_HEDLEY_UNLIKELY(!is_array()))
{
detail::throw_cannot_use_with(309, "insert()", *this);
detail::throw_cannot_use_with(detail::exception_id::insert_wrong_type, "insert()", *this);
}
// check if iterator pos fits to this JSON value
if (JSON_HEDLEY_UNLIKELY(pos.m_object != this))
{
JSON_THROW(invalid_iterator::create(202, "iterator does not fit current value", this));
JSON_THROW(invalid_iterator::create(detail::exception_id::iterator_from_other_value, "iterator does not fit current value", this));
}
// copy the values first: ilist may refer to elements of this array
@@ -4779,19 +4788,19 @@ public:
// insert only works for objects
if (JSON_HEDLEY_UNLIKELY(!is_object()))
{
detail::throw_cannot_use_with(309, "insert()", *this);
detail::throw_cannot_use_with(detail::exception_id::insert_wrong_type, "insert()", *this);
}
// check if range iterators belong to the same JSON object
if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
{
JSON_THROW(invalid_iterator::create(210, "iterators do not fit", this));
JSON_THROW(invalid_iterator::create(detail::exception_id::insert_range_incompatible, "iterators do not fit", this));
}
// passed iterators must belong to objects
if (JSON_HEDLEY_UNLIKELY(!first.m_object->is_object()))
{
JSON_THROW(invalid_iterator::create(202, "iterators first and last must point to objects", this));
JSON_THROW(invalid_iterator::create(detail::exception_id::iterator_from_other_value, "iterators first and last must point to objects", this));
}
m_data.m_value.object->insert(first.m_it.object_iterator, last.m_it.object_iterator);
@@ -4808,7 +4817,7 @@ public:
// j, not the copy made below)
if (JSON_HEDLEY_UNLIKELY(!j.is_object()))
{
detail::throw_cannot_use_with(312, "update()", j);
detail::throw_cannot_use_with(detail::exception_id::update_wrong_type, "update()", j);
}
// copy first: j may be *this or one of its descendants, and is
@@ -4826,13 +4835,13 @@ public:
// check if range iterators belong to the same JSON object
if (JSON_HEDLEY_UNLIKELY(first.m_object != last.m_object))
{
JSON_THROW(invalid_iterator::create(210, "iterators do not fit", this));
JSON_THROW(invalid_iterator::create(detail::exception_id::insert_range_incompatible, "iterators do not fit", this));
}
// passed iterators must belong to objects
if (JSON_HEDLEY_UNLIKELY(!first.m_object->is_object()))
{
detail::throw_cannot_use_with(312, "update()", *first.m_object);
detail::throw_cannot_use_with(detail::exception_id::update_wrong_type, "update()", *first.m_object);
}
// copy first: the range may belong to *this or one of its
@@ -4868,7 +4877,7 @@ public:
if (JSON_HEDLEY_UNLIKELY(!is_object()))
{
detail::throw_cannot_use_with(312, "update()", *this);
detail::throw_cannot_use_with(detail::exception_id::update_wrong_type, "update()", *this);
}
}
@@ -5031,7 +5040,7 @@ public:
}
else
{
detail::throw_cannot_use_with(310, "swap(array_t&)", *this);
detail::throw_cannot_use_with(detail::exception_id::swap_wrong_type, "swap(array_t&)", *this);
}
}
@@ -5048,7 +5057,7 @@ public:
}
else
{
detail::throw_cannot_use_with(310, "swap(object_t&)", *this);
detail::throw_cannot_use_with(detail::exception_id::swap_wrong_type, "swap(object_t&)", *this);
}
}
@@ -5064,7 +5073,7 @@ public:
}
else
{
detail::throw_cannot_use_with(310, "swap(string_t&)", *this);
detail::throw_cannot_use_with(detail::exception_id::swap_wrong_type, "swap(string_t&)", *this);
}
}
@@ -5080,7 +5089,7 @@ public:
}
else
{
detail::throw_cannot_use_with(310, "swap(binary_t&)", *this);
detail::throw_cannot_use_with(detail::exception_id::swap_wrong_type, "swap(binary_t&)", *this);
}
}
@@ -5096,7 +5105,7 @@ public:
}
else
{
detail::throw_cannot_use_with(310, "swap(binary_t::container_type&)", *this);
detail::throw_cannot_use_with(detail::exception_id::swap_wrong_type, "swap(binary_t::container_type&)", *this);
}
}
@@ -6558,7 +6567,7 @@ public:
if (JSON_HEDLEY_UNLIKELY(idx > parent.size()))
{
// avoid undefined behavior
JSON_THROW(out_of_range::create(401, detail::concat("array index ", std::to_string(idx), " is out of range"), &parent));
JSON_THROW(out_of_range::create(detail::exception_id::array_index_out_of_range, detail::concat("array index ", std::to_string(idx), " is out of range"), &parent));
}
// default case: insert add offset
@@ -6577,7 +6586,7 @@ public:
case value_t::binary:
case value_t::discarded:
default:
JSON_THROW(out_of_range::create(411, detail::concat("cannot add value: the JSON Patch 'add' target's parent is of type ", parent.type_name(), ", but must be an object or array"), &parent));
JSON_THROW(out_of_range::create(detail::exception_id::patch_add_parent_not_container, detail::concat("cannot add value: the JSON Patch 'add' target's parent is of type ", parent.type_name(), ", but must be an object or array"), &parent));
}
};
@@ -6600,7 +6609,7 @@ public:
}
else
{
JSON_THROW(out_of_range::create(403, detail::concat("key '", last_path, "' not found"), this));
JSON_THROW(out_of_range::create(detail::exception_id::key_not_found, detail::concat("key '", last_path, "' not found"), this));
}
}
else if (parent.is_array())
@@ -6612,7 +6621,7 @@ public:
{
// the parent of a "remove" target must be an object or array
// (see #5396)
JSON_THROW(out_of_range::create(413, detail::concat("cannot remove value: the JSON Patch 'remove' target's parent is of type ", parent.type_name(), ", but must be an object or array"), &parent));
JSON_THROW(out_of_range::create(detail::exception_id::patch_remove_parent_not_container, detail::concat("cannot remove value: the JSON Patch 'remove' target's parent is of type ", parent.type_name(), ", but must be an object or array"), &parent));
}
};
@@ -6643,7 +6652,7 @@ public:
// type check: top level value must be an array
if (JSON_HEDLEY_UNLIKELY(!json_patch.is_array()))
{
JSON_THROW(parse_error::create(104, 0, "JSON patch must be an array of objects", &json_patch));
JSON_THROW(parse_error::create(detail::exception_id::patch_not_an_array, 0, "JSON patch must be an array of objects", &json_patch));
}
// iterate and apply the operations
@@ -6664,14 +6673,14 @@ public:
if (JSON_HEDLEY_UNLIKELY(it == val.m_data.m_value.object->end()))
{
// NOLINTNEXTLINE(performance-inefficient-string-concatenation)
JSON_THROW(parse_error::create(105, 0, detail::concat(error_msg, " must have member '", member, "'"), &val));
JSON_THROW(parse_error::create(detail::exception_id::patch_invalid_operation, 0, detail::concat(error_msg, " must have member '", member, "'"), &val));
}
// check if the result is of type string
if (JSON_HEDLEY_UNLIKELY(string_type && !it->second.is_string()))
{
// NOLINTNEXTLINE(performance-inefficient-string-concatenation)
JSON_THROW(parse_error::create(105, 0, detail::concat(error_msg, " must have string member '", member, "'"), &val));
JSON_THROW(parse_error::create(detail::exception_id::patch_invalid_operation, 0, detail::concat(error_msg, " must have string member '", member, "'"), &val));
}
// no error: return value
@@ -6681,7 +6690,7 @@ public:
// type check: every element of the array must be an object
if (JSON_HEDLEY_UNLIKELY(!val.is_object()))
{
JSON_THROW(parse_error::create(104, 0, "JSON patch must be an array of objects", &val));
JSON_THROW(parse_error::create(detail::exception_id::patch_not_an_array, 0, "JSON patch must be an array of objects", &val));
}
// collect mandatory members
@@ -6717,7 +6726,7 @@ public:
if (JSON_HEDLEY_UNLIKELY(is_proper_prefix(from_ptr, ptr)))
{
JSON_THROW(out_of_range::create(414, detail::concat("cannot move value: 'from' path '", from_path, "' is a proper prefix of 'path' '", path, "'"), &result));
JSON_THROW(out_of_range::create(detail::exception_id::patch_move_into_child, detail::concat("cannot move value: 'from' path '", from_path, "' is a proper prefix of 'path' '", path, "'"), &result));
}
// the "from" location must exist - use at()
@@ -6764,7 +6773,7 @@ public:
// throw an exception if the test fails
if (JSON_HEDLEY_UNLIKELY(!success))
{
JSON_THROW(other_error::create(501, detail::concat("unsuccessful: ", val.dump()), &val));
JSON_THROW(other_error::create(detail::exception_id::patch_test_failed, detail::concat("unsuccessful: ", val.dump()), &val));
}
break;
@@ -6775,7 +6784,7 @@ public:
{
// op must be "add", "remove", "replace", "move", "copy", or
// "test"
JSON_THROW(parse_error::create(105, 0, detail::concat("operation value '", op, "' is invalid"), &val));
JSON_THROW(parse_error::create(detail::exception_id::patch_invalid_operation, 0, detail::concat("operation value '", op, "' is invalid"), &val));
}
}
}
File diff suppressed because it is too large. Load diff
-4
View File
@@ -51,12 +51,8 @@ The provided function `LLVMFuzzerTestOneInput` can be used in different fuzzer
drivers.
*/
#include <cassert>
#include <nlohmann/json.hpp>
#include "fuzzer_common.hpp"
using nlohmann::json;
// value-stable comparison for the round-trip checks below; see the note
// above on why this compares dump()s rather than the json values directly
static bool is_value_stable(const json& lhs, const json& rhs)
-4
View File
@@ -25,13 +25,9 @@ The provided function `LLVMFuzzerTestOneInput` can be used in different fuzzer
drivers.
*/
#include <cassert>
#include <sstream>
#include <nlohmann/json.hpp>
#include "fuzzer_common.hpp"
using nlohmann::json;
namespace
{
// the serialization of the value read from @a input, or the error message
-4
View File
@@ -21,12 +21,8 @@ The provided function `LLVMFuzzerTestOneInput` can be used in different fuzzer
drivers.
*/
#include <cassert>
#include <nlohmann/json.hpp>
#include "fuzzer_common.hpp"
using nlohmann::json;
// see http://llvm.org/docs/LibFuzzer.html
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
{
-4
View File
@@ -21,12 +21,8 @@ The provided function `LLVMFuzzerTestOneInput` can be used in different fuzzer
drivers.
*/
#include <cassert>
#include <nlohmann/json.hpp>
#include "fuzzer_common.hpp"
using nlohmann::json;
// see http://llvm.org/docs/LibFuzzer.html
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
{
-4
View File
@@ -22,12 +22,8 @@ The provided function `LLVMFuzzerTestOneInput` can be used in different fuzzer
drivers.
*/
#include <cassert>
#include <nlohmann/json.hpp>
#include "fuzzer_common.hpp"
using nlohmann::json;
// see http://llvm.org/docs/LibFuzzer.html
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
{
-4
View File
@@ -21,12 +21,8 @@ The provided function `LLVMFuzzerTestOneInput` can be used in different fuzzer
drivers.
*/
#include <cassert>
#include <nlohmann/json.hpp>
#include "fuzzer_common.hpp"
using nlohmann::json;
// see http://llvm.org/docs/LibFuzzer.html
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
{
-4
View File
@@ -30,12 +30,8 @@ The provided function `LLVMFuzzerTestOneInput` can be used in different fuzzer
drivers.
*/
#include <cassert>
#include <nlohmann/json.hpp>
#include "fuzzer_common.hpp"
using nlohmann::json;
// see http://llvm.org/docs/LibFuzzer.html
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
{
+7 -5
View File
@@ -13,6 +13,8 @@
#include <cassert> // assert
#include <nlohmann/json.hpp>
using nlohmann::json; // NOLINT(google-global-names-in-headers): shared by all fuzzer drivers
// the round-trip checks of the drivers are assertions; NDEBUG would compile them away
#ifdef NDEBUG
#error "the fuzzer drivers must be built without NDEBUG"
@@ -20,9 +22,9 @@
// compares dumps rather than values, because NaN != NaN; keep writes strings
// byte for byte, so ill-formed UTF-8 that a binary reader accepts cannot throw
inline bool same_value(const nlohmann::json& lhs, const nlohmann::json& rhs)
inline bool same_value(const json& lhs, const json& rhs)
{
return lhs.dump(-1, ' ', false, nlohmann::json::error_handler_t::keep) == rhs.dump(-1, ' ', false, nlohmann::json::error_handler_t::keep);
return lhs.dump(-1, ' ', false, json::error_handler_t::keep) == rhs.dump(-1, ' ', false, json::error_handler_t::keep);
}
// step 0 of each driver: parse the input without exceptions; a parse error
@@ -30,18 +32,18 @@ inline bool same_value(const nlohmann::json& lhs, const nlohmann::json& rhs)
// out-of-range errors are not parse errors and still throw; then @a threw is
// set and null is returned.
template<typename Parse>
nlohmann::json parse_without_exceptions(Parse parse, bool& threw)
json parse_without_exceptions(Parse parse, bool& threw)
{
threw = false;
try
{
return parse();
}
catch (const nlohmann::json::parse_error&)
catch (const json::parse_error&)
{
assert(false);
}
catch (const nlohmann::json::exception&)
catch (const json::exception&)
{
threw = true;
}
File renamed without changes.
+1 -1
View File
@@ -38,7 +38,7 @@ using nlohmann::json;
#include <vector>
#include "sax_countdown.hpp"
#include "test_sax.hpp"
#include "sax_event_loggers.hpp"
#include "test_utils.hpp"
using utils::SaxCountdown;
+1 -1
View File
@@ -36,7 +36,7 @@ using nlohmann::json;
#include <string>
#include <valarray>
#include "test_sax.hpp"
#include "sax_event_loggers.hpp"
using utils::SaxEventLogger;
using utils::SaxEventLoggerExitAfterKey;