aboutsummaryrefslogtreecommitdiff
path: root/thirdparty/fmt/test/fuzzing
diff options
context:
space:
mode:
authorStefan Boberg <[email protected]>2026-04-23 18:16:57 +0200
committerStefan Boberg <[email protected]>2026-04-23 18:16:57 +0200
commit0232b991cd7d8e3a2114ea30e4591dd3e7b65c36 (patch)
tree94730e7594fd09ae1fa820391ce311f6daf13905 /thirdparty/fmt/test/fuzzing
parentFix forward declaration order for s_GotSigWinch and SigWinchHandler (diff)
parenttrace: declare Region event name fields as AnsiString (#1012) (diff)
downloadarchived-zen-sb/zen-help.tar.xz
archived-zen-sb/zen-help.zip
Merge branch 'main' into sb/zen-helpsb/zen-help
- Combine HelpCommand (this branch) with HistoryCommand (main) in zen CLI dispatcher - Keep filter-aware TuiPickOne rewrite; adopt main's ASCII arrow glyphs in doc comment
Diffstat (limited to 'thirdparty/fmt/test/fuzzing')
-rw-r--r--thirdparty/fmt/test/fuzzing/.gitignore3
-rw-r--r--thirdparty/fmt/test/fuzzing/README.md25
-rwxr-xr-xthirdparty/fmt/test/fuzzing/build.sh90
-rw-r--r--thirdparty/fmt/test/fuzzing/chrono-duration.cc136
-rw-r--r--thirdparty/fmt/test/fuzzing/chrono-timepoint.cc32
-rw-r--r--thirdparty/fmt/test/fuzzing/float.cc39
-rw-r--r--thirdparty/fmt/test/fuzzing/fuzzer-common.h77
-rw-r--r--thirdparty/fmt/test/fuzzing/main.cc22
-rw-r--r--thirdparty/fmt/test/fuzzing/named-arg.cc102
-rw-r--r--thirdparty/fmt/test/fuzzing/one-arg.cc92
-rw-r--r--thirdparty/fmt/test/fuzzing/two-args.cc106
11 files changed, 0 insertions, 724 deletions
diff --git a/thirdparty/fmt/test/fuzzing/.gitignore b/thirdparty/fmt/test/fuzzing/.gitignore
deleted file mode 100644
index ea4104026..000000000
--- a/thirdparty/fmt/test/fuzzing/.gitignore
+++ /dev/null
@@ -1,3 +0,0 @@
-# ignore artifacts from the build.sh script
-build-*/
-
diff --git a/thirdparty/fmt/test/fuzzing/README.md b/thirdparty/fmt/test/fuzzing/README.md
deleted file mode 100644
index bb3d0e04f..000000000
--- a/thirdparty/fmt/test/fuzzing/README.md
+++ /dev/null
@@ -1,25 +0,0 @@
-# Running the fuzzers locally
-
-There is a [helper script](build.sh) to build the fuzzers, which has only been
-tested on Debian and Ubuntu linux so far. There should be no problems fuzzing on
-Windows (using clang>=8) or on Mac, but the script will probably not work out of
-the box.
-
-Something along
-```sh
-mkdir build
-cd build
-export CXX=clang++
-export CXXFLAGS="-fsanitize=fuzzer-no-link -DFUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION= -g"
-cmake .. -DFMT_SAFE_DURATION_CAST=On -DFMT_FUZZ=On -DFMT_FUZZ_LINKMAIN=Off -DFMT_FUZZ_LDFLAGS="-fsanitize=fuzzer"
-cmake --build .
-```
-should work to build the fuzzers for all platforms which clang supports.
-
-Execute a fuzzer with for instance
-```sh
-cd build
-export UBSAN_OPTIONS=halt_on_error=1
-mkdir out_chrono
-bin/fuzzer_chrono_duration out_chrono
-```
diff --git a/thirdparty/fmt/test/fuzzing/build.sh b/thirdparty/fmt/test/fuzzing/build.sh
deleted file mode 100755
index 4497b62c1..000000000
--- a/thirdparty/fmt/test/fuzzing/build.sh
+++ /dev/null
@@ -1,90 +0,0 @@
-#!/bin/sh
-#
-# Creates fuzzer builds of various kinds
-# - oss-fuzz emulated mode (makes sure a simulated invocation by oss-fuzz works)
-# - libFuzzer build (you will need clang)
-# - afl build (you will need afl)
-#
-#
-# Copyright (c) 2019 Paul Dreik
-#
-# For the license information refer to format.h.
-
-set -e
-me=$(basename $0)
-root=$(readlink -f "$(dirname "$0")/../..")
-
-
-echo $me: root=$root
-
-here=$(pwd)
-
-CXXFLAGSALL="-DFUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION= -g"
-CMAKEFLAGSALL="$root -GNinja -DCMAKE_BUILD_TYPE=Debug -DFMT_DOC=Off -DFMT_TEST=Off -DFMT_FUZZ=On -DCMAKE_CXX_STANDARD=17"
-
-CLANG=clang++-11
-
-# For performance analysis of the fuzzers.
-builddir=$here/build-fuzzers-perfanalysis
-mkdir -p $builddir
-cd $builddir
-CXX="ccache g++" CXXFLAGS="$CXXFLAGSALL -g" cmake \
-$CMAKEFLAGSALL \
--DFMT_FUZZ_LINKMAIN=On \
--DCMAKE_BUILD_TYPE=Release
-
-cmake --build $builddir
-
-# Builds the fuzzers as oss-fuzz does.
-builddir=$here/build-fuzzers-ossfuzz
-mkdir -p $builddir
-cd $builddir
-CXX=$CLANG \
-CXXFLAGS="$CXXFLAGSALL -fsanitize=fuzzer-no-link" cmake \
-cmake $CMAKEFLAGSALL \
--DFMT_FUZZ_LINKMAIN=Off \
--DFMT_FUZZ_LDFLAGS="-fsanitize=fuzzer"
-
-cmake --build $builddir
-
-
-# Builds fuzzers for local fuzzing with libfuzzer with asan+usan.
-builddir=$here/build-fuzzers-libfuzzer
-mkdir -p $builddir
-cd $builddir
-CXX=$CLANG \
-CXXFLAGS="$CXXFLAGSALL -fsanitize=fuzzer-no-link,address,undefined" cmake \
-cmake $CMAKEFLAGSALL \
--DFMT_FUZZ_LINKMAIN=Off \
--DFMT_FUZZ_LDFLAGS="-fsanitize=fuzzer"
-
-cmake --build $builddir
-
-# Builds a fast fuzzer for making coverage fast.
-builddir=$here/build-fuzzers-fast
-mkdir -p $builddir
-cd $builddir
-CXX=$CLANG \
-CXXFLAGS="$CXXFLAGSALL -fsanitize=fuzzer-no-link -O3" cmake \
-cmake $CMAKEFLAGSALL \
--DFMT_FUZZ_LINKMAIN=Off \
--DFMT_FUZZ_LDFLAGS="-fsanitize=fuzzer" \
- -DCMAKE_BUILD_TYPE=Release
-
-cmake --build $builddir
-
-
-# Builds fuzzers for local fuzzing with afl.
-builddir=$here/build-fuzzers-afl
-mkdir -p $builddir
-cd $builddir
-CXX="afl-g++" \
-CXXFLAGS="$CXXFLAGSALL -fsanitize=address,undefined" \
-cmake $CMAKEFLAGSALL \
--DFMT_FUZZ_LINKMAIN=On
-
-cmake --build $builddir
-
-
-echo $me: all good
-
diff --git a/thirdparty/fmt/test/fuzzing/chrono-duration.cc b/thirdparty/fmt/test/fuzzing/chrono-duration.cc
deleted file mode 100644
index d66068d9c..000000000
--- a/thirdparty/fmt/test/fuzzing/chrono-duration.cc
+++ /dev/null
@@ -1,136 +0,0 @@
-// Copyright (c) 2019, Paul Dreik
-// For the license information refer to format.h.
-
-#include <fmt/chrono.h>
-
-#include <cstdint>
-
-#include "fuzzer-common.h"
-
-template <typename Period, typename Rep>
-void invoke_inner(fmt::string_view format_str, Rep rep) {
- auto value = std::chrono::duration<Rep, Period>(rep);
- try {
-#if FMT_FUZZ_FORMAT_TO_STRING
- std::string message = fmt::format(format_str, value);
-#else
- auto buf = fmt::memory_buffer();
- fmt::format_to(std::back_inserter(buf), format_str, value);
-#endif
- } catch (std::exception&) {
- }
-}
-
-// Rep is a duration's representation type.
-template <typename Rep>
-void invoke_outer(const uint8_t* data, size_t size, int period) {
- // Always use a fixed location of the data.
- static_assert(sizeof(Rep) <= fixed_size, "fixed size is too small");
- if (size <= fixed_size + 1) return;
-
- const Rep rep = assign_from_buf<Rep>(data);
- data += fixed_size;
- size -= fixed_size;
-
- // data is already allocated separately in libFuzzer so reading past the end
- // will most likely be detected anyway.
- const auto format_str = fmt::string_view(as_chars(data), size);
-
- // yocto, zepto, zetta and yotta are not handled.
- switch (period) {
- case 1:
- invoke_inner<std::atto>(format_str, rep);
- break;
- case 2:
- invoke_inner<std::femto>(format_str, rep);
- break;
- case 3:
- invoke_inner<std::pico>(format_str, rep);
- break;
- case 4:
- invoke_inner<std::nano>(format_str, rep);
- break;
- case 5:
- invoke_inner<std::micro>(format_str, rep);
- break;
- case 6:
- invoke_inner<std::milli>(format_str, rep);
- break;
- case 7:
- invoke_inner<std::centi>(format_str, rep);
- break;
- case 8:
- invoke_inner<std::deci>(format_str, rep);
- break;
- case 9:
- invoke_inner<std::deca>(format_str, rep);
- break;
- case 10:
- invoke_inner<std::kilo>(format_str, rep);
- break;
- case 11:
- invoke_inner<std::mega>(format_str, rep);
- break;
- case 12:
- invoke_inner<std::giga>(format_str, rep);
- break;
- case 13:
- invoke_inner<std::tera>(format_str, rep);
- break;
- case 14:
- invoke_inner<std::peta>(format_str, rep);
- break;
- case 15:
- invoke_inner<std::exa>(format_str, rep);
- break;
- }
-}
-
-extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
- if (size <= 4) return 0;
-
- const auto representation = data[0];
- const auto period = data[1];
- data += 2;
- size -= 2;
-
- switch (representation) {
- case 1:
- invoke_outer<char>(data, size, period);
- break;
- case 2:
- invoke_outer<signed char>(data, size, period);
- break;
- case 3:
- invoke_outer<unsigned char>(data, size, period);
- break;
- case 4:
- invoke_outer<short>(data, size, period);
- break;
- case 5:
- invoke_outer<unsigned short>(data, size, period);
- break;
- case 6:
- invoke_outer<int>(data, size, period);
- break;
- case 7:
- invoke_outer<unsigned int>(data, size, period);
- break;
- case 8:
- invoke_outer<long>(data, size, period);
- break;
- case 9:
- invoke_outer<unsigned long>(data, size, period);
- break;
- case 10:
- invoke_outer<float>(data, size, period);
- break;
- case 11:
- invoke_outer<double>(data, size, period);
- break;
- case 12:
- invoke_outer<long double>(data, size, period);
- break;
- }
- return 0;
-}
diff --git a/thirdparty/fmt/test/fuzzing/chrono-timepoint.cc b/thirdparty/fmt/test/fuzzing/chrono-timepoint.cc
deleted file mode 100644
index 8a1b24d29..000000000
--- a/thirdparty/fmt/test/fuzzing/chrono-timepoint.cc
+++ /dev/null
@@ -1,32 +0,0 @@
-// Copyright (c) 2021, Paul Dreik
-// For license information refer to format.h.
-#include <fmt/chrono.h>
-
-#include "fuzzer-common.h"
-
-/*
- * a fuzzer for the chrono timepoints formatters
- * C is a clock (std::chrono::system_clock etc)
- */
-template <typename C> void doit(const uint8_t* data, size_t size) {
- using Rep = typename C::time_point::rep;
- constexpr auto N = sizeof(Rep);
- if (size < N) return;
-
- const auto x = assign_from_buf<Rep>(data);
- typename C::duration dur{x};
- typename C::time_point timepoint{dur};
- data += N;
- size -= N;
- data_to_string format_str(data, size);
-
- std::string message = fmt::format(format_str.get(), timepoint);
-}
-
-extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
- try {
- doit<std::chrono::system_clock>(data, size);
- } catch (...) {
- }
- return 0;
-}
diff --git a/thirdparty/fmt/test/fuzzing/float.cc b/thirdparty/fmt/test/fuzzing/float.cc
deleted file mode 100644
index d4c9e4f57..000000000
--- a/thirdparty/fmt/test/fuzzing/float.cc
+++ /dev/null
@@ -1,39 +0,0 @@
-// A fuzzer for floating-point formatter.
-// For the license information refer to format.h.
-
-#include <fmt/format.h>
-
-#include <cstdint>
-#include <cstdlib>
-#include <limits>
-#include <stdexcept>
-
-#include "fuzzer-common.h"
-
-void check_round_trip(fmt::string_view format_str, double value) {
- auto buffer = fmt::memory_buffer();
- fmt::format_to(std::back_inserter(buffer), format_str, value);
-
- if (std::isnan(value)) {
- auto nan = std::signbit(value) ? "-nan" : "nan";
- if (fmt::string_view(buffer.data(), buffer.size()) != nan)
- throw std::runtime_error("round trip failure");
- return;
- }
-
- buffer.push_back('\0');
- char* ptr = nullptr;
- if (std::strtod(buffer.data(), &ptr) != value)
- throw std::runtime_error("round trip failure");
- if (ptr + 1 != buffer.end()) throw std::runtime_error("unparsed output");
-}
-
-extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
- if (size <= sizeof(double) || !std::numeric_limits<double>::is_iec559)
- return 0;
- check_round_trip("{}", assign_from_buf<double>(data));
- // A larger than necessary precision is used to trigger the fallback
- // formatter.
- check_round_trip("{:.50g}", assign_from_buf<double>(data));
- return 0;
-}
diff --git a/thirdparty/fmt/test/fuzzing/fuzzer-common.h b/thirdparty/fmt/test/fuzzing/fuzzer-common.h
deleted file mode 100644
index eaae5a6e4..000000000
--- a/thirdparty/fmt/test/fuzzing/fuzzer-common.h
+++ /dev/null
@@ -1,77 +0,0 @@
-// Copyright (c) 2019, Paul Dreik
-// For the license information refer to format.h.
-
-#ifndef FUZZER_COMMON_H
-#define FUZZER_COMMON_H
-
-#include <fmt/base.h>
-
-#include <cstdint> // std::uint8_t
-#include <cstring> // memcpy
-#include <vector>
-
-// One can format to either a string, or a buffer. The latter is faster, but
-// one may be interested in formatting to a string instead to verify it works
-// as intended. To avoid a combinatoric explosion, select this at compile time
-// instead of dynamically from the fuzz data.
-#define FMT_FUZZ_FORMAT_TO_STRING 0
-
-// If {fmt} is given a buffer that is separately allocated, chances that address
-// sanitizer detects out of bound reads is much higher. However, it slows down
-// the fuzzing.
-#define FMT_FUZZ_SEPARATE_ALLOCATION 1
-
-// The size of the largest possible type in use.
-// To let the the fuzzer mutation be efficient at cross pollinating between
-// different types, use a fixed size format. The same bit pattern, interpreted
-// as another type, is likely interesting.
-constexpr auto fixed_size = 16;
-
-// Casts data to a char pointer.
-template <typename T> inline const char* as_chars(const T* data) {
- return reinterpret_cast<const char*>(data);
-}
-
-// Casts data to a byte pointer.
-template <typename T> inline const std::uint8_t* as_bytes(const T* data) {
- return reinterpret_cast<const std::uint8_t*>(data);
-}
-
-// Blits bytes from data to form an (assumed trivially constructible) object
-// of type Item.
-template <class Item> inline Item assign_from_buf(const std::uint8_t* data) {
- auto item = Item();
- std::memcpy(&item, data, sizeof(Item));
- return item;
-}
-
-// Reads a boolean value by looking at the first byte from data.
-template <> inline bool assign_from_buf<bool>(const std::uint8_t* data) {
- return *data != 0;
-}
-
-struct data_to_string {
-#if FMT_FUZZ_SEPARATE_ALLOCATION
- std::vector<char> buffer;
-
- data_to_string(const uint8_t* data, size_t size, bool add_terminator = false)
- : buffer(size + (add_terminator ? 1 : 0)) {
- if (size) {
- std::memcpy(buffer.data(), data, size);
- }
- }
-
- fmt::string_view get() const { return {buffer.data(), buffer.size()}; }
-#else
- fmt::string_view sv;
-
- data_to_string(const uint8_t* data, size_t size, bool = false)
- : str(as_chars(data), size) {}
-
- fmt::string_view get() const { return sv; }
-#endif
-
- const char* data() const { return get().data(); }
-};
-
-#endif // FUZZER_COMMON_H
diff --git a/thirdparty/fmt/test/fuzzing/main.cc b/thirdparty/fmt/test/fuzzing/main.cc
deleted file mode 100644
index 8f8c719b7..000000000
--- a/thirdparty/fmt/test/fuzzing/main.cc
+++ /dev/null
@@ -1,22 +0,0 @@
-#include <cassert>
-#include <fstream>
-#include <vector>
-
-#include "fuzzer-common.h"
-
-extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size);
-
-int main(int argc, char** argv) {
- for (int i = 1; i < argc; ++i) {
- std::ifstream in(argv[i]);
- assert(in);
- in.seekg(0, std::ios_base::end);
- const auto size = in.tellg();
- assert(size >= 0);
- in.seekg(0, std::ios_base::beg);
- std::vector<char> buf(static_cast<size_t>(size));
- in.read(buf.data(), size);
- assert(in.gcount() == size);
- LLVMFuzzerTestOneInput(as_bytes(buf.data()), buf.size());
- }
-}
diff --git a/thirdparty/fmt/test/fuzzing/named-arg.cc b/thirdparty/fmt/test/fuzzing/named-arg.cc
deleted file mode 100644
index 3bee1ae3b..000000000
--- a/thirdparty/fmt/test/fuzzing/named-arg.cc
+++ /dev/null
@@ -1,102 +0,0 @@
-// Copyright (c) 2019, Paul Dreik
-// For the license information refer to format.h.
-
-#include <fmt/chrono.h>
-
-#include <cstdint>
-#include <type_traits>
-#include <vector>
-
-#include "fuzzer-common.h"
-
-template <typename T>
-void invoke_fmt(const uint8_t* data, size_t size, unsigned arg_name_size) {
- static_assert(sizeof(T) <= fixed_size, "fixed_size too small");
- if (size <= fixed_size) return;
- const T value = assign_from_buf<T>(data);
- data += fixed_size;
- size -= fixed_size;
-
- if (arg_name_size <= 0 || arg_name_size >= size) return;
- data_to_string arg_name(data, arg_name_size, true);
- data += arg_name_size;
- size -= arg_name_size;
-
- data_to_string format_str(data, size);
- try {
-#if FMT_FUZZ_FORMAT_TO_STRING
- std::string message =
- fmt::format(format_str.get(), fmt::arg(arg_name.data(), value));
-#else
- fmt::memory_buffer out;
- fmt::format_to(std::back_inserter(out), format_str.get(),
- fmt::arg(arg_name.data(), value));
-#endif
- } catch (std::exception&) {
- }
-}
-
-// For dynamic dispatching to an explicit instantiation.
-template <typename Callback> void invoke(int type, Callback callback) {
- switch (type) {
- 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 type = data[0] & 0x0F;
- const unsigned arg_name_size = (data[0] & 0xF0) >> 4;
- data++;
- size--;
-
- invoke(type, [=](auto arg) {
- invoke_fmt<decltype(arg)>(data, size, arg_name_size);
- });
- return 0;
-}
diff --git a/thirdparty/fmt/test/fuzzing/one-arg.cc b/thirdparty/fmt/test/fuzzing/one-arg.cc
deleted file mode 100644
index af9787f81..000000000
--- a/thirdparty/fmt/test/fuzzing/one-arg.cc
+++ /dev/null
@@ -1,92 +0,0 @@
-// Copyright (c) 2019, Paul Dreik
-// For the license information refer to format.h.
-
-#include <fmt/chrono.h>
-
-#include <cstdint>
-#include <exception>
-
-#include "fuzzer-common.h"
-
-template <typename T, typename Repr> const T* from_repr(const Repr& r) {
- return &r;
-}
-
-template <> const std::tm* from_repr<std::tm>(const std::time_t& t) {
- return std::localtime(&t);
-}
-
-template <typename T, typename Repr = T>
-void invoke_fmt(const uint8_t* data, size_t size) {
- static_assert(sizeof(Repr) <= fixed_size, "Nfixed is too small");
- if (size <= fixed_size) return;
- auto repr = assign_from_buf<Repr>(data);
- const T* value = from_repr<T>(repr);
- if (!value) return;
- data += fixed_size;
- size -= fixed_size;
- data_to_string format_str(data, size);
- try {
-#if FMT_FUZZ_FORMAT_TO_STRING
- std::string message = fmt::format(format_str.get(), *value);
-#else
- auto buf = fmt::memory_buffer();
- fmt::format_to(std::back_inserter(buf), format_str.get(), *value);
-#endif
- } catch (std::exception&) {
- }
-}
-
-extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
- if (size <= 3) return 0;
-
- const auto first = data[0];
- data++;
- size--;
-
- switch (first) {
- case 0:
- invoke_fmt<bool>(data, size);
- break;
- case 1:
- invoke_fmt<char>(data, size);
- break;
- case 2:
- invoke_fmt<unsigned char>(data, size);
- break;
- case 3:
- invoke_fmt<signed char>(data, size);
- break;
- case 4:
- invoke_fmt<short>(data, size);
- break;
- case 5:
- invoke_fmt<unsigned short>(data, size);
- break;
- case 6:
- invoke_fmt<int>(data, size);
- break;
- case 7:
- invoke_fmt<unsigned int>(data, size);
- break;
- case 8:
- invoke_fmt<long>(data, size);
- break;
- case 9:
- invoke_fmt<unsigned long>(data, size);
- break;
- case 10:
- invoke_fmt<float>(data, size);
- break;
- case 11:
- invoke_fmt<double>(data, size);
- break;
- case 12:
- invoke_fmt<long double>(data, size);
- break;
- case 13:
- invoke_fmt<std::tm, std::time_t>(data, size);
- break;
- }
- return 0;
-}
diff --git a/thirdparty/fmt/test/fuzzing/two-args.cc b/thirdparty/fmt/test/fuzzing/two-args.cc
deleted file mode 100644
index 931c64656..000000000
--- a/thirdparty/fmt/test/fuzzing/two-args.cc
+++ /dev/null
@@ -1,106 +0,0 @@
-// Copyright (c) 2019, Paul Dreik
-// For the license information refer to format.h.
-
-#include <fmt/format.h>
-
-#include <cstdint>
-#include <exception>
-#include <string>
-
-#include "fuzzer-common.h"
-
-template <typename Item1, typename Item2>
-void invoke_fmt(const uint8_t* data, size_t size) {
- static_assert(sizeof(Item1) <= fixed_size, "size1 exceeded");
- static_assert(sizeof(Item2) <= fixed_size, "size2 exceeded");
- if (size <= fixed_size + fixed_size) return;
-
- const Item1 item1 = assign_from_buf<Item1>(data);
- data += fixed_size;
- size -= fixed_size;
-
- const Item2 item2 = assign_from_buf<Item2>(data);
- data += fixed_size;
- size -= fixed_size;
-
- auto format_str = fmt::string_view(as_chars(data), size);
-#if FMT_FUZZ_FORMAT_TO_STRING
- std::string message = fmt::format(format_str, item1, item2);
-#else
- auto buf = fmt::memory_buffer();
- fmt::format_to(std::back_inserter(buf), format_str, 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;
- case 13:
- using ptr = void*;
- callback(ptr());
- 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 type1 = data[0] & 0x0F;
- const auto type2 = (data[0] & 0xF0) >> 4;
- data++;
- size--;
- try {
- invoke(type1, [=](auto param1) {
- invoke(type2, [=](auto param2) {
- invoke_fmt<decltype(param1), decltype(param2)>(data, size);
- });
- });
- } catch (std::exception&) {
- }
- return 0;
-}