xref: /aosp_15_r20/external/cronet/ipc/ipc_message_unittest.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 // Copyright 2012 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "ipc/ipc_message.h"
6 
7 #include <stddef.h>
8 #include <stdint.h>
9 #include <string.h>
10 
11 #include <limits>
12 #include <memory>
13 #include <utility>
14 
15 #include "base/memory/ptr_util.h"
16 #include "base/strings/utf_string_conversions.h"
17 #include "base/values.h"
18 #include "build/build_config.h"
19 #include "ipc/ipc_message_utils.h"
20 #include "testing/gtest/include/gtest/gtest.h"
21 
22 // IPC messages for testing ----------------------------------------------------
23 
24 #define IPC_MESSAGE_IMPL
25 #include "ipc/ipc_message_macros.h"
26 #include "ipc/ipc_message_start.h"
27 
28 #define IPC_MESSAGE_START TestMsgStart
29 
30 IPC_MESSAGE_CONTROL0(TestMsgClassEmpty)
31 
32 IPC_MESSAGE_CONTROL1(TestMsgClassI, int)
33 
34 IPC_SYNC_MESSAGE_CONTROL1_1(TestMsgClassIS, int, std::string)
35 
36 namespace IPC {
37 
TEST(IPCMessageTest,BasicMessageTest)38 TEST(IPCMessageTest, BasicMessageTest) {
39   int v1 = 10;
40   std::string v2("foobar");
41   std::u16string v3(u"hello world");
42 
43   IPC::Message m(0, 1, IPC::Message::PRIORITY_NORMAL);
44   m.WriteInt(v1);
45   m.WriteString(v2);
46   m.WriteString16(v3);
47 
48   base::PickleIterator iter(m);
49 
50   int vi;
51   std::string vs;
52   std::u16string vs16;
53 
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 
TEST(IPCMessageTest,Value)69 TEST(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   {
87     base::Value::Dict dict;
88     dict.Set("key1", 42);
89     dict.Set("key2", "hi");
90     expect_value_equals(base::Value(std::move(dict)));
91   }
92   {
93     base::Value::List list;
94     list.Append(42);
95     list.Append("hello");
96     expect_value_equals(base::Value(std::move(list)));
97   }
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 
TEST(IPCMessageTest,ValueDict)107 TEST(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);
113 
114   base::Value::Dict subdict;
115   subdict.Set("str", "forty two");
116   subdict.Set("bool", false);
117 
118   base::Value::List sublist;
119   sublist.Append(42.42);
120   sublist.Append("forty");
121   sublist.Append("two");
122   subdict.Set("list", std::move(sublist));
123 
124   input.Set("dict", std::move(subdict));
125 
126   IPC::Message msg(1, 2, IPC::Message::PRIORITY_NORMAL);
127   IPC::WriteParam(&msg, input);
128 
129   base::Value::Dict output;
130   base::PickleIterator iter(msg);
131   EXPECT_TRUE(IPC::ReadParam(&msg, &iter, &output));
132 
133   EXPECT_EQ(input, output);
134 
135   // Also test the corrupt case.
136   IPC::Message bad_msg(1, 2, IPC::Message::PRIORITY_NORMAL);
137   bad_msg.WriteInt(99);
138   iter = base::PickleIterator(bad_msg);
139   EXPECT_FALSE(IPC::ReadParam(&bad_msg, &iter, &output));
140 }
141 
TEST(IPCMessageTest,FindNext)142 TEST(IPCMessageTest, FindNext) {
143   IPC::Message message;
144   message.WriteString("Goooooooogle");
145   message.WriteInt(111);
146 
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);
173   EXPECT_EQ(next.message_size, message.size());
174 
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 
TEST(IPCMessageTest,FindNextOverflow)191 TEST(IPCMessageTest, FindNextOverflow) {
192   IPC::Message message;
193   message.WriteString("Data");
194   message.WriteInt(777);
195 
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);
205   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   }
213 
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);
219   EXPECT_EQ(next.message_size,
220             message.header()->payload_size + sizeof(IPC::Message::Header));
221 }
222 
223 namespace {
224 
225 class IPCMessageParameterTest : public testing::Test {
226  public:
IPCMessageParameterTest()227   IPCMessageParameterTest() : extra_param_("extra_param"), called_(false) {}
228 
OnMessageReceived(const IPC::Message & message)229   bool OnMessageReceived(const IPC::Message& message) {
230     bool handled = true;
231     IPC_BEGIN_MESSAGE_MAP_WITH_PARAM(IPCMessageParameterTest, message,
232                                      &extra_param_)
233       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 
OnEmpty(std::string * extra_param)242   void OnEmpty(std::string* extra_param) {
243     EXPECT_EQ(extra_param, &extra_param_);
244     called_ = true;
245   }
246 
OnInt(std::string * extra_param,int foo)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 
270 }  // namespace
271 
TEST_F(IPCMessageParameterTest,EmptyDispatcherWithParam)272 TEST_F(IPCMessageParameterTest, EmptyDispatcherWithParam) {
273   TestMsgClassEmpty message;
274   EXPECT_TRUE(OnMessageReceived(message));
275   EXPECT_TRUE(called_);
276 }
277 
278 #if BUILDFLAG(IS_ANDROID)
279 #define MAYBE_OneIntegerWithParam DISABLED_OneIntegerWithParam
280 #else
281 #define MAYBE_OneIntegerWithParam OneIntegerWithParam
282 #endif
TEST_F(IPCMessageParameterTest,MAYBE_OneIntegerWithParam)283 TEST_F(IPCMessageParameterTest, MAYBE_OneIntegerWithParam) {
284   TestMsgClassI message(42);
285   EXPECT_TRUE(OnMessageReceived(message));
286   EXPECT_TRUE(called_);
287 }
288 
289 /* TODO: handle sync IPCs
290 TEST_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 
298 }  // namespace IPC
299