Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(495)

Side by Side Diff: tools/ipc_fuzzer/mutate/generate.cc

Issue 1000373004: Combine traits for IPC mutation and generation fuzzing plus other refactoring. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Define frequency as a constant and reorder arguments in ipc_fuzzer_gen.py Created 5 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « tools/ipc_fuzzer/mutate/fuzzer_main.cc ('k') | tools/ipc_fuzzer/mutate/generator.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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.
4
5 #include <stdlib.h>
6
7 #include <algorithm>
8 #include <iostream>
9 #include <ostream>
10 #include <set>
11 #include <vector>
12
13 #include "base/command_line.h"
14 #include "base/pickle.h"
15 #include "base/strings/string_util.h"
16 #include "base/strings/string_number_conversions.h"
17 #include "base/strings/utf_string_conversions.h"
18 #include "ipc/ipc_message.h"
19 #include "ipc/ipc_message_utils.h"
20 #include "ipc/ipc_switches.h"
21 #include "ipc/ipc_sync_channel.h"
22 #include "ipc/ipc_sync_message.h"
23 #include "tools/ipc_fuzzer/message_lib/message_file.h"
24 #include "tools/ipc_fuzzer/mutate/rand_util.h"
25
26 #if defined(OS_POSIX)
27 #include <unistd.h>
28 #endif
29
30 // First include of message files to provide basic type.
31 #include "tools/ipc_fuzzer/message_lib/all_messages.h"
32 #include "ipc/ipc_message_null_macros.h"
33
34 #if defined(COMPILER_GCC)
35 #define PRETTY_FUNCTION __PRETTY_FUNCTION__
36 #elif defined(COMPILER_MSVC)
37 #define PRETTY_FUNCTION __FUNCSIG__
38 #else
39 #define PRETTY_FUNCTION __FUNCTION__
40 #endif
41
42 namespace IPC {
43 class Message;
44 } // namespace IPC
45
46 namespace {
47 // For breaking deep recursion.
48 int g_depth = 0;
49 } // namespace
50
51 namespace ipc_fuzzer {
52
53 // Interface implemented by those who generate basic types. The types all
54 // correspond to the types which a pickle from base/pickle.h can pickle,
55 // plus the floating point types.
56 class Generator {
57 public:
58 virtual void GenerateBool(bool* value) = 0;
59 virtual void GenerateInt(int* value) = 0;
60 virtual void GenerateLong(long* value) = 0;
61 virtual void GenerateSize(size_t* value) = 0;
62 virtual void GenerateUChar(unsigned char *value) = 0;
63 virtual void GenerateWChar(wchar_t *value) = 0;
64 virtual void GenerateUInt16(uint16* value) = 0;
65 virtual void GenerateUInt32(uint32* value) = 0;
66 virtual void GenerateInt64(int64* value) = 0;
67 virtual void GenerateUInt64(uint64* value) = 0;
68 virtual void GenerateFloat(float *value) = 0;
69 virtual void GenerateDouble(double *value) = 0;
70 virtual void GenerateString(std::string* value) = 0;
71 virtual void GenerateString16(base::string16* value) = 0;
72 virtual void GenerateData(char* data, int length) = 0;
73 virtual void GenerateBytes(void* data, int data_len) = 0;
74 };
75
76 typedef IPC::Message* (*GeneratorFunction)(Generator*);
77 typedef std::vector<GeneratorFunction> GeneratorFunctionVector;
78 GeneratorFunctionVector g_function_vector;
79
80 template <typename T>
81 void GenerateIntegralType(T* value) {
82 switch (RandInRange(16)) {
83 case 0:
84 *value = static_cast<T>(0);
85 break;
86 case 1:
87 *value = static_cast<T>(1);
88 break;
89 case 2:
90 *value = static_cast<T>(-1);
91 break;
92 case 3:
93 *value = static_cast<T>(2);
94 break;
95 default:
96 *value = static_cast<T>(RandU64());
97 break;
98 }
99 }
100
101 template <typename T>
102 void GenerateFloatingType(T* value) {
103 *value = RandDouble();
104 }
105
106 template <typename T>
107 void GenerateStringType(T* value) {
108 T temp_string;
109 size_t length = RandInRange(300);
110 for (size_t i = 0; i < length; ++i)
111 temp_string += RandInRange(256);
112 *value = temp_string;
113 }
114
115 class GeneratorImpl : public Generator {
116 public:
117 GeneratorImpl() {}
118 virtual ~GeneratorImpl() {}
119
120 void GenerateBool(bool* value) override {
121 *value = RandInRange(2) ? true: false;
122 }
123
124 void GenerateInt(int* value) override {
125 GenerateIntegralType<int>(value);
126 }
127
128 void GenerateLong(long* value) override {
129 GenerateIntegralType<long>(value);
130 }
131
132 void GenerateSize(size_t* value) override {
133 GenerateIntegralType<size_t>(value);
134 }
135
136 void GenerateUChar(unsigned char* value) override {
137 GenerateIntegralType<unsigned char>(value);
138 }
139
140 void GenerateWChar(wchar_t* value) override {
141 GenerateIntegralType<wchar_t>(value);
142 }
143
144 void GenerateUInt16(uint16* value) override {
145 GenerateIntegralType<uint16>(value);
146 }
147
148 void GenerateUInt32(uint32* value) override {
149 GenerateIntegralType<uint32>(value);
150 }
151
152 void GenerateInt64(int64* value) override {
153 GenerateIntegralType<int64>(value);
154 }
155
156 void GenerateUInt64(uint64* value) override {
157 GenerateIntegralType<uint64>(value);
158 }
159
160 void GenerateFloat(float* value) override {
161 GenerateFloatingType<float>(value);
162 }
163
164 void GenerateDouble(double* value) override {
165 GenerateFloatingType<double>(value);
166 }
167
168 void GenerateString(std::string* value) override {
169 GenerateStringType<std::string>(value);
170 }
171
172 void GenerateString16(base::string16* value) override {
173 GenerateStringType<base::string16>(value);
174 }
175
176 void GenerateData(char* data, int length) override {
177 for (int i = 0; i < length; ++i) {
178 GenerateIntegralType<char>(&data[i]);
179 }
180 }
181
182 void GenerateBytes(void* data, int data_len) override {
183 GenerateData(static_cast<char*>(data), data_len);
184 }
185 };
186
187 // Partially-specialized class that knows how to generate a given type.
188 template <class P>
189 struct GenerateTraits {
190 static bool Generate(P* p, Generator *generator) {
191 // This is the catch-all for types we don't have enough information
192 // to generate.
193 std::cerr << "Can't handle " << PRETTY_FUNCTION << "\n";
194 return false;
195 }
196 };
197
198 // Template function to invoke partially-specialized class method.
199 template <class P>
200 static bool GenerateParam(P* p, Generator* generator) {
201 return GenerateTraits<P>::Generate(p, generator);
202 };
203
204 template <class P>
205 static bool GenerateParamArray(P* p, size_t length, Generator* generator) {
206 for (size_t i = 0; i < length; i++, p++) {
207 if (!GenerateTraits<P>::Generate(p, generator))
208 return false;
209 }
210 return true;
211 };
212
213 // Specializations to generate primitive types.
214 template <>
215 struct GenerateTraits<bool> {
216 static bool Generate(bool* p, Generator* generator) {
217 generator->GenerateBool(p);
218 return true;
219 }
220 };
221
222 template <>
223 struct GenerateTraits<int> {
224 static bool Generate(int* p, Generator* generator) {
225 generator->GenerateInt(p);
226 return true;
227 }
228 };
229
230 template <>
231 struct GenerateTraits<unsigned int> {
232 static bool Generate(unsigned int* p, Generator* generator) {
233 generator->GenerateInt(reinterpret_cast<int*>(p));
234 return true;
235 }
236 };
237
238 template <>
239 struct GenerateTraits<long> {
240 static bool Generate(long* p, Generator* generator) {
241 generator->GenerateLong(p);
242 return true;
243 }
244 };
245
246 template <>
247 struct GenerateTraits<unsigned long> {
248 static bool Generate(unsigned long* p, Generator* generator) {
249 generator->GenerateLong(reinterpret_cast<long*>(p));
250 return true;
251 }
252 };
253
254 template <>
255 struct GenerateTraits<long long> {
256 static bool Generate(long long* p, Generator* generator) {
257 generator->GenerateInt64(reinterpret_cast<int64*>(p));
258 return true;
259 }
260 };
261
262 template <>
263 struct GenerateTraits<unsigned long long> {
264 static bool Generate(unsigned long long* p, Generator* generator) {
265 generator->GenerateInt64(reinterpret_cast<int64*>(p));
266 return true;
267 }
268 };
269
270 template <>
271 struct GenerateTraits<short> {
272 static bool Generate(short* p, Generator* generator) {
273 generator->GenerateUInt16(reinterpret_cast<uint16*>(p));
274 return true;
275 }
276 };
277
278 template <>
279 struct GenerateTraits<unsigned short> {
280 static bool Generate(unsigned short* p, Generator* generator) {
281 generator->GenerateUInt16(reinterpret_cast<uint16*>(p));
282 return true;
283 }
284 };
285
286 template <>
287 struct GenerateTraits<char> {
288 static bool Generate(char* p, Generator* generator) {
289 generator->GenerateUChar(reinterpret_cast<unsigned char*>(p));
290 return true;
291 }
292 };
293
294 template <>
295 struct GenerateTraits<unsigned char> {
296 static bool Generate(unsigned char* p, Generator* generator) {
297 generator->GenerateUChar(p);
298 return true;
299 }
300 };
301
302 template <>
303 struct GenerateTraits<wchar_t> {
304 static bool Generate(wchar_t* p, Generator* generator) {
305 generator->GenerateWChar(p);
306 return true;
307 }
308 };
309
310 template <>
311 struct GenerateTraits<float> {
312 static bool Generate(float* p, Generator* generator) {
313 generator->GenerateFloat(p);
314 return true;
315 }
316 };
317
318 template <>
319 struct GenerateTraits<double> {
320 static bool Generate(double* p, Generator* generator) {
321 generator->GenerateDouble(p);
322 return true;
323 }
324 };
325
326 template <>
327 struct GenerateTraits<std::string> {
328 static bool Generate(std::string* p, Generator* generator) {
329 generator->GenerateString(p);
330 return true;
331 }
332 };
333
334 template <>
335 struct GenerateTraits<base::string16> {
336 static bool Generate(base::string16* p, Generator* generator) {
337 generator->GenerateString16(p);
338 return true;
339 }
340 };
341
342 // Specializations to generate tuples.
343 template <>
344 struct GenerateTraits<Tuple<>> {
345 static bool Generate(Tuple<>* p, Generator* generator) {
346 return true;
347 }
348 };
349
350 template <class A>
351 struct GenerateTraits<Tuple<A>> {
352 static bool Generate(Tuple<A>* p, Generator* generator) {
353 return GenerateParam(&get<0>(*p), generator);
354 }
355 };
356
357 template <class A, class B>
358 struct GenerateTraits<Tuple<A, B>> {
359 static bool Generate(Tuple<A, B>* p, Generator* generator) {
360 return
361 GenerateParam(&get<0>(*p), generator) &&
362 GenerateParam(&get<1>(*p), generator);
363 }
364 };
365
366 template <class A, class B, class C>
367 struct GenerateTraits<Tuple<A, B, C>> {
368 static bool Generate(Tuple<A, B, C>* p, Generator* generator) {
369 return
370 GenerateParam(&get<0>(*p), generator) &&
371 GenerateParam(&get<1>(*p), generator) &&
372 GenerateParam(&get<2>(*p), generator);
373 }
374 };
375
376 template <class A, class B, class C, class D>
377 struct GenerateTraits<Tuple<A, B, C, D>> {
378 static bool Generate(Tuple<A, B, C, D>* p, Generator* generator) {
379 return
380 GenerateParam(&get<0>(*p), generator) &&
381 GenerateParam(&get<1>(*p), generator) &&
382 GenerateParam(&get<2>(*p), generator) &&
383 GenerateParam(&get<3>(*p), generator);
384 }
385 };
386
387 template <class A, class B, class C, class D, class E>
388 struct GenerateTraits<Tuple<A, B, C, D, E>> {
389 static bool Generate(Tuple<A, B, C, D, E>* p, Generator* generator) {
390 return
391 GenerateParam(&get<0>(*p), generator) &&
392 GenerateParam(&get<1>(*p), generator) &&
393 GenerateParam(&get<2>(*p), generator) &&
394 GenerateParam(&get<3>(*p), generator) &&
395 GenerateParam(&get<4>(*p), generator);
396 }
397 };
398
399 // Specializations to generate containers.
400 template <class A>
401 struct GenerateTraits<std::vector<A> > {
402 static bool Generate(std::vector<A>* p, Generator* generator) {
403 size_t count = ++g_depth > 3 ? 0 : RandElementCount();
404 p->resize(count);
405 for (size_t i = 0; i < count; ++i) {
406 if (!GenerateParam(&p->at(i), generator)) {
407 --g_depth;
408 return false;
409 }
410 }
411 --g_depth;
412 return true;
413 }
414 };
415
416 template <class A>
417 struct GenerateTraits<std::set<A> > {
418 static bool Generate(std::set<A>* p, Generator* generator) {
419 static int g_depth = 0;
420 size_t count = ++g_depth > 3 ? 0 : RandElementCount();
421 A a;
422 for (size_t i = 0; i < count; ++i) {
423 if (!GenerateParam(&a, generator)) {
424 --g_depth;
425 return false;
426 }
427 p->insert(a);
428 }
429 --g_depth;
430 return true;
431 }
432 };
433
434
435 template <class A, class B>
436 struct GenerateTraits<std::map<A, B> > {
437 static bool Generate(std::map<A, B>* p, Generator* generator) {
438 static int g_depth = 0;
439 size_t count = ++g_depth > 3 ? 0 : RandElementCount();
440 std::pair<A, B> place_holder;
441 for (size_t i = 0; i < count; ++i) {
442 if (!GenerateParam(&place_holder, generator)) {
443 --g_depth;
444 return false;
445 }
446 p->insert(place_holder);
447 }
448 --g_depth;
449 return true;
450 }
451 };
452
453 template <class A, class B, class C, class D>
454 struct GenerateTraits<std::map<A, B, C, D>> {
455 static bool Generate(std::map<A, B, C, D>* p, Generator* generator) {
456 static int g_depth = 0;
457 size_t count = ++g_depth > 3 ? 0 : RandElementCount();
458 std::pair<A, B> place_holder;
459 for (size_t i = 0; i < count; ++i) {
460 if (!GenerateParam(&place_holder, generator)) {
461 --g_depth;
462 return false;
463 }
464 p->insert(place_holder);
465 }
466 --g_depth;
467 return true;
468 }
469 };
470
471 template <class A, class B>
472 struct GenerateTraits<std::pair<A, B> > {
473 static bool Generate(std::pair<A, B>* p, Generator* generator) {
474 return
475 GenerateParam(&p->first, generator) &&
476 GenerateParam(&p->second, generator);
477 }
478 };
479
480 // Specializations to generate hand-coded types.
481 template <>
482 struct GenerateTraits<base::NullableString16> {
483 static bool Generate(base::NullableString16* p, Generator* generator) {
484 *p = base::NullableString16();
485 return true;
486 }
487 };
488
489 template <>
490 struct GenerateTraits<base::FilePath> {
491 static bool Generate(base::FilePath* p, Generator* generator) {
492 const char path_chars[] = "ACz0/.~:";
493 size_t count = RandInRange(60);
494 base::FilePath::StringType random_path;
495 for (size_t i = 0; i < count; ++i)
496 random_path += path_chars[RandInRange(sizeof(path_chars) - 1)];
497 *p = base::FilePath(random_path);
498 return true;
499 }
500 };
501
502 template <>
503 struct GenerateTraits<base::File::Error> {
504 static bool Generate(base::File::Error* p, Generator* generator) {
505 int temporary;
506 if (!GenerateParam(&temporary, generator))
507 return false;
508 *p = static_cast<base::File::Error>(temporary);
509 return true;
510 }
511 };
512
513 template <>
514 struct GenerateTraits<base::File::Info> {
515 static bool Generate(base::File::Info* p, Generator* generator) {
516 double last_modified;
517 double last_accessed;
518 double creation_time;
519 if (!GenerateParam(&p->size, generator))
520 return false;
521 if (!GenerateParam(&p->is_directory, generator))
522 return false;
523 if (!GenerateParam(&last_modified, generator))
524 return false;
525 if (!GenerateParam(&last_accessed, generator))
526 return false;
527 if (!GenerateParam(&creation_time, generator))
528 return false;
529 p->last_modified = base::Time::FromDoubleT(last_modified);
530 p->last_accessed = base::Time::FromDoubleT(last_accessed);
531 p->creation_time = base::Time::FromDoubleT(creation_time);
532 return true;
533 }
534 };
535
536 template <>
537 struct GenerateTraits<base::Time> {
538 static bool Generate(base::Time* p, Generator* generator) {
539 *p = base::Time::FromInternalValue(RandU64());
540 return true;
541 }
542 };
543
544 template <>
545 struct GenerateTraits<base::TimeDelta> {
546 static bool Generate(base::TimeDelta* p, Generator* generator) {
547 *p = base::TimeDelta::FromInternalValue(RandU64());
548 return true;
549 }
550 };
551
552 template <>
553 struct GenerateTraits<base::TimeTicks> {
554 static bool Generate(base::TimeTicks* p, Generator* generator) {
555 *p = base::TimeTicks::FromInternalValue(RandU64());
556 return true;
557 }
558 };
559
560 template <>
561 struct GenerateTraits<base::ListValue> {
562 static bool Generate(base::ListValue* p, Generator* generator) {
563 ++g_depth;
564 size_t list_length = g_depth > 3 ? 0 : RandInRange(8);
565 for (size_t index = 0; index < list_length; ++index) {
566 switch (RandInRange(8))
567 {
568 case base::Value::TYPE_BOOLEAN: {
569 bool tmp;
570 generator->GenerateBool(&tmp);
571 p->Set(index, new base::FundamentalValue(tmp));
572 break;
573 }
574 case base::Value::TYPE_INTEGER: {
575 int tmp;
576 generator->GenerateInt(&tmp);
577 p->Set(index, new base::FundamentalValue(tmp));
578 break;
579 }
580 case base::Value::TYPE_DOUBLE: {
581 double tmp;
582 generator->GenerateDouble(&tmp);
583 p->Set(index, new base::FundamentalValue(tmp));
584 break;
585 }
586 case base::Value::TYPE_STRING: {
587 std::string tmp;
588 generator->GenerateString(&tmp);
589 p->Set(index, new base::StringValue(tmp));
590 break;
591 }
592 case base::Value::TYPE_BINARY: {
593 char tmp[200];
594 size_t bin_length = RandInRange(sizeof(tmp));
595 generator->GenerateData(tmp, bin_length);
596 p->Set(index,
597 base::BinaryValue::CreateWithCopiedBuffer(tmp, bin_length));
598 break;
599 }
600 case base::Value::TYPE_DICTIONARY: {
601 base::DictionaryValue* tmp = new base::DictionaryValue();
602 GenerateParam(tmp, generator);
603 p->Set(index, tmp);
604 break;
605 }
606 case base::Value::TYPE_LIST: {
607 base::ListValue* tmp = new base::ListValue();
608 GenerateParam(tmp, generator);
609 p->Set(index, tmp);
610 break;
611 }
612 case base::Value::TYPE_NULL:
613 default:
614 break;
615 }
616 }
617 --g_depth;
618 return true;
619 }
620 };
621
622 template <>
623 struct GenerateTraits<base::DictionaryValue> {
624 static bool Generate(base::DictionaryValue* p, Generator* generator) {
625 ++g_depth;
626 size_t dict_length = g_depth > 3 ? 0 : RandInRange(8);
627 for (size_t index = 0; index < dict_length; ++index) {
628 std::string property;
629 generator->GenerateString(&property);
630 switch (RandInRange(8))
631 {
632 case base::Value::TYPE_BOOLEAN: {
633 bool tmp;
634 generator->GenerateBool(&tmp);
635 p->SetWithoutPathExpansion(property, new base::FundamentalValue(tmp));
636 break;
637 }
638 case base::Value::TYPE_INTEGER: {
639 int tmp;
640 generator->GenerateInt(&tmp);
641 p->SetWithoutPathExpansion(property, new base::FundamentalValue(tmp));
642 break;
643 }
644 case base::Value::TYPE_DOUBLE: {
645 double tmp;
646 generator->GenerateDouble(&tmp);
647 p->SetWithoutPathExpansion(property, new base::FundamentalValue(tmp));
648 break;
649 }
650 case base::Value::TYPE_STRING: {
651 std::string tmp;
652 generator->GenerateString(&tmp);
653 p->SetWithoutPathExpansion(property, new base::StringValue(tmp));
654 break;
655 }
656 case base::Value::TYPE_BINARY: {
657 char tmp[200];
658 size_t bin_length = RandInRange(sizeof(tmp));
659 generator->GenerateData(tmp, bin_length);
660 p->SetWithoutPathExpansion(
661 property,
662 base::BinaryValue::CreateWithCopiedBuffer(tmp, bin_length));
663 break;
664 }
665 case base::Value::TYPE_DICTIONARY: {
666 base::DictionaryValue* tmp = new base::DictionaryValue();
667 GenerateParam(tmp, generator);
668 p->SetWithoutPathExpansion(property, tmp);
669 break;
670 }
671 case base::Value::TYPE_LIST: {
672 base::ListValue* tmp = new base::ListValue();
673 GenerateParam(tmp, generator);
674 p->SetWithoutPathExpansion(property, tmp);
675 break;
676 }
677 case base::Value::TYPE_NULL:
678 default:
679 break;
680 }
681 }
682 --g_depth;
683 return true;
684 }
685 };
686
687 template <>
688 struct GenerateTraits<blink::WebGamepad> {
689 static bool Generate(blink::WebGamepad* p, Generator* generator) {
690 if (!GenerateParam(&p->connected, generator))
691 return false;
692 if (!GenerateParam(&p->timestamp, generator))
693 return false;
694 unsigned idLength = static_cast<unsigned>(
695 RandInRange(blink::WebGamepad::idLengthCap + 1));
696 if (!GenerateParamArray(&p->id[0], idLength, generator))
697 return false;
698 p->axesLength = static_cast<unsigned>(
699 RandInRange(blink::WebGamepad::axesLengthCap + 1));
700 if (!GenerateParamArray(&p->axes[0], p->axesLength, generator))
701 return false;
702 p->buttonsLength = static_cast<unsigned>(
703 RandInRange(blink::WebGamepad::buttonsLengthCap + 1));
704 if (!GenerateParamArray(&p->buttons[0], p->buttonsLength, generator))
705 return false;
706 unsigned mappingsLength = static_cast<unsigned>(
707 RandInRange(blink::WebGamepad::mappingLengthCap + 1));
708 if (!GenerateParamArray(&p->mapping[0], mappingsLength, generator))
709 return false;
710 return true;
711 }
712 };
713
714 template <>
715 struct GenerateTraits<blink::WebGamepadButton> {
716 static bool Generate(blink::WebGamepadButton* p, Generator* generator) {
717 bool pressed;
718 double value;
719 if (!GenerateParam(&pressed, generator))
720 return false;
721 if (!GenerateParam(&value, generator))
722 return false;
723 *p = blink::WebGamepadButton(pressed, value);
724 return true;
725 }
726 };
727
728 template <>
729 struct GenerateTraits<cc::CompositorFrame> {
730 static bool Generate(cc::CompositorFrame* p, Generator* generator) {
731 if (!GenerateParam(&p->metadata, generator))
732 return false;
733 switch (RandInRange(4)) {
734 case 0: {
735 p->delegated_frame_data.reset(new cc::DelegatedFrameData());
736 if (!GenerateParam(p->delegated_frame_data.get(), generator))
737 return false;
738 return true;
739 }
740 case 1: {
741 p->gl_frame_data.reset(new cc::GLFrameData());
742 if (!GenerateParam(p->gl_frame_data.get(), generator))
743 return false;
744 return true;
745 }
746 case 2: {
747 p->software_frame_data.reset(new cc::SoftwareFrameData());
748 if (!GenerateParam(p->software_frame_data.get(), generator))
749 return false;
750 return true;
751 }
752 default:
753 // Generate nothing to handle the no frame case.
754 return true;
755 }
756 }
757 };
758
759 template <>
760 struct GenerateTraits<cc::CompositorFrameAck> {
761 static bool Generate(cc::CompositorFrameAck* p, Generator* generator) {
762 if (!GenerateParam(&p->resources, generator))
763 return false;
764 if (!GenerateParam(&p->last_software_frame_id, generator))
765 return false;
766 p->gl_frame_data.reset(new cc::GLFrameData);
767 if (!GenerateParam(p->gl_frame_data.get(), generator))
768 return false;
769 return true;
770 }
771 };
772
773 template <>
774 struct GenerateTraits<cc::DelegatedFrameData> {
775 static bool Generate(cc::DelegatedFrameData* p, Generator* generator) {
776 if (!GenerateParam(&p->device_scale_factor, generator))
777 return false;
778 if (!GenerateParam(&p->resource_list, generator))
779 return false;
780 if (!GenerateParam(&p->render_pass_list, generator))
781 return false;
782 return true;
783 }
784 };
785
786 template <class A>
787 struct GenerateTraits<cc::ListContainer<A>> {
788 static bool Generate(cc::ListContainer<A>* p, Generator* generator) {
789 // TODO(mbarbella): This should actually generate something.
790 return true;
791 }
792 };
793
794 template <>
795 struct GenerateTraits<cc::QuadList> {
796 static bool Generate(cc::QuadList* p, Generator* generator) {
797 // TODO(mbarbella): This should actually generate something.
798 return true;
799 }
800 };
801
802 template <>
803 struct GenerateTraits<cc::RenderPass> {
804 static bool Generate(cc::RenderPass* p, Generator* generator) {
805 if (!GenerateParam(&p->id, generator))
806 return false;
807 if (!GenerateParam(&p->output_rect, generator))
808 return false;
809 if (!GenerateParam(&p->damage_rect, generator))
810 return false;
811 if (!GenerateParam(&p->transform_to_root_target, generator))
812 return false;
813 if (!GenerateParam(&p->has_transparent_background, generator))
814 return false;
815 if (!GenerateParam(&p->quad_list, generator))
816 return false;
817 if (!GenerateParam(&p->shared_quad_state_list, generator))
818 return false;
819 // Omitting |copy_requests| as it is not sent over IPC.
820 return true;
821 }
822 };
823
824 template <>
825 struct GenerateTraits<cc::RenderPassList> {
826 static bool Generate(cc::RenderPassList* p, Generator* generator) {
827 size_t count = RandElementCount();
828 for (size_t i = 0; i < count; ++i) {
829 scoped_ptr<cc::RenderPass> render_pass = cc::RenderPass::Create();
830 if (!GenerateParam(render_pass.get(), generator))
831 return false;
832 p->push_back(render_pass.Pass());
833 }
834 return true;
835 }
836 };
837
838 template <>
839 struct GenerateTraits<cc::SoftwareFrameData> {
840 static bool Generate(cc::SoftwareFrameData* p, Generator* generator) {
841 if (!GenerateParam(&p->id, generator))
842 return false;
843 if (!GenerateParam(&p->size, generator))
844 return false;
845 if (!GenerateParam(&p->damage_rect, generator))
846 return false;
847 if (!GenerateParam(&p->bitmap_id, generator))
848 return false;
849 return true;
850 }
851 };
852
853 template <>
854 struct GenerateTraits<content::IndexedDBKey> {
855 static bool Generate(content::IndexedDBKey* p, Generator* generator) {
856 ++g_depth;
857 blink::WebIDBKeyType web_type =
858 static_cast<blink::WebIDBKeyType>(RandInRange(7));
859 switch (web_type)
860 {
861 case blink::WebIDBKeyTypeArray: {
862 size_t length = g_depth > 3 ? 0 : RandInRange(4);
863 std::vector<content::IndexedDBKey> array;
864 array.resize(length);
865 for (size_t i = 0; i < length; ++i) {
866 if (!GenerateParam(&array[i], generator)) {
867 --g_depth;
868 return false;
869 }
870 }
871 *p = content::IndexedDBKey(array);
872 return true;
873 }
874 case blink::WebIDBKeyTypeBinary: {
875 std::string binary;
876 if (!GenerateParam(&binary, generator)) {
877 --g_depth;
878 return false;
879 }
880 *p = content::IndexedDBKey(binary);
881 return true;
882 }
883 case blink::WebIDBKeyTypeString: {
884 base::string16 string;
885 if (!GenerateParam(&string, generator))
886 return false;
887 *p = content::IndexedDBKey(string);
888 return true;
889 }
890 case blink::WebIDBKeyTypeDate:
891 case blink::WebIDBKeyTypeNumber: {
892 double number;
893 if (!GenerateParam(&number, generator)) {
894 --g_depth;
895 return false;
896 }
897 *p = content::IndexedDBKey(number, web_type);
898 return true;
899 }
900 case blink::WebIDBKeyTypeInvalid:
901 case blink::WebIDBKeyTypeNull: {
902 *p = content::IndexedDBKey(web_type);
903 return true;
904 }
905 default: {
906 NOTREACHED();
907 --g_depth;
908 return false;
909 }
910 }
911 }
912 };
913
914 template <>
915 struct GenerateTraits<content::IndexedDBKeyRange> {
916 static bool Generate(content::IndexedDBKeyRange *p, Generator* generator) {
917 content::IndexedDBKey lower;
918 content::IndexedDBKey upper;
919 bool lower_open;
920 bool upper_open;
921 if (!GenerateParam(&lower, generator))
922 return false;
923 if (!GenerateParam(&upper, generator))
924 return false;
925 if (!GenerateParam(&lower_open, generator))
926 return false;
927 if (!GenerateParam(&upper_open, generator))
928 return false;
929 *p = content::IndexedDBKeyRange(lower, upper, lower_open, upper_open);
930 return true;
931 }
932 };
933
934 template <>
935 struct GenerateTraits<content::IndexedDBKeyPath> {
936 static bool Generate(content::IndexedDBKeyPath *p, Generator* generator) {
937 switch (RandInRange(3)) {
938 case 0: {
939 std::vector<base::string16> array;
940 if (!GenerateParam(&array, generator))
941 return false;
942 *p = content::IndexedDBKeyPath(array);
943 break;
944 }
945 case 1: {
946 base::string16 string;
947 if (!GenerateParam(&string, generator))
948 return false;
949 *p = content::IndexedDBKeyPath(string);
950 break;
951 }
952 case 2: {
953 *p = content::IndexedDBKeyPath();
954 break;
955 }
956 }
957 return true;
958 }
959 };
960
961 template <>
962 struct GenerateTraits<content::NPIdentifier_Param> {
963 static bool Generate(content::NPIdentifier_Param* p, Generator* generator) {
964 // TODO(mbarbella): This should actually generate something.
965 *p = content::NPIdentifier_Param();
966 return true;
967 }
968 };
969
970 template <>
971 struct GenerateTraits<content::NPVariant_Param> {
972 static bool Generate(content::NPVariant_Param* p, Generator* generator) {
973 // TODO(mbarbella): This should actually generate something.
974 *p = content::NPVariant_Param();
975 return true;
976 }
977 };
978
979 template <>
980 struct GenerateTraits<content::PageState> {
981 static bool Generate(content::PageState* p, Generator* generator) {
982 std::string junk;
983 if (!GenerateParam(&junk, generator))
984 return false;
985 *p = content::PageState::CreateFromEncodedData(junk);
986 return true;
987 }
988 };
989
990 template <>
991 struct GenerateTraits<content::SyntheticGesturePacket> {
992 static bool Generate(content::SyntheticGesturePacket* p,
993 Generator* generator) {
994 scoped_ptr<content::SyntheticGestureParams> gesture_params;
995 switch (RandInRange(
996 content::SyntheticGestureParams::SYNTHETIC_GESTURE_TYPE_MAX + 1)) {
997 case content::SyntheticGestureParams::GestureType::
998 SMOOTH_SCROLL_GESTURE: {
999 content::SyntheticSmoothScrollGestureParams* params =
1000 new content::SyntheticSmoothScrollGestureParams();
1001 if (!GenerateParam(&params->anchor, generator))
1002 return false;
1003 if (!GenerateParam(&params->distances, generator))
1004 return false;
1005 if (!GenerateParam(&params->prevent_fling, generator))
1006 return false;
1007 if (!GenerateParam(&params->speed_in_pixels_s, generator))
1008 return false;
1009 gesture_params.reset(params);
1010 break;
1011 }
1012 case content::SyntheticGestureParams::GestureType::SMOOTH_DRAG_GESTURE: {
1013 content::SyntheticSmoothDragGestureParams* params =
1014 new content::SyntheticSmoothDragGestureParams();
1015 if (!GenerateParam(&params->start_point, generator))
1016 return false;
1017 if (!GenerateParam(&params->distances, generator))
1018 return false;
1019 if (!GenerateParam(&params->speed_in_pixels_s, generator))
1020 return false;
1021 gesture_params.reset(params);
1022 break;
1023 }
1024 case content::SyntheticGestureParams::GestureType::PINCH_GESTURE: {
1025 content::SyntheticPinchGestureParams* params =
1026 new content::SyntheticPinchGestureParams();
1027 if (!GenerateParam(&params->scale_factor, generator))
1028 return false;
1029 if (!GenerateParam(&params->anchor, generator))
1030 return false;
1031 if (!GenerateParam(&params->relative_pointer_speed_in_pixels_s,
1032 generator))
1033 return false;
1034 gesture_params.reset(params);
1035 break;
1036 }
1037 case content::SyntheticGestureParams::GestureType::TAP_GESTURE: {
1038 content::SyntheticTapGestureParams* params =
1039 new content::SyntheticTapGestureParams();
1040 if (!GenerateParam(&params->position, generator))
1041 return false;
1042 if (!GenerateParam(&params->duration_ms, generator))
1043 return false;
1044 gesture_params.reset(params);
1045 break;
1046 }
1047 }
1048 p->set_gesture_params(gesture_params.Pass());
1049 return true;
1050 }
1051 };
1052
1053 template <>
1054 struct GenerateTraits<content::WebCursor> {
1055 static bool Generate(content::WebCursor* p, Generator* generator) {
1056 content::WebCursor::CursorInfo info;
1057
1058 // |type| enum is not validated on de-serialization, so pick random value.
1059 if (!GenerateParam(reinterpret_cast<int *>(&info.type), generator))
1060 return false;
1061 if (!GenerateParam(&info.hotspot, generator))
1062 return false;
1063 if (!GenerateParam(&info.image_scale_factor, generator))
1064 return false;
1065 if (!GenerateParam(&info.custom_image, generator))
1066 return false;
1067 // Omitting |externalHandle| since it is not serialized.
1068
1069 // Scale factor is expected to be greater than 0, otherwise we hit
1070 // a check failure.
1071 info.image_scale_factor = fabs(info.image_scale_factor) + 0.001;
1072
1073 *p = content::WebCursor(info);
1074 return true;
1075 }
1076 };
1077
1078 template <>
1079 struct GenerateTraits<ContentSettingsPattern> {
1080 static bool Generate(ContentSettingsPattern* p, Generator* generator) {
1081 // TODO(mbarbella): This can crash if a pattern is generated from a random
1082 // string. We could carefully generate a pattern or fix pattern generation.
1083 *p = ContentSettingsPattern();
1084 return true;
1085 }
1086 };
1087
1088 template <>
1089 struct GenerateTraits<ExtensionMsg_PermissionSetStruct> {
1090 static bool Generate(ExtensionMsg_PermissionSetStruct* p,
1091 Generator* generator) {
1092 // TODO(mbarbella): This should actually generate something.
1093 *p = ExtensionMsg_PermissionSetStruct();
1094 return true;
1095 }
1096 };
1097
1098 template <>
1099 struct GenerateTraits<extensions::URLPatternSet> {
1100 static bool Generate(extensions::URLPatternSet* p, Generator* generator) {
1101 std::set<URLPattern> patterns;
1102 if (!GenerateParam(&patterns, generator))
1103 return false;
1104 *p = extensions::URLPatternSet(patterns);
1105 return true;
1106 }
1107 };
1108
1109 template <>
1110 struct GenerateTraits<gfx::Point> {
1111 static bool Generate(gfx::Point *p, Generator* generator) {
1112 int x;
1113 int y;
1114 if (!GenerateParam(&x, generator))
1115 return false;
1116 if (!GenerateParam(&y, generator))
1117 return false;
1118 p->SetPoint(x, y);
1119 return true;
1120 }
1121 };
1122
1123 template <>
1124 struct GenerateTraits<gfx::PointF> {
1125 static bool Generate(gfx::PointF *p, Generator* generator) {
1126 float x;
1127 float y;
1128 if (!GenerateParam(&x, generator))
1129 return false;
1130 if (!GenerateParam(&y, generator))
1131 return false;
1132 p->SetPoint(x, y);
1133 return true;
1134 }
1135 };
1136
1137 template <>
1138 struct GenerateTraits<gfx::Rect> {
1139 static bool Generate(gfx::Rect *p, Generator* generator) {
1140 gfx::Point origin;
1141 gfx::Size size;
1142 if (!GenerateParam(&origin, generator))
1143 return false;
1144 if (!GenerateParam(&size, generator))
1145 return false;
1146 p->set_origin(origin);
1147 p->set_size(size);
1148 return true;
1149 }
1150 };
1151
1152 template <>
1153 struct GenerateTraits<gfx::RectF> {
1154 static bool Generate(gfx::RectF *p, Generator* generator) {
1155 gfx::PointF origin;
1156 gfx::SizeF size;
1157 if (!GenerateParam(&origin, generator))
1158 return false;
1159 if (!GenerateParam(&size, generator))
1160 return false;
1161 p->set_origin(origin);
1162 p->set_size(size);
1163 return true;
1164 }
1165 };
1166
1167 template <>
1168 struct GenerateTraits<gfx::Range> {
1169 static bool Generate(gfx::Range *p, Generator* generator) {
1170 size_t start;
1171 size_t end;
1172 if (!GenerateParam(&start, generator))
1173 return false;
1174 if (!GenerateParam(&end, generator))
1175 return false;
1176 *p = gfx::Range(start, end);
1177 return true;
1178 }
1179 };
1180
1181 template <>
1182 struct GenerateTraits<gfx::Size> {
1183 static bool Generate(gfx::Size* p, Generator* generator) {
1184 int w;
1185 int h;
1186 if (!GenerateParam(&w, generator))
1187 return false;
1188 if (!GenerateParam(&h, generator))
1189 return false;
1190 p->SetSize(w, h);
1191 return true;
1192 }
1193 };
1194
1195 template <>
1196 struct GenerateTraits<gfx::SizeF> {
1197 static bool Generate(gfx::SizeF* p, Generator* generator) {
1198 float w;
1199 float h;
1200 if (!GenerateParam(&w, generator))
1201 return false;
1202 if (!GenerateParam(&h, generator))
1203 return false;
1204 p->SetSize(w, h);
1205 return true;
1206 }
1207 };
1208
1209 template <>
1210 struct GenerateTraits<gfx::Transform> {
1211 static bool Generate(gfx::Transform* p, Generator* generator) {
1212 SkMScalar matrix[16];
1213 if (!GenerateParamArray(&matrix[0], arraysize(matrix), generator))
1214 return false;
1215 *p = gfx::Transform(matrix[0], matrix[1], matrix[2], matrix[3], matrix[4],
1216 matrix[5], matrix[6], matrix[7], matrix[8], matrix[9],
1217 matrix[10], matrix[11], matrix[12], matrix[13],
1218 matrix[14], matrix[15]);
1219 return true;
1220 }
1221 };
1222
1223 template <>
1224 struct GenerateTraits<gfx::Vector2d> {
1225 static bool Generate(gfx::Vector2d *p, Generator* generator) {
1226 int x;
1227 int y;
1228 if (!GenerateParam(&x, generator))
1229 return false;
1230 if (!GenerateParam(&y, generator))
1231 return false;
1232 *p = gfx::Vector2d(x, y);
1233 return true;
1234 }
1235 };
1236
1237 template <>
1238 struct GenerateTraits<gfx::Vector2dF> {
1239 static bool Generate(gfx::Vector2dF *p, Generator* generator) {
1240 float x;
1241 float y;
1242 if (!GenerateParam(&x, generator))
1243 return false;
1244 if (!GenerateParam(&y, generator))
1245 return false;
1246 *p = gfx::Vector2dF(x, y);
1247 return true;
1248 }
1249 };
1250
1251 template <>
1252 struct GenerateTraits<gpu::Mailbox> {
1253 static bool Generate(gpu::Mailbox* p, Generator* generator) {
1254 generator->GenerateBytes(p->name, sizeof(p->name));
1255 return true;
1256 }
1257 };
1258
1259 template <>
1260 struct GenerateTraits<gpu::MailboxHolder> {
1261 static bool Generate(gpu::MailboxHolder* p, Generator* generator) {
1262 gpu::Mailbox mailbox;
1263 uint32_t texture_target;
1264 uint32_t sync_point;
1265 if (!GenerateParam(&mailbox, generator))
1266 return false;
1267 if (!GenerateParam(&texture_target, generator))
1268 return false;
1269 if (!GenerateParam(&sync_point, generator))
1270 return false;
1271 *p = gpu::MailboxHolder(mailbox, texture_target, sync_point);
1272 return true;
1273 }
1274 };
1275
1276 template <>
1277 struct GenerateTraits<gpu::ValueState> {
1278 static bool Generate(gpu::ValueState* p, Generator* generator) {
1279 gpu::ValueState state;
1280 if (!GenerateParamArray(&state.float_value[0], 4, generator))
1281 return false;
1282 if (!GenerateParamArray(&state.int_value[0], 4, generator))
1283 return false;
1284 *p = state;
1285 return true;
1286 }
1287 };
1288
1289 template <>
1290 struct GenerateTraits<GURL> {
1291 static bool Generate(GURL* p, Generator* generator) {
1292 const char url_chars[] = "Ahtp0:/.?+\\%&#";
1293 size_t count = RandInRange(100);
1294 std::string random_url;
1295 for (size_t i = 0; i < count; ++i)
1296 random_url += url_chars[RandInRange(sizeof(url_chars) - 1)];
1297 int selector = RandInRange(10);
1298 if (selector == 0)
1299 random_url = std::string("http://") + random_url;
1300 else if (selector == 1)
1301 random_url = std::string("file://") + random_url;
1302 else if (selector == 2)
1303 random_url = std::string("javascript:") + random_url;
1304 else if (selector == 2)
1305 random_url = std::string("data:") + random_url;
1306 *p = GURL(random_url);
1307 return true;
1308 }
1309 };
1310
1311 #if defined(OS_WIN)
1312 template <>
1313 struct GenerateTraits<HWND> {
1314 static bool Generate(HWND* p, Generator* generator) {
1315 // TODO(aarya): This should actually generate something.
1316 return true;
1317 }
1318 };
1319 #endif
1320
1321 template <>
1322 struct GenerateTraits<IPC::Message> {
1323 static bool Generate(IPC::Message *p, Generator* generator) {
1324 if (g_function_vector.empty())
1325 return false;
1326 size_t index = RandInRange(g_function_vector.size());
1327 IPC::Message* ipc_message = (*g_function_vector[index])(generator);
1328 if (!ipc_message)
1329 return false;
1330 p = ipc_message;
1331 return true;
1332 }
1333 };
1334
1335 template <>
1336 struct GenerateTraits<IPC::PlatformFileForTransit> {
1337 static bool Generate(IPC::PlatformFileForTransit* p, Generator* generator) {
1338 // TODO(inferno): I don't think we can generate real ones due to check on
1339 // construct.
1340 *p = IPC::InvalidPlatformFileForTransit();
1341 return true;
1342 }
1343 };
1344
1345 template <>
1346 struct GenerateTraits<IPC::ChannelHandle> {
1347 static bool Generate(IPC::ChannelHandle* p, Generator* generator) {
1348 // TODO(inferno): Add way to generate real channel handles.
1349 #if defined(OS_WIN)
1350 HANDLE fake_handle = (HANDLE)(RandU64());
1351 p->pipe = IPC::ChannelHandle::PipeHandle(fake_handle);
1352 return true;
1353 #elif defined(OS_POSIX)
1354 return
1355 GenerateParam(&p->name, generator) &&
1356 GenerateParam(&p->socket, generator);
1357 #endif
1358 }
1359 };
1360
1361 #if defined(OS_WIN)
1362 template <>
1363 struct GenerateTraits<LOGFONT> {
1364 static bool Generate(LOGFONT* p, Generator* generator) {
1365 // TODO(aarya): This should actually generate something.
1366 return true;
1367 }
1368 };
1369 #endif
1370
1371 template <>
1372 struct GenerateTraits<media::AudioParameters> {
1373 static bool Generate(media::AudioParameters* p, Generator* generator) {
1374 int format;
1375 int channel_layout;
1376 int sample_rate;
1377 int bits_per_sample;
1378 int frames_per_buffer;
1379 int channels;
1380 int effects;
1381 if (!GenerateParam(&format, generator))
1382 return false;
1383 if (!GenerateParam(&channel_layout, generator))
1384 return false;
1385 if (!GenerateParam(&sample_rate, generator))
1386 return false;
1387 if (!GenerateParam(&bits_per_sample, generator))
1388 return false;
1389 if (!GenerateParam(&frames_per_buffer, generator))
1390 return false;
1391 if (!GenerateParam(&channels, generator))
1392 return false;
1393 if (!GenerateParam(&effects, generator))
1394 return false;
1395 media::AudioParameters params(
1396 static_cast<media::AudioParameters::Format>(format),
1397 static_cast<media::ChannelLayout>(channel_layout), channels,
1398 sample_rate, bits_per_sample, frames_per_buffer, effects);
1399 *p = params;
1400 return true;
1401 }
1402 };
1403
1404 template <>
1405 struct GenerateTraits<media::VideoCaptureFormat> {
1406 static bool Generate(media::VideoCaptureFormat* p, Generator* generator) {
1407 int frame_size_width;
1408 int frame_size_height;
1409 int pixel_format;
1410 if (!GenerateParam(&frame_size_height, generator))
1411 return false;
1412 if (!GenerateParam(&frame_size_width, generator))
1413 return false;
1414 if (!GenerateParam(&pixel_format, generator))
1415 return false;
1416 if (!GenerateParam(&p->frame_rate, generator))
1417 return false;
1418 p->frame_size.SetSize(frame_size_width, frame_size_height);
1419 p->pixel_format = static_cast<media::VideoPixelFormat>(pixel_format);
1420 return true;
1421 }
1422 };
1423
1424 template <>
1425 struct GenerateTraits<net::LoadTimingInfo> {
1426 static bool Generate(net::LoadTimingInfo* p, Generator* generator) {
1427 return GenerateParam(&p->socket_log_id, generator) &&
1428 GenerateParam(&p->socket_reused, generator) &&
1429 GenerateParam(&p->request_start_time, generator) &&
1430 GenerateParam(&p->request_start, generator) &&
1431 GenerateParam(&p->proxy_resolve_start, generator) &&
1432 GenerateParam(&p->proxy_resolve_end, generator) &&
1433 GenerateParam(&p->connect_timing.dns_start, generator) &&
1434 GenerateParam(&p->connect_timing.dns_end, generator) &&
1435 GenerateParam(&p->connect_timing.connect_start, generator) &&
1436 GenerateParam(&p->connect_timing.connect_end, generator) &&
1437 GenerateParam(&p->connect_timing.ssl_start, generator) &&
1438 GenerateParam(&p->connect_timing.ssl_end, generator) &&
1439 GenerateParam(&p->send_start, generator) &&
1440 GenerateParam(&p->send_end, generator) &&
1441 GenerateParam(&p->receive_headers_end, generator);
1442 }
1443 };
1444
1445 template <>
1446 struct GenerateTraits<net::HostPortPair> {
1447 static bool Generate(net::HostPortPair* p, Generator* generator) {
1448 std::string host;
1449 uint16 port;
1450 if (!GenerateParam(&host, generator))
1451 return false;
1452 if (!GenerateParam(&port, generator))
1453 return false;
1454 p->set_host(host);
1455 p->set_port(port);
1456 return true;
1457 }
1458 };
1459
1460 template <>
1461 struct GenerateTraits<net::IPEndPoint> {
1462 static bool Generate(net::IPEndPoint* p, Generator* generator) {
1463 net::IPAddressNumber address;
1464 int port;
1465 if (!GenerateParam(&address, generator))
1466 return false;
1467 if (!GenerateParam(&port, generator))
1468 return false;
1469 net::IPEndPoint ip_endpoint(address, port);
1470 *p = ip_endpoint;
1471 return true;
1472 }
1473 };
1474
1475 template <>
1476 struct GenerateTraits<network_hints::LookupRequest> {
1477 static bool Generate(network_hints::LookupRequest* p, Generator* generator) {
1478 network_hints::LookupRequest request;
1479 if (!GenerateParam(&request.hostname_list, generator))
1480 return false;
1481 *p = request;
1482 return true;
1483 }
1484 };
1485
1486 // PP_ traits.
1487 template <>
1488 struct GenerateTraits<PP_Bool> {
1489 static bool Generate(PP_Bool *p, Generator* generator) {
1490 bool tmp;
1491 if (!GenerateParam(&tmp, generator))
1492 return false;
1493 *p = PP_FromBool(tmp);
1494 return true;
1495 }
1496 };
1497
1498 template <>
1499 struct GenerateTraits<PP_KeyInformation> {
1500 static bool Generate(PP_KeyInformation* p, Generator* generator) {
1501 // TODO(mbarbella): This should actually generate something.
1502 *p = PP_KeyInformation();
1503 return true;
1504 }
1505 };
1506
1507 template <>
1508 struct GenerateTraits<PP_NetAddress_Private> {
1509 static bool Generate(PP_NetAddress_Private *p, Generator* generator) {
1510 p->size = RandInRange(sizeof(p->data) + 1);
1511 generator->GenerateBytes(&p->data, p->size);
1512 return true;
1513 }
1514 };
1515
1516 template <>
1517 struct GenerateTraits<ppapi::PPB_X509Certificate_Fields> {
1518 static bool Generate(ppapi::PPB_X509Certificate_Fields* p,
1519 Generator* generator) {
1520 // TODO(mbarbella): This should actually generate something.
1521 return true;
1522 }
1523 };
1524
1525 template <>
1526 struct GenerateTraits<ppapi::proxy::PPBFlash_DrawGlyphs_Params> {
1527 static bool Generate(ppapi::proxy::PPBFlash_DrawGlyphs_Params* p,
1528 Generator* generator) {
1529 // TODO(mbarbella): This should actually generate something.
1530 *p = ppapi::proxy::PPBFlash_DrawGlyphs_Params();
1531 return true;
1532 }
1533 };
1534
1535 template <>
1536 struct GenerateTraits<ppapi::proxy::ResourceMessageCallParams> {
1537 static bool Generate(
1538 ppapi::proxy::ResourceMessageCallParams *p, Generator* generator) {
1539 PP_Resource resource;
1540 int32_t sequence;
1541 bool has_callback;
1542 if (!GenerateParam(&resource, generator))
1543 return false;
1544 if (!GenerateParam(&sequence, generator))
1545 return false;
1546 if (!GenerateParam(&has_callback, generator))
1547 return false;
1548 *p = ppapi::proxy::ResourceMessageCallParams(resource, sequence);
1549 if (has_callback)
1550 p->set_has_callback();
1551 return true;
1552 }
1553 };
1554
1555 template <>
1556 struct GenerateTraits<ppapi::proxy::ResourceMessageReplyParams> {
1557 static bool Generate(
1558 ppapi::proxy::ResourceMessageReplyParams *p, Generator* generator) {
1559 PP_Resource resource;
1560 int32_t sequence;
1561 int32_t result;
1562 if (!GenerateParam(&resource, generator))
1563 return false;
1564 if (!GenerateParam(&sequence, generator))
1565 return false;
1566 if (!GenerateParam(&result, generator))
1567 return false;
1568 *p = ppapi::proxy::ResourceMessageReplyParams(resource, sequence);
1569 p->set_result(result);
1570 return true;
1571 }
1572 };
1573
1574 template <>
1575 struct GenerateTraits<ppapi::proxy::SerializedHandle> {
1576 static bool Generate(ppapi::proxy::SerializedHandle* p,
1577 Generator* generator) {
1578 // TODO(mbarbella): This should actually generate something.
1579 *p = ppapi::proxy::SerializedHandle();
1580 return true;
1581 }
1582 };
1583
1584 template <>
1585 struct GenerateTraits<ppapi::proxy::SerializedFontDescription> {
1586 static bool Generate(ppapi::proxy::SerializedFontDescription* p,
1587 Generator* generator) {
1588 // TODO(mbarbella): This should actually generate something.
1589 *p = ppapi::proxy::SerializedFontDescription();
1590 return true;
1591 }
1592 };
1593
1594 template <>
1595 struct GenerateTraits<ppapi::proxy::SerializedTrueTypeFontDesc> {
1596 static bool Generate(ppapi::proxy::SerializedTrueTypeFontDesc* p,
1597 Generator* generator) {
1598 // TODO(mbarbella): This should actually generate something.
1599 *p = ppapi::proxy::SerializedTrueTypeFontDesc();
1600 return true;
1601 }
1602 };
1603
1604 template <>
1605 struct GenerateTraits<ppapi::proxy::SerializedVar> {
1606 static bool Generate(ppapi::proxy::SerializedVar* p, Generator* generator) {
1607 // TODO(mbarbella): This should actually generate something.
1608 *p = ppapi::proxy::SerializedVar();
1609 return true;
1610 }
1611 };
1612
1613 template <>
1614 struct GenerateTraits<ppapi::HostResource> {
1615 static bool Generate(ppapi::HostResource *p, Generator* generator) {
1616 PP_Instance instance;
1617 PP_Resource resource;
1618 if (!GenerateParam(&instance, generator))
1619 return false;
1620 if (!GenerateParam(&resource, generator))
1621 return false;
1622 p->SetHostResource(instance, resource);
1623 return true;
1624 }
1625 };
1626
1627 template <>
1628 struct GenerateTraits<ppapi::PepperFilePath> {
1629 static bool Generate(ppapi::PepperFilePath *p, Generator* generator) {
1630 unsigned domain = RandInRange(ppapi::PepperFilePath::DOMAIN_MAX_VALID+1);
1631 base::FilePath path;
1632 if (!GenerateParam(&path, generator))
1633 return false;
1634 *p = ppapi::PepperFilePath(
1635 static_cast<ppapi::PepperFilePath::Domain>(domain), path);
1636 return true;
1637 }
1638 };
1639
1640 template <>
1641 struct GenerateTraits<ppapi::PpapiPermissions> {
1642 static bool Generate(ppapi::PpapiPermissions *p, Generator* generator) {
1643 uint32_t bits;
1644 if (!GenerateParam(&bits, generator))
1645 return false;
1646 *p = ppapi::PpapiPermissions(bits);
1647 return true;
1648 }
1649 };
1650
1651 template <>
1652 struct GenerateTraits<ppapi::SocketOptionData> {
1653 static bool Generate(ppapi::SocketOptionData *p, Generator* generator) {
1654 // FIXME: we can do better here.
1655 int32 temp;
1656 if (!GenerateParam(&temp, generator))
1657 return false;
1658 p->SetInt32(temp);
1659 return true;
1660 }
1661 };
1662
1663 template <>
1664 struct GenerateTraits<printing::PdfRenderSettings> {
1665 static bool Generate(printing::PdfRenderSettings *p, Generator* generator) {
1666 gfx::Rect area;
1667 int dpi;
1668 bool autorotate;
1669 if (!GenerateParam(&area, generator))
1670 return false;
1671 if (!GenerateParam(&dpi, generator))
1672 return false;
1673 if (!GenerateParam(&autorotate, generator))
1674 return false;
1675 *p = printing::PdfRenderSettings(area, dpi, autorotate);
1676 return true;
1677 }
1678 };
1679
1680 template <>
1681 struct GenerateTraits<remoting::ScreenResolution> {
1682 static bool Generate(remoting::ScreenResolution* p, Generator* generator) {
1683 webrtc::DesktopSize size;
1684 webrtc::DesktopVector vector;
1685 if (!GenerateParam(&size, generator))
1686 return false;
1687 if (!GenerateParam(&vector, generator))
1688 return false;
1689 *p = remoting::ScreenResolution(size, vector);
1690 return true;
1691 }
1692 };
1693
1694 template <>
1695 struct GenerateTraits<SkBitmap> {
1696 static bool Generate(SkBitmap* p, Generator* generator) {
1697 // TODO(mbarbella): This should actually generate something.
1698 *p = SkBitmap();
1699 return true;
1700 }
1701 };
1702
1703 template <>
1704 struct GenerateTraits<storage::DataElement> {
1705 static bool Generate(storage::DataElement* p, Generator* generator) {
1706 switch (RandInRange(4)) {
1707 case storage::DataElement::Type::TYPE_BYTES: {
1708 if (RandEvent(2)) {
1709 p->SetToEmptyBytes();
1710 } else {
1711 // TODO(mbarbella): Occasionally send more data here.
1712 char data[256];
1713 int data_len = RandInRange(sizeof(data));
1714 generator->GenerateBytes(&data[0], data_len);
1715 p->SetToBytes(&data[0], data_len);
1716 }
1717 return true;
1718 }
1719 case storage::DataElement::Type::TYPE_FILE: {
1720 base::FilePath path;
1721 uint64 offset;
1722 uint64 length;
1723 base::Time modification_time;
1724 if (!GenerateParam(&path, generator))
1725 return false;
1726 if (!GenerateParam(&offset, generator))
1727 return false;
1728 if (!GenerateParam(&length, generator))
1729 return false;
1730 if (!GenerateParam(&modification_time, generator))
1731 return false;
1732 p->SetToFilePathRange(path, offset, length, modification_time);
1733 return true;
1734 }
1735 case storage::DataElement::Type::TYPE_BLOB: {
1736 std::string uuid;
1737 uint64 offset;
1738 uint64 length;
1739 if (!GenerateParam(&uuid, generator))
1740 return false;
1741 if (!GenerateParam(&offset, generator))
1742 return false;
1743 if (!GenerateParam(&length, generator))
1744 return false;
1745 p->SetToBlobRange(uuid, offset, length);
1746 return true;
1747 }
1748 case storage::DataElement::Type::TYPE_FILE_FILESYSTEM: {
1749 GURL url;
1750 uint64 offset;
1751 uint64 length;
1752 base::Time modification_time;
1753 if (!GenerateParam(&url, generator))
1754 return false;
1755 if (!GenerateParam(&offset, generator))
1756 return false;
1757 if (!GenerateParam(&length, generator))
1758 return false;
1759 if (!GenerateParam(&modification_time, generator))
1760 return false;
1761 p->SetToFileSystemUrlRange(url, offset, length, modification_time);
1762 return true;
1763 }
1764 default: {
1765 NOTREACHED();
1766 return false;
1767 }
1768 }
1769 }
1770 };
1771
1772 template <>
1773 struct GenerateTraits<ui::LatencyInfo> {
1774 static bool Generate(ui::LatencyInfo* p, Generator* generator) {
1775 // TODO(inferno): Add param traits for |latency_components|.
1776 p->input_coordinates_size = static_cast<uint32>(
1777 RandInRange(ui::LatencyInfo::kMaxInputCoordinates + 1));
1778 if (!GenerateParamArray(
1779 &p->input_coordinates[0], p->input_coordinates_size, generator))
1780 return false;
1781 if (!GenerateParam(&p->trace_id, generator))
1782 return false;
1783 if (!GenerateParam(&p->terminated, generator))
1784 return false;
1785 return true;
1786 }
1787 };
1788
1789 template <>
1790 struct GenerateTraits<ui::LatencyInfo::InputCoordinate> {
1791 static bool Generate(
1792 ui::LatencyInfo::InputCoordinate* p, Generator* generator) {
1793 float x;
1794 float y;
1795 if (!GenerateParam(&x, generator))
1796 return false;
1797 if (!GenerateParam(&y, generator))
1798 return false;
1799 *p = ui::LatencyInfo::InputCoordinate(x, y);
1800 return true;
1801 }
1802 };
1803
1804 template <>
1805 struct GenerateTraits<url::Origin> {
1806 static bool Generate(url::Origin* p, Generator* generator) {
1807 std::string origin;
1808 if (!GenerateParam(&origin, generator))
1809 return false;
1810 *p = url::Origin(origin);
1811 return true;
1812 }
1813 };
1814
1815 template <>
1816 struct GenerateTraits<URLPattern> {
1817 static bool Generate(URLPattern* p, Generator* generator) {
1818 int valid_schemes;
1819 std::string host;
1820 std::string port;
1821 std::string path;
1822 if (!GenerateParam(&valid_schemes, generator))
1823 return false;
1824 if (!GenerateParam(&host, generator))
1825 return false;
1826 if (!GenerateParam(&port, generator))
1827 return false;
1828 if (!GenerateParam(&path, generator))
1829 return false;
1830 *p = URLPattern(valid_schemes);
1831 p->SetHost(host);
1832 p->SetPort(port);
1833 p->SetPath(path);
1834 return true;
1835 }
1836 };
1837
1838 template <>
1839 struct GenerateTraits<webrtc::DesktopSize> {
1840 static bool Generate(webrtc::DesktopSize* p, Generator* generator) {
1841 int32_t width;
1842 int32_t height;
1843 if (!GenerateParam(&width, generator))
1844 return false;
1845 if (!GenerateParam(&height, generator))
1846 return false;
1847 *p = webrtc::DesktopSize(width, height);
1848 return true;
1849 }
1850 };
1851
1852 template <>
1853 struct GenerateTraits<webrtc::DesktopVector> {
1854 static bool Generate(webrtc::DesktopVector* p, Generator* generator) {
1855 int32_t x;
1856 int32_t y;
1857 if (!GenerateParam(&x, generator))
1858 return false;
1859 if (!GenerateParam(&y, generator))
1860 return false;
1861 p->set(x, y);
1862 return true;
1863 }
1864 };
1865
1866 template <>
1867 struct GenerateTraits<webrtc::DesktopRect> {
1868 static bool Generate(webrtc::DesktopRect* p, Generator* generator) {
1869 int32_t left;
1870 int32_t top;
1871 int32_t right;
1872 int32_t bottom;
1873 if (!GenerateParam(&left, generator))
1874 return false;
1875 if (!GenerateParam(&top, generator))
1876 return false;
1877 if (!GenerateParam(&right, generator))
1878 return false;
1879 if (!GenerateParam(&bottom, generator))
1880 return false;
1881 *p = webrtc::DesktopRect::MakeLTRB(left, top, right, bottom);
1882 return true;
1883 }
1884 };
1885
1886 template <>
1887 struct GenerateTraits<webrtc::MouseCursor> {
1888 static bool Generate(webrtc::MouseCursor* p, Generator* generator) {
1889 webrtc::DesktopVector hotspot;
1890 if (!GenerateParam(&hotspot, generator))
1891 return false;
1892 // Using a small size here to avoid OOM or overflow on image allocation.
1893 webrtc::DesktopSize size(RandInRange(100), RandInRange(100));
1894 p->set_image(new webrtc::BasicDesktopFrame(size));
1895 p->set_hotspot(hotspot);
1896 return true;
1897 }
1898 };
1899
1900 // Redefine macros to generate generating from traits declarations.
1901 // STRUCT declarations cause corresponding STRUCT_TRAITS declarations to occur.
1902 #undef IPC_STRUCT_BEGIN
1903 #undef IPC_STRUCT_BEGIN_WITH_PARENT
1904 #undef IPC_STRUCT_MEMBER
1905 #undef IPC_STRUCT_END
1906 #define IPC_STRUCT_BEGIN_WITH_PARENT(struct_name, parent) \
1907 IPC_STRUCT_BEGIN(struct_name)
1908 #define IPC_STRUCT_BEGIN(struct_name) IPC_STRUCT_TRAITS_BEGIN(struct_name)
1909 #define IPC_STRUCT_MEMBER(type, name, ...) IPC_STRUCT_TRAITS_MEMBER(name)
1910 #define IPC_STRUCT_END() IPC_STRUCT_TRAITS_END()
1911
1912 // Set up so next include will generate generate trait classes.
1913 #undef IPC_STRUCT_TRAITS_BEGIN
1914 #undef IPC_STRUCT_TRAITS_MEMBER
1915 #undef IPC_STRUCT_TRAITS_PARENT
1916 #undef IPC_STRUCT_TRAITS_END
1917 #define IPC_STRUCT_TRAITS_BEGIN(struct_name) \
1918 template <> \
1919 struct GenerateTraits<struct_name> { \
1920 static bool Generate(struct_name *p, Generator* generator) {
1921
1922 #define IPC_STRUCT_TRAITS_MEMBER(name) \
1923 if (!GenerateParam(&p->name, generator)) \
1924 return false;
1925
1926 #define IPC_STRUCT_TRAITS_PARENT(type) \
1927 if (!GenerateParam(static_cast<type*>(p), generator)) \
1928 return false;
1929
1930 #define IPC_STRUCT_TRAITS_END() \
1931 return true; \
1932 } \
1933 };
1934
1935 // If |condition| isn't met, the messsge will fail to serialize. Try
1936 // increasingly smaller ranges until we find one that happens to meet
1937 // the condition, or fail trying.
1938 #undef IPC_ENUM_TRAITS_VALIDATE
1939 #define IPC_ENUM_TRAITS_VALIDATE(enum_name, condition) \
1940 template <> \
1941 struct GenerateTraits<enum_name> { \
1942 static bool Generate(enum_name* p, Generator* generator) { \
1943 for (int shift = 30; shift; --shift) { \
1944 for (int tries = 0; tries < 2; ++tries) { \
1945 int value = RandInRange(1 << shift); \
1946 if (condition) { \
1947 *reinterpret_cast<int*>(p) = value; \
1948 return true; \
1949 } \
1950 } \
1951 } \
1952 std::cerr << "failed to satisfy " << #condition << "\n"; \
1953 return false; \
1954 } \
1955 };
1956
1957 // Bring them into existence.
1958 #include "tools/ipc_fuzzer/message_lib/all_messages.h"
1959 #include "ipc/ipc_message_null_macros.h"
1960
1961 // Redefine macros to generate generating funtions
1962 #undef IPC_MESSAGE_DECL
1963 #define IPC_MESSAGE_DECL(kind, type, name, in, out, ilist, olist) \
1964 IPC_##kind##_##type##_GENERATE(name, in, out, ilist, olist)
1965
1966 #define IPC_EMPTY_CONTROL_GENERATE(name, in, out, ilist, olist) \
1967 IPC::Message* generator_for_##name(Generator* generator) { \
1968 return new name(); \
1969 }
1970
1971 #define IPC_EMPTY_ROUTED_GENERATE(name, in, out, ilist, olist) \
1972 IPC::Message* generator_for_##name(Generator* generator) { \
1973 return new name(RandInRange(MAX_FAKE_ROUTING_ID)); \
1974 }
1975
1976 #define IPC_ASYNC_CONTROL_GENERATE(name, in, out, ilist, olist) \
1977 IPC::Message* generator_for_##name(Generator* generator) { \
1978 IPC_TUPLE_IN_##in ilist p; \
1979 if (GenerateParam(&p, generator)) { \
1980 return new name(IPC_MEMBERS_IN_##in(p)); \
1981 } \
1982 std::cerr << "Don't know how to generate " << #name << "\n"; \
1983 return 0; \
1984 }
1985
1986 #define IPC_ASYNC_ROUTED_GENERATE(name, in, out, ilist, olist) \
1987 IPC::Message* generator_for_##name(Generator* generator) { \
1988 IPC_TUPLE_IN_##in ilist p; \
1989 if (GenerateParam(&p, generator)) { \
1990 return new name(RandInRange(MAX_FAKE_ROUTING_ID) \
1991 IPC_COMMA_##in \
1992 IPC_MEMBERS_IN_##in(p)); \
1993 } \
1994 std::cerr << "Don't know how to generate " << #name << "\n"; \
1995 return 0; \
1996 }
1997
1998 #define IPC_SYNC_CONTROL_GENERATE(name, in, out, ilist, olist) \
1999 IPC::Message* generator_for_##name(Generator* generator) { \
2000 IPC_TUPLE_IN_##in ilist p; \
2001 if (GenerateParam(&p, generator)) { \
2002 return new name(IPC_MEMBERS_IN_##in(p) \
2003 IPC_COMMA_AND_##out(IPC_COMMA_##in) \
2004 IPC_MEMBERS_OUT_##out()); \
2005 } \
2006 std::cerr << "Don't know how to generate " << #name << "\n"; \
2007 return 0; \
2008 }
2009
2010 #define IPC_SYNC_ROUTED_GENERATE(name, in, out, ilist, olist) \
2011 IPC::Message* generator_for_##name(Generator* generator) { \
2012 IPC_TUPLE_IN_##in ilist p; \
2013 if (GenerateParam(&p, generator)) { \
2014 return new name(RandInRange(MAX_FAKE_ROUTING_ID) \
2015 IPC_COMMA_OR_##out(IPC_COMMA_##in) \
2016 IPC_MEMBERS_IN_##in(p) \
2017 IPC_COMMA_AND_##out(IPC_COMMA_##in) \
2018 IPC_MEMBERS_OUT_##out()); \
2019 } \
2020 std::cerr << "Don't know how to generate " << #name << "\n"; \
2021 return 0; \
2022 }
2023
2024 #define MAX_FAKE_ROUTING_ID 15
2025
2026 #define IPC_MEMBERS_IN_0(p)
2027 #define IPC_MEMBERS_IN_1(p) get<0>(p)
2028 #define IPC_MEMBERS_IN_2(p) get<0>(p), get<1>(p)
2029 #define IPC_MEMBERS_IN_3(p) get<0>(p), get<1>(p), get<2>(p)
2030 #define IPC_MEMBERS_IN_4(p) get<0>(p), get<1>(p), get<2>(p), get<3>(p)
2031 #define IPC_MEMBERS_IN_5(p) get<0>(p), get<1>(p), get<2>(p), get<3>(p), \
2032 get<4>(p)
2033
2034 #define IPC_MEMBERS_OUT_0()
2035 #define IPC_MEMBERS_OUT_1() NULL
2036 #define IPC_MEMBERS_OUT_2() NULL, NULL
2037 #define IPC_MEMBERS_OUT_3() NULL, NULL, NULL
2038 #define IPC_MEMBERS_OUT_4() NULL, NULL, NULL, NULL
2039 #define IPC_MEMBERS_OUT_5() NULL, NULL, NULL, NULL, NULL
2040
2041 #include "tools/ipc_fuzzer/message_lib/all_messages.h"
2042 #include "ipc/ipc_message_null_macros.h"
2043
2044 void PopulateGeneratorFunctionVector(
2045 GeneratorFunctionVector *function_vector) {
2046 #undef IPC_MESSAGE_DECL
2047 #define IPC_MESSAGE_DECL(kind, type, name, in, out, ilist, olist) \
2048 function_vector->push_back(generator_for_##name);
2049 #include "tools/ipc_fuzzer/message_lib/all_messages.h"
2050 }
2051
2052 static const char kCountSwitch[] = "count";
2053 static const char kHelpSwitch[] = "help";
2054
2055 int GenerateMain(int argc, char** argv) {
2056 base::CommandLine::Init(argc, argv);
2057 base::CommandLine* cmd = base::CommandLine::ForCurrentProcess();
2058 base::CommandLine::StringVector args = cmd->GetArgs();
2059
2060 if (args.size() != 1 || cmd->HasSwitch(kHelpSwitch)) {
2061 std::cerr << "Usage: ipc_fuzzer_generate [--help] [--count=n] outfile\n";
2062 return EXIT_FAILURE;
2063 }
2064 base::FilePath::StringType output_file_name = args[0];
2065
2066 int message_count = 1000;
2067 if (cmd->HasSwitch(kCountSwitch))
2068 message_count = atoi(cmd->GetSwitchValueASCII(kCountSwitch).c_str());
2069
2070 InitRand();
2071
2072 PopulateGeneratorFunctionVector(&g_function_vector);
2073 std::cerr << "Counted " << g_function_vector.size()
2074 << " distinct messages present in chrome.\n";
2075
2076 Generator* generator = new GeneratorImpl();
2077 MessageVector message_vector;
2078
2079 int bad_count = 0;
2080 if (message_count < 0) {
2081 // Enumerate them all.
2082 for (size_t i = 0; i < g_function_vector.size(); ++i) {
2083 if (IPC::Message* new_message = (*g_function_vector[i])(generator))
2084 message_vector.push_back(new_message);
2085 else
2086 bad_count += 1;
2087 }
2088 } else {
2089 // Generate a random batch.
2090 for (int i = 0; i < message_count; ++i) {
2091 size_t index = RandInRange(g_function_vector.size());
2092 if (IPC::Message* new_message = (*g_function_vector[index])(generator))
2093 message_vector.push_back(new_message);
2094 else
2095 bad_count += 1;
2096 }
2097 }
2098
2099 std::cerr << "Failed to generate " << bad_count << " messages.\n";
2100
2101 if (!MessageFile::Write(base::FilePath(output_file_name), message_vector))
2102 return EXIT_FAILURE;
2103
2104 return EXIT_SUCCESS;
2105 }
2106
2107 } // namespace ipc_fuzzer
2108
2109 int main(int argc, char** argv) {
2110 return ipc_fuzzer::GenerateMain(argc, argv);
2111 }
OLDNEW
« no previous file with comments | « tools/ipc_fuzzer/mutate/fuzzer_main.cc ('k') | tools/ipc_fuzzer/mutate/generator.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698