Unregister from GCM when the only GCM app is removed
[chromium-blink-merge.git] / tools / ipc_fuzzer / mutate / generate.cc
blob6d8137dd2ac24c8b15925de4036af0f0d054afd6
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.
5 #include <stdlib.h>
7 #include <algorithm>
8 #include <iostream>
9 #include <ostream>
10 #include <set>
11 #include <vector>
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"
26 #if defined(OS_POSIX)
27 #include <unistd.h>
28 #endif
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"
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
42 namespace IPC {
43 class Message;
44 } // namespace IPC
46 namespace {
47 // For breaking deep recursion.
48 int g_depth = 0;
49 } // namespace
51 namespace ipc_fuzzer {
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;
76 typedef IPC::Message* (*GeneratorFunction)(Generator*);
77 typedef std::vector<GeneratorFunction> GeneratorFunctionVector;
78 GeneratorFunctionVector g_function_vector;
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;
101 template <typename T>
102 void GenerateFloatingType(T* value) {
103 *value = RandDouble();
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;
115 class GeneratorImpl : public Generator {
116 public:
117 GeneratorImpl() {}
118 virtual ~GeneratorImpl() {}
120 void GenerateBool(bool* value) override {
121 *value = RandInRange(2) ? true: false;
124 void GenerateInt(int* value) override {
125 GenerateIntegralType<int>(value);
128 void GenerateLong(long* value) override {
129 GenerateIntegralType<long>(value);
132 void GenerateSize(size_t* value) override {
133 GenerateIntegralType<size_t>(value);
136 void GenerateUChar(unsigned char* value) override {
137 GenerateIntegralType<unsigned char>(value);
140 void GenerateWChar(wchar_t* value) override {
141 GenerateIntegralType<wchar_t>(value);
144 void GenerateUInt16(uint16* value) override {
145 GenerateIntegralType<uint16>(value);
148 void GenerateUInt32(uint32* value) override {
149 GenerateIntegralType<uint32>(value);
152 void GenerateInt64(int64* value) override {
153 GenerateIntegralType<int64>(value);
156 void GenerateUInt64(uint64* value) override {
157 GenerateIntegralType<uint64>(value);
160 void GenerateFloat(float* value) override {
161 GenerateFloatingType<float>(value);
164 void GenerateDouble(double* value) override {
165 GenerateFloatingType<double>(value);
168 void GenerateString(std::string* value) override {
169 GenerateStringType<std::string>(value);
172 void GenerateString16(base::string16* value) override {
173 GenerateStringType<base::string16>(value);
176 void GenerateData(char* data, int length) override {
177 for (int i = 0; i < length; ++i) {
178 GenerateIntegralType<char>(&data[i]);
182 void GenerateBytes(void* data, int data_len) override {
183 GenerateData(static_cast<char*>(data), data_len);
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;
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);
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;
210 return true;
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;
222 template <>
223 struct GenerateTraits<int> {
224 static bool Generate(int* p, Generator* generator) {
225 generator->GenerateInt(p);
226 return true;
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;
238 template <>
239 struct GenerateTraits<long> {
240 static bool Generate(long* p, Generator* generator) {
241 generator->GenerateLong(p);
242 return true;
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;
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;
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;
270 template <>
271 struct GenerateTraits<short> {
272 static bool Generate(short* p, Generator* generator) {
273 generator->GenerateUInt16(reinterpret_cast<uint16*>(p));
274 return true;
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;
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;
294 template <>
295 struct GenerateTraits<unsigned char> {
296 static bool Generate(unsigned char* p, Generator* generator) {
297 generator->GenerateUChar(p);
298 return true;
302 template <>
303 struct GenerateTraits<wchar_t> {
304 static bool Generate(wchar_t* p, Generator* generator) {
305 generator->GenerateWChar(p);
306 return true;
310 template <>
311 struct GenerateTraits<float> {
312 static bool Generate(float* p, Generator* generator) {
313 generator->GenerateFloat(p);
314 return true;
318 template <>
319 struct GenerateTraits<double> {
320 static bool Generate(double* p, Generator* generator) {
321 generator->GenerateDouble(p);
322 return true;
326 template <>
327 struct GenerateTraits<std::string> {
328 static bool Generate(std::string* p, Generator* generator) {
329 generator->GenerateString(p);
330 return true;
334 template <>
335 struct GenerateTraits<base::string16> {
336 static bool Generate(base::string16* p, Generator* generator) {
337 generator->GenerateString16(p);
338 return true;
342 // Specializations to generate tuples.
343 template <>
344 struct GenerateTraits<Tuple<>> {
345 static bool Generate(Tuple<>* p, Generator* generator) {
346 return true;
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);
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);
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);
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);
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);
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;
411 --g_depth;
412 return true;
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;
427 p->insert(a);
429 --g_depth;
430 return true;
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;
446 p->insert(place_holder);
448 --g_depth;
449 return true;
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;
464 p->insert(place_holder);
466 --g_depth;
467 return true;
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);
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;
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;
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;
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;
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;
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;
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;
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))
568 case base::Value::TYPE_BOOLEAN: {
569 bool tmp;
570 generator->GenerateBool(&tmp);
571 p->Set(index, new base::FundamentalValue(tmp));
572 break;
574 case base::Value::TYPE_INTEGER: {
575 int tmp;
576 generator->GenerateInt(&tmp);
577 p->Set(index, new base::FundamentalValue(tmp));
578 break;
580 case base::Value::TYPE_DOUBLE: {
581 double tmp;
582 generator->GenerateDouble(&tmp);
583 p->Set(index, new base::FundamentalValue(tmp));
584 break;
586 case base::Value::TYPE_STRING: {
587 std::string tmp;
588 generator->GenerateString(&tmp);
589 p->Set(index, new base::StringValue(tmp));
590 break;
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;
600 case base::Value::TYPE_DICTIONARY: {
601 base::DictionaryValue* tmp = new base::DictionaryValue();
602 GenerateParam(tmp, generator);
603 p->Set(index, tmp);
604 break;
606 case base::Value::TYPE_LIST: {
607 base::ListValue* tmp = new base::ListValue();
608 GenerateParam(tmp, generator);
609 p->Set(index, tmp);
610 break;
612 case base::Value::TYPE_NULL:
613 default:
614 break;
617 --g_depth;
618 return true;
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))
632 case base::Value::TYPE_BOOLEAN: {
633 bool tmp;
634 generator->GenerateBool(&tmp);
635 p->SetWithoutPathExpansion(property, new base::FundamentalValue(tmp));
636 break;
638 case base::Value::TYPE_INTEGER: {
639 int tmp;
640 generator->GenerateInt(&tmp);
641 p->SetWithoutPathExpansion(property, new base::FundamentalValue(tmp));
642 break;
644 case base::Value::TYPE_DOUBLE: {
645 double tmp;
646 generator->GenerateDouble(&tmp);
647 p->SetWithoutPathExpansion(property, new base::FundamentalValue(tmp));
648 break;
650 case base::Value::TYPE_STRING: {
651 std::string tmp;
652 generator->GenerateString(&tmp);
653 p->SetWithoutPathExpansion(property, new base::StringValue(tmp));
654 break;
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;
665 case base::Value::TYPE_DICTIONARY: {
666 base::DictionaryValue* tmp = new base::DictionaryValue();
667 GenerateParam(tmp, generator);
668 p->SetWithoutPathExpansion(property, tmp);
669 break;
671 case base::Value::TYPE_LIST: {
672 base::ListValue* tmp = new base::ListValue();
673 GenerateParam(tmp, generator);
674 p->SetWithoutPathExpansion(property, tmp);
675 break;
677 case base::Value::TYPE_NULL:
678 default:
679 break;
682 --g_depth;
683 return true;
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;
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;
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;
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;
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;
752 default:
753 // Generate nothing to handle the no frame case.
754 return true;
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;
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;
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;
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;
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;
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());
834 return true;
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;
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)
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;
871 *p = content::IndexedDBKey(array);
872 return true;
874 case blink::WebIDBKeyTypeBinary: {
875 std::string binary;
876 if (!GenerateParam(&binary, generator)) {
877 --g_depth;
878 return false;
880 *p = content::IndexedDBKey(binary);
881 return true;
883 case blink::WebIDBKeyTypeString: {
884 base::string16 string;
885 if (!GenerateParam(&string, generator))
886 return false;
887 *p = content::IndexedDBKey(string);
888 return true;
890 case blink::WebIDBKeyTypeDate:
891 case blink::WebIDBKeyTypeNumber: {
892 double number;
893 if (!GenerateParam(&number, generator)) {
894 --g_depth;
895 return false;
897 *p = content::IndexedDBKey(number, web_type);
898 return true;
900 case blink::WebIDBKeyTypeInvalid:
901 case blink::WebIDBKeyTypeNull: {
902 *p = content::IndexedDBKey(web_type);
903 return true;
905 default: {
906 NOTREACHED();
907 --g_depth;
908 return false;
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;
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;
945 case 1: {
946 base::string16 string;
947 if (!GenerateParam(&string, generator))
948 return false;
949 *p = content::IndexedDBKeyPath(string);
950 break;
952 case 2: {
953 *p = content::IndexedDBKeyPath();
954 break;
957 return true;
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;
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;
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;
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(3)) {
996 case content::SyntheticGestureParams::GestureType::
997 SMOOTH_SCROLL_GESTURE: {
998 content::SyntheticSmoothScrollGestureParams* params =
999 new content::SyntheticSmoothScrollGestureParams();
1000 if (!GenerateParam(&params->anchor, generator))
1001 return false;
1002 if (!GenerateParam(&params->distances, generator))
1003 return false;
1004 if (!GenerateParam(&params->prevent_fling, generator))
1005 return false;
1006 if (!GenerateParam(&params->speed_in_pixels_s, generator))
1007 return false;
1008 gesture_params.reset(params);
1009 break;
1011 case content::SyntheticGestureParams::GestureType::PINCH_GESTURE: {
1012 content::SyntheticPinchGestureParams* params =
1013 new content::SyntheticPinchGestureParams();
1014 if (!GenerateParam(&params->scale_factor, generator))
1015 return false;
1016 if (!GenerateParam(&params->anchor, generator))
1017 return false;
1018 if (!GenerateParam(&params->relative_pointer_speed_in_pixels_s,
1019 generator))
1020 return false;
1021 gesture_params.reset(params);
1022 break;
1024 case content::SyntheticGestureParams::GestureType::TAP_GESTURE: {
1025 content::SyntheticTapGestureParams* params =
1026 new content::SyntheticTapGestureParams();
1027 if (!GenerateParam(&params->position, generator))
1028 return false;
1029 if (!GenerateParam(&params->duration_ms, generator))
1030 return false;
1031 gesture_params.reset(params);
1032 break;
1035 p->set_gesture_params(gesture_params.Pass());
1036 return true;
1040 template <>
1041 struct GenerateTraits<content::WebCursor> {
1042 static bool Generate(content::WebCursor* p, Generator* generator) {
1043 blink::WebCursorInfo::Type type;
1044 if (!GenerateParam(&type, generator))
1045 return false;
1046 content::WebCursor::CursorInfo info(type);
1048 // Omitting |externalHandle| since it is not serialized.
1049 if (!GenerateParam(&info.hotspot, generator))
1050 return false;
1051 if (!GenerateParam(&info.image_scale_factor, generator))
1052 return false;
1053 if (!GenerateParam(&info.custom_image, generator))
1054 return false;
1055 *p = content::WebCursor(info);
1056 return true;
1060 template <>
1061 struct GenerateTraits<ContentSettingsPattern> {
1062 static bool Generate(ContentSettingsPattern* p, Generator* generator) {
1063 // TODO(mbarbella): This can crash if a pattern is generated from a random
1064 // string. We could carefully generate a pattern or fix pattern generation.
1065 *p = ContentSettingsPattern();
1066 return true;
1070 template <>
1071 struct GenerateTraits<ExtensionMsg_PermissionSetStruct> {
1072 static bool Generate(ExtensionMsg_PermissionSetStruct* p,
1073 Generator* generator) {
1074 // TODO(mbarbella): This should actually generate something.
1075 *p = ExtensionMsg_PermissionSetStruct();
1076 return true;
1080 template <>
1081 struct GenerateTraits<extensions::URLPatternSet> {
1082 static bool Generate(extensions::URLPatternSet* p, Generator* generator) {
1083 std::set<URLPattern> patterns;
1084 if (!GenerateParam(&patterns, generator))
1085 return false;
1086 *p = extensions::URLPatternSet(patterns);
1087 return true;
1091 template <>
1092 struct GenerateTraits<gfx::Point> {
1093 static bool Generate(gfx::Point *p, Generator* generator) {
1094 int x;
1095 int y;
1096 if (!GenerateParam(&x, generator))
1097 return false;
1098 if (!GenerateParam(&y, generator))
1099 return false;
1100 p->SetPoint(x, y);
1101 return true;
1105 template <>
1106 struct GenerateTraits<gfx::PointF> {
1107 static bool Generate(gfx::PointF *p, Generator* generator) {
1108 float x;
1109 float y;
1110 if (!GenerateParam(&x, generator))
1111 return false;
1112 if (!GenerateParam(&y, generator))
1113 return false;
1114 p->SetPoint(x, y);
1115 return true;
1119 template <>
1120 struct GenerateTraits<gfx::Rect> {
1121 static bool Generate(gfx::Rect *p, Generator* generator) {
1122 gfx::Point origin;
1123 gfx::Size size;
1124 if (!GenerateParam(&origin, generator))
1125 return false;
1126 if (!GenerateParam(&size, generator))
1127 return false;
1128 p->set_origin(origin);
1129 p->set_size(size);
1130 return true;
1134 template <>
1135 struct GenerateTraits<gfx::RectF> {
1136 static bool Generate(gfx::RectF *p, Generator* generator) {
1137 gfx::PointF origin;
1138 gfx::SizeF size;
1139 if (!GenerateParam(&origin, generator))
1140 return false;
1141 if (!GenerateParam(&size, generator))
1142 return false;
1143 p->set_origin(origin);
1144 p->set_size(size);
1145 return true;
1149 template <>
1150 struct GenerateTraits<gfx::Range> {
1151 static bool Generate(gfx::Range *p, Generator* generator) {
1152 size_t start;
1153 size_t end;
1154 if (!GenerateParam(&start, generator))
1155 return false;
1156 if (!GenerateParam(&end, generator))
1157 return false;
1158 *p = gfx::Range(start, end);
1159 return true;
1163 template <>
1164 struct GenerateTraits<gfx::Size> {
1165 static bool Generate(gfx::Size* p, Generator* generator) {
1166 int w;
1167 int h;
1168 if (!GenerateParam(&w, generator))
1169 return false;
1170 if (!GenerateParam(&h, generator))
1171 return false;
1172 p->SetSize(w, h);
1173 return true;
1177 template <>
1178 struct GenerateTraits<gfx::SizeF> {
1179 static bool Generate(gfx::SizeF* p, Generator* generator) {
1180 float w;
1181 float h;
1182 if (!GenerateParam(&w, generator))
1183 return false;
1184 if (!GenerateParam(&h, generator))
1185 return false;
1186 p->SetSize(w, h);
1187 return true;
1191 template <>
1192 struct GenerateTraits<gfx::Transform> {
1193 static bool Generate(gfx::Transform* p, Generator* generator) {
1194 SkMScalar matrix[16];
1195 if (!GenerateParamArray(&matrix[0], arraysize(matrix), generator))
1196 return false;
1197 *p = gfx::Transform(matrix[0], matrix[1], matrix[2], matrix[3], matrix[4],
1198 matrix[5], matrix[6], matrix[7], matrix[8], matrix[9],
1199 matrix[10], matrix[11], matrix[12], matrix[13],
1200 matrix[14], matrix[15]);
1201 return true;
1205 template <>
1206 struct GenerateTraits<gfx::Vector2d> {
1207 static bool Generate(gfx::Vector2d *p, Generator* generator) {
1208 int x;
1209 int y;
1210 if (!GenerateParam(&x, generator))
1211 return false;
1212 if (!GenerateParam(&y, generator))
1213 return false;
1214 *p = gfx::Vector2d(x, y);
1215 return true;
1219 template <>
1220 struct GenerateTraits<gfx::Vector2dF> {
1221 static bool Generate(gfx::Vector2dF *p, Generator* generator) {
1222 float x;
1223 float y;
1224 if (!GenerateParam(&x, generator))
1225 return false;
1226 if (!GenerateParam(&y, generator))
1227 return false;
1228 *p = gfx::Vector2dF(x, y);
1229 return true;
1233 template <>
1234 struct GenerateTraits<gpu::Mailbox> {
1235 static bool Generate(gpu::Mailbox* p, Generator* generator) {
1236 generator->GenerateBytes(p->name, sizeof(p->name));
1237 return true;
1241 template <>
1242 struct GenerateTraits<gpu::MailboxHolder> {
1243 static bool Generate(gpu::MailboxHolder* p, Generator* generator) {
1244 gpu::Mailbox mailbox;
1245 uint32_t texture_target;
1246 uint32_t sync_point;
1247 if (!GenerateParam(&mailbox, generator))
1248 return false;
1249 if (!GenerateParam(&texture_target, generator))
1250 return false;
1251 if (!GenerateParam(&sync_point, generator))
1252 return false;
1253 *p = gpu::MailboxHolder(mailbox, texture_target, sync_point);
1254 return true;
1258 template <>
1259 struct GenerateTraits<gpu::ValueState> {
1260 static bool Generate(gpu::ValueState* p, Generator* generator) {
1261 gpu::ValueState state;
1262 if (!GenerateParamArray(&state.float_value[0], 4, generator))
1263 return false;
1264 if (!GenerateParamArray(&state.int_value[0], 4, generator))
1265 return false;
1266 *p = state;
1267 return true;
1271 template <>
1272 struct GenerateTraits<GURL> {
1273 static bool Generate(GURL* p, Generator* generator) {
1274 const char url_chars[] = "Ahtp0:/.?+\\%&#";
1275 size_t count = RandInRange(100);
1276 std::string random_url;
1277 for (size_t i = 0; i < count; ++i)
1278 random_url += url_chars[RandInRange(sizeof(url_chars) - 1)];
1279 int selector = RandInRange(10);
1280 if (selector == 0)
1281 random_url = std::string("http://") + random_url;
1282 else if (selector == 1)
1283 random_url = std::string("file://") + random_url;
1284 else if (selector == 2)
1285 random_url = std::string("javascript:") + random_url;
1286 else if (selector == 2)
1287 random_url = std::string("data:") + random_url;
1288 *p = GURL(random_url);
1289 return true;
1293 template <>
1294 struct GenerateTraits<IPC::Message> {
1295 static bool Generate(IPC::Message *p, Generator* generator) {
1296 if (g_function_vector.empty())
1297 return false;
1298 size_t index = RandInRange(g_function_vector.size());
1299 IPC::Message* ipc_message = (*g_function_vector[index])(generator);
1300 if (!ipc_message)
1301 return false;
1302 p = ipc_message;
1303 return true;
1307 template <>
1308 struct GenerateTraits<IPC::PlatformFileForTransit> {
1309 static bool Generate(IPC::PlatformFileForTransit* p, Generator* generator) {
1310 // TODO(inferno): I don't think we can generate real ones due to check on
1311 // construct.
1312 *p = IPC::InvalidPlatformFileForTransit();
1313 return true;
1317 template <>
1318 struct GenerateTraits<IPC::ChannelHandle> {
1319 static bool Generate(IPC::ChannelHandle* p, Generator* generator) {
1320 // TODO(inferno): Add way to generate real channel handles.
1321 #if defined(OS_WIN)
1322 HANDLE fake_handle = (HANDLE)(RandU64());
1323 p->pipe = IPC::ChannelHandle::PipeHandle(fake_handle);
1324 return true;
1325 #elif defined(OS_POSIX)
1326 return
1327 GenerateParam(&p->name, generator) &&
1328 GenerateParam(&p->socket, generator);
1329 #endif
1333 template <>
1334 struct GenerateTraits<media::AudioParameters> {
1335 static bool Generate(media::AudioParameters* p, Generator* generator) {
1336 int format;
1337 int channel_layout;
1338 int sample_rate;
1339 int bits_per_sample;
1340 int frames_per_buffer;
1341 int channels;
1342 int effects;
1343 if (!GenerateParam(&format, generator))
1344 return false;
1345 if (!GenerateParam(&channel_layout, generator))
1346 return false;
1347 if (!GenerateParam(&sample_rate, generator))
1348 return false;
1349 if (!GenerateParam(&bits_per_sample, generator))
1350 return false;
1351 if (!GenerateParam(&frames_per_buffer, generator))
1352 return false;
1353 if (!GenerateParam(&channels, generator))
1354 return false;
1355 if (!GenerateParam(&effects, generator))
1356 return false;
1357 media::AudioParameters params(
1358 static_cast<media::AudioParameters::Format>(format),
1359 static_cast<media::ChannelLayout>(channel_layout), channels,
1360 sample_rate, bits_per_sample, frames_per_buffer, effects);
1361 *p = params;
1362 return true;
1366 template <>
1367 struct GenerateTraits<media::VideoCaptureFormat> {
1368 static bool Generate(media::VideoCaptureFormat* p, Generator* generator) {
1369 int frame_size_width;
1370 int frame_size_height;
1371 int pixel_format;
1372 if (!GenerateParam(&frame_size_height, generator))
1373 return false;
1374 if (!GenerateParam(&frame_size_width, generator))
1375 return false;
1376 if (!GenerateParam(&pixel_format, generator))
1377 return false;
1378 if (!GenerateParam(&p->frame_rate, generator))
1379 return false;
1380 p->frame_size.SetSize(frame_size_width, frame_size_height);
1381 p->pixel_format = static_cast<media::VideoPixelFormat>(pixel_format);
1382 return true;
1386 template <>
1387 struct GenerateTraits<net::LoadTimingInfo> {
1388 static bool Generate(net::LoadTimingInfo* p, Generator* generator) {
1389 return GenerateParam(&p->socket_log_id, generator) &&
1390 GenerateParam(&p->socket_reused, generator) &&
1391 GenerateParam(&p->request_start_time, generator) &&
1392 GenerateParam(&p->request_start, generator) &&
1393 GenerateParam(&p->proxy_resolve_start, generator) &&
1394 GenerateParam(&p->proxy_resolve_end, generator) &&
1395 GenerateParam(&p->connect_timing.dns_start, generator) &&
1396 GenerateParam(&p->connect_timing.dns_end, generator) &&
1397 GenerateParam(&p->connect_timing.connect_start, generator) &&
1398 GenerateParam(&p->connect_timing.connect_end, generator) &&
1399 GenerateParam(&p->connect_timing.ssl_start, generator) &&
1400 GenerateParam(&p->connect_timing.ssl_end, generator) &&
1401 GenerateParam(&p->send_start, generator) &&
1402 GenerateParam(&p->send_end, generator) &&
1403 GenerateParam(&p->receive_headers_end, generator);
1407 template <>
1408 struct GenerateTraits<net::HostPortPair> {
1409 static bool Generate(net::HostPortPair* p, Generator* generator) {
1410 std::string host;
1411 uint16 port;
1412 if (!GenerateParam(&host, generator))
1413 return false;
1414 if (!GenerateParam(&port, generator))
1415 return false;
1416 p->set_host(host);
1417 p->set_port(port);
1418 return true;
1422 template <>
1423 struct GenerateTraits<net::IPEndPoint> {
1424 static bool Generate(net::IPEndPoint* p, Generator* generator) {
1425 net::IPAddressNumber address;
1426 int port;
1427 if (!GenerateParam(&address, generator))
1428 return false;
1429 if (!GenerateParam(&port, generator))
1430 return false;
1431 net::IPEndPoint ip_endpoint(address, port);
1432 *p = ip_endpoint;
1433 return true;
1437 template <>
1438 struct GenerateTraits<network_hints::LookupRequest> {
1439 static bool Generate(network_hints::LookupRequest* p, Generator* generator) {
1440 network_hints::LookupRequest request;
1441 if (!GenerateParam(&request.hostname_list, generator))
1442 return false;
1443 *p = request;
1444 return true;
1448 // PP_ traits.
1449 template <>
1450 struct GenerateTraits<PP_Bool> {
1451 static bool Generate(PP_Bool *p, Generator* generator) {
1452 bool tmp;
1453 if (!GenerateParam(&tmp, generator))
1454 return false;
1455 *p = PP_FromBool(tmp);
1456 return true;
1460 template <>
1461 struct GenerateTraits<PP_KeyInformation> {
1462 static bool Generate(PP_KeyInformation* p, Generator* generator) {
1463 // TODO(mbarbella): This should actually generate something.
1464 *p = PP_KeyInformation();
1465 return true;
1469 template <>
1470 struct GenerateTraits<PP_NetAddress_Private> {
1471 static bool Generate(PP_NetAddress_Private *p, Generator* generator) {
1472 p->size = RandInRange(sizeof(p->data) + 1);
1473 generator->GenerateBytes(&p->data, p->size);
1474 return true;
1478 template <>
1479 struct GenerateTraits<ppapi::PPB_X509Certificate_Fields> {
1480 static bool Generate(ppapi::PPB_X509Certificate_Fields* p,
1481 Generator* generator) {
1482 // TODO(mbarbella): This should actually generate something.
1483 return true;
1487 template <>
1488 struct GenerateTraits<ppapi::proxy::PPBFlash_DrawGlyphs_Params> {
1489 static bool Generate(ppapi::proxy::PPBFlash_DrawGlyphs_Params* p,
1490 Generator* generator) {
1491 // TODO(mbarbella): This should actually generate something.
1492 *p = ppapi::proxy::PPBFlash_DrawGlyphs_Params();
1493 return true;
1497 template <>
1498 struct GenerateTraits<ppapi::proxy::ResourceMessageCallParams> {
1499 static bool Generate(
1500 ppapi::proxy::ResourceMessageCallParams *p, Generator* generator) {
1501 PP_Resource resource;
1502 int32_t sequence;
1503 bool has_callback;
1504 if (!GenerateParam(&resource, generator))
1505 return false;
1506 if (!GenerateParam(&sequence, generator))
1507 return false;
1508 if (!GenerateParam(&has_callback, generator))
1509 return false;
1510 *p = ppapi::proxy::ResourceMessageCallParams(resource, sequence);
1511 if (has_callback)
1512 p->set_has_callback();
1513 return true;
1517 template <>
1518 struct GenerateTraits<ppapi::proxy::ResourceMessageReplyParams> {
1519 static bool Generate(
1520 ppapi::proxy::ResourceMessageReplyParams *p, Generator* generator) {
1521 PP_Resource resource;
1522 int32_t sequence;
1523 int32_t result;
1524 if (!GenerateParam(&resource, generator))
1525 return false;
1526 if (!GenerateParam(&sequence, generator))
1527 return false;
1528 if (!GenerateParam(&result, generator))
1529 return false;
1530 *p = ppapi::proxy::ResourceMessageReplyParams(resource, sequence);
1531 p->set_result(result);
1532 return true;
1536 template <>
1537 struct GenerateTraits<ppapi::proxy::SerializedHandle> {
1538 static bool Generate(ppapi::proxy::SerializedHandle* p,
1539 Generator* generator) {
1540 // TODO(mbarbella): This should actually generate something.
1541 *p = ppapi::proxy::SerializedHandle();
1542 return true;
1546 template <>
1547 struct GenerateTraits<ppapi::proxy::SerializedFontDescription> {
1548 static bool Generate(ppapi::proxy::SerializedFontDescription* p,
1549 Generator* generator) {
1550 // TODO(mbarbella): This should actually generate something.
1551 *p = ppapi::proxy::SerializedFontDescription();
1552 return true;
1556 template <>
1557 struct GenerateTraits<ppapi::proxy::SerializedTrueTypeFontDesc> {
1558 static bool Generate(ppapi::proxy::SerializedTrueTypeFontDesc* p,
1559 Generator* generator) {
1560 // TODO(mbarbella): This should actually generate something.
1561 *p = ppapi::proxy::SerializedTrueTypeFontDesc();
1562 return true;
1566 template <>
1567 struct GenerateTraits<ppapi::proxy::SerializedVar> {
1568 static bool Generate(ppapi::proxy::SerializedVar* p, Generator* generator) {
1569 // TODO(mbarbella): This should actually generate something.
1570 *p = ppapi::proxy::SerializedVar();
1571 return true;
1575 template <>
1576 struct GenerateTraits<ppapi::HostResource> {
1577 static bool Generate(ppapi::HostResource *p, Generator* generator) {
1578 PP_Instance instance;
1579 PP_Resource resource;
1580 if (!GenerateParam(&instance, generator))
1581 return false;
1582 if (!GenerateParam(&resource, generator))
1583 return false;
1584 p->SetHostResource(instance, resource);
1585 return true;
1589 template <>
1590 struct GenerateTraits<ppapi::PepperFilePath> {
1591 static bool Generate(ppapi::PepperFilePath *p, Generator* generator) {
1592 unsigned domain = RandInRange(ppapi::PepperFilePath::DOMAIN_MAX_VALID+1);
1593 base::FilePath path;
1594 if (!GenerateParam(&path, generator))
1595 return false;
1596 *p = ppapi::PepperFilePath(
1597 static_cast<ppapi::PepperFilePath::Domain>(domain), path);
1598 return true;
1602 template <>
1603 struct GenerateTraits<ppapi::PpapiPermissions> {
1604 static bool Generate(ppapi::PpapiPermissions *p, Generator* generator) {
1605 uint32_t bits;
1606 if (!GenerateParam(&bits, generator))
1607 return false;
1608 *p = ppapi::PpapiPermissions(bits);
1609 return true;
1613 template <>
1614 struct GenerateTraits<ppapi::SocketOptionData> {
1615 static bool Generate(ppapi::SocketOptionData *p, Generator* generator) {
1616 // FIXME: we can do better here.
1617 int32 temp;
1618 if (!GenerateParam(&temp, generator))
1619 return false;
1620 p->SetInt32(temp);
1621 return true;
1625 template <>
1626 struct GenerateTraits<printing::PdfRenderSettings> {
1627 static bool Generate(printing::PdfRenderSettings *p, Generator* generator) {
1628 gfx::Rect area;
1629 int dpi;
1630 bool autorotate;
1631 if (!GenerateParam(&area, generator))
1632 return false;
1633 if (!GenerateParam(&dpi, generator))
1634 return false;
1635 if (!GenerateParam(&autorotate, generator))
1636 return false;
1637 *p = printing::PdfRenderSettings(area, dpi, autorotate);
1638 return true;
1642 template <>
1643 struct GenerateTraits<remoting::ScreenResolution> {
1644 static bool Generate(remoting::ScreenResolution* p, Generator* generator) {
1645 webrtc::DesktopSize size;
1646 webrtc::DesktopVector vector;
1647 if (!GenerateParam(&size, generator))
1648 return false;
1649 if (!GenerateParam(&vector, generator))
1650 return false;
1651 *p = remoting::ScreenResolution(size, vector);
1652 return true;
1656 template <>
1657 struct GenerateTraits<SkBitmap> {
1658 static bool Generate(SkBitmap* p, Generator* generator) {
1659 // TODO(mbarbella): This should actually generate something.
1660 *p = SkBitmap();
1661 return true;
1665 template <>
1666 struct GenerateTraits<storage::DataElement> {
1667 static bool Generate(storage::DataElement* p, Generator* generator) {
1668 switch (RandInRange(4)) {
1669 case storage::DataElement::Type::TYPE_BYTES: {
1670 if (RandEvent(2)) {
1671 p->SetToEmptyBytes();
1672 } else {
1673 // TODO(mbarbella): Occasionally send more data here.
1674 char data[256];
1675 int data_len = RandInRange(sizeof(data));
1676 generator->GenerateBytes(&data[0], data_len);
1677 p->SetToBytes(&data[0], data_len);
1679 return true;
1681 case storage::DataElement::Type::TYPE_FILE: {
1682 base::FilePath path;
1683 uint64 offset;
1684 uint64 length;
1685 base::Time modification_time;
1686 if (!GenerateParam(&path, generator))
1687 return false;
1688 if (!GenerateParam(&offset, generator))
1689 return false;
1690 if (!GenerateParam(&length, generator))
1691 return false;
1692 if (!GenerateParam(&modification_time, generator))
1693 return false;
1694 p->SetToFilePathRange(path, offset, length, modification_time);
1695 return true;
1697 case storage::DataElement::Type::TYPE_BLOB: {
1698 std::string uuid;
1699 uint64 offset;
1700 uint64 length;
1701 if (!GenerateParam(&uuid, generator))
1702 return false;
1703 if (!GenerateParam(&offset, generator))
1704 return false;
1705 if (!GenerateParam(&length, generator))
1706 return false;
1707 p->SetToBlobRange(uuid, offset, length);
1708 return true;
1710 case storage::DataElement::Type::TYPE_FILE_FILESYSTEM: {
1711 GURL url;
1712 uint64 offset;
1713 uint64 length;
1714 base::Time modification_time;
1715 if (!GenerateParam(&url, generator))
1716 return false;
1717 if (!GenerateParam(&offset, generator))
1718 return false;
1719 if (!GenerateParam(&length, generator))
1720 return false;
1721 if (!GenerateParam(&modification_time, generator))
1722 return false;
1723 p->SetToFileSystemUrlRange(url, offset, length, modification_time);
1724 return true;
1726 default: {
1727 NOTREACHED();
1728 return false;
1734 template <>
1735 struct GenerateTraits<ui::LatencyInfo> {
1736 static bool Generate(ui::LatencyInfo* p, Generator* generator) {
1737 // TODO(inferno): Add param traits for |latency_components|.
1738 p->input_coordinates_size = static_cast<uint32>(
1739 RandInRange(ui::LatencyInfo::kMaxInputCoordinates + 1));
1740 if (!GenerateParamArray(
1741 &p->input_coordinates[0], p->input_coordinates_size, generator))
1742 return false;
1743 if (!GenerateParam(&p->trace_id, generator))
1744 return false;
1745 if (!GenerateParam(&p->terminated, generator))
1746 return false;
1747 return true;
1751 template <>
1752 struct GenerateTraits<ui::LatencyInfo::InputCoordinate> {
1753 static bool Generate(
1754 ui::LatencyInfo::InputCoordinate* p, Generator* generator) {
1755 float x;
1756 float y;
1757 if (!GenerateParam(&x, generator))
1758 return false;
1759 if (!GenerateParam(&y, generator))
1760 return false;
1761 *p = ui::LatencyInfo::InputCoordinate(x, y);
1762 return true;
1766 template <>
1767 struct GenerateTraits<url::Origin> {
1768 static bool Generate(url::Origin* p, Generator* generator) {
1769 std::string origin;
1770 if (!GenerateParam(&origin, generator))
1771 return false;
1772 *p = url::Origin(origin);
1773 return true;
1777 template <>
1778 struct GenerateTraits<URLPattern> {
1779 static bool Generate(URLPattern* p, Generator* generator) {
1780 int valid_schemes;
1781 std::string host;
1782 std::string port;
1783 std::string path;
1784 if (!GenerateParam(&valid_schemes, generator))
1785 return false;
1786 if (!GenerateParam(&host, generator))
1787 return false;
1788 if (!GenerateParam(&port, generator))
1789 return false;
1790 if (!GenerateParam(&path, generator))
1791 return false;
1792 *p = URLPattern(valid_schemes);
1793 p->SetHost(host);
1794 p->SetPort(port);
1795 p->SetPath(path);
1796 return true;
1800 template <>
1801 struct GenerateTraits<webrtc::DesktopSize> {
1802 static bool Generate(webrtc::DesktopSize* p, Generator* generator) {
1803 int32_t width;
1804 int32_t height;
1805 if (!GenerateParam(&width, generator))
1806 return false;
1807 if (!GenerateParam(&height, generator))
1808 return false;
1809 *p = webrtc::DesktopSize(width, height);
1810 return true;
1814 template <>
1815 struct GenerateTraits<webrtc::DesktopVector> {
1816 static bool Generate(webrtc::DesktopVector* p, Generator* generator) {
1817 int32_t x;
1818 int32_t y;
1819 if (!GenerateParam(&x, generator))
1820 return false;
1821 if (!GenerateParam(&y, generator))
1822 return false;
1823 p->set(x, y);
1824 return true;
1828 template <>
1829 struct GenerateTraits<webrtc::DesktopRect> {
1830 static bool Generate(webrtc::DesktopRect* p, Generator* generator) {
1831 int32_t left;
1832 int32_t top;
1833 int32_t right;
1834 int32_t bottom;
1835 if (!GenerateParam(&left, generator))
1836 return false;
1837 if (!GenerateParam(&top, generator))
1838 return false;
1839 if (!GenerateParam(&right, generator))
1840 return false;
1841 if (!GenerateParam(&bottom, generator))
1842 return false;
1843 *p = webrtc::DesktopRect::MakeLTRB(left, top, right, bottom);
1844 return true;
1848 template <>
1849 struct GenerateTraits<webrtc::MouseCursor> {
1850 static bool Generate(webrtc::MouseCursor* p, Generator* generator) {
1851 webrtc::DesktopVector hotspot;
1852 if (!GenerateParam(&hotspot, generator))
1853 return false;
1854 // Using a small size here to avoid OOM or overflow on image allocation.
1855 webrtc::DesktopSize size(RandInRange(100), RandInRange(100));
1856 p->set_image(new webrtc::BasicDesktopFrame(size));
1857 p->set_hotspot(hotspot);
1858 return true;
1862 // Redefine macros to generate generating from traits declarations.
1863 // STRUCT declarations cause corresponding STRUCT_TRAITS declarations to occur.
1864 #undef IPC_STRUCT_BEGIN
1865 #undef IPC_STRUCT_BEGIN_WITH_PARENT
1866 #undef IPC_STRUCT_MEMBER
1867 #undef IPC_STRUCT_END
1868 #define IPC_STRUCT_BEGIN_WITH_PARENT(struct_name, parent) \
1869 IPC_STRUCT_BEGIN(struct_name)
1870 #define IPC_STRUCT_BEGIN(struct_name) IPC_STRUCT_TRAITS_BEGIN(struct_name)
1871 #define IPC_STRUCT_MEMBER(type, name, ...) IPC_STRUCT_TRAITS_MEMBER(name)
1872 #define IPC_STRUCT_END() IPC_STRUCT_TRAITS_END()
1874 // Set up so next include will generate generate trait classes.
1875 #undef IPC_STRUCT_TRAITS_BEGIN
1876 #undef IPC_STRUCT_TRAITS_MEMBER
1877 #undef IPC_STRUCT_TRAITS_PARENT
1878 #undef IPC_STRUCT_TRAITS_END
1879 #define IPC_STRUCT_TRAITS_BEGIN(struct_name) \
1880 template <> \
1881 struct GenerateTraits<struct_name> { \
1882 static bool Generate(struct_name *p, Generator* generator) {
1884 #define IPC_STRUCT_TRAITS_MEMBER(name) \
1885 if (!GenerateParam(&p->name, generator)) \
1886 return false;
1888 #define IPC_STRUCT_TRAITS_PARENT(type) \
1889 if (!GenerateParam(static_cast<type*>(p), generator)) \
1890 return false;
1892 #define IPC_STRUCT_TRAITS_END() \
1893 return true; \
1897 // If |condition| isn't met, the messsge will fail to serialize. Try
1898 // increasingly smaller ranges until we find one that happens to meet
1899 // the condition, or fail trying.
1900 #undef IPC_ENUM_TRAITS_VALIDATE
1901 #define IPC_ENUM_TRAITS_VALIDATE(enum_name, condition) \
1902 template <> \
1903 struct GenerateTraits<enum_name> { \
1904 static bool Generate(enum_name* p, Generator* generator) { \
1905 for (int shift = 30; shift; --shift) { \
1906 for (int tries = 0; tries < 2; ++tries) { \
1907 int value = RandInRange(1 << shift); \
1908 if (condition) { \
1909 *reinterpret_cast<int*>(p) = value; \
1910 return true; \
1914 std::cerr << "failed to satisfy " << #condition << "\n"; \
1915 return false; \
1919 // Bring them into existence.
1920 #include "tools/ipc_fuzzer/message_lib/all_messages.h"
1921 #include "ipc/ipc_message_null_macros.h"
1923 // Redefine macros to generate generating funtions
1924 #undef IPC_MESSAGE_DECL
1925 #define IPC_MESSAGE_DECL(kind, type, name, in, out, ilist, olist) \
1926 IPC_##kind##_##type##_GENERATE(name, in, out, ilist, olist)
1928 #define IPC_EMPTY_CONTROL_GENERATE(name, in, out, ilist, olist) \
1929 IPC::Message* generator_for_##name(Generator* generator) { \
1930 return new name(); \
1933 #define IPC_EMPTY_ROUTED_GENERATE(name, in, out, ilist, olist) \
1934 IPC::Message* generator_for_##name(Generator* generator) { \
1935 return new name(RandInRange(MAX_FAKE_ROUTING_ID)); \
1938 #define IPC_ASYNC_CONTROL_GENERATE(name, in, out, ilist, olist) \
1939 IPC::Message* generator_for_##name(Generator* generator) { \
1940 IPC_TUPLE_IN_##in ilist p; \
1941 if (GenerateParam(&p, generator)) { \
1942 return new name(IPC_MEMBERS_IN_##in(p)); \
1944 std::cerr << "Don't know how to generate " << #name << "\n"; \
1945 return 0; \
1948 #define IPC_ASYNC_ROUTED_GENERATE(name, in, out, ilist, olist) \
1949 IPC::Message* generator_for_##name(Generator* generator) { \
1950 IPC_TUPLE_IN_##in ilist p; \
1951 if (GenerateParam(&p, generator)) { \
1952 return new name(RandInRange(MAX_FAKE_ROUTING_ID) \
1953 IPC_COMMA_##in \
1954 IPC_MEMBERS_IN_##in(p)); \
1956 std::cerr << "Don't know how to generate " << #name << "\n"; \
1957 return 0; \
1960 #define IPC_SYNC_CONTROL_GENERATE(name, in, out, ilist, olist) \
1961 IPC::Message* generator_for_##name(Generator* generator) { \
1962 IPC_TUPLE_IN_##in ilist p; \
1963 if (GenerateParam(&p, generator)) { \
1964 return new name(IPC_MEMBERS_IN_##in(p) \
1965 IPC_COMMA_AND_##out(IPC_COMMA_##in) \
1966 IPC_MEMBERS_OUT_##out()); \
1968 std::cerr << "Don't know how to generate " << #name << "\n"; \
1969 return 0; \
1972 #define IPC_SYNC_ROUTED_GENERATE(name, in, out, ilist, olist) \
1973 IPC::Message* generator_for_##name(Generator* generator) { \
1974 IPC_TUPLE_IN_##in ilist p; \
1975 if (GenerateParam(&p, generator)) { \
1976 return new name(RandInRange(MAX_FAKE_ROUTING_ID) \
1977 IPC_COMMA_OR_##out(IPC_COMMA_##in) \
1978 IPC_MEMBERS_IN_##in(p) \
1979 IPC_COMMA_AND_##out(IPC_COMMA_##in) \
1980 IPC_MEMBERS_OUT_##out()); \
1982 std::cerr << "Don't know how to generate " << #name << "\n"; \
1983 return 0; \
1986 #define MAX_FAKE_ROUTING_ID 15
1988 #define IPC_MEMBERS_IN_0(p)
1989 #define IPC_MEMBERS_IN_1(p) get<0>(p)
1990 #define IPC_MEMBERS_IN_2(p) get<0>(p), get<1>(p)
1991 #define IPC_MEMBERS_IN_3(p) get<0>(p), get<1>(p), get<2>(p)
1992 #define IPC_MEMBERS_IN_4(p) get<0>(p), get<1>(p), get<2>(p), get<3>(p)
1993 #define IPC_MEMBERS_IN_5(p) get<0>(p), get<1>(p), get<2>(p), get<3>(p), \
1994 get<4>(p)
1996 #define IPC_MEMBERS_OUT_0()
1997 #define IPC_MEMBERS_OUT_1() NULL
1998 #define IPC_MEMBERS_OUT_2() NULL, NULL
1999 #define IPC_MEMBERS_OUT_3() NULL, NULL, NULL
2000 #define IPC_MEMBERS_OUT_4() NULL, NULL, NULL, NULL
2001 #define IPC_MEMBERS_OUT_5() NULL, NULL, NULL, NULL, NULL
2003 #include "tools/ipc_fuzzer/message_lib/all_messages.h"
2004 #include "ipc/ipc_message_null_macros.h"
2006 void PopulateGeneratorFunctionVector(
2007 GeneratorFunctionVector *function_vector) {
2008 #undef IPC_MESSAGE_DECL
2009 #define IPC_MESSAGE_DECL(kind, type, name, in, out, ilist, olist) \
2010 function_vector->push_back(generator_for_##name);
2011 #include "tools/ipc_fuzzer/message_lib/all_messages.h"
2014 static const char kCountSwitch[] = "count";
2015 static const char kHelpSwitch[] = "help";
2017 int GenerateMain(int argc, char** argv) {
2018 base::CommandLine::Init(argc, argv);
2019 base::CommandLine* cmd = base::CommandLine::ForCurrentProcess();
2020 base::CommandLine::StringVector args = cmd->GetArgs();
2022 if (args.size() != 1 || cmd->HasSwitch(kHelpSwitch)) {
2023 std::cerr << "Usage: ipc_fuzzer_generate [--help] [--count=n] outfile\n";
2024 return EXIT_FAILURE;
2026 base::FilePath::StringType output_file_name = args[0];
2028 int message_count = 1000;
2029 if (cmd->HasSwitch(kCountSwitch))
2030 message_count = atoi(cmd->GetSwitchValueASCII(kCountSwitch).c_str());
2032 InitRand();
2034 PopulateGeneratorFunctionVector(&g_function_vector);
2035 std::cerr << "Counted " << g_function_vector.size()
2036 << " distinct messages present in chrome.\n";
2038 Generator* generator = new GeneratorImpl();
2039 MessageVector message_vector;
2041 int bad_count = 0;
2042 if (message_count < 0) {
2043 // Enumerate them all.
2044 for (size_t i = 0; i < g_function_vector.size(); ++i) {
2045 if (IPC::Message* new_message = (*g_function_vector[i])(generator))
2046 message_vector.push_back(new_message);
2047 else
2048 bad_count += 1;
2050 } else {
2051 // Generate a random batch.
2052 for (int i = 0; i < message_count; ++i) {
2053 size_t index = RandInRange(g_function_vector.size());
2054 if (IPC::Message* new_message = (*g_function_vector[index])(generator))
2055 message_vector.push_back(new_message);
2056 else
2057 bad_count += 1;
2061 std::cerr << "Failed to generate " << bad_count << " messages.\n";
2063 if (!MessageFile::Write(base::FilePath(output_file_name), message_vector))
2064 return EXIT_FAILURE;
2066 return EXIT_SUCCESS;
2069 } // namespace ipc_fuzzer
2071 int main(int argc, char** argv) {
2072 return ipc_fuzzer::GenerateMain(argc, argv);