// Copyright (c) 2019, Paul Dreik // License: see LICENSE.rst in the fmt root directory #include #include #include #include #include #include #include "fuzzer_common.h" template void invoke_inner(fmt::string_view formatstring, const Item item) { const std::chrono::duration value(item); try { #if FMT_FUZZ_FORMAT_TO_STRING std::string message = fmt::format(formatstring, value); #else fmt::memory_buffer buf; fmt::format_to(buf, formatstring, value); #endif } catch (std::exception& /*e*/) { } } // Item is the underlying type for duration (int, long etc) template void invoke_outer(const uint8_t* Data, size_t Size, const int scaling) { // always use a fixed location of the data using fmt_fuzzer::Nfixed; constexpr auto N = sizeof(Item); static_assert(N <= Nfixed, "fixed size is too small"); if (Size <= Nfixed + 1) { return; } const Item item = fmt_fuzzer::assignFromBuf(Data); // fast forward Data += Nfixed; Size -= Nfixed; // Data is already allocated separately in libFuzzer so reading past // the end will most likely be detected anyway const auto formatstring = fmt::string_view(fmt_fuzzer::as_chars(Data), Size); // doit_impl(buf.data(),item); // doit_impl(buf.data(),item); switch (scaling) { case 1: invoke_inner(formatstring, item); break; case 2: invoke_inner(formatstring, item); break; case 3: invoke_inner(formatstring, item); break; case 4: invoke_inner(formatstring, item); break; case 5: invoke_inner(formatstring, item); break; case 6: invoke_inner(formatstring, item); break; case 7: invoke_inner(formatstring, item); break; case 8: invoke_inner(formatstring, item); break; case 9: invoke_inner(formatstring, item); break; case 10: invoke_inner(formatstring, item); break; case 11: invoke_inner(formatstring, item); break; case 12: invoke_inner(formatstring, item); break; case 13: invoke_inner(formatstring, item); break; case 14: invoke_inner(formatstring, item); break; case 15: invoke_inner(formatstring, item); } // doit_impl(buf.data(),item); // doit_impl(buf.data(),item); } extern "C" int LLVMFuzzerTestOneInput(const uint8_t* Data, size_t Size) { if (Size <= 4) { return 0; } const auto representation = Data[0]; const auto scaling = Data[1]; Data += 2; Size -= 2; switch (representation) { case 1: invoke_outer(Data, Size, scaling); break; case 2: invoke_outer(Data, Size, scaling); break; case 3: invoke_outer(Data, Size, scaling); break; case 4: invoke_outer(Data, Size, scaling); break; case 5: invoke_outer(Data, Size, scaling); break; case 6: invoke_outer(Data, Size, scaling); break; case 7: invoke_outer(Data, Size, scaling); break; case 8: invoke_outer(Data, Size, scaling); break; case 9: invoke_outer(Data, Size, scaling); break; case 10: invoke_outer(Data, Size, scaling); break; case 11: invoke_outer(Data, Size, scaling); break; case 12: invoke_outer(Data, Size, scaling); break; default: break; } return 0; }