Updating trunk VERSION from 2139.0 to 2140.0
[chromium-blink-merge.git] / base / pickle_unittest.cc
blobdb529a4a2534e6ceeb96e1784f0e75159b263ac1
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 "testing/gtest/include/gtest/gtest.h"
13 // Remove when this file is in the base namespace.
14 using base::string16;
16 namespace {
18 const int testint = 2093847192;
19 const std::string teststr("Hello world"); // note non-aligned string length
20 const std::wstring testwstr(L"Hello, world");
21 const char testdata[] = "AAA\0BBB\0";
22 const int testdatalen = arraysize(testdata) - 1;
23 const bool testbool1 = false;
24 const bool testbool2 = true;
25 const uint16 testuint16 = 32123;
26 const float testfloat = 3.1415926935f;
27 const double testdouble = 2.71828182845904523;
29 // checks that the result
30 void VerifyResult(const Pickle& pickle) {
31 PickleIterator iter(pickle);
33 int outint;
34 EXPECT_TRUE(pickle.ReadInt(&iter, &outint));
35 EXPECT_EQ(testint, outint);
37 std::string outstr;
38 EXPECT_TRUE(pickle.ReadString(&iter, &outstr));
39 EXPECT_EQ(teststr, outstr);
41 std::wstring outwstr;
42 EXPECT_TRUE(pickle.ReadWString(&iter, &outwstr));
43 EXPECT_EQ(testwstr, outwstr);
45 bool outbool;
46 EXPECT_TRUE(pickle.ReadBool(&iter, &outbool));
47 EXPECT_FALSE(outbool);
48 EXPECT_TRUE(pickle.ReadBool(&iter, &outbool));
49 EXPECT_TRUE(outbool);
51 uint16 outuint16;
52 EXPECT_TRUE(pickle.ReadUInt16(&iter, &outuint16));
53 EXPECT_EQ(testuint16, outuint16);
55 float outfloat;
56 EXPECT_TRUE(pickle.ReadFloat(&iter, &outfloat));
57 EXPECT_EQ(testfloat, outfloat);
59 double outdouble;
60 EXPECT_TRUE(pickle.ReadDouble(&iter, &outdouble));
61 EXPECT_EQ(testdouble, outdouble);
63 const char* outdata;
64 int outdatalen;
65 EXPECT_TRUE(pickle.ReadData(&iter, &outdata, &outdatalen));
66 EXPECT_EQ(testdatalen, outdatalen);
67 EXPECT_EQ(memcmp(testdata, outdata, outdatalen), 0);
69 // reads past the end should fail
70 EXPECT_FALSE(pickle.ReadInt(&iter, &outint));
73 } // namespace
75 TEST(PickleTest, EncodeDecode) {
76 Pickle pickle;
78 EXPECT_TRUE(pickle.WriteInt(testint));
79 EXPECT_TRUE(pickle.WriteString(teststr));
80 EXPECT_TRUE(pickle.WriteWString(testwstr));
81 EXPECT_TRUE(pickle.WriteBool(testbool1));
82 EXPECT_TRUE(pickle.WriteBool(testbool2));
83 EXPECT_TRUE(pickle.WriteUInt16(testuint16));
84 EXPECT_TRUE(pickle.WriteFloat(testfloat));
85 EXPECT_TRUE(pickle.WriteDouble(testdouble));
86 EXPECT_TRUE(pickle.WriteData(testdata, testdatalen));
87 VerifyResult(pickle);
89 // test copy constructor
90 Pickle pickle2(pickle);
91 VerifyResult(pickle2);
93 // test operator=
94 Pickle pickle3;
95 pickle3 = pickle;
96 VerifyResult(pickle3);
99 // Tests that we can handle really small buffers.
100 TEST(PickleTest, SmallBuffer) {
101 scoped_ptr<char[]> buffer(new char[1]);
103 // We should not touch the buffer.
104 Pickle pickle(buffer.get(), 1);
106 PickleIterator iter(pickle);
107 int data;
108 EXPECT_FALSE(pickle.ReadInt(&iter, &data));
111 // Tests that we can handle improper headers.
112 TEST(PickleTest, BigSize) {
113 int buffer[] = { 0x56035200, 25, 40, 50 };
115 Pickle pickle(reinterpret_cast<char*>(buffer), sizeof(buffer));
117 PickleIterator iter(pickle);
118 int data;
119 EXPECT_FALSE(pickle.ReadInt(&iter, &data));
122 TEST(PickleTest, UnalignedSize) {
123 int buffer[] = { 10, 25, 40, 50 };
125 Pickle pickle(reinterpret_cast<char*>(buffer), sizeof(buffer));
127 PickleIterator iter(pickle);
128 int data;
129 EXPECT_FALSE(pickle.ReadInt(&iter, &data));
132 TEST(PickleTest, ZeroLenStr) {
133 Pickle pickle;
134 EXPECT_TRUE(pickle.WriteString(std::string()));
136 PickleIterator iter(pickle);
137 std::string outstr;
138 EXPECT_TRUE(pickle.ReadString(&iter, &outstr));
139 EXPECT_EQ("", outstr);
142 TEST(PickleTest, ZeroLenWStr) {
143 Pickle pickle;
144 EXPECT_TRUE(pickle.WriteWString(std::wstring()));
146 PickleIterator iter(pickle);
147 std::string outstr;
148 EXPECT_TRUE(pickle.ReadString(&iter, &outstr));
149 EXPECT_EQ("", outstr);
152 TEST(PickleTest, BadLenStr) {
153 Pickle pickle;
154 EXPECT_TRUE(pickle.WriteInt(-2));
156 PickleIterator iter(pickle);
157 std::string outstr;
158 EXPECT_FALSE(pickle.ReadString(&iter, &outstr));
161 TEST(PickleTest, BadLenWStr) {
162 Pickle pickle;
163 EXPECT_TRUE(pickle.WriteInt(-1));
165 PickleIterator iter(pickle);
166 std::wstring woutstr;
167 EXPECT_FALSE(pickle.ReadWString(&iter, &woutstr));
170 TEST(PickleTest, FindNext) {
171 Pickle pickle;
172 EXPECT_TRUE(pickle.WriteInt(1));
173 EXPECT_TRUE(pickle.WriteString("Domo"));
175 const char* start = reinterpret_cast<const char*>(pickle.data());
176 const char* end = start + pickle.size();
178 EXPECT_TRUE(end == Pickle::FindNext(pickle.header_size_, start, end));
179 EXPECT_TRUE(NULL == Pickle::FindNext(pickle.header_size_, start, end - 1));
180 EXPECT_TRUE(end == Pickle::FindNext(pickle.header_size_, start, end + 1));
183 TEST(PickleTest, FindNextWithIncompleteHeader) {
184 size_t header_size = sizeof(Pickle::Header);
185 scoped_ptr<char[]> buffer(new char[header_size - 1]);
186 memset(buffer.get(), 0x1, header_size - 1);
188 const char* start = buffer.get();
189 const char* end = start + header_size - 1;
191 EXPECT_TRUE(NULL == Pickle::FindNext(header_size, start, end));
194 #if defined(COMPILER_MSVC)
195 #pragma warning(push)
196 #pragma warning(disable: 4146)
197 #endif
198 TEST(PickleTest, FindNextOverflow) {
199 size_t header_size = sizeof(Pickle::Header);
200 size_t header_size2 = 2 * header_size;
201 size_t payload_received = 100;
202 scoped_ptr<char[]> buffer(new char[header_size2 + payload_received]);
203 const char* start = buffer.get();
204 Pickle::Header* header = reinterpret_cast<Pickle::Header*>(buffer.get());
205 const char* end = start + header_size2 + payload_received;
206 // It is impossible to construct an overflow test otherwise.
207 if (sizeof(size_t) > sizeof(header->payload_size) ||
208 sizeof(uintptr_t) > sizeof(header->payload_size))
209 return;
211 header->payload_size = -(reinterpret_cast<uintptr_t>(start) + header_size2);
212 EXPECT_TRUE(NULL == Pickle::FindNext(header_size2, start, end));
214 header->payload_size = -header_size2;
215 EXPECT_TRUE(NULL == Pickle::FindNext(header_size2, start, end));
217 header->payload_size = 0;
218 end = start + header_size;
219 EXPECT_TRUE(NULL == Pickle::FindNext(header_size2, start, end));
221 #if defined(COMPILER_MSVC)
222 #pragma warning(pop)
223 #endif
225 TEST(PickleTest, GetReadPointerAndAdvance) {
226 Pickle pickle;
228 PickleIterator iter(pickle);
229 EXPECT_FALSE(iter.GetReadPointerAndAdvance(1));
231 EXPECT_TRUE(pickle.WriteInt(1));
232 EXPECT_TRUE(pickle.WriteInt(2));
233 int bytes = sizeof(int) * 2;
235 EXPECT_TRUE(PickleIterator(pickle).GetReadPointerAndAdvance(0));
236 EXPECT_TRUE(PickleIterator(pickle).GetReadPointerAndAdvance(1));
237 EXPECT_FALSE(PickleIterator(pickle).GetReadPointerAndAdvance(-1));
238 EXPECT_TRUE(PickleIterator(pickle).GetReadPointerAndAdvance(bytes));
239 EXPECT_FALSE(PickleIterator(pickle).GetReadPointerAndAdvance(bytes + 1));
240 EXPECT_FALSE(PickleIterator(pickle).GetReadPointerAndAdvance(INT_MAX));
241 EXPECT_FALSE(PickleIterator(pickle).GetReadPointerAndAdvance(INT_MIN));
244 TEST(PickleTest, Resize) {
245 size_t unit = Pickle::kPayloadUnit;
246 scoped_ptr<char[]> data(new char[unit]);
247 char* data_ptr = data.get();
248 for (size_t i = 0; i < unit; i++)
249 data_ptr[i] = 'G';
251 // construct a message that will be exactly the size of one payload unit,
252 // note that any data will have a 4-byte header indicating the size
253 const size_t payload_size_after_header = unit - sizeof(uint32);
254 Pickle pickle;
255 pickle.WriteData(data_ptr,
256 static_cast<int>(payload_size_after_header - sizeof(uint32)));
257 size_t cur_payload = payload_size_after_header;
259 // note: we assume 'unit' is a power of 2
260 EXPECT_EQ(unit, pickle.capacity_after_header());
261 EXPECT_EQ(pickle.payload_size(), payload_size_after_header);
263 // fill out a full page (noting data header)
264 pickle.WriteData(data_ptr, static_cast<int>(unit - sizeof(uint32)));
265 cur_payload += unit;
266 EXPECT_EQ(unit * 2, pickle.capacity_after_header());
267 EXPECT_EQ(cur_payload, pickle.payload_size());
269 // one more byte should double the capacity
270 pickle.WriteData(data_ptr, 1);
271 cur_payload += 8;
272 EXPECT_EQ(unit * 4, pickle.capacity_after_header());
273 EXPECT_EQ(cur_payload, pickle.payload_size());
276 namespace {
278 struct CustomHeader : Pickle::Header {
279 int blah;
282 } // namespace
284 TEST(PickleTest, HeaderPadding) {
285 const uint32 kMagic = 0x12345678;
287 Pickle pickle(sizeof(CustomHeader));
288 pickle.WriteInt(kMagic);
290 // this should not overwrite the 'int' payload
291 pickle.headerT<CustomHeader>()->blah = 10;
293 PickleIterator iter(pickle);
294 int result;
295 ASSERT_TRUE(pickle.ReadInt(&iter, &result));
297 EXPECT_EQ(static_cast<uint32>(result), kMagic);
300 TEST(PickleTest, EqualsOperator) {
301 Pickle source;
302 source.WriteInt(1);
304 Pickle copy_refs_source_buffer(static_cast<const char*>(source.data()),
305 source.size());
306 Pickle copy;
307 copy = copy_refs_source_buffer;
308 ASSERT_EQ(source.size(), copy.size());
311 TEST(PickleTest, EvilLengths) {
312 Pickle source;
313 std::string str(100000, 'A');
314 EXPECT_TRUE(source.WriteData(str.c_str(), 100000));
315 // ReadString16 used to have its read buffer length calculation wrong leading
316 // to out-of-bounds reading.
317 PickleIterator iter(source);
318 string16 str16;
319 EXPECT_FALSE(source.ReadString16(&iter, &str16));
321 // And check we didn't break ReadString16.
322 str16 = (wchar_t) 'A';
323 Pickle str16_pickle;
324 EXPECT_TRUE(str16_pickle.WriteString16(str16));
325 iter = PickleIterator(str16_pickle);
326 EXPECT_TRUE(str16_pickle.ReadString16(&iter, &str16));
327 EXPECT_EQ(1U, str16.length());
329 // Check we don't fail in a length check with invalid String16 size.
330 // (1<<31) * sizeof(char16) == 0, so this is particularly evil.
331 Pickle bad_len;
332 EXPECT_TRUE(bad_len.WriteInt(1 << 31));
333 iter = PickleIterator(bad_len);
334 EXPECT_FALSE(bad_len.ReadString16(&iter, &str16));
336 // Check we don't fail in a length check with large WStrings.
337 Pickle big_len;
338 EXPECT_TRUE(big_len.WriteInt(1 << 30));
339 iter = PickleIterator(big_len);
340 std::wstring wstr;
341 EXPECT_FALSE(big_len.ReadWString(&iter, &wstr));
344 // Check we can write zero bytes of data and 'data' can be NULL.
345 TEST(PickleTest, ZeroLength) {
346 Pickle pickle;
347 EXPECT_TRUE(pickle.WriteData(NULL, 0));
349 PickleIterator iter(pickle);
350 const char* outdata;
351 int outdatalen;
352 EXPECT_TRUE(pickle.ReadData(&iter, &outdata, &outdatalen));
353 EXPECT_EQ(0, outdatalen);
354 // We can't assert that outdata is NULL.
357 // Check that ReadBytes works properly with an iterator initialized to NULL.
358 TEST(PickleTest, ReadBytes) {
359 Pickle pickle;
360 int data = 0x7abcd;
361 EXPECT_TRUE(pickle.WriteBytes(&data, sizeof(data)));
363 PickleIterator iter(pickle);
364 const char* outdata_char = NULL;
365 EXPECT_TRUE(pickle.ReadBytes(&iter, &outdata_char, sizeof(data)));
367 int outdata;
368 memcpy(&outdata, outdata_char, sizeof(outdata));
369 EXPECT_EQ(data, outdata);