// Copyright 2013 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 <stdlib.h>
#include <algorithm>
#include <iostream>
#include <ostream>
#include <set>
#include <string>
#include <vector>
#include "base/command_line.h"
#include "base/pickle.h"
#include "base/strings/string_split.h"
#include "base/strings/string_util.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/utf_string_conversions.h"
#include "ipc/ipc_message.h"
#include "ipc/ipc_message_utils.h"
#include "ipc/ipc_switches.h"
#include "ipc/ipc_sync_channel.h"
#include "ipc/ipc_sync_message.h"
#include "tools/ipc_fuzzer/message_lib/all_messages.h"
#include "tools/ipc_fuzzer/message_lib/message_cracker.h"
#include "tools/ipc_fuzzer/message_lib/message_file.h"
#include "tools/ipc_fuzzer/mutate/rand_util.h"
#if defined(OS_POSIX)
#include <unistd.h>
#endif
namespace IPC {
class Message;
} // namespace IPC
namespace ipc_fuzzer {
// Interface implemented by those who fuzz basic types. The types all
// correspond to the types which a pickle from base/pickle.h can pickle,
// plus the floating point types.
class Fuzzer {
public:
// Tweak individual values within a message.
virtual void FuzzBool(bool* value) = 0;
virtual void FuzzInt(int* value) = 0;
virtual void FuzzLong(long* value) = 0;
virtual void FuzzSize(size_t* value) = 0;
virtual void FuzzUChar(unsigned char *value) = 0;
virtual void FuzzUInt16(uint16* value) = 0;
virtual void FuzzUInt32(uint32* value) = 0;
virtual void FuzzInt64(int64* value) = 0;
virtual void FuzzUInt64(uint64* value) = 0;
virtual void FuzzFloat(float *value) = 0;
virtual void FuzzDouble(double *value) = 0;
virtual void FuzzString(std::string* value) = 0;
virtual void FuzzString16(base::string16* value) = 0;
virtual void FuzzData(char* data, int length) = 0;
virtual void FuzzBytes(void* data, int data_len) = 0;
};
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;
}
}
}
// One such fuzzer implementation.
class DefaultFuzzer : public Fuzzer {
public:
DefaultFuzzer(int frequency) : frequency_(frequency) {
}
virtual ~DefaultFuzzer() {}
virtual void FuzzBool(bool* value) OVERRIDE {
if (RandEvent(frequency_))
(*value) = !(*value);
}
virtual void FuzzInt(int* value) OVERRIDE {
FuzzIntegralType<int>(value, frequency_);
}
virtual void FuzzLong(long* value) OVERRIDE {
FuzzIntegralType<long>(value, frequency_);
}
virtual void FuzzSize(size_t* value) OVERRIDE {
FuzzIntegralType<size_t>(value, frequency_);
}
virtual void FuzzUChar(unsigned char* value) OVERRIDE {
FuzzIntegralType<unsigned char>(value, frequency_);
}
virtual void FuzzUInt16(uint16* value) OVERRIDE {
FuzzIntegralType<uint16>(value, frequency_);
}
virtual void FuzzUInt32(uint32* value) OVERRIDE {
FuzzIntegralType<uint32>(value, frequency_);
}
virtual void FuzzInt64(int64* value) OVERRIDE {
FuzzIntegralType<int64>(value, frequency_);
}
virtual void FuzzUInt64(uint64* value) OVERRIDE {
FuzzIntegralType<uint64>(value, frequency_);
}
virtual void FuzzFloat(float* value) OVERRIDE {
if (RandEvent(frequency_))
*value = RandDouble();
}
virtual void FuzzDouble(double* value) OVERRIDE {
if (RandEvent(frequency_))
*value = RandDouble();
}
virtual void FuzzString(std::string* value) OVERRIDE {
FuzzStringType<std::string>(value, frequency_, "BORKED", std::string());
}
virtual void FuzzString16(base::string16* value) OVERRIDE {
FuzzStringType<base::string16>(value, frequency_,
base::WideToUTF16(L"BORKED"),
base::WideToUTF16(L""));
}
virtual void FuzzData(char* data, int length) OVERRIDE {
if (RandEvent(frequency_)) {
for (int i = 0; i < length; ++i) {
FuzzIntegralType<char>(&data[i], frequency_);
}
}
}
virtual void FuzzBytes(void* data, int data_len) OVERRIDE {
FuzzData(static_cast<char*>(data), data_len);
}
private:
unsigned int frequency_;
};
// No-op fuzzer. Rewrites each message unchanged to check if the message
// re-assembly is legit.
class NoOpFuzzer : public Fuzzer {
public:
NoOpFuzzer() {}
virtual ~NoOpFuzzer() {}
virtual void FuzzBool(bool* value) OVERRIDE {}
virtual void FuzzInt(int* value) OVERRIDE {}
virtual void FuzzLong(long* value) OVERRIDE {}
virtual void FuzzSize(size_t* value) OVERRIDE {}
virtual void FuzzUChar(unsigned char* value) OVERRIDE {}
virtual void FuzzUInt16(uint16* value) OVERRIDE {}
virtual void FuzzUInt32(uint32* value) OVERRIDE {}
virtual void FuzzInt64(int64* value) OVERRIDE {}
virtual void FuzzUInt64(uint64* value) OVERRIDE {}
virtual void FuzzFloat(float* value) OVERRIDE {}
virtual void FuzzDouble(double* value) OVERRIDE {}
virtual void FuzzString(std::string* value) OVERRIDE {}
virtual void FuzzString16(base::string16* value) OVERRIDE {}
virtual void FuzzData(char* data, int length) OVERRIDE {}
virtual void FuzzBytes(void* data, int data_len) OVERRIDE {}
};
class FuzzerFactory {
public:
static Fuzzer *Create(const std::string& name, int frequency) {
if (name == "no-op")
return new NoOpFuzzer();
if (name == "default")
return new DefaultFuzzer(frequency);
std::cerr << "No such fuzzer: " << name << "\n";
return 0;
}
};
// Partially-specialized class that knows how to fuzz a given type.
template <class P>
struct FuzzTraits {
static void Fuzz(P* p, Fuzzer *fuzzer) {
// This is the catch-all for types we don't have enough information
// to fuzz. It simply does nothing to the type. We might want to
// change it to randomly flip a bit in the range (p, p+sizeof(P)).
}
};
// Template function to invoke partially-specialized class method.
template <class P>
static void FuzzParam(P* p, Fuzzer* fuzzer) {
FuzzTraits<P>::Fuzz(p, fuzzer);
}
// Specializations to fuzz primitive types.
template <>
struct FuzzTraits<bool> {
static void Fuzz(bool* p, Fuzzer* fuzzer) {
fuzzer->FuzzBool(p);
}
};
template <>
struct FuzzTraits<int> {
static void Fuzz(int* p, Fuzzer* fuzzer) {
fuzzer->FuzzInt(p);
}
};
template <>
struct FuzzTraits<unsigned int> {
static void Fuzz(unsigned int* p, Fuzzer* fuzzer) {
fuzzer->FuzzInt(reinterpret_cast<int*>(p));
}
};
template <>
struct FuzzTraits<long> {
static void Fuzz(long* p, Fuzzer* fuzzer) {
fuzzer->FuzzLong(p);
}
};
template <>
struct FuzzTraits<unsigned long> {
static void Fuzz(unsigned long* p, Fuzzer* fuzzer) {
fuzzer->FuzzLong(reinterpret_cast<long*>(p));
}
};
template <>
struct FuzzTraits<long long> {
static void Fuzz(long long* p, Fuzzer* fuzzer) {
fuzzer->FuzzInt64(reinterpret_cast<int64*>(p));
}
};
template <>
struct FuzzTraits<unsigned long long> {
static void Fuzz(unsigned long long* p, Fuzzer* fuzzer) {
fuzzer->FuzzInt64(reinterpret_cast<int64*>(p));
}
};
template <>
struct FuzzTraits<short> {
static void Fuzz(short* p, Fuzzer* fuzzer) {
fuzzer->FuzzUInt16(reinterpret_cast<uint16*>(p));
}
};
template <>
struct FuzzTraits<unsigned short> {
static void Fuzz(unsigned short* p, Fuzzer* fuzzer) {
fuzzer->FuzzUInt16(reinterpret_cast<uint16*>(p));
}
};
template <>
struct FuzzTraits<char> {
static void Fuzz(char* p, Fuzzer* fuzzer) {
fuzzer->FuzzUChar(reinterpret_cast<unsigned char*>(p));
}
};
template <>
struct FuzzTraits<unsigned char> {
static void Fuzz(unsigned char* p, Fuzzer* fuzzer) {
fuzzer->FuzzUChar(p);
}
};
template <>
struct FuzzTraits<float> {
static void Fuzz(float* p, Fuzzer* fuzzer) {
fuzzer->FuzzFloat(p);
}
};
template <>
struct FuzzTraits<double> {
static void Fuzz(double* p, Fuzzer* fuzzer) {
fuzzer->FuzzDouble(p);
}
};
template <>
struct FuzzTraits<std::string> {
static void Fuzz(std::string* p, Fuzzer* fuzzer) {
fuzzer->FuzzString(p);
}
};
template <>
struct FuzzTraits<base::string16> {
static void Fuzz(base::string16* p, Fuzzer* fuzzer) {
fuzzer->FuzzString16(p);
}
};
// Specializations to fuzz tuples.
template <class A>
struct FuzzTraits<Tuple1<A> > {
static void Fuzz(Tuple1<A>* p, Fuzzer* fuzzer) {
FuzzParam(&p->a, fuzzer);
}
};
template <class A, class B>
struct FuzzTraits<Tuple2<A, B> > {
static void Fuzz(Tuple2<A, B>* p, Fuzzer* fuzzer) {
FuzzParam(&p->a, fuzzer);
FuzzParam(&p->b, fuzzer);
}
};
template <class A, class B, class C>
struct FuzzTraits<Tuple3<A, B, C> > {
static void Fuzz(Tuple3<A, B, C>* p, Fuzzer* fuzzer) {
FuzzParam(&p->a, fuzzer);
FuzzParam(&p->b, fuzzer);
FuzzParam(&p->c, fuzzer);
}
};
template <class A, class B, class C, class D>
struct FuzzTraits<Tuple4<A, B, C, D> > {
static void Fuzz(Tuple4<A, B, C, D>* p, Fuzzer* fuzzer) {
FuzzParam(&p->a, fuzzer);
FuzzParam(&p->b, fuzzer);
FuzzParam(&p->c, fuzzer);
FuzzParam(&p->d, fuzzer);
}
};
template <class A, class B, class C, class D, class E>
struct FuzzTraits<Tuple5<A, B, C, D, E> > {
static void Fuzz(Tuple5<A, B, C, D, E>* p, Fuzzer* fuzzer) {
FuzzParam(&p->a, fuzzer);
FuzzParam(&p->b, fuzzer);
FuzzParam(&p->c, fuzzer);
FuzzParam(&p->d, fuzzer);
FuzzParam(&p->e, fuzzer);
}
};
// Specializations to fuzz containers.
template <class A>
struct FuzzTraits<std::vector<A> > {
static void Fuzz(std::vector<A>* p, Fuzzer* fuzzer) {
for (size_t i = 0; i < p->size(); ++i) {
FuzzParam(&p->at(i), fuzzer);
}
}
};
template <class A, class B>
struct FuzzTraits<std::map<A, B> > {
static void Fuzz(std::map<A, B>* p, Fuzzer* fuzzer) {
typename std::map<A, B>::iterator it;
for (it = p->begin(); it != p->end(); ++it) {
FuzzParam(&it->second, fuzzer);
}
}
};
template <class A, class B>
struct FuzzTraits<std::pair<A, B> > {
static void Fuzz(std::pair<A, B>* p, Fuzzer* fuzzer) {
FuzzParam(&p->second, fuzzer);
}
};
// Specializations to fuzz hand-coded tyoes
template <>
struct FuzzTraits<base::FileDescriptor> {
static void Fuzz(base::FileDescriptor* p, Fuzzer* fuzzer) {
FuzzParam(&p->fd, fuzzer);
}
};
template <>
struct FuzzTraits<GURL> {
static void Fuzz(GURL *p, Fuzzer* fuzzer) {
FuzzParam(&p->possibly_invalid_spec(), fuzzer);
}
};
template <>
struct FuzzTraits<gfx::Point> {
static void Fuzz(gfx::Point *p, Fuzzer* fuzzer) {
int x = p->x();
int y = p->y();
FuzzParam(&x, fuzzer);
FuzzParam(&y, fuzzer);
p->SetPoint(x, y);
}
};
template <>
struct FuzzTraits<gfx::Size> {
static void Fuzz(gfx::Size *p, Fuzzer* fuzzer) {
int w = p->width();
int h = p->height();
FuzzParam(&w, fuzzer);
FuzzParam(&h, fuzzer);
p->SetSize(w, h);
}
};
template <>
struct FuzzTraits<gfx::Rect> {
static void Fuzz(gfx::Rect *p, Fuzzer* fuzzer) {
gfx::Point origin = p->origin();
gfx::Size size = p->size();
FuzzParam(&origin, fuzzer);
FuzzParam(&size, fuzzer);
p->set_origin(origin);
p->set_size(size);
}
};
// Redefine macros to generate fuzzing from traits declarations.
// Null out all the macros that need nulling.
#include "ipc/ipc_message_null_macros.h"
// STRUCT declarations cause corresponding STRUCT_TRAITS declarations to occur.
#undef IPC_STRUCT_BEGIN
#undef IPC_STRUCT_BEGIN_WITH_PARENT
#undef IPC_STRUCT_MEMBER
#undef IPC_STRUCT_END
#define IPC_STRUCT_BEGIN_WITH_PARENT(struct_name, parent) \
IPC_STRUCT_BEGIN(struct_name)
#define IPC_STRUCT_BEGIN(struct_name) IPC_STRUCT_TRAITS_BEGIN(struct_name)
#define IPC_STRUCT_MEMBER(type, name, ...) IPC_STRUCT_TRAITS_MEMBER(name)
#define IPC_STRUCT_END() IPC_STRUCT_TRAITS_END()
// Set up so next include will generate fuzz trait classes.
#undef IPC_STRUCT_TRAITS_BEGIN
#undef IPC_STRUCT_TRAITS_MEMBER
#undef IPC_STRUCT_TRAITS_PARENT
#undef IPC_STRUCT_TRAITS_END
#define IPC_STRUCT_TRAITS_BEGIN(struct_name) \
template <> \
struct FuzzTraits<struct_name> { \
static void Fuzz(struct_name *p, Fuzzer* fuzzer) {
#define IPC_STRUCT_TRAITS_MEMBER(name) \
FuzzParam(&p->name, fuzzer);
#define IPC_STRUCT_TRAITS_PARENT(type) \
FuzzParam(static_cast<type*>(p), fuzzer);
#define IPC_STRUCT_TRAITS_END() \
} \
};
// TODO(tsepez): Make sure to end up with an enum that meets |condition|.
#undef IPC_ENUM_TRAITS_VALIDATE
#define IPC_ENUM_TRAITS_VALIDATE(enum_name, conditon) \
template <> \
struct FuzzTraits<enum_name> { \
static void Fuzz(enum_name* p, Fuzzer* fuzzer) { \
FuzzParam(reinterpret_cast<int*>(p), fuzzer); \
} \
};
// Bring them into existence.
#include "tools/ipc_fuzzer/message_lib/all_messages.h"
// Redefine macros to generate fuzzing funtions
#include "ipc/ipc_message_null_macros.h"
#undef IPC_MESSAGE_DECL
#define IPC_MESSAGE_DECL(kind, type, name, in, out, ilist, olist) \
IPC_##kind##_##type##_FUZZ(name, in, out, ilist, olist)
#define IPC_EMPTY_CONTROL_FUZZ(name, in, out, ilist, olist) \
IPC::Message* fuzzer_for_##name(IPC::Message *msg, Fuzzer* fuzzer) { \
return NULL; \
}
#define IPC_EMPTY_ROUTED_FUZZ(name, in, out, ilist, olist) \
IPC::Message* fuzzer_for_##name(IPC::Message *msg, Fuzzer* fuzzer) { \
return NULL; \
}
#define IPC_ASYNC_CONTROL_FUZZ(name, in, out, ilist, olist) \
IPC::Message* fuzzer_for_##name(IPC::Message *msg, Fuzzer* fuzzer) { \
name* real_msg = static_cast<name*>(msg); \
IPC_TUPLE_IN_##in ilist p; \
name::Read(real_msg, &p); \
FuzzParam(&p, fuzzer); \
return new name(IPC_MEMBERS_IN_##in(p)); \
}
#define IPC_ASYNC_ROUTED_FUZZ(name, in, out, ilist, olist) \
IPC::Message* fuzzer_for_##name(IPC::Message *msg, Fuzzer* fuzzer) { \
name* real_msg = static_cast<name*>(msg); \
IPC_TUPLE_IN_##in ilist p; \
name::Read(real_msg, &p); \
FuzzParam(&p, fuzzer); \
return new name(msg->routing_id() \
IPC_COMMA_##in \
IPC_MEMBERS_IN_##in(p)); \
}
#define IPC_SYNC_CONTROL_FUZZ(name, in, out, ilist, olist) \
IPC::Message* fuzzer_for_##name(IPC::Message *msg, Fuzzer* fuzzer) { \
name* real_msg = static_cast<name*>(msg); \
IPC_TUPLE_IN_##in ilist p; \
name::ReadSendParam(real_msg, &p); \
FuzzParam(&p, fuzzer); \
name* new_msg = new name(IPC_MEMBERS_IN_##in(p) \
IPC_COMMA_AND_##out(IPC_COMMA_##in) \
IPC_MEMBERS_OUT_##out()); \
MessageCracker::CopyMessageID(new_msg, real_msg); \
return new_msg; \
}
#define IPC_SYNC_ROUTED_FUZZ(name, in, out, ilist, olist) \
IPC::Message* fuzzer_for_##name(IPC::Message *msg, Fuzzer* fuzzer) { \
name* real_msg = static_cast<name*>(msg); \
IPC_TUPLE_IN_##in ilist p; \
name::ReadSendParam(real_msg, &p); \
FuzzParam(&p, fuzzer); \
name* new_msg = new name(msg->routing_id() \
IPC_COMMA_OR_##out(IPC_COMMA_##in) \
IPC_MEMBERS_IN_##in(p) \
IPC_COMMA_AND_##out(IPC_COMMA_##in) \
IPC_MEMBERS_OUT_##out()); \
MessageCracker::CopyMessageID(new_msg, real_msg); \
return new_msg; \
}
#define IPC_MEMBERS_IN_0(p)
#define IPC_MEMBERS_IN_1(p) p.a
#define IPC_MEMBERS_IN_2(p) p.a, p.b
#define IPC_MEMBERS_IN_3(p) p.a, p.b, p.c
#define IPC_MEMBERS_IN_4(p) p.a, p.b, p.c, p.d
#define IPC_MEMBERS_IN_5(p) p.a, p.b, p.c, p.d, p.e
#define IPC_MEMBERS_OUT_0()
#define IPC_MEMBERS_OUT_1() NULL
#define IPC_MEMBERS_OUT_2() NULL, NULL
#define IPC_MEMBERS_OUT_3() NULL, NULL, NULL
#define IPC_MEMBERS_OUT_4() NULL, NULL, NULL, NULL
#define IPC_MEMBERS_OUT_5() NULL, NULL, NULL, NULL, NULL
#include "tools/ipc_fuzzer/message_lib/all_messages.h"
typedef IPC::Message* (*FuzzFunction)(IPC::Message*, Fuzzer*);
typedef base::hash_map<uint32, FuzzFunction> FuzzFunctionMap;
// Redefine macros to register fuzzing functions into map.
#include "ipc/ipc_message_null_macros.h"
#undef IPC_MESSAGE_DECL
#define IPC_MESSAGE_DECL(kind, type, name, in, out, ilist, olist) \
(*map)[static_cast<uint32>(name::ID)] = fuzzer_for_##name;
void PopulateFuzzFunctionMap(FuzzFunctionMap *map) {
#include "tools/ipc_fuzzer/message_lib/all_messages.h"
}
static IPC::Message* RewriteMessage(
IPC::Message* message,
Fuzzer* fuzzer,
FuzzFunctionMap* map) {
FuzzFunctionMap::iterator it = map->find(message->type());
if (it == map->end()) {
// This usually indicates a missing message file in all_messages.h, or
// that the message dump file is taken from a different revision of
// chromium from this executable.
std::cerr << "Unknown message type: ["
<< IPC_MESSAGE_ID_CLASS(message->type()) << ", "
<< IPC_MESSAGE_ID_LINE(message->type()) << "].\n";
return 0;
}
return (*it->second)(message, fuzzer);
}
namespace {
const char kHelpSwitch[] = "help";
const char kHelpSwitchHelp[] =
"show this message";
const char kFrequencySwitch[] = "frequency";
const char kFrequencySwitchHelp[] =
"probability of mutation; tweak every 1/|q| times.";
const char kFuzzerNameSwitch[] = "fuzzer-name";
const char kFuzzerNameSwitchHelp[] =
"select default or no-op fuzzer.";
const char kPermuteSwitch[] = "permute";
const char kPermuteSwitchHelp[] =
"Randomly shuffle the order of all messages.";
const char kTypeListSwitch[] = "type-list";
const char kTypeListSwitchHelp[] =
"explicit list of the only message-ids to mutate.";
void usage() {
std::cerr << "Mutate messages from an exiting message file.\n";
std::cerr << "Usage:\n"
<< " ipc_fuzzer_mutate"
<< " [--" << kHelpSwitch << "]"
<< " [--" << kFuzzerNameSwitch << "=f]"
<< " [--" << kFrequencySwitch << "=q]"
<< " [--" << kTypeListSwitch << "=x,y,z...]"
<< " [--" << kPermuteSwitch << "]"
<< " infile outfile\n";
std::cerr
<< " --" << kHelpSwitch << " - " << kHelpSwitchHelp << "\n"
<< " --" << kFuzzerNameSwitch << " - " << kFuzzerNameSwitchHelp << "\n"
<< " --" << kFrequencySwitch << " - " << kFrequencySwitchHelp << "\n"
<< " --" << kTypeListSwitch << " - " << kTypeListSwitchHelp << "\n"
<< " --" << kPermuteSwitch << " - " << kPermuteSwitchHelp << "\n";
}
} // namespace
int MutateMain(int argc, char** argv) {
CommandLine::Init(argc, argv);
CommandLine* cmd = CommandLine::ForCurrentProcess();
CommandLine::StringVector args = cmd->GetArgs();
if (args.size() != 2 || cmd->HasSwitch(kHelpSwitch)) {
usage();
return EXIT_FAILURE;
}
std::string input_file_name = args[0];
std::string output_file_name = args[1];
bool permute = cmd->HasSwitch(kPermuteSwitch);
std::string fuzzer_name = "default";
if (cmd->HasSwitch(kFuzzerNameSwitch))
fuzzer_name = cmd->GetSwitchValueASCII(kFuzzerNameSwitch);
int frequency = 23;
if (cmd->HasSwitch(kFrequencySwitch))
frequency = atoi(cmd->GetSwitchValueASCII(kFrequencySwitch).c_str());
std::string type_string_list = cmd->GetSwitchValueASCII(kTypeListSwitch);
std::vector<std::string> type_string_vector;
base::SplitString(type_string_list, ',', &type_string_vector);
std::set<int> type_set;
for (size_t i = 0; i < type_string_vector.size(); ++i) {
type_set.insert(atoi(type_string_vector[i].c_str()));
}
InitRand();
Fuzzer* fuzzer = FuzzerFactory::Create(fuzzer_name, frequency);
if (!fuzzer)
return EXIT_FAILURE;
FuzzFunctionMap fuzz_function_map;
PopulateFuzzFunctionMap(&fuzz_function_map);
MessageVector message_vector;
if (!MessageFile::Read(base::FilePath(input_file_name), &message_vector))
return EXIT_FAILURE;
for (size_t i = 0; i < message_vector.size(); ++i) {
IPC::Message* msg = message_vector[i];
if (!type_set.empty() && type_set.end() == std::find(
type_set.begin(), type_set.end(), msg->type())) {
continue;
}
IPC::Message* new_message = RewriteMessage(msg, fuzzer, &fuzz_function_map);
if (new_message) {
delete message_vector[i];
message_vector[i] = new_message;
}
}
if (permute) {
std::random_shuffle(message_vector.begin(), message_vector.end(),
RandInRange);
}
if (!MessageFile::Write(base::FilePath(output_file_name), message_vector))
return EXIT_FAILURE;
return EXIT_SUCCESS;
}
} // namespace ipc_fuzzer
int main(int argc, char** argv) {
return ipc_fuzzer::MutateMain(argc, argv);
}