diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 18:45:59 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 18:45:59 +0000 |
commit | 19fcec84d8d7d21e796c7624e521b60d28ee21ed (patch) | |
tree | 42d26aa27d1e3f7c0b8bd3fd14e7d7082f5008dc /src/fmt/test/fuzzing/two_args.cpp | |
parent | Initial commit. (diff) | |
download | ceph-upstream/16.2.11+ds.tar.xz ceph-upstream/16.2.11+ds.zip |
Adding upstream version 16.2.11+ds.upstream/16.2.11+dsupstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/fmt/test/fuzzing/two_args.cpp')
-rw-r--r-- | src/fmt/test/fuzzing/two_args.cpp | 112 |
1 files changed, 112 insertions, 0 deletions
diff --git a/src/fmt/test/fuzzing/two_args.cpp b/src/fmt/test/fuzzing/two_args.cpp new file mode 100644 index 000000000..af3495ce8 --- /dev/null +++ b/src/fmt/test/fuzzing/two_args.cpp @@ -0,0 +1,112 @@ +// Copyright (c) 2019, Paul Dreik +// License: see LICENSE.rst in the fmt root directory +#include <fmt/format.h> +#include <cstdint> +#include <stdexcept> +#include <type_traits> + +#include "fuzzer_common.h" + +constexpr auto Nfixed = fmt_fuzzer::Nfixed; + +template <typename Item1, typename Item2> +void invoke_fmt(const uint8_t* Data, size_t Size) { + constexpr auto N1 = sizeof(Item1); + constexpr auto N2 = sizeof(Item2); + static_assert(N1 <= Nfixed, "size1 exceeded"); + static_assert(N2 <= Nfixed, "size2 exceeded"); + if (Size <= Nfixed + Nfixed) { + return; + } + const Item1 item1 = fmt_fuzzer::assignFromBuf<Item1>(Data); + Data += Nfixed; + Size -= Nfixed; + + const Item2 item2 = fmt_fuzzer::assignFromBuf<Item2>(Data); + Data += Nfixed; + Size -= Nfixed; + + auto fmtstring = fmt::string_view(fmt_fuzzer::as_chars(Data), Size); + +#if FMT_FUZZ_FORMAT_TO_STRING + std::string message = fmt::format(fmtstring, item1, item2); +#else + fmt::memory_buffer message; + fmt::format_to(message, fmtstring, item1, item2); +#endif +} + +// for dynamic dispatching to an explicit instantiation +template <typename Callback> void invoke(int index, Callback callback) { + switch (index) { + case 0: + callback(bool{}); + break; + case 1: + callback(char{}); + break; + case 2: + using sc = signed char; + callback(sc{}); + break; + case 3: + using uc = unsigned char; + callback(uc{}); + break; + case 4: + callback(short{}); + break; + case 5: + using us = unsigned short; + callback(us{}); + break; + case 6: + callback(int{}); + break; + case 7: + callback(unsigned{}); + break; + case 8: + callback(long{}); + break; + case 9: + using ul = unsigned long; + callback(ul{}); + break; + case 10: + callback(float{}); + break; + case 11: + callback(double{}); + break; + case 12: + using LD = long double; + callback(LD{}); + break; + } +} + +extern "C" int LLVMFuzzerTestOneInput(const uint8_t* Data, size_t Size) { + if (Size <= 3) { + return 0; + } + + // switch types depending on the first byte of the input + const auto first = Data[0] & 0x0F; + const auto second = (Data[0] & 0xF0) >> 4; + Data++; + Size--; + + auto outer = [=](auto param1) { + auto inner = [=](auto param2) { + invoke_fmt<decltype(param1), decltype(param2)>(Data, Size); + }; + invoke(second, inner); + }; + + try { + invoke(first, outer); + } catch (std::exception& /*e*/) { + } + return 0; +} |