blob: 45630470609e6ba0ca07bf0b2cd00890de0dfa0a [file] [log] [blame]
[email protected]ce208f872012-03-07 20:42:561// Copyright (c) 2012 The Chromium Authors. All rights reserved.
license.botbf09a502008-08-24 00:55:552// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
[email protected]d26cd5272008-08-07 13:40:164
dcheng093de9b2016-04-04 21:25:515#include "base/pickle.h"
6
avi9b6f42932015-12-26 22:15:147#include <limits.h>
8#include <stddef.h>
9#include <stdint.h>
10
dcheng093de9b2016-04-04 21:25:5111#include <memory>
[email protected]d26cd5272008-08-07 13:40:1612#include <string>
initial.commitd7cae122008-07-26 21:49:3813
avi9b6f42932015-12-26 22:15:1414#include "base/macros.h"
[email protected]d529cb02013-06-10 19:06:5715#include "base/strings/string16.h"
pkasting89a19f142014-10-02 03:01:0416#include "base/strings/utf_string_conversions.h"
initial.commitd7cae122008-07-26 21:49:3817#include "testing/gtest/include/gtest/gtest.h"
18
brettw05cfd8ddb2015-06-02 07:02:4719namespace base {
[email protected]476dafb2013-12-03 00:39:2620
initial.commitd7cae122008-07-26 21:49:3821namespace {
22
initial.commitd7cae122008-07-26 21:49:3823const bool testbool1 = false;
24const bool testbool2 = true;
Peter Kastinge72b278b2018-01-17 05:29:0925const int testint = 2'093'847'192;
26const long testlong = 1'093'847'192;
avi9b6f42932015-12-26 22:15:1427const uint16_t testuint16 = 32123;
28const uint32_t testuint32 = 1593847192;
Peter Kastinge72b278b2018-01-17 05:29:0929const int64_t testint64 = -0x7E8CA925'3104BDFCLL;
30const uint64_t testuint64 = 0xCE8CA925'3104BDF7ULL;
[email protected]b1f61b032012-11-28 15:40:5831const float testfloat = 3.1415926935f;
[email protected]915cc7d2014-07-14 22:50:3232const double testdouble = 2.71828182845904523;
pkasting89a19f142014-10-02 03:01:0433const std::string teststring("Hello world"); // note non-aligned string length
34const std::wstring testwstring(L"Hello, world");
brettw05cfd8ddb2015-06-02 07:02:4735const string16 teststring16(ASCIIToUTF16("Hello, world"));
brucedawsoneaa38962015-03-10 01:46:5036const char testrawstring[] = "Hello new world"; // Test raw string writing
37// Test raw char16 writing, assumes UTF16 encoding is ANSI for alpha chars.
brettw05cfd8ddb2015-06-02 07:02:4738const char16 testrawstring16[] = {'A', 'l', 'o', 'h', 'a', 0};
pkasting89a19f142014-10-02 03:01:0439const char testdata[] = "AAA\0BBB\0";
40const int testdatalen = arraysize(testdata) - 1;
initial.commitd7cae122008-07-26 21:49:3841
brucedawsoneaa38962015-03-10 01:46:5042// checks that the results can be read correctly from the Pickle
initial.commitd7cae122008-07-26 21:49:3843void VerifyResult(const Pickle& pickle) {
[email protected]ce208f872012-03-07 20:42:5644 PickleIterator iter(pickle);
initial.commitd7cae122008-07-26 21:49:3845
initial.commitd7cae122008-07-26 21:49:3846 bool outbool;
avi48fc13b2014-12-28 23:31:4847 EXPECT_TRUE(iter.ReadBool(&outbool));
[email protected]18853692013-01-03 12:30:5248 EXPECT_FALSE(outbool);
avi48fc13b2014-12-28 23:31:4849 EXPECT_TRUE(iter.ReadBool(&outbool));
[email protected]18853692013-01-03 12:30:5250 EXPECT_TRUE(outbool);
initial.commitd7cae122008-07-26 21:49:3851
pkasting89a19f142014-10-02 03:01:0452 int outint;
avi48fc13b2014-12-28 23:31:4853 EXPECT_TRUE(iter.ReadInt(&outint));
pkasting89a19f142014-10-02 03:01:0454 EXPECT_EQ(testint, outint);
55
56 long outlong;
avi48fc13b2014-12-28 23:31:4857 EXPECT_TRUE(iter.ReadLong(&outlong));
pkasting89a19f142014-10-02 03:01:0458 EXPECT_EQ(testlong, outlong);
59
avi9b6f42932015-12-26 22:15:1460 uint16_t outuint16;
avi48fc13b2014-12-28 23:31:4861 EXPECT_TRUE(iter.ReadUInt16(&outuint16));
[email protected]6d81b482011-02-22 19:47:1962 EXPECT_EQ(testuint16, outuint16);
63
avi9b6f42932015-12-26 22:15:1464 uint32_t outuint32;
avi48fc13b2014-12-28 23:31:4865 EXPECT_TRUE(iter.ReadUInt32(&outuint32));
pkasting89a19f142014-10-02 03:01:0466 EXPECT_EQ(testuint32, outuint32);
67
avi9b6f42932015-12-26 22:15:1468 int64_t outint64;
avi48fc13b2014-12-28 23:31:4869 EXPECT_TRUE(iter.ReadInt64(&outint64));
pkasting89a19f142014-10-02 03:01:0470 EXPECT_EQ(testint64, outint64);
71
avi9b6f42932015-12-26 22:15:1472 uint64_t outuint64;
avi48fc13b2014-12-28 23:31:4873 EXPECT_TRUE(iter.ReadUInt64(&outuint64));
pkasting89a19f142014-10-02 03:01:0474 EXPECT_EQ(testuint64, outuint64);
75
[email protected]b1f61b032012-11-28 15:40:5876 float outfloat;
avi48fc13b2014-12-28 23:31:4877 EXPECT_TRUE(iter.ReadFloat(&outfloat));
[email protected]b1f61b032012-11-28 15:40:5878 EXPECT_EQ(testfloat, outfloat);
79
[email protected]915cc7d2014-07-14 22:50:3280 double outdouble;
avi48fc13b2014-12-28 23:31:4881 EXPECT_TRUE(iter.ReadDouble(&outdouble));
[email protected]915cc7d2014-07-14 22:50:3282 EXPECT_EQ(testdouble, outdouble);
83
pkasting89a19f142014-10-02 03:01:0484 std::string outstring;
avi48fc13b2014-12-28 23:31:4885 EXPECT_TRUE(iter.ReadString(&outstring));
pkasting89a19f142014-10-02 03:01:0486 EXPECT_EQ(teststring, outstring);
87
brettw05cfd8ddb2015-06-02 07:02:4788 string16 outstring16;
avi48fc13b2014-12-28 23:31:4889 EXPECT_TRUE(iter.ReadString16(&outstring16));
pkasting89a19f142014-10-02 03:01:0490 EXPECT_EQ(teststring16, outstring16);
91
brettw05cfd8ddb2015-06-02 07:02:4792 StringPiece outstringpiece;
brucedawsoneaa38962015-03-10 01:46:5093 EXPECT_TRUE(iter.ReadStringPiece(&outstringpiece));
94 EXPECT_EQ(testrawstring, outstringpiece);
95
brettw05cfd8ddb2015-06-02 07:02:4796 StringPiece16 outstringpiece16;
brucedawsoneaa38962015-03-10 01:46:5097 EXPECT_TRUE(iter.ReadStringPiece16(&outstringpiece16));
98 EXPECT_EQ(testrawstring16, outstringpiece16);
99
initial.commitd7cae122008-07-26 21:49:38100 const char* outdata;
101 int outdatalen;
avi48fc13b2014-12-28 23:31:48102 EXPECT_TRUE(iter.ReadData(&outdata, &outdatalen));
initial.commitd7cae122008-07-26 21:49:38103 EXPECT_EQ(testdatalen, outdatalen);
104 EXPECT_EQ(memcmp(testdata, outdata, outdatalen), 0);
105
initial.commitd7cae122008-07-26 21:49:38106 // reads past the end should fail
avi48fc13b2014-12-28 23:31:48107 EXPECT_FALSE(iter.ReadInt(&outint));
initial.commitd7cae122008-07-26 21:49:38108}
109
110} // namespace
111
112TEST(PickleTest, EncodeDecode) {
113 Pickle pickle;
114
Daniel Cheng0d89f9222017-09-22 05:05:07115 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.commitd7cae122008-07-26 21:49:38130 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
jam03d8a782016-02-10 20:13:39142// Tests that reading/writing a long works correctly when the source process
pkasting89a19f142014-10-02 03:01:04143// is 64-bit. We rely on having both 32- and 64-bit trybots to validate both
144// arms of the conditional in this test.
jam03d8a782016-02-10 20:13:39145TEST(PickleTest, LongFrom64Bit) {
pkasting89a19f142014-10-02 03:01:04146 Pickle pickle;
jam03d8a782016-02-10 20:13:39147 // 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 Cheng0d89f9222017-09-22 05:05:07149 pickle.WriteInt64(testint64);
pkasting89a19f142014-10-02 03:01:04150
151 PickleIterator iter(pickle);
jam03d8a782016-02-10 20:13:39152 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
pkasting89a19f142014-10-02 03:01:04159 } else {
jam03d8a782016-02-10 20:13:39160 EXPECT_TRUE(iter.ReadLong(&outlong));
161 EXPECT_EQ(testint64, outlong);
pkasting89a19f142014-10-02 03:01:04162 }
163}
164
[email protected]d87f8e6f2010-11-15 19:31:23165// Tests that we can handle really small buffers.
166TEST(PickleTest, SmallBuffer) {
dcheng093de9b2016-04-04 21:25:51167 std::unique_ptr<char[]> buffer(new char[1]);
[email protected]d87f8e6f2010-11-15 19:31:23168
169 // We should not touch the buffer.
170 Pickle pickle(buffer.get(), 1);
171
[email protected]ce208f872012-03-07 20:42:56172 PickleIterator iter(pickle);
[email protected]d87f8e6f2010-11-15 19:31:23173 int data;
avi48fc13b2014-12-28 23:31:48174 EXPECT_FALSE(iter.ReadInt(&data));
[email protected]d87f8e6f2010-11-15 19:31:23175}
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
[email protected]ce208f872012-03-07 20:42:56183 PickleIterator iter(pickle);
[email protected]d87f8e6f2010-11-15 19:31:23184 int data;
avi48fc13b2014-12-28 23:31:48185 EXPECT_FALSE(iter.ReadInt(&data));
[email protected]d87f8e6f2010-11-15 19:31:23186}
187
188TEST(PickleTest, UnalignedSize) {
189 int buffer[] = { 10, 25, 40, 50 };
190
191 Pickle pickle(reinterpret_cast<char*>(buffer), sizeof(buffer));
192
[email protected]ce208f872012-03-07 20:42:56193 PickleIterator iter(pickle);
[email protected]d87f8e6f2010-11-15 19:31:23194 int data;
avi48fc13b2014-12-28 23:31:48195 EXPECT_FALSE(iter.ReadInt(&data));
[email protected]d87f8e6f2010-11-15 19:31:23196}
197
initial.commitd7cae122008-07-26 21:49:38198TEST(PickleTest, ZeroLenStr) {
199 Pickle pickle;
Daniel Cheng0d89f9222017-09-22 05:05:07200 pickle.WriteString(std::string());
initial.commitd7cae122008-07-26 21:49:38201
[email protected]ce208f872012-03-07 20:42:56202 PickleIterator iter(pickle);
initial.commitd7cae122008-07-26 21:49:38203 std::string outstr;
avi48fc13b2014-12-28 23:31:48204 EXPECT_TRUE(iter.ReadString(&outstr));
initial.commitd7cae122008-07-26 21:49:38205 EXPECT_EQ("", outstr);
206}
207
thestigf84f17f2015-03-11 20:41:55208TEST(PickleTest, ZeroLenStr16) {
initial.commitd7cae122008-07-26 21:49:38209 Pickle pickle;
Daniel Cheng0d89f9222017-09-22 05:05:07210 pickle.WriteString16(string16());
initial.commitd7cae122008-07-26 21:49:38211
[email protected]ce208f872012-03-07 20:42:56212 PickleIterator iter(pickle);
initial.commitd7cae122008-07-26 21:49:38213 std::string outstr;
avi48fc13b2014-12-28 23:31:48214 EXPECT_TRUE(iter.ReadString(&outstr));
initial.commitd7cae122008-07-26 21:49:38215 EXPECT_EQ("", outstr);
216}
217
218TEST(PickleTest, BadLenStr) {
219 Pickle pickle;
Daniel Cheng0d89f9222017-09-22 05:05:07220 pickle.WriteInt(-2);
initial.commitd7cae122008-07-26 21:49:38221
[email protected]ce208f872012-03-07 20:42:56222 PickleIterator iter(pickle);
initial.commitd7cae122008-07-26 21:49:38223 std::string outstr;
avi48fc13b2014-12-28 23:31:48224 EXPECT_FALSE(iter.ReadString(&outstr));
initial.commitd7cae122008-07-26 21:49:38225}
226
thestigf84f17f2015-03-11 20:41:55227TEST(PickleTest, BadLenStr16) {
initial.commitd7cae122008-07-26 21:49:38228 Pickle pickle;
Daniel Cheng0d89f9222017-09-22 05:05:07229 pickle.WriteInt(-1);
initial.commitd7cae122008-07-26 21:49:38230
[email protected]ce208f872012-03-07 20:42:56231 PickleIterator iter(pickle);
brettw05cfd8ddb2015-06-02 07:02:47232 string16 outstr;
thestigf84f17f2015-03-11 20:41:55233 EXPECT_FALSE(iter.ReadString16(&outstr));
initial.commitd7cae122008-07-26 21:49:38234}
235
dskiba6f3790a2015-09-30 17:24:30236TEST(PickleTest, PeekNext) {
237 struct CustomHeader : base::Pickle::Header {
238 int cookies[10];
239 };
240
241 Pickle pickle(sizeof(CustomHeader));
242
Daniel Cheng0d89f9222017-09-22 05:05:07243 pickle.WriteString("Goooooooooooogle");
dskiba6f3790a2015-09-30 17:24:30244
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.commitd7cae122008-07-26 21:49:38318TEST(PickleTest, FindNext) {
319 Pickle pickle;
Daniel Cheng0d89f9222017-09-22 05:05:07320 pickle.WriteInt(1);
321 pickle.WriteString("Domo");
initial.commitd7cae122008-07-26 21:49:38322
323 const char* start = reinterpret_cast<const char*>(pickle.data());
324 const char* end = start + pickle.size();
325
Ivan Kotenkova16212a52017-11-08 12:37:33326 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.commitd7cae122008-07-26 21:49:38329}
330
[email protected]137d2372011-01-26 13:02:27331TEST(PickleTest, FindNextWithIncompleteHeader) {
332 size_t header_size = sizeof(Pickle::Header);
dcheng093de9b2016-04-04 21:25:51333 std::unique_ptr<char[]> buffer(new char[header_size - 1]);
[email protected]137d2372011-01-26 13:02:27334 memset(buffer.get(), 0x1, header_size - 1);
335
336 const char* start = buffer.get();
337 const char* end = start + header_size - 1;
338
Ivan Kotenkova16212a52017-11-08 12:37:33339 EXPECT_EQ(nullptr, Pickle::FindNext(header_size, start, end));
[email protected]137d2372011-01-26 13:02:27340}
341
[email protected]9dbfa9842013-11-01 09:43:45342#if defined(COMPILER_MSVC)
343#pragma warning(push)
344#pragma warning(disable: 4146)
345#endif
[email protected]33a38dd2013-11-01 09:06:26346TEST(PickleTest, FindNextOverflow) {
347 size_t header_size = sizeof(Pickle::Header);
348 size_t header_size2 = 2 * header_size;
349 size_t payload_received = 100;
dcheng093de9b2016-04-04 21:25:51350 std::unique_ptr<char[]> buffer(new char[header_size2 + payload_received]);
[email protected]33a38dd2013-11-01 09:06:26351 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 Kotenkova16212a52017-11-08 12:37:33360 EXPECT_EQ(nullptr, Pickle::FindNext(header_size2, start, end));
[email protected]33a38dd2013-11-01 09:06:26361
362 header->payload_size = -header_size2;
Ivan Kotenkova16212a52017-11-08 12:37:33363 EXPECT_EQ(nullptr, Pickle::FindNext(header_size2, start, end));
[email protected]33a38dd2013-11-01 09:06:26364
365 header->payload_size = 0;
366 end = start + header_size;
Ivan Kotenkova16212a52017-11-08 12:37:33367 EXPECT_EQ(nullptr, Pickle::FindNext(header_size2, start, end));
[email protected]33a38dd2013-11-01 09:06:26368}
[email protected]9dbfa9842013-11-01 09:43:45369#if defined(COMPILER_MSVC)
370#pragma warning(pop)
371#endif
[email protected]33a38dd2013-11-01 09:06:26372
[email protected]ce208f872012-03-07 20:42:56373TEST(PickleTest, GetReadPointerAndAdvance) {
initial.commitd7cae122008-07-26 21:49:38374 Pickle pickle;
[email protected]ce208f872012-03-07 20:42:56375
376 PickleIterator iter(pickle);
377 EXPECT_FALSE(iter.GetReadPointerAndAdvance(1));
378
Daniel Cheng0d89f9222017-09-22 05:05:07379 pickle.WriteInt(1);
380 pickle.WriteInt(2);
[email protected]ce208f872012-03-07 20:42:56381 int bytes = sizeof(int) * 2;
initial.commitd7cae122008-07-26 21:49:38382
[email protected]ce208f872012-03-07 20:42:56383 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.commitd7cae122008-07-26 21:49:38390}
391
392TEST(PickleTest, Resize) {
[email protected]44a1cbfa2008-08-15 01:05:11393 size_t unit = Pickle::kPayloadUnit;
dcheng093de9b2016-04-04 21:25:51394 std::unique_ptr<char[]> data(new char[unit]);
initial.commitd7cae122008-07-26 21:49:38395 char* data_ptr = data.get();
[email protected]44a1cbfa2008-08-15 01:05:11396 for (size_t i = 0; i < unit; i++)
initial.commitd7cae122008-07-26 21:49:38397 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
avi9b6f42932015-12-26 22:15:14401 const size_t payload_size_after_header = unit - sizeof(uint32_t);
initial.commitd7cae122008-07-26 21:49:38402 Pickle pickle;
avi9b6f42932015-12-26 22:15:14403 pickle.WriteData(
404 data_ptr, static_cast<int>(payload_size_after_header - sizeof(uint32_t)));
[email protected]44a1cbfa2008-08-15 01:05:11405 size_t cur_payload = payload_size_after_header;
initial.commitd7cae122008-07-26 21:49:38406
[email protected]2de46262009-03-16 20:21:57407 // note: we assume 'unit' is a power of 2
[email protected]d1b319fc2013-10-31 04:03:02408 EXPECT_EQ(unit, pickle.capacity_after_header());
initial.commitd7cae122008-07-26 21:49:38409 EXPECT_EQ(pickle.payload_size(), payload_size_after_header);
410
411 // fill out a full page (noting data header)
avi9b6f42932015-12-26 22:15:14412 pickle.WriteData(data_ptr, static_cast<int>(unit - sizeof(uint32_t)));
initial.commitd7cae122008-07-26 21:49:38413 cur_payload += unit;
[email protected]d1b319fc2013-10-31 04:03:02414 EXPECT_EQ(unit * 2, pickle.capacity_after_header());
initial.commitd7cae122008-07-26 21:49:38415 EXPECT_EQ(cur_payload, pickle.payload_size());
416
[email protected]2de46262009-03-16 20:21:57417 // one more byte should double the capacity
initial.commitd7cae122008-07-26 21:49:38418 pickle.WriteData(data_ptr, 1);
[email protected]a15016f2014-06-02 23:23:49419 cur_payload += 8;
[email protected]d1b319fc2013-10-31 04:03:02420 EXPECT_EQ(unit * 4, pickle.capacity_after_header());
initial.commitd7cae122008-07-26 21:49:38421 EXPECT_EQ(cur_payload, pickle.payload_size());
422}
423
[email protected]d26cd5272008-08-07 13:40:16424namespace {
initial.commitd7cae122008-07-26 21:49:38425
[email protected]d26cd5272008-08-07 13:40:16426struct CustomHeader : Pickle::Header {
427 int blah;
428};
429
430} // namespace
431
432TEST(PickleTest, HeaderPadding) {
avi9b6f42932015-12-26 22:15:14433 const uint32_t kMagic = 0x12345678;
initial.commitd7cae122008-07-26 21:49:38434
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
[email protected]ce208f872012-03-07 20:42:56441 PickleIterator iter(pickle);
initial.commitd7cae122008-07-26 21:49:38442 int result;
avi48fc13b2014-12-28 23:31:48443 ASSERT_TRUE(iter.ReadInt(&result));
initial.commitd7cae122008-07-26 21:49:38444
avi9b6f42932015-12-26 22:15:14445 EXPECT_EQ(static_cast<uint32_t>(result), kMagic);
initial.commitd7cae122008-07-26 21:49:38446}
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());
[email protected]d26cd5272008-08-07 13:40:16457}
[email protected]87665562009-06-25 16:54:02458
459TEST(PickleTest, EvilLengths) {
460 Pickle source;
[email protected]b235357d2009-06-25 17:23:49461 std::string str(100000, 'A');
Daniel Cheng0d89f9222017-09-22 05:05:07462 source.WriteData(str.c_str(), 100000);
[email protected]87665562009-06-25 16:54:02463 // ReadString16 used to have its read buffer length calculation wrong leading
464 // to out-of-bounds reading.
[email protected]ce208f872012-03-07 20:42:56465 PickleIterator iter(source);
[email protected]87665562009-06-25 16:54:02466 string16 str16;
avi48fc13b2014-12-28 23:31:48467 EXPECT_FALSE(iter.ReadString16(&str16));
[email protected]87665562009-06-25 16:54:02468
469 // And check we didn't break ReadString16.
470 str16 = (wchar_t) 'A';
471 Pickle str16_pickle;
Daniel Cheng0d89f9222017-09-22 05:05:07472 str16_pickle.WriteString16(str16);
[email protected]ce208f872012-03-07 20:42:56473 iter = PickleIterator(str16_pickle);
avi48fc13b2014-12-28 23:31:48474 EXPECT_TRUE(iter.ReadString16(&str16));
[email protected]87665562009-06-25 16:54:02475 EXPECT_EQ(1U, str16.length());
476
[email protected]ce208f872012-03-07 20:42:56477 // 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 Cheng0d89f9222017-09-22 05:05:07480 bad_len.WriteInt(1 << 31);
[email protected]ce208f872012-03-07 20:42:56481 iter = PickleIterator(bad_len);
avi48fc13b2014-12-28 23:31:48482 EXPECT_FALSE(iter.ReadString16(&str16));
[email protected]87665562009-06-25 16:54:02483}
484
[email protected]e64ff5e2009-07-28 21:00:03485// Check we can write zero bytes of data and 'data' can be NULL.
486TEST(PickleTest, ZeroLength) {
487 Pickle pickle;
Ivan Kotenkova16212a52017-11-08 12:37:33488 pickle.WriteData(nullptr, 0);
[email protected]e64ff5e2009-07-28 21:00:03489
[email protected]ce208f872012-03-07 20:42:56490 PickleIterator iter(pickle);
[email protected]e64ff5e2009-07-28 21:00:03491 const char* outdata;
492 int outdatalen;
avi48fc13b2014-12-28 23:31:48493 EXPECT_TRUE(iter.ReadData(&outdata, &outdatalen));
[email protected]e64ff5e2009-07-28 21:00:03494 EXPECT_EQ(0, outdatalen);
495 // We can't assert that outdata is NULL.
496}
497
[email protected]26d2f472010-03-30 23:52:24498// Check that ReadBytes works properly with an iterator initialized to NULL.
499TEST(PickleTest, ReadBytes) {
500 Pickle pickle;
501 int data = 0x7abcd;
Daniel Cheng0d89f9222017-09-22 05:05:07502 pickle.WriteBytes(&data, sizeof(data));
[email protected]26d2f472010-03-30 23:52:24503
[email protected]ce208f872012-03-07 20:42:56504 PickleIterator iter(pickle);
Ivan Kotenkova16212a52017-11-08 12:37:33505 const char* outdata_char = nullptr;
avi48fc13b2014-12-28 23:31:48506 EXPECT_TRUE(iter.ReadBytes(&outdata_char, sizeof(data)));
[email protected]26d2f472010-03-30 23:52:24507
508 int outdata;
509 memcpy(&outdata, outdata_char, sizeof(outdata));
510 EXPECT_EQ(data, outdata);
511}
brettw05cfd8ddb2015-06-02 07:02:47512
erikchenf9ca8f5f02015-09-08 23:36:29513// 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
rockot0776a502015-12-17 06:19:49527namespace {
528
529// Publicly exposes the ClaimBytes interface for testing.
530class TestingPickle : public Pickle {
531 public:
Chris Watkinsbb7211c2017-11-29 07:16:38532 TestingPickle() = default;
rockot0776a502015-12-17 06:19:49533
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;
jam03d8a782016-02-10 20:13:39554 pickle.WriteUInt32(data.size());
rockot0776a502015-12-17 06:19:49555 void* bytes = pickle.ClaimBytes(data.size());
556 pickle.WriteInt(42);
557 memcpy(bytes, data.data(), data.size());
558
559 PickleIterator iter(pickle);
jam03d8a782016-02-10 20:13:39560 uint32_t out_data_length;
561 EXPECT_TRUE(iter.ReadUInt32(&out_data_length));
rockot0776a502015-12-17 06:19:49562 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
brettw05cfd8ddb2015-06-02 07:02:47573} // namespace base