* 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/SkMalloc.h"
#include "tools/Registry.h"
#include <limits>
#include <cmath>
#include <signal.h>
#include <limits>
class Fuzz : SkNoncopyable {
public:
explicit Fuzz(sk_sp<SkData> bytes) : fBytes(bytes), fNextByte(0) {}
size_t size() { return fBytes->size(); }
bool exhausted() {
return fBytes->size() == fNextByte;
}
size_t remaining() {
return fBytes->size() - fNextByte;
}
void deplete() {
fNextByte = fBytes->size();
}
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(SkImageFilter::CropRect* cropRect);
void next(SkRegion* region);
void nextRange(float* f, float min, float max);
private:
template <typename T>
T nextT();
sk_sp<SkData> fBytes;
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) {
this->next(value);
if (*value < (T)min) { *value = (T)min; }
if (*value > (T)max) { *value = (T)max; }
}
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