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