Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / base / pickle_unittest.cc
1 // Copyright (c) 2012 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/memory/scoped_ptr.h"
9 #include "base/pickle.h"
10 #include "base/strings/string16.h"
11 #include "base/strings/utf_string_conversions.h"
12 #include "testing/gtest/include/gtest/gtest.h"
13
14 // Remove when this file is in the base namespace.
15 using base::string16;
16
17 namespace {
18
19 const bool testbool1 = false;
20 const bool testbool2 = true;
21 const int testint = 2093847192;
22 const long testlong = 1093847192;
23 const uint16 testuint16 = 32123;
24 const uint32 testuint32 = 1593847192;
25 const int64 testint64 = -0x7E8CA9253104BDFCLL;
26 const uint64 testuint64 = 0xCE8CA9253104BDF7ULL;
27 const size_t testsizet = 0xFEDC7654;
28 const float testfloat = 3.1415926935f;
29 const double testdouble = 2.71828182845904523;
30 const std::string teststring("Hello world");  // note non-aligned string length
31 const std::wstring testwstring(L"Hello, world");
32 const base::string16 teststring16(base::ASCIIToUTF16("Hello, world"));
33 const char testdata[] = "AAA\0BBB\0";
34 const int testdatalen = arraysize(testdata) - 1;
35
36 // checks that the result
37 void VerifyResult(const Pickle& pickle) {
38   PickleIterator iter(pickle);
39
40   bool outbool;
41   EXPECT_TRUE(pickle.ReadBool(&iter, &outbool));
42   EXPECT_FALSE(outbool);
43   EXPECT_TRUE(pickle.ReadBool(&iter, &outbool));
44   EXPECT_TRUE(outbool);
45
46   int outint;
47   EXPECT_TRUE(pickle.ReadInt(&iter, &outint));
48   EXPECT_EQ(testint, outint);
49
50   long outlong;
51   EXPECT_TRUE(pickle.ReadLong(&iter, &outlong));
52   EXPECT_EQ(testlong, outlong);
53
54   uint16 outuint16;
55   EXPECT_TRUE(pickle.ReadUInt16(&iter, &outuint16));
56   EXPECT_EQ(testuint16, outuint16);
57
58   uint32 outuint32;
59   EXPECT_TRUE(pickle.ReadUInt32(&iter, &outuint32));
60   EXPECT_EQ(testuint32, outuint32);
61
62   int64 outint64;
63   EXPECT_TRUE(pickle.ReadInt64(&iter, &outint64));
64   EXPECT_EQ(testint64, outint64);
65
66   uint64 outuint64;
67   EXPECT_TRUE(pickle.ReadUInt64(&iter, &outuint64));
68   EXPECT_EQ(testuint64, outuint64);
69
70   size_t outsizet;
71   EXPECT_TRUE(pickle.ReadSizeT(&iter, &outsizet));
72   EXPECT_EQ(testsizet, outsizet);
73
74   float outfloat;
75   EXPECT_TRUE(pickle.ReadFloat(&iter, &outfloat));
76   EXPECT_EQ(testfloat, outfloat);
77
78   double outdouble;
79   EXPECT_TRUE(pickle.ReadDouble(&iter, &outdouble));
80   EXPECT_EQ(testdouble, outdouble);
81
82   std::string outstring;
83   EXPECT_TRUE(pickle.ReadString(&iter, &outstring));
84   EXPECT_EQ(teststring, outstring);
85
86   std::wstring outwstring;
87   EXPECT_TRUE(pickle.ReadWString(&iter, &outwstring));
88   EXPECT_EQ(testwstring, outwstring);
89
90   base::string16 outstring16;
91   EXPECT_TRUE(pickle.ReadString16(&iter, &outstring16));
92   EXPECT_EQ(teststring16, outstring16);
93
94   const char* outdata;
95   int outdatalen;
96   EXPECT_TRUE(pickle.ReadData(&iter, &outdata, &outdatalen));
97   EXPECT_EQ(testdatalen, outdatalen);
98   EXPECT_EQ(memcmp(testdata, outdata, outdatalen), 0);
99
100   // reads past the end should fail
101   EXPECT_FALSE(pickle.ReadInt(&iter, &outint));
102 }
103
104 }  // namespace
105
106 TEST(PickleTest, EncodeDecode) {
107   Pickle pickle;
108
109   EXPECT_TRUE(pickle.WriteBool(testbool1));
110   EXPECT_TRUE(pickle.WriteBool(testbool2));
111   EXPECT_TRUE(pickle.WriteInt(testint));
112   EXPECT_TRUE(
113       pickle.WriteLongUsingDangerousNonPortableLessPersistableForm(testlong));
114   EXPECT_TRUE(pickle.WriteUInt16(testuint16));
115   EXPECT_TRUE(pickle.WriteUInt32(testuint32));
116   EXPECT_TRUE(pickle.WriteInt64(testint64));
117   EXPECT_TRUE(pickle.WriteUInt64(testuint64));
118   EXPECT_TRUE(pickle.WriteSizeT(testsizet));
119   EXPECT_TRUE(pickle.WriteFloat(testfloat));
120   EXPECT_TRUE(pickle.WriteDouble(testdouble));
121   EXPECT_TRUE(pickle.WriteString(teststring));
122   EXPECT_TRUE(pickle.WriteWString(testwstring));
123   EXPECT_TRUE(pickle.WriteString16(teststring16));
124   EXPECT_TRUE(pickle.WriteData(testdata, testdatalen));
125   VerifyResult(pickle);
126
127   // test copy constructor
128   Pickle pickle2(pickle);
129   VerifyResult(pickle2);
130
131   // test operator=
132   Pickle pickle3;
133   pickle3 = pickle;
134   VerifyResult(pickle3);
135 }
136
137 // Tests that reading/writing a size_t works correctly when the source process
138 // is 64-bit.  We rely on having both 32- and 64-bit trybots to validate both
139 // arms of the conditional in this test.
140 TEST(PickleTest, SizeTFrom64Bit) {
141   Pickle pickle;
142   // Under the hood size_t is always written as a 64-bit value, so simulate a
143   // 64-bit size_t even on 32-bit architectures by explicitly writing a uint64.
144   EXPECT_TRUE(pickle.WriteUInt64(testuint64));
145
146   PickleIterator iter(pickle);
147   size_t outsizet;
148   if (sizeof(size_t) < sizeof(uint64)) {
149     // ReadSizeT() should return false when the original written value can't be
150     // represented as a size_t.
151     EXPECT_FALSE(pickle.ReadSizeT(&iter, &outsizet));
152   } else {
153     EXPECT_TRUE(pickle.ReadSizeT(&iter, &outsizet));
154     EXPECT_EQ(testuint64, outsizet);
155   }
156 }
157
158 // Tests that we can handle really small buffers.
159 TEST(PickleTest, SmallBuffer) {
160   scoped_ptr<char[]> buffer(new char[1]);
161
162   // We should not touch the buffer.
163   Pickle pickle(buffer.get(), 1);
164
165   PickleIterator iter(pickle);
166   int data;
167   EXPECT_FALSE(pickle.ReadInt(&iter, &data));
168 }
169
170 // Tests that we can handle improper headers.
171 TEST(PickleTest, BigSize) {
172   int buffer[] = { 0x56035200, 25, 40, 50 };
173
174   Pickle pickle(reinterpret_cast<char*>(buffer), sizeof(buffer));
175
176   PickleIterator iter(pickle);
177   int data;
178   EXPECT_FALSE(pickle.ReadInt(&iter, &data));
179 }
180
181 TEST(PickleTest, UnalignedSize) {
182   int buffer[] = { 10, 25, 40, 50 };
183
184   Pickle pickle(reinterpret_cast<char*>(buffer), sizeof(buffer));
185
186   PickleIterator iter(pickle);
187   int data;
188   EXPECT_FALSE(pickle.ReadInt(&iter, &data));
189 }
190
191 TEST(PickleTest, ZeroLenStr) {
192   Pickle pickle;
193   EXPECT_TRUE(pickle.WriteString(std::string()));
194
195   PickleIterator iter(pickle);
196   std::string outstr;
197   EXPECT_TRUE(pickle.ReadString(&iter, &outstr));
198   EXPECT_EQ("", outstr);
199 }
200
201 TEST(PickleTest, ZeroLenWStr) {
202   Pickle pickle;
203   EXPECT_TRUE(pickle.WriteWString(std::wstring()));
204
205   PickleIterator iter(pickle);
206   std::string outstr;
207   EXPECT_TRUE(pickle.ReadString(&iter, &outstr));
208   EXPECT_EQ("", outstr);
209 }
210
211 TEST(PickleTest, BadLenStr) {
212   Pickle pickle;
213   EXPECT_TRUE(pickle.WriteInt(-2));
214
215   PickleIterator iter(pickle);
216   std::string outstr;
217   EXPECT_FALSE(pickle.ReadString(&iter, &outstr));
218 }
219
220 TEST(PickleTest, BadLenWStr) {
221   Pickle pickle;
222   EXPECT_TRUE(pickle.WriteInt(-1));
223
224   PickleIterator iter(pickle);
225   std::wstring woutstr;
226   EXPECT_FALSE(pickle.ReadWString(&iter, &woutstr));
227 }
228
229 TEST(PickleTest, FindNext) {
230   Pickle pickle;
231   EXPECT_TRUE(pickle.WriteInt(1));
232   EXPECT_TRUE(pickle.WriteString("Domo"));
233
234   const char* start = reinterpret_cast<const char*>(pickle.data());
235   const char* end = start + pickle.size();
236
237   EXPECT_TRUE(end == Pickle::FindNext(pickle.header_size_, start, end));
238   EXPECT_TRUE(NULL == Pickle::FindNext(pickle.header_size_, start, end - 1));
239   EXPECT_TRUE(end == Pickle::FindNext(pickle.header_size_, start, end + 1));
240 }
241
242 TEST(PickleTest, FindNextWithIncompleteHeader) {
243   size_t header_size = sizeof(Pickle::Header);
244   scoped_ptr<char[]> buffer(new char[header_size - 1]);
245   memset(buffer.get(), 0x1, header_size - 1);
246
247   const char* start = buffer.get();
248   const char* end = start + header_size - 1;
249
250   EXPECT_TRUE(NULL == Pickle::FindNext(header_size, start, end));
251 }
252
253 #if defined(COMPILER_MSVC)
254 #pragma warning(push)
255 #pragma warning(disable: 4146)
256 #endif
257 TEST(PickleTest, FindNextOverflow) {
258   size_t header_size = sizeof(Pickle::Header);
259   size_t header_size2 = 2 * header_size;
260   size_t payload_received = 100;
261   scoped_ptr<char[]> buffer(new char[header_size2 + payload_received]);
262   const char* start = buffer.get();
263   Pickle::Header* header = reinterpret_cast<Pickle::Header*>(buffer.get());
264   const char* end = start + header_size2 + payload_received;
265   // It is impossible to construct an overflow test otherwise.
266   if (sizeof(size_t) > sizeof(header->payload_size) ||
267       sizeof(uintptr_t) > sizeof(header->payload_size))
268     return;
269
270   header->payload_size = -(reinterpret_cast<uintptr_t>(start) + header_size2);
271   EXPECT_TRUE(NULL == Pickle::FindNext(header_size2, start, end));
272
273   header->payload_size = -header_size2;
274   EXPECT_TRUE(NULL == Pickle::FindNext(header_size2, start, end));
275
276   header->payload_size = 0;
277   end = start + header_size;
278   EXPECT_TRUE(NULL == Pickle::FindNext(header_size2, start, end));
279 }
280 #if defined(COMPILER_MSVC)
281 #pragma warning(pop)
282 #endif
283
284 TEST(PickleTest, GetReadPointerAndAdvance) {
285   Pickle pickle;
286
287   PickleIterator iter(pickle);
288   EXPECT_FALSE(iter.GetReadPointerAndAdvance(1));
289
290   EXPECT_TRUE(pickle.WriteInt(1));
291   EXPECT_TRUE(pickle.WriteInt(2));
292   int bytes = sizeof(int) * 2;
293
294   EXPECT_TRUE(PickleIterator(pickle).GetReadPointerAndAdvance(0));
295   EXPECT_TRUE(PickleIterator(pickle).GetReadPointerAndAdvance(1));
296   EXPECT_FALSE(PickleIterator(pickle).GetReadPointerAndAdvance(-1));
297   EXPECT_TRUE(PickleIterator(pickle).GetReadPointerAndAdvance(bytes));
298   EXPECT_FALSE(PickleIterator(pickle).GetReadPointerAndAdvance(bytes + 1));
299   EXPECT_FALSE(PickleIterator(pickle).GetReadPointerAndAdvance(INT_MAX));
300   EXPECT_FALSE(PickleIterator(pickle).GetReadPointerAndAdvance(INT_MIN));
301 }
302
303 TEST(PickleTest, Resize) {
304   size_t unit = Pickle::kPayloadUnit;
305   scoped_ptr<char[]> data(new char[unit]);
306   char* data_ptr = data.get();
307   for (size_t i = 0; i < unit; i++)
308     data_ptr[i] = 'G';
309
310   // construct a message that will be exactly the size of one payload unit,
311   // note that any data will have a 4-byte header indicating the size
312   const size_t payload_size_after_header = unit - sizeof(uint32);
313   Pickle pickle;
314   pickle.WriteData(data_ptr,
315       static_cast<int>(payload_size_after_header - sizeof(uint32)));
316   size_t cur_payload = payload_size_after_header;
317
318   // note: we assume 'unit' is a power of 2
319   EXPECT_EQ(unit, pickle.capacity_after_header());
320   EXPECT_EQ(pickle.payload_size(), payload_size_after_header);
321
322   // fill out a full page (noting data header)
323   pickle.WriteData(data_ptr, static_cast<int>(unit - sizeof(uint32)));
324   cur_payload += unit;
325   EXPECT_EQ(unit * 2, pickle.capacity_after_header());
326   EXPECT_EQ(cur_payload, pickle.payload_size());
327
328   // one more byte should double the capacity
329   pickle.WriteData(data_ptr, 1);
330   cur_payload += 8;
331   EXPECT_EQ(unit * 4, pickle.capacity_after_header());
332   EXPECT_EQ(cur_payload, pickle.payload_size());
333 }
334
335 namespace {
336
337 struct CustomHeader : Pickle::Header {
338   int blah;
339 };
340
341 }  // namespace
342
343 TEST(PickleTest, HeaderPadding) {
344   const uint32 kMagic = 0x12345678;
345
346   Pickle pickle(sizeof(CustomHeader));
347   pickle.WriteInt(kMagic);
348
349   // this should not overwrite the 'int' payload
350   pickle.headerT<CustomHeader>()->blah = 10;
351
352   PickleIterator iter(pickle);
353   int result;
354   ASSERT_TRUE(pickle.ReadInt(&iter, &result));
355
356   EXPECT_EQ(static_cast<uint32>(result), kMagic);
357 }
358
359 TEST(PickleTest, EqualsOperator) {
360   Pickle source;
361   source.WriteInt(1);
362
363   Pickle copy_refs_source_buffer(static_cast<const char*>(source.data()),
364                                  source.size());
365   Pickle copy;
366   copy = copy_refs_source_buffer;
367   ASSERT_EQ(source.size(), copy.size());
368 }
369
370 TEST(PickleTest, EvilLengths) {
371   Pickle source;
372   std::string str(100000, 'A');
373   EXPECT_TRUE(source.WriteData(str.c_str(), 100000));
374   // ReadString16 used to have its read buffer length calculation wrong leading
375   // to out-of-bounds reading.
376   PickleIterator iter(source);
377   string16 str16;
378   EXPECT_FALSE(source.ReadString16(&iter, &str16));
379
380   // And check we didn't break ReadString16.
381   str16 = (wchar_t) 'A';
382   Pickle str16_pickle;
383   EXPECT_TRUE(str16_pickle.WriteString16(str16));
384   iter = PickleIterator(str16_pickle);
385   EXPECT_TRUE(str16_pickle.ReadString16(&iter, &str16));
386   EXPECT_EQ(1U, str16.length());
387
388   // Check we don't fail in a length check with invalid String16 size.
389   // (1<<31) * sizeof(char16) == 0, so this is particularly evil.
390   Pickle bad_len;
391   EXPECT_TRUE(bad_len.WriteInt(1 << 31));
392   iter = PickleIterator(bad_len);
393   EXPECT_FALSE(bad_len.ReadString16(&iter, &str16));
394
395   // Check we don't fail in a length check with large WStrings.
396   Pickle big_len;
397   EXPECT_TRUE(big_len.WriteInt(1 << 30));
398   iter = PickleIterator(big_len);
399   std::wstring wstr;
400   EXPECT_FALSE(big_len.ReadWString(&iter, &wstr));
401 }
402
403 // Check we can write zero bytes of data and 'data' can be NULL.
404 TEST(PickleTest, ZeroLength) {
405   Pickle pickle;
406   EXPECT_TRUE(pickle.WriteData(NULL, 0));
407
408   PickleIterator iter(pickle);
409   const char* outdata;
410   int outdatalen;
411   EXPECT_TRUE(pickle.ReadData(&iter, &outdata, &outdatalen));
412   EXPECT_EQ(0, outdatalen);
413   // We can't assert that outdata is NULL.
414 }
415
416 // Check that ReadBytes works properly with an iterator initialized to NULL.
417 TEST(PickleTest, ReadBytes) {
418   Pickle pickle;
419   int data = 0x7abcd;
420   EXPECT_TRUE(pickle.WriteBytes(&data, sizeof(data)));
421
422   PickleIterator iter(pickle);
423   const char* outdata_char = NULL;
424   EXPECT_TRUE(pickle.ReadBytes(&iter, &outdata_char, sizeof(data)));
425
426   int outdata;
427   memcpy(&outdata, outdata_char, sizeof(outdata));
428   EXPECT_EQ(data, outdata);
429 }