OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include <stdlib.h> | 5 #include <stdlib.h> |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <iostream> | 8 #include <iostream> |
9 #include <ostream> | 9 #include <ostream> |
10 #include <set> | 10 #include <set> |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
66 virtual void GenerateInt64(int64* value) = 0; | 66 virtual void GenerateInt64(int64* value) = 0; |
67 virtual void GenerateUInt64(uint64* value) = 0; | 67 virtual void GenerateUInt64(uint64* value) = 0; |
68 virtual void GenerateFloat(float *value) = 0; | 68 virtual void GenerateFloat(float *value) = 0; |
69 virtual void GenerateDouble(double *value) = 0; | 69 virtual void GenerateDouble(double *value) = 0; |
70 virtual void GenerateString(std::string* value) = 0; | 70 virtual void GenerateString(std::string* value) = 0; |
71 virtual void GenerateString16(base::string16* value) = 0; | 71 virtual void GenerateString16(base::string16* value) = 0; |
72 virtual void GenerateData(char* data, int length) = 0; | 72 virtual void GenerateData(char* data, int length) = 0; |
73 virtual void GenerateBytes(void* data, int data_len) = 0; | 73 virtual void GenerateBytes(void* data, int data_len) = 0; |
74 }; | 74 }; |
75 | 75 |
| 76 typedef IPC::Message* (*GeneratorFunction)(Generator*); |
| 77 typedef std::vector<GeneratorFunction> GeneratorFunctionVector; |
| 78 GeneratorFunctionVector g_function_vector; |
| 79 |
76 template <typename T> | 80 template <typename T> |
77 void GenerateIntegralType(T* value) { | 81 void GenerateIntegralType(T* value) { |
78 switch (RandInRange(16)) { | 82 switch (RandInRange(16)) { |
79 case 0: | 83 case 0: |
80 *value = static_cast<T>(0); | 84 *value = static_cast<T>(0); |
81 break; | 85 break; |
82 case 1: | 86 case 1: |
83 *value = static_cast<T>(1); | 87 *value = static_cast<T>(1); |
84 break; | 88 break; |
85 case 2: | 89 case 2: |
(...skipping 364 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
450 struct GenerateTraits<std::pair<A, B> > { | 454 struct GenerateTraits<std::pair<A, B> > { |
451 static bool Generate(std::pair<A, B>* p, Generator* generator) { | 455 static bool Generate(std::pair<A, B>* p, Generator* generator) { |
452 return | 456 return |
453 GenerateParam(&p->first, generator) && | 457 GenerateParam(&p->first, generator) && |
454 GenerateParam(&p->second, generator); | 458 GenerateParam(&p->second, generator); |
455 } | 459 } |
456 }; | 460 }; |
457 | 461 |
458 // Specializations to generate hand-coded types. | 462 // Specializations to generate hand-coded types. |
459 template <> | 463 template <> |
460 struct GenerateTraits<IPC::PlatformFileForTransit> { | |
461 static bool Generate(IPC::PlatformFileForTransit* p, Generator* generator) { | |
462 // TODO(inferno): I don't think we can generate real ones due to check on | |
463 // construct. | |
464 *p = IPC::InvalidPlatformFileForTransit(); | |
465 return true; | |
466 } | |
467 }; | |
468 | |
469 template <> | |
470 struct GenerateTraits<IPC::ChannelHandle> { | |
471 static bool Generate(IPC::ChannelHandle* p, Generator* generator) { | |
472 // TODO(inferno): Add way to generate real channel handles. | |
473 #if defined(OS_WIN) | |
474 HANDLE fake_handle = (HANDLE)(RandU64()); | |
475 p->pipe = IPC::ChannelHandle::PipeHandle(fake_handle); | |
476 return true; | |
477 #elif defined(OS_POSIX) | |
478 return | |
479 GenerateParam(&p->name, generator) && | |
480 GenerateParam(&p->socket, generator); | |
481 #endif | |
482 } | |
483 }; | |
484 | |
485 template <> | |
486 struct GenerateTraits<base::NullableString16> { | 464 struct GenerateTraits<base::NullableString16> { |
487 static bool Generate(base::NullableString16* p, Generator* generator) { | 465 static bool Generate(base::NullableString16* p, Generator* generator) { |
488 *p = base::NullableString16(); | 466 *p = base::NullableString16(); |
489 return true; | 467 return true; |
490 } | 468 } |
491 }; | 469 }; |
492 | 470 |
493 template <> | 471 template <> |
494 struct GenerateTraits<base::FilePath> { | 472 struct GenerateTraits<base::FilePath> { |
495 static bool Generate(base::FilePath* p, Generator* generator) { | 473 static bool Generate(base::FilePath* p, Generator* generator) { |
(...skipping 681 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1177 float y; | 1155 float y; |
1178 if (!GenerateParam(&x, generator)) | 1156 if (!GenerateParam(&x, generator)) |
1179 return false; | 1157 return false; |
1180 if (!GenerateParam(&y, generator)) | 1158 if (!GenerateParam(&y, generator)) |
1181 return false; | 1159 return false; |
1182 *p = gfx::Vector2dF(x, y); | 1160 *p = gfx::Vector2dF(x, y); |
1183 return true; | 1161 return true; |
1184 } | 1162 } |
1185 }; | 1163 }; |
1186 | 1164 |
| 1165 template <> |
| 1166 struct GenerateTraits<IPC::Message> { |
| 1167 static bool Generate(IPC::Message *p, Generator* generator) { |
| 1168 if (g_function_vector.empty()) |
| 1169 return false; |
| 1170 size_t index = RandInRange(g_function_vector.size()); |
| 1171 IPC::Message* ipc_message = (*g_function_vector[index])(generator); |
| 1172 if (!ipc_message) |
| 1173 return false; |
| 1174 p = ipc_message; |
| 1175 return true; |
| 1176 } |
| 1177 }; |
| 1178 |
| 1179 template <> |
| 1180 struct GenerateTraits<IPC::PlatformFileForTransit> { |
| 1181 static bool Generate(IPC::PlatformFileForTransit* p, Generator* generator) { |
| 1182 // TODO(inferno): I don't think we can generate real ones due to check on |
| 1183 // construct. |
| 1184 *p = IPC::InvalidPlatformFileForTransit(); |
| 1185 return true; |
| 1186 } |
| 1187 }; |
| 1188 |
| 1189 template <> |
| 1190 struct GenerateTraits<IPC::ChannelHandle> { |
| 1191 static bool Generate(IPC::ChannelHandle* p, Generator* generator) { |
| 1192 // TODO(inferno): Add way to generate real channel handles. |
| 1193 #if defined(OS_WIN) |
| 1194 HANDLE fake_handle = (HANDLE)(RandU64()); |
| 1195 p->pipe = IPC::ChannelHandle::PipeHandle(fake_handle); |
| 1196 return true; |
| 1197 #elif defined(OS_POSIX) |
| 1198 return |
| 1199 GenerateParam(&p->name, generator) && |
| 1200 GenerateParam(&p->socket, generator); |
| 1201 #endif |
| 1202 } |
| 1203 }; |
| 1204 |
1187 // PP_ traits. | 1205 // PP_ traits. |
1188 template <> | 1206 template <> |
1189 struct GenerateTraits<PP_Bool> { | 1207 struct GenerateTraits<PP_Bool> { |
1190 static bool Generate(PP_Bool *p, Generator* generator) { | 1208 static bool Generate(PP_Bool *p, Generator* generator) { |
1191 bool tmp; | 1209 bool tmp; |
1192 if (!GenerateParam(&tmp, generator)) | 1210 if (!GenerateParam(&tmp, generator)) |
1193 return false; | 1211 return false; |
1194 *p = PP_FromBool(tmp); | 1212 *p = PP_FromBool(tmp); |
1195 return true; | 1213 return true; |
1196 } | 1214 } |
(...skipping 365 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1562 #define IPC_MEMBERS_OUT_0() | 1580 #define IPC_MEMBERS_OUT_0() |
1563 #define IPC_MEMBERS_OUT_1() NULL | 1581 #define IPC_MEMBERS_OUT_1() NULL |
1564 #define IPC_MEMBERS_OUT_2() NULL, NULL | 1582 #define IPC_MEMBERS_OUT_2() NULL, NULL |
1565 #define IPC_MEMBERS_OUT_3() NULL, NULL, NULL | 1583 #define IPC_MEMBERS_OUT_3() NULL, NULL, NULL |
1566 #define IPC_MEMBERS_OUT_4() NULL, NULL, NULL, NULL | 1584 #define IPC_MEMBERS_OUT_4() NULL, NULL, NULL, NULL |
1567 #define IPC_MEMBERS_OUT_5() NULL, NULL, NULL, NULL, NULL | 1585 #define IPC_MEMBERS_OUT_5() NULL, NULL, NULL, NULL, NULL |
1568 | 1586 |
1569 #include "tools/ipc_fuzzer/message_lib/all_messages.h" | 1587 #include "tools/ipc_fuzzer/message_lib/all_messages.h" |
1570 #include "ipc/ipc_message_null_macros.h" | 1588 #include "ipc/ipc_message_null_macros.h" |
1571 | 1589 |
1572 typedef IPC::Message* (*GeneratorFunction)(Generator*); | |
1573 typedef std::vector<GeneratorFunction> GeneratorFunctionVector; | |
1574 | |
1575 void PopulateGeneratorFunctionVector( | 1590 void PopulateGeneratorFunctionVector( |
1576 GeneratorFunctionVector *function_vector) { | 1591 GeneratorFunctionVector *function_vector) { |
1577 #undef IPC_MESSAGE_DECL | 1592 #undef IPC_MESSAGE_DECL |
1578 #define IPC_MESSAGE_DECL(kind, type, name, in, out, ilist, olist) \ | 1593 #define IPC_MESSAGE_DECL(kind, type, name, in, out, ilist, olist) \ |
1579 function_vector->push_back(generator_for_##name); | 1594 function_vector->push_back(generator_for_##name); |
1580 #include "tools/ipc_fuzzer/message_lib/all_messages.h" | 1595 #include "tools/ipc_fuzzer/message_lib/all_messages.h" |
1581 } | 1596 } |
1582 | 1597 |
1583 static const char kCountSwitch[] = "count"; | 1598 static const char kCountSwitch[] = "count"; |
1584 static const char kHelpSwitch[] = "help"; | 1599 static const char kHelpSwitch[] = "help"; |
1585 | 1600 |
1586 int GenerateMain(int argc, char** argv) { | 1601 int GenerateMain(int argc, char** argv) { |
1587 base::CommandLine::Init(argc, argv); | 1602 base::CommandLine::Init(argc, argv); |
1588 base::CommandLine* cmd = base::CommandLine::ForCurrentProcess(); | 1603 base::CommandLine* cmd = base::CommandLine::ForCurrentProcess(); |
1589 base::CommandLine::StringVector args = cmd->GetArgs(); | 1604 base::CommandLine::StringVector args = cmd->GetArgs(); |
1590 | 1605 |
1591 if (args.size() != 1 || cmd->HasSwitch(kHelpSwitch)) { | 1606 if (args.size() != 1 || cmd->HasSwitch(kHelpSwitch)) { |
1592 std::cerr << "Usage: ipc_fuzzer_generate [--help] [--count=n] outfile\n"; | 1607 std::cerr << "Usage: ipc_fuzzer_generate [--help] [--count=n] outfile\n"; |
1593 return EXIT_FAILURE; | 1608 return EXIT_FAILURE; |
1594 } | 1609 } |
1595 base::FilePath::StringType output_file_name = args[0]; | 1610 base::FilePath::StringType output_file_name = args[0]; |
1596 | 1611 |
1597 int message_count = 1000; | 1612 int message_count = 1000; |
1598 if (cmd->HasSwitch(kCountSwitch)) | 1613 if (cmd->HasSwitch(kCountSwitch)) |
1599 message_count = atoi(cmd->GetSwitchValueASCII(kCountSwitch).c_str()); | 1614 message_count = atoi(cmd->GetSwitchValueASCII(kCountSwitch).c_str()); |
1600 | 1615 |
1601 InitRand(); | 1616 InitRand(); |
1602 | 1617 |
1603 GeneratorFunctionVector function_vector; | 1618 PopulateGeneratorFunctionVector(&g_function_vector); |
1604 PopulateGeneratorFunctionVector(&function_vector); | 1619 std::cerr << "Counted " << g_function_vector.size() |
1605 std::cerr << "Counted " << function_vector.size() | |
1606 << " distinct messages present in chrome.\n"; | 1620 << " distinct messages present in chrome.\n"; |
1607 | 1621 |
1608 Generator* generator = new GeneratorImpl(); | 1622 Generator* generator = new GeneratorImpl(); |
1609 MessageVector message_vector; | 1623 MessageVector message_vector; |
1610 | 1624 |
1611 int bad_count = 0; | 1625 int bad_count = 0; |
1612 if (message_count < 0) { | 1626 if (message_count < 0) { |
1613 // Enumerate them all. | 1627 // Enumerate them all. |
1614 for (size_t i = 0; i < function_vector.size(); ++i) { | 1628 for (size_t i = 0; i < g_function_vector.size(); ++i) { |
1615 if (IPC::Message* new_message = (*function_vector[i])(generator)) | 1629 if (IPC::Message* new_message = (*g_function_vector[i])(generator)) |
1616 message_vector.push_back(new_message); | 1630 message_vector.push_back(new_message); |
1617 else | 1631 else |
1618 bad_count += 1; | 1632 bad_count += 1; |
1619 } | 1633 } |
1620 } else { | 1634 } else { |
1621 // Generate a random batch. | 1635 // Generate a random batch. |
1622 for (int i = 0; i < message_count; ++i) { | 1636 for (int i = 0; i < message_count; ++i) { |
1623 size_t index = RandInRange(function_vector.size()); | 1637 size_t index = RandInRange(g_function_vector.size()); |
1624 if (IPC::Message* new_message = (*function_vector[index])(generator)) | 1638 if (IPC::Message* new_message = (*g_function_vector[index])(generator)) |
1625 message_vector.push_back(new_message); | 1639 message_vector.push_back(new_message); |
1626 else | 1640 else |
1627 bad_count += 1; | 1641 bad_count += 1; |
1628 } | 1642 } |
1629 } | 1643 } |
1630 | 1644 |
1631 std::cerr << "Failed to generate " << bad_count << " messages.\n"; | 1645 std::cerr << "Failed to generate " << bad_count << " messages.\n"; |
1632 | 1646 |
1633 if (!MessageFile::Write(base::FilePath(output_file_name), message_vector)) | 1647 if (!MessageFile::Write(base::FilePath(output_file_name), message_vector)) |
1634 return EXIT_FAILURE; | 1648 return EXIT_FAILURE; |
1635 | 1649 |
1636 return EXIT_SUCCESS; | 1650 return EXIT_SUCCESS; |
1637 } | 1651 } |
1638 | 1652 |
1639 } // namespace ipc_fuzzer | 1653 } // namespace ipc_fuzzer |
1640 | 1654 |
1641 int main(int argc, char** argv) { | 1655 int main(int argc, char** argv) { |
1642 return ipc_fuzzer::GenerateMain(argc, argv); | 1656 return ipc_fuzzer::GenerateMain(argc, argv); |
1643 } | 1657 } |
OLD | NEW |