* Copyright 2016 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef Fuzz_DEFINED
#define Fuzz_DEFINED
#include "include/core/SkData.h"
#include "include/core/SkImageFilter.h"
#include "include/core/SkRegion.h"
#include "include/core/SkTypes.h"
#include "include/private/base/SkMalloc.h"
#include "include/private/base/SkTFitsIn.h"
#include "tools/Registry.h"
#include <limits>
#include <cmath>
#include <signal.h>
#include <limits>
class Fuzz {
public:
explicit Fuzz(const uint8_t* data, size_t size) : fData(data), fSize(size), fNextByte(0) {}
Fuzz() = delete;
Fuzz(Fuzz&) = delete;
Fuzz& operator=(Fuzz&) = delete;
size_t size() const {
return fSize;
}
bool exhausted() const {
return fSize == fNextByte;
}
void deplete() {
fNextByte = fSize;
}
size_t remainingSize() const {
return fSize - fNextByte;
}
const uint8_t *remainingData() const {
return fData + fNextByte;
}
template <typename T>
void next(T* t) { this->nextBytes(t, sizeof(T)); }
template <typename Arg, typename... Args>
void next(Arg* first, Args... rest);
template <typename T, typename Min, typename Max>
void nextRange(T*, Min, Max);
template <typename T>
void nextEnum(T* ptr, T max);
template <typename T>
void nextN(T* ptr, int n);
void signalBug() {
SkDebugf("Signal bug\n");
raise(SIGSEGV);
}
void next(bool* b);
void next(SkRegion* region);
bool nextBool() {
bool b;
this->next(&b);
return b;
}
void nextRange(float* f, float min, float max);
private:
template <typename T>
T nextT();
const uint8_t *fData;
size_t fSize;
size_t fNextByte;
friend void fuzz__MakeEncoderCorpus(Fuzz*);
void nextBytes(void* ptr, size_t size);
};
template <typename Arg, typename... Args>
inline void Fuzz::next(Arg* first, Args... rest) {
this->next(first);
this->next(rest...);
}
template <typename T, typename Min, typename Max>
inline void Fuzz::nextRange(T* value, Min min, Max max) {
using Raw = typename sk_strip_enum<T>::type;
Raw raw;
this->next(&raw);
if (raw < (Raw)min) { raw = (Raw)min; }
if (raw > (Raw)max) { raw = (Raw)max; }
*value = (T)raw;
}
template <typename T>
inline void Fuzz::nextEnum(T* value, T max) {
using U = typename std::underlying_type<T>::type;
U v;
this->next(&v);
if (v < (U)0) { *value = (T)0; return;}
if (v > (U)max) { *value = (T)max; return;}
*value = (T)v;
}
template <typename T>
inline void Fuzz::nextN(T* ptr, int n) {
for (int i = 0; i < n; i++) {
this->next(ptr+i);
}
}
struct Fuzzable {
const char* name;
void (*fn)(Fuzz*);
};
#define DEF_FUZZ(name, f) \
void fuzz_##name(Fuzz*); \
sk_tools::Registry<Fuzzable> register_##name({#name, fuzz_##name}); \
void fuzz_##name(Fuzz* f)
#endif