Skip to content

Commit

Permalink
refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
pauldreik committed Jun 14, 2019
1 parent 9a3f4cf commit a23b7a1
Show file tree
Hide file tree
Showing 7 changed files with 60 additions and 36 deletions.
4 changes: 2 additions & 2 deletions test/fuzzing/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ set(FMT_FUZZ_LDFLAGS "" CACHE STRING "LDFLAGS for the fuzz targets")

#find all fuzzers.
set(SOURCES
chrono_duration.cpp # this triggers integer overflows I yet not know how to fix
chrono_duration.cpp
named_arg.cpp
one_arg.cpp
sprintf.cpp
Expand All @@ -26,7 +26,7 @@ endif()
macro(implement_fuzzer sourcefile)
get_filename_component(basename ${sourcefile} NAME_WE)
set(name fuzzer_${basename})
add_executable(${name} ${sourcefile})
add_executable(${name} ${sourcefile} fuzzer_common.h)
target_link_libraries(${name} PRIVATE fmt)
if(FMT_FUZZ_LDFLAGS)
target_link_libraries(${name} PRIVATE ${FMT_FUZZ_LDFLAGS})
Expand Down
19 changes: 5 additions & 14 deletions test/fuzzing/chrono_duration.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,13 @@
#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 {
// Don't switch these two dynamically,
// there is already a large combinatoric explosion
// of type and ratio, causing afl to suffer and the corpus
// getting enormous. Occasionally, flip this switch and
// try manually.
#if 0
#if FMT_FUZZ_FORMAT_TO_STRING
std::string message = fmt::format(formatstring, value);
#else
fmt::memory_buffer buf;
Expand All @@ -31,21 +27,16 @@ void invoke_inner(fmt::string_view formatstring, const Item item) {
// Item is the underlying type for duration (int, long etc)
template <typename Item>
void invoke_outer(const uint8_t* Data, std::size_t Size, const int scaling) {
// always use a fixed location of the data, so different cases will
// cooperate better. the same bit pattern, interpreted as another type,
// is likely interesting.
// won't work on travis.
//constexpr auto Nfixed = std::max(sizeof(long double), sizeof(std::intmax_t));
constexpr auto Nfixed=16;
// 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;
}

// travis doesn't handle this
#if 0
#if __cplusplus >= 201402L
static_assert(std::is_trivially_copyable<Item>::value,
"Item must be blittable");
#endif
Expand Down
37 changes: 37 additions & 0 deletions test/fuzzing/fuzzer_common.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
#ifndef FUZZER_COMMON_H
#define FUZZER_COMMON_H
// Copyright (c) 2019, Paul Dreik
// License: see LICENSE.rst in the fmt root directory

// one can format to either a string, or a buf. buf 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 1

// 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



// 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.
// For this, we must know the size of the largest possible type in use.
// There are some problems on old compilers, hence the C++ version check
#if __cplusplus >= 201402L
# include <algorithm>
# include <cstdint>
namespace fmt_fuzzer {
constexpr auto Nfixed = std::max(sizeof(long double), sizeof(std::intmax_t));
}
#else
namespace fmt_fuzzer {
constexpr auto Nfixed=16;
}
#endif

#endif // FUZZER_COMMON_H
7 changes: 3 additions & 4 deletions test/fuzzing/named_arg.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include <stdexcept>
#include <type_traits>
#include <vector>
#include "fuzzer_common.h"

template <typename Item1>
void invoke_fmt(const uint8_t* Data, std::size_t Size, int argsize) {
Expand All @@ -30,8 +31,7 @@ void invoke_fmt(const uint8_t* Data, std::size_t Size, int argsize) {

// allocating buffers separately is slower, but increases chances
// of detecting memory errors
#define SEPARATE_ALLOCATION 1
#if SEPARATE_ALLOCATION
#if FMT_FUZZ_SEPARATE_ALLOCATION
std::vector<char> argnamebuffer(argsize);
std::memcpy(argnamebuffer.data(), Data, argsize);
auto argname = fmt::string_view(argnamebuffer.data(), argsize);
Expand All @@ -41,7 +41,7 @@ void invoke_fmt(const uint8_t* Data, std::size_t Size, int argsize) {
Data += argsize;
Size -= argsize;

#if SEPARATE_ALLOCATION
#if FMT_FUZZ_SEPARATE_ALLOCATION
// allocates as tight as possible, making it easier to catch buffer overruns.
std::vector<char> fmtstringbuffer(Size);
std::memcpy(fmtstringbuffer.data(), Data, Size);
Expand All @@ -50,7 +50,6 @@ void invoke_fmt(const uint8_t* Data, std::size_t Size, int argsize) {
auto fmtstring = fmt::string_view((const char*)Data, Size);
#endif
std::string message = fmt::format(fmtstring, fmt::arg(argname, item1));
#undef SEPARATE_ALLOCATION
}

// for dynamic dispatching to an explicit instantiation
Expand Down
12 changes: 6 additions & 6 deletions test/fuzzing/one_arg.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include <vector>

#include <fmt/chrono.h>
#include "fuzzer_common.h"

template <typename Item>
void invoke_fmt(const uint8_t* Data, std::size_t Size) {
Expand All @@ -24,17 +25,16 @@ void invoke_fmt(const uint8_t* Data, std::size_t Size) {
Data += N;
Size -= N;

#define SEPARATE_ALLOCATION 0
#if SEPARATE_ALLOCATION
#if FMT_FUZZ_SEPARATE_ALLOCATION
// allocates as tight as possible, making it easier to catch buffer overruns.
std::vector<char> fmtstringbuffer(Size);
std::memcpy(fmtstringbuffer.data(), Data, Size);
auto fmtstring = fmt::string_view(fmtstringbuffer.data(), Size);
#else
auto fmtstring = fmt::string_view((const char*)Data, Size);
#endif
#define ALLOCATE_RESULT_IN_STRING 0
#if ALLOCATE_RESULT_IN_STRING

#if FMT_FUZZ_FORMAT_TO_STRING
std::string message = fmt::format(fmtstring, item);
#else
fmt::memory_buffer message;
Expand All @@ -52,7 +52,7 @@ void invoke_fmt_time(const uint8_t* Data, std::size_t Size) {
std::memcpy(&item, Data, N);
Data += N;
Size -= N;
#if SEPARATE_ALLOCATION
#if FMT_FUZZ_SEPARATE_ALLOCATION
// allocates as tight as possible, making it easier to catch buffer overruns.
std::vector<char> fmtstringbuffer(Size);
std::memcpy(fmtstringbuffer.data(), Data, Size);
Expand All @@ -62,7 +62,7 @@ void invoke_fmt_time(const uint8_t* Data, std::size_t Size) {
#endif
auto* b = std::localtime(&item);
if (b) {
#if ALLOCATE_RESULT_IN_STRING
#if FMT_FUZZ_FORMAT_TO_STRING
std::string message = fmt::format(fmtstring, *b);
#else
fmt::memory_buffer message;
Expand Down
8 changes: 3 additions & 5 deletions test/fuzzing/sprintf.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,9 @@
#include <cstdint>
#include <stdexcept>

#include "fuzzer_common.h"

// won't work on travis.
//constexpr auto Nmax = std::max(sizeof(long double), sizeof(std::intmax_t));
constexpr auto Nmax=16;
constexpr auto Nmax=fmt_fuzzer::Nfixed;

template <class Item>
Item assignFromBuf(const uint8_t* Data, std::size_t Size) {
Expand Down Expand Up @@ -40,8 +39,7 @@ void invoke_fmt(const uint8_t* Data, std::size_t Size) {

auto fmtstring = fmt::string_view((const char*)Data, Size);

#define ALLOCATE_RESULT_IN_STRING 0
#if ALLOCATE_RESULT_IN_STRING
#if FMT_FUZZ_FORMAT_TO_STRING
std::string message = fmt::format(fmtstring, item1, item2);
#else
fmt::memory_buffer message;
Expand Down
9 changes: 4 additions & 5 deletions test/fuzzing/two_args.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@
#include <stdexcept>
#include <type_traits>

// won't work on travis.
//constexpr auto Nmax = std::max(sizeof(long double), sizeof(std::intmax_t));
constexpr auto Nmax=16;
#include "fuzzer_common.h"

constexpr auto Nmax=fmt_fuzzer::Nfixed;

template <typename Item1, typename Item2>
void invoke_fmt(const uint8_t* Data, std::size_t Size) {
Expand Down Expand Up @@ -38,8 +38,7 @@ void invoke_fmt(const uint8_t* Data, std::size_t Size) {

auto fmtstring = fmt::string_view((const char*)Data, Size);

#define ALLOCATE_RESULT_IN_STRING 0
#if ALLOCATE_RESULT_IN_STRING
#if FMT_FUZZ_FORMAT_TO_STRING
std::string message = fmt::format(fmtstring, item1, item2);
#else
fmt::memory_buffer message;
Expand Down

0 comments on commit a23b7a1

Please sign in to comment.