aboutsummaryrefslogtreecommitdiffhomepage
path: root/fuzz/Fuzz.h
diff options
context:
space:
mode:
authorGravatar Kevin Lubick <kjlubick@google.com>2016-11-01 15:01:12 -0400
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2016-11-01 19:23:16 +0000
commit2f535cecd0e5a19a3dfb76649b1d90c7e158e24c (patch)
tree685d9bb66afe495239373aeb8a3a86fd1843e6c3 /fuzz/Fuzz.h
parent1f49f26353997195030aeab41c8665e1860d2958 (diff)
Make fuzzers use cleaner interface
signalBoring() no longer exists. When the fuzzer runs out of randomness, it just returns 0. Fuzzers should not go into infinite loops if this happens. do while loops are particularly error-prone. BUG=skia: GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=3963 Change-Id: Iebcfc14cc6b0a19c5dd015cd39875c81fa44003e Reviewed-on: https://skia-review.googlesource.com/3963 Commit-Queue: Kevin Lubick <kjlubick@google.com> Reviewed-by: Mike Klein <mtklein@chromium.org>
Diffstat (limited to 'fuzz/Fuzz.h')
-rw-r--r--fuzz/Fuzz.h98
1 files changed, 58 insertions, 40 deletions
diff --git a/fuzz/Fuzz.h b/fuzz/Fuzz.h
index 43918f4a94..17d75f4d34 100644
--- a/fuzz/Fuzz.h
+++ b/fuzz/Fuzz.h
@@ -12,7 +12,7 @@
#include "SkTRegistry.h"
#include "SkTypes.h"
-#include <vector>
+#include <cmath>
class Fuzz : SkNoncopyable {
public:
@@ -20,60 +20,78 @@ public:
// Returns the total number of "random" bytes available.
size_t size();
- // Returns the total number of "random" bytes remaining for randomness.
- size_t remaining();
+ // Returns if there are no bytes remaining for fuzzing.
+ bool exhausted();
template <typename T>
- bool SK_WARN_UNUSED_RESULT next(T* n);
+ T next();
- // UBSAN reminds us that bool can only legally hold 0 or 1.
- bool SK_WARN_UNUSED_RESULT next(bool* b) {
- uint8_t byte;
- if (!this->next(&byte)) {
- return false;
- }
- *b = (byte & 1) == 1;
- return true;
- }
+ // nextRange returns values only in [min, max].
+ template <typename T>
+ T nextRange(T min, T max);
- // The nextFoo methods are deprecated.
- // TODO(kjlubick): replace existing uses with next() and remove these.
- bool nextBool();
- uint8_t nextB();
- uint32_t nextU();
- // This can be nan, +- infinity, 0, anything.
- float nextF();
- // Returns a float between [0..1) as a IEEE float
- float nextF1();
-
- // Return the next fuzzed value [min, max) as an unsigned 32bit integer.
- uint32_t nextRangeU(uint32_t min, uint32_t max);
- /**
- * Returns next fuzzed value [min...max) as a float.
- * Will not be Infinity or NaN.
- */
- float nextRangeF(float min, float max);
-
- void signalBug (); // Tell afl-fuzz these inputs found a bug.
- void signalBoring(); // Tell afl-fuzz these inputs are not worth testing.
+ void signalBug(); // Tell afl-fuzz these inputs found a bug.
private:
template <typename T>
T nextT();
sk_sp<SkData> fBytes;
- int fNextByte;
+ size_t fNextByte;
};
+// UBSAN reminds us that bool can only legally hold 0 or 1.
+template <>
+inline bool Fuzz::next<bool>() {
+ return (this->next<uint8_t>() & 1) == 1;
+}
+
template <typename T>
-bool Fuzz::next(T* n) {
- if (fNextByte + sizeof(T) > fBytes->size()) {
- return false;
+T Fuzz::next() {
+ if ((fNextByte + sizeof(T)) > fBytes->size()) {
+ T n = 0;
+ memcpy(&n, fBytes->bytes() + fNextByte, fBytes->size() - fNextByte);
+ fNextByte = fBytes->size();
+ return n;
}
-
- memcpy(n, fBytes->bytes() + fNextByte, sizeof(T));
+ T n;
+ memcpy(&n, fBytes->bytes() + fNextByte, sizeof(T));
fNextByte += sizeof(T);
- return true;
+ return n;
+}
+
+template <>
+inline float Fuzz::nextRange(float min, float max) {
+ if (min > max) {
+ SkDebugf("Check mins and maxes (%f, %f)\n", min, max);
+ this->signalBug();
+ }
+ float f = this->next<float>();
+ if (!std::isnormal(f) && f != 0.0f) {
+ // Don't deal with infinity or other strange floats.
+ return max;
+ }
+ return min + std::fmod(std::abs(f), (max - min + 1));
+}
+
+template <typename T>
+T Fuzz::nextRange(T min, T max) {
+ if (min > max) {
+ SkDebugf("Check mins and maxes (%d, %d)\n", min, max);
+ this->signalBug();
+ }
+ T n = this->next<T>();
+ T range = max - min + 1;
+ if (0 == range) {
+ return n;
+ } else {
+ n = abs(n);
+ if (n < 0) {
+ // abs(INT_MIN) = INT_MIN, so we check this to avoid accidental negatives.
+ return min;
+ }
+ return min + n % range;
+ }
}
struct Fuzzable {