blob: 6e74d205d91f045180de0b19a533c024824d3fd0 [file] [log] [blame]
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <algorithm>
#include <string>
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "tools/ipc_fuzzer/fuzzer/mutator.h"
#include "tools/ipc_fuzzer/fuzzer/rand_util.h"
namespace ipc_fuzzer {
template <typename T>
void FuzzIntegralType(T* value, unsigned int frequency) {
if (RandEvent(frequency)) {
switch (RandInRange(4)) {
case 0: (*value) = 0; break;
case 1: (*value)--; break;
case 2: (*value)++; break;
case 3: (*value) = RandU64(); break;
}
}
}
template <typename T>
void FuzzStringType(T* value, unsigned int frequency,
const T& literal1, const T& literal2) {
if (RandEvent(frequency)) {
switch (RandInRange(5)) {
case 4: (*value) = (*value) + (*value); FALLTHROUGH;
case 3: (*value) = (*value) + (*value); FALLTHROUGH;
case 2: (*value) = (*value) + (*value); break;
case 1: (*value) += literal1; break;
case 0: (*value) = literal2; break;
}
}
}
void Mutator::FuzzBool(bool* value) {
if (RandEvent(frequency_))
(*value) = !(*value);
}
void Mutator::FuzzInt(int* value) {
FuzzIntegralType<int>(value, frequency_);
}
void Mutator::FuzzLong(long* value) {
FuzzIntegralType<long>(value, frequency_);
}
void Mutator::FuzzSize(size_t* value) {
FuzzIntegralType<size_t>(value, frequency_);
}
void Mutator::FuzzUChar(unsigned char* value) {
FuzzIntegralType<unsigned char>(value, frequency_);
}
void Mutator::FuzzWChar(wchar_t* value) {
FuzzIntegralType<wchar_t>(value, frequency_);
}
void Mutator::FuzzUInt16(uint16_t* value) {
FuzzIntegralType<uint16_t>(value, frequency_);
}
void Mutator::FuzzUInt32(uint32_t* value) {
FuzzIntegralType<uint32_t>(value, frequency_);
}
void Mutator::FuzzInt64(int64_t* value) {
FuzzIntegralType<int64_t>(value, frequency_);
}
void Mutator::FuzzUInt64(uint64_t* value) {
FuzzIntegralType<uint64_t>(value, frequency_);
}
void Mutator::FuzzFloat(float* value) {
if (RandEvent(frequency_))
*value = RandDouble();
}
void Mutator::FuzzDouble(double* value) {
if (RandEvent(frequency_))
*value = RandDouble();
}
void Mutator:: FuzzString(std::string* value) {
FuzzStringType<std::string>(value, frequency_, "BORKED", std::string());
}
void Mutator::FuzzString16(base::string16* value) {
FuzzStringType<base::string16>(value, frequency_,
base::WideToUTF16(L"BORKED"),
base::WideToUTF16(L""));
}
void Mutator::FuzzData(char* data, int length) {
if (RandEvent(frequency_)) {
for (int i = 0; i < length; ++i) {
FuzzIntegralType<char>(&data[i], frequency_);
}
}
}
void Mutator::FuzzBytes(void* data, int data_len) {
FuzzData(static_cast<char*>(data), data_len);
}
bool Mutator::ShouldGenerate() {
// TODO(mbarbella): With a low probability, allow something to be fully
// rewritten while mutating instead of always changing the existing value.
return false;
}
} // namespace ipc_fuzzer