Skip to content

Commit

Permalink
make it easier for the chrono fuzzer to explore
Browse files Browse the repository at this point in the history
using a fixed size makes the cases cross pollinate
each other better.

the execution speed is much higher as well
pauldreik committed May 30, 2019

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
1 parent f0d7ccc commit 1c274cf
Showing 1 changed file with 110 additions and 67 deletions.
177 changes: 110 additions & 67 deletions fuzzing/chrono_duration.cpp
Original file line number Diff line number Diff line change
@@ -3,41 +3,50 @@

#include <fmt/core.h>
#include <cstdint>
#include <limits>
#include <stdexcept>
#include <type_traits>
#include <vector>
#include <limits>

#include <fmt/chrono.h>

template <typename Item, typename Ratio>
void doit_impl(const char* formatstring, const Item item) {
const std::chrono::duration<Item, Ratio> value(item);
try {
std::string message = fmt::format(formatstring, value);
std::string message = fmt::format(formatstring, value);
} catch (std::exception& e) {
}
}

// Item is the underlying type for duration (int, long etc)
template <typename Item> void doit(const uint8_t* Data, std::size_t Size) {
template <typename Item>
void doit(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.
const auto Nfixed=std::max(sizeof(long double),sizeof(std::intmax_t));
const auto N = sizeof(Item);
if (Size <= N) {
static_assert(N<=Nfixed,"fixed size is too small");
if (Size <= Nfixed + 1) {
return;
}
Item item{};
std::memcpy(&item, Data, N);
Data += N;
Size -= N;

//fast forward
Data += Nfixed;
Size -= Nfixed;

// see https://github.com/fmtlib/fmt/issues/1178
const bool github_1178_is_solved=true;
if(!github_1178_is_solved) {
if(std::is_floating_point<Item>::value || std::numeric_limits<Item>::is_signed) {
if(item<0) {
return;
}
const bool github_1178_is_solved = true;
if (!github_1178_is_solved) {
if (std::is_floating_point<Item>::value ||
std::numeric_limits<Item>::is_signed) {
if (item < 0) {
return;
}
}
}

// allocates as tight as possible, making it easier to catch buffer overruns
@@ -46,74 +55,108 @@ template <typename Item> void doit(const uint8_t* Data, std::size_t Size) {
std::memcpy(buf.data(), Data, Size);
// doit_impl<Item,std::yocto>(buf.data(),item);
// doit_impl<Item,std::zepto>(buf.data(),item);
doit_impl<Item, std::atto>(buf.data(), item);
doit_impl<Item, std::femto>(buf.data(), item);
doit_impl<Item, std::pico>(buf.data(), item);
doit_impl<Item, std::nano>(buf.data(), item);
doit_impl<Item, std::micro>(buf.data(), item);
doit_impl<Item, std::milli>(buf.data(), item);
doit_impl<Item, std::centi>(buf.data(), item);
doit_impl<Item, std::deci>(buf.data(), item);
doit_impl<Item, std::deca>(buf.data(), item);
doit_impl<Item, std::kilo>(buf.data(), item);
doit_impl<Item, std::mega>(buf.data(), item);
doit_impl<Item, std::giga>(buf.data(), item);
doit_impl<Item, std::tera>(buf.data(), item);
doit_impl<Item, std::peta>(buf.data(), item);
doit_impl<Item, std::exa>(buf.data(), 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, std::size_t Size) {
if (Size <= 3) {
return 0;
}

const auto first = Data[0];
Data++;
Size--;

switch (first) {
case 1:
doit<char>(Data, Size);
switch (scaling) {
case 1:
doit_impl<Item, std::atto>(buf.data(), item);
break;
case 21:
doit<unsigned char>(Data, Size);
case 2:
doit_impl<Item, std::femto>(buf.data(), item);
break;
case 31:
doit<signed char>(Data, Size);
case 3:
doit_impl<Item, std::pico>(buf.data(), item);
break;
case 2:
doit<short>(Data, Size);
case 4:
doit_impl<Item, std::nano>(buf.data(), item);
break;
case 22:
doit<unsigned short>(Data, Size);
case 5:
doit_impl<Item, std::micro>(buf.data(), item);
break;
case 3:
doit<int>(Data, Size);
case 6:
doit_impl<Item, std::milli>(buf.data(), item);
break;
case 23:
doit<unsigned int>(Data, Size);
case 7:
doit_impl<Item, std::centi>(buf.data(), item);
break;
case 4:
doit<long>(Data, Size);
case 8:
doit_impl<Item, std::deci>(buf.data(), item);
break;
case 24:
doit<unsigned long>(Data, Size);
case 9:
doit_impl<Item, std::deca>(buf.data(), item);
break;
case 5:
doit<float>(Data, Size);
case 10:
doit_impl<Item, std::kilo>(buf.data(), item);
break;
case 6:
doit<double>(Data, Size);
case 11:
doit_impl<Item, std::mega>(buf.data(), item);
break;
case 7:
doit<long double>(Data, Size);
case 12:
doit_impl<Item, std::giga>(buf.data(), item);
break;
case 13:
doit_impl<Item, std::tera>(buf.data(), item);
break;
default:
case 14:
doit_impl<Item, std::peta>(buf.data(), item);
break;
}
case 15:
doit_impl<Item, std::exa>(buf.data(), 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, std::size_t Size) {
if (Size <= 4) {
return 0;
}

const auto first = Data[0];
Data++;
Size--;
const auto second = Data[0];
Data++;
Size--;

switch (first) {
case 1:
doit<char>(Data, Size, second);
break;
case 21:
doit<unsigned char>(Data, Size, second);
break;
case 31:
doit<signed char>(Data, Size, second);
break;
case 2:
doit<short>(Data, Size, second);
break;
case 22:
doit<unsigned short>(Data, Size, second);
break;
case 3:
doit<int>(Data, Size, second);
break;
case 23:
doit<unsigned int>(Data, Size, second);
break;
case 4:
doit<long>(Data, Size, second);
break;
case 24:
doit<unsigned long>(Data, Size, second);
break;
case 5:
doit<float>(Data, Size, second);
break;
case 6:
doit<double>(Data, Size, second);
break;
case 7:
doit<long double>(Data, Size, second);
break;
default:
break;
}

return 0;
}

0 comments on commit 1c274cf

Please sign in to comment.