• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2017 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 #ifdef UNSAFE_BUFFERS_BUILD
6 // TODO(crbug.com/351564777): Remove this and convert code to safer constructs.
7 #pragma allow_unsafe_buffers
8 #endif
9 
10 #include "build/build_config.h"
11 
12 #include "ipc/ipc_message_protobuf_utils.h"
13 
14 #include <initializer_list>
15 
16 #include "ipc/test_proto.pb.h"
17 #include "ipc/ipc_message.h"
18 #include "ipc/ipc_message_utils.h"
19 #include "testing/gtest/include/gtest/gtest.h"
20 
21 namespace IPC {
22 
23 template <>
24 struct ParamTraits<ipc_message_utils_test::TestMessage1> {
25   typedef ipc_message_utils_test::TestMessage1 param_type;
WriteIPC::ParamTraits26   static void Write(base::Pickle* m, const param_type& p) {
27     WriteParam(m, p.number());
28   }
ReadIPC::ParamTraits29   static bool Read(const base::Pickle* m,
30                    base::PickleIterator* iter,
31                    param_type* r) {
32     int number;
33     if (!iter->ReadInt(&number))
34       return false;
35     r->set_number(number);
36     return true;
37   }
38 };
39 
40 template <>
41 struct ParamTraits<ipc_message_utils_test::TestMessage2> {
42   typedef ipc_message_utils_test::TestMessage2 param_type;
WriteIPC::ParamTraits43   static void Write(base::Pickle* m, const param_type& p) {
44     WriteParam(m, p.numbers());
45     WriteParam(m, p.strings());
46     WriteParam(m, p.messages());
47   }
ReadIPC::ParamTraits48   static bool Read(const base::Pickle* m,
49                    base::PickleIterator* iter,
50                    param_type* r) {
51     return ReadParam(m, iter, r->mutable_numbers()) &&
52            ReadParam(m, iter, r->mutable_strings()) &&
53            ReadParam(m, iter, r->mutable_messages());
54   }
55 };
56 
57 namespace {
58 
59 template <class P1, class P2>
AssertEqual(const P1 & left,const P2 & right)60 void AssertEqual(const P1& left, const P2& right) {
61   ASSERT_EQ(left, right);
62 }
63 
64 template<>
AssertEqual(const int & left,const ipc_message_utils_test::TestMessage1 & right)65 void AssertEqual(const int& left,
66                  const ipc_message_utils_test::TestMessage1& right) {
67   ASSERT_EQ(left, right.number());
68 }
69 
70 template <template<class> class RepeatedFieldLike, class P1, class P2>
AssertRepeatedFieldEquals(std::initializer_list<P1> expected,const RepeatedFieldLike<P2> & fields)71 void AssertRepeatedFieldEquals(std::initializer_list<P1> expected,
72                                const RepeatedFieldLike<P2>& fields) {
73   ASSERT_EQ(static_cast<int>(expected.size()), fields.size());
74   auto it = expected.begin();
75   int i = 0;
76   for (; it != expected.end(); it++, i++) {
77     AssertEqual(*it, fields.Get(i));
78   }
79 }
80 
TEST(IPCMessageRepeatedFieldUtilsTest,RepeatedFieldShouldBeSerialized)81 TEST(IPCMessageRepeatedFieldUtilsTest, RepeatedFieldShouldBeSerialized) {
82   ipc_message_utils_test::TestMessage2 message;
83   message.add_numbers(1);
84   message.add_numbers(100);
85   message.add_strings("abc");
86   message.add_strings("def");
87   message.add_messages()->set_number(1000);
88   message.add_messages()->set_number(10000);
89 
90   base::Pickle pickle;
91   IPC::WriteParam(&pickle, message);
92 
93   base::PickleIterator iter(pickle);
94   ipc_message_utils_test::TestMessage2 output;
95   ASSERT_TRUE(IPC::ReadParam(&pickle, &iter, &output));
96 
97   AssertRepeatedFieldEquals({1, 100}, output.numbers());
98   AssertRepeatedFieldEquals({"abc", "def"}, output.strings());
99   AssertRepeatedFieldEquals({1000, 10000}, output.messages());
100 }
101 
TEST(IPCMessageRepeatedFieldUtilsTest,PartialEmptyRepeatedFieldShouldBeSerialized)102 TEST(IPCMessageRepeatedFieldUtilsTest,
103      PartialEmptyRepeatedFieldShouldBeSerialized) {
104   ipc_message_utils_test::TestMessage2 message;
105   message.add_numbers(1);
106   message.add_numbers(100);
107   message.add_messages()->set_number(1000);
108   message.add_messages()->set_number(10000);
109 
110   base::Pickle pickle;
111   IPC::WriteParam(&pickle, message);
112 
113   base::PickleIterator iter(pickle);
114   ipc_message_utils_test::TestMessage2 output;
115   ASSERT_TRUE(IPC::ReadParam(&pickle, &iter, &output));
116 
117   AssertRepeatedFieldEquals({1, 100}, output.numbers());
118   ASSERT_EQ(0, output.strings_size());
119   AssertRepeatedFieldEquals({1000, 10000}, output.messages());
120 }
121 
TEST(IPCMessageRepeatedFieldUtilsTest,EmptyRepeatedFieldShouldBeSerialized)122 TEST(IPCMessageRepeatedFieldUtilsTest, EmptyRepeatedFieldShouldBeSerialized) {
123   ipc_message_utils_test::TestMessage2 message;
124 
125   base::Pickle pickle;
126   IPC::WriteParam(&pickle, message);
127 
128   base::PickleIterator iter(pickle);
129   ipc_message_utils_test::TestMessage2 output;
130   ASSERT_TRUE(IPC::ReadParam(&pickle, &iter, &output));
131 
132   ASSERT_EQ(0, output.numbers_size());
133   ASSERT_EQ(0, output.strings_size());
134   ASSERT_EQ(0, output.messages_size());
135 }
136 
TEST(IPCMessageRepeatedFieldUtilsTest,InvalidPickleShouldNotCrashRepeatedFieldDeserialization)137 TEST(IPCMessageRepeatedFieldUtilsTest,
138      InvalidPickleShouldNotCrashRepeatedFieldDeserialization) {
139   base::Pickle pickle;
140   IPC::WriteParam(&pickle, INT_MAX);
141   IPC::WriteParam(&pickle, 0);
142   IPC::WriteParam(&pickle, INT_MAX);
143   IPC::WriteParam(&pickle, std::string());
144   IPC::WriteParam(&pickle, 0);
145 
146   base::PickleIterator iter(pickle);
147   ipc_message_utils_test::TestMessage2 output;
148   ASSERT_FALSE(IPC::ReadParam(&pickle, &iter, &output));
149 }
150 
151 // This test needs ~20 seconds in Debug mode, or ~4 seconds in Release mode.
152 // See http://crbug.com/741866 for details.
TEST(IPCMessageRepeatedFieldUtilsTest,DISABLED_InvalidPickleShouldNotCrashRepeatedFieldDeserialization2)153 TEST(IPCMessageRepeatedFieldUtilsTest,
154      DISABLED_InvalidPickleShouldNotCrashRepeatedFieldDeserialization2) {
155   base::Pickle pickle;
156   IPC::WriteParam(&pickle, 256 * 1024 * 1024);
157   IPC::WriteParam(&pickle, 0);
158   IPC::WriteParam(&pickle, INT_MAX);
159   IPC::WriteParam(&pickle, std::string());
160   IPC::WriteParam(&pickle, 0);
161 
162   base::PickleIterator iter(pickle);
163   ipc_message_utils_test::TestMessage2 output;
164   ASSERT_FALSE(IPC::ReadParam(&pickle, &iter, &output));
165 }
166 
167 }  // namespace
168 
169 }  // namespace IPC
170