1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
14 #include "base/command_line.h"
15 #include "base/pickle.h"
16 #include "base/strings/string_split.h"
17 #include "base/strings/string_util.h"
18 #include "base/strings/string_number_conversions.h"
19 #include "base/strings/utf_string_conversions.h"
20 #include "ipc/ipc_message.h"
21 #include "ipc/ipc_message_utils.h"
22 #include "ipc/ipc_switches.h"
23 #include "ipc/ipc_sync_channel.h"
24 #include "ipc/ipc_sync_message.h"
25 #include "tools/ipc_fuzzer/message_lib/all_messages.h"
26 #include "tools/ipc_fuzzer/message_lib/message_cracker.h"
27 #include "tools/ipc_fuzzer/message_lib/message_file.h"
28 #include "tools/ipc_fuzzer/mutate/rand_util.h"
38 namespace ipc_fuzzer
{
40 // Interface implemented by those who fuzz basic types. The types all
41 // correspond to the types which a pickle from base/pickle.h can pickle,
42 // plus the floating point types.
45 // Tweak individual values within a message.
46 virtual void FuzzBool(bool* value
) = 0;
47 virtual void FuzzInt(int* value
) = 0;
48 virtual void FuzzLong(long* value
) = 0;
49 virtual void FuzzSize(size_t* value
) = 0;
50 virtual void FuzzUChar(unsigned char *value
) = 0;
51 virtual void FuzzUInt16(uint16
* value
) = 0;
52 virtual void FuzzUInt32(uint32
* value
) = 0;
53 virtual void FuzzInt64(int64
* value
) = 0;
54 virtual void FuzzUInt64(uint64
* value
) = 0;
55 virtual void FuzzFloat(float *value
) = 0;
56 virtual void FuzzDouble(double *value
) = 0;
57 virtual void FuzzString(std::string
* value
) = 0;
58 virtual void FuzzString16(base::string16
* value
) = 0;
59 virtual void FuzzData(char* data
, int length
) = 0;
60 virtual void FuzzBytes(void* data
, int data_len
) = 0;
64 void FuzzIntegralType(T
* value
, unsigned int frequency
) {
65 if (RandEvent(frequency
)) {
66 switch (RandInRange(4)) {
67 case 0: (*value
) = 0; break;
68 case 1: (*value
)--; break;
69 case 2: (*value
)++; break;
70 case 3: (*value
) = RandU64(); break;
76 void FuzzStringType(T
* value
, unsigned int frequency
,
77 const T
& literal1
, const T
& literal2
) {
78 if (RandEvent(frequency
)) {
79 switch (RandInRange(5)) {
80 case 4: (*value
) = (*value
) + (*value
); // FALLTHROUGH
81 case 3: (*value
) = (*value
) + (*value
); // FALLTHROUGH
82 case 2: (*value
) = (*value
) + (*value
); break;
83 case 1: (*value
) += literal1
; break;
84 case 0: (*value
) = literal2
; break;
89 // One such fuzzer implementation.
90 class DefaultFuzzer
: public Fuzzer
{
92 DefaultFuzzer(int frequency
) : frequency_(frequency
) {
95 virtual ~DefaultFuzzer() {}
97 void FuzzBool(bool* value
) override
{
98 if (RandEvent(frequency_
))
102 void FuzzInt(int* value
) override
{
103 FuzzIntegralType
<int>(value
, frequency_
);
106 void FuzzLong(long* value
) override
{
107 FuzzIntegralType
<long>(value
, frequency_
);
110 void FuzzSize(size_t* value
) override
{
111 FuzzIntegralType
<size_t>(value
, frequency_
);
114 void FuzzUChar(unsigned char* value
) override
{
115 FuzzIntegralType
<unsigned char>(value
, frequency_
);
118 void FuzzUInt16(uint16
* value
) override
{
119 FuzzIntegralType
<uint16
>(value
, frequency_
);
122 void FuzzUInt32(uint32
* value
) override
{
123 FuzzIntegralType
<uint32
>(value
, frequency_
);
126 void FuzzInt64(int64
* value
) override
{
127 FuzzIntegralType
<int64
>(value
, frequency_
);
130 void FuzzUInt64(uint64
* value
) override
{
131 FuzzIntegralType
<uint64
>(value
, frequency_
);
134 void FuzzFloat(float* value
) override
{
135 if (RandEvent(frequency_
))
136 *value
= RandDouble();
139 void FuzzDouble(double* value
) override
{
140 if (RandEvent(frequency_
))
141 *value
= RandDouble();
144 void FuzzString(std::string
* value
) override
{
145 FuzzStringType
<std::string
>(value
, frequency_
, "BORKED", std::string());
148 void FuzzString16(base::string16
* value
) override
{
149 FuzzStringType
<base::string16
>(value
, frequency_
,
150 base::WideToUTF16(L
"BORKED"),
151 base::WideToUTF16(L
""));
154 void FuzzData(char* data
, int length
) override
{
155 if (RandEvent(frequency_
)) {
156 for (int i
= 0; i
< length
; ++i
) {
157 FuzzIntegralType
<char>(&data
[i
], frequency_
);
162 void FuzzBytes(void* data
, int data_len
) override
{
163 FuzzData(static_cast<char*>(data
), data_len
);
167 unsigned int frequency_
;
171 // No-op fuzzer. Rewrites each message unchanged to check if the message
172 // re-assembly is legit.
173 class NoOpFuzzer
: public Fuzzer
{
176 virtual ~NoOpFuzzer() {}
178 void FuzzBool(bool* value
) override
{}
179 void FuzzInt(int* value
) override
{}
180 void FuzzLong(long* value
) override
{}
181 void FuzzSize(size_t* value
) override
{}
182 void FuzzUChar(unsigned char* value
) override
{}
183 void FuzzUInt16(uint16
* value
) override
{}
184 void FuzzUInt32(uint32
* value
) override
{}
185 void FuzzInt64(int64
* value
) override
{}
186 void FuzzUInt64(uint64
* value
) override
{}
187 void FuzzFloat(float* value
) override
{}
188 void FuzzDouble(double* value
) override
{}
189 void FuzzString(std::string
* value
) override
{}
190 void FuzzString16(base::string16
* value
) override
{}
191 void FuzzData(char* data
, int length
) override
{}
192 void FuzzBytes(void* data
, int data_len
) override
{}
195 class FuzzerFactory
{
197 static Fuzzer
*Create(const std::string
& name
, int frequency
) {
199 return new NoOpFuzzer();
201 if (name
== "default")
202 return new DefaultFuzzer(frequency
);
204 std::cerr
<< "No such fuzzer: " << name
<< "\n";
209 // Partially-specialized class that knows how to fuzz a given type.
212 static void Fuzz(P
* p
, Fuzzer
*fuzzer
) {
213 // This is the catch-all for types we don't have enough information
214 // to fuzz. It simply does nothing to the type. We might want to
215 // change it to randomly flip a bit in the range (p, p+sizeof(P)).
219 // Template function to invoke partially-specialized class method.
221 static void FuzzParam(P
* p
, Fuzzer
* fuzzer
) {
222 FuzzTraits
<P
>::Fuzz(p
, fuzzer
);
225 // Specializations to fuzz primitive types.
227 struct FuzzTraits
<bool> {
228 static void Fuzz(bool* p
, Fuzzer
* fuzzer
) {
234 struct FuzzTraits
<int> {
235 static void Fuzz(int* p
, Fuzzer
* fuzzer
) {
241 struct FuzzTraits
<unsigned int> {
242 static void Fuzz(unsigned int* p
, Fuzzer
* fuzzer
) {
243 fuzzer
->FuzzInt(reinterpret_cast<int*>(p
));
248 struct FuzzTraits
<long> {
249 static void Fuzz(long* p
, Fuzzer
* fuzzer
) {
255 struct FuzzTraits
<unsigned long> {
256 static void Fuzz(unsigned long* p
, Fuzzer
* fuzzer
) {
257 fuzzer
->FuzzLong(reinterpret_cast<long*>(p
));
262 struct FuzzTraits
<long long> {
263 static void Fuzz(long long* p
, Fuzzer
* fuzzer
) {
264 fuzzer
->FuzzInt64(reinterpret_cast<int64
*>(p
));
269 struct FuzzTraits
<unsigned long long> {
270 static void Fuzz(unsigned long long* p
, Fuzzer
* fuzzer
) {
271 fuzzer
->FuzzInt64(reinterpret_cast<int64
*>(p
));
276 struct FuzzTraits
<short> {
277 static void Fuzz(short* p
, Fuzzer
* fuzzer
) {
278 fuzzer
->FuzzUInt16(reinterpret_cast<uint16
*>(p
));
283 struct FuzzTraits
<unsigned short> {
284 static void Fuzz(unsigned short* p
, Fuzzer
* fuzzer
) {
285 fuzzer
->FuzzUInt16(reinterpret_cast<uint16
*>(p
));
290 struct FuzzTraits
<char> {
291 static void Fuzz(char* p
, Fuzzer
* fuzzer
) {
292 fuzzer
->FuzzUChar(reinterpret_cast<unsigned char*>(p
));
297 struct FuzzTraits
<unsigned char> {
298 static void Fuzz(unsigned char* p
, Fuzzer
* fuzzer
) {
299 fuzzer
->FuzzUChar(p
);
304 struct FuzzTraits
<float> {
305 static void Fuzz(float* p
, Fuzzer
* fuzzer
) {
306 fuzzer
->FuzzFloat(p
);
311 struct FuzzTraits
<double> {
312 static void Fuzz(double* p
, Fuzzer
* fuzzer
) {
313 fuzzer
->FuzzDouble(p
);
318 struct FuzzTraits
<std::string
> {
319 static void Fuzz(std::string
* p
, Fuzzer
* fuzzer
) {
320 fuzzer
->FuzzString(p
);
325 struct FuzzTraits
<base::string16
> {
326 static void Fuzz(base::string16
* p
, Fuzzer
* fuzzer
) {
327 fuzzer
->FuzzString16(p
);
331 // Specializations to fuzz tuples.
333 struct FuzzTraits
<Tuple
<A
>> {
334 static void Fuzz(Tuple
<A
>* p
, Fuzzer
* fuzzer
) {
335 FuzzParam(&get
<0>(*p
), fuzzer
);
339 template <class A
, class B
>
340 struct FuzzTraits
<Tuple
<A
, B
>> {
341 static void Fuzz(Tuple
<A
, B
>* p
, Fuzzer
* fuzzer
) {
342 FuzzParam(&get
<0>(*p
), fuzzer
);
343 FuzzParam(&get
<1>(*p
), fuzzer
);
347 template <class A
, class B
, class C
>
348 struct FuzzTraits
<Tuple
<A
, B
, C
>> {
349 static void Fuzz(Tuple
<A
, B
, C
>* p
, Fuzzer
* fuzzer
) {
350 FuzzParam(&get
<0>(*p
), fuzzer
);
351 FuzzParam(&get
<1>(*p
), fuzzer
);
352 FuzzParam(&get
<2>(*p
), fuzzer
);
356 template <class A
, class B
, class C
, class D
>
357 struct FuzzTraits
<Tuple
<A
, B
, C
, D
>> {
358 static void Fuzz(Tuple
<A
, B
, C
, D
>* p
, Fuzzer
* fuzzer
) {
359 FuzzParam(&get
<0>(*p
), fuzzer
);
360 FuzzParam(&get
<1>(*p
), fuzzer
);
361 FuzzParam(&get
<2>(*p
), fuzzer
);
362 FuzzParam(&get
<3>(*p
), fuzzer
);
366 template <class A
, class B
, class C
, class D
, class E
>
367 struct FuzzTraits
<Tuple
<A
, B
, C
, D
, E
>> {
368 static void Fuzz(Tuple
<A
, B
, C
, D
, E
>* p
, Fuzzer
* fuzzer
) {
369 FuzzParam(&get
<0>(*p
), fuzzer
);
370 FuzzParam(&get
<1>(*p
), fuzzer
);
371 FuzzParam(&get
<2>(*p
), fuzzer
);
372 FuzzParam(&get
<3>(*p
), fuzzer
);
373 FuzzParam(&get
<4>(*p
), fuzzer
);
377 // Specializations to fuzz containers.
379 struct FuzzTraits
<std::vector
<A
> > {
380 static void Fuzz(std::vector
<A
>* p
, Fuzzer
* fuzzer
) {
381 for (size_t i
= 0; i
< p
->size(); ++i
) {
382 FuzzParam(&p
->at(i
), fuzzer
);
387 template <class A
, class B
>
388 struct FuzzTraits
<std::map
<A
, B
> > {
389 static void Fuzz(std::map
<A
, B
>* p
, Fuzzer
* fuzzer
) {
390 typename
std::map
<A
, B
>::iterator it
;
391 for (it
= p
->begin(); it
!= p
->end(); ++it
) {
392 FuzzParam(&it
->second
, fuzzer
);
397 template <class A
, class B
>
398 struct FuzzTraits
<std::pair
<A
, B
> > {
399 static void Fuzz(std::pair
<A
, B
>* p
, Fuzzer
* fuzzer
) {
400 FuzzParam(&p
->second
, fuzzer
);
404 // Specializations to fuzz hand-coded types.
405 #if defined(OS_POSIX)
407 struct FuzzTraits
<base::FileDescriptor
> {
408 static void Fuzz(base::FileDescriptor
* p
, Fuzzer
* fuzzer
) {
409 FuzzParam(&p
->fd
, fuzzer
);
415 struct FuzzTraits
<GURL
> {
416 static void Fuzz(GURL
*p
, Fuzzer
* fuzzer
) {
417 FuzzParam(&p
->possibly_invalid_spec(), fuzzer
);
422 struct FuzzTraits
<gfx::Point
> {
423 static void Fuzz(gfx::Point
*p
, Fuzzer
* fuzzer
) {
426 FuzzParam(&x
, fuzzer
);
427 FuzzParam(&y
, fuzzer
);
433 struct FuzzTraits
<gfx::Size
> {
434 static void Fuzz(gfx::Size
*p
, Fuzzer
* fuzzer
) {
437 FuzzParam(&w
, fuzzer
);
438 FuzzParam(&h
, fuzzer
);
444 struct FuzzTraits
<gfx::Rect
> {
445 static void Fuzz(gfx::Rect
*p
, Fuzzer
* fuzzer
) {
446 gfx::Point origin
= p
->origin();
447 gfx::Size size
= p
->size();
448 FuzzParam(&origin
, fuzzer
);
449 FuzzParam(&size
, fuzzer
);
450 p
->set_origin(origin
);
455 // Redefine macros to generate fuzzing from traits declarations.
456 // Null out all the macros that need nulling.
457 #include "ipc/ipc_message_null_macros.h"
459 // STRUCT declarations cause corresponding STRUCT_TRAITS declarations to occur.
460 #undef IPC_STRUCT_BEGIN
461 #undef IPC_STRUCT_BEGIN_WITH_PARENT
462 #undef IPC_STRUCT_MEMBER
463 #undef IPC_STRUCT_END
464 #define IPC_STRUCT_BEGIN_WITH_PARENT(struct_name, parent) \
465 IPC_STRUCT_BEGIN(struct_name)
466 #define IPC_STRUCT_BEGIN(struct_name) IPC_STRUCT_TRAITS_BEGIN(struct_name)
467 #define IPC_STRUCT_MEMBER(type, name, ...) IPC_STRUCT_TRAITS_MEMBER(name)
468 #define IPC_STRUCT_END() IPC_STRUCT_TRAITS_END()
470 // Set up so next include will generate fuzz trait classes.
471 #undef IPC_STRUCT_TRAITS_BEGIN
472 #undef IPC_STRUCT_TRAITS_MEMBER
473 #undef IPC_STRUCT_TRAITS_PARENT
474 #undef IPC_STRUCT_TRAITS_END
475 #define IPC_STRUCT_TRAITS_BEGIN(struct_name) \
477 struct FuzzTraits<struct_name> { \
478 static void Fuzz(struct_name *p, Fuzzer* fuzzer) {
480 #define IPC_STRUCT_TRAITS_MEMBER(name) \
481 FuzzParam(&p->name, fuzzer);
483 #define IPC_STRUCT_TRAITS_PARENT(type) \
484 FuzzParam(static_cast<type*>(p), fuzzer);
486 #define IPC_STRUCT_TRAITS_END() \
490 // TODO(tsepez): Make sure to end up with an enum that meets |condition|.
491 #undef IPC_ENUM_TRAITS_VALIDATE
492 #define IPC_ENUM_TRAITS_VALIDATE(enum_name, conditon) \
494 struct FuzzTraits<enum_name> { \
495 static void Fuzz(enum_name* p, Fuzzer* fuzzer) { \
496 FuzzParam(reinterpret_cast<int*>(p), fuzzer); \
500 // Bring them into existence.
501 #include "tools/ipc_fuzzer/message_lib/all_messages.h"
503 // Redefine macros to generate fuzzing funtions
504 #include "ipc/ipc_message_null_macros.h"
505 #undef IPC_MESSAGE_DECL
506 #define IPC_MESSAGE_DECL(kind, type, name, in, out, ilist, olist) \
507 IPC_##kind##_##type##_FUZZ(name, in, out, ilist, olist)
509 #define IPC_EMPTY_CONTROL_FUZZ(name, in, out, ilist, olist) \
510 IPC::Message* fuzzer_for_##name(IPC::Message *msg, Fuzzer* fuzzer) { \
514 #define IPC_EMPTY_ROUTED_FUZZ(name, in, out, ilist, olist) \
515 IPC::Message* fuzzer_for_##name(IPC::Message *msg, Fuzzer* fuzzer) { \
519 #define IPC_ASYNC_CONTROL_FUZZ(name, in, out, ilist, olist) \
520 IPC::Message* fuzzer_for_##name(IPC::Message *msg, Fuzzer* fuzzer) { \
521 name* real_msg = static_cast<name*>(msg); \
522 IPC_TUPLE_IN_##in ilist p; \
523 name::Read(real_msg, &p); \
524 FuzzParam(&p, fuzzer); \
525 return new name(IPC_MEMBERS_IN_##in(p)); \
528 #define IPC_ASYNC_ROUTED_FUZZ(name, in, out, ilist, olist) \
529 IPC::Message* fuzzer_for_##name(IPC::Message *msg, Fuzzer* fuzzer) { \
530 name* real_msg = static_cast<name*>(msg); \
531 IPC_TUPLE_IN_##in ilist p; \
532 name::Read(real_msg, &p); \
533 FuzzParam(&p, fuzzer); \
534 return new name(msg->routing_id() \
536 IPC_MEMBERS_IN_##in(p)); \
539 #define IPC_SYNC_CONTROL_FUZZ(name, in, out, ilist, olist) \
540 IPC::Message* fuzzer_for_##name(IPC::Message *msg, Fuzzer* fuzzer) { \
541 name* real_msg = static_cast<name*>(msg); \
542 IPC_TUPLE_IN_##in ilist p; \
543 name::ReadSendParam(real_msg, &p); \
544 FuzzParam(&p, fuzzer); \
545 name* new_msg = new name(IPC_MEMBERS_IN_##in(p) \
546 IPC_COMMA_AND_##out(IPC_COMMA_##in) \
547 IPC_MEMBERS_OUT_##out()); \
548 MessageCracker::CopyMessageID(new_msg, real_msg); \
553 #define IPC_SYNC_ROUTED_FUZZ(name, in, out, ilist, olist) \
554 IPC::Message* fuzzer_for_##name(IPC::Message *msg, Fuzzer* fuzzer) { \
555 name* real_msg = static_cast<name*>(msg); \
556 IPC_TUPLE_IN_##in ilist p; \
557 name::ReadSendParam(real_msg, &p); \
558 FuzzParam(&p, fuzzer); \
559 name* new_msg = new name(msg->routing_id() \
560 IPC_COMMA_OR_##out(IPC_COMMA_##in) \
561 IPC_MEMBERS_IN_##in(p) \
562 IPC_COMMA_AND_##out(IPC_COMMA_##in) \
563 IPC_MEMBERS_OUT_##out()); \
564 MessageCracker::CopyMessageID(new_msg, real_msg); \
568 #define IPC_MEMBERS_IN_0(p)
569 #define IPC_MEMBERS_IN_1(p) get<0>(p)
570 #define IPC_MEMBERS_IN_2(p) get<0>(p), get<1>(p)
571 #define IPC_MEMBERS_IN_3(p) get<0>(p), get<1>(p), get<2>(p)
572 #define IPC_MEMBERS_IN_4(p) get<0>(p), get<1>(p), get<2>(p), get<3>(p)
573 #define IPC_MEMBERS_IN_5(p) get<0>(p), get<1>(p), get<2>(p), get<3>(p), \
576 #define IPC_MEMBERS_OUT_0()
577 #define IPC_MEMBERS_OUT_1() NULL
578 #define IPC_MEMBERS_OUT_2() NULL, NULL
579 #define IPC_MEMBERS_OUT_3() NULL, NULL, NULL
580 #define IPC_MEMBERS_OUT_4() NULL, NULL, NULL, NULL
581 #define IPC_MEMBERS_OUT_5() NULL, NULL, NULL, NULL, NULL
583 #include "tools/ipc_fuzzer/message_lib/all_messages.h"
585 typedef IPC::Message
* (*FuzzFunction
)(IPC::Message
*, Fuzzer
*);
586 typedef base::hash_map
<uint32
, FuzzFunction
> FuzzFunctionMap
;
588 // Redefine macros to register fuzzing functions into map.
589 #include "ipc/ipc_message_null_macros.h"
590 #undef IPC_MESSAGE_DECL
591 #define IPC_MESSAGE_DECL(kind, type, name, in, out, ilist, olist) \
592 (*map)[static_cast<uint32>(name::ID)] = fuzzer_for_##name;
594 void PopulateFuzzFunctionMap(FuzzFunctionMap
*map
) {
595 #include "tools/ipc_fuzzer/message_lib/all_messages.h"
598 static IPC::Message
* RewriteMessage(
599 IPC::Message
* message
,
601 FuzzFunctionMap
* map
) {
602 FuzzFunctionMap::iterator it
= map
->find(message
->type());
603 if (it
== map
->end()) {
604 // This usually indicates a missing message file in all_messages.h, or
605 // that the message dump file is taken from a different revision of
606 // chromium from this executable.
607 std::cerr
<< "Unknown message type: ["
608 << IPC_MESSAGE_ID_CLASS(message
->type()) << ", "
609 << IPC_MESSAGE_ID_LINE(message
->type()) << "].\n";
613 return (*it
->second
)(message
, fuzzer
);
618 const char kHelpSwitch
[] = "help";
619 const char kHelpSwitchHelp
[] =
622 const char kFrequencySwitch
[] = "frequency";
623 const char kFrequencySwitchHelp
[] =
624 "probability of mutation; tweak every 1/|q| times.";
626 const char kFuzzerNameSwitch
[] = "fuzzer-name";
627 const char kFuzzerNameSwitchHelp
[] =
628 "select default or no-op fuzzer.";
630 const char kPermuteSwitch
[] = "permute";
631 const char kPermuteSwitchHelp
[] =
632 "Randomly shuffle the order of all messages.";
634 const char kTypeListSwitch
[] = "type-list";
635 const char kTypeListSwitchHelp
[] =
636 "explicit list of the only message-ids to mutate.";
639 std::cerr
<< "Mutate messages from an exiting message file.\n";
641 std::cerr
<< "Usage:\n"
642 << " ipc_fuzzer_mutate"
643 << " [--" << kHelpSwitch
<< "]"
644 << " [--" << kFuzzerNameSwitch
<< "=f]"
645 << " [--" << kFrequencySwitch
<< "=q]"
646 << " [--" << kTypeListSwitch
<< "=x,y,z...]"
647 << " [--" << kPermuteSwitch
<< "]"
648 << " infile outfile\n";
651 << " --" << kHelpSwitch
<< " - " << kHelpSwitchHelp
<< "\n"
652 << " --" << kFuzzerNameSwitch
<< " - " << kFuzzerNameSwitchHelp
<< "\n"
653 << " --" << kFrequencySwitch
<< " - " << kFrequencySwitchHelp
<< "\n"
654 << " --" << kTypeListSwitch
<< " - " << kTypeListSwitchHelp
<< "\n"
655 << " --" << kPermuteSwitch
<< " - " << kPermuteSwitchHelp
<< "\n";
660 int MutateMain(int argc
, char** argv
) {
661 base::CommandLine::Init(argc
, argv
);
662 base::CommandLine
* cmd
= base::CommandLine::ForCurrentProcess();
663 base::CommandLine::StringVector args
= cmd
->GetArgs();
665 if (args
.size() != 2 || cmd
->HasSwitch(kHelpSwitch
)) {
670 base::FilePath::StringType input_file_name
= args
[0];
671 base::FilePath::StringType output_file_name
= args
[1];
673 bool permute
= cmd
->HasSwitch(kPermuteSwitch
);
675 std::string fuzzer_name
= "default";
676 if (cmd
->HasSwitch(kFuzzerNameSwitch
))
677 fuzzer_name
= cmd
->GetSwitchValueASCII(kFuzzerNameSwitch
);
680 if (cmd
->HasSwitch(kFrequencySwitch
))
681 frequency
= atoi(cmd
->GetSwitchValueASCII(kFrequencySwitch
).c_str());
683 std::string type_string_list
= cmd
->GetSwitchValueASCII(kTypeListSwitch
);
684 std::vector
<std::string
> type_string_vector
;
685 base::SplitString(type_string_list
, ',', &type_string_vector
);
686 std::set
<uint32
> type_set
;
687 for (size_t i
= 0; i
< type_string_vector
.size(); ++i
) {
688 type_set
.insert(atoi(type_string_vector
[i
].c_str()));
693 Fuzzer
* fuzzer
= FuzzerFactory::Create(fuzzer_name
, frequency
);
697 FuzzFunctionMap fuzz_function_map
;
698 PopulateFuzzFunctionMap(&fuzz_function_map
);
700 MessageVector message_vector
;
701 if (!MessageFile::Read(base::FilePath(input_file_name
), &message_vector
))
704 for (size_t i
= 0; i
< message_vector
.size(); ++i
) {
705 IPC::Message
* msg
= message_vector
[i
];
706 if (!type_set
.empty() && type_set
.end() == std::find(
707 type_set
.begin(), type_set
.end(), msg
->type())) {
710 IPC::Message
* new_message
= RewriteMessage(msg
, fuzzer
, &fuzz_function_map
);
712 delete message_vector
[i
];
713 message_vector
[i
] = new_message
;
718 std::random_shuffle(message_vector
.begin(), message_vector
.end(),
722 if (!MessageFile::Write(base::FilePath(output_file_name
), message_vector
))
728 } // namespace ipc_fuzzer
730 int main(int argc
, char** argv
) {
731 return ipc_fuzzer::MutateMain(argc
, argv
);