Docserver: Skip to version 3-45-2. There was a test instance already uploaded
[chromium-blink-merge.git] / base / pickle_unittest.cc
blob20a8d674c1fe09a07cd43ef4e1188b244027ad72
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.
5 #include <string>
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"
14 // Remove when this file is in the base namespace.
15 using base::string16;
17 namespace {
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;
36 // checks that the result
37 void VerifyResult(const Pickle& pickle) {
38 PickleIterator iter(pickle);
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);
46 int outint;
47 EXPECT_TRUE(pickle.ReadInt(&iter, &outint));
48 EXPECT_EQ(testint, outint);
50 long outlong;
51 EXPECT_TRUE(pickle.ReadLong(&iter, &outlong));
52 EXPECT_EQ(testlong, outlong);
54 uint16 outuint16;
55 EXPECT_TRUE(pickle.ReadUInt16(&iter, &outuint16));
56 EXPECT_EQ(testuint16, outuint16);
58 uint32 outuint32;
59 EXPECT_TRUE(pickle.ReadUInt32(&iter, &outuint32));
60 EXPECT_EQ(testuint32, outuint32);
62 int64 outint64;
63 EXPECT_TRUE(pickle.ReadInt64(&iter, &outint64));
64 EXPECT_EQ(testint64, outint64);
66 uint64 outuint64;
67 EXPECT_TRUE(pickle.ReadUInt64(&iter, &outuint64));
68 EXPECT_EQ(testuint64, outuint64);
70 size_t outsizet;
71 EXPECT_TRUE(pickle.ReadSizeT(&iter, &outsizet));
72 EXPECT_EQ(testsizet, outsizet);
74 float outfloat;
75 EXPECT_TRUE(pickle.ReadFloat(&iter, &outfloat));
76 EXPECT_EQ(testfloat, outfloat);
78 double outdouble;
79 EXPECT_TRUE(pickle.ReadDouble(&iter, &outdouble));
80 EXPECT_EQ(testdouble, outdouble);
82 std::string outstring;
83 EXPECT_TRUE(pickle.ReadString(&iter, &outstring));
84 EXPECT_EQ(teststring, outstring);
86 std::wstring outwstring;
87 EXPECT_TRUE(pickle.ReadWString(&iter, &outwstring));
88 EXPECT_EQ(testwstring, outwstring);
90 base::string16 outstring16;
91 EXPECT_TRUE(pickle.ReadString16(&iter, &outstring16));
92 EXPECT_EQ(teststring16, outstring16);
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);
100 // reads past the end should fail
101 EXPECT_FALSE(pickle.ReadInt(&iter, &outint));
104 } // namespace
106 TEST(PickleTest, EncodeDecode) {
107 Pickle pickle;
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);
127 // test copy constructor
128 Pickle pickle2(pickle);
129 VerifyResult(pickle2);
131 // test operator=
132 Pickle pickle3;
133 pickle3 = pickle;
134 VerifyResult(pickle3);
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));
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);
158 // Tests that we can handle really small buffers.
159 TEST(PickleTest, SmallBuffer) {
160 scoped_ptr<char[]> buffer(new char[1]);
162 // We should not touch the buffer.
163 Pickle pickle(buffer.get(), 1);
165 PickleIterator iter(pickle);
166 int data;
167 EXPECT_FALSE(pickle.ReadInt(&iter, &data));
170 // Tests that we can handle improper headers.
171 TEST(PickleTest, BigSize) {
172 int buffer[] = { 0x56035200, 25, 40, 50 };
174 Pickle pickle(reinterpret_cast<char*>(buffer), sizeof(buffer));
176 PickleIterator iter(pickle);
177 int data;
178 EXPECT_FALSE(pickle.ReadInt(&iter, &data));
181 TEST(PickleTest, UnalignedSize) {
182 int buffer[] = { 10, 25, 40, 50 };
184 Pickle pickle(reinterpret_cast<char*>(buffer), sizeof(buffer));
186 PickleIterator iter(pickle);
187 int data;
188 EXPECT_FALSE(pickle.ReadInt(&iter, &data));
191 TEST(PickleTest, ZeroLenStr) {
192 Pickle pickle;
193 EXPECT_TRUE(pickle.WriteString(std::string()));
195 PickleIterator iter(pickle);
196 std::string outstr;
197 EXPECT_TRUE(pickle.ReadString(&iter, &outstr));
198 EXPECT_EQ("", outstr);
201 TEST(PickleTest, ZeroLenWStr) {
202 Pickle pickle;
203 EXPECT_TRUE(pickle.WriteWString(std::wstring()));
205 PickleIterator iter(pickle);
206 std::string outstr;
207 EXPECT_TRUE(pickle.ReadString(&iter, &outstr));
208 EXPECT_EQ("", outstr);
211 TEST(PickleTest, BadLenStr) {
212 Pickle pickle;
213 EXPECT_TRUE(pickle.WriteInt(-2));
215 PickleIterator iter(pickle);
216 std::string outstr;
217 EXPECT_FALSE(pickle.ReadString(&iter, &outstr));
220 TEST(PickleTest, BadLenWStr) {
221 Pickle pickle;
222 EXPECT_TRUE(pickle.WriteInt(-1));
224 PickleIterator iter(pickle);
225 std::wstring woutstr;
226 EXPECT_FALSE(pickle.ReadWString(&iter, &woutstr));
229 TEST(PickleTest, FindNext) {
230 Pickle pickle;
231 EXPECT_TRUE(pickle.WriteInt(1));
232 EXPECT_TRUE(pickle.WriteString("Domo"));
234 const char* start = reinterpret_cast<const char*>(pickle.data());
235 const char* end = start + pickle.size();
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));
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);
247 const char* start = buffer.get();
248 const char* end = start + header_size - 1;
250 EXPECT_TRUE(NULL == Pickle::FindNext(header_size, start, end));
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;
270 header->payload_size = -(reinterpret_cast<uintptr_t>(start) + header_size2);
271 EXPECT_TRUE(NULL == Pickle::FindNext(header_size2, start, end));
273 header->payload_size = -header_size2;
274 EXPECT_TRUE(NULL == Pickle::FindNext(header_size2, start, end));
276 header->payload_size = 0;
277 end = start + header_size;
278 EXPECT_TRUE(NULL == Pickle::FindNext(header_size2, start, end));
280 #if defined(COMPILER_MSVC)
281 #pragma warning(pop)
282 #endif
284 TEST(PickleTest, GetReadPointerAndAdvance) {
285 Pickle pickle;
287 PickleIterator iter(pickle);
288 EXPECT_FALSE(iter.GetReadPointerAndAdvance(1));
290 EXPECT_TRUE(pickle.WriteInt(1));
291 EXPECT_TRUE(pickle.WriteInt(2));
292 int bytes = sizeof(int) * 2;
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));
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';
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;
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);
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());
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());
335 namespace {
337 struct CustomHeader : Pickle::Header {
338 int blah;
341 } // namespace
343 TEST(PickleTest, HeaderPadding) {
344 const uint32 kMagic = 0x12345678;
346 Pickle pickle(sizeof(CustomHeader));
347 pickle.WriteInt(kMagic);
349 // this should not overwrite the 'int' payload
350 pickle.headerT<CustomHeader>()->blah = 10;
352 PickleIterator iter(pickle);
353 int result;
354 ASSERT_TRUE(pickle.ReadInt(&iter, &result));
356 EXPECT_EQ(static_cast<uint32>(result), kMagic);
359 TEST(PickleTest, EqualsOperator) {
360 Pickle source;
361 source.WriteInt(1);
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());
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));
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());
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));
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));
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));
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.
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)));
422 PickleIterator iter(pickle);
423 const char* outdata_char = NULL;
424 EXPECT_TRUE(pickle.ReadBytes(&iter, &outdata_char, sizeof(data)));
426 int outdata;
427 memcpy(&outdata, outdata_char, sizeof(outdata));
428 EXPECT_EQ(data, outdata);