Skip to content
This repository has been archived by the owner on Jan 1, 2023. It is now read-only.

Commit

Permalink
[libFuzzer] add one more mutator: Mutate_ChangeASCIIInteger
Browse files Browse the repository at this point in the history
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@247027 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information
kcc committed Sep 8, 2015
1 parent 2e44fc0 commit 944dec6
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 0 deletions.
2 changes: 2 additions & 0 deletions lib/Fuzzer/FuzzerInterface.h
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,8 @@ class MutationDispatcher {
size_t Mutate_AddWordFromDictionary(uint8_t *Data, size_t Size,
size_t MaxSize);

size_t Mutate_ChangeASCIIInteger(uint8_t *Data, size_t Size, size_t MaxSize);

/// Applies one of the above mutations.
/// Returns the new size of data which could be up to MaxSize.
size_t Mutate(uint8_t *Data, size_t Size, size_t MaxSize);
Expand Down
34 changes: 34 additions & 0 deletions lib/Fuzzer/FuzzerMutate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ struct MutationDispatcher::Impl {
Mutators.push_back(&MutationDispatcher::Mutate_ChangeByte);
Mutators.push_back(&MutationDispatcher::Mutate_ChangeBit);
Mutators.push_back(&MutationDispatcher::Mutate_ShuffleBytes);
Mutators.push_back(&MutationDispatcher::Mutate_ChangeASCIIInteger);
}
void AddWordToDictionary(const uint8_t *Word, size_t Size) {
if (Dictionary.empty()) {
Expand Down Expand Up @@ -116,6 +117,39 @@ size_t MutationDispatcher::Mutate_AddWordFromDictionary(uint8_t *Data,
return Size + Word.size();
}

size_t MutationDispatcher::Mutate_ChangeASCIIInteger(uint8_t *Data, size_t Size,
size_t MaxSize) {
size_t B = Rand(Size);
while (B < Size && !isdigit(Data[B])) B++;
if (B == Size) return 0;
size_t E = B;
while (E < Size && isdigit(Data[E])) E++;
assert(B < E);
// now we have digits in [B, E).
// strtol and friends don't accept non-zero-teminated data, parse it manually.
uint64_t Val = Data[B] - '0';
for (size_t i = B + 1; i < E; i++)
Val = Val * 10 + Data[i] - '0';

// Mutate the integer value.
switch(Rand(5)) {
case 0: Val++; break;
case 1: Val--; break;
case 2: Val /= 2; break;
case 3: Val *= 2; break;
case 4: Val = Rand(Val * Val); break;
default: assert(0);
}
// Just replace the bytes with the new ones, don't bother moving bytes.
for (size_t i = B; i < E; i++) {
size_t Idx = E + B - i - 1;
assert(Idx >= B && Idx < E);
Data[Idx] = (Val % 10) + '0';
Val /= 10;
}
return Size;
}

// Mutates Data in place, returns new size.
size_t MutationDispatcher::Mutate(uint8_t *Data, size_t Size, size_t MaxSize) {
assert(MaxSize > 0);
Expand Down
31 changes: 31 additions & 0 deletions lib/Fuzzer/test/FuzzerUnittest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,37 @@ TEST(FuzzerMutate, AddWordFromDictionary2) {
TestAddWordFromDictionary(&MutationDispatcher::Mutate, 1 << 15);
}

void TestChangeASCIIInteger(Mutator M, int NumIter) {
FuzzerRandomLibc Rand(0);
MutationDispatcher MD(Rand);

uint8_t CH0[8] = {'1', '2', '3', '4', '5', '6', '7', '7'};
uint8_t CH1[8] = {'1', '2', '3', '4', '5', '6', '7', '9'};
uint8_t CH2[8] = {'2', '4', '6', '9', '1', '3', '5', '6'};
uint8_t CH3[8] = {'0', '6', '1', '7', '2', '8', '3', '9'};
int FoundMask = 0;
for (int i = 0; i < NumIter; i++) {
uint8_t T[8] = {'1', '2', '3', '4', '5', '6', '7', '8'};
size_t NewSize = (MD.*M)(T, 8, 8);
/**/ if (NewSize == 8 && !memcmp(CH0, T, 8)) FoundMask |= 1 << 0;
else if (NewSize == 8 && !memcmp(CH1, T, 8)) FoundMask |= 1 << 1;
else if (NewSize == 8 && !memcmp(CH2, T, 8)) FoundMask |= 1 << 2;
else if (NewSize == 8 && !memcmp(CH3, T, 8)) FoundMask |= 1 << 3;
else if (NewSize == 8) FoundMask |= 1 << 4;
}
EXPECT_EQ(FoundMask, 31);
}

TEST(FuzzerMutate, ChangeASCIIInteger1) {
TestChangeASCIIInteger(&MutationDispatcher::Mutate_ChangeASCIIInteger,
1 << 15);
}

TEST(FuzzerMutate, ChangeASCIIInteger2) {
TestChangeASCIIInteger(&MutationDispatcher::Mutate, 1 << 15);
}


TEST(FuzzerDictionary, ParseOneDictionaryEntry) {
Unit U;
EXPECT_FALSE(ParseOneDictionaryEntry("", &U));
Expand Down

0 comments on commit 944dec6

Please # to comment.