json/tests/fuzz/src/fuzzer-parse_cbor.cpp

80 lines
2.1 KiB
C++
Raw Normal View History

// __ _____ _____ _____
// __| | __| | | | JSON for Modern C++ (supporting code)
2022-08-01 00:19:06 +03:00
// | | |__ | | | | | | version 3.11.0
// |_____|_____|_____|_|___| https://github.com/nlohmann/json
//
// SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
// SPDX-License-Identifier: MIT
2016-12-22 14:08:36 +03:00
/*
2016-12-22 14:08:36 +03:00
This file implements a parser test suitable for fuzz testing. Given a byte
array data, it performs the following steps:
- j1 = from_cbor(data)
- vec = to_cbor(j1)
- j2 = from_cbor(vec)
- assert(j1 == j2)
The provided function `LLVMFuzzerTestOneInput` can be used in different fuzzer
drivers.
*/
#include <nlohmann/json.hpp>
2016-12-22 14:08:36 +03:00
using json = nlohmann::json;
2022-08-01 15:47:13 +03:00
#ifdef __AFL_LEAK_CHECK
extern "C" void _exit(int);
#else
#define __AFL_LEAK_CHECK() do {} while(false) // NOLINT(bugprone-reserved-identifier,cert-dcl37-c,cert-dcl51-cpp)
#endif
2016-12-22 14:08:36 +03:00
// see http://llvm.org/docs/LibFuzzer.html
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
{
try
{
// step 1: parse input
std::vector<uint8_t> vec1(data, data + size);
json j1 = json::from_cbor(vec1);
2022-08-01 15:47:13 +03:00
// parse errors must raise an exception and not silently result in discarded values
assert(!j1.is_discarded());
2016-12-22 14:08:36 +03:00
try
{
// step 2: round trip
std::vector<uint8_t> vec2 = json::to_cbor(j1);
// parse serialization
json j2 = json::from_cbor(vec2);
// serializations must match
assert(json::to_cbor(j2) == vec2);
2016-12-22 14:08:36 +03:00
}
catch (const json::parse_error&)
2016-12-22 14:08:36 +03:00
{
// parsing a CBOR serialization must not fail
2022-08-01 15:47:13 +03:00
__builtin_trap();
2016-12-22 14:08:36 +03:00
}
}
catch (const json::parse_error&)
2016-12-22 14:08:36 +03:00
{
// parse errors are ok, because input may be random bytes
}
catch (const json::type_error&)
2016-12-22 14:08:36 +03:00
{
// type errors can occur during parsing, too
2016-12-22 14:08:36 +03:00
}
catch (const json::out_of_range&)
{
// out of range errors can occur during parsing, too
}
2016-12-22 14:08:36 +03:00
2022-08-01 15:47:13 +03:00
// do a leak check if fuzzing with AFL++ and LSAN
__AFL_LEAK_CHECK();
2016-12-22 14:08:36 +03:00
// return 0 - non-zero return values are reserved for future use
return 0;
}