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:
Niels Lohmann
2026-10-02 11:38:09 +02:00
335 changed files with 6103 additions and 1049 deletions
+29 -14
View File
@@ -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))