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/chrono_duration.cpp | |
parent | Initial commit. (diff) | |
download | ceph-upstream.tar.xz ceph-upstream.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 '')
-rw-r--r-- | src/fmt/test/fuzzing/chrono_duration.cpp | 152 |
1 files changed, 152 insertions, 0 deletions
diff --git a/src/fmt/test/fuzzing/chrono_duration.cpp b/src/fmt/test/fuzzing/chrono_duration.cpp new file mode 100644 index 000000000..3f25f6be7 --- /dev/null +++ b/src/fmt/test/fuzzing/chrono_duration.cpp @@ -0,0 +1,152 @@ +// Copyright (c) 2019, Paul Dreik +// License: see LICENSE.rst in the fmt root directory + +#include <fmt/chrono.h> +#include <cstdint> +#include <limits> +#include <stdexcept> +#include <type_traits> +#include <vector> +#include "fuzzer_common.h" + +template <typename Item, typename Ratio> +void invoke_inner(fmt::string_view formatstring, const Item item) { + const std::chrono::duration<Item, Ratio> 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 <typename Item> +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<Item>(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<Item,std::yocto>(buf.data(),item); + // doit_impl<Item,std::zepto>(buf.data(),item); + switch (scaling) { + case 1: + invoke_inner<Item, std::atto>(formatstring, item); + break; + case 2: + invoke_inner<Item, std::femto>(formatstring, item); + break; + case 3: + invoke_inner<Item, std::pico>(formatstring, item); + break; + case 4: + invoke_inner<Item, std::nano>(formatstring, item); + break; + case 5: + invoke_inner<Item, std::micro>(formatstring, item); + break; + case 6: + invoke_inner<Item, std::milli>(formatstring, item); + break; + case 7: + invoke_inner<Item, std::centi>(formatstring, item); + break; + case 8: + invoke_inner<Item, std::deci>(formatstring, item); + break; + case 9: + invoke_inner<Item, std::deca>(formatstring, item); + break; + case 10: + invoke_inner<Item, std::kilo>(formatstring, item); + break; + case 11: + invoke_inner<Item, std::mega>(formatstring, item); + break; + case 12: + invoke_inner<Item, std::giga>(formatstring, item); + break; + case 13: + invoke_inner<Item, std::tera>(formatstring, item); + break; + case 14: + invoke_inner<Item, std::peta>(formatstring, item); + break; + case 15: + invoke_inner<Item, std::exa>(formatstring, item); + } + // doit_impl<Item,std::zeta>(buf.data(),item); + // doit_impl<Item,std::yotta>(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<char>(Data, Size, scaling); + break; + case 2: + invoke_outer<unsigned char>(Data, Size, scaling); + break; + case 3: + invoke_outer<signed char>(Data, Size, scaling); + break; + case 4: + invoke_outer<short>(Data, Size, scaling); + break; + case 5: + invoke_outer<unsigned short>(Data, Size, scaling); + break; + case 6: + invoke_outer<int>(Data, Size, scaling); + break; + case 7: + invoke_outer<unsigned int>(Data, Size, scaling); + break; + case 8: + invoke_outer<long>(Data, Size, scaling); + break; + case 9: + invoke_outer<unsigned long>(Data, Size, scaling); + break; + case 10: + invoke_outer<float>(Data, Size, scaling); + break; + case 11: + invoke_outer<double>(Data, Size, scaling); + break; + case 12: + invoke_outer<long double>(Data, Size, scaling); + break; + default: + break; + } + + return 0; +} |