Skip to content

Commit

Permalink
Add fuzzing for standard compliance checks
Browse files Browse the repository at this point in the history
  • Loading branch information
danlark1 committed Nov 22, 2020
1 parent 51e8672 commit ffede29
Show file tree
Hide file tree
Showing 7 changed files with 70 additions and 5 deletions.
1 change: 1 addition & 0 deletions fuzz/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ if(ENABLE_FUZZING)
implement_fuzzer(fuzz_string_select)
implement_fuzzer(fuzz_sort)
implement_fuzzer(fuzz_string_sort)
implement_fuzzer(fuzz_standard_compliance)

# to be able to get a list of all fuzzers from within a script
add_custom_target(print_all_fuzzernames
Expand Down
1 change: 0 additions & 1 deletion fuzz/fuzz_select.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ void ChooseImplementation(uint8_t byte, std::vector<U>& working,
...);
}

// Use the first element as a position into the data
extern "C" int LLVMFuzzerTestOneInput(const std::uint8_t* data,
std::size_t size) {
if (size <= 3) return 0;
Expand Down
1 change: 0 additions & 1 deletion fuzz/fuzz_sort.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ void ChooseImplementation(uint8_t byte, std::vector<U>& working,
...);
}

// Use the first element as a position into the data
extern "C" int LLVMFuzzerTestOneInput(const std::uint8_t* data,
std::size_t size) {
if (size <= 3) return 0;
Expand Down
68 changes: 68 additions & 0 deletions fuzz/fuzz_standard_compliance.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
#include <algorithm>
#include <cstddef>
#include <cstdint>
#include <vector>

#include "test_common.h"

template <class Iter, class... T>
void ChooseImplementation(uint8_t byte, Iter beg, Iter end, Iter partition_iter,
const ::testing::Types<T...>&) {
static_assert(sizeof...(T) < 256);
int i = 0;
constexpr size_t size = sizeof...(T);
(
[&]() {
if (byte % size == i++) {
T::Select(beg, partition_iter, end);
}
}(),
...);
}

extern "C" int LLVMFuzzerTestOneInput(const std::uint8_t* data,
std::size_t size) {
if (size <= 3) return 0;
uint8_t impl = data[0];
uint8_t partition_point = data[1];
size = std::min(std::size_t{129}, size) - 2;
partition_point %= size;
std::vector<char> working(data + 2, data + size + 2);
miniselect::algorithms::IntegralCharIterator<char> beg(working.data());
miniselect::algorithms::IntegralCharIterator<char> ending(working.data() +
working.size());
auto canonical = working;
const auto partition_iter = beg + partition_point;
ChooseImplementation(impl, beg, ending, partition_iter,
miniselect::algorithms::All{});
if (partition_iter != ending) {
const auto& nth = *partition_iter;
bool is_error = false;
if (!std::all_of(beg, partition_iter,
[&](const auto& v) { return v <= nth; })) {
is_error = true;
}
if (!std::all_of(partition_iter, ending,
[&](const auto& v) { return v >= nth; })) {
is_error = true;
}
if (is_error) {
fail:
std::cerr << "FAILED!\nCanonical: ";
for (const auto& s : canonical) {
std::cerr << static_cast<int>(s) << ' ';
}
std::cerr << std::endl;
std::cerr << "Got: ";
for (const auto& s : working) {
std::cerr << static_cast<int>(s) << ' ';
}
std::cerr << std::endl;
std::cerr << "partition_iter = " << static_cast<int>(partition_iter - beg)
<< std::endl;
std::abort();
}
}

return 0;
}
1 change: 0 additions & 1 deletion fuzz/fuzz_string_select.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ void ChooseImplementation(uint8_t byte, std::vector<U>& working,
...);
}

// Use the first element as a position into the data
extern "C" int LLVMFuzzerTestOneInput(const std::uint8_t* data,
std::size_t size) {
if (size <= 3) return 0;
Expand Down
1 change: 0 additions & 1 deletion fuzz/fuzz_string_sort.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ void ChooseImplementation(uint8_t byte, std::vector<U>& working,
...);
}

// Use the first element as a position into the data
extern "C" int LLVMFuzzerTestOneInput(const std::uint8_t* data,
std::size_t size) {
if (size <= 3) return 0;
Expand Down
2 changes: 1 addition & 1 deletion testing/test_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -293,7 +293,7 @@ struct IntegralCharIterator {
return pos >= other.pos;
}

char* pos;
char* pos = nullptr;
};

template <class Integral>
Expand Down

0 comments on commit ffede29

Please sign in to comment.