Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 14 additions & 4 deletions include/nlohmann/detail/input/binary_reader.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,10 @@ class binary_reader
{
const std::size_t document_start = chars_read;
std::int32_t document_size{};
get_number<std::int32_t, true>(input_format_t::bson, document_size);
if (!get_number<std::int32_t, true>(input_format_t::bson, document_size))
{
return false;
}

if (JSON_HEDLEY_UNLIKELY(!sax->start_object(detail::unknown_size())))
{
Expand Down Expand Up @@ -287,7 +290,10 @@ class binary_reader

// All BSON binary values have a subtype
std::uint8_t subtype{};
get_number<std::uint8_t>(input_format_t::bson, subtype);
if (JSON_HEDLEY_UNLIKELY(!get_number<std::uint8_t>(input_format_t::bson, subtype)))
{
return false;
}
result.set_subtype(subtype);

return get_binary(input_format_t::bson, len, result);
Expand Down Expand Up @@ -340,7 +346,8 @@ class binary_reader

case 0x08: // boolean
{
return sax->boolean(get() != 0);
std::uint8_t value{};
return get_number<std::uint8_t>(input_format_t::bson, value) && sax->boolean(value != 0);
}

case 0x0A: // null
Expand Down Expand Up @@ -431,7 +438,10 @@ class binary_reader
{
const std::size_t document_start = chars_read;
std::int32_t document_size{};
get_number<std::int32_t, true>(input_format_t::bson, document_size);
if (!get_number<std::int32_t, true>(input_format_t::bson, document_size))
{
return false;
}

if (JSON_HEDLEY_UNLIKELY(!sax->start_array(detail::unknown_size())))
{
Expand Down
18 changes: 14 additions & 4 deletions single_include/nlohmann/json.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -10746,7 +10746,10 @@ class binary_reader
{
const std::size_t document_start = chars_read;
std::int32_t document_size{};
get_number<std::int32_t, true>(input_format_t::bson, document_size);
if (!get_number<std::int32_t, true>(input_format_t::bson, document_size))
{
return false;
}

if (JSON_HEDLEY_UNLIKELY(!sax->start_object(detail::unknown_size())))
{
Expand Down Expand Up @@ -10836,7 +10839,10 @@ class binary_reader

// All BSON binary values have a subtype
std::uint8_t subtype{};
get_number<std::uint8_t>(input_format_t::bson, subtype);
if (JSON_HEDLEY_UNLIKELY(!get_number<std::uint8_t>(input_format_t::bson, subtype)))
{
return false;
}
result.set_subtype(subtype);

return get_binary(input_format_t::bson, len, result);
Expand Down Expand Up @@ -10889,7 +10895,8 @@ class binary_reader

case 0x08: // boolean
{
return sax->boolean(get() != 0);
std::uint8_t value{};
return get_number<std::uint8_t>(input_format_t::bson, value) && sax->boolean(value != 0);
}

case 0x0A: // null
Expand Down Expand Up @@ -10980,7 +10987,10 @@ class binary_reader
{
const std::size_t document_start = chars_read;
std::int32_t document_size{};
get_number<std::int32_t, true>(input_format_t::bson, document_size);
if (!get_number<std::int32_t, true>(input_format_t::bson, document_size))
{
return false;
}

if (JSON_HEDLEY_UNLIKELY(!sax->start_array(detail::unknown_size())))
{
Expand Down
35 changes: 35 additions & 0 deletions tests/src/unit-bson.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -825,6 +825,41 @@ TEST_CASE("Incomplete BSON Input")
CHECK(!json::sax_parse(incomplete_bson, &scp, json::input_format_t::bson));
}

SECTION("Incomplete BSON Input 5")
{
std::vector<std::uint8_t> const incomplete_bson =
{
0x09, 0x00, 0x00, 0x00, // size (little endian)
0x08, // entry: boolean
'b', '\x00' // key, unexpected EOF before the value
};

json _;
CHECK_THROWS_WITH_AS(_ = json::from_bson(incomplete_bson), "[json.exception.parse_error.110] parse error at byte 8: syntax error while parsing BSON number: unexpected end of input", json::parse_error&);
CHECK(json::from_bson(incomplete_bson, true, false).is_discarded());

SaxCountdown scp(0);
CHECK(!json::sax_parse(incomplete_bson, &scp, json::input_format_t::bson));
}

SECTION("Incomplete BSON Input 6")
{
std::vector<std::uint8_t> const incomplete_bson =
{
0x0F, 0x00, 0x00, 0x00, // size (little endian)
0x05, // entry: binary
'b', '\x00', // key
0x00, 0x00, 0x00, 0x00 // length, unexpected EOF before the subtype
};

json _;
CHECK_THROWS_WITH_AS(_ = json::from_bson(incomplete_bson), "[json.exception.parse_error.110] parse error at byte 12: syntax error while parsing BSON number: unexpected end of input", json::parse_error&);
CHECK(json::from_bson(incomplete_bson, true, false).is_discarded());

SaxCountdown scp(0);
CHECK(!json::sax_parse(incomplete_bson, &scp, json::input_format_t::bson));
}

SECTION("Improve coverage")
{
SECTION("key")
Expand Down
Loading