Index: tools/ipc_fuzzer/fuzzer/fuzzer.cc |
diff --git a/tools/ipc_fuzzer/fuzzer/fuzzer.cc b/tools/ipc_fuzzer/fuzzer/fuzzer.cc |
index 22bbb5c40a0f6cfbcc0b2d435aea4617d83c985f..f4c88567b360d1e4ccb177b670aaa9ff62cf05da 100644 |
--- a/tools/ipc_fuzzer/fuzzer/fuzzer.cc |
+++ b/tools/ipc_fuzzer/fuzzer/fuzzer.cc |
@@ -2001,135 +2001,110 @@ struct FuzzTraits<webrtc::MouseCursor> { |
#include "tools/ipc_fuzzer/message_lib/all_messages.h" |
#include "tools/ipc_fuzzer/message_lib/all_message_null_macros.h" |
-// Redefine macros to generate generating funtions |
-#undef IPC_MESSAGE_DECL |
-#define IPC_MESSAGE_DECL(kind, type, name, in, out, ilist, olist) \ |
- IPC_##kind##_##type##_FUZZ(name, in, out, ilist, olist) |
- |
-#define IPC_EMPTY_CONTROL_FUZZ(name, in, out, ilist, olist) \ |
- IPC::Message* fuzzer_for_##name(IPC::Message* msg, Fuzzer* fuzzer) { \ |
- if (msg) { \ |
- return NULL; \ |
- } \ |
- return new name(); \ |
- } |
- |
-#define IPC_EMPTY_ROUTED_FUZZ(name, in, out, ilist, olist) \ |
- IPC::Message* fuzzer_for_##name(IPC::Message* msg, Fuzzer* fuzzer) { \ |
- if (msg) { \ |
- return NULL; \ |
- } \ |
- return new name(RandInRange(MAX_FAKE_ROUTING_ID)); \ |
- } |
- |
-#define IPC_ASYNC_CONTROL_FUZZ(name, in, out, ilist, olist) \ |
- IPC::Message* fuzzer_for_##name(IPC::Message* msg, Fuzzer* fuzzer) { \ |
- IPC_TUPLE_IN_##in ilist p; \ |
- if (msg) { \ |
- name::Read(static_cast<name*>(msg), &p); \ |
- } \ |
- if (FuzzParam(&p, fuzzer)) { \ |
- return new name(IPC_MEMBERS_IN_##in(p)); \ |
- } \ |
- std::cerr << "Don't know how to handle " << #name << "\n"; \ |
- return 0; \ |
- } |
- |
-#define IPC_ASYNC_ROUTED_FUZZ(name, in, out, ilist, olist) \ |
- IPC::Message* fuzzer_for_##name(IPC::Message* msg, Fuzzer* fuzzer) { \ |
- IPC_TUPLE_IN_##in ilist p; \ |
- if (msg) { \ |
- name::Read(static_cast<name*>(msg), &p); \ |
- } \ |
- if (FuzzParam(&p, fuzzer)) { \ |
- return new name(RandInRange(MAX_FAKE_ROUTING_ID) \ |
- IPC_COMMA_##in \ |
- IPC_MEMBERS_IN_##in(p)); \ |
- } \ |
- std::cerr << "Don't know how to handle " << #name << "\n"; \ |
- return 0; \ |
- } |
- |
-#define IPC_SYNC_CONTROL_FUZZ(name, in, out, ilist, olist) \ |
- IPC::Message* fuzzer_for_##name(IPC::Message* msg, Fuzzer* fuzzer) { \ |
- IPC_TUPLE_IN_##in ilist p; \ |
- name* real_msg = static_cast<name*>(msg); \ |
- name* new_msg = NULL; \ |
- if (real_msg) { \ |
- name::ReadSendParam(real_msg, &p); \ |
- } \ |
- if (FuzzParam(&p, fuzzer)) { \ |
- new_msg = new name(IPC_MEMBERS_IN_##in(p) \ |
- IPC_COMMA_AND_##out(IPC_COMMA_##in) \ |
- IPC_MEMBERS_OUT_##out()); \ |
- } \ |
- if (real_msg && new_msg) { \ |
- MessageCracker::CopyMessageID(new_msg, real_msg); \ |
- } \ |
- else if (!new_msg) { \ |
- std::cerr << "Don't know how to handle " << #name << "\n"; \ |
- } \ |
- return new_msg; \ |
- } |
- |
-#define IPC_SYNC_ROUTED_FUZZ(name, in, out, ilist, olist) \ |
- IPC::Message* fuzzer_for_##name(IPC::Message* msg, Fuzzer* fuzzer) { \ |
- IPC_TUPLE_IN_##in ilist p; \ |
- name* real_msg = static_cast<name*>(msg); \ |
- name* new_msg = NULL; \ |
- if (real_msg) { \ |
- name::ReadSendParam(real_msg, &p); \ |
- } \ |
- if (FuzzParam(&p, fuzzer)) { \ |
- new_msg = new name(RandInRange(MAX_FAKE_ROUTING_ID) \ |
- IPC_COMMA_OR_##out(IPC_COMMA_##in) \ |
- IPC_MEMBERS_IN_##in(p) \ |
- IPC_COMMA_AND_##out(IPC_COMMA_##in) \ |
- IPC_MEMBERS_OUT_##out()); \ |
- } \ |
- if (real_msg && new_msg) { \ |
- MessageCracker::CopyMessageID(new_msg, real_msg); \ |
- } \ |
- else if (!new_msg) { \ |
- std::cerr << "Don't know how to handle " << #name << "\n"; \ |
- } \ |
- return new_msg; \ |
+#define MAX_FAKE_ROUTING_ID 15 |
+ |
+// MessageFactory abstracts away constructing control/routed messages by |
+// providing an additional random routing ID argument when necessary. |
+template <typename Message, IPC::MessageKind> |
+class MessageFactory; |
+ |
+template <typename Message> |
+class MessageFactory<Message, IPC::MessageKind::CONTROL> { |
+ public: |
+ template <typename... Args> |
+ static Message* New(const Args&... args) { |
+ return new Message(args...); |
} |
+}; |
-#define MAX_FAKE_ROUTING_ID 15 |
+template <typename Message> |
+class MessageFactory<Message, IPC::MessageKind::ROUTED> { |
+ public: |
+ template <typename... Args> |
+ static Message* New(const Args&... args) { |
+ return new Message(RandInRange(MAX_FAKE_ROUTING_ID), args...); |
+ } |
+}; |
-#define IPC_MEMBERS_IN_0(p) |
-#define IPC_MEMBERS_IN_1(p) base::get<0>(p) |
-#define IPC_MEMBERS_IN_2(p) base::get<0>(p), base::get<1>(p) |
-#define IPC_MEMBERS_IN_3(p) base::get<0>(p), base::get<1>(p), base::get<2>(p) |
-#define IPC_MEMBERS_IN_4(p) base::get<0>(p), base::get<1>(p), base::get<2>(p), \ |
- base::get<3>(p) |
-#define IPC_MEMBERS_IN_5(p) base::get<0>(p), base::get<1>(p), base::get<2>(p), \ |
- base::get<3>(p), base::get<4>(p) |
- |
-#define IPC_MEMBERS_OUT_0() |
-#define IPC_MEMBERS_OUT_1() NULL |
-#define IPC_MEMBERS_OUT_2() NULL, NULL |
-#define IPC_MEMBERS_OUT_3() NULL, NULL, NULL |
-#define IPC_MEMBERS_OUT_4() NULL, NULL, NULL, NULL |
-#define IPC_MEMBERS_OUT_5() NULL, NULL, NULL, NULL, NULL |
+template <typename Message> |
+class FuzzerHelper; |
+ |
+template <typename Meta, typename... Ins> |
+class FuzzerHelper<IPC::MessageT<Meta, base::Tuple<Ins...>, void>> { |
+ public: |
+ using Message = IPC::MessageT<Meta, base::Tuple<Ins...>, void>; |
+ |
+ static IPC::Message* Fuzz(IPC::Message* msg, Fuzzer* fuzzer) { |
+ return FuzzImpl(msg, fuzzer, base::MakeIndexSequence<sizeof...(Ins)>()); |
+ } |
+ |
+ private: |
+ template <size_t... Ns> |
+ static IPC::Message* FuzzImpl(IPC::Message* msg, |
+ Fuzzer* fuzzer, |
+ base::IndexSequence<Ns...>) { |
+ typename Message::Param p; |
+ if (msg) { |
+ Message::Read(static_cast<Message*>(msg), &p); |
+ } |
+ if (FuzzParam(&p, fuzzer)) { |
+ return MessageFactory<Message, Meta::kKind>::New(base::get<Ns>(p)...); |
+ } |
+ std::cerr << "Don't know how to handle " << Meta::kName << "\n"; |
+ return nullptr; |
+ } |
+}; |
+ |
+template <typename Meta, typename... Ins, typename... Outs> |
+class FuzzerHelper< |
+ IPC::MessageT<Meta, base::Tuple<Ins...>, base::Tuple<Outs...>>> { |
+ public: |
+ using Message = |
+ IPC::MessageT<Meta, base::Tuple<Ins...>, base::Tuple<Outs...>>; |
+ |
+ static IPC::Message* Fuzz(IPC::Message* msg, Fuzzer* fuzzer) { |
+ return FuzzImpl(msg, fuzzer, base::MakeIndexSequence<sizeof...(Ins)>()); |
+ } |
+ |
+ private: |
+ template <size_t... Ns> |
+ static IPC::Message* FuzzImpl(IPC::Message* msg, |
+ Fuzzer* fuzzer, |
+ base::IndexSequence<Ns...>) { |
+ typename Message::SendParam p; |
+ Message* real_msg = static_cast<Message*>(msg); |
+ Message* new_msg = nullptr; |
+ if (real_msg) { |
+ Message::ReadSendParam(real_msg, &p); |
+ } |
+ if (FuzzParam(&p, fuzzer)) { |
+ new_msg = MessageFactory<Message, Meta::kKind>::New( |
+ base::get<Ns>(p)..., static_cast<Outs*>(nullptr)...); |
+ } |
+ if (real_msg && new_msg) { |
+ MessageCracker::CopyMessageID(new_msg, real_msg); |
+ } else if (!new_msg) { |
+ std::cerr << "Don't know how to handle " << Meta::kName << "\n"; |
+ } |
+ return new_msg; |
+ } |
+}; |
-#include "tools/ipc_fuzzer/message_lib/all_messages.h" |
#include "tools/ipc_fuzzer/message_lib/all_message_null_macros.h" |
void PopulateFuzzerFunctionVector( |
FuzzerFunctionVector* function_vector) { |
#undef IPC_MESSAGE_DECL |
-#define IPC_MESSAGE_DECL(kind, type, name, in, out, ilist, olist) \ |
- function_vector->push_back(fuzzer_for_##name); |
+#define IPC_MESSAGE_DECL(name, ...) \ |
+ function_vector->push_back(FuzzerHelper<name>::Fuzz); |
#include "tools/ipc_fuzzer/message_lib/all_messages.h" |
} |
// Redefine macros to register fuzzing functions into map. |
#include "tools/ipc_fuzzer/message_lib/all_message_null_macros.h" |
#undef IPC_MESSAGE_DECL |
-#define IPC_MESSAGE_DECL(kind, type, name, in, out, ilist, olist) \ |
- (*map)[static_cast<uint32_t>(name::ID)] = fuzzer_for_##name; |
+#define IPC_MESSAGE_DECL(name, ...) \ |
+ (*map)[static_cast<uint32_t>(name::ID)] = FuzzerHelper<name>::Fuzz; |
void PopulateFuzzerFunctionMap(FuzzerFunctionMap* map) { |
#include "tools/ipc_fuzzer/message_lib/all_messages.h" |