[go: nahoru, domu]

blob: 5c966eee1a55f98d19f39db3cfed7ec216a10054 [file] [log] [blame]
jbates@chromium.orgce208f872012-03-07 20:42:561// Copyright (c) 2012 The Chromium Authors. All rights reserved.
agl@chromium.org946d1b22009-07-22 23:57:212// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
dmaclach@chromium.org22b42c52010-12-20 06:59:235#include "ipc/ipc_message.h"
6
avi246998d2015-12-22 02:39:047#include <stddef.h>
8#include <stdint.h>
agl@chromium.org946d1b22009-07-22 23:57:219#include <string.h>
10
dskiba6f3790a2015-09-30 17:24:3011#include <limits>
danakj03de39b2016-04-23 04:21:0912#include <memory>
jdoerriecb205a52017-06-08 16:16:4413#include <utility>
dskiba6f3790a2015-09-30 17:24:3014
jdoerriee067999a2017-04-07 06:39:0015#include "base/memory/ptr_util.h"
tfarina477fc5da72015-07-27 17:30:1816#include "base/strings/utf_string_conversions.h"
agl@chromium.org946d1b22009-07-22 23:57:2117#include "base/values.h"
avi246998d2015-12-22 02:39:0418#include "build/build_config.h"
agl@chromium.org946d1b22009-07-22 23:57:2119#include "ipc/ipc_message_utils.h"
20#include "testing/gtest/include/gtest/gtest.h"
21
jam@chromium.org5636d902014-05-13 23:19:1022// IPC messages for testing ----------------------------------------------------
23
24#define IPC_MESSAGE_IMPL
25#include "ipc/ipc_message_macros.h"
26
27#define IPC_MESSAGE_START TestMsgStart
28
29IPC_MESSAGE_CONTROL0(TestMsgClassEmpty)
30
31IPC_MESSAGE_CONTROL1(TestMsgClassI, int)
32
33IPC_SYNC_MESSAGE_CONTROL1_1(TestMsgClassIS, int, std::string)
34
dskiba6f3790a2015-09-30 17:24:3035namespace IPC {
viettrungluu@chromium.org2a3aa7b52013-01-11 20:56:2236
tfarina477fc5da72015-07-27 17:30:1837TEST(IPCMessageTest, BasicMessageTest) {
38 int v1 = 10;
39 std::string v2("foobar");
Jan Wilken Dörriec92a6d7242021-03-23 17:43:4840 std::u16string v3(u"hello world");
tfarina477fc5da72015-07-27 17:30:1841
42 IPC::Message m(0, 1, IPC::Message::PRIORITY_NORMAL);
Daniel Cheng0d89f9222017-09-22 05:05:0743 m.WriteInt(v1);
44 m.WriteString(v2);
45 m.WriteString16(v3);
tfarina477fc5da72015-07-27 17:30:1846
47 base::PickleIterator iter(m);
48
49 int vi;
50 std::string vs;
Jan Wilken Dörrie739ccc212021-03-11 18:13:0551 std::u16string vs16;
tfarina477fc5da72015-07-27 17:30:1852
53 EXPECT_TRUE(iter.ReadInt(&vi));
54 EXPECT_EQ(v1, vi);
55
56 EXPECT_TRUE(iter.ReadString(&vs));
57 EXPECT_EQ(v2, vs);
58
59 EXPECT_TRUE(iter.ReadString16(&vs16));
60 EXPECT_EQ(v3, vs16);
61
62 // should fail
63 EXPECT_FALSE(iter.ReadInt(&vi));
64 EXPECT_FALSE(iter.ReadString(&vs));
65 EXPECT_FALSE(iter.ReadString16(&vs16));
66}
67
Devlin Cronin7178a5bd2021-02-02 02:56:4768TEST(IPCMessageTest, Value) {
69 auto expect_value_equals = [](const base::Value& input) {
70 IPC::Message msg(1, 2, IPC::Message::PRIORITY_NORMAL);
71 IPC::WriteParam(&msg, input);
72
73 base::Value output;
74 base::PickleIterator iter(msg);
75 EXPECT_TRUE(IPC::ReadParam(&msg, &iter, &output)) << input;
76 EXPECT_EQ(input, output);
77 };
78
79 expect_value_equals(base::Value("foo"));
80 expect_value_equals(base::Value(42));
81 expect_value_equals(base::Value(0.07));
82 expect_value_equals(base::Value(true));
83 expect_value_equals(base::Value(base::Value::BlobStorage({'a', 'b', 'c'})));
84
85 {
86 base::Value dict(base::Value::Type::DICTIONARY);
87 dict.SetIntKey("key1", 42);
88 dict.SetStringKey("key2", "hi");
89 expect_value_equals(dict);
90 }
91 {
92 base::Value list(base::Value::Type::LIST);
93 list.Append(42);
94 list.Append("hello");
95 expect_value_equals(list);
96 }
97
98 // Also test the corrupt case.
99 IPC::Message bad_msg(1, 2, IPC::Message::PRIORITY_NORMAL);
100 bad_msg.WriteInt(99);
101 base::PickleIterator iter(bad_msg);
102 base::Value output;
103 EXPECT_FALSE(IPC::ReadParam(&bad_msg, &iter, &output));
104}
105
agl@chromium.org946d1b22009-07-22 23:57:21106TEST(IPCMessageTest, ListValue) {
brettw@chromium.orgea5ef4c2013-06-13 22:50:27107 base::ListValue input;
jdoerrief1e72e32017-04-26 16:23:55108 input.AppendDouble(42.42);
109 input.AppendString("forty");
Jeremy Roman160eb922017-08-29 17:43:43110 input.Append(std::make_unique<base::Value>());
agl@chromium.org946d1b22009-07-22 23:57:21111
bbudge@chromium.org753bb252013-11-04 22:28:12112 IPC::Message msg(1, 2, IPC::Message::PRIORITY_NORMAL);
agl@chromium.org946d1b22009-07-22 23:57:21113 IPC::WriteParam(&msg, input);
114
brettw@chromium.orgea5ef4c2013-06-13 22:50:27115 base::ListValue output;
brettwbd4d7112015-06-03 04:29:25116 base::PickleIterator iter(msg);
agl@chromium.org946d1b22009-07-22 23:57:21117 EXPECT_TRUE(IPC::ReadParam(&msg, &iter, &output));
118
119 EXPECT_TRUE(input.Equals(&output));
120
121 // Also test the corrupt case.
bbudge@chromium.org753bb252013-11-04 22:28:12122 IPC::Message bad_msg(1, 2, IPC::Message::PRIORITY_NORMAL);
agl@chromium.org946d1b22009-07-22 23:57:21123 bad_msg.WriteInt(99);
brettwbd4d7112015-06-03 04:29:25124 iter = base::PickleIterator(bad_msg);
agl@chromium.org946d1b22009-07-22 23:57:21125 EXPECT_FALSE(IPC::ReadParam(&bad_msg, &iter, &output));
126}
127
128TEST(IPCMessageTest, DictionaryValue) {
brettw@chromium.orgea5ef4c2013-06-13 22:50:27129 base::DictionaryValue input;
Jeremy Roman160eb922017-08-29 17:43:43130 input.Set("null", std::make_unique<base::Value>());
jdoerriecb205a52017-06-08 16:16:44131 input.SetBoolean("bool", true);
132 input.SetInteger("int", 42);
jdoerrie19cdc032017-08-05 02:21:55133 input.SetKey("int.with.dot", base::Value(43));
agl@chromium.org946d1b22009-07-22 23:57:21134
Jeremy Roman160eb922017-08-29 17:43:43135 auto subdict = std::make_unique<base::DictionaryValue>();
jdoerriecb205a52017-06-08 16:16:44136 subdict->SetString("str", "forty two");
137 subdict->SetBoolean("bool", false);
agl@chromium.org946d1b22009-07-22 23:57:21138
Jeremy Roman160eb922017-08-29 17:43:43139 auto sublist = std::make_unique<base::ListValue>();
jdoerrief1e72e32017-04-26 16:23:55140 sublist->AppendDouble(42.42);
141 sublist->AppendString("forty");
142 sublist->AppendString("two");
jdoerriecb205a52017-06-08 16:16:44143 subdict->Set("list", std::move(sublist));
agl@chromium.org946d1b22009-07-22 23:57:21144
jdoerriecb205a52017-06-08 16:16:44145 input.Set("dict", std::move(subdict));
agl@chromium.org946d1b22009-07-22 23:57:21146
bbudge@chromium.org753bb252013-11-04 22:28:12147 IPC::Message msg(1, 2, IPC::Message::PRIORITY_NORMAL);
agl@chromium.org946d1b22009-07-22 23:57:21148 IPC::WriteParam(&msg, input);
149
brettw@chromium.orgea5ef4c2013-06-13 22:50:27150 base::DictionaryValue output;
brettwbd4d7112015-06-03 04:29:25151 base::PickleIterator iter(msg);
agl@chromium.org946d1b22009-07-22 23:57:21152 EXPECT_TRUE(IPC::ReadParam(&msg, &iter, &output));
153
154 EXPECT_TRUE(input.Equals(&output));
155
156 // Also test the corrupt case.
bbudge@chromium.org753bb252013-11-04 22:28:12157 IPC::Message bad_msg(1, 2, IPC::Message::PRIORITY_NORMAL);
agl@chromium.org946d1b22009-07-22 23:57:21158 bad_msg.WriteInt(99);
brettwbd4d7112015-06-03 04:29:25159 iter = base::PickleIterator(bad_msg);
agl@chromium.org946d1b22009-07-22 23:57:21160 EXPECT_FALSE(IPC::ReadParam(&bad_msg, &iter, &output));
161}
viettrungluu@chromium.org2a3aa7b52013-01-11 20:56:22162
dskiba6f3790a2015-09-30 17:24:30163TEST(IPCMessageTest, FindNext) {
164 IPC::Message message;
Daniel Cheng0d89f9222017-09-22 05:05:07165 message.WriteString("Goooooooogle");
166 message.WriteInt(111);
dskiba6f3790a2015-09-30 17:24:30167
168 std::vector<char> message_data(message.size() + 7);
169 memcpy(message_data.data(), message.data(), message.size());
170
171 const char* data_start = message_data.data();
172 const char* data_end = data_start + message.size();
173
174 IPC::Message::NextMessageInfo next;
175
176 // Data range contains the entire message plus some extra bytes
177 IPC::Message::FindNext(data_start, data_end + 1, &next);
178 EXPECT_TRUE(next.message_found);
179 EXPECT_EQ(next.message_size, message.size());
180 EXPECT_EQ(next.pickle_end, data_end);
181 EXPECT_EQ(next.message_end, data_end);
182
183 // Data range exactly contains the entire message
184 IPC::Message::FindNext(data_start, data_end, &next);
185 EXPECT_TRUE(next.message_found);
186 EXPECT_EQ(next.message_size, message.size());
187 EXPECT_EQ(next.pickle_end, data_end);
188 EXPECT_EQ(next.message_end, data_end);
189
190 // Data range doesn't contain the entire message
191 // (but contains the message header)
192 IPC::Message::FindNext(data_start, data_end - 1, &next);
193 EXPECT_FALSE(next.message_found);
dskiba6f3790a2015-09-30 17:24:30194 EXPECT_EQ(next.message_size, message.size());
dskiba6f3790a2015-09-30 17:24:30195
196 // Data range doesn't contain the message header
197 // (but contains the pickle header)
198 IPC::Message::FindNext(data_start,
199 data_start + sizeof(IPC::Message::Header) - 1,
200 &next);
201 EXPECT_FALSE(next.message_found);
202 EXPECT_EQ(next.message_size, 0u);
203
204 // Data range doesn't contain the pickle header
205 IPC::Message::FindNext(data_start,
206 data_start + sizeof(base::Pickle::Header) - 1,
207 &next);
208 EXPECT_FALSE(next.message_found);
209 EXPECT_EQ(next.message_size, 0u);
210}
211
212TEST(IPCMessageTest, FindNextOverflow) {
213 IPC::Message message;
Daniel Cheng0d89f9222017-09-22 05:05:07214 message.WriteString("Data");
215 message.WriteInt(777);
dskiba6f3790a2015-09-30 17:24:30216
217 const char* data_start = reinterpret_cast<const char*>(message.data());
218 const char* data_end = data_start + message.size();
219
220 IPC::Message::NextMessageInfo next;
221
222 // Payload size is negative (defeats 'start + size > end' check)
223 message.header()->payload_size = static_cast<uint32_t>(-1);
224 IPC::Message::FindNext(data_start, data_end, &next);
225 EXPECT_FALSE(next.message_found);
dskiba6f3790a2015-09-30 17:24:30226 if (sizeof(size_t) > sizeof(uint32_t)) {
227 // No overflow, just insane message size
228 EXPECT_EQ(next.message_size,
229 message.header()->payload_size + sizeof(IPC::Message::Header));
230 } else {
231 // Actual overflow, reported as max size_t
232 EXPECT_EQ(next.message_size, std::numeric_limits<size_t>::max());
233 }
dskiba6f3790a2015-09-30 17:24:30234
235 // Payload size is max positive integer (defeats size < 0 check, while
236 // still potentially causing overflow down the road).
237 message.header()->payload_size = std::numeric_limits<int32_t>::max();
238 IPC::Message::FindNext(data_start, data_end, &next);
239 EXPECT_FALSE(next.message_found);
dskiba6f3790a2015-09-30 17:24:30240 EXPECT_EQ(next.message_size,
241 message.header()->payload_size + sizeof(IPC::Message::Header));
dskiba6f3790a2015-09-30 17:24:30242}
243
244namespace {
245
jam@chromium.org5636d902014-05-13 23:19:10246class IPCMessageParameterTest : public testing::Test {
247 public:
248 IPCMessageParameterTest() : extra_param_("extra_param"), called_(false) {}
249
250 bool OnMessageReceived(const IPC::Message& message) {
jam@chromium.org5636d902014-05-13 23:19:10251 bool handled = true;
252 IPC_BEGIN_MESSAGE_MAP_WITH_PARAM(IPCMessageParameterTest, message,
jam@chromium.orge44d1342014-05-16 21:29:33253 &extra_param_)
jam@chromium.org5636d902014-05-13 23:19:10254 IPC_MESSAGE_HANDLER(TestMsgClassEmpty, OnEmpty)
255 IPC_MESSAGE_HANDLER(TestMsgClassI, OnInt)
256 //IPC_MESSAGE_HANDLER(TestMsgClassIS, OnSync)
257 IPC_MESSAGE_UNHANDLED(handled = false)
258 IPC_END_MESSAGE_MAP()
259
260 return handled;
261 }
262
263 void OnEmpty(std::string* extra_param) {
264 EXPECT_EQ(extra_param, &extra_param_);
265 called_ = true;
266 }
267
268 void OnInt(std::string* extra_param, int foo) {
269 EXPECT_EQ(extra_param, &extra_param_);
270 EXPECT_EQ(foo, 42);
271 called_ = true;
272 }
273
274 /* TODO: handle sync IPCs
275 void OnSync(std::string* extra_param, int foo, std::string* out) {
276 EXPECT_EQ(extra_param, &extra_param_);
277 EXPECT_EQ(foo, 42);
278 called_ = true;
279 *out = std::string("out");
280 }
281
282 bool Send(IPC::Message* reply) {
283 delete reply;
284 return true;
285 }*/
286
287 std::string extra_param_;
288 bool called_;
289};
290
dskiba6f3790a2015-09-30 17:24:30291} // namespace
292
jam@chromium.org5636d902014-05-13 23:19:10293TEST_F(IPCMessageParameterTest, EmptyDispatcherWithParam) {
294 TestMsgClassEmpty message;
295 EXPECT_TRUE(OnMessageReceived(message));
296 EXPECT_TRUE(called_);
297}
298
tfarina8514f0d2015-07-28 14:41:47299#if defined(OS_ANDROID)
300#define MAYBE_OneIntegerWithParam DISABLED_OneIntegerWithParam
301#else
302#define MAYBE_OneIntegerWithParam OneIntegerWithParam
303#endif
304TEST_F(IPCMessageParameterTest, MAYBE_OneIntegerWithParam) {
jam@chromium.org5636d902014-05-13 23:19:10305 TestMsgClassI message(42);
306 EXPECT_TRUE(OnMessageReceived(message));
307 EXPECT_TRUE(called_);
308}
309
310/* TODO: handle sync IPCs
311TEST_F(IPCMessageParameterTest, Sync) {
312 std::string output;
313 TestMsgClassIS message(42, &output);
314 EXPECT_TRUE(OnMessageReceived(message));
315 EXPECT_TRUE(called_);
316 EXPECT_EQ(output, std::string("out"));
317}*/
318
dskiba6f3790a2015-09-30 17:24:30319} // namespace IPC