class Message;
} // namespace IPC
+namespace {
+// For breaking deep recursion.
+int g_depth = 0;
+} // namespace
+
namespace ipc_fuzzer {
// Interface implemented by those who generate basic types. The types all
template <typename T>
void GenerateIntegralType(T* value) {
- *value = static_cast<T>(RandU64());
+ switch (RandInRange(16)) {
+ case 0:
+ *value = 0;
+ break;
+ case 1:
+ *value = 1;
+ break;
+ case 2:
+ *value = -1;
+ break;
+ case 3:
+ *value = 2;
+ break;
+ default:
+ *value = static_cast<T>(RandU64());
+ break;
+ }
}
template <typename T>
GeneratorImpl() {}
virtual ~GeneratorImpl() {}
- virtual void GenerateBool(bool* value) OVERRIDE {
+ virtual void GenerateBool(bool* value) override {
*value = RandInRange(2);
}
- virtual void GenerateInt(int* value) OVERRIDE {
+ virtual void GenerateInt(int* value) override {
GenerateIntegralType<int>(value);
}
- virtual void GenerateLong(long* value) OVERRIDE {
+ virtual void GenerateLong(long* value) override {
GenerateIntegralType<long>(value);
}
- virtual void GenerateSize(size_t* value) OVERRIDE {
+ virtual void GenerateSize(size_t* value) override {
GenerateIntegralType<size_t>(value);
}
- virtual void GenerateUChar(unsigned char* value) OVERRIDE {
+ virtual void GenerateUChar(unsigned char* value) override {
GenerateIntegralType<unsigned char>(value);
}
- virtual void GenerateUInt16(uint16* value) OVERRIDE {
+ virtual void GenerateUInt16(uint16* value) override {
GenerateIntegralType<uint16>(value);
}
- virtual void GenerateUInt32(uint32* value) OVERRIDE {
+ virtual void GenerateUInt32(uint32* value) override {
GenerateIntegralType<uint32>(value);
}
- virtual void GenerateInt64(int64* value) OVERRIDE {
+ virtual void GenerateInt64(int64* value) override {
GenerateIntegralType<int64>(value);
}
- virtual void GenerateUInt64(uint64* value) OVERRIDE {
+ virtual void GenerateUInt64(uint64* value) override {
GenerateIntegralType<uint64>(value);
}
- virtual void GenerateFloat(float* value) OVERRIDE {
+ virtual void GenerateFloat(float* value) override {
GenerateFloatingType<float>(value);
}
- virtual void GenerateDouble(double* value) OVERRIDE {
+ virtual void GenerateDouble(double* value) override {
GenerateFloatingType<double>(value);
}
- virtual void GenerateString(std::string* value) OVERRIDE {
+ virtual void GenerateString(std::string* value) override {
GenerateStringType<std::string>(value);
}
- virtual void GenerateString16(base::string16* value) OVERRIDE {
+ virtual void GenerateString16(base::string16* value) override {
GenerateStringType<base::string16>(value);
}
- virtual void GenerateData(char* data, int length) OVERRIDE {
+ virtual void GenerateData(char* data, int length) override {
for (int i = 0; i < length; ++i) {
GenerateIntegralType<char>(&data[i]);
}
}
- virtual void GenerateBytes(void* data, int data_len) OVERRIDE {
+ virtual void GenerateBytes(void* data, int data_len) override {
GenerateData(static_cast<char*>(data), data_len);
}
};
struct GenerateTraits {
static bool Generate(P* p, Generator *generator) {
// This is the catch-all for types we don't have enough information
- // to generate. Sadly, we must reject this message.
- std::cerr << "Cant handle " << __PRETTY_FUNCTION__ << "\n";
+ // to generate.
+ std::cerr << "Can't handle " << __PRETTY_FUNCTION__ << "\n";
return false;
}
};
template <class A>
struct GenerateTraits<std::vector<A> > {
static bool Generate(std::vector<A>* p, Generator* generator) {
- static int depth = 0;
- size_t count = ++depth > 3 ? 0 : RandInRange(20);
+ size_t count = ++g_depth > 3 ? 0 : RandInRange(20);
p->resize(count);
for (size_t i = 0; i < count; ++i) {
if (!GenerateParam(&p->at(i), generator)) {
- --depth;
+ --g_depth;
return false;
}
}
- --depth;
+ --g_depth;
return true;
}
};
template <class A>
struct GenerateTraits<std::set<A> > {
static bool Generate(std::set<A>* p, Generator* generator) {
- static int depth = 0;
- size_t count = ++depth > 3 ? 0 : RandInRange(20);
+ static int g_depth = 0;
+ size_t count = ++g_depth > 3 ? 0 : RandInRange(20);
A a;
for (size_t i = 0; i < count; ++i) {
if (!GenerateParam(&a, generator)) {
- --depth;
+ --g_depth;
return false;
}
p->insert(a);
}
- --depth;
+ --g_depth;
return true;
}
};
template <class A, class B>
struct GenerateTraits<std::map<A, B> > {
static bool Generate(std::map<A, B>* p, Generator* generator) {
- static int depth = 0;
- size_t count = ++depth > 3 ? 0 : RandInRange(20);
+ static int g_depth = 0;
+ size_t count = ++g_depth > 3 ? 0 : RandInRange(20);
std::pair<A, B> place_holder;
for (size_t i = 0; i < count; ++i) {
if (!GenerateParam(&place_holder, generator)) {
- --depth;
+ --g_depth;
return false;
}
p->insert(place_holder);
}
- --depth;
+ --g_depth;
return true;
}
};
};
template <>
+struct GenerateTraits<base::File::Error> {
+ static bool Generate(base::File::Error* p, Generator* generator) {
+ int temporary;
+ if (!GenerateParam(&temporary, generator))
+ return false;
+ *p = static_cast<base::File::Error>(temporary);
+ return true;
+ }
+};
+
+template <>
+struct GenerateTraits<base::File::Info> {
+ static bool Generate(base::File::Info* p, Generator* generator) {
+ double last_modified;
+ double last_accessed;
+ double creation_time;
+ if (!GenerateParam(&p->size, generator))
+ return false;
+ if (!GenerateParam(&p->is_directory, generator))
+ return false;
+ if (!GenerateParam(&last_modified, generator))
+ return false;
+ if (GenerateParam(&last_accessed, generator))
+ return false;
+ if (GenerateParam(&creation_time, generator))
+ return false;
+ p->last_modified = base::Time::FromDoubleT(last_modified);
+ p->last_accessed = base::Time::FromDoubleT(last_accessed);
+ p->creation_time = base::Time::FromDoubleT(creation_time);
+ return true;
+ }
+};
+
+template <>
struct GenerateTraits<base::Time> {
static bool Generate(base::Time* p, Generator* generator) {
*p = base::Time::FromInternalValue(RandU64());
};
template <>
-struct GenerateTraits<base::PlatformFileInfo> {
- static bool Generate(base::PlatformFileInfo* p, Generator* generator) {
- return
- GenerateParam(&p->size, generator) &&
- GenerateParam(&p->is_directory, generator) &&
- GenerateParam(&p->last_modified, generator) &&
- GenerateParam(&p->last_accessed, generator) &&
- GenerateParam(&p->creation_time, generator);
+struct GenerateTraits<base::ListValue> {
+ static bool Generate(base::ListValue* p, Generator* generator) {
+ ++g_depth;
+ size_t list_length = g_depth > 3 ? 0 : RandInRange(8);
+ for (size_t index = 0; index < list_length; ++index) {
+ switch (RandInRange(8))
+ {
+ case base::Value::TYPE_BOOLEAN: {
+ bool tmp;
+ generator->GenerateBool(&tmp);
+ p->Set(index, new base::FundamentalValue(tmp));
+ break;
+ }
+ case base::Value::TYPE_INTEGER: {
+ int tmp;
+ generator->GenerateInt(&tmp);
+ p->Set(index, new base::FundamentalValue(tmp));
+ break;
+ }
+ case base::Value::TYPE_DOUBLE: {
+ double tmp;
+ generator->GenerateDouble(&tmp);
+ p->Set(index, new base::FundamentalValue(tmp));
+ break;
+ }
+ case base::Value::TYPE_STRING: {
+ std::string tmp;
+ generator->GenerateString(&tmp);
+ p->Set(index, new base::StringValue(tmp));
+ break;
+ }
+ case base::Value::TYPE_BINARY: {
+ char tmp[200];
+ size_t bin_length = RandInRange(sizeof(tmp));
+ generator->GenerateData(tmp, bin_length);
+ p->Set(index,
+ base::BinaryValue::CreateWithCopiedBuffer(tmp, bin_length));
+ break;
+ }
+ case base::Value::TYPE_DICTIONARY: {
+ base::DictionaryValue* tmp = new base::DictionaryValue();
+ GenerateParam(tmp, generator);
+ p->Set(index, tmp);
+ break;
+ }
+ case base::Value::TYPE_LIST: {
+ base::ListValue* tmp = new base::ListValue();
+ GenerateParam(tmp, generator);
+ p->Set(index, tmp);
+ break;
+ }
+ case base::Value::TYPE_NULL:
+ default:
+ break;
+ }
+ }
+ --g_depth;
+ return true;
+ }
+};
+
+template <>
+struct GenerateTraits<base::DictionaryValue> {
+ static bool Generate(base::DictionaryValue* p, Generator* generator) {
+ ++g_depth;
+ size_t dict_length = g_depth > 3 ? 0 : RandInRange(8);
+ for (size_t index = 0; index < dict_length; ++index) {
+ std::string property;
+ generator->GenerateString(&property);
+ switch (RandInRange(8))
+ {
+ case base::Value::TYPE_BOOLEAN: {
+ bool tmp;
+ generator->GenerateBool(&tmp);
+ p->SetWithoutPathExpansion(property, new base::FundamentalValue(tmp));
+ break;
+ }
+ case base::Value::TYPE_INTEGER: {
+ int tmp;
+ generator->GenerateInt(&tmp);
+ p->SetWithoutPathExpansion(property, new base::FundamentalValue(tmp));
+ break;
+ }
+ case base::Value::TYPE_DOUBLE: {
+ double tmp;
+ generator->GenerateDouble(&tmp);
+ p->SetWithoutPathExpansion(property, new base::FundamentalValue(tmp));
+ break;
+ }
+ case base::Value::TYPE_STRING: {
+ std::string tmp;
+ generator->GenerateString(&tmp);
+ p->SetWithoutPathExpansion(property, new base::StringValue(tmp));
+ break;
+ }
+ case base::Value::TYPE_BINARY: {
+ char tmp[200];
+ size_t bin_length = RandInRange(sizeof(tmp));
+ generator->GenerateData(tmp, bin_length);
+ p->SetWithoutPathExpansion(
+ property,
+ base::BinaryValue::CreateWithCopiedBuffer(tmp, bin_length));
+ break;
+ }
+ case base::Value::TYPE_DICTIONARY: {
+ base::DictionaryValue* tmp = new base::DictionaryValue();
+ GenerateParam(tmp, generator);
+ p->SetWithoutPathExpansion(property, tmp);
+ break;
+ }
+ case base::Value::TYPE_LIST: {
+ base::ListValue* tmp = new base::ListValue();
+ GenerateParam(tmp, generator);
+ p->SetWithoutPathExpansion(property, tmp);
+ break;
+ }
+ case base::Value::TYPE_NULL:
+ default:
+ break;
+ }
+ }
+ --g_depth;
+ return true;
}
};
}
};
+// FIXME: Actually generate something.
+template <>
+struct GenerateTraits<SkBitmap> {
+ static bool Generate(SkBitmap* p, Generator* generator) {
+ *p = SkBitmap();
+ return true;
+ }
+};
+
+template <>
+struct GenerateTraits<IPC::ChannelHandle> {
+ static bool Generate(IPC::ChannelHandle* p, Generator* generator) {
+ return
+ GenerateParam(&p->name, generator) &&
+ GenerateParam(&p->socket, generator);
+ }
+};
+
+template <>
+struct GenerateTraits<cc::CompositorFrame> {
+ // FIXME: this should actually generate something
+ static bool Generate(cc::CompositorFrame* p, Generator* generator) {
+ return true;
+ }
+};
+
+template <>
+struct GenerateTraits<cc::CompositorFrameAck> {
+ // FIXME: this should actually generate something
+ static bool Generate(cc::CompositorFrameAck* p, Generator* generator) {
+ return true;
+ }
+};
+
+template <>
+struct GenerateTraits<content::IndexedDBKey> {
+ static bool Generate(content::IndexedDBKey* p, Generator* generator) {
+ ++g_depth;
+ blink::WebIDBKeyType web_type =
+ static_cast<blink::WebIDBKeyType>(RandInRange(7));
+ switch (web_type)
+ {
+ case blink::WebIDBKeyTypeArray: {
+ size_t length = g_depth > 3 ? 0 : RandInRange(4);
+ std::vector<content::IndexedDBKey> array;
+ array.resize(length);
+ for (size_t i = 0; i < length; ++i) {
+ if (!GenerateParam(&array[i], generator))
+ return false;
+ }
+ *p = content::IndexedDBKey(array);
+ return true;
+ }
+ case blink::WebIDBKeyTypeBinary: {
+ std::string binary;
+ if (!GenerateParam(&binary, generator))
+ return false;
+ *p = content::IndexedDBKey(binary);
+ return true;
+ }
+ case blink::WebIDBKeyTypeString: {
+ base::string16 string;
+ if (!GenerateParam(&string, generator))
+ return false;
+ *p = content::IndexedDBKey(string);
+ return true;
+ }
+ case blink::WebIDBKeyTypeDate:
+ case blink::WebIDBKeyTypeNumber: {
+ double number;
+ if (!GenerateParam(&number, generator))
+ return false;
+ *p = content::IndexedDBKey(number, web_type);
+ return true;
+ }
+ case blink::WebIDBKeyTypeInvalid:
+ case blink::WebIDBKeyTypeNull: {
+ *p = content::IndexedDBKey(web_type);
+ return true;
+ }
+ default:
+ NOTREACHED();
+ return false;
+ }
+ --g_depth;
+ return true;
+ }
+};
+
+template <>
+struct GenerateTraits<content::IndexedDBKeyRange> {
+ static bool Generate(content::IndexedDBKeyRange *p, Generator* generator) {
+ content::IndexedDBKey lower;
+ content::IndexedDBKey upper;
+ bool lower_open;
+ bool upper_open;
+ if (!GenerateParam(&lower, generator))
+ return false;
+ if (!GenerateParam(&upper, generator))
+ return false;
+ if (!GenerateParam(&lower_open, generator))
+ return false;
+ if (!GenerateParam(&upper_open, generator))
+ return false;
+ *p = content::IndexedDBKeyRange(lower, upper, lower_open, upper_open);
+ return true;
+ }
+};
+
+template <>
+struct GenerateTraits<content::IndexedDBKeyPath> {
+ static bool Generate(content::IndexedDBKeyPath *p, Generator* generator) {
+ switch (RandInRange(3)) {
+ case 0: {
+ std::vector<base::string16> array;
+ if (!GenerateParam(&array, generator))
+ return false;
+ *p = content::IndexedDBKeyPath(array);
+ break;
+ }
+ case 1: {
+ base::string16 string;
+ if (!GenerateParam(&string, generator))
+ return false;
+ *p = content::IndexedDBKeyPath(string);
+ break;
+ }
+ case 2: {
+ *p = content::IndexedDBKeyPath();
+ break;
+ }
+ }
+ return true;
+ }
+};
+
+template <>
+struct GenerateTraits<content::PageState> {
+ static bool Generate(content::PageState *p, Generator* generator) {
+ std::string junk;
+ if (!GenerateParam(&junk, generator))
+ return false;
+ *p = content::PageState::CreateFromEncodedData(junk);
+ return true;
+ }
+};
+
+template <>
+struct GenerateTraits<gpu::Mailbox> {
+ static bool Generate(gpu::Mailbox *p, Generator* generator) {
+ generator->GenerateBytes(p->name, sizeof(p->name));
+ return true;
+ }
+};
+
template <>
struct GenerateTraits<media::AudioParameters> {
static bool Generate(media::AudioParameters *p, Generator* generator) {
int format;
int channel_layout;
- int channels;
- int input_channels;
int sample_rate;
int bits_per_sample;
int frames_per_buffer;
+ int channels;
int effects;
if (!GenerateParam(&format, generator))
return false;
if (!GenerateParam(&channel_layout, generator))
return false;
- if (!GenerateParam(&channels, generator))
- return false;
- if (!GenerateParam(&input_channels, generator))
- return false;
if (!GenerateParam(&sample_rate, generator))
return false;
if (!GenerateParam(&bits_per_sample, generator))
return false;
if (!GenerateParam(&frames_per_buffer, generator))
return false;
+ if (!GenerateParam(&channels, generator))
+ return false;
if (!GenerateParam(&effects, generator))
return false;
media::AudioParameters params(
static_cast<media::AudioParameters::Format>(format),
static_cast<media::ChannelLayout>(channel_layout),
- channels, input_channels, sample_rate,
- bits_per_sample, frames_per_buffer, effects);
+ channels,
+ sample_rate,
+ bits_per_sample,
+ frames_per_buffer,
+ effects);
*p = params;
return true;
}
}
};
+
+template <>
+struct GenerateTraits<net::LoadTimingInfo> {
+ static bool Generate(net::LoadTimingInfo *p, Generator* generator) {
+ return
+ GenerateParam(&p->socket_log_id, generator) &&
+ GenerateParam(&p->socket_reused, generator) &&
+ GenerateParam(&p->request_start_time, generator) &&
+ GenerateParam(&p->request_start, generator) &&
+ GenerateParam(&p->proxy_resolve_start, generator) &&
+ GenerateParam(&p->proxy_resolve_end, generator) &&
+ GenerateParam(&p->connect_timing.dns_start, generator) &&
+ GenerateParam(&p->connect_timing.dns_end, generator) &&
+ GenerateParam(&p->connect_timing.connect_start, generator) &&
+ GenerateParam(&p->connect_timing.connect_end, generator) &&
+ GenerateParam(&p->connect_timing.ssl_start, generator) &&
+ GenerateParam(&p->connect_timing.ssl_end, generator) &&
+ GenerateParam(&p->send_start, generator) &&
+ GenerateParam(&p->send_end, generator) &&
+ GenerateParam(&p->receive_headers_end, generator);
+ }
+};
+
template <>
struct GenerateTraits<net::HostPortPair> {
static bool Generate(net::HostPortPair *p, Generator* generator) {
}
};
+// PP_ traits.
+template <>
+struct GenerateTraits<PP_Bool> {
+ static bool Generate(PP_Bool *p, Generator* generator) {
+ bool tmp;
+ if (!GenerateParam(&tmp, generator))
+ return false;
+ *p = PP_FromBool(tmp);
+ return true;
+ }
+};
+
+template <>
+struct GenerateTraits<PP_NetAddress_Private> {
+ static bool Generate(PP_NetAddress_Private *p, Generator* generator) {
+ p->size = RandInRange(sizeof(p->data) + 1);
+ generator->GenerateBytes(&p->data, p->size);
+ return true;
+ }
+};
+
+template <>
+struct GenerateTraits<ppapi::HostResource> {
+ static bool Generate(ppapi::HostResource *p, Generator* generator) {
+ PP_Instance instance;
+ PP_Resource resource;
+ if (!GenerateParam(&instance, generator))
+ return false;
+ if (!GenerateParam(&resource, generator))
+ return false;
+ p->SetHostResource(instance, resource);
+ return true;
+ }
+};
+
+template <>
+struct GenerateTraits<ppapi::PepperFilePath> {
+ static bool Generate(ppapi::PepperFilePath *p, Generator* generator) {
+ unsigned domain = RandInRange(ppapi::PepperFilePath::DOMAIN_MAX_VALID+1);
+ base::FilePath path;
+ if (!GenerateParam(&path, generator))
+ return false;
+ *p = ppapi::PepperFilePath(
+ static_cast<ppapi::PepperFilePath::Domain>(domain), path);
+ return true;
+ }
+};
+
+template <>
+struct GenerateTraits<ppapi::PpapiPermissions> {
+ static bool Generate(ppapi::PpapiPermissions *p, Generator* generator) {
+ uint32_t bits;
+ if (!GenerateParam(&bits, generator))
+ return false;
+ *p = ppapi::PpapiPermissions(bits);
+ return true;
+ }
+};
+
+template <>
+struct GenerateTraits<ppapi::SocketOptionData> {
+ static bool Generate(ppapi::SocketOptionData *p, Generator* generator) {
+ // FIXME: we can do better here.
+ int32 temp;
+ if (!GenerateParam(&temp, generator))
+ return false;
+ p->SetInt32(temp);
+ return true;
+ }
+};
+
// Redefine macros to generate generating from traits declarations.
// STRUCT declarations cause corresponding STRUCT_TRAITS declarations to occur.
#undef IPC_STRUCT_BEGIN
}
std::string output_file_name = args[0];
- int message_count = 10000;
+ int message_count = 1000;
if (cmd->HasSwitch(kCountSwitch))
message_count = atoi(cmd->GetSwitchValueASCII(kCountSwitch).c_str());