Commit 51f60c81 authored by Mark Brand's avatar Mark Brand Committed by Commit Bot

Core non-generated code for MojoLPM fuzzer.

This adds the standalone code for MojoLPM; it's not functional by
itself but it is a dependency for the generated code.

This is a cherrypick/split from
https://chromium-review.googlesource.com/c/chromium/src/+/2108507

Change-Id: I71deba7182adc31acde2546b42808a959a87b8a4
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2109698Reviewed-by: default avatarPeter Kasting <pkasting@chromium.org>
Reviewed-by: default avatarKen Rockot <rockot@google.com>
Commit-Queue: Mark Brand <markbrand@google.com>
Cr-Commit-Position: refs/heads/master@{#751984}
parent 94434052
...@@ -61,3 +61,33 @@ fuzzer_test("mojo_parse_message_proto_fuzzer") { ...@@ -61,3 +61,33 @@ fuzzer_test("mojo_parse_message_proto_fuzzer") {
proto_library("mojo_fuzzer_proto") { proto_library("mojo_fuzzer_proto") {
sources = [ "mojo_fuzzer.proto" ] sources = [ "mojo_fuzzer.proto" ]
} }
copy("mojolpm_proto_copy") {
sources = [ "mojolpm.proto" ]
outputs = [ "$root_gen_dir/mojolpm.proto" ]
testonly = true
}
proto_library("mojolpm_proto") {
sources = [ "mojolpm.proto" ]
generate_python = false
# TODO(markbrand): this is kind of a hack, but it works. not sure if it's
# the best way to get this generated in the right place though.
proto_out_dir = "mojo/public/tools/fuzzers/../../../../"
proto_deps = [ ":mojolpm_proto_copy" ]
testonly = true
}
static_library("mojolpm") {
sources = [
"mojolpm.cc",
"mojolpm.h",
]
deps = [
":mojolpm_proto",
"//base",
"//mojo/public/cpp/bindings",
]
testonly = true
}
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "mojo/public/tools/fuzzers/mojolpm.h"
#include "base/no_destructor.h"
#include "mojo/public/c/system/data_pipe.h"
#include "mojo/public/cpp/system/data_pipe.h"
namespace mojolpm {
Context::Context() : message_(0, 0, 0, 0, nullptr) {}
Context::~Context() = default;
Context::Storage::Storage() = default;
Context::Storage::~Storage() = default;
void Context::StartTestcase(
TestcaseBase* testcase,
scoped_refptr<base::SequencedTaskRunner> task_runner) {
testcase_ = testcase;
task_runner_ = task_runner;
}
void Context::EndTestcase() {
instances_.clear();
testcase_ = nullptr;
}
bool Context::IsFinished() {
if (testcase_) {
return testcase_->IsFinished();
}
return true;
}
void Context::NextAction() {
// fprintf(stderr, "NextAction\n");
CHECK(task_runner_->RunsTasksInCurrentSequence());
if (testcase_) {
testcase_->NextAction();
}
}
void Context::PostNextAction() {
if (task_runner_) {
task_runner_->PostTask(FROM_HERE, base::BindOnce(&Context::NextAction,
base::Unretained(this)));
}
}
Context* g_context = nullptr;
Context* GetContext() {
DCHECK(g_context);
return g_context;
}
void SetContext(Context* context) {
g_context = context;
}
bool FromProto(const bool& input, bool& output) {
output = input;
return true;
}
bool ToProto(const bool& input, bool& output) {
output = input;
return true;
}
bool FromProto(const ::google::protobuf::int32& input, int8_t& output) {
output = input;
return true;
}
bool ToProto(const int8_t& input, ::google::protobuf::int32& output) {
output = input;
return true;
}
bool FromProto(const ::google::protobuf::int32& input, int16_t& output) {
output = input;
return true;
}
bool ToProto(const int16_t& input, ::google::protobuf::int32& output) {
output = input;
return true;
}
bool FromProto(const ::google::protobuf::int32& input, int32_t& output) {
output = input;
return true;
}
bool ToProto(const int32_t& input, ::google::protobuf::int32& output) {
output = input;
return true;
}
bool FromProto(const ::google::protobuf::int64& input, int64_t& output) {
output = input;
return true;
}
bool ToProto(const int64_t& input, ::google::protobuf::int64& output) {
output = input;
return true;
}
bool FromProto(const ::google::protobuf::uint32& input, uint8_t& output) {
output = input;
return true;
}
bool ToProto(const uint8_t& input, ::google::protobuf::uint32& output) {
output = input;
return true;
}
bool FromProto(const ::google::protobuf::uint32& input, uint16_t& output) {
output = input;
return true;
}
bool ToProto(const uint16_t& input, ::google::protobuf::uint32& output) {
output = input;
return true;
}
bool FromProto(const ::google::protobuf::uint32& input, uint32_t& output) {
output = input;
return true;
}
bool ToProto(const uint32_t& input, ::google::protobuf::uint32& output) {
output = input;
return true;
}
bool FromProto(const ::google::protobuf::uint64& input, uint64_t& output) {
output = input;
return true;
}
bool ToProto(const uint64_t& input, ::google::protobuf::uint64& output) {
output = input;
return true;
}
bool FromProto(const double& input, double& output) {
output = input;
return true;
}
bool ToProto(const double& input, double& output) {
output = input;
return true;
}
bool FromProto(const float& input, float& output) {
output = input;
return true;
}
bool ToProto(const float& input, float& output) {
output = input;
return true;
}
bool FromProto(const std::string& input, std::string& output) {
output = input;
return true;
}
bool ToProto(const std::string& input, std::string& output) {
output = input;
return true;
}
bool FromProto(const ::mojolpm::Handle& input, mojo::ScopedHandle& output) {
return true;
}
bool ToProto(const mojo::ScopedHandle& input, ::mojolpm::Handle& output) {
return true;
}
bool FromProto(const ::mojolpm::DataPipeConsumerHandle& input,
mojo::ScopedDataPipeConsumerHandle& output) {
bool result = false;
if (input.instance_case() == ::mojolpm::DataPipeConsumerHandle::kOld) {
auto old = mojolpm::GetContext()
->GetAndRemoveInstance<mojo::ScopedDataPipeConsumerHandle>(
input.old());
if (old) {
output = std::move(*old.release());
}
} else {
MojoCreateDataPipeOptions options;
mojo::ScopedDataPipeConsumerHandle consumer;
mojo::ScopedDataPipeProducerHandle producer;
options.struct_size = sizeof(MojoCreateDataPipeOptions);
options.flags = input.new_().flags();
options.element_num_bytes = input.new_().element_num_bytes();
options.capacity_num_bytes = input.new_().capacity_num_bytes();
if (MOJO_RESULT_OK ==
mojo::CreateDataPipe(&options, &producer, &consumer)) {
result = true;
output = std::move(consumer);
mojolpm::GetContext()->AddInstance(std::move(producer));
}
}
return result;
}
bool ToProto(const mojo::ScopedDataPipeConsumerHandle& input,
::mojolpm::DataPipeConsumerHandle& output) {
return true;
}
bool FromProto(const ::mojolpm::DataPipeProducerHandle& input,
mojo::ScopedDataPipeProducerHandle& output) {
bool result = false;
if (input.instance_case() == ::mojolpm::DataPipeProducerHandle::kOld) {
auto old = mojolpm::GetContext()
->GetAndRemoveInstance<mojo::ScopedDataPipeProducerHandle>(
input.old());
if (old) {
output = std::move(*old.release());
}
} else {
MojoCreateDataPipeOptions options;
mojo::ScopedDataPipeConsumerHandle consumer;
mojo::ScopedDataPipeProducerHandle producer;
options.struct_size = sizeof(MojoCreateDataPipeOptions);
options.flags = input.new_().flags();
options.element_num_bytes = input.new_().element_num_bytes();
options.capacity_num_bytes = input.new_().capacity_num_bytes();
if (MOJO_RESULT_OK ==
mojo::CreateDataPipe(&options, &producer, &consumer)) {
result = true;
output = std::move(producer);
mojolpm::GetContext()->AddInstance(std::move(consumer));
}
}
return result;
}
bool ToProto(const mojo::ScopedDataPipeProducerHandle& input,
::mojolpm::DataPipeProducerHandle& output) {
return true;
}
bool FromProto(const ::mojolpm::MessagePipeHandle& input,
mojo::ScopedMessagePipeHandle& output) {
return true;
}
bool ToProto(const mojo::ScopedMessagePipeHandle& input,
::mojolpm::MessagePipeHandle& output) {
return true;
}
bool FromProto(const ::mojolpm::SharedBufferHandle& input,
mojo::ScopedSharedBufferHandle& output) {
return true;
}
bool ToProto(const mojo::ScopedSharedBufferHandle& input,
::mojolpm::SharedBufferHandle& output) {
return true;
}
bool FromProto(const ::mojolpm::PlatformHandle& input,
mojo::PlatformHandle& output) {
return true;
}
bool ToProto(const mojo::PlatformHandle& input,
::mojolpm::PlatformHandle& output) {
return true;
}
void HandleDataPipeRead(const ::mojolpm::DataPipeRead& input) {
mojo::ScopedDataPipeConsumerHandle* consumer_ptr = nullptr;
if (input.handle().instance_case() ==
::mojolpm::DataPipeConsumerHandle::kOld) {
consumer_ptr =
mojolpm::GetContext()->GetInstance<mojo::ScopedDataPipeConsumerHandle>(
input.handle().old());
} else {
MojoCreateDataPipeOptions options;
mojo::ScopedDataPipeConsumerHandle consumer;
mojo::ScopedDataPipeProducerHandle producer;
options.struct_size = sizeof(MojoCreateDataPipeOptions);
options.flags = input.handle().new_().flags();
options.element_num_bytes = input.handle().new_().element_num_bytes();
options.capacity_num_bytes = input.handle().new_().capacity_num_bytes();
if (MOJO_RESULT_OK ==
mojo::CreateDataPipe(&options, &producer, &consumer)) {
int id = mojolpm::GetContext()->AddInstance(std::move(consumer));
mojolpm::GetContext()->AddInstance(std::move(producer));
consumer_ptr = mojolpm::GetContext()
->GetInstance<mojo::ScopedDataPipeConsumerHandle>(id);
}
}
if (consumer_ptr) {
uint32_t size = input.size();
std::vector<char> data(size);
consumer_ptr->get().ReadData(data.data(), &size, 0);
}
}
void HandleDataPipeWrite(const ::mojolpm::DataPipeWrite& input) {
mojo::ScopedDataPipeProducerHandle* producer_ptr = nullptr;
if (input.handle().instance_case() ==
::mojolpm::DataPipeProducerHandle::kOld) {
producer_ptr =
mojolpm::GetContext()->GetInstance<mojo::ScopedDataPipeProducerHandle>(
input.handle().old());
} else {
MojoCreateDataPipeOptions options;
mojo::ScopedDataPipeConsumerHandle consumer;
mojo::ScopedDataPipeProducerHandle producer;
options.struct_size = sizeof(MojoCreateDataPipeOptions);
options.flags = input.handle().new_().flags();
options.element_num_bytes = input.handle().new_().element_num_bytes();
options.capacity_num_bytes = input.handle().new_().capacity_num_bytes();
if (MOJO_RESULT_OK ==
mojo::CreateDataPipe(&options, &producer, &consumer)) {
mojolpm::GetContext()->AddInstance(std::move(consumer));
int id = mojolpm::GetContext()->AddInstance(std::move(producer));
producer_ptr = mojolpm::GetContext()
->GetInstance<mojo::ScopedDataPipeProducerHandle>(id);
}
}
if (producer_ptr) {
uint32_t size = static_cast<uint32_t>(input.data().size());
producer_ptr->get().WriteData(input.data().data(), &size, 0);
}
}
void HandleDataPipeConsumerClose(
const ::mojolpm::DataPipeConsumerClose& input) {
mojolpm::GetContext()->RemoveInstance<mojo::ScopedDataPipeConsumerHandle>(
input.id());
}
void HandleDataPipeProducerClose(
const ::mojolpm::DataPipeProducerClose& input) {
mojolpm::GetContext()->RemoveInstance<mojo::ScopedDataPipeProducerHandle>(
input.id());
}
} // namespace mojolpm
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef MOJO_PUBLIC_TOOLS_FUZZERS_MOJOLPM_H_
#define MOJO_PUBLIC_TOOLS_FUZZERS_MOJOLPM_H_
#include <map>
#include "base/containers/flat_map.h"
#include "base/logging.h"
#include "base/optional.h"
#include "mojo/public/cpp/bindings/associated_interface_ptr.h"
#include "mojo/public/cpp/bindings/associated_remote.h"
#include "mojo/public/cpp/bindings/interface_ptr.h"
#include "mojo/public/cpp/bindings/remote.h"
#include "mojo/public/cpp/platform/platform_handle.h"
#include "mojo/public/cpp/system/core.h"
#include "mojo/public/cpp/system/data_pipe.h"
#include "mojolpm.pb.h"
#define MOJOLPM_DBG 0
#if MOJOLPM_DBG
#define mojolpmdbg(msg, ...) fprintf(stderr, msg, ##__VA_ARGS__)
#else
#define mojolpmdbg(msg, ...)
#endif
namespace mojolpm {
typedef void* TypeId;
template <typename T>
TypeId type_id() {
static std::remove_reference<T>* ptr = nullptr;
return &ptr;
}
#if MOJOLPM_DBG
template <typename T>
std::string type_name() {
return std::string(__PRETTY_FUNCTION__)
.substr(38, strlen(__PRETTY_FUNCTION__) - 39);
}
#endif
class TestcaseBase {
public:
virtual ~TestcaseBase() = default;
virtual bool IsFinished() = 0;
virtual void NextAction() = 0;
};
class Context {
struct Storage {
Storage();
template <typename T>
explicit Storage(T&& value);
~Storage();
struct StorageWrapperBase {
virtual ~StorageWrapperBase() = default;
virtual TypeId type() const = 0;
};
template <typename T>
struct StorageWrapper : StorageWrapperBase {
StorageWrapper() = default;
explicit StorageWrapper(T&& value);
TypeId type() const override;
T& value();
const T& value() const;
private:
T value_;
};
template <typename T>
T& get();
template <typename T>
const T& get() const;
template <typename T>
std::unique_ptr<T> release();
private:
std::unique_ptr<StorageWrapperBase> wrapper_;
};
TestcaseBase* testcase_;
std::map<TypeId, std::map<uint32_t, Storage>> instances_;
scoped_refptr<base::SequencedTaskRunner> task_runner_;
mojo::Message message_;
public:
explicit Context();
Context(const Context&) = delete;
~Context();
template <typename T>
T* GetInstance(uint32_t id);
template <typename T>
std::unique_ptr<T> GetAndRemoveInstance(uint32_t id);
template <typename T>
void RemoveInstance(uint32_t id);
template <typename T>
uint32_t AddInstance(T&& instance);
template <typename T>
uint32_t AddInstance(uint32_t id, T&& instance);
template <typename T>
uint32_t NextId();
void StartTestcase(TestcaseBase* testcase,
scoped_refptr<base::SequencedTaskRunner> task_runner);
void EndTestcase();
bool IsFinished();
void NextAction();
void PostNextAction();
scoped_refptr<base::SequencedTaskRunner> task_runner() const {
return task_runner_;
}
mojo::Message& message() { return message_; }
};
Context* GetContext();
void SetContext(Context* context);
template <typename T>
Context::Storage::Storage(T&& value) {
wrapper_ = std::make_unique<StorageWrapper<T>>(std::move(value));
}
template <typename T>
T& Context::Storage::Storage::get() {
// DCHECK(wrapper_->type() == type_id<T>());
DCHECK(static_cast<StorageWrapper<T>*>(wrapper_.get()));
return static_cast<StorageWrapper<T>*>(wrapper_.get())->value();
}
template <typename T>
const T& Context::Storage::Storage::get() const {
// DCHECK(wrapper_->type() == type_id<T>());
DCHECK(static_cast<StorageWrapper<T>*>(wrapper_.get()));
return static_cast<StorageWrapper<T>*>(wrapper_.get())->value();
}
template <typename T>
std::unique_ptr<T> Context::Storage::Storage::release() {
// DCHECK(wrapper_->type() == type_id<T>());
DCHECK(static_cast<StorageWrapper<T>*>(wrapper_.get()));
return std::make_unique<T>(
std::move(static_cast<StorageWrapper<T>*>(wrapper_.get())->value()));
}
template <typename T>
Context::Storage::StorageWrapper<T>::StorageWrapper(T&& value)
: value_(std::move(value)) {}
template <typename T>
TypeId Context::Storage::StorageWrapper<T>::type() const {
return type_id<T>();
}
template <typename T>
T& Context::Storage::StorageWrapper<T>::value() {
return value_;
}
template <typename T>
const T& Context::Storage::StorageWrapper<T>::value() const {
return value_;
}
template <typename T>
T* Context::GetInstance(uint32_t id) {
DCHECK(task_runner_->RunsTasksInCurrentSequence());
mojolpmdbg("getInstance(%s, %i) = ", type_name<T>().c_str(), id);
auto instances_iter = instances_.find(type_id<T>());
if (instances_iter == instances_.end()) {
mojolpmdbg("failed!\n");
return nullptr;
} else {
auto& instance_map = instances_iter->second;
// normalize id to [0, max_id]
if (instance_map.size() > 0 && instance_map.rbegin()->first < id) {
id = id % (instance_map.rbegin()->first + 1);
}
// choose the first valid entry after id
auto instance = instance_map.lower_bound(id);
if (instance == instance_map.end()) {
mojolpmdbg("failed!\n");
return nullptr;
}
mojolpmdbg("%i\n", instance->first);
return &instance->second.template get<T>();
}
}
template <typename T>
std::unique_ptr<T> Context::GetAndRemoveInstance(uint32_t id) {
DCHECK(task_runner_->RunsTasksInCurrentSequence());
mojolpmdbg("getAndRemoveInstance(%s, %i) = ", type_name<T>().c_str(), id);
auto instances_iter = instances_.find(type_id<T>());
if (instances_iter == instances_.end()) {
mojolpmdbg("failed\n");
return nullptr;
} else {
auto& instance_map = instances_iter->second;
// normalize id to [0, max_id]
if (instance_map.size() > 0 && instance_map.rbegin()->first < id) {
id = id % (instance_map.rbegin()->first + 1);
}
// choose the first valid entry after id
auto instance = instance_map.lower_bound(id);
if (instance == instance_map.end()) {
mojolpmdbg("failed!\n");
return nullptr;
}
mojolpmdbg("%i\n", instance->first);
auto result = instance->second.template release<T>();
instance_map.erase(instance);
return std::move(result);
}
}
template <typename T>
void Context::RemoveInstance(uint32_t id) {
DCHECK(task_runner_->RunsTasksInCurrentSequence());
mojolpmdbg("RemoveInstance(%s, %u) = ", type_name<T>().c_str(), id);
auto instances_iter = instances_.find(type_id<T>());
if (instances_iter != instances_.end()) {
auto& instance_map = instances_iter->second;
// normalize id to [0, max_id]
if (instance_map.size() > 0 && instance_map.rbegin()->first < id) {
id = id % (instance_map.rbegin()->first + 1);
}
// choose the first valid entry after id
auto instance = instance_map.lower_bound(id);
if (instance == instance_map.end()) {
mojolpmdbg("failed!\n");
return;
}
instance_map.erase(instance);
} else {
mojolpmdbg("failed!\n");
}
}
template <typename T>
uint32_t Context::AddInstance(T&& instance) {
DCHECK(task_runner_->RunsTasksInCurrentSequence());
auto instances_iter = instances_.find(type_id<T>());
uint32_t id = 1;
if (instances_iter == instances_.end()) {
instances_[type_id<T>()].emplace(id, std::move(instance));
} else {
auto& instance_map = instances_iter->second;
auto instance_map_iter = instance_map.begin();
while (instance_map_iter != instance_map.end()) {
id = instance_map_iter->first + 1;
instance_map_iter = instance_map.find(id);
}
instance_map.emplace(id, std::move(instance));
}
mojolpmdbg("addInstance(%s, %u)\n", type_name<T>().c_str(), id);
return id;
}
template <typename T>
uint32_t Context::AddInstance(uint32_t id, T&& instance) {
DCHECK(task_runner_->RunsTasksInCurrentSequence());
auto instances_iter = instances_.find(type_id<T>());
if (instances_iter == instances_.end()) {
instances_[type_id<T>()].emplace(id, std::move(instance));
} else {
auto& instance_map = instances_iter->second;
auto instance_map_iter = instance_map.find(id);
while (instance_map_iter != instance_map.end()) {
id = instance_map_iter->first + 1;
instance_map_iter = instance_map.find(id);
}
instance_map.emplace(id, std::move(instance));
}
mojolpmdbg("addInstance(%s, %u)\n", type_name<T>().c_str(), id);
return id;
}
template <typename T>
uint32_t Context::NextId() {
DCHECK(task_runner_->RunsTasksInCurrentSequence());
uint32_t id = 1;
auto instances_iter = instances_.find(type_id<T>());
if (instances_iter != instances_.end()) {
auto& instance_map = instances_iter->second;
if (instance_map.size() > 0) {
id = instance_map.rbegin()->first + 1;
}
}
return id;
}
template <typename T>
std::unique_ptr<mojo::InterfacePtr<T>> NewInstance() {
// mojolpmdbg("default NewInstance<>\n");
return nullptr;
}
template <typename T>
std::unique_ptr<mojo::AssociatedInterfacePtr<T>> NewAssociatedInstance() {
// mojolpmdbg("default NewInstanceA<>\n");
return nullptr;
}
template <typename T>
std::unique_ptr<mojo::Remote<T>> NewRemote() {
// mojolpmdbg("default NewInstance<>\n");
return nullptr;
}
template <typename T>
std::unique_ptr<mojo::AssociatedRemote<T>> NewAssociatedRemote() {
// mojolpmdbg("default NewInstanceA<>\n");
return nullptr;
}
template <typename T>
uint32_t NextId() {
return GetContext()->NextId<T>();
}
template <typename T>
void ResetRemote(uint32_t remote_id) {
auto remote_ref = GetContext()->GetInstance<mojo::Remote<T>>(remote_id);
if (remote_ref) {
remote_ref->reset();
}
}
template <typename T>
uint32_t AddRemote(uint32_t remote_id, mojo::Remote<T>&& remote) {
remote_id =
GetContext()->AddInstance<mojo::Remote<T>>(remote_id, std::move(remote));
auto remote_ref = GetContext()->GetInstance<mojo::Remote<T>>(remote_id);
CHECK(remote_ref);
remote_ref->set_disconnect_handler(
base::BindOnce(&ResetRemote<T>, remote_id));
return remote_id;
}
template <typename T>
void ResetAssociatedRemote(uint32_t remote_id) {
auto remote_ref =
GetContext()->GetInstance<mojo::AssociatedRemote<T>>(remote_id);
if (remote_ref) {
remote_ref->reset();
}
}
template <typename T>
uint32_t AddAssociatedRemote(uint32_t remote_id,
mojo::AssociatedRemote<T>&& remote) {
remote_id = GetContext()->AddInstance<mojo::AssociatedRemote<T>>(
remote_id, std::move(remote));
auto remote_ref =
GetContext()->GetInstance<mojo::AssociatedRemote<T>>(remote_id);
CHECK(remote_ref);
remote_ref->set_disconnect_handler(
base::BindOnce(&ResetAssociatedRemote<T>, remote_id));
return remote_id;
}
bool FromProto(const bool& input, bool& output);
bool ToProto(const bool& input, bool& output);
bool FromProto(const ::google::protobuf::int32& input, int8_t& output);
bool ToProto(const int8_t& input, ::google::protobuf::int32& output);
bool FromProto(const ::google::protobuf::int32& input, int16_t& output);
bool ToProto(const int16_t& input, ::google::protobuf::int32& output);
bool FromProto(const ::google::protobuf::int32& input, int32_t& output);
bool ToProto(const int32_t& input, ::google::protobuf::int32& output);
bool FromProto(const ::google::protobuf::int64& input, int64_t& output);
bool ToProto(const int64_t& input, ::google::protobuf::int64& output);
bool FromProto(const ::google::protobuf::uint32& input, uint8_t& output);
bool ToProto(const uint8_t& input, ::google::protobuf::uint32& output);
bool FromProto(const ::google::protobuf::uint32& input, uint16_t& output);
bool ToProto(const uint16_t& input, ::google::protobuf::uint32& output);
bool FromProto(const ::google::protobuf::uint32& input, uint32_t& output);
bool ToProto(const uint32_t& input, ::google::protobuf::uint32& output);
bool FromProto(const ::google::protobuf::uint64& input, uint64_t& output);
bool ToProto(const uint64_t& input, ::google::protobuf::uint64& output);
bool FromProto(const double& input, double& output);
bool ToProto(const double& input, double& output);
bool FromProto(const float& input, float& output);
bool ToProto(const float& input, float& output);
bool FromProto(const std::string& input, std::string& output);
bool ToProto(const std::string& input, std::string& output);
bool FromProto(const ::mojolpm::Handle& input, mojo::ScopedHandle& output);
bool ToProto(const mojo::ScopedHandle& input, ::mojolpm::Handle& output);
bool FromProto(const ::mojolpm::DataPipeConsumerHandle& input,
mojo::ScopedDataPipeConsumerHandle& output);
bool ToProto(const mojo::ScopedDataPipeConsumerHandle& input,
::mojolpm::DataPipeConsumerHandle& output);
bool FromProto(const ::mojolpm::DataPipeProducerHandle& input,
mojo::ScopedDataPipeProducerHandle& output);
bool ToProto(const mojo::ScopedDataPipeProducerHandle& input,
::mojolpm::DataPipeProducerHandle& output);
bool FromProto(const ::mojolpm::MessagePipeHandle& input,
mojo::ScopedMessagePipeHandle& output);
bool ToProto(const mojo::ScopedMessagePipeHandle& input,
::mojolpm::MessagePipeHandle& output);
bool FromProto(const ::mojolpm::SharedBufferHandle& input,
mojo::ScopedSharedBufferHandle& output);
bool ToProto(const mojo::ScopedSharedBufferHandle& input,
::mojolpm::SharedBufferHandle& output);
bool FromProto(const ::mojolpm::PlatformHandle& input,
mojo::PlatformHandle& output);
bool ToProto(const mojo::PlatformHandle& input,
::mojolpm::PlatformHandle& output);
void HandleDataPipeRead(const ::mojolpm::DataPipeRead& input);
void HandleDataPipeWrite(const ::mojolpm::DataPipeWrite& input);
void HandleDataPipeConsumerClose(const ::mojolpm::DataPipeConsumerClose& input);
void HandleDataPipeProducerClose(const ::mojolpm::DataPipeProducerClose& input);
} // namespace mojolpm
#endif // MOJO_PUBLIC_TOOLS_FUZZERS_MOJOLPM_H_
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
syntax = "proto2";
package mojolpm;
// TODO(markbrand): Is there anything sensible to do to fuzz interfaces that
// use or expect a generic mojo handle?
message Handle {}
message CreateDataPipeOptions {
required uint32 flags = 2;
required uint32 element_num_bytes = 3;
required uint32 capacity_num_bytes = 4;
}
message DataPipeConsumerHandle {
oneof instance {
uint32 old = 1;
CreateDataPipeOptions new = 2;
}
}
message DataPipeProducerHandle {
oneof instance {
uint32 old = 1;
CreateDataPipeOptions new = 2;
}
}
message DataPipeRead {
required DataPipeConsumerHandle handle = 1;
required uint32 size = 2;
}
message DataPipeWrite {
required DataPipeProducerHandle handle = 1;
required bytes data = 2;
}
message DataPipeConsumerClose {
required uint32 id = 1;
}
message DataPipeProducerClose {
required uint32 id = 1;
}
// TODO(markbrand): Implement these last two.
message MessagePipeHandle {}
message SharedBufferHandle {}
message PlatformHandle {}
...@@ -227,6 +227,10 @@ static_library("protobuf_full") { ...@@ -227,6 +227,10 @@ static_library("protobuf_full") {
"//gpu:gl_lpm_fuzzer_proto", "//gpu:gl_lpm_fuzzer_proto",
"//gpu:gl_lpm_fuzzer_proto_gen", "//gpu:gl_lpm_fuzzer_proto_gen",
"//gpu:gl_lpm_shader_to_string_unittest", "//gpu:gl_lpm_shader_to_string_unittest",
# The protobuf-based Mojo LPM fuzzer needs protobuf_full and is not included
# in Chrome.
"//mojo/public/tools/fuzzers:mojolpm",
] ]
sources = protobuf_lite_sources + [ sources = protobuf_lite_sources + [
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment