Add ICU message format support
[chromium-blink-merge.git] / tools / ipc_fuzzer / fuzzer / fuzzer.cc
blob0ff09eff26477fbd9b98144234b21bc3ddf88c62
1 // Copyright 2015 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 <iostream>
6 #include <set>
7 #include <string>
8 #include <utility>
9 #include <vector>
11 #include "base/strings/string_util.h"
12 #include "ipc/ipc_message.h"
13 #include "ipc/ipc_message_utils.h"
14 #include "ipc/ipc_switches.h"
15 #include "ipc/ipc_sync_channel.h"
16 #include "ipc/ipc_sync_message.h"
17 #include "tools/ipc_fuzzer/fuzzer/fuzzer.h"
18 #include "tools/ipc_fuzzer/fuzzer/rand_util.h"
19 #include "tools/ipc_fuzzer/message_lib/message_cracker.h"
20 #include "tools/ipc_fuzzer/message_lib/message_file.h"
22 #if defined(OS_POSIX)
23 #include <unistd.h>
24 #endif
26 // First include of all message files to provide basic types.
27 #include "tools/ipc_fuzzer/message_lib/all_messages.h"
28 #include "tools/ipc_fuzzer/message_lib/all_message_null_macros.h"
30 #if defined(COMPILER_GCC)
31 #define PRETTY_FUNCTION __PRETTY_FUNCTION__
32 #elif defined(COMPILER_MSVC)
33 #define PRETTY_FUNCTION __FUNCSIG__
34 #else
35 #define PRETTY_FUNCTION __FUNCTION__
36 #endif
38 namespace IPC {
39 class Message;
40 } // namespace IPC
42 namespace {
43 // For breaking deep recursion.
44 int g_depth = 0;
45 } // namespace
47 namespace ipc_fuzzer {
49 FuzzerFunctionVector g_function_vector;
51 bool Fuzzer::ShouldGenerate() {
52 return false;
55 // Partially-specialized class that knows how to handle a given type.
56 template <class P>
57 struct FuzzTraits {
58 static bool Fuzz(P* p, Fuzzer *fuzzer) {
59 // This is the catch-all for types we don't have enough information
60 // to generate.
61 std::cerr << "Can't handle " << PRETTY_FUNCTION << "\n";
62 return false;
66 // Template function to invoke partially-specialized class method.
67 template <class P>
68 static bool FuzzParam(P* p, Fuzzer* fuzzer) {
69 return FuzzTraits<P>::Fuzz(p, fuzzer);
72 template <class P>
73 static bool FuzzParamArray(P* p, size_t length, Fuzzer* fuzzer) {
74 for (size_t i = 0; i < length; i++, p++) {
75 if (!FuzzTraits<P>::Fuzz(p, fuzzer))
76 return false;
78 return true;
81 // Specializations to generate primitive types.
82 template <>
83 struct FuzzTraits<bool> {
84 static bool Fuzz(bool* p, Fuzzer* fuzzer) {
85 fuzzer->FuzzBool(p);
86 return true;
90 template <>
91 struct FuzzTraits<int> {
92 static bool Fuzz(int* p, Fuzzer* fuzzer) {
93 fuzzer->FuzzInt(p);
94 return true;
98 template <>
99 struct FuzzTraits<unsigned int> {
100 static bool Fuzz(unsigned int* p, Fuzzer* fuzzer) {
101 fuzzer->FuzzInt(reinterpret_cast<int*>(p));
102 return true;
106 template <>
107 struct FuzzTraits<long> {
108 static bool Fuzz(long* p, Fuzzer* fuzzer) {
109 fuzzer->FuzzLong(p);
110 return true;
114 template <>
115 struct FuzzTraits<unsigned long> {
116 static bool Fuzz(unsigned long* p, Fuzzer* fuzzer) {
117 fuzzer->FuzzLong(reinterpret_cast<long*>(p));
118 return true;
122 template <>
123 struct FuzzTraits<long long> {
124 static bool Fuzz(long long* p, Fuzzer* fuzzer) {
125 fuzzer->FuzzInt64(reinterpret_cast<int64*>(p));
126 return true;
130 template <>
131 struct FuzzTraits<unsigned long long> {
132 static bool Fuzz(unsigned long long* p, Fuzzer* fuzzer) {
133 fuzzer->FuzzInt64(reinterpret_cast<int64*>(p));
134 return true;
138 template <>
139 struct FuzzTraits<short> {
140 static bool Fuzz(short* p, Fuzzer* fuzzer) {
141 fuzzer->FuzzUInt16(reinterpret_cast<uint16*>(p));
142 return true;
146 template <>
147 struct FuzzTraits<unsigned short> {
148 static bool Fuzz(unsigned short* p, Fuzzer* fuzzer) {
149 fuzzer->FuzzUInt16(reinterpret_cast<uint16*>(p));
150 return true;
154 template <>
155 struct FuzzTraits<char> {
156 static bool Fuzz(char* p, Fuzzer* fuzzer) {
157 fuzzer->FuzzUChar(reinterpret_cast<unsigned char*>(p));
158 return true;
162 template <>
163 struct FuzzTraits<unsigned char> {
164 static bool Fuzz(unsigned char* p, Fuzzer* fuzzer) {
165 fuzzer->FuzzUChar(p);
166 return true;
170 template <>
171 struct FuzzTraits<wchar_t> {
172 static bool Fuzz(wchar_t* p, Fuzzer* fuzzer) {
173 fuzzer->FuzzWChar(p);
174 return true;
178 template <>
179 struct FuzzTraits<float> {
180 static bool Fuzz(float* p, Fuzzer* fuzzer) {
181 fuzzer->FuzzFloat(p);
182 return true;
186 template <>
187 struct FuzzTraits<double> {
188 static bool Fuzz(double* p, Fuzzer* fuzzer) {
189 fuzzer->FuzzDouble(p);
190 return true;
194 template <>
195 struct FuzzTraits<std::string> {
196 static bool Fuzz(std::string* p, Fuzzer* fuzzer) {
197 fuzzer->FuzzString(p);
198 return true;
202 template <>
203 struct FuzzTraits<base::string16> {
204 static bool Fuzz(base::string16* p, Fuzzer* fuzzer) {
205 fuzzer->FuzzString16(p);
206 return true;
210 // Specializations for tuples.
211 template <>
212 struct FuzzTraits<base::Tuple<>> {
213 static bool Fuzz(base::Tuple<>* p, Fuzzer* fuzzer) {
214 return true;
218 template <class A>
219 struct FuzzTraits<base::Tuple<A>> {
220 static bool Fuzz(base::Tuple<A>* p, Fuzzer* fuzzer) {
221 return FuzzParam(&base::get<0>(*p), fuzzer);
225 template <class A, class B>
226 struct FuzzTraits<base::Tuple<A, B>> {
227 static bool Fuzz(base::Tuple<A, B>* p, Fuzzer* fuzzer) {
228 return
229 FuzzParam(&base::get<0>(*p), fuzzer) &&
230 FuzzParam(&base::get<1>(*p), fuzzer);
234 template <class A, class B, class C>
235 struct FuzzTraits<base::Tuple<A, B, C>> {
236 static bool Fuzz(base::Tuple<A, B, C>* p, Fuzzer* fuzzer) {
237 return
238 FuzzParam(&base::get<0>(*p), fuzzer) &&
239 FuzzParam(&base::get<1>(*p), fuzzer) &&
240 FuzzParam(&base::get<2>(*p), fuzzer);
244 template <class A, class B, class C, class D>
245 struct FuzzTraits<base::Tuple<A, B, C, D>> {
246 static bool Fuzz(base::Tuple<A, B, C, D>* p, Fuzzer* fuzzer) {
247 return
248 FuzzParam(&base::get<0>(*p), fuzzer) &&
249 FuzzParam(&base::get<1>(*p), fuzzer) &&
250 FuzzParam(&base::get<2>(*p), fuzzer) &&
251 FuzzParam(&base::get<3>(*p), fuzzer);
255 template <class A, class B, class C, class D, class E>
256 struct FuzzTraits<base::Tuple<A, B, C, D, E>> {
257 static bool Fuzz(base::Tuple<A, B, C, D, E>* p, Fuzzer* fuzzer) {
258 return
259 FuzzParam(&base::get<0>(*p), fuzzer) &&
260 FuzzParam(&base::get<1>(*p), fuzzer) &&
261 FuzzParam(&base::get<2>(*p), fuzzer) &&
262 FuzzParam(&base::get<3>(*p), fuzzer) &&
263 FuzzParam(&base::get<4>(*p), fuzzer);
267 // Specializations for containers.
268 template <class A>
269 struct FuzzTraits<std::vector<A> > {
270 static bool Fuzz(std::vector<A>* p, Fuzzer* fuzzer) {
271 ++g_depth;
272 size_t count = p->size();
273 if (fuzzer->ShouldGenerate()) {
274 count = g_depth > 3 ? 0 : RandElementCount();
275 p->resize(count);
277 for (size_t i = 0; i < count; ++i) {
278 if (!FuzzParam(&p->at(i), fuzzer)) {
279 --g_depth;
280 return false;
283 --g_depth;
284 return true;
288 template <class A>
289 struct FuzzTraits<std::set<A> > {
290 static bool Fuzz(std::set<A>* p, Fuzzer* fuzzer) {
291 if (!fuzzer->ShouldGenerate()) {
292 std::set<A> result;
293 typename std::set<A>::iterator it;
294 for (it = p->begin(); it != p->end(); ++it) {
295 A item = *it;
296 if (!FuzzParam(&item, fuzzer))
297 return false;
298 result.insert(item);
300 *p = result;
301 return true;
304 static int g_depth = 0;
305 size_t count = ++g_depth > 3 ? 0 : RandElementCount();
306 A a;
307 for (size_t i = 0; i < count; ++i) {
308 if (!FuzzParam(&a, fuzzer)) {
309 --g_depth;
310 return false;
312 p->insert(a);
314 --g_depth;
315 return true;
319 template <class A, class B>
320 struct FuzzTraits<std::map<A, B> > {
321 static bool Fuzz(std::map<A, B>* p, Fuzzer* fuzzer) {
322 if (!fuzzer->ShouldGenerate()) {
323 typename std::map<A, B>::iterator it;
324 for (it = p->begin(); it != p->end(); ++it) {
325 if (!FuzzParam(&it->second, fuzzer))
326 return false;
328 return true;
331 static int g_depth = 0;
332 size_t count = ++g_depth > 3 ? 0 : RandElementCount();
333 std::pair<A, B> place_holder;
334 for (size_t i = 0; i < count; ++i) {
335 if (!FuzzParam(&place_holder, fuzzer)) {
336 --g_depth;
337 return false;
339 p->insert(place_holder);
341 --g_depth;
342 return true;
346 template <class A, class B, class C, class D>
347 struct FuzzTraits<std::map<A, B, C, D>> {
348 static bool Fuzz(std::map<A, B, C, D>* p, Fuzzer* fuzzer) {
349 if (!fuzzer->ShouldGenerate()) {
350 typename std::map<A, B, C, D>::iterator it;
351 for (it = p->begin(); it != p->end(); ++it) {
352 if (!FuzzParam(&it->second, fuzzer))
353 return false;
355 return true;
358 static int g_depth = 0;
359 size_t count = ++g_depth > 3 ? 0 : RandElementCount();
360 std::pair<A, B> place_holder;
361 for (size_t i = 0; i < count; ++i) {
362 if (!FuzzParam(&place_holder, fuzzer)) {
363 --g_depth;
364 return false;
366 p->insert(place_holder);
368 --g_depth;
369 return true;
373 template <class A, class B>
374 struct FuzzTraits<std::pair<A, B> > {
375 static bool Fuzz(std::pair<A, B>* p, Fuzzer* fuzzer) {
376 return
377 FuzzParam(&p->first, fuzzer) &&
378 FuzzParam(&p->second, fuzzer);
382 // Specializations for hand-coded types.
384 template <>
385 struct FuzzTraits<base::FilePath> {
386 static bool Fuzz(base::FilePath* p, Fuzzer* fuzzer) {
387 if (!fuzzer->ShouldGenerate()) {
388 base::FilePath::StringType path = p->value();
389 if(!FuzzParam(&path, fuzzer))
390 return false;
391 *p = base::FilePath(path);
392 return true;
395 const char path_chars[] = "ACz0/.~:";
396 size_t count = RandInRange(60);
397 base::FilePath::StringType random_path;
398 for (size_t i = 0; i < count; ++i)
399 random_path += path_chars[RandInRange(sizeof(path_chars) - 1)];
400 *p = base::FilePath(random_path);
401 return true;
405 template <>
406 struct FuzzTraits<base::File::Error> {
407 static bool Fuzz(base::File::Error* p, Fuzzer* fuzzer) {
408 int value = static_cast<int>(*p);
409 if (!FuzzParam(&value, fuzzer))
410 return false;
411 *p = static_cast<base::File::Error>(value);
412 return true;
416 template <>
417 struct FuzzTraits<base::File::Info> {
418 static bool Fuzz(base::File::Info* p, Fuzzer* fuzzer) {
419 double last_modified = p->last_modified.ToDoubleT();
420 double last_accessed = p->last_accessed.ToDoubleT();
421 double creation_time = p->creation_time.ToDoubleT();
422 if (!FuzzParam(&p->size, fuzzer))
423 return false;
424 if (!FuzzParam(&p->is_directory, fuzzer))
425 return false;
426 if (!FuzzParam(&last_modified, fuzzer))
427 return false;
428 if (!FuzzParam(&last_accessed, fuzzer))
429 return false;
430 if (!FuzzParam(&creation_time, fuzzer))
431 return false;
432 p->last_modified = base::Time::FromDoubleT(last_modified);
433 p->last_accessed = base::Time::FromDoubleT(last_accessed);
434 p->creation_time = base::Time::FromDoubleT(creation_time);
435 return true;
439 template <>
440 struct FuzzTraits<base::NullableString16> {
441 static bool Fuzz(base::NullableString16* p, Fuzzer* fuzzer) {
442 base::string16 string = p->string();
443 bool is_null = p->is_null();
444 if (!FuzzParam(&string, fuzzer))
445 return false;
446 if (!FuzzParam(&is_null, fuzzer))
447 return false;
448 *p = base::NullableString16(string, is_null);
449 return true;
453 template <>
454 struct FuzzTraits<base::Time> {
455 static bool Fuzz(base::Time* p, Fuzzer* fuzzer) {
456 int64 internal_value = p->ToInternalValue();
457 if (!FuzzParam(&internal_value, fuzzer))
458 return false;
459 *p = base::Time::FromInternalValue(internal_value);
460 return true;
464 template <>
465 struct FuzzTraits<base::TimeDelta> {
466 static bool Fuzz(base::TimeDelta* p, Fuzzer* fuzzer) {
467 int64 internal_value = p->ToInternalValue();
468 if (!FuzzParam(&internal_value, fuzzer))
469 return false;
470 *p = base::TimeDelta::FromInternalValue(internal_value);
471 return true;
475 template <>
476 struct FuzzTraits<base::TimeTicks> {
477 static bool Fuzz(base::TimeTicks* p, Fuzzer* fuzzer) {
478 int64 internal_value = p->ToInternalValue();
479 if (!FuzzParam(&internal_value, fuzzer))
480 return false;
481 *p = base::TimeTicks::FromInternalValue(internal_value);
482 return true;
486 template <>
487 struct FuzzTraits<base::ListValue> {
488 static bool Fuzz(base::ListValue* p, Fuzzer* fuzzer) {
489 // TODO(mbarbella): Support mutation.
490 if (!fuzzer->ShouldGenerate())
491 return true;
493 ++g_depth;
494 size_t list_length = p->GetSize();
495 if (fuzzer->ShouldGenerate())
496 list_length = g_depth > 3 ? 0 : RandInRange(8);
497 for (size_t index = 0; index < list_length; ++index) {
498 switch (RandInRange(8)) {
499 case base::Value::TYPE_BOOLEAN: {
500 bool tmp;
501 p->GetBoolean(index, &tmp);
502 fuzzer->FuzzBool(&tmp);
503 p->Set(index, new base::FundamentalValue(tmp));
504 break;
506 case base::Value::TYPE_INTEGER: {
507 int tmp;
508 p->GetInteger(index, &tmp);
509 fuzzer->FuzzInt(&tmp);
510 p->Set(index, new base::FundamentalValue(tmp));
511 break;
513 case base::Value::TYPE_DOUBLE: {
514 double tmp;
515 p->GetDouble(index, &tmp);
516 fuzzer->FuzzDouble(&tmp);
517 p->Set(index, new base::FundamentalValue(tmp));
518 break;
520 case base::Value::TYPE_STRING: {
521 std::string tmp;
522 p->GetString(index, &tmp);
523 fuzzer->FuzzString(&tmp);
524 p->Set(index, new base::StringValue(tmp));
525 break;
527 case base::Value::TYPE_BINARY: {
528 char tmp[200];
529 size_t bin_length = RandInRange(sizeof(tmp));
530 fuzzer->FuzzData(tmp, bin_length);
531 p->Set(index,
532 base::BinaryValue::CreateWithCopiedBuffer(tmp, bin_length));
533 break;
535 case base::Value::TYPE_DICTIONARY: {
536 base::DictionaryValue* tmp = new base::DictionaryValue();
537 p->GetDictionary(index, &tmp);
538 FuzzParam(tmp, fuzzer);
539 p->Set(index, tmp);
540 break;
542 case base::Value::TYPE_LIST: {
543 base::ListValue* tmp = new base::ListValue();
544 p->GetList(index, &tmp);
545 FuzzParam(tmp, fuzzer);
546 p->Set(index, tmp);
547 break;
549 case base::Value::TYPE_NULL:
550 default:
551 break;
554 --g_depth;
555 return true;
559 template <>
560 struct FuzzTraits<base::DictionaryValue> {
561 static bool Fuzz(base::DictionaryValue* p, Fuzzer* fuzzer) {
562 // TODO(mbarbella): Support mutation.
563 if (!fuzzer->ShouldGenerate())
564 return true;
566 ++g_depth;
567 size_t dict_length = g_depth > 3 ? 0 : RandInRange(8);
568 for (size_t index = 0; index < dict_length; ++index) {
569 std::string property;
570 fuzzer->FuzzString(&property);
571 switch (RandInRange(8)) {
572 case base::Value::TYPE_BOOLEAN: {
573 bool tmp;
574 fuzzer->FuzzBool(&tmp);
575 p->SetWithoutPathExpansion(property, new base::FundamentalValue(tmp));
576 break;
578 case base::Value::TYPE_INTEGER: {
579 int tmp;
580 fuzzer->FuzzInt(&tmp);
581 p->SetWithoutPathExpansion(property, new base::FundamentalValue(tmp));
582 break;
584 case base::Value::TYPE_DOUBLE: {
585 double tmp;
586 fuzzer->FuzzDouble(&tmp);
587 p->SetWithoutPathExpansion(property, new base::FundamentalValue(tmp));
588 break;
590 case base::Value::TYPE_STRING: {
591 std::string tmp;
592 fuzzer->FuzzString(&tmp);
593 p->SetWithoutPathExpansion(property, new base::StringValue(tmp));
594 break;
596 case base::Value::TYPE_BINARY: {
597 char tmp[200];
598 size_t bin_length = RandInRange(sizeof(tmp));
599 fuzzer->FuzzData(tmp, bin_length);
600 p->SetWithoutPathExpansion(
601 property,
602 base::BinaryValue::CreateWithCopiedBuffer(tmp, bin_length));
603 break;
605 case base::Value::TYPE_DICTIONARY: {
606 base::DictionaryValue* tmp = new base::DictionaryValue();
607 FuzzParam(tmp, fuzzer);
608 p->SetWithoutPathExpansion(property, tmp);
609 break;
611 case base::Value::TYPE_LIST: {
612 base::ListValue* tmp = new base::ListValue();
613 FuzzParam(tmp, fuzzer);
614 p->SetWithoutPathExpansion(property, tmp);
615 break;
617 case base::Value::TYPE_NULL:
618 default:
619 break;
622 --g_depth;
623 return true;
627 template <>
628 struct FuzzTraits<blink::WebGamepad> {
629 static bool Fuzz(blink::WebGamepad* p, Fuzzer* fuzzer) {
630 if (!FuzzParam(&p->connected, fuzzer))
631 return false;
632 if (!FuzzParam(&p->timestamp, fuzzer))
633 return false;
634 unsigned idLength = static_cast<unsigned>(
635 RandInRange(blink::WebGamepad::idLengthCap + 1));
636 if (!FuzzParamArray(&p->id[0], idLength, fuzzer))
637 return false;
638 p->axesLength = static_cast<unsigned>(
639 RandInRange(blink::WebGamepad::axesLengthCap + 1));
640 if (!FuzzParamArray(&p->axes[0], p->axesLength, fuzzer))
641 return false;
642 p->buttonsLength = static_cast<unsigned>(
643 RandInRange(blink::WebGamepad::buttonsLengthCap + 1));
644 if (!FuzzParamArray(&p->buttons[0], p->buttonsLength, fuzzer))
645 return false;
646 unsigned mappingsLength = static_cast<unsigned>(
647 RandInRange(blink::WebGamepad::mappingLengthCap + 1));
648 if (!FuzzParamArray(&p->mapping[0], mappingsLength, fuzzer))
649 return false;
650 return true;
654 template <>
655 struct FuzzTraits<blink::WebGamepadButton> {
656 static bool Fuzz(blink::WebGamepadButton* p, Fuzzer* fuzzer) {
657 if (!FuzzParam(&p->pressed, fuzzer))
658 return false;
659 if (!FuzzParam(&p->value, fuzzer))
660 return false;
661 return true;
665 template <>
666 struct FuzzTraits<cc::CompositorFrame> {
667 static bool Fuzz(cc::CompositorFrame* p, Fuzzer* fuzzer) {
668 // TODO(mbarbella): Support mutation.
669 if (!fuzzer->ShouldGenerate())
670 return true;
672 if (!FuzzParam(&p->metadata, fuzzer))
673 return false;
675 switch (RandInRange(4)) {
676 case 0: {
677 p->delegated_frame_data.reset(new cc::DelegatedFrameData());
678 if (!FuzzParam(p->delegated_frame_data.get(), fuzzer))
679 return false;
680 return true;
682 case 1: {
683 p->gl_frame_data.reset(new cc::GLFrameData());
684 if (!FuzzParam(p->gl_frame_data.get(), fuzzer))
685 return false;
686 return true;
688 case 2: {
689 p->software_frame_data.reset(new cc::SoftwareFrameData());
690 if (!FuzzParam(p->software_frame_data.get(), fuzzer))
691 return false;
692 return true;
694 default:
695 // Fuzz nothing to handle the no frame case.
696 return true;
701 template <>
702 struct FuzzTraits<cc::CompositorFrameAck> {
703 static bool Fuzz(cc::CompositorFrameAck* p, Fuzzer* fuzzer) {
704 if (!FuzzParam(&p->resources, fuzzer))
705 return false;
707 if (!p->gl_frame_data)
708 p->gl_frame_data.reset(new cc::GLFrameData);
709 if (!FuzzParam(p->gl_frame_data.get(), fuzzer))
710 return false;
711 return true;
715 template <>
716 struct FuzzTraits<cc::DelegatedFrameData> {
717 static bool Fuzz(cc::DelegatedFrameData* p, Fuzzer* fuzzer) {
718 if (!FuzzParam(&p->device_scale_factor, fuzzer))
719 return false;
720 if (!FuzzParam(&p->resource_list, fuzzer))
721 return false;
722 if (!FuzzParam(&p->render_pass_list, fuzzer))
723 return false;
724 return true;
728 template <class A>
729 struct FuzzTraits<cc::ListContainer<A>> {
730 static bool Fuzz(cc::ListContainer<A>* p, Fuzzer* fuzzer) {
731 // TODO(mbarbella): This should actually do something.
732 return true;
736 template <>
737 struct FuzzTraits<cc::QuadList> {
738 static bool Fuzz(cc::QuadList* p, Fuzzer* fuzzer) {
739 // TODO(mbarbella): This should actually do something.
740 return true;
744 template <>
745 struct FuzzTraits<cc::RenderPass> {
746 static bool Fuzz(cc::RenderPass* p, Fuzzer* fuzzer) {
747 if (!FuzzParam(&p->id, fuzzer))
748 return false;
749 if (!FuzzParam(&p->output_rect, fuzzer))
750 return false;
751 if (!FuzzParam(&p->damage_rect, fuzzer))
752 return false;
753 if (!FuzzParam(&p->transform_to_root_target, fuzzer))
754 return false;
755 if (!FuzzParam(&p->has_transparent_background, fuzzer))
756 return false;
757 if (!FuzzParam(&p->quad_list, fuzzer))
758 return false;
759 if (!FuzzParam(&p->shared_quad_state_list, fuzzer))
760 return false;
761 // Omitting |copy_requests| as it is not sent over IPC.
762 return true;
766 template <>
767 struct FuzzTraits<cc::RenderPassList> {
768 static bool Fuzz(cc::RenderPassList* p, Fuzzer* fuzzer) {
769 if (!fuzzer->ShouldGenerate()) {
770 for (size_t i = 0; i < p->size(); ++i) {
771 if (!FuzzParam(p->at(i), fuzzer))
772 return false;
774 return true;
777 size_t count = RandElementCount();
778 for (size_t i = 0; i < count; ++i) {
779 scoped_ptr<cc::RenderPass> render_pass = cc::RenderPass::Create();
780 if (!FuzzParam(render_pass.get(), fuzzer))
781 return false;
782 p->push_back(render_pass.Pass());
784 return true;
788 template <>
789 struct FuzzTraits<cc::SoftwareFrameData> {
790 static bool Fuzz(cc::SoftwareFrameData* p, Fuzzer* fuzzer) {
791 if (!FuzzParam(&p->id, fuzzer))
792 return false;
793 if (!FuzzParam(&p->size, fuzzer))
794 return false;
795 if (!FuzzParam(&p->damage_rect, fuzzer))
796 return false;
797 if (!FuzzParam(&p->bitmap_id, fuzzer))
798 return false;
799 return true;
803 template <>
804 struct FuzzTraits<content::IndexedDBKey> {
805 static bool Fuzz(content::IndexedDBKey* p, Fuzzer* fuzzer) {
806 // TODO(mbarbella): Support mutation.
807 if (!fuzzer->ShouldGenerate())
808 return true;
810 ++g_depth;
811 blink::WebIDBKeyType web_type =
812 static_cast<blink::WebIDBKeyType>(RandInRange(7));
813 switch (web_type) {
814 case blink::WebIDBKeyTypeArray: {
815 size_t length = g_depth > 3 ? 0 : RandInRange(4);
816 std::vector<content::IndexedDBKey> array;
817 array.resize(length);
818 for (size_t i = 0; i < length; ++i) {
819 if (!FuzzParam(&array[i], fuzzer)) {
820 --g_depth;
821 return false;
824 *p = content::IndexedDBKey(array);
825 return true;
827 case blink::WebIDBKeyTypeBinary: {
828 std::string binary;
829 if (!FuzzParam(&binary, fuzzer)) {
830 --g_depth;
831 return false;
833 *p = content::IndexedDBKey(binary);
834 return true;
836 case blink::WebIDBKeyTypeString: {
837 base::string16 string;
838 if (!FuzzParam(&string, fuzzer))
839 return false;
840 *p = content::IndexedDBKey(string);
841 return true;
843 case blink::WebIDBKeyTypeDate:
844 case blink::WebIDBKeyTypeNumber: {
845 double number;
846 if (!FuzzParam(&number, fuzzer)) {
847 --g_depth;
848 return false;
850 *p = content::IndexedDBKey(number, web_type);
851 return true;
853 case blink::WebIDBKeyTypeInvalid:
854 case blink::WebIDBKeyTypeNull: {
855 *p = content::IndexedDBKey(web_type);
856 return true;
858 default: {
859 NOTREACHED();
860 --g_depth;
861 return false;
867 template <>
868 struct FuzzTraits<content::IndexedDBKeyRange> {
869 static bool Fuzz(content::IndexedDBKeyRange* p, Fuzzer* fuzzer) {
870 content::IndexedDBKey lower = p->lower();
871 content::IndexedDBKey upper = p->upper();
872 bool lower_open = p->lower_open();
873 bool upper_open = p->upper_open();
874 if (!FuzzParam(&lower, fuzzer))
875 return false;
876 if (!FuzzParam(&upper, fuzzer))
877 return false;
878 if (!FuzzParam(&lower_open, fuzzer))
879 return false;
880 if (!FuzzParam(&upper_open, fuzzer))
881 return false;
882 *p = content::IndexedDBKeyRange(lower, upper, lower_open, upper_open);
883 return true;
887 template <>
888 struct FuzzTraits<content::IndexedDBKeyPath> {
889 static bool Fuzz(content::IndexedDBKeyPath* p, Fuzzer* fuzzer) {
890 // TODO(mbarbella): Support mutation.
891 if (!fuzzer->ShouldGenerate())
892 return true;
894 switch (RandInRange(3)) {
895 case 0: {
896 std::vector<base::string16> array;
897 if (!FuzzParam(&array, fuzzer))
898 return false;
899 *p = content::IndexedDBKeyPath(array);
900 break;
902 case 1: {
903 base::string16 string;
904 if (!FuzzParam(&string, fuzzer))
905 return false;
906 *p = content::IndexedDBKeyPath(string);
907 break;
909 case 2: {
910 *p = content::IndexedDBKeyPath();
911 break;
914 return true;
918 template <>
919 struct FuzzTraits<content::NPIdentifier_Param> {
920 static bool Fuzz(content::NPIdentifier_Param* p, Fuzzer* fuzzer) {
921 // TODO(mbarbella): This should actually do something.
922 return true;
926 template <>
927 struct FuzzTraits<content::NPVariant_Param> {
928 static bool Fuzz(content::NPVariant_Param* p, Fuzzer* fuzzer) {
929 // TODO(mbarbella): This should actually do something.
930 return true;
934 template <>
935 struct FuzzTraits<content::PageState> {
936 static bool Fuzz(content::PageState* p, Fuzzer* fuzzer) {
937 std::string data = p->ToEncodedData();
938 if (!FuzzParam(&data, fuzzer))
939 return false;
940 *p = content::PageState::CreateFromEncodedData(data);
941 return true;
945 template <>
946 struct FuzzTraits<content::SyntheticGesturePacket> {
947 static bool Fuzz(content::SyntheticGesturePacket* p,
948 Fuzzer* fuzzer) {
949 // TODO(mbarbella): Support mutation.
950 if (!fuzzer->ShouldGenerate())
951 return true;
953 scoped_ptr<content::SyntheticGestureParams> gesture_params;
954 switch (RandInRange(
955 content::SyntheticGestureParams::SYNTHETIC_GESTURE_TYPE_MAX + 1)) {
956 case content::SyntheticGestureParams::GestureType::
957 SMOOTH_SCROLL_GESTURE: {
958 content::SyntheticSmoothScrollGestureParams* params =
959 new content::SyntheticSmoothScrollGestureParams();
960 if (!FuzzParam(&params->anchor, fuzzer))
961 return false;
962 if (!FuzzParam(&params->distances, fuzzer))
963 return false;
964 if (!FuzzParam(&params->prevent_fling, fuzzer))
965 return false;
966 if (!FuzzParam(&params->speed_in_pixels_s, fuzzer))
967 return false;
968 gesture_params.reset(params);
969 break;
971 case content::SyntheticGestureParams::GestureType::SMOOTH_DRAG_GESTURE: {
972 content::SyntheticSmoothDragGestureParams* params =
973 new content::SyntheticSmoothDragGestureParams();
974 if (!FuzzParam(&params->start_point, fuzzer))
975 return false;
976 if (!FuzzParam(&params->distances, fuzzer))
977 return false;
978 if (!FuzzParam(&params->speed_in_pixels_s, fuzzer))
979 return false;
980 gesture_params.reset(params);
981 break;
983 case content::SyntheticGestureParams::GestureType::PINCH_GESTURE: {
984 content::SyntheticPinchGestureParams* params =
985 new content::SyntheticPinchGestureParams();
986 if (!FuzzParam(&params->scale_factor, fuzzer))
987 return false;
988 if (!FuzzParam(&params->anchor, fuzzer))
989 return false;
990 if (!FuzzParam(&params->relative_pointer_speed_in_pixels_s,
991 fuzzer))
992 return false;
993 gesture_params.reset(params);
994 break;
996 case content::SyntheticGestureParams::GestureType::TAP_GESTURE: {
997 content::SyntheticTapGestureParams* params =
998 new content::SyntheticTapGestureParams();
999 if (!FuzzParam(&params->position, fuzzer))
1000 return false;
1001 if (!FuzzParam(&params->duration_ms, fuzzer))
1002 return false;
1003 gesture_params.reset(params);
1004 break;
1007 p->set_gesture_params(gesture_params.Pass());
1008 return true;
1012 template <>
1013 struct FuzzTraits<content::WebCursor> {
1014 static bool Fuzz(content::WebCursor* p, Fuzzer* fuzzer) {
1015 content::WebCursor::CursorInfo info;
1016 p->GetCursorInfo(&info);
1018 // |type| enum is not validated on de-serialization, so pick random value.
1019 if (!FuzzParam(reinterpret_cast<int*>(&info.type), fuzzer))
1020 return false;
1021 if (!FuzzParam(&info.hotspot, fuzzer))
1022 return false;
1023 if (!FuzzParam(&info.image_scale_factor, fuzzer))
1024 return false;
1025 if (!FuzzParam(&info.custom_image, fuzzer))
1026 return false;
1027 // Omitting |externalHandle| since it is not serialized.
1029 // Scale factor is expected to be greater than 0, otherwise we hit
1030 // a check failure.
1031 info.image_scale_factor = fabs(info.image_scale_factor) + 0.001;
1033 *p = content::WebCursor(info);
1034 return true;
1038 template <>
1039 struct FuzzTraits<ContentSettingsPattern> {
1040 static bool Fuzz(ContentSettingsPattern* p, Fuzzer* fuzzer) {
1041 // TODO(mbarbella): This can crash if a pattern is generated from a random
1042 // string. We could carefully generate a pattern or fix pattern generation.
1043 return true;
1047 template <>
1048 struct FuzzTraits<ExtensionMsg_PermissionSetStruct> {
1049 static bool Fuzz(ExtensionMsg_PermissionSetStruct* p,
1050 Fuzzer* fuzzer) {
1051 // TODO(mbarbella): This should actually do something.
1052 return true;
1056 template <>
1057 struct FuzzTraits<extensions::URLPatternSet> {
1058 static bool Fuzz(extensions::URLPatternSet* p, Fuzzer* fuzzer) {
1059 std::set<URLPattern> patterns = p->patterns();
1060 if (!FuzzParam(&patterns, fuzzer))
1061 return false;
1062 *p = extensions::URLPatternSet(patterns);
1063 return true;
1067 template <>
1068 struct FuzzTraits<gfx::Point> {
1069 static bool Fuzz(gfx::Point* p, Fuzzer* fuzzer) {
1070 int x = p->x();
1071 int y = p->y();
1072 if (!FuzzParam(&x, fuzzer))
1073 return false;
1074 if (!FuzzParam(&y, fuzzer))
1075 return false;
1076 p->SetPoint(x, y);
1077 return true;
1081 template <>
1082 struct FuzzTraits<gfx::PointF> {
1083 static bool Fuzz(gfx::PointF* p, Fuzzer* fuzzer) {
1084 float x = p->x();
1085 float y = p->y();
1086 if (!FuzzParam(&x, fuzzer))
1087 return false;
1088 if (!FuzzParam(&y, fuzzer))
1089 return false;
1090 p->SetPoint(x, y);
1091 return true;
1095 template <>
1096 struct FuzzTraits<gfx::Rect> {
1097 static bool Fuzz(gfx::Rect* p, Fuzzer* fuzzer) {
1098 gfx::Point origin = p->origin();
1099 gfx::Size size = p->size();
1100 if (!FuzzParam(&origin, fuzzer))
1101 return false;
1102 if (!FuzzParam(&size, fuzzer))
1103 return false;
1104 p->set_origin(origin);
1105 p->set_size(size);
1106 return true;
1110 template <>
1111 struct FuzzTraits<gfx::RectF> {
1112 static bool Fuzz(gfx::RectF* p, Fuzzer* fuzzer) {
1113 gfx::PointF origin = p->origin();
1114 gfx::SizeF size = p->size();
1115 if (!FuzzParam(&origin, fuzzer))
1116 return false;
1117 if (!FuzzParam(&size, fuzzer))
1118 return false;
1119 p->set_origin(origin);
1120 p->set_size(size);
1121 return true;
1125 template <>
1126 struct FuzzTraits<gfx::Range> {
1127 static bool Fuzz(gfx::Range* p, Fuzzer* fuzzer) {
1128 size_t start = p->start();
1129 size_t end = p->end();
1130 if (!FuzzParam(&start, fuzzer))
1131 return false;
1132 if (!FuzzParam(&end, fuzzer))
1133 return false;
1134 *p = gfx::Range(start, end);
1135 return true;
1139 template <>
1140 struct FuzzTraits<gfx::Size> {
1141 static bool Fuzz(gfx::Size* p, Fuzzer* fuzzer) {
1142 int width = p->width();
1143 int height = p->height();
1144 if (!FuzzParam(&width, fuzzer))
1145 return false;
1146 if (!FuzzParam(&height, fuzzer))
1147 return false;
1148 p->SetSize(width, height);
1149 return true;
1153 template <>
1154 struct FuzzTraits<gfx::SizeF> {
1155 static bool Fuzz(gfx::SizeF* p, Fuzzer* fuzzer) {
1156 float w;
1157 float h;
1158 if (!FuzzParam(&w, fuzzer))
1159 return false;
1160 if (!FuzzParam(&h, fuzzer))
1161 return false;
1162 p->SetSize(w, h);
1163 return true;
1167 template <>
1168 struct FuzzTraits<gfx::Transform> {
1169 static bool Fuzz(gfx::Transform* p, Fuzzer* fuzzer) {
1170 SkMScalar matrix[16];
1171 for (size_t i = 0; i < arraysize(matrix); i++) {
1172 matrix[i] = p->matrix().get(i / 4, i % 4);
1174 if (!FuzzParamArray(&matrix[0], arraysize(matrix), fuzzer))
1175 return false;
1176 *p = gfx::Transform(matrix[0], matrix[1], matrix[2], matrix[3], matrix[4],
1177 matrix[5], matrix[6], matrix[7], matrix[8], matrix[9],
1178 matrix[10], matrix[11], matrix[12], matrix[13],
1179 matrix[14], matrix[15]);
1180 return true;
1184 template <>
1185 struct FuzzTraits<gfx::Vector2d> {
1186 static bool Fuzz(gfx::Vector2d* p, Fuzzer* fuzzer) {
1187 int x = p->x();
1188 int y = p->y();
1189 if (!FuzzParam(&x, fuzzer))
1190 return false;
1191 if (!FuzzParam(&y, fuzzer))
1192 return false;
1193 *p = gfx::Vector2d(x, y);
1194 return true;
1198 template <>
1199 struct FuzzTraits<gfx::Vector2dF> {
1200 static bool Fuzz(gfx::Vector2dF* p, Fuzzer* fuzzer) {
1201 float x = p->x();
1202 float y = p->y();
1203 if (!FuzzParam(&x, fuzzer))
1204 return false;
1205 if (!FuzzParam(&y, fuzzer))
1206 return false;
1207 *p = gfx::Vector2dF(x, y);
1208 return true;
1212 template <>
1213 struct FuzzTraits<gpu::Mailbox> {
1214 static bool Fuzz(gpu::Mailbox* p, Fuzzer* fuzzer) {
1215 fuzzer->FuzzBytes(p->name, sizeof(p->name));
1216 return true;
1220 template <>
1221 struct FuzzTraits<gpu::MailboxHolder> {
1222 static bool Fuzz(gpu::MailboxHolder* p, Fuzzer* fuzzer) {
1223 if (!FuzzParam(&p->mailbox, fuzzer))
1224 return false;
1225 if (!FuzzParam(&p->texture_target, fuzzer))
1226 return false;
1227 if (!FuzzParam(&p->sync_point, fuzzer))
1228 return false;
1229 return true;
1233 template <>
1234 struct FuzzTraits<gpu::ValueState> {
1235 static bool Fuzz(gpu::ValueState* p, Fuzzer* fuzzer) {
1236 if (!FuzzParamArray(&p->float_value[0], 4, fuzzer))
1237 return false;
1238 if (!FuzzParamArray(&p->int_value[0], 4, fuzzer))
1239 return false;
1240 return true;
1244 template <>
1245 struct FuzzTraits<GURL> {
1246 static bool Fuzz(GURL* p, Fuzzer* fuzzer) {
1247 if (!fuzzer->ShouldGenerate()) {
1248 std::string spec = p->possibly_invalid_spec();
1249 if (!FuzzParam(&spec, fuzzer))
1250 return false;
1251 if (spec != p->possibly_invalid_spec())
1252 *p = GURL(spec);
1253 return true;
1256 const char url_chars[] = "Ahtp0:/.?+\\%&#";
1257 size_t count = RandInRange(100);
1258 std::string random_url;
1259 for (size_t i = 0; i < count; ++i)
1260 random_url += url_chars[RandInRange(sizeof(url_chars) - 1)];
1261 int selector = RandInRange(10);
1262 if (selector == 0)
1263 random_url = std::string("http://") + random_url;
1264 else if (selector == 1)
1265 random_url = std::string("file://") + random_url;
1266 else if (selector == 2)
1267 random_url = std::string("javascript:") + random_url;
1268 else if (selector == 2)
1269 random_url = std::string("data:") + random_url;
1270 *p = GURL(random_url);
1271 return true;
1275 template <>
1276 struct FuzzTraits<HostID> {
1277 static bool Fuzz(HostID* p, Fuzzer* fuzzer) {
1278 HostID::HostType type = p->type();
1279 std::string id = p->id();
1280 if (!FuzzParam(&type, fuzzer))
1281 return false;
1282 if (!FuzzParam(&id, fuzzer))
1283 return false;
1284 *p = HostID(type, id);
1285 return true;
1289 #if defined(OS_WIN)
1290 template <>
1291 struct FuzzTraits<HWND> {
1292 static bool Fuzz(HWND* p, Fuzzer* fuzzer) {
1293 // TODO(aarya): This should actually do something.
1294 return true;
1297 #endif
1299 template <>
1300 struct FuzzTraits<IPC::Message> {
1301 static bool Fuzz(IPC::Message* p, Fuzzer* fuzzer) {
1302 // TODO(mbarbella): Support mutation.
1303 if (!fuzzer->ShouldGenerate())
1304 return true;
1306 if (g_function_vector.empty())
1307 return false;
1308 size_t index = RandInRange(g_function_vector.size());
1309 IPC::Message* ipc_message = (*g_function_vector[index])(NULL, fuzzer);
1310 if (!ipc_message)
1311 return false;
1312 p = ipc_message;
1313 return true;
1317 template <>
1318 struct FuzzTraits<IPC::PlatformFileForTransit> {
1319 static bool Fuzz(IPC::PlatformFileForTransit* p, Fuzzer* fuzzer) {
1320 // TODO(inferno): I don't think we can generate real ones due to check on
1321 // construct.
1322 return true;
1326 template <>
1327 struct FuzzTraits<IPC::ChannelHandle> {
1328 static bool Fuzz(IPC::ChannelHandle* p, Fuzzer* fuzzer) {
1329 // TODO(mbarbella): Support mutation.
1330 if (!fuzzer->ShouldGenerate())
1331 return true;
1333 // TODO(inferno): Add way to generate real channel handles.
1334 #if defined(OS_WIN)
1335 HANDLE fake_handle = (HANDLE)(RandU64());
1336 p->pipe = IPC::ChannelHandle::PipeHandle(fake_handle);
1337 return true;
1338 #elif defined(OS_POSIX)
1339 return
1340 FuzzParam(&p->name, fuzzer) &&
1341 FuzzParam(&p->socket, fuzzer);
1342 #endif
1346 #if defined(OS_WIN)
1347 template <>
1348 struct FuzzTraits<LOGFONT> {
1349 static bool Fuzz(LOGFONT* p, Fuzzer* fuzzer) {
1350 // TODO(aarya): This should actually do something.
1351 return true;
1354 #endif
1356 template <>
1357 struct FuzzTraits<media::AudioParameters> {
1358 static bool Fuzz(media::AudioParameters* p, Fuzzer* fuzzer) {
1359 int format = p->format();
1360 int channel_layout = p->channel_layout();
1361 int sample_rate = p->sample_rate();
1362 int bits_per_sample = p->bits_per_sample();
1363 int frames_per_buffer = p->frames_per_buffer();
1364 int channels = p->channels();
1365 int effects = p->effects();
1366 if (!FuzzParam(&format, fuzzer))
1367 return false;
1368 if (!FuzzParam(&channel_layout, fuzzer))
1369 return false;
1370 if (!FuzzParam(&sample_rate, fuzzer))
1371 return false;
1372 if (!FuzzParam(&bits_per_sample, fuzzer))
1373 return false;
1374 if (!FuzzParam(&frames_per_buffer, fuzzer))
1375 return false;
1376 if (!FuzzParam(&channels, fuzzer))
1377 return false;
1378 if (!FuzzParam(&effects, fuzzer))
1379 return false;
1380 media::AudioParameters params(
1381 static_cast<media::AudioParameters::Format>(format),
1382 static_cast<media::ChannelLayout>(channel_layout), channels,
1383 sample_rate, bits_per_sample, frames_per_buffer, effects);
1384 *p = params;
1385 return true;
1389 template <>
1390 struct FuzzTraits<media::VideoCaptureFormat> {
1391 static bool Fuzz(media::VideoCaptureFormat* p, Fuzzer* fuzzer) {
1392 if (!FuzzParam(&p->frame_size, fuzzer))
1393 return false;
1394 if (!FuzzParam(&p->frame_rate, fuzzer))
1395 return false;
1396 if (!FuzzParam(reinterpret_cast<int*>(&p->pixel_format), fuzzer))
1397 return false;
1398 return true;
1402 template <>
1403 struct FuzzTraits<net::LoadTimingInfo> {
1404 static bool Fuzz(net::LoadTimingInfo* p, Fuzzer* fuzzer) {
1405 return FuzzParam(&p->socket_log_id, fuzzer) &&
1406 FuzzParam(&p->socket_reused, fuzzer) &&
1407 FuzzParam(&p->request_start_time, fuzzer) &&
1408 FuzzParam(&p->request_start, fuzzer) &&
1409 FuzzParam(&p->proxy_resolve_start, fuzzer) &&
1410 FuzzParam(&p->proxy_resolve_end, fuzzer) &&
1411 FuzzParam(&p->connect_timing.dns_start, fuzzer) &&
1412 FuzzParam(&p->connect_timing.dns_end, fuzzer) &&
1413 FuzzParam(&p->connect_timing.connect_start, fuzzer) &&
1414 FuzzParam(&p->connect_timing.connect_end, fuzzer) &&
1415 FuzzParam(&p->connect_timing.ssl_start, fuzzer) &&
1416 FuzzParam(&p->connect_timing.ssl_end, fuzzer) &&
1417 FuzzParam(&p->send_start, fuzzer) &&
1418 FuzzParam(&p->send_end, fuzzer) &&
1419 FuzzParam(&p->receive_headers_end, fuzzer);
1423 template <>
1424 struct FuzzTraits<net::HostPortPair> {
1425 static bool Fuzz(net::HostPortPair* p, Fuzzer* fuzzer) {
1426 std::string host = p->host();
1427 uint16 port = p->port();
1428 if (!FuzzParam(&host, fuzzer))
1429 return false;
1430 if (!FuzzParam(&port, fuzzer))
1431 return false;
1432 p->set_host(host);
1433 p->set_port(port);
1434 return true;
1438 template <>
1439 struct FuzzTraits<net::IPEndPoint> {
1440 static bool Fuzz(net::IPEndPoint* p, Fuzzer* fuzzer) {
1441 net::IPAddressNumber address = p->address();
1442 int port = p->port();
1443 if (!FuzzParam(&address, fuzzer))
1444 return false;
1445 if (!FuzzParam(&port, fuzzer))
1446 return false;
1447 net::IPEndPoint ip_endpoint(address, port);
1448 *p = ip_endpoint;
1449 return true;
1453 template <>
1454 struct FuzzTraits<network_hints::LookupRequest> {
1455 static bool Fuzz(network_hints::LookupRequest* p, Fuzzer* fuzzer) {
1456 if (!FuzzParam(&p->hostname_list, fuzzer))
1457 return false;
1458 return true;
1462 // PP_ traits.
1463 template <>
1464 struct FuzzTraits<PP_Bool> {
1465 static bool Fuzz(PP_Bool* p, Fuzzer* fuzzer) {
1466 bool tmp = PP_ToBool(*p);
1467 if (!FuzzParam(&tmp, fuzzer))
1468 return false;
1469 *p = PP_FromBool(tmp);
1470 return true;
1474 template <>
1475 struct FuzzTraits<PP_KeyInformation> {
1476 static bool Fuzz(PP_KeyInformation* p, Fuzzer* fuzzer) {
1477 // TODO(mbarbella): This should actually do something.
1478 return true;
1482 template <>
1483 struct FuzzTraits<PP_NetAddress_Private> {
1484 static bool Fuzz(PP_NetAddress_Private* p, Fuzzer* fuzzer) {
1485 p->size = RandInRange(sizeof(p->data) + 1);
1486 fuzzer->FuzzBytes(&p->data, p->size);
1487 return true;
1491 template <>
1492 struct FuzzTraits<ppapi::PPB_X509Certificate_Fields> {
1493 static bool Fuzz(ppapi::PPB_X509Certificate_Fields* p,
1494 Fuzzer* fuzzer) {
1495 // TODO(mbarbella): This should actually do something.
1496 return true;
1500 template <>
1501 struct FuzzTraits<ppapi::proxy::PPBFlash_DrawGlyphs_Params> {
1502 static bool Fuzz(ppapi::proxy::PPBFlash_DrawGlyphs_Params* p,
1503 Fuzzer* fuzzer) {
1504 // TODO(mbarbella): This should actually do something.
1505 return true;
1509 template <>
1510 struct FuzzTraits<ppapi::proxy::ResourceMessageCallParams> {
1511 static bool Fuzz(
1512 ppapi::proxy::ResourceMessageCallParams* p, Fuzzer* fuzzer) {
1513 // TODO(mbarbella): Support mutation.
1514 if (!fuzzer->ShouldGenerate())
1515 return true;
1517 PP_Resource resource;
1518 int32_t sequence;
1519 bool has_callback;
1520 if (!FuzzParam(&resource, fuzzer))
1521 return false;
1522 if (!FuzzParam(&sequence, fuzzer))
1523 return false;
1524 if (!FuzzParam(&has_callback, fuzzer))
1525 return false;
1526 *p = ppapi::proxy::ResourceMessageCallParams(resource, sequence);
1527 if (has_callback)
1528 p->set_has_callback();
1529 return true;
1533 template <>
1534 struct FuzzTraits<ppapi::proxy::ResourceMessageReplyParams> {
1535 static bool Fuzz(
1536 ppapi::proxy::ResourceMessageReplyParams* p, Fuzzer* fuzzer) {
1537 // TODO(mbarbella): Support mutation.
1538 if (!fuzzer->ShouldGenerate())
1539 return true;
1541 PP_Resource resource;
1542 int32_t sequence;
1543 int32_t result;
1544 if (!FuzzParam(&resource, fuzzer))
1545 return false;
1546 if (!FuzzParam(&sequence, fuzzer))
1547 return false;
1548 if (!FuzzParam(&result, fuzzer))
1549 return false;
1550 *p = ppapi::proxy::ResourceMessageReplyParams(resource, sequence);
1551 p->set_result(result);
1552 return true;
1556 template <>
1557 struct FuzzTraits<ppapi::proxy::SerializedHandle> {
1558 static bool Fuzz(ppapi::proxy::SerializedHandle* p,
1559 Fuzzer* fuzzer) {
1560 // TODO(mbarbella): This should actually do something.
1561 return true;
1565 template <>
1566 struct FuzzTraits<ppapi::proxy::SerializedFontDescription> {
1567 static bool Fuzz(ppapi::proxy::SerializedFontDescription* p,
1568 Fuzzer* fuzzer) {
1569 // TODO(mbarbella): This should actually do something.
1570 return true;
1574 template <>
1575 struct FuzzTraits<ppapi::proxy::SerializedTrueTypeFontDesc> {
1576 static bool Fuzz(ppapi::proxy::SerializedTrueTypeFontDesc* p,
1577 Fuzzer* fuzzer) {
1578 // TODO(mbarbella): This should actually do something.
1579 return true;
1583 template <>
1584 struct FuzzTraits<ppapi::proxy::SerializedVar> {
1585 static bool Fuzz(ppapi::proxy::SerializedVar* p, Fuzzer* fuzzer) {
1586 // TODO(mbarbella): This should actually do something.
1587 return true;
1591 template <>
1592 struct FuzzTraits<ppapi::HostResource> {
1593 static bool Fuzz(ppapi::HostResource* p, Fuzzer* fuzzer) {
1594 // TODO(mbarbella): Support mutation.
1595 if (!fuzzer->ShouldGenerate())
1596 return true;
1598 PP_Instance instance;
1599 PP_Resource resource;
1600 if (!FuzzParam(&instance, fuzzer))
1601 return false;
1602 if (!FuzzParam(&resource, fuzzer))
1603 return false;
1604 p->SetHostResource(instance, resource);
1605 return true;
1609 template <>
1610 struct FuzzTraits<ppapi::PepperFilePath> {
1611 static bool Fuzz(ppapi::PepperFilePath *p, Fuzzer* fuzzer) {
1612 // TODO(mbarbella): Support mutation.
1613 if (!fuzzer->ShouldGenerate())
1614 return true;
1616 unsigned domain = RandInRange(ppapi::PepperFilePath::DOMAIN_MAX_VALID+1);
1617 base::FilePath path;
1618 if (!FuzzParam(&path, fuzzer))
1619 return false;
1620 *p = ppapi::PepperFilePath(
1621 static_cast<ppapi::PepperFilePath::Domain>(domain), path);
1622 return true;
1626 template <>
1627 struct FuzzTraits<ppapi::PpapiPermissions> {
1628 static bool Fuzz(ppapi::PpapiPermissions* p, Fuzzer* fuzzer) {
1629 uint32_t bits = p->GetBits();
1630 if (!FuzzParam(&bits, fuzzer))
1631 return false;
1632 *p = ppapi::PpapiPermissions(bits);
1633 return true;
1637 template <>
1638 struct FuzzTraits<ppapi::SocketOptionData> {
1639 static bool Fuzz(ppapi::SocketOptionData* p, Fuzzer* fuzzer) {
1640 // TODO(mbarbella): This can be improved.
1641 int32 tmp;
1642 p->GetInt32(&tmp);
1643 if (!FuzzParam(&tmp, fuzzer))
1644 return false;
1645 p->SetInt32(tmp);
1646 return true;
1650 template <>
1651 struct FuzzTraits<printing::PdfRenderSettings> {
1652 static bool Fuzz(printing::PdfRenderSettings* p, Fuzzer* fuzzer) {
1653 gfx::Rect area = p->area();
1654 int dpi = p->dpi();
1655 bool autorotate = p->autorotate();
1656 if (!FuzzParam(&area, fuzzer))
1657 return false;
1658 if (!FuzzParam(&dpi, fuzzer))
1659 return false;
1660 if (!FuzzParam(&autorotate, fuzzer))
1661 return false;
1662 *p = printing::PdfRenderSettings(area, dpi, autorotate);
1663 return true;
1667 template <>
1668 struct FuzzTraits<remoting::ScreenResolution> {
1669 static bool Fuzz(remoting::ScreenResolution* p, Fuzzer* fuzzer) {
1670 webrtc::DesktopSize dimensions = p->dimensions();
1671 webrtc::DesktopVector dpi = p->dpi();
1672 if (!FuzzParam(&dimensions, fuzzer))
1673 return false;
1674 if (!FuzzParam(&dpi, fuzzer))
1675 return false;
1676 *p = remoting::ScreenResolution(dimensions, dpi);
1677 return true;
1681 template <>
1682 struct FuzzTraits<SkBitmap> {
1683 static bool Fuzz(SkBitmap* p, Fuzzer* fuzzer) {
1684 // TODO(mbarbella): This should actually do something.
1685 return true;
1689 template <>
1690 struct FuzzTraits<storage::DataElement> {
1691 static bool Fuzz(storage::DataElement* p, Fuzzer* fuzzer) {
1692 // TODO(mbarbella): Support mutation.
1693 if (!fuzzer->ShouldGenerate())
1694 return true;
1696 switch (RandInRange(4)) {
1697 case storage::DataElement::Type::TYPE_BYTES: {
1698 if (RandEvent(2)) {
1699 p->SetToEmptyBytes();
1700 } else {
1701 char data[256];
1702 int data_len = RandInRange(sizeof(data));
1703 fuzzer->FuzzBytes(&data[0], data_len);
1704 p->SetToBytes(&data[0], data_len);
1706 return true;
1708 case storage::DataElement::Type::TYPE_FILE: {
1709 base::FilePath path;
1710 uint64 offset;
1711 uint64 length;
1712 base::Time modification_time;
1713 if (!FuzzParam(&path, fuzzer))
1714 return false;
1715 if (!FuzzParam(&offset, fuzzer))
1716 return false;
1717 if (!FuzzParam(&length, fuzzer))
1718 return false;
1719 if (!FuzzParam(&modification_time, fuzzer))
1720 return false;
1721 p->SetToFilePathRange(path, offset, length, modification_time);
1722 return true;
1724 case storage::DataElement::Type::TYPE_BLOB: {
1725 std::string uuid;
1726 uint64 offset;
1727 uint64 length;
1728 if (!FuzzParam(&uuid, fuzzer))
1729 return false;
1730 if (!FuzzParam(&offset, fuzzer))
1731 return false;
1732 if (!FuzzParam(&length, fuzzer))
1733 return false;
1734 p->SetToBlobRange(uuid, offset, length);
1735 return true;
1737 case storage::DataElement::Type::TYPE_FILE_FILESYSTEM: {
1738 GURL url;
1739 uint64 offset;
1740 uint64 length;
1741 base::Time modification_time;
1742 if (!FuzzParam(&url, fuzzer))
1743 return false;
1744 if (!FuzzParam(&offset, fuzzer))
1745 return false;
1746 if (!FuzzParam(&length, fuzzer))
1747 return false;
1748 if (!FuzzParam(&modification_time, fuzzer))
1749 return false;
1750 p->SetToFileSystemUrlRange(url, offset, length, modification_time);
1751 return true;
1753 default: {
1754 NOTREACHED();
1755 return false;
1761 template <>
1762 struct FuzzTraits<ui::LatencyInfo> {
1763 static bool Fuzz(ui::LatencyInfo* p, Fuzzer* fuzzer) {
1764 // TODO(inferno): Add param traits for |latency_components|.
1765 int64 trace_id = p->trace_id();
1766 bool terminated = p->terminated();
1767 uint32 input_coordinates_size = static_cast<uint32>(
1768 RandInRange(ui::LatencyInfo::kMaxInputCoordinates + 1));
1769 ui::LatencyInfo::InputCoordinate
1770 input_coordinates[ui::LatencyInfo::kMaxInputCoordinates];
1771 if (!FuzzParamArray(
1772 input_coordinates, input_coordinates_size, fuzzer))
1773 return false;
1774 if (!FuzzParam(&trace_id, fuzzer))
1775 return false;
1776 if (!FuzzParam(&terminated, fuzzer))
1777 return false;
1779 ui::LatencyInfo latency(trace_id, terminated);
1780 for (size_t i = 0; i < input_coordinates_size; i++) {
1781 latency.AddInputCoordinate(input_coordinates[i]);
1783 *p = latency;
1785 return true;
1789 template <>
1790 struct FuzzTraits<ui::LatencyInfo::InputCoordinate> {
1791 static bool Fuzz(
1792 ui::LatencyInfo::InputCoordinate* p, Fuzzer* fuzzer) {
1793 if (!FuzzParam(&p->x, fuzzer))
1794 return false;
1795 if (!FuzzParam(&p->y, fuzzer))
1796 return false;
1797 return true;
1801 template <>
1802 struct FuzzTraits<url::Origin> {
1803 static bool Fuzz(url::Origin* p, Fuzzer* fuzzer) {
1804 std::string scheme = p->scheme();
1805 std::string host = p->host();
1806 uint16 port = p->port();
1807 if (!FuzzParam(&scheme, fuzzer))
1808 return false;
1809 if (!FuzzParam(&host, fuzzer))
1810 return false;
1811 if (!FuzzParam(&port, fuzzer))
1812 return false;
1813 *p = url::Origin::UnsafelyCreateOriginWithoutNormalization(scheme, host,
1814 port);
1816 // Force a unique origin 1% of the time:
1817 if (RandInRange(100) == 1)
1818 *p = url::Origin();
1819 return true;
1823 template <>
1824 struct FuzzTraits<URLPattern> {
1825 static bool Fuzz(URLPattern* p, Fuzzer* fuzzer) {
1826 int valid_schemes = p->valid_schemes();
1827 std::string host = p->host();
1828 std::string port = p->port();
1829 std::string path = p->path();
1830 if (!FuzzParam(&valid_schemes, fuzzer))
1831 return false;
1832 if (!FuzzParam(&host, fuzzer))
1833 return false;
1834 if (!FuzzParam(&port, fuzzer))
1835 return false;
1836 if (!FuzzParam(&path, fuzzer))
1837 return false;
1838 *p = URLPattern(valid_schemes);
1839 p->SetHost(host);
1840 p->SetPort(port);
1841 p->SetPath(path);
1842 return true;
1846 template <>
1847 struct FuzzTraits<webrtc::DesktopSize> {
1848 static bool Fuzz(webrtc::DesktopSize* p, Fuzzer* fuzzer) {
1849 int32_t width = p->width();
1850 int32_t height = p->height();
1851 if (!FuzzParam(&width, fuzzer))
1852 return false;
1853 if (!FuzzParam(&height, fuzzer))
1854 return false;
1855 *p = webrtc::DesktopSize(width, height);
1856 return true;
1860 template <>
1861 struct FuzzTraits<webrtc::DesktopVector> {
1862 static bool Fuzz(webrtc::DesktopVector* p, Fuzzer* fuzzer) {
1863 int32_t x = p->x();
1864 int32_t y = p->y();
1865 if (!FuzzParam(&x, fuzzer))
1866 return false;
1867 if (!FuzzParam(&y, fuzzer))
1868 return false;
1869 p->set(x, y);
1870 return true;
1874 template <>
1875 struct FuzzTraits<webrtc::DesktopRect> {
1876 static bool Fuzz(webrtc::DesktopRect* p, Fuzzer* fuzzer) {
1877 int32_t left = p->left();
1878 int32_t top = p->top();
1879 int32_t right = p->right();
1880 int32_t bottom = p->bottom();
1881 if (!FuzzParam(&left, fuzzer))
1882 return false;
1883 if (!FuzzParam(&top, fuzzer))
1884 return false;
1885 if (!FuzzParam(&right, fuzzer))
1886 return false;
1887 if (!FuzzParam(&bottom, fuzzer))
1888 return false;
1889 *p = webrtc::DesktopRect::MakeLTRB(left, top, right, bottom);
1890 return true;
1894 template <>
1895 struct FuzzTraits<webrtc::MouseCursor> {
1896 static bool Fuzz(webrtc::MouseCursor* p, Fuzzer* fuzzer) {
1897 webrtc::DesktopVector hotspot = p->hotspot();
1898 if (!FuzzParam(&hotspot, fuzzer))
1899 return false;
1900 p->set_hotspot(hotspot);
1902 // TODO(mbarbella): Find a way to handle the size mutation properly.
1903 if (!fuzzer->ShouldGenerate())
1904 return false;
1906 // Using a small size here to avoid OOM or overflow on image allocation.
1907 webrtc::DesktopSize size(RandInRange(100), RandInRange(100));
1908 p->set_image(new webrtc::BasicDesktopFrame(size));
1909 return true;
1913 // Redefine macros to generate generating from traits declarations.
1914 // STRUCT declarations cause corresponding STRUCT_TRAITS declarations to occur.
1915 #undef IPC_STRUCT_BEGIN
1916 #undef IPC_STRUCT_BEGIN_WITH_PARENT
1917 #undef IPC_STRUCT_MEMBER
1918 #undef IPC_STRUCT_END
1919 #define IPC_STRUCT_BEGIN_WITH_PARENT(struct_name, parent) \
1920 IPC_STRUCT_BEGIN(struct_name)
1921 #define IPC_STRUCT_BEGIN(struct_name) IPC_STRUCT_TRAITS_BEGIN(struct_name)
1922 #define IPC_STRUCT_MEMBER(type, name, ...) IPC_STRUCT_TRAITS_MEMBER(name)
1923 #define IPC_STRUCT_END() IPC_STRUCT_TRAITS_END()
1925 // Set up so next include will generate generate trait classes.
1926 #undef IPC_STRUCT_TRAITS_BEGIN
1927 #undef IPC_STRUCT_TRAITS_MEMBER
1928 #undef IPC_STRUCT_TRAITS_PARENT
1929 #undef IPC_STRUCT_TRAITS_END
1930 #define IPC_STRUCT_TRAITS_BEGIN(struct_name) \
1931 template <> \
1932 struct FuzzTraits<struct_name> { \
1933 static bool Fuzz(struct_name *p, Fuzzer* fuzzer) {
1935 #define IPC_STRUCT_TRAITS_MEMBER(name) \
1936 if (!FuzzParam(&p->name, fuzzer)) \
1937 return false;
1939 #define IPC_STRUCT_TRAITS_PARENT(type) \
1940 if (!FuzzParam(static_cast<type*>(p), fuzzer)) \
1941 return false;
1943 #define IPC_STRUCT_TRAITS_END() \
1944 return true; \
1948 // If |condition| isn't met, the messsge will fail to serialize. Try
1949 // increasingly smaller ranges until we find one that happens to meet
1950 // the condition, or fail trying.
1951 // TODO(mbarbella): Attempt to validate even in the mutation case.
1952 #undef IPC_ENUM_TRAITS_VALIDATE
1953 #define IPC_ENUM_TRAITS_VALIDATE(enum_name, condition) \
1954 template <> \
1955 struct FuzzTraits<enum_name> { \
1956 static bool Fuzz(enum_name* p, Fuzzer* fuzzer) { \
1957 if (!fuzzer->ShouldGenerate()) { \
1958 return FuzzParam(reinterpret_cast<int*>(p), fuzzer); \
1960 for (int shift = 30; shift; --shift) { \
1961 for (int tries = 0; tries < 2; ++tries) { \
1962 int value = RandInRange(1 << shift); \
1963 if (condition) { \
1964 *reinterpret_cast<int*>(p) = value; \
1965 return true; \
1969 std::cerr << "failed to satisfy " << #condition << "\n"; \
1970 return false; \
1974 // Bring them into existence.
1975 #include "tools/ipc_fuzzer/message_lib/all_messages.h"
1976 #include "tools/ipc_fuzzer/message_lib/all_message_null_macros.h"
1978 // Redefine macros to generate generating funtions
1979 #undef IPC_MESSAGE_DECL
1980 #define IPC_MESSAGE_DECL(kind, type, name, in, out, ilist, olist) \
1981 IPC_##kind##_##type##_FUZZ(name, in, out, ilist, olist)
1983 #define IPC_EMPTY_CONTROL_FUZZ(name, in, out, ilist, olist) \
1984 IPC::Message* fuzzer_for_##name(IPC::Message* msg, Fuzzer* fuzzer) { \
1985 if (msg) { \
1986 return NULL; \
1988 return new name(); \
1991 #define IPC_EMPTY_ROUTED_FUZZ(name, in, out, ilist, olist) \
1992 IPC::Message* fuzzer_for_##name(IPC::Message* msg, Fuzzer* fuzzer) { \
1993 if (msg) { \
1994 return NULL; \
1996 return new name(RandInRange(MAX_FAKE_ROUTING_ID)); \
1999 #define IPC_ASYNC_CONTROL_FUZZ(name, in, out, ilist, olist) \
2000 IPC::Message* fuzzer_for_##name(IPC::Message* msg, Fuzzer* fuzzer) { \
2001 IPC_TUPLE_IN_##in ilist p; \
2002 if (msg) { \
2003 name::Read(static_cast<name*>(msg), &p); \
2005 if (FuzzParam(&p, fuzzer)) { \
2006 return new name(IPC_MEMBERS_IN_##in(p)); \
2008 std::cerr << "Don't know how to handle " << #name << "\n"; \
2009 return 0; \
2012 #define IPC_ASYNC_ROUTED_FUZZ(name, in, out, ilist, olist) \
2013 IPC::Message* fuzzer_for_##name(IPC::Message* msg, Fuzzer* fuzzer) { \
2014 IPC_TUPLE_IN_##in ilist p; \
2015 if (msg) { \
2016 name::Read(static_cast<name*>(msg), &p); \
2018 if (FuzzParam(&p, fuzzer)) { \
2019 return new name(RandInRange(MAX_FAKE_ROUTING_ID) \
2020 IPC_COMMA_##in \
2021 IPC_MEMBERS_IN_##in(p)); \
2023 std::cerr << "Don't know how to handle " << #name << "\n"; \
2024 return 0; \
2027 #define IPC_SYNC_CONTROL_FUZZ(name, in, out, ilist, olist) \
2028 IPC::Message* fuzzer_for_##name(IPC::Message* msg, Fuzzer* fuzzer) { \
2029 IPC_TUPLE_IN_##in ilist p; \
2030 name* real_msg = static_cast<name*>(msg); \
2031 name* new_msg = NULL; \
2032 if (real_msg) { \
2033 name::ReadSendParam(real_msg, &p); \
2035 if (FuzzParam(&p, fuzzer)) { \
2036 new_msg = new name(IPC_MEMBERS_IN_##in(p) \
2037 IPC_COMMA_AND_##out(IPC_COMMA_##in) \
2038 IPC_MEMBERS_OUT_##out()); \
2040 if (real_msg && new_msg) { \
2041 MessageCracker::CopyMessageID(new_msg, real_msg); \
2043 else if (!new_msg) { \
2044 std::cerr << "Don't know how to handle " << #name << "\n"; \
2046 return new_msg; \
2049 #define IPC_SYNC_ROUTED_FUZZ(name, in, out, ilist, olist) \
2050 IPC::Message* fuzzer_for_##name(IPC::Message* msg, Fuzzer* fuzzer) { \
2051 IPC_TUPLE_IN_##in ilist p; \
2052 name* real_msg = static_cast<name*>(msg); \
2053 name* new_msg = NULL; \
2054 if (real_msg) { \
2055 name::ReadSendParam(real_msg, &p); \
2057 if (FuzzParam(&p, fuzzer)) { \
2058 new_msg = new name(RandInRange(MAX_FAKE_ROUTING_ID) \
2059 IPC_COMMA_OR_##out(IPC_COMMA_##in) \
2060 IPC_MEMBERS_IN_##in(p) \
2061 IPC_COMMA_AND_##out(IPC_COMMA_##in) \
2062 IPC_MEMBERS_OUT_##out()); \
2064 if (real_msg && new_msg) { \
2065 MessageCracker::CopyMessageID(new_msg, real_msg); \
2067 else if (!new_msg) { \
2068 std::cerr << "Don't know how to handle " << #name << "\n"; \
2070 return new_msg; \
2073 #define MAX_FAKE_ROUTING_ID 15
2075 #define IPC_MEMBERS_IN_0(p)
2076 #define IPC_MEMBERS_IN_1(p) base::get<0>(p)
2077 #define IPC_MEMBERS_IN_2(p) base::get<0>(p), base::get<1>(p)
2078 #define IPC_MEMBERS_IN_3(p) base::get<0>(p), base::get<1>(p), base::get<2>(p)
2079 #define IPC_MEMBERS_IN_4(p) base::get<0>(p), base::get<1>(p), base::get<2>(p), \
2080 base::get<3>(p)
2081 #define IPC_MEMBERS_IN_5(p) base::get<0>(p), base::get<1>(p), base::get<2>(p), \
2082 base::get<3>(p), base::get<4>(p)
2084 #define IPC_MEMBERS_OUT_0()
2085 #define IPC_MEMBERS_OUT_1() NULL
2086 #define IPC_MEMBERS_OUT_2() NULL, NULL
2087 #define IPC_MEMBERS_OUT_3() NULL, NULL, NULL
2088 #define IPC_MEMBERS_OUT_4() NULL, NULL, NULL, NULL
2089 #define IPC_MEMBERS_OUT_5() NULL, NULL, NULL, NULL, NULL
2091 #include "tools/ipc_fuzzer/message_lib/all_messages.h"
2092 #include "tools/ipc_fuzzer/message_lib/all_message_null_macros.h"
2094 void PopulateFuzzerFunctionVector(
2095 FuzzerFunctionVector* function_vector) {
2096 #undef IPC_MESSAGE_DECL
2097 #define IPC_MESSAGE_DECL(kind, type, name, in, out, ilist, olist) \
2098 function_vector->push_back(fuzzer_for_##name);
2099 #include "tools/ipc_fuzzer/message_lib/all_messages.h"
2102 // Redefine macros to register fuzzing functions into map.
2103 #include "tools/ipc_fuzzer/message_lib/all_message_null_macros.h"
2104 #undef IPC_MESSAGE_DECL
2105 #define IPC_MESSAGE_DECL(kind, type, name, in, out, ilist, olist) \
2106 (*map)[static_cast<uint32>(name::ID)] = fuzzer_for_##name;
2108 void PopulateFuzzerFunctionMap(FuzzerFunctionMap* map) {
2109 #include "tools/ipc_fuzzer/message_lib/all_messages.h"
2112 } // namespace ipc_fuzzer