summaryrefslogtreecommitdiff
path: root/chromium/mojo
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2019-05-24 11:40:17 +0200
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2019-05-24 12:42:11 +0000
commit5d87695f37678f96492b258bbab36486c59866b4 (patch)
treebe9783bbaf04fb930c4d74ca9c00b5e7954c8bc6 /chromium/mojo
parent6c11fb357ec39bf087b8b632e2b1e375aef1b38b (diff)
downloadqtwebengine-chromium-5d87695f37678f96492b258bbab36486c59866b4.tar.gz
BASELINE: Update Chromium to 75.0.3770.56
Change-Id: I86d2007fd27a45d5797eee06f4c9369b8b50ac4f Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>
Diffstat (limited to 'chromium/mojo')
-rw-r--r--chromium/mojo/core/BUILD.gn56
-rw-r--r--chromium/mojo/core/channel.cc268
-rw-r--r--chromium/mojo/core/channel.h66
-rw-r--r--chromium/mojo/core/channel_fuchsia.cc4
-rw-r--r--chromium/mojo/core/channel_mac.cc718
-rw-r--r--chromium/mojo/core/channel_mac_fuzzer.cc136
-rw-r--r--chromium/mojo/core/channel_posix.cc29
-rw-r--r--chromium/mojo/core/channel_unittest.cc123
-rw-r--r--chromium/mojo/core/embedder_unittest.cc9
-rw-r--r--chromium/mojo/core/invitation_unittest.cc14
-rw-r--r--chromium/mojo/core/ports/name.h2
-rw-r--r--chromium/mojo/core/ports/node.cc4
-rw-r--r--chromium/mojo/core/test/BUILD.gn14
-rw-r--r--chromium/mojo/core/watcher_dispatcher.cc4
-rw-r--r--chromium/mojo/public/BUILD.gn1
-rw-r--r--chromium/mojo/public/c/system/macros.h36
-rw-r--r--chromium/mojo/public/cpp/base/values_mojom_traits.h7
-rw-r--r--chromium/mojo/public/cpp/bindings/BUILD.gn3
-rw-r--r--chromium/mojo/public/cpp/bindings/README.md2
-rw-r--r--chromium/mojo/public/cpp/bindings/call_internal.cc18
-rw-r--r--chromium/mojo/public/cpp/bindings/call_internal.h48
-rw-r--r--chromium/mojo/public/cpp/bindings/lib/interface_serialization.h4
-rw-r--r--chromium/mojo/public/cpp/bindings/lib/serialization_util.h56
-rw-r--r--chromium/mojo/public/cpp/bindings/lib/string_serialization.h9
-rw-r--r--chromium/mojo/public/cpp/bindings/lib/string_traits_wtf.cc57
-rw-r--r--chromium/mojo/public/cpp/bindings/pending_receiver.h23
-rw-r--r--chromium/mojo/public/cpp/bindings/pending_remote.h15
-rw-r--r--chromium/mojo/public/cpp/bindings/receiver.h27
-rw-r--r--chromium/mojo/public/cpp/bindings/receiver_set.h334
-rw-r--r--chromium/mojo/public/cpp/bindings/remote.h42
-rw-r--r--chromium/mojo/public/cpp/bindings/string_traits.h28
-rw-r--r--chromium/mojo/public/cpp/bindings/string_traits_stl.h4
-rw-r--r--chromium/mojo/public/cpp/bindings/string_traits_string_piece.h8
-rw-r--r--chromium/mojo/public/cpp/bindings/string_traits_wtf.h8
-rw-r--r--chromium/mojo/public/cpp/platform/BUILD.gn4
-rw-r--r--chromium/mojo/public/cpp/platform/named_platform_channel_mac.cc83
-rw-r--r--chromium/mojo/public/cpp/platform/named_platform_channel_posix.cc23
-rw-r--r--chromium/mojo/public/cpp/platform/platform_channel.cc94
-rw-r--r--chromium/mojo/public/cpp/platform/platform_channel.h12
-rw-r--r--chromium/mojo/public/cpp/system/buffer.h2
-rw-r--r--chromium/mojo/public/cpp/system/data_pipe.h12
-rw-r--r--chromium/mojo/public/cpp/system/platform_handle.cc4
-rw-r--r--chromium/mojo/public/cpp/system/platform_handle.h8
-rw-r--r--chromium/mojo/public/cpp/test/BUILD.gn12
-rw-r--r--chromium/mojo/public/interfaces/bindings/tests/BUILD.gn2
-rw-r--r--chromium/mojo/public/java/system/BUILD.gn1
-rw-r--r--chromium/mojo/public/js/BUILD.gn6
-rw-r--r--chromium/mojo/public/js/bindings_lite.js8
-rw-r--r--chromium/mojo/public/js/interface_support.js17
-rw-r--r--chromium/mojo/public/js/mojo_bindings_resources.grd13
-rw-r--r--chromium/mojo/public/js/test/BUILD.gn46
-rw-r--r--chromium/mojo/public/tools/bindings/chromium_bindings_configuration.gni6
-rwxr-xr-xchromium/mojo/public/tools/bindings/generate_type_mappings.py2
-rw-r--r--chromium/mojo/public/tools/bindings/generators/cpp_templates/enum_macros.tmpl10
-rw-r--r--chromium/mojo/public/tools/bindings/generators/cpp_templates/interface_declaration.tmpl7
-rw-r--r--chromium/mojo/public/tools/bindings/generators/cpp_templates/interface_definition.tmpl4
-rw-r--r--chromium/mojo/public/tools/bindings/generators/cpp_templates/module-forward.h.tmpl21
-rw-r--r--chromium/mojo/public/tools/bindings/generators/cpp_templates/module-shared-internal.h.tmpl6
-rw-r--r--chromium/mojo/public/tools/bindings/generators/cpp_templates/module-shared.h.tmpl10
-rw-r--r--chromium/mojo/public/tools/bindings/generators/cpp_templates/module.h.tmpl18
-rw-r--r--chromium/mojo/public/tools/bindings/generators/cpp_templates/struct_serialization_declaration.tmpl4
-rw-r--r--chromium/mojo/public/tools/bindings/generators/cpp_templates/union_declaration.tmpl7
-rw-r--r--chromium/mojo/public/tools/bindings/generators/cpp_templates/union_serialization_declaration.tmpl11
-rw-r--r--chromium/mojo/public/tools/bindings/generators/cpp_templates/wrapper_class_declaration.tmpl6
-rw-r--r--chromium/mojo/public/tools/bindings/generators/cpp_templates/wrapper_union_class_declaration.tmpl6
-rw-r--r--chromium/mojo/public/tools/bindings/generators/java_templates/enum_definition.tmpl38
-rw-r--r--chromium/mojo/public/tools/bindings/generators/js_templates/lite/enum_definition.tmpl11
-rw-r--r--chromium/mojo/public/tools/bindings/generators/js_templates/lite/interface_definition.tmpl16
-rw-r--r--chromium/mojo/public/tools/bindings/generators/js_templates/lite/mojom-lite.js.tmpl7
-rw-r--r--chromium/mojo/public/tools/bindings/generators/js_templates/lite/struct_definition.tmpl2
-rw-r--r--chromium/mojo/public/tools/bindings/generators/js_templates/lite/union_definition.tmpl3
-rw-r--r--chromium/mojo/public/tools/bindings/generators/mojom_cpp_generator.py4
-rw-r--r--chromium/mojo/public/tools/bindings/generators/mojom_java_generator.py12
-rw-r--r--chromium/mojo/public/tools/bindings/generators/mojom_js_generator.py25
-rw-r--r--chromium/mojo/public/tools/bindings/mojom.gni12
-rwxr-xr-xchromium/mojo/public/tools/bindings/mojom_bindings_generator.py59
-rw-r--r--chromium/mojo/public/tools/bindings/pylib/mojom/generate/generator.py11
-rw-r--r--chromium/mojo/public/tools/bindings/pylib/mojom/generate/module.py1
-rw-r--r--chromium/mojo/public/tools/bindings/pylib/mojom/generate/pack.py10
-rw-r--r--chromium/mojo/public/tools/bindings/pylib/mojom/generate/template_expander.py2
-rw-r--r--chromium/mojo/public/tools/bindings/pylib/mojom/generate/translate.py79
-rw-r--r--chromium/mojo/public/tools/bindings/pylib/mojom/parse/ast.py2
-rw-r--r--chromium/mojo/public/tools/fuzzers/DEPS3
-rw-r--r--chromium/mojo/public/tools/fuzzers/OWNERS2
-rw-r--r--chromium/mojo/public/tools/fuzzers/fuzz_impl.cc45
-rw-r--r--chromium/mojo/public/tools/fuzzers/fuzz_impl.h45
-rw-r--r--chromium/mojo/public/tools/fuzzers/message_corpus/message_0.mojomsgbin32 -> 0 bytes
-rw-r--r--chromium/mojo/public/tools/fuzzers/message_corpus/message_1.mojomsgbin40 -> 0 bytes
-rw-r--r--chromium/mojo/public/tools/fuzzers/message_corpus/message_10.mojomsgbin32 -> 0 bytes
-rw-r--r--chromium/mojo/public/tools/fuzzers/message_corpus/message_11.mojomsgbin72 -> 0 bytes
-rw-r--r--chromium/mojo/public/tools/fuzzers/message_corpus/message_2.mojomsgbin40 -> 0 bytes
-rw-r--r--chromium/mojo/public/tools/fuzzers/message_corpus/message_3.mojomsgbin328 -> 0 bytes
-rw-r--r--chromium/mojo/public/tools/fuzzers/message_corpus/message_4.mojomsgbin1736 -> 0 bytes
-rw-r--r--chromium/mojo/public/tools/fuzzers/message_corpus/message_5.mojomsgbin1744 -> 0 bytes
-rw-r--r--chromium/mojo/public/tools/fuzzers/message_corpus/message_6.mojomsgbin1744 -> 0 bytes
-rw-r--r--chromium/mojo/public/tools/fuzzers/message_corpus/message_7.mojomsgbin1744 -> 0 bytes
-rw-r--r--chromium/mojo/public/tools/fuzzers/message_corpus/message_8.mojomsgbin1744 -> 0 bytes
-rw-r--r--chromium/mojo/public/tools/fuzzers/message_corpus/message_9.mojomsgbin80 -> 0 bytes
-rw-r--r--chromium/mojo/public/tools/fuzzers/mojo_fuzzer.proto7
-rw-r--r--chromium/mojo/public/tools/fuzzers/mojo_fuzzer_message_dump.cc268
-rw-r--r--chromium/mojo/public/tools/fuzzers/mojo_parse_message_fuzzer.cc62
-rw-r--r--chromium/mojo/public/tools/fuzzers/mojo_parse_message_proto_corpus/07775ad8fdb79599024caefbe7889501dfee9e061
-rw-r--r--chromium/mojo/public/tools/fuzzers/mojo_parse_message_proto_corpus/2ce2f91669a46921ebf4e47679c86dd2bf5b14961
-rw-r--r--chromium/mojo/public/tools/fuzzers/mojo_parse_message_proto_corpus/32a65dcd84debde03d51f8b8ace2cdcc87461d341
-rw-r--r--chromium/mojo/public/tools/fuzzers/mojo_parse_message_proto_corpus/7cbf9144ec3980eb121eedc679ebc56a3ddd22a61
-rw-r--r--chromium/mojo/public/tools/fuzzers/mojo_parse_message_proto_corpus/9ccc6b5c0a61672816dc252194c3d722c18107bc1
-rw-r--r--chromium/mojo/public/tools/fuzzers/mojo_parse_message_proto_corpus/9e0a62bdd4b08cb777bee9449a22b3ad6702b1061
-rw-r--r--chromium/mojo/public/tools/fuzzers/mojo_parse_message_proto_corpus/a74241101f97704b96c9ba11b4781651e236ad8f1
-rw-r--r--chromium/mojo/public/tools/fuzzers/mojo_parse_message_proto_corpus/be66c5d078fbf574388b7b1d25a29ff2d16df67e1
-rw-r--r--chromium/mojo/public/tools/fuzzers/mojo_parse_message_proto_corpus/e4be6bde72d04c5cda7d4939a80e5890c5c013741
-rw-r--r--chromium/mojo/public/tools/fuzzers/mojo_parse_message_proto_fuzzer.cc71
111 files changed, 2377 insertions, 1071 deletions
diff --git a/chromium/mojo/core/BUILD.gn b/chromium/mojo/core/BUILD.gn
index acfbeb9e508..515972a9cf5 100644
--- a/chromium/mojo/core/BUILD.gn
+++ b/chromium/mojo/core/BUILD.gn
@@ -6,6 +6,10 @@ import("//build/config/nacl/config.gni")
import("//testing/libfuzzer/fuzzer_test.gni")
import("//testing/test.gni")
+if (is_mac) {
+ import("//third_party/protobuf/proto_library.gni")
+}
+
component("embedder_internal") {
output_name = "mojo_core_embedder_internal"
public_deps = [
@@ -126,6 +130,7 @@ template("core_impl_source_set") {
if (is_mac && !is_ios) {
sources += [
+ "channel_mac.cc",
"mach_port_relay.cc",
"mach_port_relay.h",
]
@@ -347,6 +352,57 @@ fuzzer_test("mojo_core_channel_fuzzer") {
]
}
+if (is_mac) {
+ protoc_convert("mojo_core_channel_mac_fuzzer_convert_corpus") {
+ sources = [
+ "test/data/channel_mac/bad_handshake1.textproto",
+ "test/data/channel_mac/bad_handshake2.textproto",
+ "test/data/channel_mac/bad_handshake3.textproto",
+ "test/data/channel_mac/bad_message1.textproto",
+ "test/data/channel_mac/complex_messages.textproto",
+ "test/data/channel_mac/double_handshake.textproto",
+ "test/data/channel_mac/handshake.textproto",
+ "test/data/channel_mac/invalid_handles.textproto",
+ "test/data/channel_mac/non_complex_with_descriptor_count.textproto",
+ "test/data/channel_mac/ool_type_mismatch.textproto",
+ "test/data/channel_mac/simple_message1.textproto",
+ "test/data/channel_mac/simple_message2.textproto",
+ ]
+
+ inputs = [
+ "test/data/channel_mac/channel_mac.proto",
+ "//testing/libfuzzer/fuzzers/mach/mach_message.proto",
+ ]
+
+ output_pattern = "$target_gen_dir/mojo_core_channel_mac_corpus/{{source_name_part}}.binarypb"
+
+ args = [
+ "--encode=mojo_fuzzer.ChannelMac",
+ "-I",
+ rebase_path("//testing/libfuzzer/fuzzers/mach"),
+ "-I",
+ rebase_path("//mojo/core/test/data/channel_mac"),
+ "channel_mac.proto",
+ ]
+ }
+
+ fuzzer_test("mojo_core_channel_mac_fuzzer") {
+ sources = [
+ "channel_mac_fuzzer.cc",
+ ]
+ seed_corpus = "$target_gen_dir/mojo_core_channel_mac_corpus"
+ seed_corpus_deps = [ ":mojo_core_channel_mac_fuzzer_convert_corpus" ]
+ deps = [
+ ":core_impl_for_fuzzers",
+ "test:channel_mac_proto",
+ "//base",
+ "//base/test:test_support",
+ "//testing/libfuzzer/fuzzers/mach:converter",
+ "//third_party/libprotobuf-mutator",
+ ]
+ }
+}
+
fuzzer_test("mojo_core_node_channel_fuzzer") {
sources = [
"node_channel_fuzzer.cc",
diff --git a/chromium/mojo/core/channel.cc b/chromium/mojo/core/channel.cc
index c641e66f0c9..7daaaa13d22 100644
--- a/chromium/mojo/core/channel.cc
+++ b/chromium/mojo/core/channel.cc
@@ -19,6 +19,7 @@
#include "build/build_config.h"
#include "mojo/core/configuration.h"
#include "mojo/core/core.h"
+#include "mojo/public/cpp/platform/features.h"
#if defined(OS_MACOSX) && !defined(OS_IOS)
#include "base/mac/mach_logging.h"
@@ -153,8 +154,12 @@ Channel::Message::Message(size_t capacity,
mach_ports_header_->num_ports = 0;
// Initialize all handles to invalid values.
for (size_t i = 0; i < max_handles_; ++i) {
- mach_ports_header_->entries[i] = {0,
- static_cast<uint32_t>(MACH_PORT_NULL)};
+ if (base::FeatureList::IsEnabled(features::kMojoChannelMac)) {
+ mach_ports_header_->entries[i].mach_entry.type = {0};
+ } else {
+ mach_ports_header_->entries[i].posix_entry = {
+ 0, static_cast<uint32_t>(MACH_PORT_NULL)};
+ }
}
#endif
}
@@ -440,36 +445,51 @@ void Channel::Message::SetHandles(
#if defined(OS_MACOSX) && !defined(OS_IOS)
size_t mach_port_index = 0;
+ const bool use_channel_mac =
+ base::FeatureList::IsEnabled(features::kMojoChannelMac);
if (mach_ports_header_) {
for (size_t i = 0; i < max_handles_; ++i) {
- mach_ports_header_->entries[i] = {0,
- static_cast<uint32_t>(MACH_PORT_NULL)};
+ if (use_channel_mac) {
+ mach_ports_header_->entries[i].mach_entry.type = {0};
+ } else {
+ mach_ports_header_->entries[i].posix_entry = {
+ 0, static_cast<uint32_t>(MACH_PORT_NULL)};
+ }
}
for (size_t i = 0; i < handle_vector_.size(); i++) {
- if (!handle_vector_[i].is_mach_port_name() &&
- !handle_vector_[i].handle().is_mach_port()) {
- DCHECK(handle_vector_[i].handle().is_valid_fd());
- continue;
+ if (use_channel_mac) {
+ mach_ports_header_->entries[i].mach_entry.type =
+ static_cast<uint8_t>(handle_vector_[i].handle().type());
+ } else {
+ if (!handle_vector_[i].is_mach_port_name() &&
+ !handle_vector_[i].handle().is_mach_port()) {
+ DCHECK(handle_vector_[i].handle().is_valid_fd());
+ continue;
+ }
+
+ mach_port_t port = handle_vector_[i].is_mach_port_name()
+ ? handle_vector_[i].mach_port_name()
+ : handle_vector_[i].handle().GetMachPort().get();
+ mach_ports_header_->entries[mach_port_index].posix_entry.index = i;
+ mach_ports_header_->entries[mach_port_index].posix_entry.mach_port =
+ port;
+ mach_port_index++;
}
-
- mach_port_t port = handle_vector_[i].is_mach_port_name()
- ? handle_vector_[i].mach_port_name()
- : handle_vector_[i].handle().GetMachPort().get();
- mach_ports_header_->entries[mach_port_index].index = i;
- mach_ports_header_->entries[mach_port_index].mach_port = port;
- mach_port_index++;
}
- mach_ports_header_->num_ports = static_cast<uint16_t>(mach_port_index);
+ mach_ports_header_->num_ports =
+ use_channel_mac ? handle_vector_.size()
+ : static_cast<uint16_t>(mach_port_index);
}
#endif
}
std::vector<PlatformHandleInTransit> Channel::Message::TakeHandles() {
#if defined(OS_MACOSX) && !defined(OS_IOS)
- if (mach_ports_header_) {
+ if (mach_ports_header_ &&
+ !base::FeatureList::IsEnabled(features::kMojoChannelMac)) {
for (size_t i = 0; i < max_handles_; ++i) {
- mach_ports_header_->entries[i] = {0,
- static_cast<uint32_t>(MACH_PORT_NULL)};
+ mach_ports_header_->entries[i].posix_entry = {
+ 0, static_cast<uint32_t>(MACH_PORT_NULL)};
}
mach_ports_header_->num_ports = 0;
}
@@ -484,18 +504,22 @@ Channel::Message::TakeHandlesForTransport() {
NOTREACHED();
return std::vector<PlatformHandleInTransit>();
#elif defined(OS_MACOSX) && !defined(OS_IOS)
- std::vector<PlatformHandleInTransit> non_mach_handles;
- for (auto& handle : handle_vector_) {
- if (handle.is_mach_port_name() || handle.handle().is_mach_port()) {
- // Ownership is effectively transferred to the receiving process
- // out-of-band via MachPortRelay.
- handle.CompleteTransit();
- } else {
- non_mach_handles.emplace_back(std::move(handle));
+ if (base::FeatureList::IsEnabled(features::kMojoChannelMac)) {
+ return std::move(handle_vector_);
+ } else {
+ std::vector<PlatformHandleInTransit> non_mach_handles;
+ for (auto& handle : handle_vector_) {
+ if (handle.is_mach_port_name() || handle.handle().is_mach_port()) {
+ // Ownership is effectively transferred to the receiving process
+ // out-of-band via MachPortRelay.
+ handle.CompleteTransit();
+ } else {
+ non_mach_handles.emplace_back(std::move(handle));
+ }
}
+ handle_vector_.clear();
+ return non_mach_handles;
}
- handle_vector_.clear();
- return non_mach_handles;
#else
return std::move(handle_vector_);
#endif
@@ -622,10 +646,14 @@ class Channel::ReadBuffer {
DISALLOW_COPY_AND_ASSIGN(ReadBuffer);
};
-Channel::Channel(Delegate* delegate, HandlePolicy handle_policy)
+Channel::Channel(Delegate* delegate,
+ HandlePolicy handle_policy,
+ DispatchBufferPolicy buffer_policy)
: delegate_(delegate),
handle_policy_(handle_policy),
- read_buffer_(new ReadBuffer) {}
+ read_buffer_(buffer_policy == DispatchBufferPolicy::kManaged
+ ? new ReadBuffer
+ : nullptr) {}
Channel::~Channel() {}
@@ -645,7 +673,8 @@ char* Channel::GetReadBuffer(size_t* buffer_capacity) {
}
bool Channel::OnReadComplete(size_t bytes_read, size_t* next_read_size_hint) {
- bool did_consume_message = false;
+ DCHECK(read_buffer_);
+ *next_read_size_hint = kReadBufferSize;
read_buffer_->Claim(bytes_read);
while (read_buffer_->num_occupied_bytes() >= sizeof(Message::LegacyHeader)) {
// Ensure the occupied data is properly aligned. If it isn't, a SIGBUS could
@@ -656,98 +685,115 @@ bool Channel::OnReadComplete(size_t bytes_read, size_t* next_read_size_hint) {
read_buffer_->Realign();
}
- // We have at least enough data available for a LegacyHeader.
- const Message::LegacyHeader* legacy_header =
- reinterpret_cast<const Message::LegacyHeader*>(
- read_buffer_->occupied_bytes());
-
- const size_t kMaxMessageSize = GetConfiguration().max_message_num_bytes;
- if (legacy_header->num_bytes < sizeof(Message::LegacyHeader) ||
- legacy_header->num_bytes > kMaxMessageSize) {
- LOG(ERROR) << "Invalid message size: " << legacy_header->num_bytes;
+ DispatchResult result =
+ TryDispatchMessage(base::make_span(read_buffer_->occupied_bytes(),
+ read_buffer_->num_occupied_bytes()),
+ next_read_size_hint);
+ if (result == DispatchResult::kOK) {
+ read_buffer_->Discard(*next_read_size_hint);
+ *next_read_size_hint = 0;
+ } else if (result == DispatchResult::kNotEnoughData) {
+ return true;
+ } else if (result == DispatchResult::kMissingHandles) {
+ break;
+ } else if (result == DispatchResult::kError) {
return false;
}
+ }
+ return true;
+}
- if (read_buffer_->num_occupied_bytes() < legacy_header->num_bytes) {
- // Not enough data available to read the full message. Hint to the
- // implementation that it should try reading the full size of the message.
- *next_read_size_hint =
- legacy_header->num_bytes - read_buffer_->num_occupied_bytes();
- return true;
- }
+Channel::DispatchResult Channel::TryDispatchMessage(
+ base::span<const char> buffer,
+ size_t* size_hint) {
+ bool did_consume_message = false;
- const Message::Header* header = nullptr;
- if (legacy_header->message_type != Message::MessageType::NORMAL_LEGACY) {
- header = reinterpret_cast<const Message::Header*>(legacy_header);
- }
+ // We have at least enough data available for a LegacyHeader.
+ const Message::LegacyHeader* legacy_header =
+ reinterpret_cast<const Message::LegacyHeader*>(buffer.data());
- size_t extra_header_size = 0;
- const void* extra_header = nullptr;
- size_t payload_size = 0;
- void* payload = nullptr;
- if (header) {
- if (header->num_header_bytes < sizeof(Message::Header) ||
- header->num_header_bytes > header->num_bytes) {
- LOG(ERROR) << "Invalid message header size: "
- << header->num_header_bytes;
- return false;
- }
- extra_header_size = header->num_header_bytes - sizeof(Message::Header);
- extra_header = extra_header_size ? header + 1 : nullptr;
- payload_size = header->num_bytes - header->num_header_bytes;
- payload = payload_size
- ? reinterpret_cast<Message::Header*>(
- const_cast<char*>(read_buffer_->occupied_bytes()) +
- header->num_header_bytes)
- : nullptr;
- } else {
- payload_size = legacy_header->num_bytes - sizeof(Message::LegacyHeader);
- payload = payload_size
- ? const_cast<Message::LegacyHeader*>(&legacy_header[1])
- : nullptr;
- }
+ const size_t kMaxMessageSize = GetConfiguration().max_message_num_bytes;
+ if (legacy_header->num_bytes < sizeof(Message::LegacyHeader) ||
+ legacy_header->num_bytes > kMaxMessageSize) {
+ LOG(ERROR) << "Invalid message size: " << legacy_header->num_bytes;
+ return DispatchResult::kError;
+ }
- const uint16_t num_handles =
- header ? header->num_handles : legacy_header->num_handles;
- std::vector<PlatformHandle> handles;
- bool deferred = false;
- if (num_handles > 0) {
- if (handle_policy_ == HandlePolicy::kRejectHandles)
- return false;
-
- if (!GetReadPlatformHandles(payload, payload_size, num_handles,
- extra_header, extra_header_size, &handles,
- &deferred)) {
- return false;
- }
+ if (buffer.size() < legacy_header->num_bytes) {
+ // Not enough data available to read the full message. Hint to the
+ // implementation that it should try reading the full size of the message.
+ *size_hint = legacy_header->num_bytes - buffer.size();
+ return DispatchResult::kNotEnoughData;
+ }
- if (handles.empty()) {
- // Not enough handles available for this message.
- break;
- }
+ const Message::Header* header = nullptr;
+ if (legacy_header->message_type != Message::MessageType::NORMAL_LEGACY) {
+ header = reinterpret_cast<const Message::Header*>(legacy_header);
+ }
+
+ size_t extra_header_size = 0;
+ const void* extra_header = nullptr;
+ size_t payload_size = 0;
+ void* payload = nullptr;
+ if (header) {
+ if (header->num_header_bytes < sizeof(Message::Header) ||
+ header->num_header_bytes > header->num_bytes) {
+ LOG(ERROR) << "Invalid message header size: " << header->num_header_bytes;
+ return DispatchResult::kError;
}
+ extra_header_size = header->num_header_bytes - sizeof(Message::Header);
+ extra_header = extra_header_size ? header + 1 : nullptr;
+ payload_size = header->num_bytes - header->num_header_bytes;
+ payload =
+ payload_size
+ ? reinterpret_cast<Message::Header*>(
+ const_cast<char*>(buffer.data()) + header->num_header_bytes)
+ : nullptr;
+ } else {
+ payload_size = legacy_header->num_bytes - sizeof(Message::LegacyHeader);
+ payload = payload_size
+ ? const_cast<Message::LegacyHeader*>(&legacy_header[1])
+ : nullptr;
+ }
- // We've got a complete message! Dispatch it and try another.
- if (legacy_header->message_type != Message::MessageType::NORMAL_LEGACY &&
- legacy_header->message_type != Message::MessageType::NORMAL) {
- DCHECK(!deferred);
- if (!OnControlMessage(legacy_header->message_type, payload, payload_size,
- std::move(handles))) {
- return false;
- }
- did_consume_message = true;
- } else if (deferred) {
- did_consume_message = true;
- } else if (delegate_) {
- delegate_->OnChannelMessage(payload, payload_size, std::move(handles));
- did_consume_message = true;
+ const uint16_t num_handles =
+ header ? header->num_handles : legacy_header->num_handles;
+ std::vector<PlatformHandle> handles;
+ bool deferred = false;
+ if (num_handles > 0) {
+ if (handle_policy_ == HandlePolicy::kRejectHandles)
+ return DispatchResult::kError;
+
+ if (!GetReadPlatformHandles(payload, payload_size, num_handles,
+ extra_header, extra_header_size, &handles,
+ &deferred)) {
+ return DispatchResult::kError;
}
- read_buffer_->Discard(legacy_header->num_bytes);
+ if (handles.empty()) {
+ // Not enough handles available for this message.
+ return DispatchResult::kMissingHandles;
+ }
}
- *next_read_size_hint = did_consume_message ? 0 : kReadBufferSize;
- return true;
+ // We've got a complete message! Dispatch it and try another.
+ if (legacy_header->message_type != Message::MessageType::NORMAL_LEGACY &&
+ legacy_header->message_type != Message::MessageType::NORMAL) {
+ DCHECK(!deferred);
+ if (!OnControlMessage(legacy_header->message_type, payload, payload_size,
+ std::move(handles))) {
+ return DispatchResult::kError;
+ }
+ did_consume_message = true;
+ } else if (deferred) {
+ did_consume_message = true;
+ } else if (delegate_) {
+ delegate_->OnChannelMessage(payload, payload_size, std::move(handles));
+ did_consume_message = true;
+ }
+
+ *size_hint = legacy_header->num_bytes;
+ return DispatchResult::kOK;
}
void Channel::OnError(Error error) {
diff --git a/chromium/mojo/core/channel.h b/chromium/mojo/core/channel.h
index 9d0f8fd05ae..e06ce1af2b9 100644
--- a/chromium/mojo/core/channel.h
+++ b/chromium/mojo/core/channel.h
@@ -42,6 +42,17 @@ class MOJO_SYSTEM_IMPL_EXPORT Channel
// platform handle attachments and treat them as malformed messages.
kRejectHandles,
};
+ enum class DispatchBufferPolicy {
+ // If the Channel is constructed in this mode, it will create and manage a
+ // buffer that implementations should manipulate with GetReadBuffer() and
+ // OnReadComplete().
+ kManaged,
+
+ // If the Channel is constructed in this mode, it will not create and
+ // manage a buffer for the implementation. Instead, the implementation must
+ // use its own buffer and pass spans of it to TryDispatchMessage().
+ kUnmanaged,
+ };
struct Message;
@@ -100,12 +111,22 @@ class MOJO_SYSTEM_IMPL_EXPORT Channel
};
#if defined(OS_MACOSX) && !defined(OS_IOS)
- struct MachPortsEntry {
- // Index of Mach port in the original vector of PlatformHandleInTransits.
- uint16_t index;
-
- // Mach port name.
- uint32_t mach_port;
+ union MachPortsEntry {
+ // Used with ChannelPosix.
+ struct {
+ // Index of Mach port in the original vector of
+ // PlatformHandleInTransits.
+ uint16_t index;
+
+ // Mach port name.
+ uint32_t mach_port;
+ } posix_entry;
+
+ // Used with ChannelMac.
+ struct {
+ // The PlatformHandle::Type.
+ uint8_t type;
+ } mach_entry;
static_assert(sizeof(mach_port_t) <= sizeof(uint32_t),
"mach_port_t must be no larger than uint32_t");
};
@@ -312,7 +333,12 @@ class MOJO_SYSTEM_IMPL_EXPORT Channel
virtual void LeakHandle() = 0;
protected:
- Channel(Delegate* delegate, HandlePolicy handle_policy);
+ // Constructor for implementations to call. |delegate| and |handle_policy|
+ // should be passed from Create(). |buffer_policy| should be specified by
+ // the implementation.
+ Channel(Delegate* delegate,
+ HandlePolicy handle_policy,
+ DispatchBufferPolicy buffer_policy = DispatchBufferPolicy::kManaged);
virtual ~Channel();
Delegate* delegate() const { return delegate_; }
@@ -323,14 +349,38 @@ class MOJO_SYSTEM_IMPL_EXPORT Channel
//
// Returns the address of a buffer which can be written to, and indicates its
// actual capacity in |*buffer_capacity|.
+ //
+ // This should only be used with DispatchBufferPolicy::kManaged.
char* GetReadBuffer(size_t* buffer_capacity);
// Called by the implementation when new data is available in the read
// buffer. Returns false to indicate an error. Upon success,
// |*next_read_size_hint| will be set to a recommended size for the next
- // read done by the implementation.
+ // read done by the implementation. This should only be used with
+ // DispatchBufferPolicy::kManaged.
bool OnReadComplete(size_t bytes_read, size_t* next_read_size_hint);
+ // Called by the implementation to deserialize a message stored in |buffer|.
+ // If the channel was created with DispatchBufferPolicy::kUnmanaged, the
+ // implementation should call this directly. If it was created with kManaged,
+ // OnReadComplete() will call this. |*size_hint| will be set to a recommended
+ // size for the next read done by the implementation.
+ enum class DispatchResult {
+ // The message was dispatched and consumed. |size_hint| contains the size
+ // of the message.
+ kOK,
+ // The message could not be deserialized because |buffer| does not contain
+ // enough data. |size_hint| contains the amount of data missing.
+ kNotEnoughData,
+ // The message has associated handles that were not transferred in this
+ // message.
+ kMissingHandles,
+ // An error occurred during processing.
+ kError,
+ };
+ DispatchResult TryDispatchMessage(base::span<const char> buffer,
+ size_t* size_hint);
+
// Called by the implementation when something goes horribly wrong. It is NOT
// OK to call this synchronously from any public interface methods.
void OnError(Error error);
diff --git a/chromium/mojo/core/channel_fuchsia.cc b/chromium/mojo/core/channel_fuchsia.cc
index eb30cb9fef9..e603731744d 100644
--- a/chromium/mojo/core/channel_fuchsia.cc
+++ b/chromium/mojo/core/channel_fuchsia.cc
@@ -300,8 +300,8 @@ class ChannelFuchsia : public Channel,
zx_handle_t handles[ZX_CHANNEL_MAX_MSG_HANDLES] = {};
zx_status_t read_result =
- handle_.read(0, buffer, buffer_capacity, &bytes_read, handles,
- base::size(handles), &handles_read);
+ handle_.rea2(0, buffer, handles, buffer_capacity, base::size(handles),
+ &bytes_read, &handles_read);
if (read_result == ZX_OK) {
for (size_t i = 0; i < handles_read; ++i) {
incoming_handles_.emplace_back(handles[i]);
diff --git a/chromium/mojo/core/channel_mac.cc b/chromium/mojo/core/channel_mac.cc
new file mode 100644
index 00000000000..8820afe0a0c
--- /dev/null
+++ b/chromium/mojo/core/channel_mac.cc
@@ -0,0 +1,718 @@
+// 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/core/channel.h"
+
+#include <mach/mach.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <algorithm>
+#include <memory>
+#include <utility>
+#include <vector>
+
+#include "base/bind.h"
+#include "base/containers/buffer_iterator.h"
+#include "base/containers/circular_deque.h"
+#include "base/containers/span.h"
+#include "base/logging.h"
+#include "base/mac/mach_logging.h"
+#include "base/mac/scoped_mach_msg_destroy.h"
+#include "base/mac/scoped_mach_port.h"
+#include "base/mac/scoped_mach_vm.h"
+#include "base/message_loop/message_loop_current.h"
+#include "base/message_loop/message_pump_for_io.h"
+#include "base/strings/stringprintf.h"
+
+extern "C" {
+kern_return_t fileport_makeport(int fd, mach_port_t*);
+int fileport_makefd(mach_port_t);
+} // extern "C"
+
+namespace mojo {
+namespace core {
+
+namespace {
+
+constexpr mach_msg_id_t kChannelMacHandshakeMsgId = 'mjhs';
+constexpr mach_msg_id_t kChannelMacInlineMsgId = 'MOJO';
+constexpr mach_msg_id_t kChannelMacOOLMsgId = 'MOJ+';
+
+class ChannelMac : public Channel,
+ public base::MessageLoopCurrent::DestructionObserver,
+ public base::MessagePumpKqueue::MachPortWatcher {
+ public:
+ ChannelMac(Delegate* delegate,
+ ConnectionParams connection_params,
+ HandlePolicy handle_policy,
+ scoped_refptr<base::TaskRunner> io_task_runner)
+ : Channel(delegate, handle_policy, DispatchBufferPolicy::kUnmanaged),
+ self_(this),
+ io_task_runner_(io_task_runner),
+ watch_controller_(FROM_HERE) {
+ PlatformHandle channel_handle;
+ if (connection_params.server_endpoint().is_valid()) {
+ channel_handle =
+ connection_params.TakeServerEndpoint().TakePlatformHandle();
+ } else {
+ channel_handle = connection_params.TakeEndpoint().TakePlatformHandle();
+ }
+
+ if (channel_handle.is_mach_send()) {
+ send_port_ = channel_handle.TakeMachSendRight();
+ } else if (channel_handle.is_mach_receive()) {
+ receive_port_ = channel_handle.TakeMachReceiveRight();
+ } else {
+ NOTREACHED();
+ }
+ }
+
+ void Start() override {
+ io_task_runner_->PostTask(
+ FROM_HERE, base::BindOnce(&ChannelMac::StartOnIOThread, this));
+ }
+
+ void ShutDownImpl() override {
+ io_task_runner_->PostTask(
+ FROM_HERE, base::BindOnce(&ChannelMac::ShutDownOnIOThread, this));
+ }
+
+ void Write(MessagePtr message) override {
+ base::AutoLock lock(write_lock_);
+
+ if (reject_writes_) {
+ return;
+ }
+
+ // If the channel is not fully established, queue pending messages.
+ if (!handshake_done_) {
+ pending_messages_.push_back(std::move(message));
+ return;
+ }
+
+ // If messages are being queued, enqueue |message| and try to flush
+ // the queue.
+ if (send_buffer_contains_message_ || !pending_messages_.empty()) {
+ pending_messages_.push_back(std::move(message));
+ SendPendingMessagesLocked();
+ return;
+ }
+
+ SendMessageLocked(std::move(message));
+ }
+
+ void LeakHandle() override {
+ DCHECK(io_task_runner_->RunsTasksInCurrentSequence());
+ leak_handles_ = true;
+ }
+
+ bool GetReadPlatformHandles(const void* payload,
+ size_t payload_size,
+ size_t num_handles,
+ const void* extra_header,
+ size_t extra_header_size,
+ std::vector<PlatformHandle>* handles,
+ bool* deferred) override {
+ // Validate the incoming handles. If validation fails, ensure they are
+ // destroyed.
+ std::vector<PlatformHandle> incoming_handles;
+ std::swap(incoming_handles, incoming_handles_);
+
+ if (extra_header_size <
+ sizeof(Message::MachPortsExtraHeader) +
+ (incoming_handles.size() * sizeof(Message::MachPortsEntry))) {
+ return false;
+ }
+
+ const auto* mach_ports_header =
+ reinterpret_cast<const Message::MachPortsExtraHeader*>(extra_header);
+ if (mach_ports_header->num_ports != incoming_handles.size()) {
+ return false;
+ }
+
+ for (uint16_t i = 0; i < mach_ports_header->num_ports; ++i) {
+ auto type = static_cast<PlatformHandle::Type>(
+ mach_ports_header->entries[i].mach_entry.type);
+ if (type == PlatformHandle::Type::kNone) {
+ return false;
+ } else if (type == PlatformHandle::Type::kFd &&
+ incoming_handles[i].is_mach_send()) {
+ int fd = fileport_makefd(incoming_handles[i].GetMachSendRight().get());
+ if (fd < 0) {
+ return false;
+ }
+ incoming_handles[i] = PlatformHandle(base::ScopedFD(fd));
+ } else if (type != incoming_handles[i].type()) {
+ return false;
+ }
+ }
+
+ *handles = std::move(incoming_handles);
+ return true;
+ }
+
+ private:
+ ~ChannelMac() override = default;
+
+ void StartOnIOThread() {
+ vm_address_t address = 0;
+ const vm_size_t size = getpagesize();
+ kern_return_t kr =
+ vm_allocate(mach_task_self(), &address, size,
+ VM_MAKE_TAG(VM_MEMORY_MACH_MSG) | VM_FLAGS_ANYWHERE);
+ MACH_CHECK(kr == KERN_SUCCESS, kr) << "vm_allocate";
+ send_buffer_.reset(address, size);
+
+ kr = vm_allocate(mach_task_self(), &address, size,
+ VM_MAKE_TAG(VM_MEMORY_MACH_MSG) | VM_FLAGS_ANYWHERE);
+ MACH_CHECK(kr == KERN_SUCCESS, kr) << "vm_allocate";
+ receive_buffer_.reset(address, size);
+
+ // When a channel is created, it only has one end of communication (either
+ // send or receive). If it was created with a receive port, the first thing
+ // a channel does is receive a special channel-internal message containing
+ // its peer's send right. If the channel was created with a send right, it
+ // creates a new receive right and sends to its peer (using the send right
+ // it was created with) a new send right to the receive right. This
+ // establishes the bidirectional communication channel.
+ if (send_port_ != MACH_PORT_NULL) {
+ DCHECK(receive_port_ == MACH_PORT_NULL);
+ CHECK(base::mac::CreateMachPort(&receive_port_, nullptr,
+ MACH_PORT_QLIMIT_LARGE));
+ if (!RequestSendDeadNameNotification()) {
+ OnError(Error::kConnectionFailed);
+ return;
+ }
+ SendHandshake();
+ } else if (receive_port_ != MACH_PORT_NULL) {
+ DCHECK(send_port_ == MACH_PORT_NULL);
+ // Wait for the received message via the MessageLoop.
+ } else {
+ NOTREACHED();
+ }
+
+ base::MessageLoopCurrent::Get()->AddDestructionObserver(this);
+ base::MessageLoopCurrentForIO::Get()->WatchMachReceivePort(
+ receive_port_.get(), &watch_controller_, this);
+ }
+
+ void ShutDownOnIOThread() {
+ base::MessageLoopCurrent::Get()->RemoveDestructionObserver(this);
+
+ watch_controller_.StopWatchingMachPort();
+
+ send_buffer_.reset();
+ receive_buffer_.reset();
+ incoming_handles_.clear();
+
+ if (leak_handles_) {
+ ignore_result(receive_port_.release());
+ ignore_result(send_port_.release());
+ } else {
+ receive_port_.reset();
+ send_port_.reset();
+ }
+
+ // May destroy the |this| if it was the last reference.
+ self_ = nullptr;
+ }
+
+ // Requests that the kernel notify the |receive_port_| when the receive right
+ // connected to |send_port_| becomes a dead name. This should be called as
+ // soon as the Channel establishes both the send and receive ports.
+ bool RequestSendDeadNameNotification() {
+ base::mac::ScopedMachSendRight previous;
+ kern_return_t kr = mach_port_request_notification(
+ mach_task_self(), send_port_.get(), MACH_NOTIFY_DEAD_NAME, 0,
+ receive_port_.get(), MACH_MSG_TYPE_MAKE_SEND_ONCE,
+ base::mac::ScopedMachSendRight::Receiver(previous).get());
+ if (kr != KERN_SUCCESS) {
+ // If port is already a dead name (i.e. the receiver is already gone),
+ // then the channel should be shut down by the caller.
+ MACH_LOG_IF(ERROR, kr != KERN_INVALID_ARGUMENT, kr)
+ << "mach_port_request_notification";
+ return false;
+ }
+ return true;
+ }
+
+ // SendHandshake() sends to the |receive_port_| a right to |send_port_|,
+ // establishing bi-directional communication with the peer. After the
+ // handshake message has been sent, this Channel can queue any pending
+ // messages for its peer.
+ void SendHandshake() {
+ mach_msg_header_t message{};
+ message.msgh_bits =
+ MACH_MSGH_BITS(MACH_MSG_TYPE_COPY_SEND, MACH_MSG_TYPE_MAKE_SEND);
+ message.msgh_size = sizeof(message);
+ message.msgh_remote_port = send_port_.get();
+ message.msgh_local_port = receive_port_.get();
+ message.msgh_id = kChannelMacHandshakeMsgId;
+ kern_return_t kr =
+ mach_msg(&message, MACH_SEND_MSG, sizeof(message), 0, MACH_PORT_NULL,
+ MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL);
+ if (kr != KERN_SUCCESS) {
+ MACH_LOG(ERROR, kr) << "mach_msg send handshake";
+
+ base::AutoLock lock(write_lock_);
+ OnWriteErrorLocked(Error::kConnectionFailed);
+ return;
+ }
+
+ base::AutoLock lock(write_lock_);
+ handshake_done_ = true;
+ SendPendingMessagesLocked();
+ }
+
+ // Acquires the peer's send right from the handshake message sent via
+ // SendHandshake(). After this, bi-directional communication is established
+ // and this Channel can send to its peer any pending messages.
+ bool ReceiveHandshake(base::BufferIterator<const char> buffer) {
+ if (handshake_done_) {
+ OnError(Error::kReceivedMalformedData);
+ return false;
+ }
+
+ DCHECK(send_port_ == MACH_PORT_NULL);
+
+ auto* message = buffer.Object<mach_msg_header_t>();
+ if (message->msgh_id != kChannelMacHandshakeMsgId ||
+ message->msgh_local_port == MACH_PORT_NULL) {
+ OnError(Error::kConnectionFailed);
+ return false;
+ }
+
+ // Record the audit token of the sender. All messages received by the
+ // channel must be from this same sender.
+ auto* trailer = buffer.Object<mach_msg_audit_trailer_t>();
+ peer_audit_token_.reset(new audit_token_t);
+ memcpy(peer_audit_token_.get(), &trailer->msgh_audit,
+ sizeof(audit_token_t));
+
+ send_port_ = base::mac::ScopedMachSendRight(message->msgh_remote_port);
+
+ if (!RequestSendDeadNameNotification()) {
+ OnError(Error::kConnectionFailed);
+ return false;
+ }
+
+ base::AutoLock lock(write_lock_);
+ handshake_done_ = true;
+ SendPendingMessagesLocked();
+
+ return true;
+ }
+
+ void SendPendingMessages() {
+ base::AutoLock lock(write_lock_);
+ SendPendingMessagesLocked();
+ }
+
+ void SendPendingMessagesLocked() {
+ // If a previous send failed due to the receiver's kernel message queue
+ // being full, attempt to send that failed message first.
+ if (send_buffer_contains_message_ && !reject_writes_) {
+ auto* header =
+ reinterpret_cast<mach_msg_header_t*>(send_buffer_.address());
+ if (!MachMessageSendLocked(header)) {
+ // The send failed again. If the peer is still unable to receive,
+ // MachMessageSendLocked() will have arranged another attempt. If an
+ // error occurred, the channel will be shut down.
+ return;
+ }
+ }
+
+ // Try and send any other pending messages that were queued.
+ while (!pending_messages_.empty() && !reject_writes_) {
+ bool did_send = SendMessageLocked(std::move(pending_messages_.front()));
+ // If the message failed to send because the kernel message queue is
+ // full, the message will have been fully serialized and
+ // |send_buffer_contains_message_| will be set to true. The Mojo message
+ // object can be destroyed at this point.
+ pending_messages_.pop_front();
+ if (!did_send)
+ break;
+ }
+ }
+
+ bool SendMessageLocked(MessagePtr message) {
+ DCHECK(!send_buffer_contains_message_);
+ base::BufferIterator<char> buffer(
+ reinterpret_cast<char*>(send_buffer_.address()), send_buffer_.size());
+
+ auto* header = buffer.MutableObject<mach_msg_header_t>();
+ *header = mach_msg_header_t{};
+
+ // Compute the total size of the message. If the message data are larger
+ // than the allocated receive buffer, the data will be transferred out-of-
+ // line. The receive buffer is the same size as the send buffer, but there
+ // also needs to be room to receive the trailer.
+ const size_t mach_header_size =
+ sizeof(mach_msg_header_t) + sizeof(mach_msg_body_t) +
+ (message->num_handles() * sizeof(mach_msg_port_descriptor_t));
+ const size_t expected_message_size =
+ round_msg(mach_header_size + message->data_num_bytes() +
+ sizeof(mach_msg_audit_trailer_t));
+ const bool transfer_message_ool =
+ expected_message_size >= send_buffer_.size();
+
+ const bool is_complex = message->has_handles() || transfer_message_ool;
+
+ header->msgh_bits = MACH_MSGH_BITS_REMOTE(MACH_MSG_TYPE_COPY_SEND) |
+ (is_complex ? MACH_MSGH_BITS_COMPLEX : 0);
+ header->msgh_remote_port = send_port_.get();
+ header->msgh_id =
+ transfer_message_ool ? kChannelMacOOLMsgId : kChannelMacInlineMsgId;
+
+ auto* body = buffer.MutableObject<mach_msg_body_t>();
+ body->msgh_descriptor_count = message->num_handles();
+
+ std::vector<PlatformHandleInTransit> handles = message->TakeHandles();
+ auto descriptors =
+ buffer.MutableSpan<mach_msg_port_descriptor_t>(handles.size());
+ for (size_t i = 0; i < message->num_handles(); ++i) {
+ auto* descriptor = &descriptors[i];
+ descriptor->pad1 = 0;
+ descriptor->pad2 = 0;
+ descriptor->type = MACH_MSG_PORT_DESCRIPTOR;
+
+ PlatformHandle handle = handles[i].TakeHandle();
+
+ switch (handle.type()) {
+ case PlatformHandle::Type::kMachSend:
+ descriptor->name = handle.ReleaseMachSendRight();
+ descriptor->disposition = MACH_MSG_TYPE_MOVE_SEND;
+ break;
+ case PlatformHandle::Type::kMachReceive:
+ descriptor->name = handle.ReleaseMachReceiveRight();
+ descriptor->disposition = MACH_MSG_TYPE_MOVE_RECEIVE;
+ break;
+ case PlatformHandle::Type::kFd: {
+ // After putting the FD in a fileport, the kernel will keep a
+ // reference to the opened file, and the local descriptor can be
+ // closed.
+ kern_return_t kr =
+ fileport_makeport(handle.GetFD().get(), &descriptor->name);
+ if (kr != KERN_SUCCESS) {
+ MACH_LOG(ERROR, kr) << "fileport_makeport";
+ OnWriteErrorLocked(Error::kDisconnected);
+ return false;
+ }
+ descriptor->disposition = MACH_MSG_TYPE_MOVE_SEND;
+ break;
+ }
+ default:
+ NOTREACHED() << "Unsupported handle type "
+ << static_cast<int>(handle.type());
+ OnWriteErrorLocked(Error::kDisconnected);
+ }
+ }
+
+ if (transfer_message_ool) {
+ auto* descriptor = buffer.MutableObject<mach_msg_ool_descriptor_t>();
+ descriptor->address = const_cast<void*>(message->data());
+ descriptor->size = message->data_num_bytes();
+ descriptor->copy = MACH_MSG_VIRTUAL_COPY;
+ descriptor->deallocate = false;
+ descriptor->pad1 = 0;
+ descriptor->type = MACH_MSG_OOL_DESCRIPTOR;
+ ++body->msgh_descriptor_count;
+ } else {
+ auto* data_size = buffer.MutableObject<uint64_t>();
+ *data_size = message->data_num_bytes();
+
+ auto data = buffer.MutableSpan<char>(message->data_num_bytes());
+ memcpy(data.data(), message->data(), message->data_num_bytes());
+ }
+
+ header->msgh_size = round_msg(buffer.position());
+ return MachMessageSendLocked(header);
+ }
+
+ bool MachMessageSendLocked(mach_msg_header_t* header) {
+ kern_return_t kr = mach_msg(header, MACH_SEND_MSG | MACH_SEND_TIMEOUT,
+ header->msgh_size, 0, MACH_PORT_NULL,
+ /*timeout=*/0, MACH_PORT_NULL);
+ if (kr != KERN_SUCCESS) {
+ if (kr == MACH_SEND_TIMED_OUT) {
+ // The kernel message queue for the peer's receive port is full, so the
+ // send timed out. Since the send buffer contains a fully serialized
+ // message, set a flag to indicate this condition and arrange to try
+ // sending it again.
+ send_buffer_contains_message_ = true;
+ io_task_runner_->PostTask(
+ FROM_HERE, base::BindOnce(&ChannelMac::SendPendingMessages, this));
+ } else {
+ // If the message failed to send for other reasons, destroy it and
+ // close the channel.
+ MACH_LOG_IF(ERROR, kr != MACH_SEND_INVALID_DEST, kr) << "mach_msg send";
+ send_buffer_contains_message_ = false;
+ mach_msg_destroy(header);
+ OnWriteErrorLocked(Error::kDisconnected);
+ }
+ return false;
+ }
+
+ send_buffer_contains_message_ = false;
+ return true;
+ }
+
+ // base::MessageLoopCurrent::DestructionObserver:
+ void WillDestroyCurrentMessageLoop() override {
+ DCHECK(io_task_runner_->RunsTasksInCurrentSequence());
+ if (self_)
+ ShutDownOnIOThread();
+ }
+
+ // base::MessagePumpKqueue::MachPortWatcher:
+ void OnMachMessageReceived(mach_port_t port) override {
+ DCHECK(io_task_runner_->RunsTasksInCurrentSequence());
+
+ base::BufferIterator<const char> buffer(
+ reinterpret_cast<const char*>(receive_buffer_.address()),
+ receive_buffer_.size());
+ auto* header = buffer.MutableObject<mach_msg_header_t>();
+ *header = mach_msg_header_t{};
+ header->msgh_size = buffer.total_size();
+ header->msgh_local_port = receive_port_.get();
+
+ const mach_msg_option_t rcv_options =
+ MACH_RCV_MSG | MACH_RCV_TIMEOUT |
+ MACH_RCV_TRAILER_TYPE(MACH_MSG_TRAILER_FORMAT_0) |
+ MACH_RCV_TRAILER_ELEMENTS(MACH_RCV_TRAILER_AUDIT);
+ kern_return_t kr =
+ mach_msg(header, rcv_options, 0, header->msgh_size, receive_port_.get(),
+ /*timeout=*/0, MACH_PORT_NULL);
+ if (kr != KERN_SUCCESS) {
+ if (kr == MACH_RCV_TIMED_OUT)
+ return;
+ MACH_LOG(ERROR, kr) << "mach_msg receive";
+ OnError(Error::kDisconnected);
+ return;
+ }
+
+ base::ScopedMachMsgDestroy scoped_message(header);
+
+ if (header->msgh_id == kChannelMacHandshakeMsgId) {
+ buffer.Seek(0);
+ if (ReceiveHandshake(buffer))
+ scoped_message.Disarm();
+ return;
+ }
+
+ if (header->msgh_id == MACH_NOTIFY_DEAD_NAME) {
+ // The DEAD_NAME notification contains a port right that must be
+ // explicitly destroyed, as it is not carried in a descriptor.
+ buffer.Seek(0);
+ auto* notification = buffer.Object<mach_dead_name_notification_t>();
+
+ // Verify that the kernel sent the notification.
+ buffer.Seek(notification->not_header.msgh_size);
+ auto* trailer = buffer.Object<mach_msg_audit_trailer_t>();
+ static const audit_token_t kernel_audit_token = KERNEL_AUDIT_TOKEN_VALUE;
+ if (memcmp(&trailer->msgh_audit, &kernel_audit_token,
+ sizeof(audit_token_t)) == 0) {
+ DCHECK(notification->not_port == send_port_);
+ // Release the notification's send right using this scoper.
+ base::mac::ScopedMachSendRight notify_port(notification->not_port);
+ }
+ OnError(Error::kDisconnected);
+ return;
+ } else if (header->msgh_id == MACH_NOTIFY_SEND_ONCE) {
+ // Notification of an extant send-once right being destroyed. This is
+ // sent for the right allocated in RequestSendDeadNameNotification(),
+ // and no action needs to be taken. Since it is ignored, the kernel
+ // audit token need not be checked.
+ return;
+ }
+
+ if (header->msgh_size < sizeof(mach_msg_base_t)) {
+ OnError(Error::kReceivedMalformedData);
+ return;
+ }
+
+ if (peer_audit_token_) {
+ buffer.Seek(header->msgh_size);
+ auto* trailer = buffer.Object<mach_msg_audit_trailer_t>();
+ if (memcmp(&trailer->msgh_audit, peer_audit_token_.get(),
+ sizeof(audit_token_t)) != 0) {
+ // Do not shut down the channel because this endpoint could be
+ // accessible via the bootstrap server, which means anyone could send
+ // messages to it.
+ LOG(ERROR) << "Rejecting message from unauthorized peer";
+ return;
+ }
+ buffer.Seek(sizeof(*header));
+ }
+
+ auto* body = buffer.Object<mach_msg_body_t>();
+ if (((header->msgh_bits & MACH_MSGH_BITS_COMPLEX) != 0) !=
+ (body->msgh_descriptor_count > 0)) {
+ LOG(ERROR) << "Message complex bit does not match descriptor count";
+ OnError(Error::kReceivedMalformedData);
+ return;
+ }
+
+ bool transfer_message_ool = false;
+ mach_msg_size_t mojo_handle_count = body->msgh_descriptor_count;
+ if (header->msgh_id == kChannelMacOOLMsgId) {
+ transfer_message_ool = true;
+ // The number of Mojo handles to process will be one fewer, since the
+ // message itself was transferred using OOL memory.
+ if (body->msgh_descriptor_count < 1) {
+ LOG(ERROR) << "OOL message does not have descriptor";
+ OnError(Error::kReceivedMalformedData);
+ return;
+ }
+ --mojo_handle_count;
+ } else if (header->msgh_id != kChannelMacInlineMsgId) {
+ OnError(Error::kReceivedMalformedData);
+ return;
+ }
+
+ incoming_handles_.clear();
+ incoming_handles_.reserve(mojo_handle_count);
+
+ // Accept the descriptors into |incoming_handles_|. They will be validated
+ // in GetReadPlatformHandles(). If the handle is accepted, the name in the
+ // descriptor is cleared, so that it is not double-unrefed if the
+ // |scoped_message| destroys the message on error.
+ auto descriptors =
+ buffer.MutableSpan<mach_msg_port_descriptor_t>(mojo_handle_count);
+ for (auto& descriptor : descriptors) {
+ if (descriptor.type != MACH_MSG_PORT_DESCRIPTOR) {
+ LOG(ERROR) << "Incorrect descriptor type " << descriptor.type;
+ OnError(Error::kReceivedMalformedData);
+ return;
+ }
+ switch (descriptor.disposition) {
+ case MACH_MSG_TYPE_MOVE_SEND:
+ incoming_handles_.emplace_back(
+ base::mac::ScopedMachSendRight(descriptor.name));
+ descriptor.name = MACH_PORT_NULL;
+ break;
+ case MACH_MSG_TYPE_MOVE_RECEIVE:
+ incoming_handles_.emplace_back(
+ base::mac::ScopedMachReceiveRight(descriptor.name));
+ descriptor.name = MACH_PORT_NULL;
+ break;
+ default:
+ DLOG(ERROR) << "Unhandled descriptor disposition "
+ << descriptor.disposition;
+ OnError(Error::kReceivedMalformedData);
+ return;
+ }
+ }
+
+ base::span<const char> payload;
+ base::mac::ScopedMachVM ool_memory;
+ if (transfer_message_ool) {
+ auto* descriptor = buffer.Object<mach_msg_ool_descriptor_t>();
+ if (descriptor->type != MACH_MSG_OOL_DESCRIPTOR) {
+ LOG(ERROR) << "Incorrect descriptor type " << descriptor->type;
+ OnError(Error::kReceivedMalformedData);
+ return;
+ }
+
+ payload = base::span<const char>(
+ reinterpret_cast<const char*>(descriptor->address), descriptor->size);
+ // The kernel page-aligns the OOL memory when performing the mach_msg on
+ // the send side, but it preserves the original size in the descriptor.
+ ool_memory.reset_unaligned(
+ reinterpret_cast<vm_address_t>(descriptor->address),
+ descriptor->size);
+ } else {
+ auto* data_size_ptr = buffer.Object<uint64_t>();
+ payload = buffer.Span<const char>(*data_size_ptr);
+ }
+
+ if (payload.empty()) {
+ OnError(Error::kReceivedMalformedData);
+ return;
+ }
+
+ scoped_message.Disarm();
+
+ size_t ignored;
+ DispatchResult result = TryDispatchMessage(payload, &ignored);
+ if (result != DispatchResult::kOK) {
+ OnError(Error::kReceivedMalformedData);
+ return;
+ }
+ }
+
+ // Marks the channel as unaccepting of new messages and shuts it down.
+ void OnWriteErrorLocked(Error error) {
+ reject_writes_ = true;
+ io_task_runner_->PostTask(
+ FROM_HERE, base::BindOnce(&ChannelMac::OnError, this, error));
+ }
+
+ // Keeps the Channel alive at least until explicit shutdown on the IO thread.
+ scoped_refptr<ChannelMac> self_;
+
+ scoped_refptr<base::TaskRunner> io_task_runner_;
+
+ base::mac::ScopedMachReceiveRight receive_port_;
+ base::mac::ScopedMachSendRight send_port_;
+
+ // Whether to leak the above Mach ports when the channel is shut down.
+ bool leak_handles_ = false;
+
+ // Whether or not the channel-internal handshake, which establishes bi-
+ // directional communication, is complete. If false, calls to Write() will
+ // enqueue messages on |pending_messages_|.
+ bool handshake_done_ = false;
+
+ // If the channel was created with a receive right, the first message it
+ // receives is the internal handshake. The audit token of the sender of the
+ // handshake is recorded here, and all future messages are required to be
+ // from that sender.
+ std::unique_ptr<audit_token_t> peer_audit_token_;
+
+ // IO buffer for receiving Mach messages. Only accessed on |io_task_runner_|.
+ base::mac::ScopedMachVM receive_buffer_;
+
+ // Handles that were received with a message that are validated and returned
+ // in GetReadPlatformHandles(). Only accessed on |io_task_runner_|.
+ std::vector<PlatformHandle> incoming_handles_;
+
+ // Watch controller for |receive_port_|, calls OnMachMessageReceived() when
+ // new messages are available.
+ base::MessagePumpForIO::MachPortWatchController watch_controller_;
+
+ // Lock that protects the following members.
+ base::Lock write_lock_;
+ // Whether writes should be rejected due to an internal error.
+ bool reject_writes_ = false;
+ // IO buffer for sending Mach messages.
+ base::mac::ScopedMachVM send_buffer_;
+ // If a message timed out during send in MachMessageSendLocked(), this will
+ // be true to indicate that |send_buffer_| contains a message that must
+ // be sent. If this is true, then other calls to Write() queue messages onto
+ // |pending_messages_|.
+ bool send_buffer_contains_message_ = false;
+ // When |handshake_done_| is false or |send_buffer_contains_message_| is true,
+ // calls to Write() will enqueue messages here.
+ base::circular_deque<MessagePtr> pending_messages_;
+
+ DISALLOW_COPY_AND_ASSIGN(ChannelMac);
+};
+
+} // namespace
+
+// TODO(crbug.com/932175): This will be renamed Channel::Create.
+MOJO_SYSTEM_IMPL_EXPORT
+scoped_refptr<Channel> ChannelMacCreate(
+ Channel::Delegate* delegate,
+ ConnectionParams connection_params,
+ Channel::HandlePolicy handle_policy,
+ scoped_refptr<base::TaskRunner> io_task_runner) {
+ return new ChannelMac(delegate, std::move(connection_params), handle_policy,
+ io_task_runner);
+}
+
+} // namespace core
+} // namespace mojo
diff --git a/chromium/mojo/core/channel_mac_fuzzer.cc b/chromium/mojo/core/channel_mac_fuzzer.cc
new file mode 100644
index 00000000000..e45e6bbe5c2
--- /dev/null
+++ b/chromium/mojo/core/channel_mac_fuzzer.cc
@@ -0,0 +1,136 @@
+// 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 <list>
+
+#include "base/logging.h"
+#include "base/mac/mach_logging.h"
+#include "base/message_loop/message_loop.h"
+#include "base/run_loop.h"
+#include "base/test/scoped_feature_list.h"
+#include "mojo/core/channel.h"
+#include "mojo/core/entrypoints.h"
+#include "mojo/core/test/data/channel_mac/channel_mac.pb.h"
+#include "mojo/public/cpp/platform/features.h"
+#include "mojo/public/cpp/platform/platform_channel.h"
+#include "testing/libfuzzer/fuzzers/mach/mach_message_converter.h"
+#include "testing/libfuzzer/proto/lpm_interface.h"
+
+namespace {
+
+class ChannelMacFuzzer {
+ public:
+ ChannelMacFuzzer() {
+ feature_list_.InitAndEnableFeature(mojo::features::kMojoChannelMac);
+
+ mojo::core::InitializeCore();
+
+ logging::SetMinLogLevel(logging::LOG_FATAL);
+ }
+
+ scoped_refptr<base::TaskRunner> io_task_runner() {
+ return message_loop_.task_runner();
+ }
+
+ private:
+ base::test::ScopedFeatureList feature_list_;
+ base::MessageLoopForIO message_loop_;
+};
+
+class FakeChannelDelegate : public mojo::core::Channel::Delegate {
+ public:
+ FakeChannelDelegate() = default;
+ ~FakeChannelDelegate() override = default;
+
+ void OnChannelMessage(const void* payload,
+ size_t payload_size,
+ std::vector<mojo::PlatformHandle> handles) override {}
+ void OnChannelError(mojo::core::Channel::Error error) override {}
+};
+
+} // namespace
+
+DEFINE_BINARY_PROTO_FUZZER(mojo_fuzzer::ChannelMac proto) {
+ static ChannelMacFuzzer environment;
+
+ mojo::PlatformChannel platform_channel;
+ mojo::PlatformChannelEndpoint fuzzed_endpoint;
+ mojo::PlatformChannelEndpoint other_endpoint;
+
+ mach_port_t send_port = platform_channel.local_endpoint()
+ .platform_handle()
+ .GetMachSendRight()
+ .get();
+
+ if (proto.endpoint_type() == mojo_fuzzer::ChannelMac_EndpointType_LOCAL) {
+ fuzzed_endpoint = platform_channel.TakeLocalEndpoint();
+ other_endpoint = platform_channel.TakeRemoteEndpoint();
+ } else if (proto.endpoint_type() ==
+ mojo_fuzzer::ChannelMac_EndpointType_REMOTE) {
+ fuzzed_endpoint = platform_channel.TakeRemoteEndpoint();
+ other_endpoint = platform_channel.TakeLocalEndpoint();
+ }
+
+ FakeChannelDelegate delegate;
+
+ auto channel = mojo::core::Channel::Create(
+ &delegate, mojo::core::ConnectionParams(std::move(fuzzed_endpoint)),
+ mojo::core::Channel::HandlePolicy::kAcceptHandles,
+ environment.io_task_runner());
+ channel->Start();
+
+ // If the handshake is not being fuzzed, establish a peer Channel that will
+ // put |channel| into a good state by performing the handshake.
+ scoped_refptr<mojo::core::Channel> peer_channel;
+ if (!proto.fuzz_handshake()) {
+ peer_channel = mojo::core::Channel::Create(
+ &delegate, mojo::core::ConnectionParams(std::move(other_endpoint)),
+ mojo::core::Channel::HandlePolicy::kAcceptHandles,
+ environment.io_task_runner());
+ peer_channel->Start();
+ }
+
+ base::RunLoop().RunUntilIdle();
+
+ // Save off any ports that were sent as part of a message until after the
+ // channel has been shut down.
+ std::list<mach_fuzzer::SendablePort> ports_to_destroy;
+
+ for (auto& message : *proto.mutable_messages()) {
+ if (message.HasExtension(mojo_fuzzer::MojoMessage::mojo_message)) {
+ // Mojo message data for inline Mach messages is
+ // [data_length_uint64][data_bytes].
+ const auto& mojo_message =
+ message.GetExtension(mojo_fuzzer::MojoMessage::mojo_message);
+
+ // If the fuzz data do not specify an explicit length, just use the byte
+ // length.
+ uint64_t data_length = mojo_message.has_data_length()
+ ? mojo_message.data_length()
+ : mojo_message.data().size();
+ std::string data;
+ data.append(reinterpret_cast<const char*>(&data_length),
+ sizeof(data_length));
+ data.append(mojo_message.data().begin(), mojo_message.data().end());
+ message.set_data(data);
+ }
+
+ mach_fuzzer::SendResult result = SendMessage(send_port, message);
+
+ std::move(result.message.ports.begin(), result.message.ports.end(),
+ std::back_inserter(ports_to_destroy));
+ }
+
+ base::RunLoop().RunUntilIdle();
+
+ channel->ShutDown();
+ channel.reset();
+
+ if (peer_channel) {
+ peer_channel->ShutDown();
+ peer_channel.reset();
+ }
+
+ base::RunLoop().RunUntilIdle();
+}
diff --git a/chromium/mojo/core/channel_posix.cc b/chromium/mojo/core/channel_posix.cc
index 2ef2a5fcfe3..eed78a3c7f4 100644
--- a/chromium/mojo/core/channel_posix.cc
+++ b/chromium/mojo/core/channel_posix.cc
@@ -22,6 +22,7 @@
#include "base/task_runner.h"
#include "build/build_config.h"
#include "mojo/core/core.h"
+#include "mojo/public/cpp/platform/features.h"
#include "mojo/public/cpp/platform/socket_utils_posix.h"
#if !defined(OS_NACL)
@@ -53,12 +54,7 @@ class MessageView {
MessageView(MessageView&& other) { *this = std::move(other); }
- MessageView& operator=(MessageView&& other) {
- message_ = std::move(other.message_);
- offset_ = other.offset_;
- handles_ = std::move(other.handles_);
- return *this;
- }
+ MessageView& operator=(MessageView&& other) = default;
~MessageView() {}
@@ -232,9 +228,9 @@ class ChannelPosix : public Channel,
const bool extract_send_rights = remote_process().is_valid();
for (size_t i = 0, mach_port_index = 0; i < num_handles; ++i) {
if (mach_port_index < num_mach_ports &&
- mach_ports[mach_port_index].index == i) {
- mach_port_t port_name =
- static_cast<mach_port_t>(mach_ports[mach_port_index].mach_port);
+ mach_ports[mach_port_index].posix_entry.index == i) {
+ mach_port_t port_name = static_cast<mach_port_t>(
+ mach_ports[mach_port_index].posix_entry.mach_port);
if (extract_send_rights) {
handles_in_transit[i] =
PlatformHandleInTransit::CreateForMachPortName(port_name);
@@ -780,12 +776,27 @@ class ChannelPosix : public Channel,
} // namespace
+#if defined(OS_MACOSX) && !defined(OS_IOS)
+// Forward declare from channel_mac.cc.
+scoped_refptr<Channel> ChannelMacCreate(
+ Channel::Delegate* delegate,
+ ConnectionParams connection_params,
+ Channel::HandlePolicy handle_policy,
+ scoped_refptr<base::TaskRunner> io_task_runner);
+#endif
+
// static
scoped_refptr<Channel> Channel::Create(
Delegate* delegate,
ConnectionParams connection_params,
HandlePolicy handle_policy,
scoped_refptr<base::TaskRunner> io_task_runner) {
+#if defined(OS_MACOSX) && !defined(OS_IOS)
+ if (base::FeatureList::IsEnabled(features::kMojoChannelMac)) {
+ return ChannelMacCreate(delegate, std::move(connection_params),
+ handle_policy, io_task_runner);
+ }
+#endif
return new ChannelPosix(delegate, std::move(connection_params), handle_policy,
io_task_runner);
}
diff --git a/chromium/mojo/core/channel_unittest.cc b/chromium/mojo/core/channel_unittest.cc
index d5b37dce383..14585e348ea 100644
--- a/chromium/mojo/core/channel_unittest.cc
+++ b/chromium/mojo/core/channel_unittest.cc
@@ -4,6 +4,8 @@
#include "mojo/core/channel.h"
+#include <atomic>
+
#include "base/bind.h"
#include "base/memory/ptr_util.h"
#include "base/message_loop/message_loop.h"
@@ -362,6 +364,127 @@ TEST(ChannelTest, DeserializeMessage_BadExtraHeaderSize) {
base::kNullProcessHandle));
}
+class CountingChannelDelegate : public Channel::Delegate {
+ public:
+ explicit CountingChannelDelegate(base::OnceClosure on_final_message)
+ : on_final_message_(std::move(on_final_message)) {}
+ ~CountingChannelDelegate() override = default;
+
+ void OnChannelMessage(const void* payload,
+ size_t payload_size,
+ std::vector<PlatformHandle> handles) override {
+ // If this is the special "final message", run the closure.
+ if (payload_size == 1) {
+ auto* payload_str = reinterpret_cast<const char*>(payload);
+ if (payload_str[0] == '!') {
+ std::move(on_final_message_).Run();
+ return;
+ }
+ }
+
+ ++message_count_;
+ }
+
+ void OnChannelError(Channel::Error error) override { ++error_count_; }
+
+ size_t message_count_ = 0;
+ size_t error_count_ = 0;
+
+ private:
+ base::OnceClosure on_final_message_;
+};
+
+TEST(ChannelTest, PeerStressTest) {
+ constexpr size_t kLotsOfMessages = 1024;
+
+ base::MessageLoop message_loop(base::MessageLoop::TYPE_IO);
+ base::RunLoop run_loop;
+
+ // Both channels should receive all the messages that each is sent. When
+ // the count becomes 2 (indicating both channels have received the final
+ // message), quit the main test thread's run loop.
+ std::atomic_int count_channels_received_final_message(0);
+ auto quit_when_both_channels_received_final_message = base::BindRepeating(
+ [](std::atomic_int* count_channels_received_final_message,
+ base::OnceClosure quit_closure) {
+ if (++(*count_channels_received_final_message) == 2) {
+ std::move(quit_closure).Run();
+ }
+ },
+ base::Unretained(&count_channels_received_final_message),
+ run_loop.QuitClosure());
+
+ // Create a second IO thread for the peer channel.
+ base::Thread::Options thread_options;
+ thread_options.message_loop_type = base::MessageLoop::TYPE_IO;
+ base::Thread peer_thread("peer_b_io");
+ peer_thread.StartWithOptions(thread_options);
+
+ // Create two channels that run on separate threads.
+ PlatformChannel platform_channel;
+
+ CountingChannelDelegate delegate_a(
+ quit_when_both_channels_received_final_message);
+ scoped_refptr<Channel> channel_a = Channel::Create(
+ &delegate_a, ConnectionParams(platform_channel.TakeLocalEndpoint()),
+ Channel::HandlePolicy::kRejectHandles, message_loop.task_runner());
+
+ CountingChannelDelegate delegate_b(
+ quit_when_both_channels_received_final_message);
+ scoped_refptr<Channel> channel_b = Channel::Create(
+ &delegate_b, ConnectionParams(platform_channel.TakeRemoteEndpoint()),
+ Channel::HandlePolicy::kRejectHandles, peer_thread.task_runner());
+
+ // Send a lot of messages, followed by a final terminating message.
+ auto send_lots_of_messages = [](scoped_refptr<Channel> channel) {
+ for (size_t i = 0; i < kLotsOfMessages; ++i) {
+ channel->Write(std::make_unique<Channel::Message>(0, 0));
+ }
+ };
+ auto send_final_message = [](scoped_refptr<Channel> channel) {
+ auto message = std::make_unique<Channel::Message>(1, 0);
+ auto* payload = static_cast<char*>(message->mutable_payload());
+ payload[0] = '!';
+ channel->Write(std::move(message));
+ };
+
+ channel_a->Start();
+ channel_b->Start();
+
+ send_lots_of_messages(channel_a);
+ send_lots_of_messages(channel_b);
+
+ message_loop.task_runner()->PostTask(
+ FROM_HERE, base::BindOnce(send_lots_of_messages, channel_a));
+ message_loop.task_runner()->PostTask(
+ FROM_HERE, base::BindOnce(send_lots_of_messages, channel_a));
+ message_loop.task_runner()->PostTask(
+ FROM_HERE, base::BindOnce(send_final_message, channel_a));
+
+ peer_thread.task_runner()->PostTask(
+ FROM_HERE, base::BindOnce(send_lots_of_messages, channel_b));
+ peer_thread.task_runner()->PostTask(
+ FROM_HERE, base::BindOnce(send_lots_of_messages, channel_b));
+ peer_thread.task_runner()->PostTask(
+ FROM_HERE, base::BindOnce(send_final_message, channel_b));
+
+ // Run until quit_when_both_channels_received_final_message quits the loop.
+ run_loop.Run();
+
+ channel_a->ShutDown();
+ channel_b->ShutDown();
+
+ peer_thread.StopSoon();
+
+ base::RunLoop().RunUntilIdle();
+
+ EXPECT_EQ(kLotsOfMessages * 3, delegate_a.message_count_);
+ EXPECT_EQ(kLotsOfMessages * 3, delegate_b.message_count_);
+
+ EXPECT_EQ(0u, delegate_a.error_count_);
+ EXPECT_EQ(0u, delegate_b.error_count_);
+}
+
} // namespace
} // namespace core
} // namespace mojo
diff --git a/chromium/mojo/core/embedder_unittest.cc b/chromium/mojo/core/embedder_unittest.cc
index f336f4c8f70..8d90cc2690d 100644
--- a/chromium/mojo/core/embedder_unittest.cc
+++ b/chromium/mojo/core/embedder_unittest.cc
@@ -293,7 +293,7 @@ TEST_F(EmbedderTest, MultiprocessBaseSharedMemory) {
WriteMessageWithHandles(server_mp, "hello", &sb2, 1);
// 4. Read a message from |server_mp|.
- EXPECT_EQ("bye", ReadMessage(server_mp));
+ EXPECT_EQ("hey", ReadMessage(server_mp));
// 5. Expect that the contents of the shared buffer have changed.
EXPECT_EQ(kByeWorld, std::string(buffer));
@@ -305,6 +305,9 @@ TEST_F(EmbedderTest, MultiprocessBaseSharedMemory) {
EXPECT_EQ(kByeWorld, std::string(static_cast<char*>(mapping.memory())));
ASSERT_EQ(MOJO_RESULT_OK, MojoClose(sb1));
+
+ // Tell the child it's safe to shut down.
+ WriteMessage(server_mp, "bye");
});
}
@@ -327,7 +330,7 @@ DEFINE_TEST_CLIENT_TEST_WITH_PIPE(MultiprocessSharedMemoryClient,
// 4. Write into |buffer| and send a message back.
memcpy(buffer, kByeWorld, sizeof(kByeWorld));
- WriteMessage(client_mp, "bye");
+ WriteMessage(client_mp, "hey");
// 5. Extract the shared memory handle and ensure we can map it and read the
// contents.
@@ -338,6 +341,8 @@ DEFINE_TEST_CLIENT_TEST_WITH_PIPE(MultiprocessSharedMemoryClient,
EXPECT_NE(buffer, mapping.memory());
EXPECT_EQ(kByeWorld, std::string(static_cast<char*>(mapping.memory())));
+ EXPECT_EQ("bye", ReadMessage(client_mp));
+
// 6. Close |sb1|. Should fail because |ExtractRegionFromSharedBuffer()|
// should have closed the handle.
EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, MojoClose(sb1));
diff --git a/chromium/mojo/core/invitation_unittest.cc b/chromium/mojo/core/invitation_unittest.cc
index 58603897535..dae047ad6c9 100644
--- a/chromium/mojo/core/invitation_unittest.cc
+++ b/chromium/mojo/core/invitation_unittest.cc
@@ -22,6 +22,7 @@
#include "build/build_config.h"
#include "mojo/core/test/mojo_test_base.h"
#include "mojo/public/c/system/invitation.h"
+#include "mojo/public/cpp/platform/features.h"
#include "mojo/public/cpp/platform/named_platform_channel.h"
#include "mojo/public/cpp/platform/platform_channel.h"
#include "mojo/public/cpp/system/platform_handle.h"
@@ -78,6 +79,19 @@ void PrepareToPassRemoteEndpoint(PlatformChannel* channel,
std::string value;
#if defined(OS_FUCHSIA)
channel->PrepareToPassRemoteEndpoint(&options->handles_to_transfer, &value);
+#elif defined(OS_MACOSX)
+ PlatformChannel::HandlePassingInfo info;
+ if (base::FeatureList::IsEnabled(features::kMojoChannelMac))
+ info = options->mach_ports_for_rendezvous;
+ else
+ info = options->fds_to_remap;
+
+ channel->PrepareToPassRemoteEndpoint(&info, &value);
+
+ if (base::FeatureList::IsEnabled(features::kMojoChannelMac))
+ options->mach_ports_for_rendezvous = info;
+ else
+ options->fds_to_remap = info;
#elif defined(OS_POSIX)
channel->PrepareToPassRemoteEndpoint(&options->fds_to_remap, &value);
#elif defined(OS_WIN)
diff --git a/chromium/mojo/core/ports/name.h b/chromium/mojo/core/ports/name.h
index 415ba65a958..0dafee2720e 100644
--- a/chromium/mojo/core/ports/name.h
+++ b/chromium/mojo/core/ports/name.h
@@ -11,7 +11,7 @@
#include <tuple>
#include "base/component_export.h"
-#include "base/hash.h"
+#include "base/hash/hash.h"
namespace mojo {
namespace core {
diff --git a/chromium/mojo/core/ports/node.cc b/chromium/mojo/core/ports/node.cc
index 64989c2948b..767e37ce305 100644
--- a/chromium/mojo/core/ports/node.cc
+++ b/chromium/mojo/core/ports/node.cc
@@ -879,7 +879,7 @@ int Node::MergePortsInternal(const PortRef& port0_ref,
{
// Needed to swap peer map entries below.
PortLocker::AssertNoPortsLockedOnCurrentThread();
- base::Optional<base::AutoLock> ports_locker(base::in_place, ports_lock_);
+ base::ReleasableAutoLock ports_locker(&ports_lock_);
base::Optional<PortLocker> locker(base::in_place, port_refs, 2);
auto* port0 = locker->GetPort(port0_ref);
@@ -910,7 +910,7 @@ int Node::MergePortsInternal(const PortRef& port0_ref,
const bool close_port1 =
port1->state == Port::kReceiving || allow_close_on_bad_state;
locker.reset();
- ports_locker.reset();
+ ports_locker.Release();
if (close_port0)
ClosePort(port0_ref);
if (close_port1)
diff --git a/chromium/mojo/core/test/BUILD.gn b/chromium/mojo/core/test/BUILD.gn
index 6fad6fec711..5e18e02740a 100644
--- a/chromium/mojo/core/test/BUILD.gn
+++ b/chromium/mojo/core/test/BUILD.gn
@@ -2,6 +2,8 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
+import("//third_party/protobuf/proto_library.gni")
+
static_library("test_support") {
testonly = true
sources = [
@@ -86,3 +88,15 @@ static_library("test_support_impl") {
"test_support_impl.h",
]
}
+
+if (is_mac) {
+ proto_library("channel_mac_proto") {
+ sources = [
+ "data/channel_mac/channel_mac.proto",
+ ]
+ deps = [
+ "//testing/libfuzzer/fuzzers/mach:proto",
+ ]
+ import_dirs = [ "//testing/libfuzzer/fuzzers/mach" ]
+ }
+}
diff --git a/chromium/mojo/core/watcher_dispatcher.cc b/chromium/mojo/core/watcher_dispatcher.cc
index f2eb2e253d7..00d2a431036 100644
--- a/chromium/mojo/core/watcher_dispatcher.cc
+++ b/chromium/mojo/core/watcher_dispatcher.cc
@@ -7,6 +7,7 @@
#include <algorithm>
#include <limits>
+#include "base/compiler_specific.h"
#include "base/debug/alias.h"
#include "base/macros.h"
#include "base/memory/ptr_util.h"
@@ -58,6 +59,9 @@ void WatcherDispatcher::NotifyHandleClosed(Dispatcher* dispatcher) {
watch->Cancel();
}
+// handler_ may be address-taken in a different DSO, and hence incompatible with
+// CFI-icall.
+NO_SANITIZE("cfi-icall")
void WatcherDispatcher::InvokeWatchCallback(uintptr_t context,
MojoResult result,
const HandleSignalsState& state,
diff --git a/chromium/mojo/public/BUILD.gn b/chromium/mojo/public/BUILD.gn
index bd094c8c328..b7d5d05b3a1 100644
--- a/chromium/mojo/public/BUILD.gn
+++ b/chromium/mojo/public/BUILD.gn
@@ -8,6 +8,7 @@ group("public") {
deps = [
":sdk",
"cpp/bindings",
+ "cpp/test:test_mojom",
"interfaces/bindings/tests:test_interfaces",
]
diff --git a/chromium/mojo/public/c/system/macros.h b/chromium/mojo/public/c/system/macros.h
index 7786094e250..1023e1c111a 100644
--- a/chromium/mojo/public/c/system/macros.h
+++ b/chromium/mojo/public/c/system/macros.h
@@ -7,41 +7,27 @@
#include <stddef.h>
+#if !defined(__cplusplus)
+#include <assert.h> // Defines static_assert() in C11.
+#include <stdalign.h> // Defines alignof() in C11.
+#endif
+
// Assert things at compile time. (|msg| should be a valid identifier name.)
// Use like:
// MOJO_STATIC_ASSERT(sizeof(struct Foo) == 12, "Foo has invalid size");
-#if defined(__cplusplus)
#define MOJO_STATIC_ASSERT(expr, msg) static_assert(expr, msg)
-#elif defined(__clang__)
-// TODO(thakis): Use #include <assert.h> and static_assert() in C11 mode
-// (__STDC_VERSION__>= 201112L) once https://reviews.llvm.org/D17444 made its
-// way into Chromium.
-#define MOJO_STATIC_ASSERT(expr, msg) _Static_assert(expr, msg)
-#else
-#define MOJO_STATIC_ASSERT(expr, msg)
-#endif
// Defines a pointer-sized struct field of the given type. This ensures that the
// field has an 8-byte footprint on both 32-bit and 64-bit systems, using an
-// anonymous bitfield of either 32 or 0 bits, depending on pointer size. Weird
-// formatting here courtesy of clang-format.
+// anonymous bitfield of either 32 or 0 bits, depending on pointer size.
+// clang-format off
#define MOJO_POINTER_FIELD(type, name) \
type name; \
- uint32_t: \
- (sizeof(void*) == 4 ? 32 : 0)
+ uint32_t : (sizeof(void*) == 4 ? 32 : 0)
+// clang-format on
// Like the C++11 |alignof| operator.
-#if __cplusplus >= 201103L
#define MOJO_ALIGNOF(type) alignof(type)
-#elif defined(__GNUC__)
-#define MOJO_ALIGNOF(type) __alignof__(type)
-#elif defined(_MSC_VER)
-// The use of |sizeof| is to work around a bug in MSVC 2010 (see
-// http://goo.gl/isH0C; supposedly fixed since then).
-#define MOJO_ALIGNOF(type) (sizeof(type) - sizeof(type) + __alignof(type))
-#else
-#error "Please define MOJO_ALIGNOF() for your compiler."
-#endif
// Specify the alignment of a |struct|, etc.
// Use like:
@@ -49,7 +35,9 @@
// Unlike the C++11 |alignas()|, |alignment| must be an integer. It may not be a
// type, nor can it be an expression like |MOJO_ALIGNOF(type)| (due to the
// non-C++11 MSVS version).
-#if __cplusplus >= 201103L
+// This can't use alignas() in C11 mode because unlike the C++11 version the
+// C11 version can't be used on struct declarations.
+#if defined(__cplusplus)
#define MOJO_ALIGNAS(alignment) alignas(alignment)
#elif defined(__GNUC__)
#define MOJO_ALIGNAS(alignment) __attribute__((aligned(alignment)))
diff --git a/chromium/mojo/public/cpp/base/values_mojom_traits.h b/chromium/mojo/public/cpp/base/values_mojom_traits.h
index cdb9bbbd94d..66752b7c90d 100644
--- a/chromium/mojo/public/cpp/base/values_mojom_traits.h
+++ b/chromium/mojo/public/cpp/base/values_mojom_traits.h
@@ -86,8 +86,13 @@ struct COMPONENT_EXPORT(MOJO_BASE_SHARED_TRAITS)
return mojo_base::mojom::ValueDataView::Tag::DICTIONARY_VALUE;
case base::Value::Type::LIST:
return mojo_base::mojom::ValueDataView::Tag::LIST_VALUE;
+ // TODO(crbug.com/859477): Remove after root cause is found.
+ case base::Value::Type::DEAD:
+ CHECK(false);
+ return mojo_base::mojom::ValueDataView::Tag::NULL_VALUE;
}
- NOTREACHED();
+ // TODO(crbug.com/859477): Revert to NOTREACHED() after root cause is found.
+ CHECK(false);
return mojo_base::mojom::ValueDataView::Tag::NULL_VALUE;
}
diff --git a/chromium/mojo/public/cpp/bindings/BUILD.gn b/chromium/mojo/public/cpp/bindings/BUILD.gn
index 52082de79a6..f95d4fbfda4 100644
--- a/chromium/mojo/public/cpp/bindings/BUILD.gn
+++ b/chromium/mojo/public/cpp/bindings/BUILD.gn
@@ -120,8 +120,6 @@ component("bindings") {
"associated_interface_request.h",
"binding.h",
"binding_set.h",
- "call_internal.cc",
- "call_internal.h",
"callback_helpers.h",
"connection_error_callback.h",
"connector.h",
@@ -171,6 +169,7 @@ component("bindings") {
"pipe_control_message_proxy.h",
"raw_ptr_impl_ref_traits.h",
"receiver.h",
+ "receiver_set.h",
"remote.h",
"sequence_local_sync_event_watcher.h",
"strong_associated_binding.h",
diff --git a/chromium/mojo/public/cpp/bindings/README.md b/chromium/mojo/public/cpp/bindings/README.md
index 75ef5a7702a..55a366c45fc 100644
--- a/chromium/mojo/public/cpp/bindings/README.md
+++ b/chromium/mojo/public/cpp/bindings/README.md
@@ -657,7 +657,7 @@ Similarly to [structs](#Structs), tagged unions generate an identically named,
representative C++ class which is typically wrapped in a `mojo::StructPtr<T>`.
Unlike structs, all generated union fields are private and must be retrieved and
-manipulated using accessors. A field `foo` is accessible by `foo()` and
+manipulated using accessors. A field `foo` is accessible by `get_foo()` and
settable by `set_foo()`. There is also a boolean `is_foo()` for each field which
indicates whether the union is currently taking on the value of field `foo` in
exclusion to all other union fields.
diff --git a/chromium/mojo/public/cpp/bindings/call_internal.cc b/chromium/mojo/public/cpp/bindings/call_internal.cc
deleted file mode 100644
index 8e4e57eeea2..00000000000
--- a/chromium/mojo/public/cpp/bindings/call_internal.cc
+++ /dev/null
@@ -1,18 +0,0 @@
-// 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/cpp/bindings/call_internal.h"
-
-namespace mojo {
-namespace internal {
-
-CallProxyWrapperBase::CallProxyWrapperBase(void* proxy) : proxy_(proxy) {}
-
-CallProxyWrapperBase::CallProxyWrapperBase(CallProxyWrapperBase&& other)
- : proxy_(other.proxy_) {}
-
-CallProxyWrapperBase::~CallProxyWrapperBase() = default;
-
-} // namespace internal
-} // namespace mojo
diff --git a/chromium/mojo/public/cpp/bindings/call_internal.h b/chromium/mojo/public/cpp/bindings/call_internal.h
deleted file mode 100644
index ddefd8eb28a..00000000000
--- a/chromium/mojo/public/cpp/bindings/call_internal.h
+++ /dev/null
@@ -1,48 +0,0 @@
-// 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_CPP_BINDINGS_CALL_INTERNAL_H_
-#define MOJO_PUBLIC_CPP_BINDINGS_CALL_INTERNAL_H_
-
-#include <utility>
-
-#include "base/component_export.h"
-#include "base/macros.h"
-
-namespace mojo {
-namespace internal {
-
-// Base class for temporary objects returned by |Remote<T>::rpc()|. This
-// provides pass-through access to the passed calling proxy.
-class COMPONENT_EXPORT(MOJO_CPP_BINDINGS) CallProxyWrapperBase {
- public:
- explicit CallProxyWrapperBase(void* proxy);
- CallProxyWrapperBase(CallProxyWrapperBase&& other);
- ~CallProxyWrapperBase();
-
- void* proxy() const { return proxy_; }
-
- private:
- void* proxy_;
-
- DISALLOW_COPY_AND_ASSIGN(CallProxyWrapperBase);
-};
-
-template <typename T>
-class CallProxyWrapper : public CallProxyWrapperBase {
- public:
- explicit CallProxyWrapper(T* proxy) : CallProxyWrapperBase(proxy) {}
- CallProxyWrapper(CallProxyWrapper&& other)
- : CallProxyWrapperBase(std::move(other)) {}
-
- T* operator->() const { return static_cast<T*>(proxy()); }
-
- private:
- DISALLOW_COPY_AND_ASSIGN(CallProxyWrapper);
-};
-
-} // namespace internal
-} // namespace mojo
-
-#endif // MOJO_PUBLIC_CPP_BINDINGS_CALL_INTERNAL_H_
diff --git a/chromium/mojo/public/cpp/bindings/lib/interface_serialization.h b/chromium/mojo/public/cpp/bindings/lib/interface_serialization.h
index 498308a3108..79b334d34d8 100644
--- a/chromium/mojo/public/cpp/bindings/lib/interface_serialization.h
+++ b/chromium/mojo/public/cpp/bindings/lib/interface_serialization.h
@@ -123,7 +123,7 @@ struct Serializer<InterfacePtrDataView<Base>, PendingRemote<T>> {
static void Serialize(PendingRemote<T>& input,
Interface_Data* output,
SerializationContext* context) {
- context->AddInterfaceInfo(input.TakePipe(), input.version(), output);
+ context->AddInterfaceInfo(input.PassPipe(), input.version(), output);
}
static bool Deserialize(Interface_Data* input,
@@ -162,7 +162,7 @@ struct Serializer<InterfaceRequestDataView<Base>, PendingReceiver<T>> {
static void Serialize(PendingReceiver<T>& input,
Handle_Data* output,
SerializationContext* context) {
- context->AddHandle(ScopedHandle::From(input.TakePipe()), output);
+ context->AddHandle(ScopedHandle::From(input.PassPipe()), output);
}
static bool Deserialize(Handle_Data* input,
diff --git a/chromium/mojo/public/cpp/bindings/lib/serialization_util.h b/chromium/mojo/public/cpp/bindings/lib/serialization_util.h
index a7a99b3bb72..51eb5f230ba 100644
--- a/chromium/mojo/public/cpp/bindings/lib/serialization_util.h
+++ b/chromium/mojo/public/cpp/bindings/lib/serialization_util.h
@@ -77,62 +77,6 @@ bool CallSetToNullIfExists(UserType* output) {
return false;
}
-template <typename T>
-struct HasSetUpContextMethod {
- template <typename U>
- static char Test(decltype(U::SetUpContext) *);
- template <typename U>
- static int Test(...);
- static const bool value = sizeof(Test<T>(0)) == sizeof(char);
-
- private:
- EnsureTypeIsComplete<T> check_t_;
-};
-
-template <typename Traits,
- bool has_context = HasSetUpContextMethod<Traits>::value>
-struct CustomContextHelper;
-
-template <typename Traits>
-struct CustomContextHelper<Traits, true> {
- template <typename MaybeConstUserType>
- static void* SetUp(MaybeConstUserType& input, SerializationContext* context) {
- return Traits::SetUpContext(input);
- }
-
- template <typename MaybeConstUserType>
- static void TearDown(MaybeConstUserType& input, void* custom_context) {
- Traits::TearDownContext(input, custom_context);
- }
-};
-
-template <typename Traits>
-struct CustomContextHelper<Traits, false> {
- template <typename MaybeConstUserType>
- static void* SetUp(MaybeConstUserType& input, SerializationContext* context) {
- return nullptr;
- }
-
- template <typename MaybeConstUserType>
- static void TearDown(MaybeConstUserType& input, void* custom_context) {
- DCHECK(!custom_context);
- }
-};
-
-template <typename ReturnType, typename ParamType, typename InputUserType>
-ReturnType CallWithContext(ReturnType (*f)(ParamType, void*),
- InputUserType&& input,
- void* context) {
- return f(std::forward<InputUserType>(input), context);
-}
-
-template <typename ReturnType, typename ParamType, typename InputUserType>
-ReturnType CallWithContext(ReturnType (*f)(ParamType),
- InputUserType&& input,
- void* context) {
- return f(std::forward<InputUserType>(input));
-}
-
template <typename T, typename MaybeConstUserType>
struct HasGetBeginMethod {
template <typename U>
diff --git a/chromium/mojo/public/cpp/bindings/lib/string_serialization.h b/chromium/mojo/public/cpp/bindings/lib/string_serialization.h
index 1fe6b87af70..d11a0c74eee 100644
--- a/chromium/mojo/public/cpp/bindings/lib/string_serialization.h
+++ b/chromium/mojo/public/cpp/bindings/lib/string_serialization.h
@@ -29,12 +29,9 @@ struct Serializer<StringDataView, MaybeConstUserType> {
if (CallIsNullIfExists<Traits>(input))
return;
- void* custom_context = CustomContextHelper<Traits>::SetUp(input, context);
- const size_t size = CallWithContext(Traits::GetSize, input, custom_context);
- writer->Allocate(size, buffer);
- memcpy((*writer)->storage(),
- CallWithContext(Traits::GetData, input, custom_context), size);
- CustomContextHelper<Traits>::TearDown(input, custom_context);
+ auto r = Traits::GetUTF8(input);
+ writer->Allocate(r.size(), buffer);
+ memcpy((*writer)->storage(), r.data(), r.size());
}
static bool Deserialize(String_Data* input,
diff --git a/chromium/mojo/public/cpp/bindings/lib/string_traits_wtf.cc b/chromium/mojo/public/cpp/bindings/lib/string_traits_wtf.cc
index 71b758c49c1..540a154fd3f 100644
--- a/chromium/mojo/public/cpp/bindings/lib/string_traits_wtf.cc
+++ b/chromium/mojo/public/cpp/bindings/lib/string_traits_wtf.cc
@@ -4,43 +4,9 @@
#include "mojo/public/cpp/bindings/string_traits_wtf.h"
-#include <string.h>
-
-#include "base/logging.h"
-#include "mojo/public/cpp/bindings/lib/array_internal.h"
#include "mojo/public/cpp/bindings/string_data_view.h"
-#include "third_party/blink/renderer/platform/wtf/text/string_utf8_adaptor.h"
namespace mojo {
-namespace {
-
-struct UTF8AdaptorInfo {
- explicit UTF8AdaptorInfo(const WTF::String& input) : utf8_adaptor(input) {
-#if DCHECK_IS_ON()
- original_size_in_bytes = input.CharactersSizeInBytes();
-#endif
- }
-
- ~UTF8AdaptorInfo() {}
-
- WTF::StringUTF8Adaptor utf8_adaptor;
-
-#if DCHECK_IS_ON()
- // For sanity check only.
- size_t original_size_in_bytes;
-#endif
-};
-
-UTF8AdaptorInfo* ToAdaptor(const WTF::String& input, void* context) {
- UTF8AdaptorInfo* adaptor = static_cast<UTF8AdaptorInfo*>(context);
-
-#if DCHECK_IS_ON()
- DCHECK_EQ(adaptor->original_size_in_bytes, input.CharactersSizeInBytes());
-#endif
- return adaptor;
-}
-
-} // namespace
// static
void StringTraits<WTF::String>::SetToNull(WTF::String* output) {
@@ -52,26 +18,9 @@ void StringTraits<WTF::String>::SetToNull(WTF::String* output) {
}
// static
-void* StringTraits<WTF::String>::SetUpContext(const WTF::String& input) {
- return new UTF8AdaptorInfo(input);
-}
-
-// static
-void StringTraits<WTF::String>::TearDownContext(const WTF::String& input,
- void* context) {
- delete ToAdaptor(input, context);
-}
-
-// static
-size_t StringTraits<WTF::String>::GetSize(const WTF::String& input,
- void* context) {
- return ToAdaptor(input, context)->utf8_adaptor.length();
-}
-
-// static
-const char* StringTraits<WTF::String>::GetData(const WTF::String& input,
- void* context) {
- return ToAdaptor(input, context)->utf8_adaptor.Data();
+WTF::StringUTF8Adaptor StringTraits<WTF::String>::GetUTF8(
+ const WTF::String& input) {
+ return WTF::StringUTF8Adaptor(input);
}
// static
diff --git a/chromium/mojo/public/cpp/bindings/pending_receiver.h b/chromium/mojo/public/cpp/bindings/pending_receiver.h
index 342d077ab21..73d0ed5a5e3 100644
--- a/chromium/mojo/public/cpp/bindings/pending_receiver.h
+++ b/chromium/mojo/public/cpp/bindings/pending_receiver.h
@@ -8,6 +8,7 @@
#include <utility>
#include "base/macros.h"
+#include "mojo/public/cpp/bindings/interface_request.h"
#include "mojo/public/cpp/system/message_pipe.h"
namespace mojo {
@@ -34,12 +35,18 @@ class PendingReceiver {
// any Remote and cannot be used to bind a Receiver.
//
// A valid PendingReceiver is commonly obtained by calling
- // |Remote::BindNewReceiver()| on an existing unbound Remote instance or less
- // commonly by calling calling |PendingRemote::MakeReceiver()| on an existing
- // but invalid PendingRemote instance.
+ // |Remote::BindNewPipeAndPassReceiver()| on an existing unbound Remote
+ // instance or less commonly by calling calling
+ // |PendingRemote::InitWithNewPipeAndPassReceiver()| on an existing but
+ // invalid PendingRemote instance.
PendingReceiver() = default;
PendingReceiver(PendingReceiver&&) noexcept = default;
+ // Temporary implicit move constructor to aid in converting from use of
+ // InterfaceRequest<Interface> to PendingReceiver.
+ PendingReceiver(InterfaceRequest<Interface>&& request)
+ : PendingReceiver(request.PassMessagePipe()) {}
+
// Constructs a valid PendingReceiver from a valid raw message pipe handle.
explicit PendingReceiver(ScopedMessagePipeHandle pipe)
: pipe_(std::move(pipe)) {
@@ -50,6 +57,12 @@ class PendingReceiver {
PendingReceiver& operator=(PendingReceiver&&) noexcept = default;
+ // Temporary implicit conversion operator to InterfaceRequest<Interface> to
+ // aid in converting usage to PendingReceiver.
+ operator InterfaceRequest<Interface>() {
+ return InterfaceRequest<Interface>(PassPipe());
+ }
+
// Indicates whether the PendingReceiver is valid, meaning it can ne used to
// bind a Receiver that wants to begin dispatching method calls made by the
// entangled Remote.
@@ -61,10 +74,10 @@ class PendingReceiver {
// effectively be dropped.
void reset() { pipe_.reset(); }
- // Takes ownership of this PendingReceiver's message pipe handle. After this
+ // Passes ownership of this PendingReceiver's message pipe handle. After this
// call, the PendingReceiver is no longer in a valid state and can no longer
// be used to bind a Receiver.
- ScopedMessagePipeHandle TakePipe() WARN_UNUSED_RESULT {
+ ScopedMessagePipeHandle PassPipe() WARN_UNUSED_RESULT {
return std::move(pipe_);
}
diff --git a/chromium/mojo/public/cpp/bindings/pending_remote.h b/chromium/mojo/public/cpp/bindings/pending_remote.h
index cf37734e61b..ebac0a45214 100644
--- a/chromium/mojo/public/cpp/bindings/pending_remote.h
+++ b/chromium/mojo/public/cpp/bindings/pending_remote.h
@@ -38,11 +38,12 @@ class PendingRemote {
// receiver and cannot be used to bind a Remote.
//
// A valid PendingRemote is typically obtained by calling
- // |Receiver::BindNewRemote()| on an existing unbound Receiver instance.
+ // |Receiver::BindNewPipeAndPassRemote()| on an existing unbound Receiver
+ // instance.
//
// To simultaneously create a valid PendingRemote and an entangled
// PendingReceiver for rarer cases where both objects need to be passed
- // elsewhere, use the |MakeReceiver()| method defined below.
+ // elsewhere, use the |InitWithNewPipeAndPassReceiver()| method defined below.
PendingRemote() = default;
PendingRemote(PendingRemote&&) noexcept = default;
@@ -73,7 +74,7 @@ class PendingRemote {
// Takes ownership of this PendingRemote's message pipe handle. After this
// call, the PendingRemote is no longer in a valid state and can no longer be
// used to bind a Remote.
- ScopedMessagePipeHandle TakePipe() WARN_UNUSED_RESULT {
+ ScopedMessagePipeHandle PassPipe() WARN_UNUSED_RESULT {
version_ = 0;
return std::move(pipe_);
}
@@ -83,9 +84,11 @@ class PendingRemote {
// always zero.
uint32_t version() const { return version_; }
- // Creates a new PendingReceiver and entangles this PendingRemote with it.
- // May only be called on an invalid PendingRemote.
- PendingReceiver<Interface> MakeReceiver() WARN_UNUSED_RESULT {
+ // Creates a new message pipe, retaining one end in the PendingRemote (making
+ // it valid) and returning the other end as its entangled PendingReceiver. May
+ // only be called on an invalid PendingRemote.
+ PendingReceiver<Interface> InitWithNewPipeAndPassReceiver()
+ WARN_UNUSED_RESULT {
DCHECK(!is_valid()) << "PendingRemote already has a receiver";
MessagePipe pipe;
pipe_ = std::move(pipe.handle0);
diff --git a/chromium/mojo/public/cpp/bindings/receiver.h b/chromium/mojo/public/cpp/bindings/receiver.h
index e97d0aafa02..078a5ce8160 100644
--- a/chromium/mojo/public/cpp/bindings/receiver.h
+++ b/chromium/mojo/public/cpp/bindings/receiver.h
@@ -5,6 +5,7 @@
#ifndef MOJO_PUBLIC_CPP_BINDINGS_RECEIVER_H_
#define MOJO_PUBLIC_CPP_BINDINGS_RECEIVER_H_
+#include <memory>
#include <utility>
#include "base/compiler_specific.h"
@@ -25,8 +26,8 @@ namespace mojo {
// implementation of Interface. Every Receiver object is permanently linked to
// an implementation of Interface at construction time. The Receiver begins
// receiving and scheduling method calls to the implementation once it becomes
-// bound by consuming a PendingReceiver, either at construction time or by
-// calling |Bind()|.
+// bound either by consuming a PendingReceiver (at construction time or via
+// |Bind()|) or by calling |BindNewPipeAndPassRemote()|.
//
// Receiver is NOT thread- or sequence- safe and must be used from a single
// (but otherwise arbitrary) sequence. All bound Receiver objects are associated
@@ -49,8 +50,8 @@ class Receiver {
// Constructs an unbound Receiver linked to |impl| for the duration of the
// Receive's lifetime. The Receiver can be bound later by calling |Bind()| or
- // |BindNewRemote()|. An unbound Receiver does not schedule any asynchronous
- // tasks.
+ // |BindNewPipeAndPassRemote()|. An unbound Receiver does not schedule any
+ // asynchronous tasks.
explicit Receiver(ImplPointerType impl) : internal_state_(std::move(impl)) {}
// Constructs a bound Receiver by consuming |pending_receiver|. The Receiver
@@ -104,19 +105,19 @@ class Receiver {
// notifications on the default SequencedTaskRunner (i.e.
// base::SequencedTaskRunnerHandle::Get() at the time of this call). Must only
// be called on an unbound Receiver.
- PendingRemote<Interface> BindNewRemote() WARN_UNUSED_RESULT {
- return BindNewRemote(nullptr);
+ PendingRemote<Interface> BindNewPipeAndPassRemote() WARN_UNUSED_RESULT {
+ return BindNewPipeAndPassRemote(nullptr);
}
// Like above, but the Receiver will schedule incoming |impl| method calls and
// disconnection notifications on |task_runner| rather than on the default
// SequencedTaskRunner. Must only be called on an unbound Receiver.
// |task_runner| must run tasks on the same sequence that owns this Receiver.
- PendingRemote<Interface> BindNewRemote(
+ PendingRemote<Interface> BindNewPipeAndPassRemote(
scoped_refptr<base::SequencedTaskRunner> task_runner) WARN_UNUSED_RESULT {
DCHECK(!is_bound()) << "Receiver is already bound";
PendingRemote<Interface> remote;
- Bind(remote.MakeReceiver(), std::move(task_runner));
+ Bind(remote.InitWithNewPipeAndPassReceiver(), std::move(task_runner));
return remote;
}
@@ -138,7 +139,7 @@ class Receiver {
// Receiver.
void Bind(PendingReceiver<Interface> pending_receiver,
scoped_refptr<base::SequencedTaskRunner> task_runner) {
- internal_state_.Bind(pending_receiver.TakePipe(), std::move(task_runner));
+ internal_state_.Bind(pending_receiver.PassPipe(), std::move(task_runner));
}
// Unbinds this Receiver, preventing any further |impl| method calls or
@@ -161,6 +162,14 @@ class Receiver {
internal_state_.Unbind().PassMessagePipe());
}
+ // Adds a message filter to be notified of each incoming message before
+ // dispatch. If a filter returns |false| from Accept(), the message is not
+ // dispatched and the pipe is closed. Filters cannot be removed once added.
+ void AddFilter(std::unique_ptr<MessageReceiver> filter) {
+ DCHECK(is_bound());
+ internal_state_.AddFilter(std::move(filter));
+ }
+
private:
internal::BindingState<Interface, ImplRefTraits> internal_state_;
diff --git a/chromium/mojo/public/cpp/bindings/receiver_set.h b/chromium/mojo/public/cpp/bindings/receiver_set.h
new file mode 100644
index 00000000000..59267047556
--- /dev/null
+++ b/chromium/mojo/public/cpp/bindings/receiver_set.h
@@ -0,0 +1,334 @@
+// 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_CPP_BINDINGS_RECEIVER_SET_H_
+#define MOJO_PUBLIC_CPP_BINDINGS_RECEIVER_SET_H_
+
+#include <map>
+#include <memory>
+#include <string>
+#include <utility>
+
+#include "base/bind.h"
+#include "base/callback.h"
+#include "base/macros.h"
+#include "base/memory/ptr_util.h"
+#include "mojo/public/cpp/bindings/connection_error_callback.h"
+#include "mojo/public/cpp/bindings/message.h"
+#include "mojo/public/cpp/bindings/pending_receiver.h"
+#include "mojo/public/cpp/bindings/receiver.h"
+#include "mojo/public/cpp/bindings/remote.h"
+#include "mojo/public/cpp/bindings/unique_ptr_impl_ref_traits.h"
+
+namespace mojo {
+
+using ReceiverId = size_t;
+
+template <typename ReceiverType>
+struct ReceiverSetTraits;
+
+template <typename Interface, typename ImplRefTraits>
+struct ReceiverSetTraits<Receiver<Interface, ImplRefTraits>> {
+ using InterfaceType = Interface;
+ using ImplPointerType = typename ImplRefTraits::PointerType;
+};
+
+template <typename ContextType>
+struct ReceiverSetContextTraits {
+ using Type = ContextType;
+
+ static constexpr bool SupportsContext() { return true; }
+};
+
+template <>
+struct ReceiverSetContextTraits<void> {
+ // NOTE: This choice of Type only matters insofar as it affects the size of
+ // the |context_| field of a ReceiverSetBase::Entry with void context. The
+ // context value is never used in this case.
+ using Type = bool;
+
+ static constexpr bool SupportsContext() { return false; }
+};
+
+// Generic helper used to own a collection of Receiver endpoints. For
+// convenience this type automatically manages cleanup of receivers that have
+// been disconnected from their remote caller.
+//
+// Note that this type is not typically used directly by application. Instead,
+// prefer to use one of the various aliases (like ReceiverSet) that are based on
+// it.
+//
+// If |ContextType| is non-void, then every added receiver must include a
+// context value of that type (when calling |Add()|), and |current_context()|
+// will return that value during the extent of any message dispatch or
+// disconnection notification pertaining to that specific receiver.
+//
+// So for example if ContextType is |int| and we call:
+//
+// Remote<mojom::Foo> foo1, foo2;
+// ReceiverSet<mojom::Foo> receivers;
+// // Assume |this| is an implementation of mojom::Foo...
+// receivers.Add(this, foo1.BindNewReceiver(), 42);
+// receivers.Add(this, foo2.BindNewReceiver(), 43);
+//
+// foo1->DoSomething();
+// foo2->DoSomething();
+//
+// We can expect two asynchronous calls to |this->DoSomething()|. If that
+// method looks at the value of |current_context()|, it will see a value of 42
+// while executing the call from |foo1| and a value of 43 while executing the
+// call from |foo2|.
+//
+// Finally, note that ContextType can be any type of thing, including move-only
+// objects like std::unique_ptrs.
+template <typename ReceiverType, typename ContextType>
+class ReceiverSetBase {
+ public:
+ using Traits = ReceiverSetTraits<ReceiverType>;
+ using Interface = typename Traits::InterfaceType;
+ using ImplPointerType = typename Traits::ImplPointerType;
+ using ContextTraits = ReceiverSetContextTraits<ContextType>;
+ using Context = typename ContextTraits::Type;
+ using PreDispatchCallback = base::RepeatingCallback<void(const Context&)>;
+
+ ReceiverSetBase() : weak_ptr_factory_(this) {}
+
+ // Sets a callback to be invoked any time a receiver in the set is
+ // disconnected. The callback is invoked *after* the receiver in question
+ // is removed from the set, and |current_context()| will correspond to the
+ // disconnected receiver's context value during the callback if the
+ // ContextType is not void.
+ void set_disconnect_handler(base::RepeatingClosure handler) {
+ disconnect_handler_ = std::move(handler);
+ }
+
+ // Adds a new receiver to the set, binding |receiver| to |impl| with no
+ // additional context. If |task_runner| is non-null, the receiver's messages
+ // will be dispatched to |impl| on that |task_runner|. |task_runner| must run
+ // messages on the same sequence that owns this ReceiverSetBase. If
+ // |task_runner| is null, the value of
+ // |base::SequencedTaskRunnerHandle::Get()| at the time of the |Add()| call
+ // will be used to run scheduled tasks for the receiver.
+ ReceiverId Add(
+ ImplPointerType impl,
+ PendingReceiver<Interface> receiver,
+ scoped_refptr<base::SequencedTaskRunner> task_runner = nullptr) {
+ static_assert(!ContextTraits::SupportsContext(),
+ "Context value required for non-void context type.");
+ return AddImpl(std::move(impl), std::move(receiver), false,
+ std::move(task_runner));
+ }
+
+ // Adds a new receiver associated with |context|. See above method for all
+ // other (identical) details.
+ ReceiverId Add(
+ ImplPointerType impl,
+ PendingReceiver<Interface> receiver,
+ Context context,
+ scoped_refptr<base::SequencedTaskRunner> task_runner = nullptr) {
+ static_assert(ContextTraits::SupportsContext(),
+ "Context value unsupported for void context type.");
+ return AddImpl(std::move(impl), std::move(receiver), std::move(context),
+ std::move(task_runner));
+ }
+
+ // Removes a receiver from the set. Note that this is safe to call even if the
+ // receiver corresponding to |id| has already been removed (will be a no-op).
+ //
+ // Returns |true| if the receiver was removed and |false| if it didn't exist.
+ //
+ // A removed receiver is effectively closed and its remote (if any) will be
+ // disconnected. No further messages or disconnection notifications will be
+ // scheduled or executed for the removed receiver.
+ bool Remove(ReceiverId id) {
+ auto it = receivers_.find(id);
+ if (it == receivers_.end())
+ return false;
+ receivers_.erase(it);
+ return true;
+ }
+
+ // Removes all receivers from the set, effectively closing all of them. This
+ // ReceiverSet will not schedule or execute any further method invocations or
+ // disconnection notifications until a new receiver is added to the set.
+ void Clear() { receivers_.clear(); }
+
+ bool empty() const { return receivers_.empty(); }
+
+ size_t size() const { return receivers_.size(); }
+
+ // Implementations may call this when processing a received method call or
+ // disconnection notification. During the extent of method invocation or
+ // disconnection notification, this returns the context value associated with
+ // the specific receiver which received the method call or disconnection.
+ //
+ // Each receiver must be associated with a context value when it's added
+ // to the set by |Add()|, and this is only supported when ContextType is
+ // not void.
+ //
+ // NOTE: It is important to understand that this must only be called within
+ // the stack frame of an actual interface method invocation or disconnect
+ // notification scheduled by a receiver. It is a illegal to attempt to call
+ // this any other time (e.g., from another async task you post from within a
+ // message handler).
+ const Context& current_context() const {
+ static_assert(ContextTraits::SupportsContext(),
+ "current_context() requires non-void context type.");
+ DCHECK(current_context_);
+ return *current_context_;
+ }
+
+ // Implementations may call this when processing a received method call or
+ // disconnection notification. See above note for constraints on usage.
+ // This returns the ReceiverId associated with the specific receiver which
+ // received the incoming method call or disconnection notification.
+ ReceiverId current_receiver() const {
+ DCHECK(current_context_);
+ return current_receiver_;
+ }
+
+ // Reports the currently dispatching Message as bad and removes the receiver
+ // which received it. Note that this is only legal to call from directly
+ // within the stack frame of an incoming method call. If you need to do
+ // asynchronous work before you can determine the legitimacy of a message, use
+ // GetBadMessageCallback() and retain its result until you're ready to invoke
+ // or discard it.
+ void ReportBadMessage(const std::string& error) {
+ GetBadMessageCallback().Run(error);
+ }
+
+ // Acquires a callback which may be run to report the currently dispatching
+ // Message as bad and remove the receiver which received it. Note that this
+ // this is only legal to call from directly within the stack frame of an
+ // incoming method call, but the returned callback may be called exactly once
+ // any time thereafter, as long as the ReceiverSetBase itself hasn't been
+ // destroyed yet. If the callback is invoked, it must be done from the same
+ // sequence which owns the ReceiverSetBase, and upon invocation it will report
+ // the corresponding message as bad.
+ ReportBadMessageCallback GetBadMessageCallback() {
+ DCHECK(current_context_);
+ return base::BindOnce(
+ [](ReportBadMessageCallback error_callback,
+ base::WeakPtr<ReceiverSetBase> receiver_set, ReceiverId receiver_id,
+ const std::string& error) {
+ std::move(error_callback).Run(error);
+ if (receiver_set)
+ receiver_set->RemoveBinding(receiver_id);
+ },
+ mojo::GetBadMessageCallback(), weak_ptr_factory_.GetWeakPtr(),
+ current_receiver());
+ }
+
+ private:
+ friend class Entry;
+
+ class Entry {
+ public:
+ Entry(ImplPointerType impl,
+ PendingReceiver<Interface> receiver,
+ ReceiverSetBase* receiver_set,
+ ReceiverId receiver_id,
+ Context context,
+ scoped_refptr<base::SequencedTaskRunner> task_runner)
+ : receiver_(std::move(impl),
+ std::move(receiver),
+ std::move(task_runner)),
+ receiver_set_(receiver_set),
+ receiver_id_(receiver_id),
+ context_(std::move(context)) {
+ receiver_.AddFilter(std::make_unique<DispatchFilter>(this));
+ receiver_.set_disconnect_handler(
+ base::BindOnce(&Entry::OnDisconnect, base::Unretained(this)));
+ }
+
+ private:
+ class DispatchFilter : public MessageReceiver {
+ public:
+ explicit DispatchFilter(Entry* entry) : entry_(entry) {}
+ ~DispatchFilter() override {}
+
+ private:
+ // MessageReceiver:
+ bool Accept(Message* message) override {
+ entry_->WillDispatch();
+ return true;
+ }
+
+ Entry* entry_;
+
+ DISALLOW_COPY_AND_ASSIGN(DispatchFilter);
+ };
+
+ void WillDispatch() {
+ receiver_set_->SetDispatchContext(&context_, receiver_id_);
+ }
+
+ void OnDisconnect() {
+ WillDispatch();
+ receiver_set_->OnDisconnect(receiver_id_);
+ }
+
+ ReceiverType receiver_;
+ ReceiverSetBase* const receiver_set_;
+ const ReceiverId receiver_id_;
+ Context const context_;
+
+ DISALLOW_COPY_AND_ASSIGN(Entry);
+ };
+
+ void SetDispatchContext(const Context* context, ReceiverId receiver_id) {
+ current_context_ = context;
+ current_receiver_ = receiver_id;
+ }
+
+ ReceiverId AddImpl(ImplPointerType impl,
+ PendingReceiver<Interface> receiver,
+ Context context,
+ scoped_refptr<base::SequencedTaskRunner> task_runner) {
+ ReceiverId id = next_receiver_id_++;
+ DCHECK_GE(next_receiver_id_, 0u);
+ auto entry =
+ std::make_unique<Entry>(std::move(impl), std::move(receiver), this, id,
+ std::move(context), std::move(task_runner));
+ receivers_.insert(std::make_pair(id, std::move(entry)));
+ return id;
+ }
+
+ void OnDisconnect(ReceiverId id) {
+ auto it = receivers_.find(id);
+ DCHECK(it != receivers_.end());
+
+ // We keep the Entry alive throughout error dispatch.
+ std::unique_ptr<Entry> entry = std::move(it->second);
+ receivers_.erase(it);
+
+ if (disconnect_handler_)
+ disconnect_handler_.Run();
+ }
+
+ base::RepeatingClosure disconnect_handler_;
+ ReceiverId next_receiver_id_ = 0;
+ std::map<ReceiverId, std::unique_ptr<Entry>> receivers_;
+ const Context* current_context_ = nullptr;
+ ReceiverId current_receiver_;
+ base::WeakPtrFactory<ReceiverSetBase> weak_ptr_factory_;
+
+ DISALLOW_COPY_AND_ASSIGN(ReceiverSetBase);
+};
+
+// Common helper for a set of Receivers which do not own their implementation.
+template <typename Interface, typename ContextType = void>
+using ReceiverSet = ReceiverSetBase<Receiver<Interface>, ContextType>;
+
+// Helper for a set of Receivers where each bound Receiver is tied to an owned
+// implementation. The |Add()| method takes a std::unique_ptr<Interface> for
+// each bound implementation.
+template <typename Interface, typename ContextType = void>
+using OwnedReceiverSet =
+ ReceiverSetBase<Receiver<Interface, UniquePtrImplRefTraits<Interface>>,
+ ContextType>;
+
+} // namespace mojo
+
+#endif // MOJO_PUBLIC_CPP_BINDINGS_RECEIVER_SET_H_
diff --git a/chromium/mojo/public/cpp/bindings/remote.h b/chromium/mojo/public/cpp/bindings/remote.h
index eeb7d9334de..afda20605ac 100644
--- a/chromium/mojo/public/cpp/bindings/remote.h
+++ b/chromium/mojo/public/cpp/bindings/remote.h
@@ -10,12 +10,10 @@
#include "base/callback_forward.h"
#include "base/compiler_specific.h"
-#include "base/location.h"
#include "base/logging.h"
#include "base/macros.h"
#include "base/memory/scoped_refptr.h"
#include "base/sequenced_task_runner.h"
-#include "mojo/public/cpp/bindings/call_internal.h"
#include "mojo/public/cpp/bindings/interface_ptr_info.h"
#include "mojo/public/cpp/bindings/lib/interface_ptr_state.h"
#include "mojo/public/cpp/bindings/pending_remote.h"
@@ -35,13 +33,13 @@ namespace mojo {
// response callbacks and disconnection notifications.
//
// The most common ways to bind a Remote are to consume to a PendingRemote
-// received via some IPC, or to call |BindNewReceiver()| and send the returned
-// PendingReceiver somewhere useful (i.e., to a remote Receiver who will consume
-// it). For example:
+// received via some IPC, or to call |BindNewPipeAndPassReceiver()| and send the
+// returned PendingReceiver somewhere useful (i.e., to a remote Receiver who
+// will consume it). For example:
//
// mojo::Remote<mojom::Widget> widget;
-// widget_factory->CreateWidget(widget.BindNewReceiver());
-// widget.rpc(FROM_HERE)->Click();
+// widget_factory->CreateWidget(widget.BindNewPipeAndPassReceiver());
+// widget->Click();
//
// IMPORTANT: There are some things to be aware of regarding Interface method
// calls as they relate to Remote object lifetime:
@@ -85,25 +83,8 @@ class Remote {
~Remote() = default;
- // Issue a method call to the remote implementation of Interface. If the
- // remote end is still a PendingReceiver, the call will be queued within that
- // object. If the remote end is bound to a live Receiver, the call will
- // eventually be dispatched in the order it was received.
- //
- // If the Remote is no longer connected because the receiver has been
- // destroyed, the call will be dropped.
- internal::CallProxyWrapper<Interface> rpc(const base::Location& from_here) {
- internal_state_.SetNextCallLocation(from_here);
- return internal::CallProxyWrapper<Interface>(internal_state_.instance());
- }
-
// Exposes access to callable Interface methods directed at this Remote's
// receiver. Must only be called on a bound Remote.
- //
- // Direct use of this accessor is discouraged and callers should prefer to use
- // |rpc()| instead when making remote calls. Using |rpc()| can provide
- // useful call-site attribution in DCHECK-enabled builds and makes IPC call
- // sites easier to grok.
typename Interface::Proxy_* get() const {
DCHECK(is_bound())
<< "Cannot issue Interface method calls on an unbound Remote";
@@ -111,13 +92,10 @@ class Remote {
}
// Shorthand form of |get()|. See above.
- //
- // TODO(https://crbug.com/934883): Figure out whether to disallow use of this
- // operator in certain environments.
typename Interface::Proxy_* operator->() const { return get(); }
// Indicates whether this Remote is bound and thus can issue Interface method
- // calls via e.g. |rpc()|.
+ // calls via the above accessors.
//
// NOTE: The state of being "bound" should not be confused with the state of
// being "connected" (see |is_connected()| below). A Remote is NEVER passively
@@ -171,15 +149,15 @@ class Remote {
// will schedule any response callbacks or disconnection notifications on the
// default SequencedTaskRunner (i.e. base::SequencedTaskRunnerHandle::Get() at
// the time of this call). Must only be called on an unbound Remote.
- PendingReceiver<Interface> BindNewReceiver() WARN_UNUSED_RESULT {
- return BindNewReceiver(nullptr);
+ PendingReceiver<Interface> BindNewPipeAndPassReceiver() WARN_UNUSED_RESULT {
+ return BindNewPipeAndPassReceiver(nullptr);
}
// Like above, but the Remote will schedule response callbacks and
// disconnection notifications on |task_runner| instead of the default
// SequencedTaskRunner. |task_runner| must run tasks on the same sequence that
// owns this Remote.
- PendingReceiver<Interface> BindNewReceiver(
+ PendingReceiver<Interface> BindNewPipeAndPassReceiver(
scoped_refptr<base::SequencedTaskRunner> task_runner) WARN_UNUSED_RESULT {
MessagePipe pipe;
Bind(PendingRemote<Interface>(std::move(pipe.handle0), 0),
@@ -204,7 +182,7 @@ class Remote {
void Bind(PendingRemote<Interface> pending_remote,
scoped_refptr<base::SequencedTaskRunner> task_runner) {
DCHECK(!is_bound()) << "Remote is already bound";
- internal_state_.Bind(InterfacePtrInfo<Interface>(pending_remote.TakePipe(),
+ internal_state_.Bind(InterfacePtrInfo<Interface>(pending_remote.PassPipe(),
pending_remote.version()),
std::move(task_runner));
diff --git a/chromium/mojo/public/cpp/bindings/string_traits.h b/chromium/mojo/public/cpp/bindings/string_traits.h
index 165c9fa8cd8..bd256472c5a 100644
--- a/chromium/mojo/public/cpp/bindings/string_traits.h
+++ b/chromium/mojo/public/cpp/bindings/string_traits.h
@@ -12,8 +12,7 @@ namespace mojo {
// This must be specialized for any type |T| to be serialized/deserialized as
// a mojom string.
//
-// Imagine you want to specialize it for CustomString, usually you need to
-// implement:
+// An example specialization for CustomString:
//
// template <T>
// struct StringTraits<CustomString> {
@@ -21,31 +20,14 @@ namespace mojo {
// static bool IsNull(const CustomString& input);
// static void SetToNull(CustomString* output);
//
-// static size_t GetSize(const CustomString& input);
-// static const char* GetData(const CustomString& input);
+// // This doesn't need to be a base::StringPiece; it simply needs to be a
+// // type that exposes a data() method that returns a pointer to the UTF-8
+// // bytes and a size() method that returns the length of the UTF-8 bytes.
+// static std::span<char> GetUTF8(const CustomString& input);
//
// // The caller guarantees that |!input.is_null()|.
// static bool Read(StringDataView input, CustomString* output);
// };
-//
-// In some cases, you may need to do conversion before you can return the size
-// and data as 8-bit characters for serialization. (For example, CustomString is
-// UTF-16 string). In that case, you can add two optional methods:
-//
-// static void* SetUpContext(const CustomString& input);
-// static void TearDownContext(const CustomString& input, void* context);
-//
-// And then you append a second parameter, void* context, to GetSize() and
-// GetData():
-//
-// static size_t GetSize(const CustomString& input, void* context);
-// static const char* GetData(const CustomString& input, void* context);
-//
-// If a CustomString instance is not null, the serialization code will call
-// SetUpContext() at the beginning, and pass the resulting context pointer to
-// GetSize()/GetData(). After serialization is done, it calls TearDownContext()
-// so that you can do any necessary cleanup.
-//
template <typename T>
struct StringTraits {
static_assert(internal::AlwaysFalse<T>::value,
diff --git a/chromium/mojo/public/cpp/bindings/string_traits_stl.h b/chromium/mojo/public/cpp/bindings/string_traits_stl.h
index f6cc8ad098f..cb3c5fb4a07 100644
--- a/chromium/mojo/public/cpp/bindings/string_traits_stl.h
+++ b/chromium/mojo/public/cpp/bindings/string_traits_stl.h
@@ -23,9 +23,7 @@ struct StringTraits<std::string> {
output->clear();
}
- static size_t GetSize(const std::string& input) { return input.size(); }
-
- static const char* GetData(const std::string& input) { return input.data(); }
+ static const std::string& GetUTF8(const std::string& input) { return input; }
static bool Read(StringDataView input, std::string* output) {
output->assign(input.storage(), input.size());
diff --git a/chromium/mojo/public/cpp/bindings/string_traits_string_piece.h b/chromium/mojo/public/cpp/bindings/string_traits_string_piece.h
index af6be893ac0..785537962c9 100644
--- a/chromium/mojo/public/cpp/bindings/string_traits_string_piece.h
+++ b/chromium/mojo/public/cpp/bindings/string_traits_string_piece.h
@@ -12,7 +12,7 @@ namespace mojo {
template <>
struct StringTraits<base::StringPiece> {
- static bool IsNull(const base::StringPiece& input) {
+ static bool IsNull(base::StringPiece input) {
// base::StringPiece is always converted to non-null mojom string. We could
// have let StringPiece containing a null data pointer map to null mojom
// string, but StringPiece::empty() returns true in this case. It seems
@@ -26,11 +26,7 @@ struct StringTraits<base::StringPiece> {
output->set(nullptr, 0);
}
- static size_t GetSize(const base::StringPiece& input) { return input.size(); }
-
- static const char* GetData(const base::StringPiece& input) {
- return input.data();
- }
+ static base::StringPiece GetUTF8(base::StringPiece input) { return input; }
static bool Read(StringDataView input, base::StringPiece* output) {
output->set(input.storage(), input.size());
diff --git a/chromium/mojo/public/cpp/bindings/string_traits_wtf.h b/chromium/mojo/public/cpp/bindings/string_traits_wtf.h
index 51601d1ab85..662fff5daf7 100644
--- a/chromium/mojo/public/cpp/bindings/string_traits_wtf.h
+++ b/chromium/mojo/public/cpp/bindings/string_traits_wtf.h
@@ -7,6 +7,7 @@
#include "mojo/public/cpp/bindings/lib/bindings_internal.h"
#include "mojo/public/cpp/bindings/string_traits.h"
+#include "third_party/blink/renderer/platform/wtf/text/string_utf8_adaptor.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
namespace mojo {
@@ -16,12 +17,7 @@ struct StringTraits<WTF::String> {
static bool IsNull(const WTF::String& input) { return input.IsNull(); }
static void SetToNull(WTF::String* output);
- static void* SetUpContext(const WTF::String& input);
- static void TearDownContext(const WTF::String& input, void* context);
-
- static size_t GetSize(const WTF::String& input, void* context);
-
- static const char* GetData(const WTF::String& input, void* context);
+ static WTF::StringUTF8Adaptor GetUTF8(const WTF::String& input);
static bool Read(StringDataView input, WTF::String* output);
};
diff --git a/chromium/mojo/public/cpp/platform/BUILD.gn b/chromium/mojo/public/cpp/platform/BUILD.gn
index c20f95bb6d7..79c017608d8 100644
--- a/chromium/mojo/public/cpp/platform/BUILD.gn
+++ b/chromium/mojo/public/cpp/platform/BUILD.gn
@@ -38,6 +38,10 @@ component("platform") {
sources += [ "named_platform_channel_posix.cc" ]
}
+ if (is_mac) {
+ sources += [ "named_platform_channel_mac.cc" ]
+ }
+
if (is_fuchsia) {
public_deps += [
"//third_party/fuchsia-sdk/sdk:fdio",
diff --git a/chromium/mojo/public/cpp/platform/named_platform_channel_mac.cc b/chromium/mojo/public/cpp/platform/named_platform_channel_mac.cc
new file mode 100644
index 00000000000..0a2df95360d
--- /dev/null
+++ b/chromium/mojo/public/cpp/platform/named_platform_channel_mac.cc
@@ -0,0 +1,83 @@
+// 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/cpp/platform/named_platform_channel.h"
+
+#include <mach/port.h>
+#include <servers/bootstrap.h>
+
+#include "base/mac/foundation_util.h"
+#include "base/mac/mach_logging.h"
+#include "base/mac/scoped_mach_port.h"
+#include "base/rand_util.h"
+#include "base/strings/stringprintf.h"
+#include "mojo/public/cpp/platform/platform_channel.h"
+
+namespace mojo {
+
+namespace {
+
+std::string GetBootstrapName(const std::string& name) {
+ if (name.empty()) {
+ return base::StringPrintf("%s.mojo.%llu", base::mac::BaseBundleID(),
+ base::RandUint64());
+ }
+ return name;
+}
+
+} // namespace
+
+// TODO(crbug.com/932175): This namespace will go away and these methods
+// will be defined direclty on NamedPlatformChannel.
+namespace NamedPlatformChannelMac {
+
+// static
+COMPONENT_EXPORT(MOJO_CPP_PLATFORM)
+PlatformChannelServerEndpoint CreateServerEndpoint(
+ const NamedPlatformChannel::Options& options,
+ NamedPlatformChannel::ServerName* server_name) {
+ const std::string bootstrap_name = GetBootstrapName(options.server_name);
+ DCHECK_LT(bootstrap_name.length(),
+ static_cast<size_t>(BOOTSTRAP_MAX_NAME_LEN));
+
+ base::mac::ScopedMachReceiveRight receive_right;
+ kern_return_t kr = bootstrap_check_in(
+ bootstrap_port, bootstrap_name.c_str(),
+ base::mac::ScopedMachReceiveRight::Receiver(receive_right).get());
+ if (kr != KERN_SUCCESS) {
+ BOOTSTRAP_LOG(ERROR, kr) << "bootstrap_check_in " << bootstrap_name;
+ return PlatformChannelServerEndpoint();
+ }
+
+ // The mpl_qlimit specified here should stay in sync with PlatformChannel.
+ mach_port_limits_t limits{};
+ limits.mpl_qlimit = MACH_PORT_QLIMIT_LARGE;
+ kr = mach_port_set_attributes(
+ mach_task_self(), receive_right.get(), MACH_PORT_LIMITS_INFO,
+ reinterpret_cast<mach_port_info_t>(&limits), MACH_PORT_LIMITS_INFO_COUNT);
+ MACH_LOG_IF(ERROR, kr != KERN_SUCCESS, kr) << "mach_port_set_attributes";
+
+ *server_name = bootstrap_name;
+ return PlatformChannelServerEndpoint(
+ PlatformHandle(std::move(receive_right)));
+}
+
+// static
+COMPONENT_EXPORT(MOJO_CPP_PLATFORM)
+PlatformChannelEndpoint CreateClientEndpoint(
+ const NamedPlatformChannel::ServerName& server_name) {
+ base::mac::ScopedMachSendRight send_right;
+ kern_return_t kr = bootstrap_look_up(
+ bootstrap_port, server_name.c_str(),
+ base::mac::ScopedMachSendRight::Receiver(send_right).get());
+ if (kr != KERN_SUCCESS) {
+ BOOTSTRAP_LOG(ERROR, kr) << "bootstrap_look_up " << server_name;
+ return PlatformChannelEndpoint();
+ }
+
+ return PlatformChannelEndpoint(PlatformHandle(std::move(send_right)));
+}
+
+} // namespace NamedPlatformChannelMac
+} // namespace mojo
diff --git a/chromium/mojo/public/cpp/platform/named_platform_channel_posix.cc b/chromium/mojo/public/cpp/platform/named_platform_channel_posix.cc
index 9082ac4da59..d5f82d86430 100644
--- a/chromium/mojo/public/cpp/platform/named_platform_channel_posix.cc
+++ b/chromium/mojo/public/cpp/platform/named_platform_channel_posix.cc
@@ -15,6 +15,8 @@
#include "base/posix/eintr_wrapper.h"
#include "base/rand_util.h"
#include "base/strings/string_number_conversions.h"
+#include "build/build_config.h"
+#include "mojo/public/cpp/platform/features.h"
namespace mojo {
@@ -77,10 +79,26 @@ PlatformHandle CreateUnixDomainSocket() {
} // namespace
+#if defined(OS_MACOSX) && !defined(OS_IOS)
+// Temporarily forward declare named_platform_channel_mac.cc symbols.
+namespace NamedPlatformChannelMac {
+PlatformChannelServerEndpoint CreateServerEndpoint(
+ const NamedPlatformChannel::Options& options,
+ NamedPlatformChannel::ServerName* server_name);
+PlatformChannelEndpoint CreateClientEndpoint(
+ const NamedPlatformChannel::ServerName& server_name);
+} // namespace NamedPlatformChannelMac
+#endif
+
// static
PlatformChannelServerEndpoint NamedPlatformChannel::CreateServerEndpoint(
const Options& options,
ServerName* server_name) {
+#if defined(OS_MACOSX) && !defined(OS_IOS)
+ if (base::FeatureList::IsEnabled(features::kMojoChannelMac)) {
+ return NamedPlatformChannelMac::CreateServerEndpoint(options, server_name);
+ }
+#endif
ServerName name = options.server_name;
if (name.empty())
name = GenerateRandomServerName(options);
@@ -128,6 +146,11 @@ PlatformChannelServerEndpoint NamedPlatformChannel::CreateServerEndpoint(
// static
PlatformChannelEndpoint NamedPlatformChannel::CreateClientEndpoint(
const ServerName& server_name) {
+#if defined(OS_MACOSX) && !defined(OS_IOS)
+ if (base::FeatureList::IsEnabled(features::kMojoChannelMac)) {
+ return NamedPlatformChannelMac::CreateClientEndpoint(server_name);
+ }
+#endif
DCHECK(!server_name.empty());
struct sockaddr_un unix_addr;
diff --git a/chromium/mojo/public/cpp/platform/platform_channel.cc b/chromium/mojo/public/cpp/platform/platform_channel.cc
index fd73f967da4..8502ae35c95 100644
--- a/chromium/mojo/public/cpp/platform/platform_channel.cc
+++ b/chromium/mojo/public/cpp/platform/platform_channel.cc
@@ -7,6 +7,7 @@
#include <cstddef>
#include <cstdint>
#include <string>
+#include <utility>
#include "base/logging.h"
#include "base/rand_util.h"
@@ -15,6 +16,7 @@
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "build/build_config.h"
+#include "mojo/public/cpp/platform/features.h"
#if defined(OS_WIN)
#include <windows.h>
@@ -35,6 +37,13 @@
#include "base/posix/global_descriptors.h"
#endif
+#if defined(OS_MACOSX) && !defined(OS_IOS)
+#include <mach/port.h>
+
+#include "base/mac/mach_logging.h"
+#include "base/mac/scoped_mach_port.h"
+#endif
+
#if defined(OS_POSIX) && !defined(OS_NACL_SFI)
#include <sys/socket.h>
#elif defined(OS_NACL_SFI)
@@ -95,6 +104,28 @@ void CreateChannel(PlatformHandle* local_endpoint,
}
#elif defined(OS_POSIX)
+#if defined(OS_MACOSX) && !defined(OS_IOS)
+// TODO(crbug.com/932175): This will be renamed CreateChannel().
+void CreateMachChannel(PlatformHandle* local_endpoint,
+ PlatformHandle* remote_endpoint) {
+ // Mach messaging is simplex; and in order to enable full-duplex
+ // communication, the Mojo channel implementation performs an internal
+ // handshake with its peer to establish two sets of Mach receive and send
+ // rights. The handshake process starts with the creation of one
+ // PlatformChannel endpoint.
+ base::mac::ScopedMachReceiveRight receive;
+ base::mac::ScopedMachSendRight send;
+ // The mpl_qlimit specified here should stay in sync with
+ // NamedPlatformChannel.
+ CHECK(base::mac::CreateMachPort(&receive, &send, MACH_PORT_QLIMIT_LARGE));
+
+ // In a reverse of Mach messaging semantics, in Mojo the "local" endpoint is
+ // the send right, while the "remote" end is the receive right.
+ *local_endpoint = PlatformHandle(std::move(send));
+ *remote_endpoint = PlatformHandle(std::move(receive));
+}
+#endif // defined(OS_MACOSX) && !defined(OS_IOS)
+
#if defined(OS_ANDROID)
// Leave room for any other descriptors defined in content for example.
// TODO(https://crbug.com/676442): Consider changing base::GlobalDescriptors to
@@ -114,6 +145,11 @@ bool IsTargetDescriptorUsed(const base::FileHandleMappingVector& mapping,
void CreateChannel(PlatformHandle* local_endpoint,
PlatformHandle* remote_endpoint) {
+#if defined(OS_MACOSX) && !defined(OS_IOS)
+ if (base::FeatureList::IsEnabled(features::kMojoChannelMac)) {
+ return CreateMachChannel(local_endpoint, remote_endpoint);
+ }
+#endif
int fds[2];
#if defined(OS_NACL_SFI)
PCHECK(imc_socketpair(fds) == 0);
@@ -163,9 +199,12 @@ PlatformChannel::~PlatformChannel() = default;
PlatformChannel& PlatformChannel::operator=(PlatformChannel&& other) = default;
-void PlatformChannel::PrepareToPassRemoteEndpoint(HandlePassingInfo* info,
+void PlatformChannel::PrepareToPassRemoteEndpoint(HandlePassingInfo* info_input,
std::string* value) {
+#if !defined(OS_MACOSX) || defined(OS_IOS)
+ auto* info = info_input;
DCHECK(info);
+#endif
DCHECK(value);
DCHECK(remote_endpoint_.is_valid());
@@ -183,6 +222,26 @@ void PlatformChannel::PrepareToPassRemoteEndpoint(HandlePassingInfo* info,
info->emplace_back(fd, mapped_fd);
*value = base::NumberToString(mapped_fd);
#elif defined(OS_POSIX)
+#if defined(OS_MACOSX) && !defined(OS_IOS)
+ if (base::FeatureList::IsEnabled(features::kMojoChannelMac)) {
+ auto* info = static_cast<base::MachPortsForRendezvous*>(info_input);
+ DCHECK(remote_endpoint_.platform_handle().is_mach_receive());
+ base::mac::ScopedMachReceiveRight receive_right =
+ remote_endpoint_.TakePlatformHandle().TakeMachReceiveRight();
+ base::MachPortsForRendezvous::key_type rendezvous_key = 0;
+ do {
+ rendezvous_key =
+ static_cast<decltype(rendezvous_key)>(base::RandUint64());
+ } while (info->find(rendezvous_key) != info->end());
+ auto it = info->insert(std::make_pair(
+ rendezvous_key, base::MachRendezvousPort(std::move(receive_right))));
+ DCHECK(it.second) << "Failed to insert port for rendezvous.";
+ *value = base::NumberToString(rendezvous_key);
+ return;
+ }
+
+ auto* info = static_cast<base::FileHandleMappingVector*>(info_input);
+#endif // defined(OS_MACOSX) && !defined(OS_IOS)
// Arbitrary sanity check to ensure the loop below terminates reasonably
// quickly.
CHECK_LT(info->size(), 1000u);
@@ -215,6 +274,19 @@ void PlatformChannel::PrepareToPassRemoteEndpoint(
PrepareToPassRemoteEndpoint(&options->handles_to_inherit, command_line);
#elif defined(OS_FUCHSIA)
PrepareToPassRemoteEndpoint(&options->handles_to_transfer, command_line);
+#elif defined(OS_MACOSX) && !defined(OS_IOS)
+ HandlePassingInfo info;
+ if (base::FeatureList::IsEnabled(features::kMojoChannelMac))
+ info = options->mach_ports_for_rendezvous;
+ else
+ info = options->fds_to_remap;
+
+ PrepareToPassRemoteEndpoint(&info, command_line);
+
+ if (base::FeatureList::IsEnabled(features::kMojoChannelMac))
+ options->mach_ports_for_rendezvous = info;
+ else
+ options->fds_to_remap = info;
#elif defined(OS_POSIX)
PrepareToPassRemoteEndpoint(&options->fds_to_remap, command_line);
#else
@@ -262,6 +334,26 @@ PlatformChannelEndpoint PlatformChannel::RecoverPassedEndpointFromString(
return PlatformChannelEndpoint(PlatformHandle(
base::ScopedFD(base::GlobalDescriptors::GetInstance()->Get(key))));
#elif defined(OS_POSIX)
+#if defined(OS_MACOSX) && !defined(OS_IOS)
+ if (base::FeatureList::IsEnabled(features::kMojoChannelMac)) {
+ auto* client = base::MachPortRendezvousClient::GetInstance();
+ if (!client) {
+ DLOG(ERROR) << "Mach rendezvous failed.";
+ return PlatformChannelEndpoint();
+ }
+ uint32_t rendezvous_key = 0;
+ if (value.empty() || !base::StringToUint(value, &rendezvous_key)) {
+ DLOG(ERROR) << "Invalid PlatformChannel rendezvous key.";
+ return PlatformChannelEndpoint();
+ }
+ auto receive = client->TakeReceiveRight(rendezvous_key);
+ if (!receive.is_valid()) {
+ DLOG(ERROR) << "Invalid PlatformChannel receive right.";
+ return PlatformChannelEndpoint();
+ }
+ return PlatformChannelEndpoint(PlatformHandle(std::move(receive)));
+ }
+#endif // defined(OS_MACOSX) && !defined(OS_IOS)
int fd = -1;
if (value.empty() || !base::StringToInt(value, &fd) ||
fd < base::GlobalDescriptors::kBaseDescriptor) {
diff --git a/chromium/mojo/public/cpp/platform/platform_channel.h b/chromium/mojo/public/cpp/platform/platform_channel.h
index 534c6bbfdc2..d31668a3286 100644
--- a/chromium/mojo/public/cpp/platform/platform_channel.h
+++ b/chromium/mojo/public/cpp/platform/platform_channel.h
@@ -41,6 +41,18 @@ class COMPONENT_EXPORT(MOJO_CPP_PLATFORM) PlatformChannel {
using HandlePassingInfo = base::HandlesToInheritVector;
#elif defined(OS_FUCHSIA)
using HandlePassingInfo = base::HandlesToTransferVector;
+#elif defined(OS_MACOSX) && !defined(OS_IOS)
+ // This type represents a union between MachPortsForRendezvous and
+ // FileHandleMappingVector, so that the type to use can be determined at run-
+ // time.
+ // TODO(crbug.com/932175): This will become a typedef to
+ // base::MachPortsForRendezvous in the future.
+ class HandlePassingInfo : public base::MachPortsForRendezvous,
+ public base::FileHandleMappingVector {
+ public:
+ using base::MachPortsForRendezvous::operator=;
+ using base::FileHandleMappingVector::operator=;
+ };
#elif defined(OS_POSIX)
using HandlePassingInfo = base::FileHandleMappingVector;
#else
diff --git a/chromium/mojo/public/cpp/system/buffer.h b/chromium/mojo/public/cpp/system/buffer.h
index d816e6a79de..e20a8fe14d9 100644
--- a/chromium/mojo/public/cpp/system/buffer.h
+++ b/chromium/mojo/public/cpp/system/buffer.h
@@ -58,7 +58,7 @@ class MOJO_CPP_SYSTEM_EXPORT SharedBufferHandle : public Handle {
//
// Note for those converting legacy shared memory to the
// base::*SharedMemoryRegion API: if SharedBufferHandle::Create is used for
- // your shared memory regions, the mojo::Create*SahredMemoryRegion methods in
+ // your shared memory regions, the mojo::Create*SharedMemoryRegion methods in
// mojo/public/cpp/base/shared_memory_utils.h should be used. These know how
// to use a broker to create regions in unprivileged contexts in the same way
// as this SharedBufferHandle::Create method.
diff --git a/chromium/mojo/public/cpp/system/data_pipe.h b/chromium/mojo/public/cpp/system/data_pipe.h
index 205af858aee..eb7d6e279ad 100644
--- a/chromium/mojo/public/cpp/system/data_pipe.h
+++ b/chromium/mojo/public/cpp/system/data_pipe.h
@@ -131,16 +131,12 @@ inline MojoResult CreateDataPipe(
return rv;
}
-// A wrapper class that automatically creates a data pipe and owns both handles.
+// DEPRECATED: use |CreateDataPipe| instead.
//
-// Note that this class is not safe to use in production code, as there is no
-// way for it to report failure while creating the pipe, while in practice
-// creating a new data pipe does fail every now and then. Instead just call
-// CreateDataPipe directly and check its return value.
+// This class is not safe to use in production code as there is no way for it to
+// report failure while creating the pipe and it will CHECK in case of failures.
//
-// TODO(vtl): Make an even more friendly version? (Maybe templatized for a
-// particular type instead of some "element"? Maybe functions that take
-// vectors?)
+// A wrapper class that automatically creates a data pipe and owns both handles.
class MOJO_CPP_SYSTEM_EXPORT DataPipe {
public:
DataPipe();
diff --git a/chromium/mojo/public/cpp/system/platform_handle.cc b/chromium/mojo/public/cpp/system/platform_handle.cc
index 9e55f550b2f..f00df808682 100644
--- a/chromium/mojo/public/cpp/system/platform_handle.cc
+++ b/chromium/mojo/public/cpp/system/platform_handle.cc
@@ -33,6 +33,8 @@ base::PlatformFile PlatformFileFromPlatformHandleValue(uint64_t value) {
#endif
}
+} // namespace
+
ScopedSharedBufferHandle WrapPlatformSharedMemoryRegion(
base::subtle::PlatformSharedMemoryRegion region) {
if (!region.IsValid())
@@ -177,8 +179,6 @@ base::subtle::PlatformSharedMemoryRegion UnwrapPlatformSharedMemoryRegion(
base::UnguessableToken::Deserialize(mojo_guid.high, mojo_guid.low));
}
-} // namespace
-
ScopedHandle WrapPlatformHandle(PlatformHandle handle) {
MojoPlatformHandle platform_handle;
PlatformHandle::ToMojoPlatformHandle(std::move(handle), &platform_handle);
diff --git a/chromium/mojo/public/cpp/system/platform_handle.h b/chromium/mojo/public/cpp/system/platform_handle.h
index b18ceafacd9..5134275edc5 100644
--- a/chromium/mojo/public/cpp/system/platform_handle.h
+++ b/chromium/mojo/public/cpp/system/platform_handle.h
@@ -76,6 +76,14 @@ enum class UnwrappedSharedMemoryHandleProtection {
kReadOnly,
};
+// Wraps and unwraps base::subtle::PlatformSharedMemoryRegions. This should be
+// used only while transitioning from the legacy shared memory API. In new code
+// only base::*SharedMemoryRegion should be used instead.
+ScopedSharedBufferHandle WrapPlatformSharedMemoryRegion(
+ base::subtle::PlatformSharedMemoryRegion region);
+base::subtle::PlatformSharedMemoryRegion UnwrapPlatformSharedMemoryRegion(
+ ScopedSharedBufferHandle mojo_handle);
+
// Wraps a PlatformHandle from the C++ platform support library as a Mojo
// handle.
MOJO_CPP_SYSTEM_EXPORT ScopedHandle WrapPlatformHandle(PlatformHandle handle);
diff --git a/chromium/mojo/public/cpp/test/BUILD.gn b/chromium/mojo/public/cpp/test/BUILD.gn
new file mode 100644
index 00000000000..c667cd41bb4
--- /dev/null
+++ b/chromium/mojo/public/cpp/test/BUILD.gn
@@ -0,0 +1,12 @@
+# 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.
+
+import("//mojo/public/tools/bindings/mojom.gni")
+
+mojom("test_mojom") {
+ testonly = true
+ sources = [
+ "module.test-mojom",
+ ]
+}
diff --git a/chromium/mojo/public/interfaces/bindings/tests/BUILD.gn b/chromium/mojo/public/interfaces/bindings/tests/BUILD.gn
index 1309315189b..a5efd42d93c 100644
--- a/chromium/mojo/public/interfaces/bindings/tests/BUILD.gn
+++ b/chromium/mojo/public/interfaces/bindings/tests/BUILD.gn
@@ -320,7 +320,7 @@ component("test_export_component") {
if (!is_ios) {
component("test_export_blink_component") {
testonly = true
- deps = [
+ public_deps = [
":test_export_blink",
]
}
diff --git a/chromium/mojo/public/java/system/BUILD.gn b/chromium/mojo/public/java/system/BUILD.gn
index 0025f5588d3..49b2dbcaebf 100644
--- a/chromium/mojo/public/java/system/BUILD.gn
+++ b/chromium/mojo/public/java/system/BUILD.gn
@@ -174,4 +174,5 @@ instrumentation_test_apk("mojo_test_apk") {
shared_libraries = [ ":mojo_java_unittests" ]
apk_name = "MojoTest"
android_manifest = "javatests/AndroidManifest.xml"
+ enable_multidex = false
}
diff --git a/chromium/mojo/public/js/BUILD.gn b/chromium/mojo/public/js/BUILD.gn
index b27019dde25..3f94385c708 100644
--- a/chromium/mojo/public/js/BUILD.gn
+++ b/chromium/mojo/public/js/BUILD.gn
@@ -126,3 +126,9 @@ grit("resources") {
"//mojo/public/mojom/base:base_js",
]
}
+
+group("tests") {
+ deps = [
+ "//mojo/public/js/test:compile_test",
+ ]
+}
diff --git a/chromium/mojo/public/js/bindings_lite.js b/chromium/mojo/public/js/bindings_lite.js
index c7fd65834b2..e16d8db629d 100644
--- a/chromium/mojo/public/js/bindings_lite.js
+++ b/chromium/mojo/public/js/bindings_lite.js
@@ -84,7 +84,7 @@ mojo.internal.align = function(size, alignment) {
*/
mojo.internal.setInt64 = function(dataView, byteOffset, value) {
if (mojo.internal.kHostLittleEndian) {
- dataView.setInt32(
+ dataView.setUint32(
byteOffset, Number(BigInt(value) & BigInt(0xffffffff)),
mojo.internal.kHostLittleEndian);
dataView.setInt32(
@@ -94,7 +94,7 @@ mojo.internal.setInt64 = function(dataView, byteOffset, value) {
dataView.setInt32(
byteOffset, Number(BigInt(value) >> BigInt(32)),
mojo.internal.kHostLittleEndian);
- dataView.setInt32(
+ dataView.setUint32(
byteOffset + 4, Number(BigInt(value) & BigInt(0xffffffff)),
mojo.internal.kHostLittleEndian);
}
@@ -131,10 +131,10 @@ mojo.internal.setUint64 = function(dataView, byteOffset, value) {
mojo.internal.getInt64 = function(dataView, byteOffset) {
let low, high;
if (mojo.internal.kHostLittleEndian) {
- low = dataView.getInt32(byteOffset, mojo.internal.kHostLittleEndian);
+ low = dataView.getUint32(byteOffset, mojo.internal.kHostLittleEndian);
high = dataView.getInt32(byteOffset + 4, mojo.internal.kHostLittleEndian);
} else {
- low = dataView.getInt32(byteOffset + 4, mojo.internal.kHostLittleEndian);
+ low = dataView.getUint32(byteOffset + 4, mojo.internal.kHostLittleEndian);
high = dataView.getInt32(byteOffset, mojo.internal.kHostLittleEndian);
}
const value = (BigInt(high) << BigInt(32)) | BigInt(low);
diff --git a/chromium/mojo/public/js/interface_support.js b/chromium/mojo/public/js/interface_support.js
index 9e36eb1fbb0..77ab0f966c3 100644
--- a/chromium/mojo/public/js/interface_support.js
+++ b/chromium/mojo/public/js/interface_support.js
@@ -257,7 +257,7 @@ mojo.internal.interfaceSupport.InterfaceProxyBase = class {
}
// The pipe has already been closed, so just drop the message.
- if (!this.reader_ || this.reader_.isStopped())
+ if (responseStruct && (!this.reader_ || this.reader_.isStopped()))
return Promise.reject(new Error('The pipe has already been closed.'));
const requestId = this.nextRequestId_++;
@@ -531,6 +531,10 @@ mojo.internal.interfaceSupport.InterfaceTarget = class {
/** @private {mojo.internal.interfaceSupport.ControlMessageHandler} */
this.controlMessageHandler_ = null;
+
+ /** @private {!mojo.internal.interfaceSupport.ConnectionErrorEventRouter} */
+ this.connectionErrorEventRouter_ =
+ new mojo.internal.interfaceSupport.ConnectionErrorEventRouter;
}
/**
@@ -569,6 +573,14 @@ mojo.internal.interfaceSupport.InterfaceTarget = class {
}
/**
+ * @return {!mojo.internal.interfaceSupport.ConnectionErrorEventRouter}
+ * @export
+ */
+ getConnectionErrorEventRouter() {
+ return this.connectionErrorEventRouter_;
+ }
+
+ /**
* @param {!MojoHandle} handle
* @param {!ArrayBuffer} buffer
* @param {!Array<MojoHandle>} handles
@@ -634,6 +646,7 @@ mojo.internal.interfaceSupport.InterfaceTarget = class {
const reader = this.readers_.get(handle);
if (!reader)
return;
+ this.connectionErrorEventRouter_.dispatchErrorEvent();
reader.stopAndCloseHandle();
this.readers_.delete(handle);
}
@@ -679,6 +692,8 @@ mojo.internal.interfaceSupport.HandleReader = class {
}
stopAndCloseHandle() {
+ if (!this.watcher_)
+ return;
this.stop();
this.handle_.close();
}
diff --git a/chromium/mojo/public/js/mojo_bindings_resources.grd b/chromium/mojo/public/js/mojo_bindings_resources.grd
index deddde08110..eb615379ee5 100644
--- a/chromium/mojo/public/js/mojo_bindings_resources.grd
+++ b/chromium/mojo/public/js/mojo_bindings_resources.grd
@@ -13,11 +13,14 @@
<translations />
<release seq="1">
<includes>
- <include name="IDR_MOJO_MOJO_BINDINGS_JS"
- file="${root_gen_dir}/mojo/public/js/mojo_bindings.js"
- use_base_dir="false"
- type="BINDATA"
- compress="gzip" />
+ <!-- All resources included on Android should use the lite bindings. -->
+ <if expr="not is_android">
+ <include name="IDR_MOJO_MOJO_BINDINGS_JS"
+ file="${root_gen_dir}/mojo/public/js/mojo_bindings.js"
+ use_base_dir="false"
+ type="BINDATA"
+ compress="gzip" />
+ </if>
<include name="IDR_MOJO_MOJO_BINDINGS_LITE_JS"
file="${root_gen_dir}/mojo/public/js/mojo_bindings_lite.js"
use_base_dir="false"
diff --git a/chromium/mojo/public/js/test/BUILD.gn b/chromium/mojo/public/js/test/BUILD.gn
new file mode 100644
index 00000000000..8816cc14c29
--- /dev/null
+++ b/chromium/mojo/public/js/test/BUILD.gn
@@ -0,0 +1,46 @@
+# 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.
+
+import("//mojo/public/tools/bindings/mojom.gni")
+import("//third_party/closure_compiler/closure_args.gni")
+import("//third_party/closure_compiler/compile_js.gni")
+
+mojom("test_mojom") {
+ testonly = true
+ sources = [
+ "module_a.test-mojom",
+ "module_b_1.test-mojom",
+ "module_b_2.test-mojom",
+ ]
+}
+
+if (enable_mojom_closure_compile || closure_compile) {
+ js_library("compile_test_sources") {
+ sources = [
+ "compile_test.js",
+ ]
+ deps = [
+ ":test_mojom_js_library_for_compile",
+ ]
+ }
+
+ js_binary("compile_test") {
+ outputs = [
+ "$target_gen_dir/compile_test.js",
+ ]
+ deps = [
+ ":compile_test_sources",
+ ":test_mojom_js_library_for_compile",
+ ]
+ closure_flags = strict_error_checking_closure_args + [
+ "compilation_level=ADVANCED_OPTIMIZATIONS",
+ "language_in=ECMASCRIPT_2017",
+ "language_out=ECMASCRIPT5_STRICT",
+ "generate_exports",
+ ]
+ }
+} else {
+ group("compile_test") {
+ }
+}
diff --git a/chromium/mojo/public/tools/bindings/chromium_bindings_configuration.gni b/chromium/mojo/public/tools/bindings/chromium_bindings_configuration.gni
index 6cd039ea3c8..c2a0f444482 100644
--- a/chromium/mojo/public/tools/bindings/chromium_bindings_configuration.gni
+++ b/chromium/mojo/public/tools/bindings/chromium_bindings_configuration.gni
@@ -13,6 +13,7 @@ _typemap_imports = [
"//chromeos/components/multidevice/mojom/typemaps.gni",
"//chromeos/services/secure_channel/public/mojom/typemaps.gni",
"//components/arc/common/typemaps.gni",
+ "//components/chromeos_camera/common/typemaps.gni",
"//components/sync/mojo/typemaps.gni",
"//components/typemaps.gni",
"//content/common/bluetooth/typemaps.gni",
@@ -48,15 +49,16 @@ _typemap_imports = [
"//third_party/blink/common/typemaps.gni",
"//third_party/blink/public/public_typemaps.gni",
"//ui/accessibility/mojom/typemaps.gni",
- "//ui/base/mojo/typemaps.gni",
"//ui/base/accelerators/mojo/typemaps.gni",
+ "//ui/base/ime/mojo/typemaps.gni",
+ "//ui/base/mojo/typemaps.gni",
"//ui/display/mojo/typemaps.gni",
"//ui/events/devices/mojo/typemaps.gni",
"//ui/events/mojo/typemaps.gni",
"//ui/gfx/typemaps.gni",
"//ui/latency/mojo/typemaps.gni",
- "//ui/ozone/public/interfaces/typemaps.gni",
"//ui/message_center/public/mojo/typemaps.gni",
+ "//ui/ozone/public/interfaces/typemaps.gni",
"//url/mojom/typemaps.gni",
]
diff --git a/chromium/mojo/public/tools/bindings/generate_type_mappings.py b/chromium/mojo/public/tools/bindings/generate_type_mappings.py
index ee55e99404e..d6796afb8b3 100755
--- a/chromium/mojo/public/tools/bindings/generate_type_mappings.py
+++ b/chromium/mojo/public/tools/bindings/generate_type_mappings.py
@@ -149,7 +149,7 @@ def main():
for path in params.dependency:
typemaps.update(ReadTypemap(path))
- WriteFile(json.dumps({'c++': typemaps}, indent=2), params.output)
+ WriteFile(json.dumps({'c++': typemaps}, indent=2).encode(), params.output)
if __name__ == '__main__':
diff --git a/chromium/mojo/public/tools/bindings/generators/cpp_templates/enum_macros.tmpl b/chromium/mojo/public/tools/bindings/generators/cpp_templates/enum_macros.tmpl
index f353ac79a08..1093c7ff5fe 100644
--- a/chromium/mojo/public/tools/bindings/generators/cpp_templates/enum_macros.tmpl
+++ b/chromium/mojo/public/tools/bindings/generators/cpp_templates/enum_macros.tmpl
@@ -2,6 +2,12 @@
Macro for enum definition, and the declaration of associated functions.
---#}
+{%- macro kythe_annotation(name) %}
+{%- if enable_kythe_annotations %}
+// @generated_from: {{name}}
+{%- endif %}
+{%- endmacro %}
+
{%- macro enum_forward(enum) %}
{%- set enum_name = enum|get_name_for_kind(flatten_nested_kind=True) %}
enum class {{enum_name}} : int32_t;
@@ -10,11 +16,15 @@ enum class {{enum_name}} : int32_t;
{%- macro enum_decl(enum, export_attribute) %}
{%- set enum_name = enum|get_name_for_kind(flatten_nested_kind=True) %}
+{%- set full_enum_name = enum|get_full_mojom_name_for_kind() %}
+{{ kythe_annotation(full_enum_name) }}
enum class {{enum_name}} : int32_t {
{%- for field in enum.fields %}
{%- if field.value %}
+ {{ kythe_annotation("%s.%s"|format(full_enum_name, field.name)) }}
{{field.name}} = {{field.value|expression_to_text}},
{%- else %}
+ {{ kythe_annotation("%s.%s"|format(full_enum_name, field.name)) }}
{{field.name}},
{%- endif %}
{%- endfor %}
diff --git a/chromium/mojo/public/tools/bindings/generators/cpp_templates/interface_declaration.tmpl b/chromium/mojo/public/tools/bindings/generators/cpp_templates/interface_declaration.tmpl
index 51c106ed7ff..03343948630 100644
--- a/chromium/mojo/public/tools/bindings/generators/cpp_templates/interface_declaration.tmpl
+++ b/chromium/mojo/public/tools/bindings/generators/cpp_templates/interface_declaration.tmpl
@@ -9,6 +9,9 @@ class {{interface.name}}RequestValidator;
class {{interface.name}}ResponseValidator;
{%- endif %}
+{%- set interface_prefix = "%s.%s"|format(module_prefix, interface.name) %}
+
+{{ kythe_annotation(interface_prefix) }}
class {{export_attribute}} {{interface.name}}
: public {{interface.name}}InterfaceBase {
public:
@@ -38,11 +41,13 @@ class {{export_attribute}} {{interface.name}}
{#--- Enums #}
{%- for enum in interface.enums %}
+ {{ kythe_annotation(enum|get_full_mojom_name_for_kind()) }}
using {{enum.name}} = {{enum|get_name_for_kind(flatten_nested_kind=True)}};
{%- endfor %}
{#--- Constants #}
{%- for constant in interface.constants %}
+ {{ kythe_annotation("%s.%s"|format(interface_prefix, constant.name)) }}
static {{constant|format_constant_declaration(nested=True)}};
{%- endfor %}
@@ -54,11 +59,13 @@ class {{export_attribute}} {{interface.name}}
{%- if method.sync %}
// Sync method. This signature is used by the client side; the service side
// should implement the signature with callback below.
+ {{ kythe_annotation("%s.%s"|format(interface_prefix, method.name)) }}
virtual bool {{method.name}}({{interface_macros.declare_sync_method_params("", method)}});
{%- endif %}
using {{method.name}}Callback = {{interface_macros.declare_callback(method, for_blink)}};
{%- endif %}
+ {{ kythe_annotation("%s.%s"|format(interface_prefix, method.name)) }}
virtual void {{method.name}}({{interface_macros.declare_request_params("", method)}}) = 0;
{%- endfor %}
};
diff --git a/chromium/mojo/public/tools/bindings/generators/cpp_templates/interface_definition.tmpl b/chromium/mojo/public/tools/bindings/generators/cpp_templates/interface_definition.tmpl
index b60b926045f..906eae02b6b 100644
--- a/chromium/mojo/public/tools/bindings/generators/cpp_templates/interface_definition.tmpl
+++ b/chromium/mojo/public/tools/bindings/generators/cpp_templates/interface_definition.tmpl
@@ -431,7 +431,7 @@ bool {{class_name}}StubDispatch::Accept(
{{alloc_params(method.param_struct, "params", "message", desc)|
indent(4)}}
// A null |impl| means no implementation was bound.
- assert(impl);
+ DCHECK(impl);
impl->{{method.name}}({{pass_params(method.parameters)}});
return true;
{%- else %}
@@ -494,7 +494,7 @@ bool {{class_name}}StubDispatch::AcceptWithResponder(
message->has_flag(mojo::Message::kFlagIsSync),
std::move(responder));
// A null |impl| means no implementation was bound.
- assert(impl);
+ DCHECK(impl);
impl->{{method.name}}(
{%- if method.parameters -%}{{pass_params(method.parameters)}}, {% endif -%}std::move(callback));
return true;
diff --git a/chromium/mojo/public/tools/bindings/generators/cpp_templates/module-forward.h.tmpl b/chromium/mojo/public/tools/bindings/generators/cpp_templates/module-forward.h.tmpl
index a14d5112656..63085aaec91 100644
--- a/chromium/mojo/public/tools/bindings/generators/cpp_templates/module-forward.h.tmpl
+++ b/chromium/mojo/public/tools/bindings/generators/cpp_templates/module-forward.h.tmpl
@@ -30,6 +30,12 @@ namespace {{variant}} {
{%- endfor %}
{%- endmacro %}
+{%- macro kythe_annotation(name) %}
+{%- if enable_kythe_annotations %}
+// @generated_from: {{name}}
+{%- endif %}
+{%- endmacro %}
+
#ifndef {{header_guard}}
#define {{header_guard}}
@@ -46,9 +52,6 @@ namespace {{variant}} {
#include "mojo/public/cpp/bindings/pending_remote.h"
#include "mojo/public/cpp/bindings/raw_ptr_impl_ref_traits.h"
#include "mojo/public/cpp/bindings/thread_safe_interface_ptr.h"
-{%- if for_blink %}
-#include "third_party/blink/renderer/platform/mojo/revocable_interface_ptr.h"
-{%- endif %}
{%- endif %}
{% if not disallow_native_types %}
@@ -60,6 +63,12 @@ namespace {{variant}} {
#include "{{export_header}}"
{%- endif %}
+{% if enable_kythe_annotations -%}
+#ifdef KYTHE_IS_RUNNING
+#pragma kythe_inline_metadata "Metadata comment"
+#endif
+{%- endif %}
+
{%- if variant %}
{%- for namespace in namespaces_as_array %}
namespace {{namespace}} {
@@ -95,6 +104,8 @@ using {{enum|get_name_for_kind(flatten_nested_kind=True)}} = mojo::NativeEnum;
{{namespace_begin()}}
+{%- set module_prefix = "%s"|format(namespaces_as_array|join(".")) %}
+
{#- These are non-variant header only. #}
{%- if not variant %}
@@ -133,6 +144,7 @@ using {{enum.name}} = {{enum.name}}; // Alias for definition in the parent name
{#--- Constants #}
{%- for constant in module.constants %}
+{{ kythe_annotation("%s.%s"|format(module_prefix, constant.name)) }}
{{constant|format_constant_declaration}};
{%- endfor %}
@@ -166,9 +178,6 @@ typedef mojo::StructPtr<{{union.name}}> {{union.name}}Ptr;
{% for interface in interfaces %}
class {{interface.name}};
using {{interface.name}}Ptr = mojo::InterfacePtr<{{interface.name}}>;
-{%- if for_blink %}
-using Revocable{{interface.name}}Ptr = ::blink::RevocableInterfacePtr<{{interface.name}}>;
-{%- endif %}
using {{interface.name}}PtrInfo = mojo::InterfacePtrInfo<{{interface.name}}>;
using ThreadSafe{{interface.name}}Ptr =
mojo::ThreadSafeInterfacePtr<{{interface.name}}>;
diff --git a/chromium/mojo/public/tools/bindings/generators/cpp_templates/module-shared-internal.h.tmpl b/chromium/mojo/public/tools/bindings/generators/cpp_templates/module-shared-internal.h.tmpl
index f6ee8a61f3e..200a00029c9 100644
--- a/chromium/mojo/public/tools/bindings/generators/cpp_templates/module-shared-internal.h.tmpl
+++ b/chromium/mojo/public/tools/bindings/generators/cpp_templates/module-shared-internal.h.tmpl
@@ -27,6 +27,12 @@
#include "{{export_header}}"
{%- endif %}
+{% if enable_kythe_annotations -%}
+#ifdef KYTHE_IS_RUNNING
+#pragma kythe_inline_metadata "Metadata comment"
+#endif
+{%- endif %}
+
namespace mojo {
namespace internal {
class ValidationContext;
diff --git a/chromium/mojo/public/tools/bindings/generators/cpp_templates/module-shared.h.tmpl b/chromium/mojo/public/tools/bindings/generators/cpp_templates/module-shared.h.tmpl
index 0c2e6e4492a..994069aa6b7 100644
--- a/chromium/mojo/public/tools/bindings/generators/cpp_templates/module-shared.h.tmpl
+++ b/chromium/mojo/public/tools/bindings/generators/cpp_templates/module-shared.h.tmpl
@@ -69,6 +69,12 @@ namespace {{namespace}} {
#include "{{export_header}}"
{%- endif %}
+{% if enable_kythe_annotations -%}
+#ifdef KYTHE_IS_RUNNING
+#pragma kythe_inline_metadata "Metadata comment"
+#endif
+{%- endif %}
+
{{namespace_begin()}}
{#--- Struct Forward Declarations -#}
@@ -105,8 +111,10 @@ namespace internal {
{{namespace_begin()}}
+{%- set module_prefix = "%s"|format(namespaces_as_array|join(".")) %}
+
{#--- Enums #}
-{%- from "enum_macros.tmpl" import enum_decl%}
+{%- from "enum_macros.tmpl" import enum_decl with context %}
{%- for enum in all_enums %}
{%- if enum|is_native_only_kind %}
using {{enum|get_name_for_kind(flatten_nested_kind=True)}} = mojo::NativeEnum;
diff --git a/chromium/mojo/public/tools/bindings/generators/cpp_templates/module.h.tmpl b/chromium/mojo/public/tools/bindings/generators/cpp_templates/module.h.tmpl
index b4f2a452191..28b8a6f217c 100644
--- a/chromium/mojo/public/tools/bindings/generators/cpp_templates/module.h.tmpl
+++ b/chromium/mojo/public/tools/bindings/generators/cpp_templates/module.h.tmpl
@@ -30,6 +30,12 @@ namespace {{variant}} {
{%- endfor %}
{%- endmacro %}
+{%- macro kythe_annotation(name) %}
+{%- if enable_kythe_annotations %}
+// @generated_from: {{name}}
+{%- endif %}
+{%- endmacro %}
+
#ifndef {{header_guard}}
#define {{header_guard}}
@@ -91,7 +97,6 @@ namespace {{variant}} {
every use of {Inlined}StructPtr. #}
#include "mojo/public/cpp/bindings/lib/wtf_clone_equals_util.h"
#include "mojo/public/cpp/bindings/lib/wtf_hash_util.h"
-#include "third_party/blink/renderer/platform/mojo/revocable_interface_ptr.h"
#include "third_party/blink/renderer/platform/wtf/hash_functions.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
{%- endif %}
@@ -105,9 +110,6 @@ namespace {{variant}} {
#include "mojo/public/cpp/bindings/lib/control_message_handler.h"
#include "mojo/public/cpp/bindings/raw_ptr_impl_ref_traits.h"
#include "mojo/public/cpp/bindings/thread_safe_interface_ptr.h"
-{%- if for_blink %}
-#include "third_party/blink/renderer/platform/mojo/revocable_interface_ptr.h"
-{%- endif %}
{%- endif %}
{% if not disallow_native_types %}
@@ -123,6 +125,12 @@ namespace {{variant}} {
#include "{{export_header}}"
{%- endif %}
+{% if enable_kythe_annotations -%}
+#ifdef KYTHE_IS_RUNNING
+#pragma kythe_inline_metadata "Metadata comment"
+#endif
+{%- endif %}
+
{#--- WTF enum hashing #}
{%- from "enum_macros.tmpl" import enum_hash_blink%}
{%- if for_blink %}
@@ -135,6 +143,8 @@ namespace {{variant}} {
{{namespace_begin()}}
+{%- set module_prefix = "%s"|format(namespaces_as_array|join(".")) %}
+
{#--- Interfaces -#}
{% for interface in interfaces %}
{% include "interface_declaration.tmpl" %}
diff --git a/chromium/mojo/public/tools/bindings/generators/cpp_templates/struct_serialization_declaration.tmpl b/chromium/mojo/public/tools/bindings/generators/cpp_templates/struct_serialization_declaration.tmpl
index 5571e8449f9..5f11278b57b 100644
--- a/chromium/mojo/public/tools/bindings/generators/cpp_templates/struct_serialization_declaration.tmpl
+++ b/chromium/mojo/public/tools/bindings/generators/cpp_templates/struct_serialization_declaration.tmpl
@@ -17,12 +17,10 @@ struct Serializer<{{data_view}}, MaybeConstUserType> {
SerializationContext* context) {
if (CallIsNullIfExists<Traits>(input))
return;
- void* custom_context = CustomContextHelper<Traits>::SetUp(input, context);
{{struct_macros.serialize(
struct, struct.name ~ " struct",
- "CallWithContext(Traits::%s, input, custom_context)", "(*output)",
+ "Traits::%s(input)", "(*output)",
"buffer", "context", True)|indent(2)}}
- CustomContextHelper<Traits>::TearDown(input, custom_context);
}
static bool Deserialize({{data_type}}* input,
diff --git a/chromium/mojo/public/tools/bindings/generators/cpp_templates/union_declaration.tmpl b/chromium/mojo/public/tools/bindings/generators/cpp_templates/union_declaration.tmpl
index e14169a2630..7e61dde2112 100644
--- a/chromium/mojo/public/tools/bindings/generators/cpp_templates/union_declaration.tmpl
+++ b/chromium/mojo/public/tools/bindings/generators/cpp_templates/union_declaration.tmpl
@@ -1,3 +1,9 @@
+{%- macro kythe_annotation(name) %}
+{%- if enable_kythe_annotations %}
+// @generated_from: {{name}}
+{%- endif %}
+{%- endmacro %}
+
{%- set class_name = union.name ~ "_Data" -%}
{%- set enum_name = union.name ~ "_Tag" -%}
{%- import "struct_macros.tmpl" as struct_macros %}
@@ -59,6 +65,7 @@ class {{export_attribute}} {{class_name}} {
enum class {{enum_name}} : uint32_t {
{% for field in union.fields %}
+ {{ kythe_annotation("%s.%s"|format(union|get_full_mojom_name_for_kind(), field.name)) }}
{{field.name|upper}},
{%- endfor %}
};
diff --git a/chromium/mojo/public/tools/bindings/generators/cpp_templates/union_serialization_declaration.tmpl b/chromium/mojo/public/tools/bindings/generators/cpp_templates/union_serialization_declaration.tmpl
index 4e39774b607..3e98edeb514 100644
--- a/chromium/mojo/public/tools/bindings/generators/cpp_templates/union_serialization_declaration.tmpl
+++ b/chromium/mojo/public/tools/bindings/generators/cpp_templates/union_serialization_declaration.tmpl
@@ -18,8 +18,6 @@ struct Serializer<{{data_view}}, MaybeConstUserType> {
writer->data()->set_null();
return;
}
- void* custom_context = CustomContextHelper<Traits>::SetUp(input, context);
-
if (!inlined)
writer->Allocate(buffer);
@@ -28,16 +26,15 @@ struct Serializer<{{data_view}}, MaybeConstUserType> {
// TODO(azani): Handle unknown and objects.
// Set the not-null flag.
result->size = kUnionDataSize;
- result->tag = CallWithContext(Traits::GetTag, input, custom_context);
+ result->tag = Traits::GetTag(input);
switch (result->tag) {
{%- for field in union.fields %}
{%- set name = field.name %}
{%- set kind = field.kind %}
{%- set serializer_type = kind|unmapped_type_for_serializer %}
case {{data_view}}::Tag::{{field.name|upper}}: {
- decltype(CallWithContext(Traits::{{name}}, input, custom_context))
- in_{{name}} = CallWithContext(Traits::{{name}}, input,
- custom_context);
+ decltype(Traits::{{name}}(input))
+ in_{{name}} = Traits::{{name}}(input);
{%- if kind|is_object_kind %}
typename decltype(result->data.f_{{name}})::BaseType::BufferWriter
value_writer;
@@ -88,8 +85,6 @@ struct Serializer<{{data_view}}, MaybeConstUserType> {
}
{%- endfor %}
}
-
- CustomContextHelper<Traits>::TearDown(input, custom_context);
}
static bool Deserialize({{data_type}}* input,
diff --git a/chromium/mojo/public/tools/bindings/generators/cpp_templates/wrapper_class_declaration.tmpl b/chromium/mojo/public/tools/bindings/generators/cpp_templates/wrapper_class_declaration.tmpl
index e03fd0cb3e2..801c01523bd 100644
--- a/chromium/mojo/public/tools/bindings/generators/cpp_templates/wrapper_class_declaration.tmpl
+++ b/chromium/mojo/public/tools/bindings/generators/cpp_templates/wrapper_class_declaration.tmpl
@@ -1,3 +1,6 @@
+{%- set struct_prefix = "%s.%s"|format(module_prefix, struct.name) %}
+
+{{ kythe_annotation(struct_prefix) }}
class {{export_attribute}} {{struct.name}} {
public:
using DataView = {{struct.name}}DataView;
@@ -5,11 +8,13 @@ class {{export_attribute}} {{struct.name}} {
{#--- Enums #}
{%- for enum in struct.enums -%}
+ {{ kythe_annotation(enum|get_full_mojom_name_for_kind()) }}
using {{enum.name}} = {{enum|get_name_for_kind(flatten_nested_kind=True)}};
{%- endfor %}
{#--- Constants #}
{%- for constant in struct.constants %}
+ {{ kythe_annotation("%s.%s"|format(struct_prefix, constant.name)) }}
static {{constant|format_constant_declaration(nested=True)}};
{%- endfor %}
@@ -119,6 +124,7 @@ class {{export_attribute}} {{struct.name}} {
{% for field in struct.fields %}
{%- set type = field.kind|cpp_wrapper_type %}
{%- set name = field.name %}
+ {{ kythe_annotation("%s.%s"|format(struct_prefix, name)) }}
{{type}} {{name}};
{%- endfor %}
diff --git a/chromium/mojo/public/tools/bindings/generators/cpp_templates/wrapper_union_class_declaration.tmpl b/chromium/mojo/public/tools/bindings/generators/cpp_templates/wrapper_union_class_declaration.tmpl
index a0be109b030..40603a7fe53 100644
--- a/chromium/mojo/public/tools/bindings/generators/cpp_templates/wrapper_union_class_declaration.tmpl
+++ b/chromium/mojo/public/tools/bindings/generators/cpp_templates/wrapper_union_class_declaration.tmpl
@@ -1,3 +1,6 @@
+{%- set union_prefix = "%s.%s"|format(module_prefix, union.name) %}
+
+{{ kythe_annotation(union_prefix) }}
class {{export_attribute}} {{union.name}} {
public:
using DataView = {{union.name}}DataView;
@@ -55,8 +58,10 @@ class {{export_attribute}} {{union.name}} {
}
{% for field in union.fields %}
+ {{ kythe_annotation("%s.%s"|format(union_prefix, field.name)) }}
bool is_{{field.name}}() const { return tag_ == Tag::{{field.name|upper}}; }
+ {{ kythe_annotation("%s.%s"|format(union_prefix, field.name)) }}
{{field.kind|cpp_union_getter_return_type}} get_{{field.name}}() const {
DCHECK(tag_ == Tag::{{field.name|upper}});
{%- if field.kind|is_object_kind or
@@ -67,6 +72,7 @@ class {{export_attribute}} {{union.name}} {
{%- endif %}
}
+ {{ kythe_annotation("%s.%s"|format(union_prefix, field.name)) }}
void set_{{field.name}}(
{{field.kind|cpp_wrapper_param_type_new}} {{field.name}});
{%- endfor %}
diff --git a/chromium/mojo/public/tools/bindings/generators/java_templates/enum_definition.tmpl b/chromium/mojo/public/tools/bindings/generators/java_templates/enum_definition.tmpl
index 99859e0e986..c2541994f00 100644
--- a/chromium/mojo/public/tools/bindings/generators/java_templates/enum_definition.tmpl
+++ b/chromium/mojo/public/tools/bindings/generators/java_templates/enum_definition.tmpl
@@ -1,49 +1,45 @@
{%- macro enum_value(enum, field, index) -%}
{%- if field.value -%}
-(int) ({{field.value|expression_to_text('i32')}})
+{{field.value|expression_to_text('i32')}};
{%- elif index == 0 -%}
-0
+{{field.numeric_value}};
{%- else -%}
-{{enum.fields[index - 1]|name}} + 1
+{{field.numeric_value}}; // {{enum.fields[index - 1]|name}} + 1
{%- endif -%}
{%- endmacro -%}
{%- macro enum_def(enum, top_level) -%}
public {{ 'static ' if not top_level }}final class {{enum|name}} {
-
+ private static final boolean IS_EXTENSIBLE = {% if enum.extensible %}true{% else %}false{% endif %};
{% for field in enum.fields %}
- public static final int {{field|name}} = {{enum_value(enum, field, loop.index0)}};
-{% endfor %}
+ public static final int {{field|name}} = {{enum_value(enum, field, loop.index0)}}
+{%- endfor %}
-{%- if enum.min_value is not none %}
- public static final int MIN_VALUE = (int) ({{enum.min_value}});
-{%- endif %}
-{%- if enum.max_value is not none %}
- public static final int MAX_VALUE = (int) ({{enum.max_value}});
-{%- endif %}
+{%- if enum|covers_continuous_range %}
- private static final boolean IS_EXTENSIBLE = {% if enum.extensible %}true{% else %}false{% endif %};
+ public static boolean isKnownValue(int value) {
+ return value >= {{enum.min_value}} && value <= {{enum.max_value}};
+ }
+{%- else %}
public static boolean isKnownValue(int value) {
-{%- if enum.fields %}
+{%- if enum.fields %}
switch (value) {
-{%- for enum_field in enum.fields|groupby('numeric_value') %}
+{%- for enum_field in enum.fields|groupby('numeric_value') %}
case {{enum_field[0]}}:
-{%- endfor %}
+{%- endfor %}
return true;
}
-{%- endif %}
+{%- endif %}
return false;
}
+{%- endif %}
public static void validate(int value) {
- if (IS_EXTENSIBLE || isKnownValue(value))
- return;
-
+ if (IS_EXTENSIBLE || isKnownValue(value)) return;
throw new DeserializationException("Invalid enum value.");
}
private {{enum|name}}() {}
-
}
{%- endmacro -%}
diff --git a/chromium/mojo/public/tools/bindings/generators/js_templates/lite/enum_definition.tmpl b/chromium/mojo/public/tools/bindings/generators/js_templates/lite/enum_definition.tmpl
index b6f1293d96d..affa4d09650 100644
--- a/chromium/mojo/public/tools/bindings/generators/js_templates/lite/enum_definition.tmpl
+++ b/chromium/mojo/public/tools/bindings/generators/js_templates/lite/enum_definition.tmpl
@@ -2,7 +2,10 @@
{# TODO: Less generic enum annotations would be nice. We do it this way because
the bindings generator is still too stupid to generate the right integral
constants directly. #}
+{%- set enum_name = enum|lite_closure_type -%}
+
{% if generate_closure_exports -%}
+goog.provide('{{enum_name}}');
goog.provide('{{enum_spec_parent}}.{{enum.name}}Spec');
{%- endif %}
/**
@@ -15,7 +18,7 @@ goog.provide('{{enum_spec_parent}}.{{enum.name}}Spec');
* @enum {number}
* @export
*/
-{{enum_parent}}.{{enum.name}} = {
+{{enum_name}} = {
{# Set up the enum here, but fill out the values later. #}
{%- for field in enum.fields %}
{{field.name}}: 0,
@@ -31,11 +34,11 @@ goog.provide('{{enum_spec_parent}}.{{enum.name}}Spec');
{# Suppress type checks since we're assigning number into an enum. #}
/** @suppress {checkTypes} */
{%- if field.value %}
-{{enum_parent}}.{{enum.name}}.{{field.name}} = {{field.value|expression_to_text_lite}};
+{{enum_name}}.{{field.name}} = {{field.value|expression_to_text_lite}};
{%- elif loop.first %}
-{{enum_parent}}.{{enum.name}}.{{field.name}} = 0;
+{{enum_name}}.{{field.name}} = 0;
{%- else %}
-{{enum_parent}}.{{enum.name}}.{{field.name}} = {{enum_parent}}.{{enum.name}}.{{enum.fields[loop.index0 - 1].name}} + 1;
+{{enum_name}}.{{field.name}} = {{enum_name}}.{{enum.fields[loop.index0 - 1].name}} + 1;
{%- endif %}
{%- endfor %}
diff --git a/chromium/mojo/public/tools/bindings/generators/js_templates/lite/interface_definition.tmpl b/chromium/mojo/public/tools/bindings/generators/js_templates/lite/interface_definition.tmpl
index 874b97ff4ba..53cce1708a3 100644
--- a/chromium/mojo/public/tools/bindings/generators/js_templates/lite/interface_definition.tmpl
+++ b/chromium/mojo/public/tools/bindings/generators/js_templates/lite/interface_definition.tmpl
@@ -17,6 +17,14 @@
*/
{% endmacro %}
+{% if generate_closure_exports -%}
+goog.provide('{{module.namespace}}.{{interface.name}}');
+goog.provide('{{module.namespace}}.{{interface.name}}CallbackRouter');
+goog.provide('{{module.namespace}}.{{interface.name}}Interface');
+goog.provide('{{module.namespace}}.{{interface.name}}Proxy');
+goog.provide('{{module.namespace}}.{{interface.name}}Request');
+{% endif %}
+
/** @export */
{{module.namespace}}.{{interface.name}}Request = class {
/** @param {!MojoHandle} handle */
@@ -120,6 +128,8 @@
{%- endif %}
impl.{{method.name}}.bind(impl));
{%- endfor %}
+ /** @public {!mojo.internal.interfaceSupport.ConnectionErrorEventRouter} */
+ this.onConnectionError = this.target_.getConnectionErrorEventRouter();
}
/**
@@ -165,7 +175,7 @@
{#--- Enums #}
{% from "lite/enum_definition.tmpl" import enum_def with context %}
{%- for enum in interface.enums %}
-{{ enum_def("%s.%sSpec"|format(module.namespace, interface.name),
+{{ enum_def("%s.%s"|format(module.namespace, interface.name),
"%s.%s"|format(module.namespace, interface.name),
enum) }}
{%- endfor %}
@@ -193,7 +203,7 @@
{%- set interface_message_id =
interface.mojom_name ~ "_" ~ method.mojom_name %}
/**
- * @export {!mojo.internal.interfaceSupport.InterfaceCallbackTarget}
+ * @public {!mojo.internal.interfaceSupport.InterfaceCallbackTarget}
*/
this.{{method.name}} =
new mojo.internal.interfaceSupport.InterfaceCallbackTarget(
@@ -210,6 +220,8 @@
this.{{method.name}}.createTargetHandler(false /* expectsResponse */));
{%- endif %}
{%- endfor %}
+ /** @public {!mojo.internal.interfaceSupport.ConnectionErrorEventRouter} */
+ this.onConnectionError = this.target_.getConnectionErrorEventRouter();
}
/**
diff --git a/chromium/mojo/public/tools/bindings/generators/js_templates/lite/mojom-lite.js.tmpl b/chromium/mojo/public/tools/bindings/generators/js_templates/lite/mojom-lite.js.tmpl
index b9b2e32e0aa..a02c7a32077 100644
--- a/chromium/mojo/public/tools/bindings/generators/js_templates/lite/mojom-lite.js.tmpl
+++ b/chromium/mojo/public/tools/bindings/generators/js_templates/lite/mojom-lite.js.tmpl
@@ -8,8 +8,11 @@ goog.require('mojo.internal');
{%- if interfaces %}
goog.require('mojo.internal.interfaceSupport');
{%- endif %}
-{% endif %}
-
+{% for kind in module.imported_kinds.values() %}
+goog.require('{{kind|lite_js_import_name}}');
+{%- endfor %}
+{% else %}
mojo.internal.exportModule('{{module.namespace}}');
+{% endif %}
{% include "lite/module_definition.tmpl" %}
diff --git a/chromium/mojo/public/tools/bindings/generators/js_templates/lite/struct_definition.tmpl b/chromium/mojo/public/tools/bindings/generators/js_templates/lite/struct_definition.tmpl
index fa6bd2e71b3..98b6f1fb33d 100644
--- a/chromium/mojo/public/tools/bindings/generators/js_templates/lite/struct_definition.tmpl
+++ b/chromium/mojo/public/tools/bindings/generators/js_templates/lite/struct_definition.tmpl
@@ -3,7 +3,7 @@
* @const { {{constant.kind|lite_closure_type_with_nullability}} }
* @export
*/
-{{module.namespace}}.{{struct.name}}.{{constant.name}} =
+{{module.namespace}}.{{struct.name}}_{{constant.name}} =
{{constant.value|expression_to_text_lite}};
{% endfor %}
diff --git a/chromium/mojo/public/tools/bindings/generators/js_templates/lite/union_definition.tmpl b/chromium/mojo/public/tools/bindings/generators/js_templates/lite/union_definition.tmpl
index ee637012d2b..2174ecd89aa 100644
--- a/chromium/mojo/public/tools/bindings/generators/js_templates/lite/union_definition.tmpl
+++ b/chromium/mojo/public/tools/bindings/generators/js_templates/lite/union_definition.tmpl
@@ -1,3 +1,6 @@
+{% if generate_closure_exports -%}
+goog.provide('{{module.namespace}}.{{union.name}}');
+{% endif %}
mojo.internal.Union(
{{module.namespace}}.{{union.name}}Spec.$, '{{union.name}}',
diff --git a/chromium/mojo/public/tools/bindings/generators/mojom_cpp_generator.py b/chromium/mojo/public/tools/bindings/generators/mojom_cpp_generator.py
index 2e6e20a78c9..b8070e6f8bd 100644
--- a/chromium/mojo/public/tools/bindings/generators/mojom_cpp_generator.py
+++ b/chromium/mojo/public/tools/bindings/generators/mojom_cpp_generator.py
@@ -268,7 +268,7 @@ class Generator(generator.Generator):
for typename in
self.module.structs + all_enums + self.module.unions)
headers = set()
- for typename, typemap in self.typemap.iteritems():
+ for typename, typemap in self.typemap.items():
if typename in types:
headers.update(typemap.get("public_headers", []))
return sorted(headers)
@@ -294,6 +294,7 @@ class Generator(generator.Generator):
"all_enums": all_enums,
"disallow_interfaces": self.disallow_interfaces,
"disallow_native_types": self.disallow_native_types,
+ "enable_kythe_annotations": self.enable_kythe_annotations,
"enums": self.module.enums,
"export_attribute": self.export_attribute,
"export_header": self.export_header,
@@ -337,6 +338,7 @@ class Generator(generator.Generator):
"format_constant_declaration": self._FormatConstantDeclaration,
"get_container_validate_params_ctor_args":
self._GetContainerValidateParamsCtorArgs,
+ "get_full_mojom_name_for_kind": self._GetFullMojomNameForKind,
"get_name_for_kind": self._GetNameForKind,
"get_pad": pack.GetPad,
"get_qualified_name_for_kind": self._GetQualifiedNameForKind,
diff --git a/chromium/mojo/public/tools/bindings/generators/mojom_java_generator.py b/chromium/mojo/public/tools/bindings/generators/mojom_java_generator.py
index 8097af35ffc..7b7fc8375c0 100644
--- a/chromium/mojo/public/tools/bindings/generators/mojom_java_generator.py
+++ b/chromium/mojo/public/tools/bindings/generators/mojom_java_generator.py
@@ -339,7 +339,6 @@ def ExpressionToText(context, token, kind_spec=''):
if isinstance(token, mojom.NamedValue):
return _TranslateNamedValue(token)
if kind_spec.startswith('i') or kind_spec.startswith('u'):
- # Add Long suffix to all integer literals.
number = ast.literal_eval(token.lstrip('+ '))
if not isinstance(number, (int, long)):
raise ValueError('got unexpected type %r for int literal %r' % (
@@ -348,6 +347,8 @@ def ExpressionToText(context, token, kind_spec=''):
# equivalent signed long.
if number >= 2 ** 63:
number -= 2 ** 64
+ if number < 2 ** 31 and number >= -2 ** 31:
+ return '%d' % number
return '%dL' % number
if isinstance(token, mojom.BuiltinValue):
if token.value == 'double.INFINITY':
@@ -421,6 +422,14 @@ def TempDir():
finally:
shutil.rmtree(dirname)
+def EnumCoversContinuousRange(kind):
+ if not kind.fields:
+ return False
+ number_of_unique_keys = len(set(map(lambda field: field.numeric_value, kind.fields)))
+ if kind.max_value - kind.min_value + 1 != number_of_unique_keys:
+ return False
+ return True
+
class Generator(generator.Generator):
def _GetJinjaExports(self):
return {
@@ -436,6 +445,7 @@ class Generator(generator.Generator):
'array_expected_length': GetArrayExpectedLength,
'array': GetArrayKind,
'constant_value': ConstantValue,
+ 'covers_continuous_range': EnumCoversContinuousRange,
'decode_method': DecodeMethod,
'default_value': DefaultValue,
'encode_method': EncodeMethod,
diff --git a/chromium/mojo/public/tools/bindings/generators/mojom_js_generator.py b/chromium/mojo/public/tools/bindings/generators/mojom_js_generator.py
index bc8bc63a39f..4b53f3ec90d 100644
--- a/chromium/mojo/public/tools/bindings/generators/mojom_js_generator.py
+++ b/chromium/mojo/public/tools/bindings/generators/mojom_js_generator.py
@@ -301,10 +301,12 @@ class Generator(generator.Generator):
"js_type": self._JavaScriptType,
"lite_default_value": self._LiteJavaScriptDefaultValue,
"lite_js_type": self._LiteJavaScriptType,
+ "lite_js_import_name": self._LiteJavaScriptImportName,
"method_passes_associated_kinds": mojom.MethodPassesAssociatedKinds,
"namespace_declarations": self._NamespaceDeclarations,
"closure_type_with_nullability": self._ClosureTypeWithNullability,
"lite_closure_param_type": self._LiteClosureParamType,
+ "lite_closure_type": self._LiteClosureType,
"lite_closure_type_with_nullability":
self._LiteClosureTypeWithNullability,
"lite_closure_field_type": self._LiteClosureFieldType,
@@ -441,8 +443,13 @@ class Generator(generator.Generator):
name.append(named_kind.module.namespace)
if named_kind.parent_kind:
name.append(named_kind.parent_kind.name)
- name.append("" + named_kind.name)
- name = ".".join(name)
+
+ if mojom.IsEnumKind(kind) and named_kind.parent_kind:
+ name = ".".join(name)
+ name += "_" + named_kind.name
+ else:
+ name.append("" + named_kind.name)
+ name = ".".join(name)
if (mojom.IsStructKind(kind) or mojom.IsUnionKind(kind) or
mojom.IsEnumKind(kind)):
@@ -532,7 +539,10 @@ class Generator(generator.Generator):
if named_kind.module:
name.append(named_kind.module.namespace)
if named_kind.parent_kind:
- name.append(named_kind.parent_kind.name + "Spec")
+ parent_name = named_kind.parent_kind.name
+ if mojom.IsStructKind(named_kind.parent_kind):
+ parent_name += "Spec"
+ name.append(parent_name)
name.append(named_kind.name)
name = ".".join(name)
@@ -552,6 +562,15 @@ class Generator(generator.Generator):
return name
+ def _LiteJavaScriptImportName(self, kind):
+ name = []
+ if kind.parent_kind:
+ name.append(self._LiteJavaScriptImportName(kind.parent_kind))
+ elif kind.module:
+ name.append(kind.module.namespace)
+ name.append(kind.name)
+ return '.'.join(name)
+
def _JavaScriptDefaultValue(self, field):
if field.default:
if mojom.IsStructKind(field.kind):
diff --git a/chromium/mojo/public/tools/bindings/mojom.gni b/chromium/mojo/public/tools/bindings/mojom.gni
index ac896c8dea2..0c2e3780458 100644
--- a/chromium/mojo/public/tools/bindings/mojom.gni
+++ b/chromium/mojo/public/tools/bindings/mojom.gni
@@ -40,6 +40,10 @@ declare_args() {
# where compilation is supported, any mojom target "foo" will also have a
# corresponding "foo_js_library_for_compile" target generated.
enable_mojom_closure_compile = closure_compile && optimize_webui
+
+ # Enable adding annotations to generated C++ headers that are used for
+ # cross-references in CodeSearch.
+ enable_kythe_annotations = false
}
# NOTE: We would like to avoid scrambling message IDs where it doesn't add
@@ -679,6 +683,10 @@ template("mojom") {
"base/component_export.h",
]
}
+
+ if (enable_kythe_annotations) {
+ args += [ "--enable_kythe_annotations" ]
+ }
}
} else {
group(generator_cpp_message_ids_target_name) {
@@ -910,6 +918,10 @@ template("mojom") {
invoker.support_lazy_serialization) {
args += [ "--support_lazy_serialization" ]
}
+
+ if (enable_kythe_annotations) {
+ args += [ "--enable_kythe_annotations" ]
+ }
}
}
diff --git a/chromium/mojo/public/tools/bindings/mojom_bindings_generator.py b/chromium/mojo/public/tools/bindings/mojom_bindings_generator.py
index d847f4b1a4d..72f23d86fa9 100755
--- a/chromium/mojo/public/tools/bindings/mojom_bindings_generator.py
+++ b/chromium/mojo/public/tools/bindings/mojom_bindings_generator.py
@@ -5,9 +5,15 @@
"""The frontend for the Mojo bindings system."""
+from __future__ import print_function
import argparse
-import cPickle
+
+try:
+ import cPickle as pickle
+except ImportError:
+ import pickle
+
import hashlib
import importlib
import json
@@ -62,7 +68,7 @@ def LoadGenerators(generators_string):
for generator_name in [s.strip() for s in generators_string.split(",")]:
language = generator_name.lower()
if language not in _BUILTIN_GENERATORS:
- print "Unknown generator name %s" % generator_name
+ print("Unknown generator name %s" % generator_name)
sys.exit(1)
generator_module = importlib.import_module(
"generators.%s" % _BUILTIN_GENERATORS[language])
@@ -158,7 +164,7 @@ class MojomProcessor(object):
for filename in typemaps:
with open(filename) as f:
typemaps = json.loads("".join(filter(no_comments, f.readlines())))
- for language, typemap in typemaps.iteritems():
+ for language, typemap in typemaps.items():
language_map = self._typemap.get(language, {})
language_map.update(typemap)
self._typemap[language] = language_map
@@ -170,8 +176,8 @@ class MojomProcessor(object):
return self._processed_files[rel_filename.path]
if rel_filename.path in imported_filename_stack:
- print "%s: Error: Circular dependency" % rel_filename.path + \
- MakeImportStackMessage(imported_filename_stack + [rel_filename.path])
+ print("%s: Error: Circular dependency" % rel_filename.path + \
+ MakeImportStackMessage(imported_filename_stack + [rel_filename.path]))
sys.exit(1)
tree = _UnpickleAST(_FindPicklePath(rel_filename, args.gen_directories +
@@ -202,7 +208,7 @@ class MojomProcessor(object):
if self._should_generate(rel_filename.path):
AddComputedData(module)
- for language, generator_module in generator_modules.iteritems():
+ for language, generator_module in generator_modules.items():
generator = generator_module.Generator(
module, args.output_dir, typemap=self._typemap.get(language, {}),
variant=args.variant, bytecode_path=args.bytecode_path,
@@ -215,7 +221,8 @@ class MojomProcessor(object):
disallow_native_types=args.disallow_native_types,
disallow_interfaces=args.disallow_interfaces,
generate_message_ids=args.generate_message_ids,
- generate_fuzzing=args.generate_fuzzing)
+ generate_fuzzing=args.generate_fuzzing,
+ enable_kythe_annotations=args.enable_kythe_annotations)
filtered_args = []
if hasattr(generator_module, 'GENERATOR_PREFIX'):
prefix = '--' + generator_module.GENERATOR_PREFIX + '_'
@@ -278,32 +285,33 @@ def _PickleAST(ast, output_file):
fileutil.EnsureDirectoryExists(full_dir)
try:
- WriteFile(cPickle.dumps(ast), output_file)
- except (IOError, cPickle.PicklingError) as e:
- print "%s: Error: %s" % (output_file, str(e))
+ WriteFile(pickle.dumps(ast), output_file)
+ except (IOError, pickle.PicklingError) as e:
+ print("%s: Error: %s" % (output_file, str(e)))
sys.exit(1)
def _UnpickleAST(input_file):
- try:
- with open(input_file, "rb") as f:
- return cPickle.load(f)
- except (IOError, cPickle.UnpicklingError) as e:
- print "%s: Error: %s" % (input_file, str(e))
- sys.exit(1)
+ try:
+ with open(input_file, "rb") as f:
+ return pickle.load(f)
+ except (IOError, pickle.UnpicklingError) as e:
+ print("%s: Error: %s" % (input_file, str(e)))
+ sys.exit(1)
+
def _ParseFile(args, rel_filename):
try:
with open(rel_filename.path) as f:
source = f.read()
except IOError as e:
- print "%s: Error: %s" % (rel_filename.path, e.strerror)
+ print("%s: Error: %s" % (rel_filename.path, e.strerror))
sys.exit(1)
try:
tree = Parse(source, rel_filename.path)
RemoveDisabledDefinitions(tree, args.enabled_features)
except Error as e:
- print "%s: Error: %s" % (rel_filename.path, str(e))
+ print("%s: Error: %s" % (rel_filename.path, str(e)))
sys.exit(1)
_PickleAST(tree, _GetPicklePath(rel_filename, args.output_dir))
@@ -371,16 +379,16 @@ def _VerifyImportDeps(args, __):
full_target_name = "//" + target_prefix_without_gen_dir.rsplit(
"/", 1)[0] + ":" + target_name
- print ">>> File \"%s\"" % (filename)
- print ">>> from target \"%s\"" % (full_target_name)
- print ">>> is missing dependencies for the following imports:\n%s" % \
- list(mojom_imports.difference(sources))
+ print(">>> File \"%s\"" % filename)
+ print(">>> from target \"%s\"" % full_target_name)
+ print(">>> is missing dependencies for the following imports:\n%s" % list(
+ mojom_imports.difference(sources)))
sys.exit(1)
source_filename, _ = os.path.splitext(rel_path.relative_path())
output_file = source_filename + '.v'
output_file_path = os.path.join(args.gen_dir, output_file)
- WriteFile("", output_file_path)
+ WriteFile(b"", output_file_path)
return 0
@@ -497,6 +505,11 @@ def main():
"--generate_fuzzing",
action="store_true",
help="Generates additional bindings for fuzzing in JS.")
+ generate_parser.add_argument(
+ "--enable_kythe_annotations",
+ action="store_true",
+ help="Adds annotations for kythe metadata generation.")
+
generate_parser.set_defaults(func=_Generate)
precompile_parser = subparsers.add_parser("precompile",
diff --git a/chromium/mojo/public/tools/bindings/pylib/mojom/generate/generator.py b/chromium/mojo/public/tools/bindings/pylib/mojom/generate/generator.py
index 045800f8930..709dd22cfcd 100644
--- a/chromium/mojo/public/tools/bindings/pylib/mojom/generate/generator.py
+++ b/chromium/mojo/public/tools/bindings/pylib/mojom/generate/generator.py
@@ -4,13 +4,15 @@
"""Code shared by the various language-specific code generators."""
+from __future__ import print_function
+
from functools import partial
import os.path
import re
-import module as mojom
+import mojom.generate.module as mojom
import mojom.fileutil as fileutil
-import pack
+import mojom.generate.pack as pack
def ExpectedArraySize(kind):
@@ -165,7 +167,7 @@ class Generator(object):
export_header=None, generate_non_variant_code=False,
support_lazy_serialization=False, disallow_native_types=False,
disallow_interfaces=False, generate_message_ids=False,
- generate_fuzzing=False):
+ generate_fuzzing=False, enable_kythe_annotations=False):
self.module = module
self.output_dir = output_dir
self.typemap = typemap or {}
@@ -181,10 +183,11 @@ class Generator(object):
self.disallow_interfaces = disallow_interfaces
self.generate_message_ids = generate_message_ids
self.generate_fuzzing = generate_fuzzing
+ self.enable_kythe_annotations = enable_kythe_annotations
def Write(self, contents, filename):
if self.output_dir is None:
- print contents
+ print(contents)
return
full_path = os.path.join(self.output_dir, filename)
WriteFile(contents, full_path)
diff --git a/chromium/mojo/public/tools/bindings/pylib/mojom/generate/module.py b/chromium/mojo/public/tools/bindings/pylib/mojom/generate/module.py
index 79264a0d23a..18a410159cb 100644
--- a/chromium/mojo/public/tools/bindings/pylib/mojom/generate/module.py
+++ b/chromium/mojo/public/tools/bindings/pylib/mojom/generate/module.py
@@ -740,6 +740,7 @@ class Module(object):
self.kinds = {}
self.attributes = attributes
self.imports = []
+ self.imported_kinds = {}
def __repr__(self):
# Gives us a decent __repr__ for modules.
diff --git a/chromium/mojo/public/tools/bindings/pylib/mojom/generate/pack.py b/chromium/mojo/public/tools/bindings/pylib/mojom/generate/pack.py
index 9187364d1e2..b30949e3f8c 100644
--- a/chromium/mojo/public/tools/bindings/pylib/mojom/generate/pack.py
+++ b/chromium/mojo/public/tools/bindings/pylib/mojom/generate/pack.py
@@ -2,7 +2,7 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
-import module as mojom
+import mojom.generate.module as mojom
# This module provides a mechanism for determining the packed order and offsets
# of a mojom.Struct.
@@ -165,7 +165,7 @@ class PackedStruct(object):
# Then find first slot that each field will fit.
for src_field in src_fields[1:]:
last_field = dst_fields[0]
- for i in xrange(1, len(dst_fields)):
+ for i in range(1, len(dst_fields)):
next_field = dst_fields[i]
offset, bit = GetFieldOffset(src_field, last_field)
if offset + src_field.size <= next_field.offset:
@@ -190,16 +190,16 @@ class ByteInfo(object):
def GetByteLayout(packed_struct):
total_payload_size = GetPayloadSizeUpToField(
packed_struct.packed_fields[-1] if packed_struct.packed_fields else None)
- bytes = [ByteInfo() for i in xrange(total_payload_size)]
+ bytes = [ByteInfo() for i in range(total_payload_size)]
limit_of_previous_field = 0
for packed_field in packed_struct.packed_fields:
- for i in xrange(limit_of_previous_field, packed_field.offset):
+ for i in range(limit_of_previous_field, packed_field.offset):
bytes[i].is_padding = True
bytes[packed_field.offset].packed_fields.append(packed_field)
limit_of_previous_field = packed_field.offset + packed_field.size
- for i in xrange(limit_of_previous_field, len(bytes)):
+ for i in range(limit_of_previous_field, len(bytes)):
bytes[i].is_padding = True
for byte in bytes:
diff --git a/chromium/mojo/public/tools/bindings/pylib/mojom/generate/template_expander.py b/chromium/mojo/public/tools/bindings/pylib/mojom/generate/template_expander.py
index 653a2dfc74d..948ba3d30c7 100644
--- a/chromium/mojo/public/tools/bindings/pylib/mojom/generate/template_expander.py
+++ b/chromium/mojo/public/tools/bindings/pylib/mojom/generate/template_expander.py
@@ -35,7 +35,7 @@ def UseJinja(path_to_template, **kwargs):
def GeneratorInternal(*args, **kwargs2):
parameters = generator(*args, **kwargs2)
return ApplyTemplate(args[0], path_to_template, parameters, **kwargs)
- GeneratorInternal.func_name = generator.func_name
+ GeneratorInternal.__name__ = generator.__name__
return GeneratorInternal
return RealDecorator
diff --git a/chromium/mojo/public/tools/bindings/pylib/mojom/generate/translate.py b/chromium/mojo/public/tools/bindings/pylib/mojom/generate/translate.py
index cdc9d0e7c42..3d3d53d99f7 100644
--- a/chromium/mojo/public/tools/bindings/pylib/mojom/generate/translate.py
+++ b/chromium/mojo/public/tools/bindings/pylib/mojom/generate/translate.py
@@ -10,10 +10,11 @@ representation of a mojom file. When called it's assumed that all imports have
already been parsed and converted to ASTs before.
"""
+import itertools
import os
import re
-import module as mojom
+import mojom.generate.module as mojom
from mojom.parse import ast
def _DuplicateName(values):
@@ -128,7 +129,7 @@ def _LookupKind(kinds, spec, scope):
to the location where the type is referenced."""
if spec.startswith('x:'):
mojom_name = spec[2:]
- for i in xrange(len(scope), -1, -1):
+ for i in range(len(scope), -1, -1):
test_spec = 'x:'
if i > 0:
test_spec += '.'.join(scope[:i]) + '.'
@@ -147,7 +148,7 @@ def _LookupValue(values, mojom_name, scope, kind):
# enum name.
if isinstance(kind, mojom.Enum) and '.' not in mojom_name:
mojom_name = '%s.%s' % (kind.spec.split(':', 1)[1], mojom_name)
- for i in reversed(xrange(len(scope) + 1)):
+ for i in reversed(range(len(scope) + 1)):
test_spec = '.'.join(scope[:i])
if test_spec:
test_spec += '.'
@@ -554,6 +555,61 @@ def _Constant(module, parsed_const, parent_kind):
module.values[value.GetSpec()] = value
return constant
+
+def _CollectReferencedKinds(module, all_defined_kinds):
+ """
+ Takes a {mojom.Module} object and a list of all defined kinds within that
+ module, and enumerates the complete dict of user-defined mojom types
+ (as {mojom.Kind} objects) referenced by the module's own defined kinds (i.e.
+ as types of struct or union or interface parameters. The returned dict is
+ keyed by kind spec.
+ """
+
+ def extract_referenced_user_kinds(kind):
+ if mojom.IsArrayKind(kind):
+ return extract_referenced_user_kinds(kind.kind)
+ if mojom.IsMapKind(kind):
+ return (extract_referenced_user_kinds(kind.key_kind) +
+ extract_referenced_user_kinds(kind.value_kind))
+ if mojom.IsInterfaceRequestKind(kind) or mojom.IsAssociatedKind(kind):
+ return [kind.kind]
+ if mojom.IsStructKind(kind):
+ return [kind]
+ if (mojom.IsInterfaceKind(kind) or mojom.IsEnumKind(kind) or
+ mojom.IsUnionKind(kind)):
+ return [kind]
+ return []
+
+ def sanitize_kind(kind):
+ """Removes nullability from a kind"""
+ if kind.spec.startswith('?'):
+ return _Kind(module.kinds, kind.spec[1:],
+ (module.mojom_namespace, ''))
+ return kind
+
+ referenced_user_kinds = {}
+ for defined_kind in all_defined_kinds:
+ if mojom.IsStructKind(defined_kind) or mojom.IsUnionKind(defined_kind):
+ for field in defined_kind.fields:
+ for referenced_kind in extract_referenced_user_kinds(field.kind):
+ sanitized_kind = sanitize_kind(referenced_kind)
+ referenced_user_kinds[sanitized_kind.spec] = sanitized_kind
+
+ # Also scan for references in parameter lists
+ for interface in module.interfaces:
+ for method in interface.methods:
+ for param in itertools.chain(method.parameters or [],
+ method.response_parameters or []):
+ if (mojom.IsStructKind(param.kind) or mojom.IsUnionKind(param.kind) or
+ mojom.IsEnumKind(param.kind) or
+ mojom.IsAnyInterfaceKind(param.kind)):
+ for referenced_kind in extract_referenced_user_kinds(param.kind):
+ sanitized_kind = sanitize_kind(referenced_kind)
+ referenced_user_kinds[sanitized_kind.spec] = sanitized_kind
+
+ return referenced_user_kinds
+
+
def _Module(tree, path, imports):
"""
Args:
@@ -604,18 +660,35 @@ def _Module(tree, path, imports):
# Second pass expands fields and methods. This allows fields and parameters
# to refer to kinds defined anywhere in the mojom.
+ all_defined_kinds = {}
for struct in module.structs:
struct.fields = map(lambda field:
_StructField(module, field, struct), struct.fields_data)
del struct.fields_data
+ all_defined_kinds[struct.spec] = struct
+ for enum in struct.enums:
+ all_defined_kinds[enum.spec] = enum
for union in module.unions:
union.fields = map(lambda field:
_UnionField(module, field, union), union.fields_data)
del union.fields_data
+ all_defined_kinds[union.spec] = union
for interface in module.interfaces:
interface.methods = map(lambda method:
_Method(module, method, interface), interface.methods_data)
del interface.methods_data
+ all_defined_kinds[interface.spec] = interface
+ for enum in interface.enums:
+ all_defined_kinds[enum.spec] = enum
+ for enum in module.enums:
+ all_defined_kinds[enum.spec] = enum
+
+ all_referenced_kinds = _CollectReferencedKinds(module,
+ all_defined_kinds.values())
+ imported_kind_specs = set(all_referenced_kinds.keys()).difference(
+ set(all_defined_kinds.keys()))
+ module.imported_kinds = dict((spec, all_referenced_kinds[spec])
+ for spec in imported_kind_specs)
return module
diff --git a/chromium/mojo/public/tools/bindings/pylib/mojom/parse/ast.py b/chromium/mojo/public/tools/bindings/pylib/mojom/parse/ast.py
index e9d78449868..32e4d117db4 100644
--- a/chromium/mojo/public/tools/bindings/pylib/mojom/parse/ast.py
+++ b/chromium/mojo/public/tools/bindings/pylib/mojom/parse/ast.py
@@ -18,7 +18,7 @@ class NodeBase(object):
self.lineno = lineno
def __eq__(self, other):
- return type(self) == type(other)
+ return isinstance(self, other)
# Make != the inverse of ==. (Subclasses shouldn't have to override this.)
def __ne__(self, other):
diff --git a/chromium/mojo/public/tools/fuzzers/DEPS b/chromium/mojo/public/tools/fuzzers/DEPS
deleted file mode 100644
index 9243dcd6900..00000000000
--- a/chromium/mojo/public/tools/fuzzers/DEPS
+++ /dev/null
@@ -1,3 +0,0 @@
-include_rules = [
- "+mojo/core/embedder",
-]
diff --git a/chromium/mojo/public/tools/fuzzers/OWNERS b/chromium/mojo/public/tools/fuzzers/OWNERS
deleted file mode 100644
index 08850f42120..00000000000
--- a/chromium/mojo/public/tools/fuzzers/OWNERS
+++ /dev/null
@@ -1,2 +0,0 @@
-per-file *.mojom=set noparent
-per-file *.mojom=file://ipc/SECURITY_OWNERS
diff --git a/chromium/mojo/public/tools/fuzzers/fuzz_impl.cc b/chromium/mojo/public/tools/fuzzers/fuzz_impl.cc
deleted file mode 100644
index d3b10128bd1..00000000000
--- a/chromium/mojo/public/tools/fuzzers/fuzz_impl.cc
+++ /dev/null
@@ -1,45 +0,0 @@
-// Copyright 2017 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 <utility>
-
-#include "mojo/public/tools/fuzzers/fuzz.mojom.h"
-#include "mojo/public/tools/fuzzers/fuzz_impl.h"
-
-FuzzImpl::FuzzImpl(fuzz::mojom::FuzzInterfaceRequest request)
- : binding_(this, std::move(request)) {}
-
-FuzzImpl::~FuzzImpl() {}
-
-void FuzzImpl::FuzzBasic() {}
-
-void FuzzImpl::FuzzBasicResp(FuzzBasicRespCallback callback) {
- std::move(callback).Run();
-}
-
-void FuzzImpl::FuzzBasicSyncResp(FuzzBasicSyncRespCallback callback) {
- std::move(callback).Run();
-}
-
-void FuzzImpl::FuzzArgs(fuzz::mojom::FuzzStructPtr a,
- fuzz::mojom::FuzzStructPtr b) {}
-
-void FuzzImpl::FuzzArgsResp(fuzz::mojom::FuzzStructPtr a,
- fuzz::mojom::FuzzStructPtr b,
- FuzzArgsRespCallback callback) {
- std::move(callback).Run();
-}
-
-void FuzzImpl::FuzzArgsSyncResp(fuzz::mojom::FuzzStructPtr a,
- fuzz::mojom::FuzzStructPtr b,
- FuzzArgsSyncRespCallback callback) {
- std::move(callback).Run();
-}
-
-void FuzzImpl::FuzzAssociated(
- fuzz::mojom::FuzzDummyInterfaceAssociatedRequest req) {
- associated_bindings_.AddBinding(this, std::move(req));
-}
-
-void FuzzImpl::Ping() {}
diff --git a/chromium/mojo/public/tools/fuzzers/fuzz_impl.h b/chromium/mojo/public/tools/fuzzers/fuzz_impl.h
deleted file mode 100644
index d63a7073e2e..00000000000
--- a/chromium/mojo/public/tools/fuzzers/fuzz_impl.h
+++ /dev/null
@@ -1,45 +0,0 @@
-// Copyright 2017 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_FUZZ_IMPL_H_
-#define MOJO_PUBLIC_TOOLS_FUZZERS_FUZZ_IMPL_H_
-
-#include "mojo/public/cpp/bindings/associated_binding_set.h"
-#include "mojo/public/cpp/bindings/binding.h"
-#include "mojo/public/tools/fuzzers/fuzz.mojom.h"
-
-class FuzzImpl : public fuzz::mojom::FuzzInterface,
- public fuzz::mojom::FuzzDummyInterface {
- public:
- explicit FuzzImpl(fuzz::mojom::FuzzInterfaceRequest request);
- ~FuzzImpl() override;
-
- // fuzz::mojom::FuzzInterface:
- void FuzzBasic() override;
- void FuzzBasicResp(FuzzBasicRespCallback callback) override;
- void FuzzBasicSyncResp(FuzzBasicSyncRespCallback callback) override;
- void FuzzArgs(fuzz::mojom::FuzzStructPtr a,
- fuzz::mojom::FuzzStructPtr b) override;
-
- void FuzzArgsResp(fuzz::mojom::FuzzStructPtr a,
- fuzz::mojom::FuzzStructPtr b,
- FuzzArgsRespCallback callback) override;
- void FuzzArgsSyncResp(fuzz::mojom::FuzzStructPtr a,
- fuzz::mojom::FuzzStructPtr b,
- FuzzArgsSyncRespCallback callback) override;
-
- void FuzzAssociated(
- fuzz::mojom::FuzzDummyInterfaceAssociatedRequest req) override;
-
- // fuzz::mojom::FuzzDummyInterface:
- void Ping() override;
-
- /* Expose the binding to the fuzz harness. */
- mojo::Binding<FuzzInterface> binding_;
-
- private:
- mojo::AssociatedBindingSet<FuzzDummyInterface> associated_bindings_;
-};
-
-#endif // MOJO_PUBLIC_TOOLS_FUZZERS_FUZZ_IMPL_H_
diff --git a/chromium/mojo/public/tools/fuzzers/message_corpus/message_0.mojomsg b/chromium/mojo/public/tools/fuzzers/message_corpus/message_0.mojomsg
deleted file mode 100644
index 945b63c4723..00000000000
--- a/chromium/mojo/public/tools/fuzzers/message_corpus/message_0.mojomsg
+++ /dev/null
Binary files differ
diff --git a/chromium/mojo/public/tools/fuzzers/message_corpus/message_1.mojomsg b/chromium/mojo/public/tools/fuzzers/message_corpus/message_1.mojomsg
deleted file mode 100644
index 41715c8239e..00000000000
--- a/chromium/mojo/public/tools/fuzzers/message_corpus/message_1.mojomsg
+++ /dev/null
Binary files differ
diff --git a/chromium/mojo/public/tools/fuzzers/message_corpus/message_10.mojomsg b/chromium/mojo/public/tools/fuzzers/message_corpus/message_10.mojomsg
deleted file mode 100644
index c19d5c752e9..00000000000
--- a/chromium/mojo/public/tools/fuzzers/message_corpus/message_10.mojomsg
+++ /dev/null
Binary files differ
diff --git a/chromium/mojo/public/tools/fuzzers/message_corpus/message_11.mojomsg b/chromium/mojo/public/tools/fuzzers/message_corpus/message_11.mojomsg
deleted file mode 100644
index 61ba9898037..00000000000
--- a/chromium/mojo/public/tools/fuzzers/message_corpus/message_11.mojomsg
+++ /dev/null
Binary files differ
diff --git a/chromium/mojo/public/tools/fuzzers/message_corpus/message_2.mojomsg b/chromium/mojo/public/tools/fuzzers/message_corpus/message_2.mojomsg
deleted file mode 100644
index 7b5b3028888..00000000000
--- a/chromium/mojo/public/tools/fuzzers/message_corpus/message_2.mojomsg
+++ /dev/null
Binary files differ
diff --git a/chromium/mojo/public/tools/fuzzers/message_corpus/message_3.mojomsg b/chromium/mojo/public/tools/fuzzers/message_corpus/message_3.mojomsg
deleted file mode 100644
index d0503715fd2..00000000000
--- a/chromium/mojo/public/tools/fuzzers/message_corpus/message_3.mojomsg
+++ /dev/null
Binary files differ
diff --git a/chromium/mojo/public/tools/fuzzers/message_corpus/message_4.mojomsg b/chromium/mojo/public/tools/fuzzers/message_corpus/message_4.mojomsg
deleted file mode 100644
index 380c391bbcf..00000000000
--- a/chromium/mojo/public/tools/fuzzers/message_corpus/message_4.mojomsg
+++ /dev/null
Binary files differ
diff --git a/chromium/mojo/public/tools/fuzzers/message_corpus/message_5.mojomsg b/chromium/mojo/public/tools/fuzzers/message_corpus/message_5.mojomsg
deleted file mode 100644
index 1bf4b452b73..00000000000
--- a/chromium/mojo/public/tools/fuzzers/message_corpus/message_5.mojomsg
+++ /dev/null
Binary files differ
diff --git a/chromium/mojo/public/tools/fuzzers/message_corpus/message_6.mojomsg b/chromium/mojo/public/tools/fuzzers/message_corpus/message_6.mojomsg
deleted file mode 100644
index 8cffad65f78..00000000000
--- a/chromium/mojo/public/tools/fuzzers/message_corpus/message_6.mojomsg
+++ /dev/null
Binary files differ
diff --git a/chromium/mojo/public/tools/fuzzers/message_corpus/message_7.mojomsg b/chromium/mojo/public/tools/fuzzers/message_corpus/message_7.mojomsg
deleted file mode 100644
index aeff3d60248..00000000000
--- a/chromium/mojo/public/tools/fuzzers/message_corpus/message_7.mojomsg
+++ /dev/null
Binary files differ
diff --git a/chromium/mojo/public/tools/fuzzers/message_corpus/message_8.mojomsg b/chromium/mojo/public/tools/fuzzers/message_corpus/message_8.mojomsg
deleted file mode 100644
index 019f9e656e9..00000000000
--- a/chromium/mojo/public/tools/fuzzers/message_corpus/message_8.mojomsg
+++ /dev/null
Binary files differ
diff --git a/chromium/mojo/public/tools/fuzzers/message_corpus/message_9.mojomsg b/chromium/mojo/public/tools/fuzzers/message_corpus/message_9.mojomsg
deleted file mode 100644
index 61049cf149e..00000000000
--- a/chromium/mojo/public/tools/fuzzers/message_corpus/message_9.mojomsg
+++ /dev/null
Binary files differ
diff --git a/chromium/mojo/public/tools/fuzzers/mojo_fuzzer.proto b/chromium/mojo/public/tools/fuzzers/mojo_fuzzer.proto
deleted file mode 100644
index fb17871151f..00000000000
--- a/chromium/mojo/public/tools/fuzzers/mojo_fuzzer.proto
+++ /dev/null
@@ -1,7 +0,0 @@
-syntax = "proto2";
-
-package mojo_proto_fuzzer;
-
-message MojoFuzzerMessages {
- repeated bytes messages = 1;
-} \ No newline at end of file
diff --git a/chromium/mojo/public/tools/fuzzers/mojo_fuzzer_message_dump.cc b/chromium/mojo/public/tools/fuzzers/mojo_fuzzer_message_dump.cc
deleted file mode 100644
index 3cc657cf04c..00000000000
--- a/chromium/mojo/public/tools/fuzzers/mojo_fuzzer_message_dump.cc
+++ /dev/null
@@ -1,268 +0,0 @@
-// Copyright 2017 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 <stddef.h>
-#include <stdint.h>
-
-#include "base/bind.h"
-#include "base/containers/flat_map.h"
-#include "base/files/file.h"
-#include "base/message_loop/message_loop.h"
-#include "base/run_loop.h"
-#include "base/strings/string_number_conversions.h"
-#include "base/task/task_scheduler/task_scheduler.h"
-#include "mojo/core/embedder/embedder.h"
-#include "mojo/public/tools/fuzzers/fuzz.mojom.h"
-#include "mojo/public/tools/fuzzers/fuzz_impl.h"
-
-/* Environment for the executable. Initializes the mojo EDK and sets up a
- * TaskScheduler, because Mojo messages must be sent and processed from
- * TaskRunners. */
-struct Environment {
- Environment() : message_loop() {
- base::TaskScheduler::CreateAndStartWithDefaultParams(
- "MojoFuzzerMessageDumpProcess");
- mojo::core::Init();
- }
-
- /* Message loop to send messages on. */
- base::MessageLoop message_loop;
-
- /* Impl to be created. Stored in environment to keep it alive after
- * DumpMessages returns. */
- std::unique_ptr<FuzzImpl> impl;
-};
-
-Environment* env = new Environment();
-
-/* MessageReceiver which dumps raw message bytes to disk in the provided
- * directory. */
-class MessageDumper : public mojo::MessageReceiver {
- public:
- explicit MessageDumper(std::string directory)
- : directory_(directory), count_(0) {}
-
- bool Accept(mojo::Message* message) override {
- base::FilePath path = directory_.Append(FILE_PATH_LITERAL("message_") +
- base::NumberToString(count_++) +
- FILE_PATH_LITERAL(".mojomsg"));
-
- base::File file(path,
- base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_WRITE);
- if (!file.IsValid()) {
- LOG(ERROR) << "Failed to create mojo message file: " << path.value();
- return false;
- }
-
- size_t size = message->data_num_bytes();
- const char* data = reinterpret_cast<const char*>(message->data());
- int ret = file.WriteAtCurrentPos(data, size);
- if (ret != static_cast<int>(size)) {
- LOG(ERROR) << "Failed to write " << size << " bytes.";
- return false;
- }
- return true;
- }
-
- base::FilePath directory_;
- int count_;
-};
-
-/* Returns a FuzzUnion with fuzz_bool initialized. */
-auto GetBoolFuzzUnion() {
- fuzz::mojom::FuzzUnionPtr union_bool = fuzz::mojom::FuzzUnion::New();
- union_bool->set_fuzz_bool(true);
- return union_bool;
-}
-
-/* Returns a FuzzUnion with fuzz_struct_map initialized. Takes in a
- * FuzzDummyStructPtr to use within the fuzz_struct_map value. */
-auto GetStructMapFuzzUnion(fuzz::mojom::FuzzDummyStructPtr in) {
- fuzz::mojom::FuzzUnionPtr union_struct_map = fuzz::mojom::FuzzUnion::New();
- base::flat_map<std::string, fuzz::mojom::FuzzDummyStructPtr> struct_map;
- struct_map["fuzz"] = std::move(in);
- union_struct_map->set_fuzz_struct_map(std::move(struct_map));
- return union_struct_map;
-}
-
-/* Returns a FuzzUnion with fuzz_complex initialized. Takes in a FuzzUnionPtr
- * to use within the fuzz_complex value. */
-auto GetComplexFuzzUnion(fuzz::mojom::FuzzUnionPtr in) {
- std::remove_reference<decltype(in->get_fuzz_complex())>::type complex_map;
- std::remove_reference<decltype(complex_map.value()[0])>::type outer;
- std::remove_reference<decltype(
- outer[fuzz::mojom::FuzzEnum::FUZZ_VALUE0])>::type inner;
- std::remove_reference<decltype(inner['z'])>::type center;
-
- center.emplace();
- center.value().push_back(std::move(in));
- inner['z'] = std::move(center);
- outer[fuzz::mojom::FuzzEnum::FUZZ_VALUE0] = std::move(inner);
- complex_map.emplace();
- complex_map.value().push_back(std::move(outer));
-
- fuzz::mojom::FuzzUnionPtr union_complex = fuzz::mojom::FuzzUnion::New();
- union_complex->set_fuzz_complex(std::move(complex_map));
- return union_complex;
-}
-
-/* Returns a populated value for FuzzStruct->fuzz_primitive_array. */
-auto GetFuzzStructPrimitiveArrayValue() {
- decltype(fuzz::mojom::FuzzStruct::fuzz_primitive_array) primitive_array;
- primitive_array = {'f', 'u', 'z', 'z'};
- return primitive_array;
-}
-
-/* Returns a populated value for FuzzStruct->fuzz_primitive_map. */
-auto GetFuzzStructPrimitiveMapValue() {
- decltype(fuzz::mojom::FuzzStruct::fuzz_primitive_map) primitive_map;
- primitive_map["fuzz"] = 'z';
- return primitive_map;
-}
-
-/* Returns a populated value for FuzzStruct->fuzz_array_map. */
-auto GetFuzzStructArrayMapValue() {
- decltype(fuzz::mojom::FuzzStruct::fuzz_array_map) array_map;
- array_map["fuzz"] = {"fuzz1", "fuzz2"};
- return array_map;
-}
-
-/* Returns a populated value for FuzzStruct->fuzz_union_map. Takes in a
- * FuzzUnionPtr to use within the fuzz_union_map value.*/
-auto GetFuzzStructUnionMapValue(fuzz::mojom::FuzzUnionPtr in) {
- decltype(fuzz::mojom::FuzzStruct::fuzz_union_map) union_map;
- union_map[fuzz::mojom::FuzzEnum::FUZZ_VALUE1] = std::move(in);
- return union_map;
-}
-
-/* Returns a populated value for FuzzStruct->fuzz_union_array. Takes in a
- * FuzzUnionPtr to use within the fuzz_union_array value.*/
-auto GetFuzzStructUnionArrayValue(fuzz::mojom::FuzzUnionPtr in) {
- decltype(fuzz::mojom::FuzzStruct::fuzz_union_array) union_array;
- union_array.push_back(std::move(in));
- return union_array;
-}
-
-/* Returns a populated value for FuzzStruct->fuzz_struct_array. Takes in a
- * FuzzStructPtr to use within the fuzz_struct_array value. */
-auto GetFuzzStructStructArrayValue(fuzz::mojom::FuzzStructPtr in) {
- decltype(fuzz::mojom::FuzzStruct::fuzz_struct_array) struct_array;
- struct_array.push_back(std::move(in));
- return struct_array;
-}
-
-/* Returns a populated value for FuzzStruct->fuzz_nullable_array. */
-auto GetFuzzStructNullableArrayValue() {
- decltype(fuzz::mojom::FuzzStruct::fuzz_nullable_array) nullable_array;
- return nullable_array;
-}
-
-/* Returns a populated value for FuzzStruct->fuzz_complex. */
-auto GetFuzzStructComplexValue() {
- decltype(fuzz::mojom::FuzzStruct::fuzz_complex) complex_map;
- std::remove_reference<decltype(complex_map.value()[0])>::type outer;
- std::remove_reference<decltype(
- outer[fuzz::mojom::FuzzEnum::FUZZ_VALUE0])>::type inner;
- std::remove_reference<decltype(inner['z'])>::type center;
-
- center.emplace();
- center.value().push_back(fuzz::mojom::FuzzStruct::New());
- inner['z'] = std::move(center);
- outer[fuzz::mojom::FuzzEnum::FUZZ_VALUE0] = std::move(inner);
- complex_map.emplace();
- complex_map.value().push_back(std::move(outer));
- return complex_map;
-}
-
-/* Returns a FuzzStruct with its fields populated. */
-fuzz::mojom::FuzzStructPtr GetPopulatedFuzzStruct() {
- /* Make some populated Unions. */
- auto union_bool = GetBoolFuzzUnion();
- auto union_struct_map =
- GetStructMapFuzzUnion(fuzz::mojom::FuzzDummyStruct::New());
- auto union_complex = GetComplexFuzzUnion(std::move(union_bool));
-
- /* Prepare the nontrivial fields for the struct. */
- auto fuzz_primitive_array = GetFuzzStructPrimitiveArrayValue();
- auto fuzz_primitive_map = GetFuzzStructPrimitiveMapValue();
- auto fuzz_array_map = GetFuzzStructArrayMapValue();
- auto fuzz_union_map = GetFuzzStructUnionMapValue(std::move(union_struct_map));
- auto fuzz_union_array =
- GetFuzzStructUnionArrayValue(std::move(union_complex));
- auto fuzz_struct_array =
- GetFuzzStructStructArrayValue(fuzz::mojom::FuzzStruct::New());
- auto fuzz_nullable_array = GetFuzzStructNullableArrayValue();
- auto fuzz_complex = GetFuzzStructComplexValue();
-
- /* Make a populated struct and return it. */
- return fuzz::mojom::FuzzStruct::New(
- true, /* fuzz_bool */
- -1, /* fuzz_int8 */
- 1, /* fuzz_uint8 */
- -(1 << 8), /* fuzz_int16 */
- 1 << 8, /* fuzz_uint16 */
- -(1 << 16), /* fuzz_int32 */
- 1 << 16, /* fuzz_uint32 */
- -((int64_t)1 << 32), /* fuzz_int64 */
- (uint64_t)1 << 32, /* fuzz_uint64 */
- 1.0, /* fuzz_float */
- 1.0, /* fuzz_double */
- "fuzz", /* fuzz_string */
- std::move(fuzz_primitive_array), /* fuzz_primitive_array */
- std::move(fuzz_primitive_map), /* fuzz_primitive_map */
- std::move(fuzz_array_map), /* fuzz_array_map */
- std::move(fuzz_union_map), /* fuzz_union_map */
- std::move(fuzz_union_array), /* fuzz_union_array */
- std::move(fuzz_struct_array), /* fuzz_struct_array */
- std::move(fuzz_nullable_array), /* fuzz_nullable_array */
- std::move(fuzz_complex)); /* fuzz_complex */
-}
-
-/* Callback used for messages with responses. Does nothing. */
-void FuzzCallback() {}
-
-/* Invokes each method in the FuzzInterface and dumps the messages to the
- * supplied directory. */
-void DumpMessages(std::string output_directory) {
- fuzz::mojom::FuzzInterfacePtr fuzz;
- fuzz::mojom::FuzzDummyInterfaceAssociatedPtr dummy;
-
- /* Create the impl and add a MessageDumper to the filter chain. */
- env->impl = std::make_unique<FuzzImpl>(MakeRequest(&fuzz));
- env->impl->binding_.RouterForTesting()->AddIncomingMessageFilter(
- std::make_unique<MessageDumper>(output_directory));
-
- /* Call methods in various ways to generate interesting messages. */
- fuzz->FuzzBasic();
- fuzz->FuzzBasicResp(base::Bind(FuzzCallback));
- fuzz->FuzzBasicSyncResp();
- fuzz->FuzzArgs(fuzz::mojom::FuzzStruct::New(),
- fuzz::mojom::FuzzStructPtr(nullptr));
- fuzz->FuzzArgs(fuzz::mojom::FuzzStruct::New(), GetPopulatedFuzzStruct());
- fuzz->FuzzArgsResp(fuzz::mojom::FuzzStruct::New(), GetPopulatedFuzzStruct(),
- base::Bind(FuzzCallback));
- fuzz->FuzzArgsResp(fuzz::mojom::FuzzStruct::New(), GetPopulatedFuzzStruct(),
- base::Bind(FuzzCallback));
- fuzz->FuzzArgsSyncResp(fuzz::mojom::FuzzStruct::New(),
- GetPopulatedFuzzStruct(), base::Bind(FuzzCallback));
- fuzz->FuzzArgsSyncResp(fuzz::mojom::FuzzStruct::New(),
- GetPopulatedFuzzStruct(), base::Bind(FuzzCallback));
- fuzz->FuzzAssociated(MakeRequest(&dummy));
- dummy->Ping();
-}
-
-int main(int argc, char** argv) {
- if (argc < 2) {
- printf("Usage: %s [output_directory]\n", argv[0]);
- exit(1);
- }
- std::string output_directory(argv[1]);
-
- /* Dump the messages from a MessageLoop, and wait for it to finish. */
- env->message_loop.task_runner()->PostTask(
- FROM_HERE, base::BindOnce(&DumpMessages, output_directory));
- base::RunLoop().RunUntilIdle();
-
- return 0;
-}
diff --git a/chromium/mojo/public/tools/fuzzers/mojo_parse_message_fuzzer.cc b/chromium/mojo/public/tools/fuzzers/mojo_parse_message_fuzzer.cc
deleted file mode 100644
index 28ff521a4ee..00000000000
--- a/chromium/mojo/public/tools/fuzzers/mojo_parse_message_fuzzer.cc
+++ /dev/null
@@ -1,62 +0,0 @@
-// Copyright 2017 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 "base/bind.h"
-#include "base/message_loop/message_loop.h"
-#include "base/run_loop.h"
-#include "base/task/task_scheduler/task_scheduler.h"
-#include "mojo/core/embedder/embedder.h"
-#include "mojo/public/cpp/bindings/binding.h"
-#include "mojo/public/tools/fuzzers/fuzz_impl.h"
-
-void FuzzMessage(const uint8_t* data, size_t size, base::RunLoop* run) {
- fuzz::mojom::FuzzInterfacePtr fuzz;
- auto impl = std::make_unique<FuzzImpl>(MakeRequest(&fuzz));
- auto router = impl->binding_.RouterForTesting();
-
- /* Create a mojo message with the appropriate payload size. */
- mojo::Message message(0, 0, size, 0, nullptr);
- if (message.data_num_bytes() < size) {
- message.payload_buffer()->Allocate(size - message.data_num_bytes());
- }
-
- /* Set the raw message data. */
- memcpy(message.mutable_data(), data, size);
-
- /* Run the message through header validation, payload validation, and
- * dispatch to the impl. */
- router->SimulateReceivingMessageForTesting(&message);
-
- /* Allow the harness function to return now. */
- run->Quit();
-}
-
-/* Environment for the fuzzer. Initializes the mojo EDK and sets up a
- * TaskScheduler, because Mojo messages must be sent and processed from
- * TaskRunners. */
-struct Environment {
- Environment() : message_loop(base::MessageLoop::TYPE_UI) {
- base::TaskScheduler::CreateAndStartWithDefaultParams(
- "MojoParseMessageFuzzerProcess");
- mojo::core::Init();
- }
-
- /* Message loop to send and handle messages on. */
- base::MessageLoop message_loop;
-
- /* Suppress mojo validation failure logs. */
- mojo::internal::ScopedSuppressValidationErrorLoggingForTests log_suppression;
-};
-
-// Entry point for LibFuzzer.
-extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
- static Environment* env = new Environment();
- /* Pass the data along to run on a MessageLoop, and wait for it to finish. */
- base::RunLoop run;
- env->message_loop.task_runner()->PostTask(
- FROM_HERE, base::BindOnce(&FuzzMessage, data, size, &run));
- run.Run();
-
- return 0;
-}
diff --git a/chromium/mojo/public/tools/fuzzers/mojo_parse_message_proto_corpus/07775ad8fdb79599024caefbe7889501dfee9e06 b/chromium/mojo/public/tools/fuzzers/mojo_parse_message_proto_corpus/07775ad8fdb79599024caefbe7889501dfee9e06
deleted file mode 100644
index f1932a62de8..00000000000
--- a/chromium/mojo/public/tools/fuzzers/mojo_parse_message_proto_corpus/07775ad8fdb79599024caefbe7889501dfee9e06
+++ /dev/null
@@ -1 +0,0 @@
-messages: "\060\000\000\000\002\000\000\000\000\000\000\000\006\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\020\000\000\000\000\000\000\000\030\000\000\000\000\000\000\000\020\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\014\000\000\000\001\000\000\000\001\000\000\200\000\000\000\000"
diff --git a/chromium/mojo/public/tools/fuzzers/mojo_parse_message_proto_corpus/2ce2f91669a46921ebf4e47679c86dd2bf5b1496 b/chromium/mojo/public/tools/fuzzers/mojo_parse_message_proto_corpus/2ce2f91669a46921ebf4e47679c86dd2bf5b1496
deleted file mode 100644
index 52bae3dad43..00000000000
--- a/chromium/mojo/public/tools/fuzzers/mojo_parse_message_proto_corpus/2ce2f91669a46921ebf4e47679c86dd2bf5b1496
+++ /dev/null
@@ -1 +0,0 @@
-messages: "\030\000\000\000\000\000\000\000\001\000\000\200\000\000\000\000\000\000\000\000\000\000\000\000\010\000\000\000\000\000\000\000"
diff --git a/chromium/mojo/public/tools/fuzzers/mojo_parse_message_proto_corpus/32a65dcd84debde03d51f8b8ace2cdcc87461d34 b/chromium/mojo/public/tools/fuzzers/mojo_parse_message_proto_corpus/32a65dcd84debde03d51f8b8ace2cdcc87461d34
deleted file mode 100644
index 9cbd5621d55..00000000000
--- a/chromium/mojo/public/tools/fuzzers/mojo_parse_message_proto_corpus/32a65dcd84debde03d51f8b8ace2cdcc87461d34
+++ /dev/null
@@ -1 +0,0 @@
-messages: "\030\000\000\000\000\000\000\000\000\000\000\000\003\000\000\000\000\000\000\000\000\000\000\000\030\000\000\000\000\000\000\000\020\000\000\000\000\000\000\000\040\001\000\000\000\000\000\000\200\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\110\000\000\000\000\000\000\000\110\000\000\000\000\000\000\000\110\000\000\000\000\000\000\000\150\000\000\000\000\000\000\000\210\000\000\000\000\000\000\000\250\000\000\000\000\000\000\000\250\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\010\000\000\000\000\000\000\000\010\000\000\000\000\000\000\000\030\000\000\000\000\000\000\000\020\000\000\000\000\000\000\000\020\000\000\000\000\000\000\000\010\000\000\000\000\000\000\000\010\000\000\000\000\000\000\000\030\000\000\000\000\000\000\000\020\000\000\000\000\000\000\000\020\000\000\000\000\000\000\000\010\000\000\000\000\000\000\000\010\000\000\000\000\000\000\000\030\000\000\000\000\000\000\000\020\000\000\000\000\000\000\000\020\000\000\000\000\000\000\000\010\000\000\000\000\000\000\000\010\000\000\000\000\000\000\000\010\000\000\000\000\000\000\000\010\000\000\000\000\000\000\000\200\000\000\000\000\000\000\000\001\377\001\000\000\377\000\001\000\000\377\377\000\000\001\000\000\000\000\000\377\377\377\377\000\000\000\000\001\000\000\000\000\000\200\077\000\000\000\000\000\000\000\000\000\000\360\077\110\000\000\000\000\000\000\000\120\000\000\000\000\000\000\000\130\000\000\000\000\000\000\000\230\000\000\000\000\000\000\000\020\001\000\000\000\000\000\000\240\001\000\000\000\000\000\000\110\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\140\003\000\000\000\000\000\000\014\000\000\000\004\000\000\000\146\165\172\172\000\000\000\000\014\000\000\000\004\000\000\000\146\165\172\172\000\000\000\000\030\000\000\000\000\000\000\000\020\000\000\000\000\000\000\000\050\000\000\000\000\000\000\000\020\000\000\000\001\000\000\000\010\000\000\000\000\000\000\000\014\000\000\000\004\000\000\000\146\165\172\172\000\000\000\000\011\000\000\000\001\000\000\000\172\000\000\000\000\000\000\000\030\000\000\000\000\000\000\000\020\000\000\000\000\000\000\000\050\000\000\000\000\000\000\000\020\000\000\000\001\000\000\000\010\000\000\000\000\000\000\000\014\000\000\000\004\000\000\000\146\165\172\172\000\000\000\000\020\000\000\000\001\000\000\000\010\000\000\000\000\000\000\000\030\000\000\000\002\000\000\000\020\000\000\000\000\000\000\000\030\000\000\000\000\000\000\000\015\000\000\000\005\000\000\000\146\165\172\172\061\000\000\000\015\000\000\000\005\000\000\000\146\165\172\172\062\000\000\000\030\000\000\000\000\000\000\000\020\000\000\000\000\000\000\000\030\000\000\000\000\000\000\000\014\000\000\000\001\000\000\000\001\000\000\000\000\000\000\000\030\000\000\000\001\000\000\000\020\000\000\000\020\000\000\000\010\000\000\000\000\000\000\000\030\000\000\000\000\000\000\000\020\000\000\000\000\000\000\000\050\000\000\000\000\000\000\000\020\000\000\000\001\000\000\000\010\000\000\000\000\000\000\000\014\000\000\000\004\000\000\000\146\165\172\172\000\000\000\000\020\000\000\000\001\000\000\000\010\000\000\000\000\000\000\000\020\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\030\000\000\000\001\000\000\000\020\000\000\000\022\000\000\000\010\000\000\000\000\000\000\000\020\000\000\000\001\000\000\000\010\000\000\000\000\000\000\000\030\000\000\000\000\000\000\000\020\000\000\000\000\000\000\000\030\000\000\000\000\000\000\000\014\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\020\000\000\000\001\000\000\000\010\000\000\000\000\000\000\000\030\000\000\000\000\000\000\000\020\000\000\000\000\000\000\000\030\000\000\000\000\000\000\000\011\000\000\000\001\000\000\000\172\000\000\000\000\000\000\000\020\000\000\000\001\000\000\000\010\000\000\000\000\000\000\000\030\000\000\000\001\000\000\000\020\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\020\000\000\000\001\000\000\000\010\000\000\000\000\000\000\000\200\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\110\000\000\000\000\000\000\000\110\000\000\000\000\000\000\000\110\000\000\000\000\000\000\000\150\000\000\000\000\000\000\000\210\000\000\000\000\000\000\000\250\000\000\000\000\000\000\000\250\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\010\000\000\000\000\000\000\000\010\000\000\000\000\000\000\000\030\000\000\000\000\000\000\000\020\000\000\000\000\000\000\000\020\000\000\000\000\000\000\000\010\000\000\000\000\000\000\000\010\000\000\000\000\000\000\000\030\000\000\000\000\000\000\000\020\000\000\000\000\000\000\000\020\000\000\000\000\000\000\000\010\000\000\000\000\000\000\000\010\000\000\000\000\000\000\000\030\000\000\000\000\000\000\000\020\000\000\000\000\000\000\000\020\000\000\000\000\000\000\000\010\000\000\000\000\000\000\000\010\000\000\000\000\000\000\000\010\000\000\000\000\000\000\000\010\000\000\000\000\000\000\000\020\000\000\000\001\000\000\000\010\000\000\000\000\000\000\000\030\000\000\000\000\000\000\000\020\000\000\000\000\000\000\000\030\000\000\000\000\000\000\000\014\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\020\000\000\000\001\000\000\000\010\000\000\000\000\000\000\000\030\000\000\000\000\000\000\000\020\000\000\000\000\000\000\000\030\000\000\000\000\000\000\000\011\000\000\000\001\000\000\000\172\000\000\000\000\000\000\000\020\000\000\000\001\000\000\000\010\000\000\000\000\000\000\000\020\000\000\000\001\000\000\000\010\000\000\000\000\000\000\000\200\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\110\000\000\000\000\000\000\000\110\000\000\000\000\000\000\000\110\000\000\000\000\000\000\000\150\000\000\000\000\000\000\000\210\000\000\000\000\000\000\000\250\000\000\000\000\000\000\000\250\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\010\000\000\000\000\000\000\000\010\000\000\000\000\000\000\000\030\000\000\000\000\000\000\000\020\000\000\000\000\000\000\000\020\000\000\000\000\000\000\000\010\000\000\000\000\000\000\000\010\000\000\000\000\000\000\000\030\000\000\000\000\000\000\000\020\000\000\000\000\000\000\000\020\000\000\000\000\000\000\000\010\000\000\000\000\000\000\000\010\000\000\000\000\000\000\000\030\000\000\000\000\000\000\000\020\000\000\000\000\000\000\000\020\000\000\000\000\000\000\000\010\000\000\000\000\000\000\000\010\000\000\000\000\000\000\000\010\000\000\000\000\000\000\000\010\000\000\000\000\000\000\000"
diff --git a/chromium/mojo/public/tools/fuzzers/mojo_parse_message_proto_corpus/7cbf9144ec3980eb121eedc679ebc56a3ddd22a6 b/chromium/mojo/public/tools/fuzzers/mojo_parse_message_proto_corpus/7cbf9144ec3980eb121eedc679ebc56a3ddd22a6
deleted file mode 100644
index fb4a52b1980..00000000000
--- a/chromium/mojo/public/tools/fuzzers/mojo_parse_message_proto_corpus/7cbf9144ec3980eb121eedc679ebc56a3ddd22a6
+++ /dev/null
@@ -1 +0,0 @@
-messages: "\040\000\000\000\001\000\000\000\000\000\000\000\005\000\000\000\001\000\000\000\000\000\000\000\006\000\000\000\000\000\000\000\030\000\000\000\000\000\000\000\020\000\000\000\000\000\000\000\040\001\000\000\000\000\000\000\200\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\110\000\000\000\000\000\000\000\110\000\000\000\000\000\000\000\110\000\000\000\000\000\000\000\150\000\000\000\000\000\000\000\210\000\000\000\000\000\000\000\250\000\000\000\000\000\000\000\250\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\010\000\000\000\000\000\000\000\010\000\000\000\000\000\000\000\030\000\000\000\000\000\000\000\020\000\000\000\000\000\000\000\020\000\000\000\000\000\000\000\010\000\000\000\000\000\000\000\010\000\000\000\000\000\000\000\030\000\000\000\000\000\000\000\020\000\000\000\000\000\000\000\020\000\000\000\000\000\000\000\010\000\000\000\000\000\000\000\010\000\000\000\000\000\000\000\030\000\000\000\000\000\000\000\020\000\000\000\000\000\000\000\020\000\000\000\000\000\000\000\010\000\000\000\000\000\000\000\010\000\000\000\000\000\000\000\010\000\000\000\000\000\000\000\010\000\000\000\000\000\000\000\200\000\000\000\000\000\000\000\001\377\001\000\000\377\000\001\000\000\377\377\000\000\001\000\000\000\000\000\377\377\377\377\000\000\000\000\001\000\000\000\000\000\200\077\000\000\000\000\000\000\000\000\000\000\360\077\110\000\000\000\000\000\000\000\120\000\000\000\000\000\000\000\130\000\000\000\000\000\000\000\230\000\000\000\000\000\000\000\020\001\000\000\000\000\000\000\240\001\000\000\000\000\000\000\110\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\140\003\000\000\000\000\000\000\014\000\000\000\004\000\000\000\146\165\172\172\000\000\000\000\014\000\000\000\004\000\000\000\146\165\172\172\000\000\000\000\030\000\000\000\000\000\000\000\020\000\000\000\000\000\000\000\050\000\000\000\000\000\000\000\020\000\000\000\001\000\000\000\010\000\000\000\000\000\000\000\014\000\000\000\004\000\000\000\146\165\172\172\000\000\000\000\011\000\000\000\001\000\000\000\172\000\000\000\000\000\000\000\030\000\000\000\000\000\000\000\020\000\000\000\000\000\000\000\050\000\000\000\000\000\000\000\020\000\000\000\001\000\000\000\010\000\000\000\000\000\000\000\014\000\000\000\004\000\000\000\146\165\172\172\000\000\000\000\020\000\000\000\001\000\000\000\010\000\000\000\000\000\000\000\030\000\000\000\002\000\000\000\020\000\000\000\000\000\000\000\030\000\000\000\000\000\000\000\015\000\000\000\005\000\000\000\146\165\172\172\061\000\000\000\015\000\000\000\005\000\000\000\146\165\172\172\062\000\000\000\030\000\000\000\000\000\000\000\020\000\000\000\000\000\000\000\030\000\000\000\000\000\000\000\014\000\000\000\001\000\000\000\001\000\000\000\000\000\000\000\030\000\000\000\001\000\000\000\020\000\000\000\020\000\000\000\010\000\000\000\000\000\000\000\030\000\000\000\000\000\000\000\020\000\000\000\000\000\000\000\050\000\000\000\000\000\000\000\020\000\000\000\001\000\000\000\010\000\000\000\000\000\000\000\014\000\000\000\004\000\000\000\146\165\172\172\000\000\000\000\020\000\000\000\001\000\000\000\010\000\000\000\000\000\000\000\020\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\030\000\000\000\001\000\000\000\020\000\000\000\022\000\000\000\010\000\000\000\000\000\000\000\020\000\000\000\001\000\000\000\010\000\000\000\000\000\000\000\030\000\000\000\000\000\000\000\020\000\000\000\000\000\000\000\030\000\000\000\000\000\000\000\014\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\020\000\000\000\001\000\000\000\010\000\000\000\000\000\000\000\030\000\000\000\000\000\000\000\020\000\000\000\000\000\000\000\030\000\000\000\000\000\000\000\011\000\000\000\001\000\000\000\172\000\000\000\000\000\000\000\020\000\000\000\001\000\000\000\010\000\000\000\000\000\000\000\030\000\000\000\001\000\000\000\020\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\020\000\000\000\001\000\000\000\010\000\000\000\000\000\000\000\200\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\110\000\000\000\000\000\000\000\110\000\000\000\000\000\000\000\110\000\000\000\000\000\000\000\150\000\000\000\000\000\000\000\210\000\000\000\000\000\000\000\250\000\000\000\000\000\000\000\250\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\010\000\000\000\000\000\000\000\010\000\000\000\000\000\000\000\030\000\000\000\000\000\000\000\020\000\000\000\000\000\000\000\020\000\000\000\000\000\000\000\010\000\000\000\000\000\000\000\010\000\000\000\000\000\000\000\030\000\000\000\000\000\000\000\020\000\000\000\000\000\000\000\020\000\000\000\000\000\000\000\010\000\000\000\000\000\000\000\010\000\000\000\000\000\000\000\030\000\000\000\000\000\000\000\020\000\000\000\000\000\000\000\020\000\000\000\000\000\000\000\010\000\000\000\000\000\000\000\010\000\000\000\000\000\000\000\010\000\000\000\000\000\000\000\010\000\000\000\000\000\000\000\020\000\000\000\001\000\000\000\010\000\000\000\000\000\000\000\030\000\000\000\000\000\000\000\020\000\000\000\000\000\000\000\030\000\000\000\000\000\000\000\014\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\020\000\000\000\001\000\000\000\010\000\000\000\000\000\000\000\030\000\000\000\000\000\000\000\020\000\000\000\000\000\000\000\030\000\000\000\000\000\000\000\011\000\000\000\001\000\000\000\172\000\000\000\000\000\000\000\020\000\000\000\001\000\000\000\010\000\000\000\000\000\000\000\020\000\000\000\001\000\000\000\010\000\000\000\000\000\000\000\200\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\110\000\000\000\000\000\000\000\110\000\000\000\000\000\000\000\110\000\000\000\000\000\000\000\150\000\000\000\000\000\000\000\210\000\000\000\000\000\000\000\250\000\000\000\000\000\000\000\250\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\010\000\000\000\000\000\000\000\010\000\000\000\000\000\000\000\030\000\000\000\000\000\000\000\020\000\000\000\000\000\000\000\020\000\000\000\000\000\000\000\010\000\000\000\000\000\000\000\010\000\000\000\000\000\000\000\030\000\000\000\000\000\000\000\020\000\000\000\000\000\000\000\020\000\000\000\000\000\000\000\010\000\000\000\000\000\000\000\010\000\000\000\000\000\000\000\030\000\000\000\000\000\000\000\020\000\000\000\000\000\000\000\020\000\000\000\000\000\000\000\010\000\000\000\000\000\000\000\010\000\000\000\000\000\000\000\010\000\000\000\000\000\000\000\010\000\000\000\000\000\000\000"
diff --git a/chromium/mojo/public/tools/fuzzers/mojo_parse_message_proto_corpus/9ccc6b5c0a61672816dc252194c3d722c18107bc b/chromium/mojo/public/tools/fuzzers/mojo_parse_message_proto_corpus/9ccc6b5c0a61672816dc252194c3d722c18107bc
deleted file mode 100644
index d5fa6119789..00000000000
--- a/chromium/mojo/public/tools/fuzzers/mojo_parse_message_proto_corpus/9ccc6b5c0a61672816dc252194c3d722c18107bc
+++ /dev/null
@@ -1 +0,0 @@
-messages: "\040\000\000\000\001\000\000\000\000\000\000\000\002\000\000\000\005\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\010\000\000\000\000\000\000\000"
diff --git a/chromium/mojo/public/tools/fuzzers/mojo_parse_message_proto_corpus/9e0a62bdd4b08cb777bee9449a22b3ad6702b106 b/chromium/mojo/public/tools/fuzzers/mojo_parse_message_proto_corpus/9e0a62bdd4b08cb777bee9449a22b3ad6702b106
deleted file mode 100644
index c5567f2f49b..00000000000
--- a/chromium/mojo/public/tools/fuzzers/mojo_parse_message_proto_corpus/9e0a62bdd4b08cb777bee9449a22b3ad6702b106
+++ /dev/null
@@ -1 +0,0 @@
-messages: "\030\000\000\000\000\000\000\000\000\000\000\000\003\000\000\000\000\000\000\000\000\000\000\000\030\000\000\000\000\000\000\000\020\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\200\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\110\000\000\000\000\000\000\000\110\000\000\000\000\000\000\000\110\000\000\000\000\000\000\000\150\000\000\000\000\000\000\000\210\000\000\000\000\000\000\000\250\000\000\000\000\000\000\000\250\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\010\000\000\000\000\000\000\000\010\000\000\000\000\000\000\000\030\000\000\000\000\000\000\000\020\000\000\000\000\000\000\000\020\000\000\000\000\000\000\000\010\000\000\000\000\000\000\000\010\000\000\000\000\000\000\000\030\000\000\000\000\000\000\000\020\000\000\000\000\000\000\000\020\000\000\000\000\000\000\000\010\000\000\000\000\000\000\000\010\000\000\000\000\000\000\000\030\000\000\000\000\000\000\000\020\000\000\000\000\000\000\000\020\000\000\000\000\000\000\000\010\000\000\000\000\000\000\000\010\000\000\000\000\000\000\000\010\000\000\000\000\000\000\000\010\000\000\000\000\000\000\000"
diff --git a/chromium/mojo/public/tools/fuzzers/mojo_parse_message_proto_corpus/a74241101f97704b96c9ba11b4781651e236ad8f b/chromium/mojo/public/tools/fuzzers/mojo_parse_message_proto_corpus/a74241101f97704b96c9ba11b4781651e236ad8f
deleted file mode 100644
index 619a2bbe143..00000000000
--- a/chromium/mojo/public/tools/fuzzers/mojo_parse_message_proto_corpus/a74241101f97704b96c9ba11b4781651e236ad8f
+++ /dev/null
@@ -1 +0,0 @@
-messages: "\030\000\000\000\000\000\000\000\377\377\377\377\376\377\377\377\000\000\000\000\000\000\000\000\030\000\000\000\000\000\000\000\020\000\000\000\000\000\000\000\010\000\000\000\000\000\000\000\030\000\000\000\000\000\000\000\001\000\000\200\000\000\000\000\000\000\000\000\000\000\000\000"
diff --git a/chromium/mojo/public/tools/fuzzers/mojo_parse_message_proto_corpus/be66c5d078fbf574388b7b1d25a29ff2d16df67e b/chromium/mojo/public/tools/fuzzers/mojo_parse_message_proto_corpus/be66c5d078fbf574388b7b1d25a29ff2d16df67e
deleted file mode 100644
index dcd7e6e8c1b..00000000000
--- a/chromium/mojo/public/tools/fuzzers/mojo_parse_message_proto_corpus/be66c5d078fbf574388b7b1d25a29ff2d16df67e
+++ /dev/null
@@ -1 +0,0 @@
-messages: "\040\000\000\000\001\000\000\000\000\000\000\000\001\000\000\000\001\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\010\000\000\000\000\000\000\000"
diff --git a/chromium/mojo/public/tools/fuzzers/mojo_parse_message_proto_corpus/e4be6bde72d04c5cda7d4939a80e5890c5c01374 b/chromium/mojo/public/tools/fuzzers/mojo_parse_message_proto_corpus/e4be6bde72d04c5cda7d4939a80e5890c5c01374
deleted file mode 100644
index 186f82d8676..00000000000
--- a/chromium/mojo/public/tools/fuzzers/mojo_parse_message_proto_corpus/e4be6bde72d04c5cda7d4939a80e5890c5c01374
+++ /dev/null
@@ -1 +0,0 @@
-messages: "\030\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\010\000\000\000\000\000\000\000"
diff --git a/chromium/mojo/public/tools/fuzzers/mojo_parse_message_proto_fuzzer.cc b/chromium/mojo/public/tools/fuzzers/mojo_parse_message_proto_fuzzer.cc
deleted file mode 100644
index d6b5e9684cd..00000000000
--- a/chromium/mojo/public/tools/fuzzers/mojo_parse_message_proto_fuzzer.cc
+++ /dev/null
@@ -1,71 +0,0 @@
-// Copyright 2018 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.
-
-// Implementation of a proto version of mojo_parse_message_fuzzer that sends
-// multiple messages per run.
-
-#include "base/bind.h"
-#include "base/message_loop/message_loop.h"
-#include "base/run_loop.h"
-#include "base/task/task_scheduler/task_scheduler.h"
-#include "mojo/core/embedder/embedder.h"
-#include "mojo/public/cpp/bindings/binding.h"
-#include "mojo/public/tools/fuzzers/fuzz_impl.h"
-#include "mojo/public/tools/fuzzers/mojo_fuzzer.pb.h"
-#include "testing/libfuzzer/proto/lpm_interface.h"
-
-namespace mojo_proto_fuzzer {
-
-void FuzzMessage(const MojoFuzzerMessages& mojo_fuzzer_messages,
- base::RunLoop* run) {
- fuzz::mojom::FuzzInterfacePtr fuzz;
- auto impl = std::make_unique<FuzzImpl>(MakeRequest(&fuzz));
- auto router = impl->binding_.RouterForTesting();
-
- for (auto& message_str : mojo_fuzzer_messages.messages()) {
- // Create a mojo message with the appropriate payload size.
- mojo::Message message(0, 0, message_str.size(), 0, nullptr);
- if (message.data_num_bytes() < message_str.size()) {
- message.payload_buffer()->Allocate(message_str.size() -
- message.data_num_bytes());
- }
-
- // Set the raw message data.
- memcpy(message.mutable_data(), message_str.data(), message_str.size());
-
- // Run the message through header validation, payload validation, and
- // dispatch to the impl.
- router->SimulateReceivingMessageForTesting(&message);
- }
-
- // Allow the harness function to return now.
- run->Quit();
-}
-
-// Environment for the fuzzer. Initializes the mojo EDK and sets up a
-// TaskScheduler, because Mojo messages must be sent and processed from
-// TaskRunners.
-struct Environment {
- Environment() : message_loop(base::MessageLoop::TYPE_UI) {
- base::TaskScheduler::CreateAndStartWithDefaultParams(
- "MojoParseMessageFuzzerProcess");
- mojo::core::Init();
- }
-
- // Message loop to send and handle messages on.
- base::MessageLoop message_loop;
-
- // Suppress mojo validation failure logs.
- mojo::internal::ScopedSuppressValidationErrorLoggingForTests log_suppression;
-};
-
-DEFINE_PROTO_FUZZER(const MojoFuzzerMessages& mojo_fuzzer_messages) {
- static Environment* env = new Environment();
- // Pass the data along to run on a MessageLoop, and wait for it to finish.
- base::RunLoop run;
- env->message_loop.task_runner()->PostTask(
- FROM_HERE, base::BindOnce(&FuzzMessage, mojo_fuzzer_messages, &run));
- run.Run();
-}
-} // namespace mojo_proto_fuzzer