aboutsummaryrefslogtreecommitdiff
path: root/src/test/fuzz/fuzz.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/test/fuzz/fuzz.cpp')
-rw-r--r--src/test/fuzz/fuzz.cpp38
1 files changed, 33 insertions, 5 deletions
diff --git a/src/test/fuzz/fuzz.cpp b/src/test/fuzz/fuzz.cpp
index 753cfffdcb..fd87667755 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,36 @@
const std::function<void(const std::string&)> G_TEST_LOG_FUN{};
+std::map<std::string_view, std::tuple<TypeTestOneInput, TypeInitialize>>& FuzzTargets()
+{
+ static std::map<std::string_view, std::tuple<TypeTestOneInput, TypeInitialize>> g_fuzz_targets;
+ return g_fuzz_targets;
+}
+
+void FuzzFrameworkRegisterTarget(std::string_view name, TypeTestOneInput target, TypeInitialize init)
+{
+ const auto it_ins = FuzzTargets().try_emplace(name, std::move(target), std::move(init));
+ 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()) {
+ 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,14 +55,10 @@ 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)
{
+ static const auto& test_one_input = *Assert(g_test_one_input);
const std::vector<uint8_t> input(data, data + size);
test_one_input(input);
return 0;
@@ -48,6 +75,7 @@ extern "C" int LLVMFuzzerInitialize(int* argc, char*** argv)
__attribute__((weak)) 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.