mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-06-15 11:21:32 +02:00
fuzz: Accept options in FUZZ_TARGET macro
* This allows to reduce the number of total macros. * Also, adding a new option no longer requires doubling the number of macros in the worst case.
This commit is contained in:
parent
357e3f6aa4
commit
fa36ad8b09
@ -54,20 +54,25 @@ const std::function<std::vector<const char*>()> G_TEST_COMMAND_LINE_ARGUMENTS =
|
|||||||
return g_args;
|
return g_args;
|
||||||
};
|
};
|
||||||
|
|
||||||
std::map<std::string_view, std::tuple<TypeTestOneInput, TypeInitialize, TypeHidden>>& FuzzTargets()
|
struct FuzzTarget {
|
||||||
|
const TypeTestOneInput test_one_input;
|
||||||
|
const FuzzTargetOptions opts;
|
||||||
|
};
|
||||||
|
|
||||||
|
auto& FuzzTargets()
|
||||||
{
|
{
|
||||||
static std::map<std::string_view, std::tuple<TypeTestOneInput, TypeInitialize, TypeHidden>> g_fuzz_targets;
|
static std::map<std::string_view, FuzzTarget> g_fuzz_targets;
|
||||||
return g_fuzz_targets;
|
return g_fuzz_targets;
|
||||||
}
|
}
|
||||||
|
|
||||||
void FuzzFrameworkRegisterTarget(std::string_view name, TypeTestOneInput target, TypeInitialize init, TypeHidden hidden)
|
void FuzzFrameworkRegisterTarget(std::string_view name, TypeTestOneInput target, FuzzTargetOptions opts)
|
||||||
{
|
{
|
||||||
const auto it_ins = FuzzTargets().try_emplace(name, std::move(target), std::move(init), hidden);
|
const auto it_ins{FuzzTargets().try_emplace(name, FuzzTarget /* temporary can be dropped in C++20 */ {std::move(target), std::move(opts)})};
|
||||||
Assert(it_ins.second);
|
Assert(it_ins.second);
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::string_view g_fuzz_target;
|
static std::string_view g_fuzz_target;
|
||||||
static TypeTestOneInput* g_test_one_input{nullptr};
|
static const TypeTestOneInput* g_test_one_input{nullptr};
|
||||||
|
|
||||||
void initialize()
|
void initialize()
|
||||||
{
|
{
|
||||||
@ -84,22 +89,22 @@ void initialize()
|
|||||||
|
|
||||||
bool should_exit{false};
|
bool should_exit{false};
|
||||||
if (std::getenv("PRINT_ALL_FUZZ_TARGETS_AND_ABORT")) {
|
if (std::getenv("PRINT_ALL_FUZZ_TARGETS_AND_ABORT")) {
|
||||||
for (const auto& t : FuzzTargets()) {
|
for (const auto& [name, t] : FuzzTargets()) {
|
||||||
if (std::get<2>(t.second)) continue;
|
if (t.opts.hidden) continue;
|
||||||
std::cout << t.first << std::endl;
|
std::cout << name << std::endl;
|
||||||
}
|
}
|
||||||
should_exit = true;
|
should_exit = true;
|
||||||
}
|
}
|
||||||
if (const char* out_path = std::getenv("WRITE_ALL_FUZZ_TARGETS_AND_ABORT")) {
|
if (const char* out_path = std::getenv("WRITE_ALL_FUZZ_TARGETS_AND_ABORT")) {
|
||||||
std::cout << "Writing all fuzz target names to '" << out_path << "'." << std::endl;
|
std::cout << "Writing all fuzz target names to '" << out_path << "'." << std::endl;
|
||||||
std::ofstream out_stream{out_path, std::ios::binary};
|
std::ofstream out_stream{out_path, std::ios::binary};
|
||||||
for (const auto& t : FuzzTargets()) {
|
for (const auto& [name, t] : FuzzTargets()) {
|
||||||
if (std::get<2>(t.second)) continue;
|
if (t.opts.hidden) continue;
|
||||||
out_stream << t.first << std::endl;
|
out_stream << name << std::endl;
|
||||||
}
|
}
|
||||||
should_exit= true;
|
should_exit = true;
|
||||||
}
|
}
|
||||||
if (should_exit){
|
if (should_exit) {
|
||||||
std::exit(EXIT_SUCCESS);
|
std::exit(EXIT_SUCCESS);
|
||||||
}
|
}
|
||||||
if (const auto* env_fuzz{std::getenv("FUZZ")}) {
|
if (const auto* env_fuzz{std::getenv("FUZZ")}) {
|
||||||
@ -117,8 +122,8 @@ void initialize()
|
|||||||
std::exit(EXIT_FAILURE);
|
std::exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
Assert(!g_test_one_input);
|
Assert(!g_test_one_input);
|
||||||
g_test_one_input = &std::get<0>(it->second);
|
g_test_one_input = &it->second.test_one_input;
|
||||||
std::get<1>(it->second)();
|
it->second.opts.init();
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(PROVIDE_FUZZ_MAIN_FUNCTION)
|
#if defined(PROVIDE_FUZZ_MAIN_FUNCTION)
|
||||||
|
@ -21,25 +21,28 @@
|
|||||||
using FuzzBufferType = Span<const uint8_t>;
|
using FuzzBufferType = Span<const uint8_t>;
|
||||||
|
|
||||||
using TypeTestOneInput = std::function<void(FuzzBufferType)>;
|
using TypeTestOneInput = std::function<void(FuzzBufferType)>;
|
||||||
using TypeInitialize = std::function<void()>;
|
struct FuzzTargetOptions {
|
||||||
using TypeHidden = bool;
|
std::function<void()> init{[] {}};
|
||||||
|
bool hidden{false};
|
||||||
|
};
|
||||||
|
|
||||||
void FuzzFrameworkRegisterTarget(std::string_view name, TypeTestOneInput target, TypeInitialize init, TypeHidden hidden);
|
void FuzzFrameworkRegisterTarget(std::string_view name, TypeTestOneInput target, FuzzTargetOptions opts);
|
||||||
|
|
||||||
inline void FuzzFrameworkEmptyInitFun() {}
|
#if defined(__clang__)
|
||||||
|
#define FUZZ_TARGET(...) _Pragma("clang diagnostic push") _Pragma("clang diagnostic ignored \"-Wgnu-zero-variadic-macro-arguments\"") DETAIL_FUZZ(__VA_ARGS__) _Pragma("clang diagnostic pop")
|
||||||
#define FUZZ_TARGET(name) \
|
#else
|
||||||
FUZZ_TARGET_INIT(name, FuzzFrameworkEmptyInitFun)
|
#define FUZZ_TARGET(...) DETAIL_FUZZ(__VA_ARGS__)
|
||||||
|
#endif
|
||||||
|
|
||||||
#define FUZZ_TARGET_INIT(name, init_fun) \
|
#define FUZZ_TARGET_INIT(name, init_fun) \
|
||||||
FUZZ_TARGET_INIT_HIDDEN(name, init_fun, false)
|
FUZZ_TARGET(name, .init = init_fun)
|
||||||
|
|
||||||
#define FUZZ_TARGET_INIT_HIDDEN(name, init_fun, hidden) \
|
#define DETAIL_FUZZ(name, ...) \
|
||||||
void name##_fuzz_target(FuzzBufferType); \
|
void name##_fuzz_target(FuzzBufferType); \
|
||||||
struct name##_Before_Main { \
|
struct name##_Before_Main { \
|
||||||
name##_Before_Main() \
|
name##_Before_Main() \
|
||||||
{ \
|
{ \
|
||||||
FuzzFrameworkRegisterTarget(#name, name##_fuzz_target, init_fun, hidden); \
|
FuzzFrameworkRegisterTarget(#name, name##_fuzz_target, {__VA_ARGS__}); \
|
||||||
} \
|
} \
|
||||||
} const static g_##name##_before_main; \
|
} const static g_##name##_before_main; \
|
||||||
void name##_fuzz_target(FuzzBufferType buffer)
|
void name##_fuzz_target(FuzzBufferType buffer)
|
||||||
|
@ -186,7 +186,7 @@ void Test(const std::string& str)
|
|||||||
|
|
||||||
void test_init() {}
|
void test_init() {}
|
||||||
|
|
||||||
FUZZ_TARGET_INIT_HIDDEN(script_assets_test_minimizer, test_init, /*hidden=*/true)
|
FUZZ_TARGET(script_assets_test_minimizer, .init = test_init, .hidden = true)
|
||||||
{
|
{
|
||||||
if (buffer.size() < 2 || buffer.back() != '\n' || buffer[buffer.size() - 2] != ',') return;
|
if (buffer.size() < 2 || buffer.back() != '\n' || buffer[buffer.size() - 2] != ',') return;
|
||||||
const std::string str((const char*)buffer.data(), buffer.size() - 2);
|
const std::string str((const char*)buffer.data(), buffer.size() - 2);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user