Merge remote-tracking branch 'origin/develop' into claude/fix-issue-3989-db7e45
Signed-off-by: Niels Lohmann <mail@nlohmann.me> # Conflicts: # docs/mkdocs/docs/api/json_sax/parse_error.md # docs/mkdocs/docs/features/parsing/index.md
This commit is contained in:
335 files changed
+6103
-1049
No files matched your search
@@ -617,7 +617,7 @@ class binary_reader
|
||||
@brief Parses a C-style string from the BSON input.
|
||||
@param[in,out] result A reference to the string variable where the read
|
||||
string is to be stored.
|
||||
@return `true` if the \x00-byte indicating the end of the string was
|
||||
@return `true` if the \\x00-byte indicating the end of the string was
|
||||
encountered before the EOF; false` indicates an unexpected EOF.
|
||||
*/
|
||||
bool get_bson_cstr(string_t& result)
|
||||
@@ -647,7 +647,7 @@ class binary_reader
|
||||
@brief read a C-style string from contiguous input in one step
|
||||
|
||||
@param[in,out] result the string to append to
|
||||
@return whether the string was read; if the input has no \x00-byte, nothing
|
||||
@return whether the string was read; if the input has no \\x00-byte, nothing
|
||||
is read, and @ref get_bson_cstr reports the end of the input
|
||||
*/
|
||||
bool get_bson_cstr_bulk(string_t& result, std::true_type /*bulk*/)
|
||||
@@ -812,13 +812,13 @@ class binary_reader
|
||||
case 0x10: // int32
|
||||
{
|
||||
std::int32_t value{};
|
||||
return get_number<std::int32_t, true>(input_format_t::bson, value) && sax->number_integer(value);
|
||||
return get_number<std::int32_t, true>(input_format_t::bson, value) && sax->number_integer(conditional_static_cast<number_integer_t>(value));
|
||||
}
|
||||
|
||||
case 0x12: // int64
|
||||
{
|
||||
std::int64_t value{};
|
||||
return get_number<std::int64_t, true>(input_format_t::bson, value) && sax->number_integer(value);
|
||||
return get_number<std::int64_t, true>(input_format_t::bson, value) && sax->number_integer(conditional_static_cast<number_integer_t>(value));
|
||||
}
|
||||
|
||||
case 0x11: // uint64
|
||||
@@ -856,7 +856,7 @@ class binary_reader
|
||||
// too small for number_integer_t: pass the nearest floating-point number
|
||||
return sax->number_float(static_cast<number_float_t>(-1) - static_cast<number_float_t>(number), "");
|
||||
}
|
||||
return sax->number_integer(static_cast<number_integer_t>(-1) - static_cast<number_integer_t>(number));
|
||||
return sax->number_integer(conditional_static_cast<number_integer_t>(static_cast<number_integer_t>(-1) - static_cast<number_integer_t>(number)));
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -2269,25 +2269,25 @@ class binary_reader
|
||||
case 0xD0: // int 8
|
||||
{
|
||||
std::int8_t number{};
|
||||
return get_number(input_format_t::msgpack, number) && sax->number_integer(number);
|
||||
return get_number(input_format_t::msgpack, number) && sax->number_integer(conditional_static_cast<number_integer_t>(number));
|
||||
}
|
||||
|
||||
case 0xD1: // int 16
|
||||
{
|
||||
std::int16_t number{};
|
||||
return get_number(input_format_t::msgpack, number) && sax->number_integer(number);
|
||||
return get_number(input_format_t::msgpack, number) && sax->number_integer(conditional_static_cast<number_integer_t>(number));
|
||||
}
|
||||
|
||||
case 0xD2: // int 32
|
||||
{
|
||||
std::int32_t number{};
|
||||
return get_number(input_format_t::msgpack, number) && sax->number_integer(number);
|
||||
return get_number(input_format_t::msgpack, number) && sax->number_integer(conditional_static_cast<number_integer_t>(number));
|
||||
}
|
||||
|
||||
case 0xD3: // int 64
|
||||
{
|
||||
std::int64_t number{};
|
||||
return get_number(input_format_t::msgpack, number) && sax->number_integer(number);
|
||||
return get_number(input_format_t::msgpack, number) && sax->number_integer(conditional_static_cast<number_integer_t>(number));
|
||||
}
|
||||
|
||||
case 0xDC: // array 16
|
||||
@@ -3500,25 +3500,25 @@ class binary_reader
|
||||
case 'i':
|
||||
{
|
||||
std::int8_t number{};
|
||||
return get_number(input_format, number) && sax->number_integer(number);
|
||||
return get_number(input_format, number) && sax->number_integer(conditional_static_cast<number_integer_t>(number));
|
||||
}
|
||||
|
||||
case 'I':
|
||||
{
|
||||
std::int16_t number{};
|
||||
return get_number(input_format, number) && sax->number_integer(number);
|
||||
return get_number(input_format, number) && sax->number_integer(conditional_static_cast<number_integer_t>(number));
|
||||
}
|
||||
|
||||
case 'l':
|
||||
{
|
||||
std::int32_t number{};
|
||||
return get_number(input_format, number) && sax->number_integer(number);
|
||||
return get_number(input_format, number) && sax->number_integer(conditional_static_cast<number_integer_t>(number));
|
||||
}
|
||||
|
||||
case 'L':
|
||||
{
|
||||
std::int64_t number{};
|
||||
return get_number(input_format, number) && sax->number_integer(number);
|
||||
return get_number(input_format, number) && sax->number_integer(conditional_static_cast<number_integer_t>(number));
|
||||
}
|
||||
|
||||
case 'u':
|
||||
@@ -4171,7 +4171,7 @@ class binary_reader
|
||||
// integer -1..-10
|
||||
if (byte <= 0xC1)
|
||||
{
|
||||
return sax->number_integer(-1 - static_cast<number_integer_t>(byte - 0xB8));
|
||||
return sax->number_integer(conditional_static_cast<number_integer_t>(-1 - static_cast<number_integer_t>(byte - 0xB8)));
|
||||
}
|
||||
|
||||
// 0xC2..0xF7: a UTF-8 lead byte begins a string if a continuation
|
||||
@@ -4301,6 +4301,11 @@ class binary_reader
|
||||
if (0xC2 <= byte && byte <= 0xF7)
|
||||
{
|
||||
const auto second = get_bon8();
|
||||
if (second == char_traits<char_type>::eof())
|
||||
{
|
||||
// the input ends inside a character or an integer
|
||||
return unexpect_eof(input_format_t::bon8, "key");
|
||||
}
|
||||
unget_bon8(second);
|
||||
if (is_bon8_continuation(second))
|
||||
{
|
||||
@@ -4517,6 +4522,12 @@ class binary_reader
|
||||
// a lead byte ends the string if no continuation byte follows: it
|
||||
// is then the first byte of an integer
|
||||
const auto second = get_bon8();
|
||||
if (second == char_traits<char_type>::eof())
|
||||
{
|
||||
// the input ends inside a character or an integer: either
|
||||
// way, the message is incomplete
|
||||
return unexpect_eof(input_format_t::bon8, "string");
|
||||
}
|
||||
if (!is_bon8_continuation(second))
|
||||
{
|
||||
unget_bon8(second);
|
||||
@@ -4597,6 +4608,8 @@ class binary_reader
|
||||
template<class T>
|
||||
bool get_to(T& dest, const input_format_t format, const char* context)
|
||||
{
|
||||
// false positive: new_chars_read is read on the next lines
|
||||
// @infer-ignore DEAD_STORE
|
||||
auto new_chars_read = ia.get_elements(&dest);
|
||||
chars_read += new_chars_read;
|
||||
if (JSON_HEDLEY_UNLIKELY(new_chars_read < sizeof(T)))
|
||||
@@ -4853,6 +4866,8 @@ class binary_reader
|
||||
// resize() is required to make size() exactly old_size + wanted;
|
||||
// that is the room get_elements() is allowed to write into
|
||||
JSON_ASSERT(result.size() == old_size + wanted);
|
||||
// false positive: bytes_read is read on the next lines
|
||||
// @infer-ignore DEAD_STORE
|
||||
const std::size_t bytes_read = ia.get_elements(&result[old_size], wanted);
|
||||
chars_read += bytes_read;
|
||||
if (JSON_HEDLEY_UNLIKELY(bytes_read < wanted))
|
||||
|
||||
@@ -744,6 +744,9 @@ struct container_input_adapter_factory< ContainerType,
|
||||
|
||||
static adapter_type create(ContainerType&& container)
|
||||
{
|
||||
// container is forwarded twice on purpose: the resulting begin/end
|
||||
// iterator types must match adapter_type, computed the same way
|
||||
// NOLINTNEXTLINE(bugprone-use-after-move)
|
||||
return input_adapter(begin(std::forward<ContainerType>(container)), end(std::forward<ContainerType>(container)));
|
||||
}
|
||||
};
|
||||
|
||||
@@ -222,9 +222,9 @@ class lexer : public lexer_base<BasicJsonType>
|
||||
/////////////////////
|
||||
|
||||
/*!
|
||||
@brief get codepoint from 4 hex characters following `\u`
|
||||
@brief get codepoint from 4 hex characters following `\\u`
|
||||
|
||||
For input "\u c1 c2 c3 c4" the codepoint is:
|
||||
For input "\\u c1 c2 c3 c4" the codepoint is:
|
||||
(c1 * 0x1000) + (c2 * 0x0100) + (c3 * 0x0010) + c4
|
||||
= (c1 << 12) + (c2 << 8) + (c3 << 4) + (c4 << 0)
|
||||
|
||||
|
||||
@@ -428,14 +428,14 @@ inline bool parse_float_eisel_lemire(const char* first, const char* last, double
|
||||
}
|
||||
|
||||
std::uint64_t w = 0;
|
||||
int digits = 0; // significant digits in w
|
||||
unsigned int digits = 0; // significant digits in w
|
||||
std::int64_t exponent = 0;
|
||||
bool truncated = false;
|
||||
bool in_fraction = false;
|
||||
for (;;)
|
||||
{
|
||||
// eight digits at a time, as long as they fit into w
|
||||
while (w != 0 && digits <= 19 - 8 && last - p >= 8)
|
||||
while (w != 0 && digits <= 19u - 8u && last - p >= 8)
|
||||
{
|
||||
const std::uint64_t v = read_eight_bytes(p);
|
||||
if (!is_eight_digits(v))
|
||||
@@ -443,7 +443,7 @@ inline bool parse_float_eisel_lemire(const char* first, const char* last, double
|
||||
break;
|
||||
}
|
||||
w = (w * 100000000u) + parse_eight_digits(v);
|
||||
digits += 8;
|
||||
digits += 8u;
|
||||
exponent -= in_fraction ? 8 : 0;
|
||||
p += 8;
|
||||
}
|
||||
@@ -459,7 +459,7 @@ inline bool parse_float_eisel_lemire(const char* first, const char* last, double
|
||||
// leading zeros are not significant, but scale a fraction
|
||||
exponent -= in_fraction ? 1 : 0;
|
||||
}
|
||||
else if (digits < 19)
|
||||
else if (digits < 19u)
|
||||
{
|
||||
w = (w * 10u) + static_cast<std::uint64_t>(c - '0');
|
||||
++digits;
|
||||
|
||||
@@ -54,8 +54,9 @@ using parser_callback_t =
|
||||
/*!
|
||||
@brief syntax analysis
|
||||
|
||||
This class implements an iterative parser that keeps the open containers on
|
||||
an explicit stack and reports what it reads as SAX events.
|
||||
This class implements a parser for JSON text. Nested arrays and objects are tracked with an explicit
|
||||
stack instead of recursion, so deeply nested input does not exhaust the call stack, and what is read
|
||||
is reported as SAX events.
|
||||
*/
|
||||
template<typename BasicJsonType, typename InputAdapterType>
|
||||
class parser
|
||||
|
||||
Reference in new issue
Block a user