[go: nahoru, domu]

blob: 9c7c35d7442243be19d2f35285ea293ca97ae793 [file] [log] [blame]
Avi Drissmanea1be232022-09-14 23:29:061// Copyright 2012 The Chromium Authors
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"
Lei Zhangf038b172021-05-04 06:59:2226#include "ipc/ipc_message_start.h"
jam@chromium.org5636d902014-05-13 23:19:1027
28#define IPC_MESSAGE_START TestMsgStart
29
30IPC_MESSAGE_CONTROL0(TestMsgClassEmpty)
31
32IPC_MESSAGE_CONTROL1(TestMsgClassI, int)
33
34IPC_SYNC_MESSAGE_CONTROL1_1(TestMsgClassIS, int, std::string)
35
dskiba6f3790a2015-09-30 17:24:3036namespace IPC {
viettrungluu@chromium.org2a3aa7b52013-01-11 20:56:2237
tfarina477fc5da72015-07-27 17:30:1838TEST(IPCMessageTest, BasicMessageTest) {
39 int v1 = 10;
40 std::string v2("foobar");
Jan Wilken Dörriec92a6d7242021-03-23 17:43:4841 std::u16string v3(u"hello world");
tfarina477fc5da72015-07-27 17:30:1842
43 IPC::Message m(0, 1, IPC::Message::PRIORITY_NORMAL);
Daniel Cheng0d89f9222017-09-22 05:05:0744 m.WriteInt(v1);
45 m.WriteString(v2);
46 m.WriteString16(v3);
tfarina477fc5da72015-07-27 17:30:1847
48 base::PickleIterator iter(m);
49
50 int vi;
51 std::string vs;
Jan Wilken Dörrie739ccc212021-03-11 18:13:0552 std::u16string vs16;
tfarina477fc5da72015-07-27 17:30:1853
54 EXPECT_TRUE(iter.ReadInt(&vi));
55 EXPECT_EQ(v1, vi);
56
57 EXPECT_TRUE(iter.ReadString(&vs));
58 EXPECT_EQ(v2, vs);
59
60 EXPECT_TRUE(iter.ReadString16(&vs16));
61 EXPECT_EQ(v3, vs16);
62
63 // should fail
64 EXPECT_FALSE(iter.ReadInt(&vi));
65 EXPECT_FALSE(iter.ReadString(&vs));
66 EXPECT_FALSE(iter.ReadString16(&vs16));
67}
68
Devlin Cronin7178a5bd2021-02-02 02:56:4769TEST(IPCMessageTest, Value) {
70 auto expect_value_equals = [](const base::Value& input) {
71 IPC::Message msg(1, 2, IPC::Message::PRIORITY_NORMAL);
72 IPC::WriteParam(&msg, input);
73
74 base::Value output;
75 base::PickleIterator iter(msg);
76 EXPECT_TRUE(IPC::ReadParam(&msg, &iter, &output)) << input;
77 EXPECT_EQ(input, output);
78 };
79
80 expect_value_equals(base::Value("foo"));
81 expect_value_equals(base::Value(42));
82 expect_value_equals(base::Value(0.07));
83 expect_value_equals(base::Value(true));
84 expect_value_equals(base::Value(base::Value::BlobStorage({'a', 'b', 'c'})));
85
86 {
Matt Menkeb4ee00a2022-12-13 03:36:2587 base::Value::Dict dict;
88 dict.Set("key1", 42);
89 dict.Set("key2", "hi");
90 expect_value_equals(base::Value(std::move(dict)));
Devlin Cronin7178a5bd2021-02-02 02:56:4791 }
92 {
Matt Menkeb4ee00a2022-12-13 03:36:2593 base::Value::List list;
94 list.Append(42);
95 list.Append("hello");
96 expect_value_equals(base::Value(std::move(list)));
Devlin Cronin7178a5bd2021-02-02 02:56:4797 }
98
99 // Also test the corrupt case.
100 IPC::Message bad_msg(1, 2, IPC::Message::PRIORITY_NORMAL);
101 bad_msg.WriteInt(99);
102 base::PickleIterator iter(bad_msg);
103 base::Value output;
104 EXPECT_FALSE(IPC::ReadParam(&bad_msg, &iter, &output));
105}
106
Matt Menkeb4ee00a2022-12-13 03:36:25107TEST(IPCMessageTest, ValueDict) {
108 base::Value::Dict input;
109 input.Set("null", base::Value());
110 input.Set("bool", true);
111 input.Set("int", 42);
112 input.Set("int.with.dot", 43);
agl@chromium.org946d1b22009-07-22 23:57:21113
Matt Menkeb4ee00a2022-12-13 03:36:25114 base::Value::Dict subdict;
115 subdict.Set("str", "forty two");
116 subdict.Set("bool", false);
agl@chromium.org946d1b22009-07-22 23:57:21117
Matt Menkeb4ee00a2022-12-13 03:36:25118 base::Value::List sublist;
119 sublist.Append(42.42);
120 sublist.Append("forty");
121 sublist.Append("two");
122 subdict.Set("list", std::move(sublist));
agl@chromium.org946d1b22009-07-22 23:57:21123
Matt Menkeb4ee00a2022-12-13 03:36:25124 input.Set("dict", std::move(subdict));
agl@chromium.org946d1b22009-07-22 23:57:21125
bbudge@chromium.org753bb252013-11-04 22:28:12126 IPC::Message msg(1, 2, IPC::Message::PRIORITY_NORMAL);
agl@chromium.org946d1b22009-07-22 23:57:21127 IPC::WriteParam(&msg, input);
128
Matt Menkeb4ee00a2022-12-13 03:36:25129 base::Value::Dict output;
brettwbd4d7112015-06-03 04:29:25130 base::PickleIterator iter(msg);
agl@chromium.org946d1b22009-07-22 23:57:21131 EXPECT_TRUE(IPC::ReadParam(&msg, &iter, &output));
132
Ghazale Hosseinabadi7bf70b32022-02-01 17:43:43133 EXPECT_EQ(input, output);
agl@chromium.org946d1b22009-07-22 23:57:21134
135 // Also test the corrupt case.
bbudge@chromium.org753bb252013-11-04 22:28:12136 IPC::Message bad_msg(1, 2, IPC::Message::PRIORITY_NORMAL);
agl@chromium.org946d1b22009-07-22 23:57:21137 bad_msg.WriteInt(99);
brettwbd4d7112015-06-03 04:29:25138 iter = base::PickleIterator(bad_msg);
agl@chromium.org946d1b22009-07-22 23:57:21139 EXPECT_FALSE(IPC::ReadParam(&bad_msg, &iter, &output));
140}
viettrungluu@chromium.org2a3aa7b52013-01-11 20:56:22141
dskiba6f3790a2015-09-30 17:24:30142TEST(IPCMessageTest, FindNext) {
143 IPC::Message message;
Daniel Cheng0d89f9222017-09-22 05:05:07144 message.WriteString("Goooooooogle");
145 message.WriteInt(111);
dskiba6f3790a2015-09-30 17:24:30146
147 std::vector<char> message_data(message.size() + 7);
148 memcpy(message_data.data(), message.data(), message.size());
149
150 const char* data_start = message_data.data();
151 const char* data_end = data_start + message.size();
152
153 IPC::Message::NextMessageInfo next;
154
155 // Data range contains the entire message plus some extra bytes
156 IPC::Message::FindNext(data_start, data_end + 1, &next);
157 EXPECT_TRUE(next.message_found);
158 EXPECT_EQ(next.message_size, message.size());
159 EXPECT_EQ(next.pickle_end, data_end);
160 EXPECT_EQ(next.message_end, data_end);
161
162 // Data range exactly contains the entire message
163 IPC::Message::FindNext(data_start, data_end, &next);
164 EXPECT_TRUE(next.message_found);
165 EXPECT_EQ(next.message_size, message.size());
166 EXPECT_EQ(next.pickle_end, data_end);
167 EXPECT_EQ(next.message_end, data_end);
168
169 // Data range doesn't contain the entire message
170 // (but contains the message header)
171 IPC::Message::FindNext(data_start, data_end - 1, &next);
172 EXPECT_FALSE(next.message_found);
dskiba6f3790a2015-09-30 17:24:30173 EXPECT_EQ(next.message_size, message.size());
dskiba6f3790a2015-09-30 17:24:30174
175 // Data range doesn't contain the message header
176 // (but contains the pickle header)
177 IPC::Message::FindNext(data_start,
178 data_start + sizeof(IPC::Message::Header) - 1,
179 &next);
180 EXPECT_FALSE(next.message_found);
181 EXPECT_EQ(next.message_size, 0u);
182
183 // Data range doesn't contain the pickle header
184 IPC::Message::FindNext(data_start,
185 data_start + sizeof(base::Pickle::Header) - 1,
186 &next);
187 EXPECT_FALSE(next.message_found);
188 EXPECT_EQ(next.message_size, 0u);
189}
190
191TEST(IPCMessageTest, FindNextOverflow) {
192 IPC::Message message;
Daniel Cheng0d89f9222017-09-22 05:05:07193 message.WriteString("Data");
194 message.WriteInt(777);
dskiba6f3790a2015-09-30 17:24:30195
196 const char* data_start = reinterpret_cast<const char*>(message.data());
197 const char* data_end = data_start + message.size();
198
199 IPC::Message::NextMessageInfo next;
200
201 // Payload size is negative (defeats 'start + size > end' check)
202 message.header()->payload_size = static_cast<uint32_t>(-1);
203 IPC::Message::FindNext(data_start, data_end, &next);
204 EXPECT_FALSE(next.message_found);
dskiba6f3790a2015-09-30 17:24:30205 if (sizeof(size_t) > sizeof(uint32_t)) {
206 // No overflow, just insane message size
207 EXPECT_EQ(next.message_size,
208 message.header()->payload_size + sizeof(IPC::Message::Header));
209 } else {
210 // Actual overflow, reported as max size_t
211 EXPECT_EQ(next.message_size, std::numeric_limits<size_t>::max());
212 }
dskiba6f3790a2015-09-30 17:24:30213
214 // Payload size is max positive integer (defeats size < 0 check, while
215 // still potentially causing overflow down the road).
216 message.header()->payload_size = std::numeric_limits<int32_t>::max();
217 IPC::Message::FindNext(data_start, data_end, &next);
218 EXPECT_FALSE(next.message_found);
dskiba6f3790a2015-09-30 17:24:30219 EXPECT_EQ(next.message_size,
220 message.header()->payload_size + sizeof(IPC::Message::Header));
dskiba6f3790a2015-09-30 17:24:30221}
222
223namespace {
224
jam@chromium.org5636d902014-05-13 23:19:10225class IPCMessageParameterTest : public testing::Test {
226 public:
227 IPCMessageParameterTest() : extra_param_("extra_param"), called_(false) {}
228
229 bool OnMessageReceived(const IPC::Message& message) {
jam@chromium.org5636d902014-05-13 23:19:10230 bool handled = true;
231 IPC_BEGIN_MESSAGE_MAP_WITH_PARAM(IPCMessageParameterTest, message,
jam@chromium.orge44d1342014-05-16 21:29:33232 &extra_param_)
jam@chromium.org5636d902014-05-13 23:19:10233 IPC_MESSAGE_HANDLER(TestMsgClassEmpty, OnEmpty)
234 IPC_MESSAGE_HANDLER(TestMsgClassI, OnInt)
235 //IPC_MESSAGE_HANDLER(TestMsgClassIS, OnSync)
236 IPC_MESSAGE_UNHANDLED(handled = false)
237 IPC_END_MESSAGE_MAP()
238
239 return handled;
240 }
241
242 void OnEmpty(std::string* extra_param) {
243 EXPECT_EQ(extra_param, &extra_param_);
244 called_ = true;
245 }
246
247 void OnInt(std::string* extra_param, int foo) {
248 EXPECT_EQ(extra_param, &extra_param_);
249 EXPECT_EQ(foo, 42);
250 called_ = true;
251 }
252
253 /* TODO: handle sync IPCs
254 void OnSync(std::string* extra_param, int foo, std::string* out) {
255 EXPECT_EQ(extra_param, &extra_param_);
256 EXPECT_EQ(foo, 42);
257 called_ = true;
258 *out = std::string("out");
259 }
260
261 bool Send(IPC::Message* reply) {
262 delete reply;
263 return true;
264 }*/
265
266 std::string extra_param_;
267 bool called_;
268};
269
dskiba6f3790a2015-09-30 17:24:30270} // namespace
271
jam@chromium.org5636d902014-05-13 23:19:10272TEST_F(IPCMessageParameterTest, EmptyDispatcherWithParam) {
273 TestMsgClassEmpty message;
274 EXPECT_TRUE(OnMessageReceived(message));
275 EXPECT_TRUE(called_);
276}
277
Xiaohan Wangab909b32022-01-12 17:57:39278#if BUILDFLAG(IS_ANDROID)
tfarina8514f0d2015-07-28 14:41:47279#define MAYBE_OneIntegerWithParam DISABLED_OneIntegerWithParam
280#else
281#define MAYBE_OneIntegerWithParam OneIntegerWithParam
282#endif
283TEST_F(IPCMessageParameterTest, MAYBE_OneIntegerWithParam) {
jam@chromium.org5636d902014-05-13 23:19:10284 TestMsgClassI message(42);
285 EXPECT_TRUE(OnMessageReceived(message));
286 EXPECT_TRUE(called_);
287}
288
289/* TODO: handle sync IPCs
290TEST_F(IPCMessageParameterTest, Sync) {
291 std::string output;
292 TestMsgClassIS message(42, &output);
293 EXPECT_TRUE(OnMessageReceived(message));
294 EXPECT_TRUE(called_);
295 EXPECT_EQ(output, std::string("out"));
296}*/
297
dskiba6f3790a2015-09-30 17:24:30298} // namespace IPC