mirror of
https://github.com/nlohmann/json.git
synced 2026-10-05 06:00:29 +00:00
Run the CBOR, MessagePack, BSON and BON8 round-trip invariants in CI
tests/src/round_trip_corpus.hpp exists so that the byte-stability invariant the fuzzer drivers check also runs on a fixed corpus in CI, instead of only at OSS-Fuzz. So far only the UBJSON and BJData drivers had a matching unit test; the CBOR, MessagePack, BSON and BON8 drivers assert the same invariant (assert(to_X(j2) == vec)) but nothing ran it outside OSS-Fuzz. Add "<FORMAT> round-trip invariants" test cases to unit-cbor.cpp, unit-msgpack.cpp, unit-bson.cpp and unit-bon8.cpp, modeled on the UBJSON case: seed j1 from the corpus (skipping values that do not survive the format's own round trip, as the fuzzer drivers only ever see values from_X() actually produced), then require from_X(to_X(j1)) not to throw and check to_X(j2) == to_X(j1). BSON only serializes objects, so non-object corpus values are skipped. Update the comments in round_trip_corpus.hpp and tests/fuzzing.md to name all six formats. The stream-versus-contiguous check in the BON8 driver is left out, as #5601 reworks it. A local probe confirms no violations on the current corpus (CBOR 3849 checked, MessagePack 3909, BSON 2958, BON8 3841 - matching the counts already recorded for this probe in the issue). Closes #5714 item 1. Signed-off-by: Niels Lohmann <mail@nlohmann.me>
This commit is contained in:
@@ -17,6 +17,7 @@ using nlohmann::json;
|
||||
#include <sstream>
|
||||
#include <vector>
|
||||
#include "make_test_data_available.hpp"
|
||||
#include "round_trip_corpus.hpp"
|
||||
#include "test_utils.hpp"
|
||||
#include "sax_countdown.hpp"
|
||||
using utils::SaxCountdown;
|
||||
@@ -1613,6 +1614,44 @@ TEST_CASE("Parse BSON directly from a file using iterator and sentinel")
|
||||
CHECK(parsed == expected);
|
||||
}
|
||||
|
||||
TEST_CASE("BSON round-trip invariants")
|
||||
{
|
||||
// This checks what the parse_bson_fuzzer driver checks (see
|
||||
// tests/src/fuzzer-parse_bson.cpp), so that a regression shows up in CI
|
||||
// rather than as an OSS-Fuzz report: anything from_bson() returns (j1)
|
||||
// can be serialized, parsed back (j2), and serialized again to reproduce
|
||||
// the exact bytes. BSON only serializes objects, so non-object corpus
|
||||
// values are skipped.
|
||||
for (const auto& j0 : utils::round_trip_corpus::values())
|
||||
{
|
||||
if (!j0.is_object())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
json j1;
|
||||
try
|
||||
{
|
||||
// turn the corpus value into a value as from_bson() returns it
|
||||
j1 = json::from_bson(json::to_bson(j0));
|
||||
}
|
||||
catch (const json::exception&)
|
||||
{
|
||||
// the fuzzer driver only ever sees values from_bson() actually
|
||||
// produced, so skip corpus values that do not survive the
|
||||
// round trip here, too
|
||||
continue;
|
||||
}
|
||||
|
||||
INFO("j1 = " << j1.dump());
|
||||
const std::vector<std::uint8_t> vec = json::to_bson(j1);
|
||||
json j2;
|
||||
// anything the library writes must be parsable by the library
|
||||
REQUIRE_NOTHROW(j2 = json::from_bson(vec));
|
||||
CHECK(json::to_bson(j2) == vec);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("BSON roundtrips" * doctest::skip())
|
||||
{
|
||||
SECTION("reference files")
|
||||
|
||||
Reference in New Issue
Block a user