aboutsummaryrefslogtreecommitdiffhomepage
path: root/fuzz/Fuzz.h
diff options
context:
space:
mode:
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 {