summaryrefslogtreecommitdiff
path: root/fuzzing/fuzzing.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'fuzzing/fuzzing.cpp')
-rw-r--r--fuzzing/fuzzing.cpp70
1 files changed, 62 insertions, 8 deletions
diff --git a/fuzzing/fuzzing.cpp b/fuzzing/fuzzing.cpp
index 9471a1d0af90..8888cbeac72e 100644
--- a/fuzzing/fuzzing.cpp
+++ b/fuzzing/fuzzing.cpp
@@ -105,6 +105,60 @@ struct is_even<stable_test>
typedef std::vector<uint8_t> Vec;
typedef std::vector<stable_test> StableVec;
+typedef StableVec::const_iterator SVIter;
+
+// Cheap version of is_permutation
+// Builds a set of buckets for each of the key values.
+// Sums all the payloads.
+// Not 100% perfect, but _way_ faster
+bool is_permutation(SVIter first1, SVIter last1, SVIter first2)
+{
+ size_t xBuckets[256] = {0};
+ size_t xPayloads[256] = {0};
+ size_t yBuckets[256] = {0};
+ size_t yPayloads[256] = {0};
+
+ for (; first1 != last1; ++first1, ++first2)
+ {
+ xBuckets [first1->key]++;
+ xPayloads[first1->key] += first1->payload;
+
+ yBuckets [first2->key]++;
+ yPayloads[first2->key] += first2->payload;
+ }
+
+ for (size_t i = 0; i < 256; ++i)
+ {
+ if (xBuckets[i] != yBuckets[i])
+ return false;
+ if (xPayloads[i] != yPayloads[i])
+ return false;
+ }
+
+ return true;
+}
+
+template <typename Iter1, typename Iter2>
+bool is_permutation(Iter1 first1, Iter1 last1, Iter2 first2)
+{
+ static_assert((std::is_same<typename std::iterator_traits<Iter1>::value_type, uint8_t>::value), "");
+ static_assert((std::is_same<typename std::iterator_traits<Iter2>::value_type, uint8_t>::value), "");
+
+ size_t xBuckets[256] = {0};
+ size_t yBuckets[256] = {0};
+
+ for (; first1 != last1; ++first1, ++first2)
+ {
+ xBuckets [*first1]++;
+ yBuckets [*first2]++;
+ }
+
+ for (size_t i = 0; i < 256; ++i)
+ if (xBuckets[i] != yBuckets[i])
+ return false;
+
+ return true;
+}
// == sort ==
int sort(const uint8_t *data, size_t size)
@@ -113,7 +167,7 @@ int sort(const uint8_t *data, size_t size)
std::sort(working.begin(), working.end());
if (!std::is_sorted(working.begin(), working.end())) return 1;
- if (!std::is_permutation(data, data + size, working.begin())) return 99;
+ if (!fuzzing::is_permutation(data, data + size, working.cbegin())) return 99;
return 0;
}
@@ -135,7 +189,7 @@ int stable_sort(const uint8_t *data, size_t size)
if (!std::is_sorted(range.first, range.second, total_less())) return 2;
iter = range.second;
}
- if (!std::is_permutation(input.begin(), input.end(), working.begin())) return 99;
+ if (!fuzzing::is_permutation(input.cbegin(), input.cend(), working.cbegin())) return 99;
return 0;
}
@@ -147,7 +201,7 @@ int partition(const uint8_t *data, size_t size)
if (!std::all_of (working.begin(), iter, is_even<uint8_t>())) return 1;
if (!std::none_of(iter, working.end(), is_even<uint8_t>())) return 2;
- if (!std::is_permutation(data, data + size, working.begin())) return 99;
+ if (!fuzzing::is_permutation(data, data + size, working.cbegin())) return 99;
return 0;
}
@@ -190,7 +244,7 @@ int stable_partition (const uint8_t *data, size_t size)
if (!std::none_of(iter, working.end(), is_even<stable_test>())) return 2;
if (!std::is_sorted(working.begin(), iter, payload_less())) return 3;
if (!std::is_sorted(iter, working.end(), payload_less())) return 4;
- if (!std::is_permutation(input.begin(), input.end(), working.begin())) return 99;
+ if (!fuzzing::is_permutation(input.cbegin(), input.cend(), working.cbegin())) return 99;
return 0;
}
@@ -216,7 +270,7 @@ int nth_element (const uint8_t *data, size_t size)
return 1;
if (!std::all_of(partition_iter, working.end(), [=](uint8_t v) { return v >= nth; }))
return 2;
- if (!std::is_permutation(data + 1, data + size, working.begin())) return 99;
+ if (!fuzzing::is_permutation(data + 1, data + size, working.cbegin())) return 99;
}
return 0;
@@ -241,7 +295,7 @@ int partial_sort (const uint8_t *data, size_t size)
return 2;
}
if (!std::is_sorted(working.begin(), sort_iter)) return 3;
- if (!std::is_permutation(data + 1, data + size, working.begin())) return 99;
+ if (!fuzzing::is_permutation(data + 1, data + size, working.cbegin())) return 99;
return 0;
}
@@ -440,7 +494,7 @@ int make_heap (const uint8_t *data, size_t 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;
+ if (!fuzzing::is_permutation(data, data + size, working.cbegin())) return 99;
return 0;
}
@@ -461,7 +515,7 @@ int push_heap (const uint8_t *data, size_t size)
if (!std::is_heap(working.begin(), iter)) return 2;
}
- if (!std::is_permutation(data, data + size, working.begin())) return 99;
+ if (!fuzzing::is_permutation(data, data + size, working.cbegin())) return 99;
return 0;
}