| 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 |