to_bson() silently emits corrupt documents when a length exceeds INT32_MAX (#5314)

This commit is contained in:
Luke Banicevic
2026-07-28 09:08:57 +00:00
committed by GitHub
parent 227c5cdfb1
commit 2e23687092
5 changed files with 88 additions and 8 deletions
+31
View File
@@ -11,12 +11,35 @@
#include <nlohmann/json.hpp>
using nlohmann::json;
#include <cstdint>
#include <fstream>
#include <limits>
#include <sstream>
#include <vector>
#include "make_test_data_available.hpp"
#include "test_utils.hpp"
namespace
{
// a binary container that reports a size beyond INT32_MAX without allocating
// that much memory, so the BSON length overflow can be tested cheaply
class huge_binary_t : public std::vector<std::uint8_t>
{
public:
using std::vector<std::uint8_t>::vector;
size_type size() const noexcept // NOLINT(readability-convert-member-functions-to-static)
{
// one byte more than the BSON length field can represent
return static_cast<size_type>((std::numeric_limits<std::int32_t>::max)()) + 1;
}
};
using huge_binary_json = nlohmann::basic_json <
std::map, std::vector, std::string, bool, std::int64_t, std::uint64_t,
double, std::allocator, nlohmann::adl_serializer, huge_binary_t, void >;
} // namespace
TEST_CASE("BSON")
{
SECTION("individual values not supported")
@@ -80,6 +103,14 @@ TEST_CASE("BSON")
#endif
}
SECTION("lengths exceeding INT32_MAX cannot be serialized to BSON")
{
huge_binary_json j;
j["b"] = huge_binary_json::binary(huge_binary_t{});
CHECK_THROWS_WITH_AS(huge_binary_json::to_bson(j), "[json.exception.out_of_range.412] BSON length 2147483661 exceeds maximum of 2147483647", huge_binary_json::out_of_range&);
}
SECTION("string length must be at least 1")
{
// from https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=11175