diff options
Diffstat (limited to 'src/test/fuzz/fuzz.cpp')
-rw-r--r-- | src/test/fuzz/fuzz.cpp | 44 |
1 files changed, 36 insertions, 8 deletions
diff --git a/src/test/fuzz/fuzz.cpp b/src/test/fuzz/fuzz.cpp index 753cfffdcb..edb270d437 100644 --- a/src/test/fuzz/fuzz.cpp +++ b/src/test/fuzz/fuzz.cpp @@ -5,6 +5,7 @@ #include <test/fuzz/fuzz.h> #include <test/util/setup_common.h> +#include <util/check.h> #include <cstdint> #include <unistd.h> @@ -12,6 +13,37 @@ const std::function<void(const std::string&)> G_TEST_LOG_FUN{}; +std::map<std::string_view, std::tuple<TypeTestOneInput, TypeInitialize, TypeHidden>>& FuzzTargets() +{ + static std::map<std::string_view, std::tuple<TypeTestOneInput, TypeInitialize, TypeHidden>> g_fuzz_targets; + return g_fuzz_targets; +} + +void FuzzFrameworkRegisterTarget(std::string_view name, TypeTestOneInput target, TypeInitialize init, TypeHidden hidden) +{ + const auto it_ins = FuzzTargets().try_emplace(name, std::move(target), std::move(init), hidden); + Assert(it_ins.second); +} + +static TypeTestOneInput* g_test_one_input{nullptr}; + +void initialize() +{ + if (std::getenv("PRINT_ALL_FUZZ_TARGETS_AND_ABORT")) { + for (const auto& t : FuzzTargets()) { + if (std::get<2>(t.second)) continue; + std::cout << t.first << std::endl; + } + Assert(false); + } + std::string_view fuzz_target{Assert(std::getenv("FUZZ"))}; + const auto it = FuzzTargets().find(fuzz_target); + Assert(it != FuzzTargets().end()); + Assert(!g_test_one_input); + g_test_one_input = &std::get<0>(it->second); + std::get<1>(it->second)(); +} + #if defined(PROVIDE_MAIN_FUNCTION) static bool read_stdin(std::vector<uint8_t>& data) { @@ -24,16 +56,11 @@ static bool read_stdin(std::vector<uint8_t>& data) } #endif -// Default initialization: Override using a non-weak initialize(). -__attribute__((weak)) void initialize() -{ -} - // This function is used by libFuzzer extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { - const std::vector<uint8_t> input(data, data + size); - test_one_input(input); + static const auto& test_one_input = *Assert(g_test_one_input); + test_one_input({data, size}); return 0; } @@ -45,9 +72,10 @@ extern "C" int LLVMFuzzerInitialize(int* argc, char*** argv) } #if defined(PROVIDE_MAIN_FUNCTION) -__attribute__((weak)) int main(int argc, char** argv) +int main(int argc, char** argv) { initialize(); + static const auto& test_one_input = *Assert(g_test_one_input); #ifdef __AFL_INIT // Enable AFL deferred forkserver mode. Requires compilation using // afl-clang-fast++. See fuzzing.md for details. |