More fuzzing interfaces

llvm-svn: 316394
This commit is contained in:
Marshall Clow 2017-10-23 23:19:30 +00:00
parent 252d7bdc67
commit 5c947f0dd4
3 changed files with 142 additions and 17 deletions

View File

@ -0,0 +1,16 @@
sort
stable_sort
partition
stable_partition
nth_element
partial_sort
make_heap
push_heap
pop_heap
regex_ECMAScript
regex_POSIX
regex_extended
regex_awk
regex_grep
regex_egrep
search

View File

@ -26,9 +26,12 @@
#include "fuzzing.h" #include "fuzzing.h"
#include <vector> #include <vector>
#include <algorithm> #include <algorithm>
#include <functional>
#include <regex> #include <regex>
// If we had C++14, we could use the four iterator version of is_permutation #include <iostream>
// If we had C++14, we could use the four iterator version of is_permutation and equal
namespace fuzzing { namespace fuzzing {
@ -273,4 +276,101 @@ int regex_egrep (const uint8_t *data, size_t size)
return 0; return 0;
} }
// -- heap fuzzers
int make_heap (const uint8_t *data, size_t size)
{
std::vector<uint8_t> working(data, data + size);
std::make_heap(working.begin(), working.end());
if (!std::is_heap(working.begin(), working.end())) return 1;
if (!std::is_permutation(data, data + size, working.begin())) return 99;
return 0;
}
int push_heap (const uint8_t *data, size_t size)
{
if (size < 2) return 0;
// Make a heap from the first half of the data
std::vector<uint8_t> working(data, data + size);
auto iter = working.begin() + (size / 2);
std::make_heap(working.begin(), iter);
if (!std::is_heap(working.begin(), iter)) return 1;
// Now push the rest onto the heap, one at a time
++iter;
for (; iter != working.end(); ++iter) {
std::push_heap(working.begin(), iter);
if (!std::is_heap(working.begin(), iter)) return 2;
}
if (!std::is_permutation(data, data + size, working.begin())) return 99;
return 0;
}
int pop_heap (const uint8_t *data, size_t size)
{
if (size < 2) return 0;
std::vector<uint8_t> working(data, data + size);
std::make_heap(working.begin(), working.end());
// Pop things off, one at a time
auto iter = --working.end();
while (iter != working.begin()) {
std::pop_heap(working.begin(), iter);
if (!std::is_heap(working.begin(), --iter)) return 2;
}
return 0;
}
// -- search fuzzers
int search (const uint8_t *data, size_t size)
{
if (size < 2) return 0;
const size_t pat_size = data[0] * (size - 1) / std::numeric_limits<uint8_t>::max();
assert(pat_size <= size - 1);
const uint8_t *pat_begin = data + 1;
const uint8_t *pat_end = pat_begin + pat_size;
const uint8_t *data_end = data + size;
assert(pat_end <= data_end);
// std::cerr << "data[0] = " << size_t(data[0]) << " ";
// std::cerr << "Pattern size = " << pat_size << "; corpus is " << size - 1 << std::endl;
auto it = std::search(pat_end, data_end, pat_begin, pat_end);
if (it != data_end) // not found
if (!std::equal(pat_begin, pat_end, it))
return 1;
return 0;
}
template <typename S>
static int search_helper (const uint8_t *data, size_t size)
{
if (size < 2) return 0;
const size_t pat_size = data[0] * (size - 1) / std::numeric_limits<uint8_t>::max();
const uint8_t *pat_begin = data + 1;
const uint8_t *pat_end = pat_begin + pat_size;
const uint8_t *data_end = data + size;
auto it = std::search(pat_end, data_end, S(pat_begin, pat_end));
if (it != data_end) // not found
if (!std::equal(pat_begin, pat_end, it))
return 1;
return 0;
}
// These are still in std::experimental
// int search_boyer_moore (const uint8_t *data, size_t size)
// {
// return search_helper<std::boyer_moore_searcher<const uint8_t *>>(data, size);
// }
//
// int search_boyer_moore_horspool (const uint8_t *data, size_t size)
// {
// return search_helper<std::boyer_moore_horspool_searcher<const uint8_t *>>(data, size);
// }
} // namespace fuzzing } // namespace fuzzing

View File

@ -16,25 +16,34 @@
namespace fuzzing { namespace fuzzing {
// These all return 0 on success; != 0 on failure // These all return 0 on success; != 0 on failure
int sort (const uint8_t *data, size_t size); int sort (const uint8_t *data, size_t size);
int stable_sort (const uint8_t *data, size_t size); int stable_sort (const uint8_t *data, size_t size);
int partition (const uint8_t *data, size_t size); int partition (const uint8_t *data, size_t size);
int stable_partition (const uint8_t *data, size_t size); int stable_partition (const uint8_t *data, size_t size);
// partition and stable_partition take Bi-Di iterators. // partition and stable_partition take Bi-Di iterators.
// Should test those, too // Should test those, too
int nth_element (const uint8_t *data, size_t size);
int partial_sort (const uint8_t *data, size_t size);
int nth_element (const uint8_t *data, size_t size); // Heap operations
int partial_sort (const uint8_t *data, size_t size); int make_heap (const uint8_t *data, size_t size);
int push_heap (const uint8_t *data, size_t size);
int pop_heap (const uint8_t *data, size_t size);
// Various flavors of regex // Various flavors of regex
int regex_ECMAScript (const uint8_t *data, size_t size); int regex_ECMAScript (const uint8_t *data, size_t size);
int regex_POSIX (const uint8_t *data, size_t size); int regex_POSIX (const uint8_t *data, size_t size);
int regex_extended (const uint8_t *data, size_t size); int regex_extended (const uint8_t *data, size_t size);
int regex_awk (const uint8_t *data, size_t size); int regex_awk (const uint8_t *data, size_t size);
int regex_grep (const uint8_t *data, size_t size); int regex_grep (const uint8_t *data, size_t size);
int regex_egrep (const uint8_t *data, size_t size); int regex_egrep (const uint8_t *data, size_t size);
// Searching
int search (const uint8_t *data, size_t size);
// int search_boyer_moore (const uint8_t *data, size_t size);
// int search_boyer_moore_horspool (const uint8_t *data, size_t size);
} // namespace fuzzing } // namespace fuzzing