Index: lib/fuzzer/FuzzerExtFunctions.def =================================================================== --- lib/fuzzer/FuzzerExtFunctions.def +++ lib/fuzzer/FuzzerExtFunctions.def @@ -18,6 +18,9 @@ EXT_FUNC(LLVMFuzzerCustomMutator, size_t, (uint8_t *Data, size_t Size, size_t MaxSize, unsigned int Seed), false); +EXT_FUNC(LLVMFuzzerCustomOutput, void, + (const uint8_t * Data, size_t Size), + false); EXT_FUNC(LLVMFuzzerCustomCrossOver, size_t, (const uint8_t *Data1, size_t Size1, const uint8_t *Data2, size_t Size2, Index: lib/fuzzer/FuzzerInterface.h =================================================================== --- lib/fuzzer/FuzzerInterface.h +++ lib/fuzzer/FuzzerInterface.h @@ -63,6 +63,13 @@ const uint8_t *Data2, size_t Size2, uint8_t *Out, size_t MaxOutSize, unsigned int Seed); + +// Optional user-provided custom output function. +// Takes the found input data and prints it in whatever formatting +// best suits the testcase. +FUZZER_INTERFACE_VISIBILITY void +LLVMFuzzerCustomOutput(const uint8_t *Data, size_t Size); + // Experimental, may go away in future. // libFuzzer-provided function to be used inside LLVMFuzzerCustomMutator. // Mutates raw data in [Data, Data+Size) inplace. Index: lib/fuzzer/FuzzerLoop.cpp =================================================================== --- lib/fuzzer/FuzzerLoop.cpp +++ lib/fuzzer/FuzzerLoop.cpp @@ -185,6 +185,9 @@ } WriteUnitToFileWithPrefix({CurrentUnitData, CurrentUnitData + UnitSize}, Prefix); + if (EF->LLVMFuzzerCustomOutput) { + EF->LLVMFuzzerCustomOutput(CurrentUnitData, CurrentUnitSize); + } } NO_SANITIZE_MEMORY