[libFuzzer] refactor the mutation functions so that they are now methods of a class. NFC

llvm-svn: 246808
This commit is contained in:
Kostya Serebryany 2015-09-03 21:24:19 +00:00
parent f11bc761d8
commit ec2dcb1d91
5 changed files with 78 additions and 67 deletions

View File

@ -16,9 +16,9 @@
namespace fuzzer { namespace fuzzer {
// Cross Data1 and Data2, store the result (up to MaxOutSize bytes) in Out. // Cross Data1 and Data2, store the result (up to MaxOutSize bytes) in Out.
size_t CrossOver(const uint8_t *Data1, size_t Size1, size_t MutationDispatcher::CrossOver(const uint8_t *Data1, size_t Size1,
const uint8_t *Data2, size_t Size2, const uint8_t *Data2, size_t Size2,
uint8_t *Out, size_t MaxOutSize, FuzzerRandomBase &Rand) { uint8_t *Out, size_t MaxOutSize) {
assert(Size1 || Size2); assert(Size1 || Size2);
MaxOutSize = Rand(MaxOutSize) + 1; MaxOutSize = Rand(MaxOutSize) + 1;
size_t OutPos = 0; size_t OutPos = 0;

View File

@ -20,9 +20,10 @@ void FuzzerRandomLibc::ResetSeed(int seed) { srand(seed); }
size_t FuzzerRandomLibc::Rand() { return rand(); } size_t FuzzerRandomLibc::Rand() { return rand(); }
UserSuppliedFuzzer::UserSuppliedFuzzer() UserSuppliedFuzzer::UserSuppliedFuzzer()
: OwnRand(true), Rand(new FuzzerRandomLibc(0)) {} : OwnRand(true), Rand(new FuzzerRandomLibc(0)), MD(*Rand) {}
UserSuppliedFuzzer::UserSuppliedFuzzer(FuzzerRandomBase *Rand) : Rand(Rand) {} UserSuppliedFuzzer::UserSuppliedFuzzer(FuzzerRandomBase *Rand)
: Rand(Rand), MD(*Rand) {}
UserSuppliedFuzzer::~UserSuppliedFuzzer() { UserSuppliedFuzzer::~UserSuppliedFuzzer() {
if (OwnRand) if (OwnRand)

View File

@ -62,33 +62,38 @@ class FuzzerRandomLibc : public FuzzerRandomBase {
size_t Rand() override; size_t Rand() override;
}; };
class MutationDispatcher {
public:
MutationDispatcher(FuzzerRandomBase &Rand) : Rand(Rand) {}
/// Mutates data by shuffling bytes.
size_t Mutate_ShuffleBytes(uint8_t *Data, size_t Size, size_t MaxSize);
/// Mutates data by erasing a byte.
size_t Mutate_EraseByte(uint8_t *Data, size_t Size, size_t MaxSize);
/// Mutates data by inserting a byte.
size_t Mutate_InsertByte(uint8_t *Data, size_t Size, size_t MaxSize);
/// Mutates data by chanding one byte.
size_t Mutate_ChangeByte(uint8_t *Data, size_t Size, size_t MaxSize);
/// Mutates data by chanding one bit.
size_t Mutate_ChangeBit(uint8_t *Data, size_t Size, size_t MaxSize);
/// Mutates data by shuffling bytes. /// Applies one of the above mutations.
size_t Mutate_ShuffleBytes(uint8_t *Data, size_t Size, size_t MaxSize, /// Returns the new size of data which could be up to MaxSize.
FuzzerRandomBase &Rand); size_t Mutate(uint8_t *Data, size_t Size, size_t MaxSize);
/// Mutates data by erasing a byte.
size_t Mutate_EraseByte(uint8_t *Data, size_t Size, size_t MaxSize,
FuzzerRandomBase &Rand);
/// Mutates data by inserting a byte.
size_t Mutate_InsertByte(uint8_t *Data, size_t Size, size_t MaxSize,
FuzzerRandomBase &Rand);
/// Mutates data by chanding one byte.
size_t Mutate_ChangeByte(uint8_t *Data, size_t Size, size_t MaxSize,
FuzzerRandomBase &Rand);
/// Mutates data by chanding one bit.
size_t Mutate_ChangeBit(uint8_t *Data, size_t Size, size_t MaxSize,
FuzzerRandomBase &Rand);
/// Applies one of the above mutations. /// Creates a cross-over of two pieces of Data, returns its size.
/// Returns the new size of data which could be up to MaxSize. size_t CrossOver(const uint8_t *Data1, size_t Size1, const uint8_t *Data2,
size_t Mutate(uint8_t *Data, size_t Size, size_t MaxSize, size_t Size2, uint8_t *Out, size_t MaxOutSize);
FuzzerRandomBase &Rand);
/// Creates a cross-over of two pieces of Data, returns its size. private:
size_t CrossOver(const uint8_t *Data1, size_t Size1, const uint8_t *Data2, FuzzerRandomBase &Rand;
size_t Size2, uint8_t *Out, size_t MaxOutSize, };
FuzzerRandomBase &Rand);
// For backward compatibility only, deprecated.
static inline size_t Mutate(uint8_t *Data, size_t Size, size_t MaxSize,
FuzzerRandomBase &Rand) {
MutationDispatcher MD(Rand);
return MD.Mutate(Data, Size, MaxSize);
}
/** An abstract class that allows to use user-supplied mutators with libFuzzer. /** An abstract class that allows to use user-supplied mutators with libFuzzer.
@ -122,15 +127,14 @@ class UserSuppliedFuzzer {
/// Mutates 'Size' bytes of data in 'Data' inplace into up to 'MaxSize' bytes, /// Mutates 'Size' bytes of data in 'Data' inplace into up to 'MaxSize' bytes,
/// returns the new size of the data, which should be positive. /// returns the new size of the data, which should be positive.
virtual size_t Mutate(uint8_t *Data, size_t Size, size_t MaxSize) { virtual size_t Mutate(uint8_t *Data, size_t Size, size_t MaxSize) {
return ::fuzzer::Mutate(Data, Size, MaxSize, GetRand()); return MD.Mutate(Data, Size, MaxSize);
} }
/// Crosses 'Data1' and 'Data2', writes up to 'MaxOutSize' bytes into Out, /// Crosses 'Data1' and 'Data2', writes up to 'MaxOutSize' bytes into Out,
/// returns the number of bytes written, which should be positive. /// returns the number of bytes written, which should be positive.
virtual size_t CrossOver(const uint8_t *Data1, size_t Size1, virtual size_t CrossOver(const uint8_t *Data1, size_t Size1,
const uint8_t *Data2, size_t Size2, const uint8_t *Data2, size_t Size2,
uint8_t *Out, size_t MaxOutSize) { uint8_t *Out, size_t MaxOutSize) {
return ::fuzzer::CrossOver(Data1, Size1, Data2, Size2, Out, MaxOutSize, return MD.CrossOver(Data1, Size1, Data2, Size2, Out, MaxOutSize);
GetRand());
} }
virtual ~UserSuppliedFuzzer(); virtual ~UserSuppliedFuzzer();
@ -139,6 +143,7 @@ class UserSuppliedFuzzer {
private: private:
bool OwnRand = false; bool OwnRand = false;
FuzzerRandomBase *Rand; FuzzerRandomBase *Rand;
MutationDispatcher MD;
}; };
/// Runs the fuzzing with the UserSuppliedFuzzer. /// Runs the fuzzing with the UserSuppliedFuzzer.

View File

@ -35,8 +35,8 @@ static char RandCh(FuzzerRandomBase &Rand) {
return Special[Rand(sizeof(Special) - 1)]; return Special[Rand(sizeof(Special) - 1)];
} }
size_t Mutate_ShuffleBytes(uint8_t *Data, size_t Size, size_t MaxSize, size_t MutationDispatcher::Mutate_ShuffleBytes(uint8_t *Data, size_t Size,
FuzzerRandomBase &Rand) { size_t MaxSize) {
assert(Size); assert(Size);
size_t ShuffleAmount = Rand(std::min(Size, 8UL)) + 1; // [1,8] and <= Size. size_t ShuffleAmount = Rand(std::min(Size, 8UL)) + 1; // [1,8] and <= Size.
size_t ShuffleStart = Rand(Size - ShuffleAmount); size_t ShuffleStart = Rand(Size - ShuffleAmount);
@ -46,8 +46,8 @@ size_t Mutate_ShuffleBytes(uint8_t *Data, size_t Size, size_t MaxSize,
return Size; return Size;
} }
size_t Mutate_EraseByte(uint8_t *Data, size_t Size, size_t MaxSize, size_t MutationDispatcher::Mutate_EraseByte(uint8_t *Data, size_t Size,
FuzzerRandomBase &Rand) { size_t MaxSize) {
assert(Size); assert(Size);
if (Size == 1) return Size; if (Size == 1) return Size;
size_t Idx = Rand(Size); size_t Idx = Rand(Size);
@ -56,8 +56,8 @@ size_t Mutate_EraseByte(uint8_t *Data, size_t Size, size_t MaxSize,
return Size - 1; return Size - 1;
} }
size_t Mutate_InsertByte(uint8_t *Data, size_t Size, size_t MaxSize, size_t MutationDispatcher::Mutate_InsertByte(uint8_t *Data, size_t Size,
FuzzerRandomBase &Rand) { size_t MaxSize) {
if (Size == MaxSize) return Size; if (Size == MaxSize) return Size;
size_t Idx = Rand(Size + 1); size_t Idx = Rand(Size + 1);
// Insert new value at Data[Idx]. // Insert new value at Data[Idx].
@ -66,23 +66,22 @@ size_t Mutate_InsertByte(uint8_t *Data, size_t Size, size_t MaxSize,
return Size + 1; return Size + 1;
} }
size_t Mutate_ChangeByte(uint8_t *Data, size_t Size, size_t MaxSize, size_t MutationDispatcher::Mutate_ChangeByte(uint8_t *Data, size_t Size,
FuzzerRandomBase &Rand) { size_t MaxSize) {
size_t Idx = Rand(Size); size_t Idx = Rand(Size);
Data[Idx] = RandCh(Rand); Data[Idx] = RandCh(Rand);
return Size; return Size;
} }
size_t Mutate_ChangeBit(uint8_t *Data, size_t Size, size_t MaxSize, size_t MutationDispatcher::Mutate_ChangeBit(uint8_t *Data, size_t Size,
FuzzerRandomBase &Rand) { size_t MaxSize) {
size_t Idx = Rand(Size); size_t Idx = Rand(Size);
Data[Idx] = FlipRandomBit(Data[Idx], Rand); Data[Idx] = FlipRandomBit(Data[Idx], Rand);
return Size; return Size;
} }
// Mutates Data in place, returns new size. // Mutates Data in place, returns new size.
size_t Mutate(uint8_t *Data, size_t Size, size_t MaxSize, size_t MutationDispatcher::Mutate(uint8_t *Data, size_t Size, size_t MaxSize) {
FuzzerRandomBase &Rand) {
assert(MaxSize > 0); assert(MaxSize > 0);
assert(Size <= MaxSize); assert(Size <= MaxSize);
if (Size == 0) { if (Size == 0) {
@ -92,11 +91,11 @@ size_t Mutate(uint8_t *Data, size_t Size, size_t MaxSize,
} }
assert(Size > 0); assert(Size > 0);
switch (Rand(5)) { switch (Rand(5)) {
case 0: Size = Mutate_EraseByte(Data, Size, MaxSize, Rand); break; case 0: Size = Mutate_EraseByte(Data, Size, MaxSize); break;
case 1: Size = Mutate_InsertByte(Data, Size, MaxSize, Rand); break; case 1: Size = Mutate_InsertByte(Data, Size, MaxSize); break;
case 2: Size = Mutate_ChangeByte(Data, Size, MaxSize, Rand); break; case 2: Size = Mutate_ChangeByte(Data, Size, MaxSize); break;
case 3: Size = Mutate_ChangeBit(Data, Size, MaxSize, Rand); break; case 3: Size = Mutate_ChangeBit(Data, Size, MaxSize); break;
case 4: Size = Mutate_ShuffleBytes(Data, Size, MaxSize, Rand); break; case 4: Size = Mutate_ShuffleBytes(Data, Size, MaxSize); break;
} }
assert(Size > 0); assert(Size > 0);
return Size; return Size;

View File

@ -12,6 +12,7 @@ extern "C" void LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
TEST(Fuzzer, CrossOver) { TEST(Fuzzer, CrossOver) {
FuzzerRandomLibc Rand(0); FuzzerRandomLibc Rand(0);
MutationDispatcher MD(Rand);
Unit A({0, 1, 2}), B({5, 6, 7}); Unit A({0, 1, 2}), B({5, 6, 7});
Unit C; Unit C;
Unit Expected[] = { Unit Expected[] = {
@ -54,8 +55,8 @@ TEST(Fuzzer, CrossOver) {
std::set<Unit> FoundUnits, ExpectedUnitsWitThisLength; std::set<Unit> FoundUnits, ExpectedUnitsWitThisLength;
for (int Iter = 0; Iter < 3000; Iter++) { for (int Iter = 0; Iter < 3000; Iter++) {
C.resize(Len); C.resize(Len);
size_t NewSize = CrossOver(A.data(), A.size(), B.data(), B.size(), size_t NewSize = MD.CrossOver(A.data(), A.size(), B.data(), B.size(),
C.data(), C.size(), Rand); C.data(), C.size());
C.resize(NewSize); C.resize(NewSize);
FoundUnits.insert(C); FoundUnits.insert(C);
} }
@ -74,8 +75,8 @@ TEST(Fuzzer, Hash) {
EXPECT_EQ("81fe8bfe87576c3ecb22426f8e57847382917acf", fuzzer::Hash(U)); EXPECT_EQ("81fe8bfe87576c3ecb22426f8e57847382917acf", fuzzer::Hash(U));
} }
typedef size_t (*Mutator)(uint8_t *Data, size_t Size, size_t MaxSize, typedef size_t (MutationDispatcher::*Mutator)(uint8_t *Data, size_t Size,
FuzzerRandomBase &Rand); size_t MaxSize);
void TestEraseByte(Mutator M, int NumIter) { void TestEraseByte(Mutator M, int NumIter) {
uint8_t REM0[8] = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77}; uint8_t REM0[8] = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
@ -87,10 +88,11 @@ void TestEraseByte(Mutator M, int NumIter) {
uint8_t REM6[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x77}; uint8_t REM6[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x77};
uint8_t REM7[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66}; uint8_t REM7[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66};
FuzzerRandomLibc Rand(0); FuzzerRandomLibc Rand(0);
MutationDispatcher MD(Rand);
int FoundMask = 0; int FoundMask = 0;
for (int i = 0; i < NumIter; i++) { for (int i = 0; i < NumIter; i++) {
uint8_t T[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77}; uint8_t T[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
size_t NewSize = M(T, sizeof(T), sizeof(T), Rand); size_t NewSize = (MD.*M)(T, sizeof(T), sizeof(T));
if (NewSize == 7 && !memcmp(REM0, T, 7)) FoundMask |= 1 << 0; if (NewSize == 7 && !memcmp(REM0, T, 7)) FoundMask |= 1 << 0;
if (NewSize == 7 && !memcmp(REM1, T, 7)) FoundMask |= 1 << 1; if (NewSize == 7 && !memcmp(REM1, T, 7)) FoundMask |= 1 << 1;
if (NewSize == 7 && !memcmp(REM2, T, 7)) FoundMask |= 1 << 2; if (NewSize == 7 && !memcmp(REM2, T, 7)) FoundMask |= 1 << 2;
@ -103,11 +105,12 @@ void TestEraseByte(Mutator M, int NumIter) {
EXPECT_EQ(FoundMask, 255); EXPECT_EQ(FoundMask, 255);
} }
TEST(FuzzerMutate, EraseByte1) { TestEraseByte(Mutate_EraseByte, 100); } TEST(FuzzerMutate, EraseByte1) { TestEraseByte(&MutationDispatcher::Mutate_EraseByte, 100); }
TEST(FuzzerMutate, EraseByte2) { TestEraseByte(Mutate, 1000); } TEST(FuzzerMutate, EraseByte2) { TestEraseByte(&MutationDispatcher::Mutate, 1000); }
void TestInsertByte(Mutator M, int NumIter) { void TestInsertByte(Mutator M, int NumIter) {
FuzzerRandomLibc Rand(0); FuzzerRandomLibc Rand(0);
MutationDispatcher MD(Rand);
int FoundMask = 0; int FoundMask = 0;
uint8_t INS0[8] = {0xF1, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66}; uint8_t INS0[8] = {0xF1, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66};
uint8_t INS1[8] = {0x00, 0xF2, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66}; uint8_t INS1[8] = {0x00, 0xF2, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66};
@ -119,7 +122,7 @@ void TestInsertByte(Mutator M, int NumIter) {
uint8_t INS7[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0xF8}; uint8_t INS7[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0xF8};
for (int i = 0; i < NumIter; i++) { for (int i = 0; i < NumIter; i++) {
uint8_t T[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66}; uint8_t T[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66};
size_t NewSize = M(T, 7, 8, Rand); size_t NewSize = (MD.*M)(T, 7, 8);
if (NewSize == 8 && !memcmp(INS0, T, 8)) FoundMask |= 1 << 0; if (NewSize == 8 && !memcmp(INS0, T, 8)) FoundMask |= 1 << 0;
if (NewSize == 8 && !memcmp(INS1, T, 8)) FoundMask |= 1 << 1; if (NewSize == 8 && !memcmp(INS1, T, 8)) FoundMask |= 1 << 1;
if (NewSize == 8 && !memcmp(INS2, T, 8)) FoundMask |= 1 << 2; if (NewSize == 8 && !memcmp(INS2, T, 8)) FoundMask |= 1 << 2;
@ -132,11 +135,12 @@ void TestInsertByte(Mutator M, int NumIter) {
EXPECT_EQ(FoundMask, 255); EXPECT_EQ(FoundMask, 255);
} }
TEST(FuzzerMutate, InsertByte1) { TestInsertByte(Mutate_InsertByte, 1 << 15); } TEST(FuzzerMutate, InsertByte1) { TestInsertByte(&MutationDispatcher::Mutate_InsertByte, 1 << 15); }
TEST(FuzzerMutate, InsertByte2) { TestInsertByte(Mutate, 1 << 17); } TEST(FuzzerMutate, InsertByte2) { TestInsertByte(&MutationDispatcher::Mutate, 1 << 17); }
void TestChangeByte(Mutator M, int NumIter) { void TestChangeByte(Mutator M, int NumIter) {
FuzzerRandomLibc Rand(0); FuzzerRandomLibc Rand(0);
MutationDispatcher MD(Rand);
int FoundMask = 0; int FoundMask = 0;
uint8_t CH0[8] = {0xF0, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77}; uint8_t CH0[8] = {0xF0, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
uint8_t CH1[8] = {0x00, 0xF1, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77}; uint8_t CH1[8] = {0x00, 0xF1, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
@ -148,7 +152,7 @@ void TestChangeByte(Mutator M, int NumIter) {
uint8_t CH7[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0xF7}; uint8_t CH7[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0xF7};
for (int i = 0; i < NumIter; i++) { for (int i = 0; i < NumIter; i++) {
uint8_t T[9] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77}; uint8_t T[9] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
size_t NewSize = M(T, 8, 9, Rand); size_t NewSize = (MD.*M)(T, 8, 9);
if (NewSize == 8 && !memcmp(CH0, T, 8)) FoundMask |= 1 << 0; if (NewSize == 8 && !memcmp(CH0, T, 8)) FoundMask |= 1 << 0;
if (NewSize == 8 && !memcmp(CH1, T, 8)) FoundMask |= 1 << 1; if (NewSize == 8 && !memcmp(CH1, T, 8)) FoundMask |= 1 << 1;
if (NewSize == 8 && !memcmp(CH2, T, 8)) FoundMask |= 1 << 2; if (NewSize == 8 && !memcmp(CH2, T, 8)) FoundMask |= 1 << 2;
@ -161,11 +165,12 @@ void TestChangeByte(Mutator M, int NumIter) {
EXPECT_EQ(FoundMask, 255); EXPECT_EQ(FoundMask, 255);
} }
TEST(FuzzerMutate, ChangeByte1) { TestChangeByte(Mutate_ChangeByte, 1 << 15); } TEST(FuzzerMutate, ChangeByte1) { TestChangeByte(&MutationDispatcher::Mutate_ChangeByte, 1 << 15); }
TEST(FuzzerMutate, ChangeByte2) { TestChangeByte(Mutate, 1 << 17); } TEST(FuzzerMutate, ChangeByte2) { TestChangeByte(&MutationDispatcher::Mutate, 1 << 17); }
void TestChangeBit(Mutator M, int NumIter) { void TestChangeBit(Mutator M, int NumIter) {
FuzzerRandomLibc Rand(0); FuzzerRandomLibc Rand(0);
MutationDispatcher MD(Rand);
int FoundMask = 0; int FoundMask = 0;
uint8_t CH0[8] = {0x01, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77}; uint8_t CH0[8] = {0x01, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
uint8_t CH1[8] = {0x00, 0x13, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77}; uint8_t CH1[8] = {0x00, 0x13, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
@ -177,7 +182,7 @@ void TestChangeBit(Mutator M, int NumIter) {
uint8_t CH7[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0xF7}; uint8_t CH7[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0xF7};
for (int i = 0; i < NumIter; i++) { for (int i = 0; i < NumIter; i++) {
uint8_t T[9] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77}; uint8_t T[9] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
size_t NewSize = M(T, 8, 9, Rand); size_t NewSize = (MD.*M)(T, 8, 9);
if (NewSize == 8 && !memcmp(CH0, T, 8)) FoundMask |= 1 << 0; if (NewSize == 8 && !memcmp(CH0, T, 8)) FoundMask |= 1 << 0;
if (NewSize == 8 && !memcmp(CH1, T, 8)) FoundMask |= 1 << 1; if (NewSize == 8 && !memcmp(CH1, T, 8)) FoundMask |= 1 << 1;
if (NewSize == 8 && !memcmp(CH2, T, 8)) FoundMask |= 1 << 2; if (NewSize == 8 && !memcmp(CH2, T, 8)) FoundMask |= 1 << 2;
@ -190,11 +195,12 @@ void TestChangeBit(Mutator M, int NumIter) {
EXPECT_EQ(FoundMask, 255); EXPECT_EQ(FoundMask, 255);
} }
TEST(FuzzerMutate, ChangeBit1) { TestChangeBit(Mutate_ChangeBit, 1 << 16); } TEST(FuzzerMutate, ChangeBit1) { TestChangeBit(&MutationDispatcher::Mutate_ChangeBit, 1 << 16); }
TEST(FuzzerMutate, ChangeBit2) { TestChangeBit(Mutate, 1 << 18); } TEST(FuzzerMutate, ChangeBit2) { TestChangeBit(&MutationDispatcher::Mutate, 1 << 18); }
void TestShuffleBytes(Mutator M, int NumIter) { void TestShuffleBytes(Mutator M, int NumIter) {
FuzzerRandomLibc Rand(0); FuzzerRandomLibc Rand(0);
MutationDispatcher MD(Rand);
int FoundMask = 0; int FoundMask = 0;
uint8_t CH0[7] = {0x00, 0x22, 0x11, 0x33, 0x44, 0x55, 0x66}; uint8_t CH0[7] = {0x00, 0x22, 0x11, 0x33, 0x44, 0x55, 0x66};
uint8_t CH1[7] = {0x11, 0x00, 0x33, 0x22, 0x44, 0x55, 0x66}; uint8_t CH1[7] = {0x11, 0x00, 0x33, 0x22, 0x44, 0x55, 0x66};
@ -203,7 +209,7 @@ void TestShuffleBytes(Mutator M, int NumIter) {
uint8_t CH4[7] = {0x00, 0x11, 0x22, 0x33, 0x55, 0x44, 0x66}; uint8_t CH4[7] = {0x00, 0x11, 0x22, 0x33, 0x55, 0x44, 0x66};
for (int i = 0; i < NumIter; i++) { for (int i = 0; i < NumIter; i++) {
uint8_t T[7] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66}; uint8_t T[7] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66};
size_t NewSize = M(T, 7, 7, Rand); size_t NewSize = (MD.*M)(T, 7, 7);
if (NewSize == 7 && !memcmp(CH0, T, 7)) FoundMask |= 1 << 0; if (NewSize == 7 && !memcmp(CH0, T, 7)) FoundMask |= 1 << 0;
if (NewSize == 7 && !memcmp(CH1, T, 7)) FoundMask |= 1 << 1; if (NewSize == 7 && !memcmp(CH1, T, 7)) FoundMask |= 1 << 1;
if (NewSize == 7 && !memcmp(CH2, T, 7)) FoundMask |= 1 << 2; if (NewSize == 7 && !memcmp(CH2, T, 7)) FoundMask |= 1 << 2;
@ -213,8 +219,8 @@ void TestShuffleBytes(Mutator M, int NumIter) {
EXPECT_EQ(FoundMask, 31); EXPECT_EQ(FoundMask, 31);
} }
TEST(FuzzerMutate, ShuffleBytes1) { TestShuffleBytes(Mutate_ShuffleBytes, 1 << 15); } TEST(FuzzerMutate, ShuffleBytes1) { TestShuffleBytes(&MutationDispatcher::Mutate_ShuffleBytes, 1 << 15); }
TEST(FuzzerMutate, ShuffleBytes2) { TestShuffleBytes(Mutate, 1 << 16); } TEST(FuzzerMutate, ShuffleBytes2) { TestShuffleBytes(&MutationDispatcher::Mutate, 1 << 16); }
TEST(FuzzerDictionary, ParseOneDictionaryEntry) { TEST(FuzzerDictionary, ParseOneDictionaryEntry) {
Unit U; Unit U;