From b5aaede7b1cb58b51dedd93abf5fe5e121a54002 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Sat, 28 Oct 2017 15:09:11 +0200 Subject: [PATCH] Add a helper for running fuzz function with a single input This is useful when not using libFuzzer (e.g. because the compiler is gcc or MSVC and not clang) as it allows to debug the problems found by libFuzzer with the reproducers generated by it. --- tests/fuzz/runner.cpp | 65 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 tests/fuzz/runner.cpp diff --git a/tests/fuzz/runner.cpp b/tests/fuzz/runner.cpp new file mode 100644 index 0000000000..240ed72dd7 --- /dev/null +++ b/tests/fuzz/runner.cpp @@ -0,0 +1,65 @@ +/////////////////////////////////////////////////////////////////////////////// +// Name: tests/fuzz/runner.cpp +// Purpose: Main function for running fuzzers with a single input file +// Author: Vadim Zeitlin +// Created: 2017-10-28 +// Copyright: (c) 2017 Vadim Zeitlin +/////////////////////////////////////////////////////////////////////////////// + +// Normally fuzzers are run by libFuzzer, which executes the entry function +// LLVMFuzzerTestOneInput() with many different inputs, but it can be useful to +// run them with just a single input to check a particular problem found during +// fuzzing. To do this, link the fuzzer code with this file and run it with the +// file name containing the test data. E.g. an example use: +// +// $ g++ -g -fsanitize=undefined -c tests/fuzz/{zip,runner}.cpp \ +// `wx-config --cxxflags --libs base` +// $ ./a.out testcase-found-by-libfuzzer + +#include "wx/buffer.h" +#include "wx/crt.h" +#include "wx/ffile.h" +#include "wx/init.h" + +// The fuzzer entry function. +extern "C" int LLVMFuzzerTestOneInput(const wxUint8 *data, size_t size); + +int main(int argc, char** argv) +{ + wxInitializer init(argc, argv); + if ( !init.IsOk() ) + { + wxPrintf("Initializing wxWidgets failed.\n"); + return 1; + } + + if ( argc != 2 ) + { + wxPrintf("Usage: %s \n", argv[0]); + return 2; + } + + wxFFile file(argv[1], "rb"); + if ( !file.IsOpened() ) + { + wxPrintf("Failed to open the input file \"%s\".\n", argv[1]); + return 3; + } + + const wxFileOffset ofs = file.Length(); + if ( ofs < 0 ) + { + wxPrintf("Failed to get the input file \"%s\" size.\n", argv[1]); + return 3; + } + + const size_t len = ofs; + wxMemoryBuffer buf(len); + if ( file.Read(buf.GetData(), len) != len ) + { + wxPrintf("Failed to read from the input file \"%s\".\n", argv[1]); + return 3; + } + + return LLVMFuzzerTestOneInput(static_cast(buf.GetData()), len); +}