blob: 45630470609e6ba0ca07bf0b2cd00890de0dfa0a [file] [log] [blame]
jbates@chromium.org0fc87362012-03-08 05:42:56 +09001// Copyright (c) 2012 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
dchengcc8e4d82016-04-05 06:25:51 +09005#include "base/pickle.h"
6
avia6a6a682015-12-27 07:15:14 +09007#include <limits.h>
8#include <stddef.h>
9#include <stdint.h>
10
dchengcc8e4d82016-04-05 06:25:51 +090011#include <memory>
deanm@google.com75df3102008-08-07 22:40:16 +090012#include <string>
initial.commit3f4a7322008-07-27 06:49:38 +090013
avia6a6a682015-12-27 07:15:14 +090014#include "base/macros.h"
avi@chromium.org67d593d2013-06-11 04:06:57 +090015#include "base/strings/string16.h"
pkasting7ed1f882014-10-02 12:01:04 +090016#include "base/strings/utf_string_conversions.h"
initial.commit3f4a7322008-07-27 06:49:38 +090017#include "testing/gtest/include/gtest/gtest.h"
18
brettwa4879472015-06-02 16:02:47 +090019namespace base {
brettw@chromium.org5b040852013-12-03 09:39:26 +090020
initial.commit3f4a7322008-07-27 06:49:38 +090021namespace {
22
initial.commit3f4a7322008-07-27 06:49:38 +090023const bool testbool1 = false;
24const bool testbool2 = true;
Peter Kasting56e720f2018-01-17 14:29:09 +090025const int testint = 2'093'847'192;
26const long testlong = 1'093'847'192;
avia6a6a682015-12-27 07:15:14 +090027const uint16_t testuint16 = 32123;
28const uint32_t testuint32 = 1593847192;
Peter Kasting56e720f2018-01-17 14:29:09 +090029const int64_t testint64 = -0x7E8CA925'3104BDFCLL;
30const uint64_t testuint64 = 0xCE8CA925'3104BDF7ULL;
rbyers@chromium.orga1f0b982012-11-29 00:40:58 +090031const float testfloat = 3.1415926935f;
mostynb@opera.comf0b78532014-07-15 07:50:32 +090032const double testdouble = 2.71828182845904523;
pkasting7ed1f882014-10-02 12:01:04 +090033const std::string teststring("Hello world"); // note non-aligned string length
34const std::wstring testwstring(L"Hello, world");
brettwa4879472015-06-02 16:02:47 +090035const string16 teststring16(ASCIIToUTF16("Hello, world"));
brucedawson0fff3892015-03-10 10:46:50 +090036const char testrawstring[] = "Hello new world"; // Test raw string writing
37// Test raw char16 writing, assumes UTF16 encoding is ANSI for alpha chars.
brettwa4879472015-06-02 16:02:47 +090038const char16 testrawstring16[] = {'A', 'l', 'o', 'h', 'a', 0};
pkasting7ed1f882014-10-02 12:01:04 +090039const char testdata[] = "AAA\0BBB\0";
40const int testdatalen = arraysize(testdata) - 1;
initial.commit3f4a7322008-07-27 06:49:38 +090041
brucedawson0fff3892015-03-10 10:46:50 +090042// checks that the results can be read correctly from the Pickle
initial.commit3f4a7322008-07-27 06:49:38 +090043void VerifyResult(const Pickle& pickle) {
jbates@chromium.org0fc87362012-03-08 05:42:56 +090044 PickleIterator iter(pickle);
initial.commit3f4a7322008-07-27 06:49:38 +090045
initial.commit3f4a7322008-07-27 06:49:38 +090046 bool outbool;
avic9f0ad02014-12-29 08:31:48 +090047 EXPECT_TRUE(iter.ReadBool(&outbool));
kamil.jiwa@gmail.com844e67a2013-01-03 21:30:52 +090048 EXPECT_FALSE(outbool);
avic9f0ad02014-12-29 08:31:48 +090049 EXPECT_TRUE(iter.ReadBool(&outbool));
kamil.jiwa@gmail.com844e67a2013-01-03 21:30:52 +090050 EXPECT_TRUE(outbool);
initial.commit3f4a7322008-07-27 06:49:38 +090051
pkasting7ed1f882014-10-02 12:01:04 +090052 int outint;
avic9f0ad02014-12-29 08:31:48 +090053 EXPECT_TRUE(iter.ReadInt(&outint));
pkasting7ed1f882014-10-02 12:01:04 +090054 EXPECT_EQ(testint, outint);
55
56 long outlong;
avic9f0ad02014-12-29 08:31:48 +090057 EXPECT_TRUE(iter.ReadLong(&outlong));
pkasting7ed1f882014-10-02 12:01:04 +090058 EXPECT_EQ(testlong, outlong);
59
avia6a6a682015-12-27 07:15:14 +090060 uint16_t outuint16;
avic9f0ad02014-12-29 08:31:48 +090061 EXPECT_TRUE(iter.ReadUInt16(&outuint16));
bryner@chromium.orgc85d0fd2011-02-23 04:47:19 +090062 EXPECT_EQ(testuint16, outuint16);
63
avia6a6a682015-12-27 07:15:14 +090064 uint32_t outuint32;
avic9f0ad02014-12-29 08:31:48 +090065 EXPECT_TRUE(iter.ReadUInt32(&outuint32));
pkasting7ed1f882014-10-02 12:01:04 +090066 EXPECT_EQ(testuint32, outuint32);
67
avia6a6a682015-12-27 07:15:14 +090068 int64_t outint64;
avic9f0ad02014-12-29 08:31:48 +090069 EXPECT_TRUE(iter.ReadInt64(&outint64));
pkasting7ed1f882014-10-02 12:01:04 +090070 EXPECT_EQ(testint64, outint64);
71
avia6a6a682015-12-27 07:15:14 +090072 uint64_t outuint64;
avic9f0ad02014-12-29 08:31:48 +090073 EXPECT_TRUE(iter.ReadUInt64(&outuint64));
pkasting7ed1f882014-10-02 12:01:04 +090074 EXPECT_EQ(testuint64, outuint64);
75
rbyers@chromium.orga1f0b982012-11-29 00:40:58 +090076 float outfloat;
avic9f0ad02014-12-29 08:31:48 +090077 EXPECT_TRUE(iter.ReadFloat(&outfloat));
rbyers@chromium.orga1f0b982012-11-29 00:40:58 +090078 EXPECT_EQ(testfloat, outfloat);
79
mostynb@opera.comf0b78532014-07-15 07:50:32 +090080 double outdouble;
avic9f0ad02014-12-29 08:31:48 +090081 EXPECT_TRUE(iter.ReadDouble(&outdouble));
mostynb@opera.comf0b78532014-07-15 07:50:32 +090082 EXPECT_EQ(testdouble, outdouble);
83
pkasting7ed1f882014-10-02 12:01:04 +090084 std::string outstring;
avic9f0ad02014-12-29 08:31:48 +090085 EXPECT_TRUE(iter.ReadString(&outstring));
pkasting7ed1f882014-10-02 12:01:04 +090086 EXPECT_EQ(teststring, outstring);
87
brettwa4879472015-06-02 16:02:47 +090088 string16 outstring16;
avic9f0ad02014-12-29 08:31:48 +090089 EXPECT_TRUE(iter.ReadString16(&outstring16));
pkasting7ed1f882014-10-02 12:01:04 +090090 EXPECT_EQ(teststring16, outstring16);
91
brettwa4879472015-06-02 16:02:47 +090092 StringPiece outstringpiece;
brucedawson0fff3892015-03-10 10:46:50 +090093 EXPECT_TRUE(iter.ReadStringPiece(&outstringpiece));
94 EXPECT_EQ(testrawstring, outstringpiece);
95
brettwa4879472015-06-02 16:02:47 +090096 StringPiece16 outstringpiece16;
brucedawson0fff3892015-03-10 10:46:50 +090097 EXPECT_TRUE(iter.ReadStringPiece16(&outstringpiece16));
98 EXPECT_EQ(testrawstring16, outstringpiece16);
99
initial.commit3f4a7322008-07-27 06:49:38 +0900100 const char* outdata;
101 int outdatalen;
avic9f0ad02014-12-29 08:31:48 +0900102 EXPECT_TRUE(iter.ReadData(&outdata, &outdatalen));
initial.commit3f4a7322008-07-27 06:49:38 +0900103 EXPECT_EQ(testdatalen, outdatalen);
104 EXPECT_EQ(memcmp(testdata, outdata, outdatalen), 0);
105
initial.commit3f4a7322008-07-27 06:49:38 +0900106 // reads past the end should fail
avic9f0ad02014-12-29 08:31:48 +0900107 EXPECT_FALSE(iter.ReadInt(&outint));
initial.commit3f4a7322008-07-27 06:49:38 +0900108}
109
110} // namespace
111
112TEST(PickleTest, EncodeDecode) {
113 Pickle pickle;
114
Daniel Cheng51215ca2017-09-22 14:05:07 +0900115 pickle.WriteBool(testbool1);
116 pickle.WriteBool(testbool2);
117 pickle.WriteInt(testint);
118 pickle.WriteLong(testlong);
119 pickle.WriteUInt16(testuint16);
120 pickle.WriteUInt32(testuint32);
121 pickle.WriteInt64(testint64);
122 pickle.WriteUInt64(testuint64);
123 pickle.WriteFloat(testfloat);
124 pickle.WriteDouble(testdouble);
125 pickle.WriteString(teststring);
126 pickle.WriteString16(teststring16);
127 pickle.WriteString(testrawstring);
128 pickle.WriteString16(testrawstring16);
129 pickle.WriteData(testdata, testdatalen);
initial.commit3f4a7322008-07-27 06:49:38 +0900130 VerifyResult(pickle);
131
132 // test copy constructor
133 Pickle pickle2(pickle);
134 VerifyResult(pickle2);
135
136 // test operator=
137 Pickle pickle3;
138 pickle3 = pickle;
139 VerifyResult(pickle3);
140}
141
jam923e5462016-02-11 05:13:39 +0900142// Tests that reading/writing a long works correctly when the source process
pkasting7ed1f882014-10-02 12:01:04 +0900143// is 64-bit. We rely on having both 32- and 64-bit trybots to validate both
144// arms of the conditional in this test.
jam923e5462016-02-11 05:13:39 +0900145TEST(PickleTest, LongFrom64Bit) {
pkasting7ed1f882014-10-02 12:01:04 +0900146 Pickle pickle;
jam923e5462016-02-11 05:13:39 +0900147 // Under the hood long is always written as a 64-bit value, so simulate a
148 // 64-bit long even on 32-bit architectures by explicitly writing an int64_t.
Daniel Cheng51215ca2017-09-22 14:05:07 +0900149 pickle.WriteInt64(testint64);
pkasting7ed1f882014-10-02 12:01:04 +0900150
151 PickleIterator iter(pickle);
jam923e5462016-02-11 05:13:39 +0900152 long outlong;
153 if (sizeof(long) < sizeof(int64_t)) {
154 // ReadLong() should return false when the original written value can't be
155 // represented as a long.
156#if GTEST_HAS_DEATH_TEST
157 EXPECT_DEATH(ignore_result(iter.ReadLong(&outlong)), "");
158#endif
pkasting7ed1f882014-10-02 12:01:04 +0900159 } else {
jam923e5462016-02-11 05:13:39 +0900160 EXPECT_TRUE(iter.ReadLong(&outlong));
161 EXPECT_EQ(testint64, outlong);
pkasting7ed1f882014-10-02 12:01:04 +0900162 }
163}
164
rvargas@google.com8d9b2b92010-11-16 04:31:23 +0900165// Tests that we can handle really small buffers.
166TEST(PickleTest, SmallBuffer) {
dchengcc8e4d82016-04-05 06:25:51 +0900167 std::unique_ptr<char[]> buffer(new char[1]);
rvargas@google.com8d9b2b92010-11-16 04:31:23 +0900168
169 // We should not touch the buffer.
170 Pickle pickle(buffer.get(), 1);
171
jbates@chromium.org0fc87362012-03-08 05:42:56 +0900172 PickleIterator iter(pickle);
rvargas@google.com8d9b2b92010-11-16 04:31:23 +0900173 int data;
avic9f0ad02014-12-29 08:31:48 +0900174 EXPECT_FALSE(iter.ReadInt(&data));
rvargas@google.com8d9b2b92010-11-16 04:31:23 +0900175}
176
177// Tests that we can handle improper headers.
178TEST(PickleTest, BigSize) {
179 int buffer[] = { 0x56035200, 25, 40, 50 };
180
181 Pickle pickle(reinterpret_cast<char*>(buffer), sizeof(buffer));
182
jbates@chromium.org0fc87362012-03-08 05:42:56 +0900183 PickleIterator iter(pickle);
rvargas@google.com8d9b2b92010-11-16 04:31:23 +0900184 int data;
avic9f0ad02014-12-29 08:31:48 +0900185 EXPECT_FALSE(iter.ReadInt(&data));
rvargas@google.com8d9b2b92010-11-16 04:31:23 +0900186}
187
188TEST(PickleTest, UnalignedSize) {
189 int buffer[] = { 10, 25, 40, 50 };
190
191 Pickle pickle(reinterpret_cast<char*>(buffer), sizeof(buffer));
192
jbates@chromium.org0fc87362012-03-08 05:42:56 +0900193 PickleIterator iter(pickle);
rvargas@google.com8d9b2b92010-11-16 04:31:23 +0900194 int data;
avic9f0ad02014-12-29 08:31:48 +0900195 EXPECT_FALSE(iter.ReadInt(&data));
rvargas@google.com8d9b2b92010-11-16 04:31:23 +0900196}
197
initial.commit3f4a7322008-07-27 06:49:38 +0900198TEST(PickleTest, ZeroLenStr) {
199 Pickle pickle;
Daniel Cheng51215ca2017-09-22 14:05:07 +0900200 pickle.WriteString(std::string());
initial.commit3f4a7322008-07-27 06:49:38 +0900201
jbates@chromium.org0fc87362012-03-08 05:42:56 +0900202 PickleIterator iter(pickle);
initial.commit3f4a7322008-07-27 06:49:38 +0900203 std::string outstr;
avic9f0ad02014-12-29 08:31:48 +0900204 EXPECT_TRUE(iter.ReadString(&outstr));
initial.commit3f4a7322008-07-27 06:49:38 +0900205 EXPECT_EQ("", outstr);
206}
207
thestig4a308552015-03-12 05:41:55 +0900208TEST(PickleTest, ZeroLenStr16) {
initial.commit3f4a7322008-07-27 06:49:38 +0900209 Pickle pickle;
Daniel Cheng51215ca2017-09-22 14:05:07 +0900210 pickle.WriteString16(string16());
initial.commit3f4a7322008-07-27 06:49:38 +0900211
jbates@chromium.org0fc87362012-03-08 05:42:56 +0900212 PickleIterator iter(pickle);
initial.commit3f4a7322008-07-27 06:49:38 +0900213 std::string outstr;
avic9f0ad02014-12-29 08:31:48 +0900214 EXPECT_TRUE(iter.ReadString(&outstr));
initial.commit3f4a7322008-07-27 06:49:38 +0900215 EXPECT_EQ("", outstr);
216}
217
218TEST(PickleTest, BadLenStr) {
219 Pickle pickle;
Daniel Cheng51215ca2017-09-22 14:05:07 +0900220 pickle.WriteInt(-2);
initial.commit3f4a7322008-07-27 06:49:38 +0900221
jbates@chromium.org0fc87362012-03-08 05:42:56 +0900222 PickleIterator iter(pickle);
initial.commit3f4a7322008-07-27 06:49:38 +0900223 std::string outstr;
avic9f0ad02014-12-29 08:31:48 +0900224 EXPECT_FALSE(iter.ReadString(&outstr));
initial.commit3f4a7322008-07-27 06:49:38 +0900225}
226
thestig4a308552015-03-12 05:41:55 +0900227TEST(PickleTest, BadLenStr16) {
initial.commit3f4a7322008-07-27 06:49:38 +0900228 Pickle pickle;
Daniel Cheng51215ca2017-09-22 14:05:07 +0900229 pickle.WriteInt(-1);
initial.commit3f4a7322008-07-27 06:49:38 +0900230
jbates@chromium.org0fc87362012-03-08 05:42:56 +0900231 PickleIterator iter(pickle);
brettwa4879472015-06-02 16:02:47 +0900232 string16 outstr;
thestig4a308552015-03-12 05:41:55 +0900233 EXPECT_FALSE(iter.ReadString16(&outstr));
initial.commit3f4a7322008-07-27 06:49:38 +0900234}
235
dskibaaa08dcb2015-10-01 02:24:30 +0900236TEST(PickleTest, PeekNext) {
237 struct CustomHeader : base::Pickle::Header {
238 int cookies[10];
239 };
240
241 Pickle pickle(sizeof(CustomHeader));
242
Daniel Cheng51215ca2017-09-22 14:05:07 +0900243 pickle.WriteString("Goooooooooooogle");
dskibaaa08dcb2015-10-01 02:24:30 +0900244
245 const char* pickle_data = static_cast<const char*>(pickle.data());
246
247 size_t pickle_size;
248
249 // Data range doesn't contain header
250 EXPECT_FALSE(Pickle::PeekNext(
251 sizeof(CustomHeader),
252 pickle_data,
253 pickle_data + sizeof(CustomHeader) - 1,
254 &pickle_size));
255
256 // Data range contains header
257 EXPECT_TRUE(Pickle::PeekNext(
258 sizeof(CustomHeader),
259 pickle_data,
260 pickle_data + sizeof(CustomHeader),
261 &pickle_size));
262 EXPECT_EQ(pickle_size, pickle.size());
263
264 // Data range contains header and some other data
265 EXPECT_TRUE(Pickle::PeekNext(
266 sizeof(CustomHeader),
267 pickle_data,
268 pickle_data + sizeof(CustomHeader) + 1,
269 &pickle_size));
270 EXPECT_EQ(pickle_size, pickle.size());
271
272 // Data range contains full pickle
273 EXPECT_TRUE(Pickle::PeekNext(
274 sizeof(CustomHeader),
275 pickle_data,
276 pickle_data + pickle.size(),
277 &pickle_size));
278 EXPECT_EQ(pickle_size, pickle.size());
279}
280
281TEST(PickleTest, PeekNextOverflow) {
282 struct CustomHeader : base::Pickle::Header {
283 int cookies[10];
284 };
285
286 CustomHeader header;
287
288 // Check if we can wrap around at all
289 if (sizeof(size_t) > sizeof(header.payload_size))
290 return;
291
292 const char* pickle_data = reinterpret_cast<const char*>(&header);
293
294 size_t pickle_size;
295
296 // Wrapping around is detected and reported as maximum size_t value
297 header.payload_size = static_cast<uint32_t>(
298 1 - static_cast<int32_t>(sizeof(CustomHeader)));
299 EXPECT_TRUE(Pickle::PeekNext(
300 sizeof(CustomHeader),
301 pickle_data,
302 pickle_data + sizeof(CustomHeader),
303 &pickle_size));
304 EXPECT_EQ(pickle_size, std::numeric_limits<size_t>::max());
305
306 // Ridiculous pickle sizes are fine (callers are supposed to
307 // verify them)
308 header.payload_size =
309 std::numeric_limits<uint32_t>::max() / 2 - sizeof(CustomHeader);
310 EXPECT_TRUE(Pickle::PeekNext(
311 sizeof(CustomHeader),
312 pickle_data,
313 pickle_data + sizeof(CustomHeader),
314 &pickle_size));
315 EXPECT_EQ(pickle_size, std::numeric_limits<uint32_t>::max() / 2);
316}
317
initial.commit3f4a7322008-07-27 06:49:38 +0900318TEST(PickleTest, FindNext) {
319 Pickle pickle;
Daniel Cheng51215ca2017-09-22 14:05:07 +0900320 pickle.WriteInt(1);
321 pickle.WriteString("Domo");
initial.commit3f4a7322008-07-27 06:49:38 +0900322
323 const char* start = reinterpret_cast<const char*>(pickle.data());
324 const char* end = start + pickle.size();
325
Ivan Kotenkove88f3462017-11-08 21:37:33 +0900326 EXPECT_EQ(end, Pickle::FindNext(pickle.header_size_, start, end));
327 EXPECT_EQ(nullptr, Pickle::FindNext(pickle.header_size_, start, end - 1));
328 EXPECT_EQ(end, Pickle::FindNext(pickle.header_size_, start, end + 1));
initial.commit3f4a7322008-07-27 06:49:38 +0900329}
330
glider@chromium.org8b725fa2011-01-26 22:02:27 +0900331TEST(PickleTest, FindNextWithIncompleteHeader) {
332 size_t header_size = sizeof(Pickle::Header);
dchengcc8e4d82016-04-05 06:25:51 +0900333 std::unique_ptr<char[]> buffer(new char[header_size - 1]);
glider@chromium.org8b725fa2011-01-26 22:02:27 +0900334 memset(buffer.get(), 0x1, header_size - 1);
335
336 const char* start = buffer.get();
337 const char* end = start + header_size - 1;
338
Ivan Kotenkove88f3462017-11-08 21:37:33 +0900339 EXPECT_EQ(nullptr, Pickle::FindNext(header_size, start, end));
glider@chromium.org8b725fa2011-01-26 22:02:27 +0900340}
341
halyavin@google.com12064802013-11-01 18:43:45 +0900342#if defined(COMPILER_MSVC)
343#pragma warning(push)
344#pragma warning(disable: 4146)
345#endif
halyavin@google.com893e5bb2013-11-01 18:06:26 +0900346TEST(PickleTest, FindNextOverflow) {
347 size_t header_size = sizeof(Pickle::Header);
348 size_t header_size2 = 2 * header_size;
349 size_t payload_received = 100;
dchengcc8e4d82016-04-05 06:25:51 +0900350 std::unique_ptr<char[]> buffer(new char[header_size2 + payload_received]);
halyavin@google.com893e5bb2013-11-01 18:06:26 +0900351 const char* start = buffer.get();
352 Pickle::Header* header = reinterpret_cast<Pickle::Header*>(buffer.get());
353 const char* end = start + header_size2 + payload_received;
354 // It is impossible to construct an overflow test otherwise.
355 if (sizeof(size_t) > sizeof(header->payload_size) ||
356 sizeof(uintptr_t) > sizeof(header->payload_size))
357 return;
358
359 header->payload_size = -(reinterpret_cast<uintptr_t>(start) + header_size2);
Ivan Kotenkove88f3462017-11-08 21:37:33 +0900360 EXPECT_EQ(nullptr, Pickle::FindNext(header_size2, start, end));
halyavin@google.com893e5bb2013-11-01 18:06:26 +0900361
362 header->payload_size = -header_size2;
Ivan Kotenkove88f3462017-11-08 21:37:33 +0900363 EXPECT_EQ(nullptr, Pickle::FindNext(header_size2, start, end));
halyavin@google.com893e5bb2013-11-01 18:06:26 +0900364
365 header->payload_size = 0;
366 end = start + header_size;
Ivan Kotenkove88f3462017-11-08 21:37:33 +0900367 EXPECT_EQ(nullptr, Pickle::FindNext(header_size2, start, end));
halyavin@google.com893e5bb2013-11-01 18:06:26 +0900368}
halyavin@google.com12064802013-11-01 18:43:45 +0900369#if defined(COMPILER_MSVC)
370#pragma warning(pop)
371#endif
halyavin@google.com893e5bb2013-11-01 18:06:26 +0900372
jbates@chromium.org0fc87362012-03-08 05:42:56 +0900373TEST(PickleTest, GetReadPointerAndAdvance) {
initial.commit3f4a7322008-07-27 06:49:38 +0900374 Pickle pickle;
jbates@chromium.org0fc87362012-03-08 05:42:56 +0900375
376 PickleIterator iter(pickle);
377 EXPECT_FALSE(iter.GetReadPointerAndAdvance(1));
378
Daniel Cheng51215ca2017-09-22 14:05:07 +0900379 pickle.WriteInt(1);
380 pickle.WriteInt(2);
jbates@chromium.org0fc87362012-03-08 05:42:56 +0900381 int bytes = sizeof(int) * 2;
initial.commit3f4a7322008-07-27 06:49:38 +0900382
jbates@chromium.org0fc87362012-03-08 05:42:56 +0900383 EXPECT_TRUE(PickleIterator(pickle).GetReadPointerAndAdvance(0));
384 EXPECT_TRUE(PickleIterator(pickle).GetReadPointerAndAdvance(1));
385 EXPECT_FALSE(PickleIterator(pickle).GetReadPointerAndAdvance(-1));
386 EXPECT_TRUE(PickleIterator(pickle).GetReadPointerAndAdvance(bytes));
387 EXPECT_FALSE(PickleIterator(pickle).GetReadPointerAndAdvance(bytes + 1));
388 EXPECT_FALSE(PickleIterator(pickle).GetReadPointerAndAdvance(INT_MAX));
389 EXPECT_FALSE(PickleIterator(pickle).GetReadPointerAndAdvance(INT_MIN));
initial.commit3f4a7322008-07-27 06:49:38 +0900390}
391
392TEST(PickleTest, Resize) {
darin@google.comcf7eff42008-08-15 10:05:11 +0900393 size_t unit = Pickle::kPayloadUnit;
dchengcc8e4d82016-04-05 06:25:51 +0900394 std::unique_ptr<char[]> data(new char[unit]);
initial.commit3f4a7322008-07-27 06:49:38 +0900395 char* data_ptr = data.get();
darin@google.comcf7eff42008-08-15 10:05:11 +0900396 for (size_t i = 0; i < unit; i++)
initial.commit3f4a7322008-07-27 06:49:38 +0900397 data_ptr[i] = 'G';
398
399 // construct a message that will be exactly the size of one payload unit,
400 // note that any data will have a 4-byte header indicating the size
avia6a6a682015-12-27 07:15:14 +0900401 const size_t payload_size_after_header = unit - sizeof(uint32_t);
initial.commit3f4a7322008-07-27 06:49:38 +0900402 Pickle pickle;
avia6a6a682015-12-27 07:15:14 +0900403 pickle.WriteData(
404 data_ptr, static_cast<int>(payload_size_after_header - sizeof(uint32_t)));
darin@google.comcf7eff42008-08-15 10:05:11 +0900405 size_t cur_payload = payload_size_after_header;
initial.commit3f4a7322008-07-27 06:49:38 +0900406
mpcomplete@google.com54d2f942009-03-17 05:21:57 +0900407 // note: we assume 'unit' is a power of 2
piman@chromium.org5d3eee22013-10-31 13:03:02 +0900408 EXPECT_EQ(unit, pickle.capacity_after_header());
initial.commit3f4a7322008-07-27 06:49:38 +0900409 EXPECT_EQ(pickle.payload_size(), payload_size_after_header);
410
411 // fill out a full page (noting data header)
avia6a6a682015-12-27 07:15:14 +0900412 pickle.WriteData(data_ptr, static_cast<int>(unit - sizeof(uint32_t)));
initial.commit3f4a7322008-07-27 06:49:38 +0900413 cur_payload += unit;
piman@chromium.org5d3eee22013-10-31 13:03:02 +0900414 EXPECT_EQ(unit * 2, pickle.capacity_after_header());
initial.commit3f4a7322008-07-27 06:49:38 +0900415 EXPECT_EQ(cur_payload, pickle.payload_size());
416
mpcomplete@google.com54d2f942009-03-17 05:21:57 +0900417 // one more byte should double the capacity
initial.commit3f4a7322008-07-27 06:49:38 +0900418 pickle.WriteData(data_ptr, 1);
halyavin@google.com0398c722014-06-03 08:23:49 +0900419 cur_payload += 8;
piman@chromium.org5d3eee22013-10-31 13:03:02 +0900420 EXPECT_EQ(unit * 4, pickle.capacity_after_header());
initial.commit3f4a7322008-07-27 06:49:38 +0900421 EXPECT_EQ(cur_payload, pickle.payload_size());
422}
423
deanm@google.com75df3102008-08-07 22:40:16 +0900424namespace {
initial.commit3f4a7322008-07-27 06:49:38 +0900425
deanm@google.com75df3102008-08-07 22:40:16 +0900426struct CustomHeader : Pickle::Header {
427 int blah;
428};
429
430} // namespace
431
432TEST(PickleTest, HeaderPadding) {
avia6a6a682015-12-27 07:15:14 +0900433 const uint32_t kMagic = 0x12345678;
initial.commit3f4a7322008-07-27 06:49:38 +0900434
435 Pickle pickle(sizeof(CustomHeader));
436 pickle.WriteInt(kMagic);
437
438 // this should not overwrite the 'int' payload
439 pickle.headerT<CustomHeader>()->blah = 10;
440
jbates@chromium.org0fc87362012-03-08 05:42:56 +0900441 PickleIterator iter(pickle);
initial.commit3f4a7322008-07-27 06:49:38 +0900442 int result;
avic9f0ad02014-12-29 08:31:48 +0900443 ASSERT_TRUE(iter.ReadInt(&result));
initial.commit3f4a7322008-07-27 06:49:38 +0900444
avia6a6a682015-12-27 07:15:14 +0900445 EXPECT_EQ(static_cast<uint32_t>(result), kMagic);
initial.commit3f4a7322008-07-27 06:49:38 +0900446}
447
448TEST(PickleTest, EqualsOperator) {
449 Pickle source;
450 source.WriteInt(1);
451
452 Pickle copy_refs_source_buffer(static_cast<const char*>(source.data()),
453 source.size());
454 Pickle copy;
455 copy = copy_refs_source_buffer;
456 ASSERT_EQ(source.size(), copy.size());
deanm@google.com75df3102008-08-07 22:40:16 +0900457}
cevans@chromium.orga834cdd2009-06-26 01:54:02 +0900458
459TEST(PickleTest, EvilLengths) {
460 Pickle source;
cevans@chromium.orgd8cb1122009-06-26 02:23:49 +0900461 std::string str(100000, 'A');
Daniel Cheng51215ca2017-09-22 14:05:07 +0900462 source.WriteData(str.c_str(), 100000);
cevans@chromium.orga834cdd2009-06-26 01:54:02 +0900463 // ReadString16 used to have its read buffer length calculation wrong leading
464 // to out-of-bounds reading.
jbates@chromium.org0fc87362012-03-08 05:42:56 +0900465 PickleIterator iter(source);
cevans@chromium.orga834cdd2009-06-26 01:54:02 +0900466 string16 str16;
avic9f0ad02014-12-29 08:31:48 +0900467 EXPECT_FALSE(iter.ReadString16(&str16));
cevans@chromium.orga834cdd2009-06-26 01:54:02 +0900468
469 // And check we didn't break ReadString16.
470 str16 = (wchar_t) 'A';
471 Pickle str16_pickle;
Daniel Cheng51215ca2017-09-22 14:05:07 +0900472 str16_pickle.WriteString16(str16);
jbates@chromium.org0fc87362012-03-08 05:42:56 +0900473 iter = PickleIterator(str16_pickle);
avic9f0ad02014-12-29 08:31:48 +0900474 EXPECT_TRUE(iter.ReadString16(&str16));
cevans@chromium.orga834cdd2009-06-26 01:54:02 +0900475 EXPECT_EQ(1U, str16.length());
476
jbates@chromium.org0fc87362012-03-08 05:42:56 +0900477 // Check we don't fail in a length check with invalid String16 size.
478 // (1<<31) * sizeof(char16) == 0, so this is particularly evil.
479 Pickle bad_len;
Daniel Cheng51215ca2017-09-22 14:05:07 +0900480 bad_len.WriteInt(1 << 31);
jbates@chromium.org0fc87362012-03-08 05:42:56 +0900481 iter = PickleIterator(bad_len);
avic9f0ad02014-12-29 08:31:48 +0900482 EXPECT_FALSE(iter.ReadString16(&str16));
cevans@chromium.orga834cdd2009-06-26 01:54:02 +0900483}
484
wtc@chromium.orgc2f15c52009-07-29 06:00:03 +0900485// Check we can write zero bytes of data and 'data' can be NULL.
486TEST(PickleTest, ZeroLength) {
487 Pickle pickle;
Ivan Kotenkove88f3462017-11-08 21:37:33 +0900488 pickle.WriteData(nullptr, 0);
wtc@chromium.orgc2f15c52009-07-29 06:00:03 +0900489
jbates@chromium.org0fc87362012-03-08 05:42:56 +0900490 PickleIterator iter(pickle);
wtc@chromium.orgc2f15c52009-07-29 06:00:03 +0900491 const char* outdata;
492 int outdatalen;
avic9f0ad02014-12-29 08:31:48 +0900493 EXPECT_TRUE(iter.ReadData(&outdata, &outdatalen));
wtc@chromium.orgc2f15c52009-07-29 06:00:03 +0900494 EXPECT_EQ(0, outdatalen);
495 // We can't assert that outdata is NULL.
496}
497
mpcomplete@chromium.org0409ecb2010-03-31 08:52:24 +0900498// Check that ReadBytes works properly with an iterator initialized to NULL.
499TEST(PickleTest, ReadBytes) {
500 Pickle pickle;
501 int data = 0x7abcd;
Daniel Cheng51215ca2017-09-22 14:05:07 +0900502 pickle.WriteBytes(&data, sizeof(data));
mpcomplete@chromium.org0409ecb2010-03-31 08:52:24 +0900503
jbates@chromium.org0fc87362012-03-08 05:42:56 +0900504 PickleIterator iter(pickle);
Ivan Kotenkove88f3462017-11-08 21:37:33 +0900505 const char* outdata_char = nullptr;
avic9f0ad02014-12-29 08:31:48 +0900506 EXPECT_TRUE(iter.ReadBytes(&outdata_char, sizeof(data)));
mpcomplete@chromium.org0409ecb2010-03-31 08:52:24 +0900507
508 int outdata;
509 memcpy(&outdata, outdata_char, sizeof(outdata));
510 EXPECT_EQ(data, outdata);
511}
brettwa4879472015-06-02 16:02:47 +0900512
erikchenb2ca7762015-09-09 08:36:29 +0900513// Checks that when a pickle is deep-copied, the result is not larger than
514// needed.
515TEST(PickleTest, DeepCopyResize) {
516 Pickle pickle;
517 while (pickle.capacity_after_header() != pickle.payload_size())
518 pickle.WriteBool(true);
519
520 // Make a deep copy.
521 Pickle pickle2(pickle);
522
523 // Check that there isn't any extraneous capacity.
524 EXPECT_EQ(pickle.capacity_after_header(), pickle2.capacity_after_header());
525}
526
rockot76180b02015-12-17 15:19:49 +0900527namespace {
528
529// Publicly exposes the ClaimBytes interface for testing.
530class TestingPickle : public Pickle {
531 public:
Chris Watkinsd155d9f2017-11-29 16:16:38 +0900532 TestingPickle() = default;
rockot76180b02015-12-17 15:19:49 +0900533
534 void* ClaimBytes(size_t num_bytes) { return Pickle::ClaimBytes(num_bytes); }
535};
536
537} // namespace
538
539// Checks that claimed bytes are zero-initialized.
540TEST(PickleTest, ClaimBytesInitialization) {
541 static const int kChunkSize = 64;
542 TestingPickle pickle;
543 const char* bytes = static_cast<const char*>(pickle.ClaimBytes(kChunkSize));
544 for (size_t i = 0; i < kChunkSize; ++i) {
545 EXPECT_EQ(0, bytes[i]);
546 }
547}
548
549// Checks that ClaimBytes properly advances the write offset.
550TEST(PickleTest, ClaimBytes) {
551 std::string data("Hello, world!");
552
553 TestingPickle pickle;
jam923e5462016-02-11 05:13:39 +0900554 pickle.WriteUInt32(data.size());
rockot76180b02015-12-17 15:19:49 +0900555 void* bytes = pickle.ClaimBytes(data.size());
556 pickle.WriteInt(42);
557 memcpy(bytes, data.data(), data.size());
558
559 PickleIterator iter(pickle);
jam923e5462016-02-11 05:13:39 +0900560 uint32_t out_data_length;
561 EXPECT_TRUE(iter.ReadUInt32(&out_data_length));
rockot76180b02015-12-17 15:19:49 +0900562 EXPECT_EQ(data.size(), out_data_length);
563
564 const char* out_data = nullptr;
565 EXPECT_TRUE(iter.ReadBytes(&out_data, out_data_length));
566 EXPECT_EQ(data, std::string(out_data, out_data_length));
567
568 int out_value;
569 EXPECT_TRUE(iter.ReadInt(&out_value));
570 EXPECT_EQ(42, out_value);
571}
572
brettwa4879472015-06-02 16:02:47 +0900573} // namespace base