• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
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 <string>
6 
7 #include "base/basictypes.h"
8 #include "base/pickle.h"
9 #include "base/scoped_ptr.h"
10 #include "base/string16.h"
11 #include "testing/gtest/include/gtest/gtest.h"
12 
13 namespace {
14 
15 const int testint = 2093847192;
16 const std::string teststr("Hello world");  // note non-aligned string length
17 const std::wstring testwstr(L"Hello, world");
18 const char testdata[] = "AAA\0BBB\0";
19 const int testdatalen = arraysize(testdata) - 1;
20 const bool testbool1 = false;
21 const bool testbool2 = true;
22 
23 // checks that the result
VerifyResult(const Pickle & pickle)24 void VerifyResult(const Pickle& pickle) {
25   void* iter = NULL;
26 
27   int outint;
28   EXPECT_TRUE(pickle.ReadInt(&iter, &outint));
29   EXPECT_EQ(testint, outint);
30 
31   std::string outstr;
32   EXPECT_TRUE(pickle.ReadString(&iter, &outstr));
33   EXPECT_EQ(teststr, outstr);
34 
35   std::wstring outwstr;
36   EXPECT_TRUE(pickle.ReadWString(&iter, &outwstr));
37   EXPECT_EQ(testwstr, outwstr);
38 
39   bool outbool;
40   EXPECT_TRUE(pickle.ReadBool(&iter, &outbool));
41   EXPECT_EQ(testbool1, outbool);
42   EXPECT_TRUE(pickle.ReadBool(&iter, &outbool));
43   EXPECT_EQ(testbool2, outbool);
44 
45   const char* outdata;
46   int outdatalen;
47   EXPECT_TRUE(pickle.ReadData(&iter, &outdata, &outdatalen));
48   EXPECT_EQ(testdatalen, outdatalen);
49   EXPECT_EQ(memcmp(testdata, outdata, outdatalen), 0);
50 
51   EXPECT_TRUE(pickle.ReadData(&iter, &outdata, &outdatalen));
52   EXPECT_EQ(testdatalen, outdatalen);
53   EXPECT_EQ(memcmp(testdata, outdata, outdatalen), 0);
54 
55   // reads past the end should fail
56   EXPECT_FALSE(pickle.ReadInt(&iter, &outint));
57 }
58 
59 }  // namespace
60 
TEST(PickleTest,EncodeDecode)61 TEST(PickleTest, EncodeDecode) {
62   Pickle pickle;
63 
64   EXPECT_TRUE(pickle.WriteInt(testint));
65   EXPECT_TRUE(pickle.WriteString(teststr));
66   EXPECT_TRUE(pickle.WriteWString(testwstr));
67   EXPECT_TRUE(pickle.WriteBool(testbool1));
68   EXPECT_TRUE(pickle.WriteBool(testbool2));
69   EXPECT_TRUE(pickle.WriteData(testdata, testdatalen));
70 
71   // Over allocate BeginWriteData so we can test TrimWriteData.
72   char* dest = pickle.BeginWriteData(testdatalen + 100);
73   EXPECT_TRUE(dest);
74   memcpy(dest, testdata, testdatalen);
75 
76   pickle.TrimWriteData(testdatalen);
77 
78   VerifyResult(pickle);
79 
80   // test copy constructor
81   Pickle pickle2(pickle);
82   VerifyResult(pickle2);
83 
84   // test operator=
85   Pickle pickle3;
86   pickle3 = pickle;
87   VerifyResult(pickle3);
88 }
89 
TEST(PickleTest,ZeroLenStr)90 TEST(PickleTest, ZeroLenStr) {
91   Pickle pickle;
92   EXPECT_TRUE(pickle.WriteString(""));
93 
94   void* iter = NULL;
95   std::string outstr;
96   EXPECT_TRUE(pickle.ReadString(&iter, &outstr));
97   EXPECT_EQ("", outstr);
98 }
99 
TEST(PickleTest,ZeroLenWStr)100 TEST(PickleTest, ZeroLenWStr) {
101   Pickle pickle;
102   EXPECT_TRUE(pickle.WriteWString(L""));
103 
104   void* iter = NULL;
105   std::string outstr;
106   EXPECT_TRUE(pickle.ReadString(&iter, &outstr));
107   EXPECT_EQ("", outstr);
108 }
109 
TEST(PickleTest,BadLenStr)110 TEST(PickleTest, BadLenStr) {
111   Pickle pickle;
112   EXPECT_TRUE(pickle.WriteInt(-2));
113 
114   void* iter = NULL;
115   std::string outstr;
116   EXPECT_FALSE(pickle.ReadString(&iter, &outstr));
117 }
118 
TEST(PickleTest,BadLenWStr)119 TEST(PickleTest, BadLenWStr) {
120   Pickle pickle;
121   EXPECT_TRUE(pickle.WriteInt(-1));
122 
123   void* iter = NULL;
124   std::wstring woutstr;
125   EXPECT_FALSE(pickle.ReadWString(&iter, &woutstr));
126 }
127 
TEST(PickleTest,FindNext)128 TEST(PickleTest, FindNext) {
129   Pickle pickle;
130   EXPECT_TRUE(pickle.WriteInt(1));
131   EXPECT_TRUE(pickle.WriteString("Domo"));
132 
133   const char* start = reinterpret_cast<const char*>(pickle.data());
134   const char* end = start + pickle.size();
135 
136   EXPECT_TRUE(end == Pickle::FindNext(pickle.header_size_, start, end));
137   EXPECT_TRUE(NULL == Pickle::FindNext(pickle.header_size_, start, end - 1));
138   EXPECT_TRUE(end == Pickle::FindNext(pickle.header_size_, start, end + 1));
139 }
140 
TEST(PickleTest,IteratorHasRoom)141 TEST(PickleTest, IteratorHasRoom) {
142   Pickle pickle;
143   EXPECT_TRUE(pickle.WriteInt(1));
144   EXPECT_TRUE(pickle.WriteInt(2));
145 
146   const void* iter = 0;
147   EXPECT_FALSE(pickle.IteratorHasRoomFor(iter, 1));
148   iter = pickle.payload();
149   EXPECT_TRUE(pickle.IteratorHasRoomFor(iter, 0));
150   EXPECT_TRUE(pickle.IteratorHasRoomFor(iter, 1));
151   EXPECT_FALSE(pickle.IteratorHasRoomFor(iter, -1));
152   EXPECT_TRUE(pickle.IteratorHasRoomFor(iter, sizeof(int) * 2));
153   EXPECT_FALSE(pickle.IteratorHasRoomFor(iter, (sizeof(int) * 2) + 1));
154 }
155 
TEST(PickleTest,Resize)156 TEST(PickleTest, Resize) {
157   size_t unit = Pickle::kPayloadUnit;
158   scoped_array<char> data(new char[unit]);
159   char* data_ptr = data.get();
160   for (size_t i = 0; i < unit; i++)
161     data_ptr[i] = 'G';
162 
163   // construct a message that will be exactly the size of one payload unit,
164   // note that any data will have a 4-byte header indicating the size
165   const size_t payload_size_after_header = unit - sizeof(uint32);
166   Pickle pickle;
167   pickle.WriteData(data_ptr,
168       static_cast<int>(payload_size_after_header - sizeof(uint32)));
169   size_t cur_payload = payload_size_after_header;
170 
171   // note: we assume 'unit' is a power of 2
172   EXPECT_EQ(unit, pickle.capacity());
173   EXPECT_EQ(pickle.payload_size(), payload_size_after_header);
174 
175   // fill out a full page (noting data header)
176   pickle.WriteData(data_ptr, static_cast<int>(unit - sizeof(uint32)));
177   cur_payload += unit;
178   EXPECT_EQ(unit * 2, pickle.capacity());
179   EXPECT_EQ(cur_payload, pickle.payload_size());
180 
181   // one more byte should double the capacity
182   pickle.WriteData(data_ptr, 1);
183   cur_payload += 5;
184   EXPECT_EQ(unit * 4, pickle.capacity());
185   EXPECT_EQ(cur_payload, pickle.payload_size());
186 }
187 
188 namespace {
189 
190 struct CustomHeader : Pickle::Header {
191   int blah;
192 };
193 
194 }  // namespace
195 
TEST(PickleTest,HeaderPadding)196 TEST(PickleTest, HeaderPadding) {
197   const uint32 kMagic = 0x12345678;
198 
199   Pickle pickle(sizeof(CustomHeader));
200   pickle.WriteInt(kMagic);
201 
202   // this should not overwrite the 'int' payload
203   pickle.headerT<CustomHeader>()->blah = 10;
204 
205   void* iter = NULL;
206   int result;
207   ASSERT_TRUE(pickle.ReadInt(&iter, &result));
208 
209   EXPECT_EQ(static_cast<uint32>(result), kMagic);
210 }
211 
TEST(PickleTest,EqualsOperator)212 TEST(PickleTest, EqualsOperator) {
213   Pickle source;
214   source.WriteInt(1);
215 
216   Pickle copy_refs_source_buffer(static_cast<const char*>(source.data()),
217                                  source.size());
218   Pickle copy;
219   copy = copy_refs_source_buffer;
220   ASSERT_EQ(source.size(), copy.size());
221 }
222 
TEST(PickleTest,EvilLengths)223 TEST(PickleTest, EvilLengths) {
224   Pickle source;
225   std::string str(100000, 'A');
226   source.WriteData(str.c_str(), 100000);
227   // ReadString16 used to have its read buffer length calculation wrong leading
228   // to out-of-bounds reading.
229   void* iter = NULL;
230   string16 str16;
231   EXPECT_FALSE(source.ReadString16(&iter, &str16));
232 
233   // And check we didn't break ReadString16.
234   str16 = (wchar_t) 'A';
235   Pickle str16_pickle;
236   str16_pickle.WriteString16(str16);
237   iter = NULL;
238   EXPECT_TRUE(str16_pickle.ReadString16(&iter, &str16));
239   EXPECT_EQ(1U, str16.length());
240 
241   // Check we don't fail in a length check with large WStrings.
242   Pickle big_len;
243   big_len.WriteInt(1 << 30);
244   iter = NULL;
245   std::wstring wstr;
246   EXPECT_FALSE(big_len.ReadWString(&iter, &wstr));
247 }
248 
249 // Check we can write zero bytes of data and 'data' can be NULL.
TEST(PickleTest,ZeroLength)250 TEST(PickleTest, ZeroLength) {
251   Pickle pickle;
252   EXPECT_TRUE(pickle.WriteData(NULL, 0));
253 
254   void* iter = NULL;
255   const char* outdata;
256   int outdatalen;
257   EXPECT_TRUE(pickle.ReadData(&iter, &outdata, &outdatalen));
258   EXPECT_EQ(0, outdatalen);
259   // We can't assert that outdata is NULL.
260 }
261 
262