blob: 07be5e36ff83b0e3de2d7512db98f08fabe90d10 [file] [log] [blame]
levin@chromium.org5c528682011-03-28 10:54:15 +09001// Copyright (c) 2011 The Chromium Authors. All rights reserved.
license.botf003cfe2008-08-24 09:55:55 +09002// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
deanm@google.com75df3102008-08-07 22:40:16 +09004
5#include <string>
initial.commit3f4a7322008-07-27 06:49:38 +09006
7#include "base/basictypes.h"
levin@chromium.org5c528682011-03-28 10:54:15 +09008#include "base/memory/scoped_ptr.h"
initial.commit3f4a7322008-07-27 06:49:38 +09009#include "base/pickle.h"
cevans@chromium.orga834cdd2009-06-26 01:54:02 +090010#include "base/string16.h"
initial.commit3f4a7322008-07-27 06:49:38 +090011#include "testing/gtest/include/gtest/gtest.h"
12
13namespace {
14
15const int testint = 2093847192;
wtc@chromium.orgc2f15c52009-07-29 06:00:03 +090016const std::string teststr("Hello world"); // note non-aligned string length
initial.commit3f4a7322008-07-27 06:49:38 +090017const std::wstring testwstr(L"Hello, world");
18const char testdata[] = "AAA\0BBB\0";
19const int testdatalen = arraysize(testdata) - 1;
20const bool testbool1 = false;
21const bool testbool2 = true;
bryner@chromium.orgc85d0fd2011-02-23 04:47:19 +090022const uint16 testuint16 = 32123;
initial.commit3f4a7322008-07-27 06:49:38 +090023
24// checks that the result
25void VerifyResult(const Pickle& pickle) {
26 void* iter = NULL;
27
28 int outint;
29 EXPECT_TRUE(pickle.ReadInt(&iter, &outint));
30 EXPECT_EQ(testint, outint);
31
32 std::string outstr;
33 EXPECT_TRUE(pickle.ReadString(&iter, &outstr));
34 EXPECT_EQ(teststr, outstr);
35
36 std::wstring outwstr;
37 EXPECT_TRUE(pickle.ReadWString(&iter, &outwstr));
38 EXPECT_EQ(testwstr, outwstr);
39
40 bool outbool;
41 EXPECT_TRUE(pickle.ReadBool(&iter, &outbool));
42 EXPECT_EQ(testbool1, outbool);
43 EXPECT_TRUE(pickle.ReadBool(&iter, &outbool));
44 EXPECT_EQ(testbool2, outbool);
45
bryner@chromium.orgc85d0fd2011-02-23 04:47:19 +090046 uint16 outuint16;
47 EXPECT_TRUE(pickle.ReadUInt16(&iter, &outuint16));
48 EXPECT_EQ(testuint16, outuint16);
49
initial.commit3f4a7322008-07-27 06:49:38 +090050 const char* outdata;
51 int outdatalen;
52 EXPECT_TRUE(pickle.ReadData(&iter, &outdata, &outdatalen));
53 EXPECT_EQ(testdatalen, outdatalen);
54 EXPECT_EQ(memcmp(testdata, outdata, outdatalen), 0);
55
56 EXPECT_TRUE(pickle.ReadData(&iter, &outdata, &outdatalen));
57 EXPECT_EQ(testdatalen, outdatalen);
58 EXPECT_EQ(memcmp(testdata, outdata, outdatalen), 0);
59
60 // reads past the end should fail
61 EXPECT_FALSE(pickle.ReadInt(&iter, &outint));
62}
63
64} // namespace
65
66TEST(PickleTest, EncodeDecode) {
67 Pickle pickle;
68
69 EXPECT_TRUE(pickle.WriteInt(testint));
70 EXPECT_TRUE(pickle.WriteString(teststr));
71 EXPECT_TRUE(pickle.WriteWString(testwstr));
72 EXPECT_TRUE(pickle.WriteBool(testbool1));
73 EXPECT_TRUE(pickle.WriteBool(testbool2));
bryner@chromium.orgc85d0fd2011-02-23 04:47:19 +090074 EXPECT_TRUE(pickle.WriteUInt16(testuint16));
initial.commit3f4a7322008-07-27 06:49:38 +090075 EXPECT_TRUE(pickle.WriteData(testdata, testdatalen));
76
deanm@google.com75df3102008-08-07 22:40:16 +090077 // Over allocate BeginWriteData so we can test TrimWriteData.
78 char* dest = pickle.BeginWriteData(testdatalen + 100);
initial.commit3f4a7322008-07-27 06:49:38 +090079 EXPECT_TRUE(dest);
80 memcpy(dest, testdata, testdatalen);
81
deanm@google.com75df3102008-08-07 22:40:16 +090082 pickle.TrimWriteData(testdatalen);
83
initial.commit3f4a7322008-07-27 06:49:38 +090084 VerifyResult(pickle);
85
86 // test copy constructor
87 Pickle pickle2(pickle);
88 VerifyResult(pickle2);
89
90 // test operator=
91 Pickle pickle3;
92 pickle3 = pickle;
93 VerifyResult(pickle3);
94}
95
rvargas@google.com8d9b2b92010-11-16 04:31:23 +090096// Tests that we can handle really small buffers.
97TEST(PickleTest, SmallBuffer) {
98 scoped_array<char> buffer(new char[1]);
99
100 // We should not touch the buffer.
101 Pickle pickle(buffer.get(), 1);
102
103 void* iter = NULL;
104 int data;
105 EXPECT_FALSE(pickle.ReadInt(&iter, &data));
106}
107
108// Tests that we can handle improper headers.
109TEST(PickleTest, BigSize) {
110 int buffer[] = { 0x56035200, 25, 40, 50 };
111
112 Pickle pickle(reinterpret_cast<char*>(buffer), sizeof(buffer));
113
114 void* iter = NULL;
115 int data;
116 EXPECT_FALSE(pickle.ReadInt(&iter, &data));
117}
118
119TEST(PickleTest, UnalignedSize) {
120 int buffer[] = { 10, 25, 40, 50 };
121
122 Pickle pickle(reinterpret_cast<char*>(buffer), sizeof(buffer));
123
124 void* iter = NULL;
125 int data;
126 EXPECT_FALSE(pickle.ReadInt(&iter, &data));
127}
128
initial.commit3f4a7322008-07-27 06:49:38 +0900129TEST(PickleTest, ZeroLenStr) {
130 Pickle pickle;
131 EXPECT_TRUE(pickle.WriteString(""));
132
133 void* iter = NULL;
134 std::string outstr;
135 EXPECT_TRUE(pickle.ReadString(&iter, &outstr));
136 EXPECT_EQ("", outstr);
137}
138
139TEST(PickleTest, ZeroLenWStr) {
140 Pickle pickle;
141 EXPECT_TRUE(pickle.WriteWString(L""));
142
143 void* iter = NULL;
144 std::string outstr;
145 EXPECT_TRUE(pickle.ReadString(&iter, &outstr));
146 EXPECT_EQ("", outstr);
147}
148
149TEST(PickleTest, BadLenStr) {
150 Pickle pickle;
151 EXPECT_TRUE(pickle.WriteInt(-2));
152
153 void* iter = NULL;
154 std::string outstr;
155 EXPECT_FALSE(pickle.ReadString(&iter, &outstr));
156}
157
158TEST(PickleTest, BadLenWStr) {
159 Pickle pickle;
160 EXPECT_TRUE(pickle.WriteInt(-1));
161
162 void* iter = NULL;
163 std::wstring woutstr;
164 EXPECT_FALSE(pickle.ReadWString(&iter, &woutstr));
165}
166
167TEST(PickleTest, FindNext) {
168 Pickle pickle;
169 EXPECT_TRUE(pickle.WriteInt(1));
170 EXPECT_TRUE(pickle.WriteString("Domo"));
171
172 const char* start = reinterpret_cast<const char*>(pickle.data());
173 const char* end = start + pickle.size();
174
175 EXPECT_TRUE(end == Pickle::FindNext(pickle.header_size_, start, end));
176 EXPECT_TRUE(NULL == Pickle::FindNext(pickle.header_size_, start, end - 1));
177 EXPECT_TRUE(end == Pickle::FindNext(pickle.header_size_, start, end + 1));
178}
179
glider@chromium.org8b725fa2011-01-26 22:02:27 +0900180TEST(PickleTest, FindNextWithIncompleteHeader) {
181 size_t header_size = sizeof(Pickle::Header);
182 scoped_array<char> buffer(new char[header_size - 1]);
183 memset(buffer.get(), 0x1, header_size - 1);
184
185 const char* start = buffer.get();
186 const char* end = start + header_size - 1;
187
188 EXPECT_TRUE(NULL == Pickle::FindNext(header_size, start, end));
189}
190
initial.commit3f4a7322008-07-27 06:49:38 +0900191TEST(PickleTest, IteratorHasRoom) {
192 Pickle pickle;
193 EXPECT_TRUE(pickle.WriteInt(1));
194 EXPECT_TRUE(pickle.WriteInt(2));
195
196 const void* iter = 0;
197 EXPECT_FALSE(pickle.IteratorHasRoomFor(iter, 1));
198 iter = pickle.payload();
199 EXPECT_TRUE(pickle.IteratorHasRoomFor(iter, 0));
200 EXPECT_TRUE(pickle.IteratorHasRoomFor(iter, 1));
201 EXPECT_FALSE(pickle.IteratorHasRoomFor(iter, -1));
202 EXPECT_TRUE(pickle.IteratorHasRoomFor(iter, sizeof(int) * 2));
203 EXPECT_FALSE(pickle.IteratorHasRoomFor(iter, (sizeof(int) * 2) + 1));
204}
205
206TEST(PickleTest, Resize) {
darin@google.comcf7eff42008-08-15 10:05:11 +0900207 size_t unit = Pickle::kPayloadUnit;
initial.commit3f4a7322008-07-27 06:49:38 +0900208 scoped_array<char> data(new char[unit]);
209 char* data_ptr = data.get();
darin@google.comcf7eff42008-08-15 10:05:11 +0900210 for (size_t i = 0; i < unit; i++)
initial.commit3f4a7322008-07-27 06:49:38 +0900211 data_ptr[i] = 'G';
212
213 // construct a message that will be exactly the size of one payload unit,
214 // note that any data will have a 4-byte header indicating the size
darin@google.comcf7eff42008-08-15 10:05:11 +0900215 const size_t payload_size_after_header = unit - sizeof(uint32);
initial.commit3f4a7322008-07-27 06:49:38 +0900216 Pickle pickle;
darin@google.com2c7afc12008-08-15 10:40:41 +0900217 pickle.WriteData(data_ptr,
218 static_cast<int>(payload_size_after_header - sizeof(uint32)));
darin@google.comcf7eff42008-08-15 10:05:11 +0900219 size_t cur_payload = payload_size_after_header;
initial.commit3f4a7322008-07-27 06:49:38 +0900220
mpcomplete@google.com54d2f942009-03-17 05:21:57 +0900221 // note: we assume 'unit' is a power of 2
222 EXPECT_EQ(unit, pickle.capacity());
initial.commit3f4a7322008-07-27 06:49:38 +0900223 EXPECT_EQ(pickle.payload_size(), payload_size_after_header);
224
225 // fill out a full page (noting data header)
darin@google.com2c7afc12008-08-15 10:40:41 +0900226 pickle.WriteData(data_ptr, static_cast<int>(unit - sizeof(uint32)));
initial.commit3f4a7322008-07-27 06:49:38 +0900227 cur_payload += unit;
darin@google.comcf7eff42008-08-15 10:05:11 +0900228 EXPECT_EQ(unit * 2, pickle.capacity());
initial.commit3f4a7322008-07-27 06:49:38 +0900229 EXPECT_EQ(cur_payload, pickle.payload_size());
230
mpcomplete@google.com54d2f942009-03-17 05:21:57 +0900231 // one more byte should double the capacity
initial.commit3f4a7322008-07-27 06:49:38 +0900232 pickle.WriteData(data_ptr, 1);
233 cur_payload += 5;
mpcomplete@google.com54d2f942009-03-17 05:21:57 +0900234 EXPECT_EQ(unit * 4, pickle.capacity());
initial.commit3f4a7322008-07-27 06:49:38 +0900235 EXPECT_EQ(cur_payload, pickle.payload_size());
236}
237
deanm@google.com75df3102008-08-07 22:40:16 +0900238namespace {
initial.commit3f4a7322008-07-27 06:49:38 +0900239
deanm@google.com75df3102008-08-07 22:40:16 +0900240struct CustomHeader : Pickle::Header {
241 int blah;
242};
243
244} // namespace
245
246TEST(PickleTest, HeaderPadding) {
initial.commit3f4a7322008-07-27 06:49:38 +0900247 const uint32 kMagic = 0x12345678;
248
249 Pickle pickle(sizeof(CustomHeader));
250 pickle.WriteInt(kMagic);
251
252 // this should not overwrite the 'int' payload
253 pickle.headerT<CustomHeader>()->blah = 10;
254
255 void* iter = NULL;
256 int result;
257 ASSERT_TRUE(pickle.ReadInt(&iter, &result));
258
darin@google.comcf7eff42008-08-15 10:05:11 +0900259 EXPECT_EQ(static_cast<uint32>(result), kMagic);
initial.commit3f4a7322008-07-27 06:49:38 +0900260}
261
262TEST(PickleTest, EqualsOperator) {
263 Pickle source;
264 source.WriteInt(1);
265
266 Pickle copy_refs_source_buffer(static_cast<const char*>(source.data()),
267 source.size());
268 Pickle copy;
269 copy = copy_refs_source_buffer;
270 ASSERT_EQ(source.size(), copy.size());
deanm@google.com75df3102008-08-07 22:40:16 +0900271}
cevans@chromium.orga834cdd2009-06-26 01:54:02 +0900272
273TEST(PickleTest, EvilLengths) {
274 Pickle source;
cevans@chromium.orgd8cb1122009-06-26 02:23:49 +0900275 std::string str(100000, 'A');
cevans@chromium.orga834cdd2009-06-26 01:54:02 +0900276 source.WriteData(str.c_str(), 100000);
277 // ReadString16 used to have its read buffer length calculation wrong leading
278 // to out-of-bounds reading.
279 void* iter = NULL;
280 string16 str16;
281 EXPECT_FALSE(source.ReadString16(&iter, &str16));
282
283 // And check we didn't break ReadString16.
284 str16 = (wchar_t) 'A';
285 Pickle str16_pickle;
286 str16_pickle.WriteString16(str16);
287 iter = NULL;
288 EXPECT_TRUE(str16_pickle.ReadString16(&iter, &str16));
289 EXPECT_EQ(1U, str16.length());
290
291 // Check we don't fail in a length check with large WStrings.
292 Pickle big_len;
293 big_len.WriteInt(1 << 30);
294 iter = NULL;
295 std::wstring wstr;
296 EXPECT_FALSE(big_len.ReadWString(&iter, &wstr));
297}
298
wtc@chromium.orgc2f15c52009-07-29 06:00:03 +0900299// Check we can write zero bytes of data and 'data' can be NULL.
300TEST(PickleTest, ZeroLength) {
301 Pickle pickle;
302 EXPECT_TRUE(pickle.WriteData(NULL, 0));
303
304 void* iter = NULL;
305 const char* outdata;
306 int outdatalen;
307 EXPECT_TRUE(pickle.ReadData(&iter, &outdata, &outdatalen));
308 EXPECT_EQ(0, outdatalen);
309 // We can't assert that outdata is NULL.
310}
311
mpcomplete@chromium.org0409ecb2010-03-31 08:52:24 +0900312// Check that ReadBytes works properly with an iterator initialized to NULL.
313TEST(PickleTest, ReadBytes) {
314 Pickle pickle;
315 int data = 0x7abcd;
316 EXPECT_TRUE(pickle.WriteBytes(&data, sizeof(data)));
317
318 void* iter = NULL;
319 const char* outdata_char;
320 EXPECT_TRUE(pickle.ReadBytes(&iter, &outdata_char, sizeof(data)));
321
322 int outdata;
323 memcpy(&outdata, outdata_char, sizeof(outdata));
324 EXPECT_EQ(data, outdata);
325}