1*635a8641SAndroid Build Coastguard Worker // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2*635a8641SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*635a8641SAndroid Build Coastguard Worker // found in the LICENSE file.
4*635a8641SAndroid Build Coastguard Worker
5*635a8641SAndroid Build Coastguard Worker #include "ipc/ipc_message_utils.h"
6*635a8641SAndroid Build Coastguard Worker
7*635a8641SAndroid Build Coastguard Worker #include <stddef.h>
8*635a8641SAndroid Build Coastguard Worker #include <stdint.h>
9*635a8641SAndroid Build Coastguard Worker #include <memory>
10*635a8641SAndroid Build Coastguard Worker
11*635a8641SAndroid Build Coastguard Worker #include "base/files/file_path.h"
12*635a8641SAndroid Build Coastguard Worker #include "base/json/json_reader.h"
13*635a8641SAndroid Build Coastguard Worker #include "base/memory/ptr_util.h"
14*635a8641SAndroid Build Coastguard Worker #include "base/memory/shared_memory.h"
15*635a8641SAndroid Build Coastguard Worker #include "base/test/test_shared_memory_util.h"
16*635a8641SAndroid Build Coastguard Worker #include "base/unguessable_token.h"
17*635a8641SAndroid Build Coastguard Worker #include "ipc/ipc_channel_handle.h"
18*635a8641SAndroid Build Coastguard Worker #include "ipc/ipc_message.h"
19*635a8641SAndroid Build Coastguard Worker #include "testing/gtest/include/gtest/gtest.h"
20*635a8641SAndroid Build Coastguard Worker
21*635a8641SAndroid Build Coastguard Worker namespace IPC {
22*635a8641SAndroid Build Coastguard Worker namespace {
23*635a8641SAndroid Build Coastguard Worker
24*635a8641SAndroid Build Coastguard Worker // Tests nesting of messages as parameters to other messages.
TEST(IPCMessageUtilsTest,NestedMessages)25*635a8641SAndroid Build Coastguard Worker TEST(IPCMessageUtilsTest, NestedMessages) {
26*635a8641SAndroid Build Coastguard Worker int32_t nested_routing = 12;
27*635a8641SAndroid Build Coastguard Worker uint32_t nested_type = 78;
28*635a8641SAndroid Build Coastguard Worker int nested_content = 456789;
29*635a8641SAndroid Build Coastguard Worker Message::PriorityValue nested_priority = Message::PRIORITY_HIGH;
30*635a8641SAndroid Build Coastguard Worker Message nested_msg(nested_routing, nested_type, nested_priority);
31*635a8641SAndroid Build Coastguard Worker nested_msg.set_sync();
32*635a8641SAndroid Build Coastguard Worker ParamTraits<int>::Write(&nested_msg, nested_content);
33*635a8641SAndroid Build Coastguard Worker
34*635a8641SAndroid Build Coastguard Worker // Outer message contains the nested one as its parameter.
35*635a8641SAndroid Build Coastguard Worker int32_t outer_routing = 91;
36*635a8641SAndroid Build Coastguard Worker uint32_t outer_type = 88;
37*635a8641SAndroid Build Coastguard Worker Message::PriorityValue outer_priority = Message::PRIORITY_NORMAL;
38*635a8641SAndroid Build Coastguard Worker Message outer_msg(outer_routing, outer_type, outer_priority);
39*635a8641SAndroid Build Coastguard Worker ParamTraits<Message>::Write(&outer_msg, nested_msg);
40*635a8641SAndroid Build Coastguard Worker
41*635a8641SAndroid Build Coastguard Worker // Read back the nested message.
42*635a8641SAndroid Build Coastguard Worker base::PickleIterator iter(outer_msg);
43*635a8641SAndroid Build Coastguard Worker IPC::Message result_msg;
44*635a8641SAndroid Build Coastguard Worker ASSERT_TRUE(ParamTraits<Message>::Read(&outer_msg, &iter, &result_msg));
45*635a8641SAndroid Build Coastguard Worker
46*635a8641SAndroid Build Coastguard Worker // Verify nested message headers.
47*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(nested_msg.routing_id(), result_msg.routing_id());
48*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(nested_msg.type(), result_msg.type());
49*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(nested_msg.priority(), result_msg.priority());
50*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(nested_msg.flags(), result_msg.flags());
51*635a8641SAndroid Build Coastguard Worker
52*635a8641SAndroid Build Coastguard Worker // Verify nested message content
53*635a8641SAndroid Build Coastguard Worker base::PickleIterator nested_iter(nested_msg);
54*635a8641SAndroid Build Coastguard Worker int result_content = 0;
55*635a8641SAndroid Build Coastguard Worker ASSERT_TRUE(ParamTraits<int>::Read(&nested_msg, &nested_iter,
56*635a8641SAndroid Build Coastguard Worker &result_content));
57*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(nested_content, result_content);
58*635a8641SAndroid Build Coastguard Worker
59*635a8641SAndroid Build Coastguard Worker // Try reading past the ends for both messages and make sure it fails.
60*635a8641SAndroid Build Coastguard Worker IPC::Message dummy;
61*635a8641SAndroid Build Coastguard Worker ASSERT_FALSE(ParamTraits<Message>::Read(&outer_msg, &iter, &dummy));
62*635a8641SAndroid Build Coastguard Worker ASSERT_FALSE(ParamTraits<int>::Read(&nested_msg, &nested_iter,
63*635a8641SAndroid Build Coastguard Worker &result_content));
64*635a8641SAndroid Build Coastguard Worker }
65*635a8641SAndroid Build Coastguard Worker
66*635a8641SAndroid Build Coastguard Worker // Tests that detection of various bad parameters is working correctly.
TEST(IPCMessageUtilsTest,ParameterValidation)67*635a8641SAndroid Build Coastguard Worker TEST(IPCMessageUtilsTest, ParameterValidation) {
68*635a8641SAndroid Build Coastguard Worker base::FilePath::StringType ok_string(FILE_PATH_LITERAL("hello"), 5);
69*635a8641SAndroid Build Coastguard Worker base::FilePath::StringType bad_string(FILE_PATH_LITERAL("hel\0o"), 5);
70*635a8641SAndroid Build Coastguard Worker
71*635a8641SAndroid Build Coastguard Worker // Change this if ParamTraits<FilePath>::Write() changes.
72*635a8641SAndroid Build Coastguard Worker IPC::Message message;
73*635a8641SAndroid Build Coastguard Worker ParamTraits<base::FilePath::StringType>::Write(&message, ok_string);
74*635a8641SAndroid Build Coastguard Worker ParamTraits<base::FilePath::StringType>::Write(&message, bad_string);
75*635a8641SAndroid Build Coastguard Worker
76*635a8641SAndroid Build Coastguard Worker base::PickleIterator iter(message);
77*635a8641SAndroid Build Coastguard Worker base::FilePath ok_path;
78*635a8641SAndroid Build Coastguard Worker base::FilePath bad_path;
79*635a8641SAndroid Build Coastguard Worker ASSERT_TRUE(ParamTraits<base::FilePath>::Read(&message, &iter, &ok_path));
80*635a8641SAndroid Build Coastguard Worker ASSERT_FALSE(ParamTraits<base::FilePath>::Read(&message, &iter, &bad_path));
81*635a8641SAndroid Build Coastguard Worker }
82*635a8641SAndroid Build Coastguard Worker
83*635a8641SAndroid Build Coastguard Worker
TEST(IPCMessageUtilsTest,StackVector)84*635a8641SAndroid Build Coastguard Worker TEST(IPCMessageUtilsTest, StackVector) {
85*635a8641SAndroid Build Coastguard Worker static const size_t stack_capacity = 5;
86*635a8641SAndroid Build Coastguard Worker base::StackVector<double, stack_capacity> stack_vector;
87*635a8641SAndroid Build Coastguard Worker for (size_t i = 0; i < 2 * stack_capacity; i++)
88*635a8641SAndroid Build Coastguard Worker stack_vector->push_back(i * 2.0);
89*635a8641SAndroid Build Coastguard Worker
90*635a8641SAndroid Build Coastguard Worker IPC::Message msg(1, 2, IPC::Message::PRIORITY_NORMAL);
91*635a8641SAndroid Build Coastguard Worker IPC::WriteParam(&msg, stack_vector);
92*635a8641SAndroid Build Coastguard Worker
93*635a8641SAndroid Build Coastguard Worker base::StackVector<double, stack_capacity> output;
94*635a8641SAndroid Build Coastguard Worker base::PickleIterator iter(msg);
95*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(IPC::ReadParam(&msg, &iter, &output));
96*635a8641SAndroid Build Coastguard Worker for (size_t i = 0; i < 2 * stack_capacity; i++)
97*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(stack_vector[i], output[i]);
98*635a8641SAndroid Build Coastguard Worker }
99*635a8641SAndroid Build Coastguard Worker
TEST(IPCMessageUtilsTest,MojoChannelHandle)100*635a8641SAndroid Build Coastguard Worker TEST(IPCMessageUtilsTest, MojoChannelHandle) {
101*635a8641SAndroid Build Coastguard Worker mojo::MessagePipe message_pipe;
102*635a8641SAndroid Build Coastguard Worker IPC::ChannelHandle channel_handle(message_pipe.handle0.release());
103*635a8641SAndroid Build Coastguard Worker
104*635a8641SAndroid Build Coastguard Worker IPC::Message message;
105*635a8641SAndroid Build Coastguard Worker IPC::WriteParam(&message, channel_handle);
106*635a8641SAndroid Build Coastguard Worker
107*635a8641SAndroid Build Coastguard Worker base::PickleIterator iter(message);
108*635a8641SAndroid Build Coastguard Worker IPC::ChannelHandle result_handle;
109*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(IPC::ReadParam(&message, &iter, &result_handle));
110*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(channel_handle.mojo_handle, result_handle.mojo_handle);
111*635a8641SAndroid Build Coastguard Worker }
112*635a8641SAndroid Build Coastguard Worker
TEST(IPCMessageUtilsTest,OptionalUnset)113*635a8641SAndroid Build Coastguard Worker TEST(IPCMessageUtilsTest, OptionalUnset) {
114*635a8641SAndroid Build Coastguard Worker base::Optional<int> opt;
115*635a8641SAndroid Build Coastguard Worker base::Pickle pickle;
116*635a8641SAndroid Build Coastguard Worker IPC::WriteParam(&pickle, opt);
117*635a8641SAndroid Build Coastguard Worker
118*635a8641SAndroid Build Coastguard Worker std::string log;
119*635a8641SAndroid Build Coastguard Worker IPC::LogParam(opt, &log);
120*635a8641SAndroid Build Coastguard Worker EXPECT_EQ("(unset)", log);
121*635a8641SAndroid Build Coastguard Worker
122*635a8641SAndroid Build Coastguard Worker base::Optional<int> unserialized_opt;
123*635a8641SAndroid Build Coastguard Worker base::PickleIterator iter(pickle);
124*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(IPC::ReadParam(&pickle, &iter, &unserialized_opt));
125*635a8641SAndroid Build Coastguard Worker EXPECT_FALSE(unserialized_opt);
126*635a8641SAndroid Build Coastguard Worker }
127*635a8641SAndroid Build Coastguard Worker
TEST(IPCMessageUtilsTest,OptionalSet)128*635a8641SAndroid Build Coastguard Worker TEST(IPCMessageUtilsTest, OptionalSet) {
129*635a8641SAndroid Build Coastguard Worker base::Optional<int> opt(10);
130*635a8641SAndroid Build Coastguard Worker base::Pickle pickle;
131*635a8641SAndroid Build Coastguard Worker IPC::WriteParam(&pickle, opt);
132*635a8641SAndroid Build Coastguard Worker
133*635a8641SAndroid Build Coastguard Worker std::string log;
134*635a8641SAndroid Build Coastguard Worker IPC::LogParam(opt, &log);
135*635a8641SAndroid Build Coastguard Worker EXPECT_EQ("10", log);
136*635a8641SAndroid Build Coastguard Worker
137*635a8641SAndroid Build Coastguard Worker base::Optional<int> unserialized_opt;
138*635a8641SAndroid Build Coastguard Worker base::PickleIterator iter(pickle);
139*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(IPC::ReadParam(&pickle, &iter, &unserialized_opt));
140*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(unserialized_opt);
141*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(opt.value(), unserialized_opt.value());
142*635a8641SAndroid Build Coastguard Worker }
143*635a8641SAndroid Build Coastguard Worker
TEST(IPCMessageUtilsTest,SharedMemoryHandle)144*635a8641SAndroid Build Coastguard Worker TEST(IPCMessageUtilsTest, SharedMemoryHandle) {
145*635a8641SAndroid Build Coastguard Worker base::SharedMemoryCreateOptions options;
146*635a8641SAndroid Build Coastguard Worker options.size = 1004;
147*635a8641SAndroid Build Coastguard Worker base::SharedMemory shmem;
148*635a8641SAndroid Build Coastguard Worker ASSERT_TRUE(shmem.Create(options));
149*635a8641SAndroid Build Coastguard Worker
150*635a8641SAndroid Build Coastguard Worker base::SharedMemoryHandle pre_pickle = shmem.handle().Duplicate();
151*635a8641SAndroid Build Coastguard Worker ASSERT_TRUE(pre_pickle.IsValid());
152*635a8641SAndroid Build Coastguard Worker
153*635a8641SAndroid Build Coastguard Worker IPC::Message message;
154*635a8641SAndroid Build Coastguard Worker IPC::WriteParam(&message, pre_pickle);
155*635a8641SAndroid Build Coastguard Worker
156*635a8641SAndroid Build Coastguard Worker base::SharedMemoryHandle post_pickle;
157*635a8641SAndroid Build Coastguard Worker base::PickleIterator iter(message);
158*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(IPC::ReadParam(&message, &iter, &post_pickle));
159*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(pre_pickle.GetGUID(), post_pickle.GetGUID());
160*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(pre_pickle.GetSize(), post_pickle.GetSize());
161*635a8641SAndroid Build Coastguard Worker }
162*635a8641SAndroid Build Coastguard Worker
163*635a8641SAndroid Build Coastguard Worker template <typename SharedMemoryRegionType>
164*635a8641SAndroid Build Coastguard Worker class SharedMemoryRegionTypedTest : public ::testing::Test {};
165*635a8641SAndroid Build Coastguard Worker
166*635a8641SAndroid Build Coastguard Worker typedef ::testing::Types<base::WritableSharedMemoryRegion,
167*635a8641SAndroid Build Coastguard Worker base::UnsafeSharedMemoryRegion,
168*635a8641SAndroid Build Coastguard Worker base::ReadOnlySharedMemoryRegion>
169*635a8641SAndroid Build Coastguard Worker AllSharedMemoryRegionTypes;
170*635a8641SAndroid Build Coastguard Worker TYPED_TEST_CASE(SharedMemoryRegionTypedTest, AllSharedMemoryRegionTypes);
171*635a8641SAndroid Build Coastguard Worker
TYPED_TEST(SharedMemoryRegionTypedTest,WriteAndRead)172*635a8641SAndroid Build Coastguard Worker TYPED_TEST(SharedMemoryRegionTypedTest, WriteAndRead) {
173*635a8641SAndroid Build Coastguard Worker const size_t size = 2314;
174*635a8641SAndroid Build Coastguard Worker TypeParam pre_pickle;
175*635a8641SAndroid Build Coastguard Worker base::WritableSharedMemoryMapping pre_mapping;
176*635a8641SAndroid Build Coastguard Worker std::tie(pre_pickle, pre_mapping) = base::CreateMappedRegion<TypeParam>(size);
177*635a8641SAndroid Build Coastguard Worker const size_t pre_size = pre_pickle.GetSize();
178*635a8641SAndroid Build Coastguard Worker
179*635a8641SAndroid Build Coastguard Worker const std::string content = "Hello, world!";
180*635a8641SAndroid Build Coastguard Worker memcpy(pre_mapping.memory(), content.data(), content.size());
181*635a8641SAndroid Build Coastguard Worker
182*635a8641SAndroid Build Coastguard Worker IPC::Message message;
183*635a8641SAndroid Build Coastguard Worker IPC::WriteParam(&message, pre_pickle);
184*635a8641SAndroid Build Coastguard Worker EXPECT_FALSE(pre_pickle.IsValid());
185*635a8641SAndroid Build Coastguard Worker
186*635a8641SAndroid Build Coastguard Worker TypeParam post_pickle;
187*635a8641SAndroid Build Coastguard Worker base::PickleIterator iter(message);
188*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(IPC::ReadParam(&message, &iter, &post_pickle));
189*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(pre_size, post_pickle.GetSize());
190*635a8641SAndroid Build Coastguard Worker typename TypeParam::MappingType post_mapping = post_pickle.Map();
191*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(pre_mapping.guid(), post_mapping.guid());
192*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(0, memcmp(pre_mapping.memory(), post_mapping.memory(),
193*635a8641SAndroid Build Coastguard Worker post_pickle.GetSize()));
194*635a8641SAndroid Build Coastguard Worker }
195*635a8641SAndroid Build Coastguard Worker
TYPED_TEST(SharedMemoryRegionTypedTest,InvalidRegion)196*635a8641SAndroid Build Coastguard Worker TYPED_TEST(SharedMemoryRegionTypedTest, InvalidRegion) {
197*635a8641SAndroid Build Coastguard Worker TypeParam pre_pickle;
198*635a8641SAndroid Build Coastguard Worker EXPECT_FALSE(pre_pickle.IsValid());
199*635a8641SAndroid Build Coastguard Worker
200*635a8641SAndroid Build Coastguard Worker IPC::Message message;
201*635a8641SAndroid Build Coastguard Worker IPC::WriteParam(&message, pre_pickle);
202*635a8641SAndroid Build Coastguard Worker
203*635a8641SAndroid Build Coastguard Worker TypeParam post_pickle;
204*635a8641SAndroid Build Coastguard Worker base::PickleIterator iter(message);
205*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(IPC::ReadParam(&message, &iter, &post_pickle));
206*635a8641SAndroid Build Coastguard Worker EXPECT_FALSE(post_pickle.IsValid());
207*635a8641SAndroid Build Coastguard Worker }
208*635a8641SAndroid Build Coastguard Worker
TEST(IPCMessageUtilsTest,UnguessableTokenTest)209*635a8641SAndroid Build Coastguard Worker TEST(IPCMessageUtilsTest, UnguessableTokenTest) {
210*635a8641SAndroid Build Coastguard Worker base::UnguessableToken token = base::UnguessableToken::Create();
211*635a8641SAndroid Build Coastguard Worker base::Pickle pickle;
212*635a8641SAndroid Build Coastguard Worker IPC::WriteParam(&pickle, token);
213*635a8641SAndroid Build Coastguard Worker
214*635a8641SAndroid Build Coastguard Worker std::string log;
215*635a8641SAndroid Build Coastguard Worker IPC::LogParam(token, &log);
216*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(token.ToString(), log);
217*635a8641SAndroid Build Coastguard Worker
218*635a8641SAndroid Build Coastguard Worker base::UnguessableToken deserialized_token;
219*635a8641SAndroid Build Coastguard Worker base::PickleIterator iter(pickle);
220*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(IPC::ReadParam(&pickle, &iter, &deserialized_token));
221*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(token, deserialized_token);
222*635a8641SAndroid Build Coastguard Worker }
223*635a8641SAndroid Build Coastguard Worker
TEST(IPCMessageUtilsTest,FlatMap)224*635a8641SAndroid Build Coastguard Worker TEST(IPCMessageUtilsTest, FlatMap) {
225*635a8641SAndroid Build Coastguard Worker base::flat_map<std::string, int> input;
226*635a8641SAndroid Build Coastguard Worker input["foo"] = 42;
227*635a8641SAndroid Build Coastguard Worker input["bar"] = 96;
228*635a8641SAndroid Build Coastguard Worker
229*635a8641SAndroid Build Coastguard Worker base::Pickle pickle;
230*635a8641SAndroid Build Coastguard Worker IPC::WriteParam(&pickle, input);
231*635a8641SAndroid Build Coastguard Worker
232*635a8641SAndroid Build Coastguard Worker base::PickleIterator iter(pickle);
233*635a8641SAndroid Build Coastguard Worker base::flat_map<std::string, int> output;
234*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(IPC::ReadParam(&pickle, &iter, &output));
235*635a8641SAndroid Build Coastguard Worker
236*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(input, output);
237*635a8641SAndroid Build Coastguard Worker }
238*635a8641SAndroid Build Coastguard Worker
239*635a8641SAndroid Build Coastguard Worker } // namespace
240*635a8641SAndroid Build Coastguard Worker } // namespace IPC
241