1*635a8641SAndroid Build Coastguard Worker // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2*635a8641SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*635a8641SAndroid Build Coastguard Worker // found in the LICENSE file.
4*635a8641SAndroid Build Coastguard Worker
5*635a8641SAndroid Build Coastguard Worker #include "base/pickle.h"
6*635a8641SAndroid Build Coastguard Worker
7*635a8641SAndroid Build Coastguard Worker #include <limits.h>
8*635a8641SAndroid Build Coastguard Worker #include <stddef.h>
9*635a8641SAndroid Build Coastguard Worker #include <stdint.h>
10*635a8641SAndroid Build Coastguard Worker
11*635a8641SAndroid Build Coastguard Worker #include <memory>
12*635a8641SAndroid Build Coastguard Worker #include <string>
13*635a8641SAndroid Build Coastguard Worker
14*635a8641SAndroid Build Coastguard Worker #include "base/macros.h"
15*635a8641SAndroid Build Coastguard Worker #include "base/strings/string16.h"
16*635a8641SAndroid Build Coastguard Worker #include "base/strings/utf_string_conversions.h"
17*635a8641SAndroid Build Coastguard Worker #include "testing/gtest/include/gtest/gtest.h"
18*635a8641SAndroid Build Coastguard Worker
19*635a8641SAndroid Build Coastguard Worker namespace base {
20*635a8641SAndroid Build Coastguard Worker
21*635a8641SAndroid Build Coastguard Worker namespace {
22*635a8641SAndroid Build Coastguard Worker
23*635a8641SAndroid Build Coastguard Worker const bool testbool1 = false;
24*635a8641SAndroid Build Coastguard Worker const bool testbool2 = true;
25*635a8641SAndroid Build Coastguard Worker const int testint = 2'093'847'192;
26*635a8641SAndroid Build Coastguard Worker const long testlong = 1'093'847'192;
27*635a8641SAndroid Build Coastguard Worker const uint16_t testuint16 = 32123;
28*635a8641SAndroid Build Coastguard Worker const uint32_t testuint32 = 1593847192;
29*635a8641SAndroid Build Coastguard Worker const int64_t testint64 = -0x7E8CA925'3104BDFCLL;
30*635a8641SAndroid Build Coastguard Worker const uint64_t testuint64 = 0xCE8CA925'3104BDF7ULL;
31*635a8641SAndroid Build Coastguard Worker const float testfloat = 3.1415926935f;
32*635a8641SAndroid Build Coastguard Worker const double testdouble = 2.71828182845904523;
33*635a8641SAndroid Build Coastguard Worker const std::string teststring("Hello world"); // note non-aligned string length
34*635a8641SAndroid Build Coastguard Worker const std::wstring testwstring(L"Hello, world");
35*635a8641SAndroid Build Coastguard Worker const string16 teststring16(ASCIIToUTF16("Hello, world"));
36*635a8641SAndroid Build Coastguard Worker const char testrawstring[] = "Hello new world"; // Test raw string writing
37*635a8641SAndroid Build Coastguard Worker // Test raw char16 writing, assumes UTF16 encoding is ANSI for alpha chars.
38*635a8641SAndroid Build Coastguard Worker const char16 testrawstring16[] = {'A', 'l', 'o', 'h', 'a', 0};
39*635a8641SAndroid Build Coastguard Worker const char testdata[] = "AAA\0BBB\0";
40*635a8641SAndroid Build Coastguard Worker const int testdatalen = arraysize(testdata) - 1;
41*635a8641SAndroid Build Coastguard Worker
42*635a8641SAndroid Build Coastguard Worker // checks that the results can be read correctly from the Pickle
VerifyResult(const Pickle & pickle)43*635a8641SAndroid Build Coastguard Worker void VerifyResult(const Pickle& pickle) {
44*635a8641SAndroid Build Coastguard Worker PickleIterator iter(pickle);
45*635a8641SAndroid Build Coastguard Worker
46*635a8641SAndroid Build Coastguard Worker bool outbool;
47*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(iter.ReadBool(&outbool));
48*635a8641SAndroid Build Coastguard Worker EXPECT_FALSE(outbool);
49*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(iter.ReadBool(&outbool));
50*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(outbool);
51*635a8641SAndroid Build Coastguard Worker
52*635a8641SAndroid Build Coastguard Worker int outint;
53*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(iter.ReadInt(&outint));
54*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(testint, outint);
55*635a8641SAndroid Build Coastguard Worker
56*635a8641SAndroid Build Coastguard Worker long outlong;
57*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(iter.ReadLong(&outlong));
58*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(testlong, outlong);
59*635a8641SAndroid Build Coastguard Worker
60*635a8641SAndroid Build Coastguard Worker uint16_t outuint16;
61*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(iter.ReadUInt16(&outuint16));
62*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(testuint16, outuint16);
63*635a8641SAndroid Build Coastguard Worker
64*635a8641SAndroid Build Coastguard Worker uint32_t outuint32;
65*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(iter.ReadUInt32(&outuint32));
66*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(testuint32, outuint32);
67*635a8641SAndroid Build Coastguard Worker
68*635a8641SAndroid Build Coastguard Worker int64_t outint64;
69*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(iter.ReadInt64(&outint64));
70*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(testint64, outint64);
71*635a8641SAndroid Build Coastguard Worker
72*635a8641SAndroid Build Coastguard Worker uint64_t outuint64;
73*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(iter.ReadUInt64(&outuint64));
74*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(testuint64, outuint64);
75*635a8641SAndroid Build Coastguard Worker
76*635a8641SAndroid Build Coastguard Worker float outfloat;
77*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(iter.ReadFloat(&outfloat));
78*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(testfloat, outfloat);
79*635a8641SAndroid Build Coastguard Worker
80*635a8641SAndroid Build Coastguard Worker double outdouble;
81*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(iter.ReadDouble(&outdouble));
82*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(testdouble, outdouble);
83*635a8641SAndroid Build Coastguard Worker
84*635a8641SAndroid Build Coastguard Worker std::string outstring;
85*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(iter.ReadString(&outstring));
86*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(teststring, outstring);
87*635a8641SAndroid Build Coastguard Worker
88*635a8641SAndroid Build Coastguard Worker string16 outstring16;
89*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(iter.ReadString16(&outstring16));
90*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(teststring16, outstring16);
91*635a8641SAndroid Build Coastguard Worker
92*635a8641SAndroid Build Coastguard Worker StringPiece outstringpiece;
93*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(iter.ReadStringPiece(&outstringpiece));
94*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(testrawstring, outstringpiece);
95*635a8641SAndroid Build Coastguard Worker
96*635a8641SAndroid Build Coastguard Worker StringPiece16 outstringpiece16;
97*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(iter.ReadStringPiece16(&outstringpiece16));
98*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(testrawstring16, outstringpiece16);
99*635a8641SAndroid Build Coastguard Worker
100*635a8641SAndroid Build Coastguard Worker const char* outdata;
101*635a8641SAndroid Build Coastguard Worker int outdatalen;
102*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(iter.ReadData(&outdata, &outdatalen));
103*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(testdatalen, outdatalen);
104*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(memcmp(testdata, outdata, outdatalen), 0);
105*635a8641SAndroid Build Coastguard Worker
106*635a8641SAndroid Build Coastguard Worker // reads past the end should fail
107*635a8641SAndroid Build Coastguard Worker EXPECT_FALSE(iter.ReadInt(&outint));
108*635a8641SAndroid Build Coastguard Worker }
109*635a8641SAndroid Build Coastguard Worker
110*635a8641SAndroid Build Coastguard Worker } // namespace
111*635a8641SAndroid Build Coastguard Worker
TEST(PickleTest,EncodeDecode)112*635a8641SAndroid Build Coastguard Worker TEST(PickleTest, EncodeDecode) {
113*635a8641SAndroid Build Coastguard Worker Pickle pickle;
114*635a8641SAndroid Build Coastguard Worker
115*635a8641SAndroid Build Coastguard Worker pickle.WriteBool(testbool1);
116*635a8641SAndroid Build Coastguard Worker pickle.WriteBool(testbool2);
117*635a8641SAndroid Build Coastguard Worker pickle.WriteInt(testint);
118*635a8641SAndroid Build Coastguard Worker pickle.WriteLong(testlong);
119*635a8641SAndroid Build Coastguard Worker pickle.WriteUInt16(testuint16);
120*635a8641SAndroid Build Coastguard Worker pickle.WriteUInt32(testuint32);
121*635a8641SAndroid Build Coastguard Worker pickle.WriteInt64(testint64);
122*635a8641SAndroid Build Coastguard Worker pickle.WriteUInt64(testuint64);
123*635a8641SAndroid Build Coastguard Worker pickle.WriteFloat(testfloat);
124*635a8641SAndroid Build Coastguard Worker pickle.WriteDouble(testdouble);
125*635a8641SAndroid Build Coastguard Worker pickle.WriteString(teststring);
126*635a8641SAndroid Build Coastguard Worker pickle.WriteString16(teststring16);
127*635a8641SAndroid Build Coastguard Worker pickle.WriteString(testrawstring);
128*635a8641SAndroid Build Coastguard Worker pickle.WriteString16(testrawstring16);
129*635a8641SAndroid Build Coastguard Worker pickle.WriteData(testdata, testdatalen);
130*635a8641SAndroid Build Coastguard Worker VerifyResult(pickle);
131*635a8641SAndroid Build Coastguard Worker
132*635a8641SAndroid Build Coastguard Worker // test copy constructor
133*635a8641SAndroid Build Coastguard Worker Pickle pickle2(pickle);
134*635a8641SAndroid Build Coastguard Worker VerifyResult(pickle2);
135*635a8641SAndroid Build Coastguard Worker
136*635a8641SAndroid Build Coastguard Worker // test operator=
137*635a8641SAndroid Build Coastguard Worker Pickle pickle3;
138*635a8641SAndroid Build Coastguard Worker pickle3 = pickle;
139*635a8641SAndroid Build Coastguard Worker VerifyResult(pickle3);
140*635a8641SAndroid Build Coastguard Worker }
141*635a8641SAndroid Build Coastguard Worker
142*635a8641SAndroid Build Coastguard Worker // Tests that reading/writing a long works correctly when the source process
143*635a8641SAndroid Build Coastguard Worker // is 64-bit. We rely on having both 32- and 64-bit trybots to validate both
144*635a8641SAndroid Build Coastguard Worker // arms of the conditional in this test.
TEST(PickleTest,LongFrom64Bit)145*635a8641SAndroid Build Coastguard Worker TEST(PickleTest, LongFrom64Bit) {
146*635a8641SAndroid Build Coastguard Worker Pickle pickle;
147*635a8641SAndroid Build Coastguard Worker // Under the hood long is always written as a 64-bit value, so simulate a
148*635a8641SAndroid Build Coastguard Worker // 64-bit long even on 32-bit architectures by explicitly writing an int64_t.
149*635a8641SAndroid Build Coastguard Worker pickle.WriteInt64(testint64);
150*635a8641SAndroid Build Coastguard Worker
151*635a8641SAndroid Build Coastguard Worker PickleIterator iter(pickle);
152*635a8641SAndroid Build Coastguard Worker long outlong;
153*635a8641SAndroid Build Coastguard Worker if (sizeof(long) < sizeof(int64_t)) {
154*635a8641SAndroid Build Coastguard Worker // ReadLong() should return false when the original written value can't be
155*635a8641SAndroid Build Coastguard Worker // represented as a long.
156*635a8641SAndroid Build Coastguard Worker #if GTEST_HAS_DEATH_TEST
157*635a8641SAndroid Build Coastguard Worker EXPECT_DEATH(ignore_result(iter.ReadLong(&outlong)), "");
158*635a8641SAndroid Build Coastguard Worker #endif
159*635a8641SAndroid Build Coastguard Worker } else {
160*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(iter.ReadLong(&outlong));
161*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(testint64, outlong);
162*635a8641SAndroid Build Coastguard Worker }
163*635a8641SAndroid Build Coastguard Worker }
164*635a8641SAndroid Build Coastguard Worker
165*635a8641SAndroid Build Coastguard Worker // Tests that we can handle really small buffers.
TEST(PickleTest,SmallBuffer)166*635a8641SAndroid Build Coastguard Worker TEST(PickleTest, SmallBuffer) {
167*635a8641SAndroid Build Coastguard Worker std::unique_ptr<char[]> buffer(new char[1]);
168*635a8641SAndroid Build Coastguard Worker
169*635a8641SAndroid Build Coastguard Worker // We should not touch the buffer.
170*635a8641SAndroid Build Coastguard Worker Pickle pickle(buffer.get(), 1);
171*635a8641SAndroid Build Coastguard Worker
172*635a8641SAndroid Build Coastguard Worker PickleIterator iter(pickle);
173*635a8641SAndroid Build Coastguard Worker int data;
174*635a8641SAndroid Build Coastguard Worker EXPECT_FALSE(iter.ReadInt(&data));
175*635a8641SAndroid Build Coastguard Worker }
176*635a8641SAndroid Build Coastguard Worker
177*635a8641SAndroid Build Coastguard Worker // Tests that we can handle improper headers.
TEST(PickleTest,BigSize)178*635a8641SAndroid Build Coastguard Worker TEST(PickleTest, BigSize) {
179*635a8641SAndroid Build Coastguard Worker int buffer[] = { 0x56035200, 25, 40, 50 };
180*635a8641SAndroid Build Coastguard Worker
181*635a8641SAndroid Build Coastguard Worker Pickle pickle(reinterpret_cast<char*>(buffer), sizeof(buffer));
182*635a8641SAndroid Build Coastguard Worker
183*635a8641SAndroid Build Coastguard Worker PickleIterator iter(pickle);
184*635a8641SAndroid Build Coastguard Worker int data;
185*635a8641SAndroid Build Coastguard Worker EXPECT_FALSE(iter.ReadInt(&data));
186*635a8641SAndroid Build Coastguard Worker }
187*635a8641SAndroid Build Coastguard Worker
TEST(PickleTest,UnalignedSize)188*635a8641SAndroid Build Coastguard Worker TEST(PickleTest, UnalignedSize) {
189*635a8641SAndroid Build Coastguard Worker int buffer[] = { 10, 25, 40, 50 };
190*635a8641SAndroid Build Coastguard Worker
191*635a8641SAndroid Build Coastguard Worker Pickle pickle(reinterpret_cast<char*>(buffer), sizeof(buffer));
192*635a8641SAndroid Build Coastguard Worker
193*635a8641SAndroid Build Coastguard Worker PickleIterator iter(pickle);
194*635a8641SAndroid Build Coastguard Worker int data;
195*635a8641SAndroid Build Coastguard Worker EXPECT_FALSE(iter.ReadInt(&data));
196*635a8641SAndroid Build Coastguard Worker }
197*635a8641SAndroid Build Coastguard Worker
TEST(PickleTest,ZeroLenStr)198*635a8641SAndroid Build Coastguard Worker TEST(PickleTest, ZeroLenStr) {
199*635a8641SAndroid Build Coastguard Worker Pickle pickle;
200*635a8641SAndroid Build Coastguard Worker pickle.WriteString(std::string());
201*635a8641SAndroid Build Coastguard Worker
202*635a8641SAndroid Build Coastguard Worker PickleIterator iter(pickle);
203*635a8641SAndroid Build Coastguard Worker std::string outstr;
204*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(iter.ReadString(&outstr));
205*635a8641SAndroid Build Coastguard Worker EXPECT_EQ("", outstr);
206*635a8641SAndroid Build Coastguard Worker }
207*635a8641SAndroid Build Coastguard Worker
TEST(PickleTest,ZeroLenStr16)208*635a8641SAndroid Build Coastguard Worker TEST(PickleTest, ZeroLenStr16) {
209*635a8641SAndroid Build Coastguard Worker Pickle pickle;
210*635a8641SAndroid Build Coastguard Worker pickle.WriteString16(string16());
211*635a8641SAndroid Build Coastguard Worker
212*635a8641SAndroid Build Coastguard Worker PickleIterator iter(pickle);
213*635a8641SAndroid Build Coastguard Worker std::string outstr;
214*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(iter.ReadString(&outstr));
215*635a8641SAndroid Build Coastguard Worker EXPECT_EQ("", outstr);
216*635a8641SAndroid Build Coastguard Worker }
217*635a8641SAndroid Build Coastguard Worker
TEST(PickleTest,BadLenStr)218*635a8641SAndroid Build Coastguard Worker TEST(PickleTest, BadLenStr) {
219*635a8641SAndroid Build Coastguard Worker Pickle pickle;
220*635a8641SAndroid Build Coastguard Worker pickle.WriteInt(-2);
221*635a8641SAndroid Build Coastguard Worker
222*635a8641SAndroid Build Coastguard Worker PickleIterator iter(pickle);
223*635a8641SAndroid Build Coastguard Worker std::string outstr;
224*635a8641SAndroid Build Coastguard Worker EXPECT_FALSE(iter.ReadString(&outstr));
225*635a8641SAndroid Build Coastguard Worker }
226*635a8641SAndroid Build Coastguard Worker
TEST(PickleTest,BadLenStr16)227*635a8641SAndroid Build Coastguard Worker TEST(PickleTest, BadLenStr16) {
228*635a8641SAndroid Build Coastguard Worker Pickle pickle;
229*635a8641SAndroid Build Coastguard Worker pickle.WriteInt(-1);
230*635a8641SAndroid Build Coastguard Worker
231*635a8641SAndroid Build Coastguard Worker PickleIterator iter(pickle);
232*635a8641SAndroid Build Coastguard Worker string16 outstr;
233*635a8641SAndroid Build Coastguard Worker EXPECT_FALSE(iter.ReadString16(&outstr));
234*635a8641SAndroid Build Coastguard Worker }
235*635a8641SAndroid Build Coastguard Worker
TEST(PickleTest,PeekNext)236*635a8641SAndroid Build Coastguard Worker TEST(PickleTest, PeekNext) {
237*635a8641SAndroid Build Coastguard Worker struct CustomHeader : base::Pickle::Header {
238*635a8641SAndroid Build Coastguard Worker int cookies[10];
239*635a8641SAndroid Build Coastguard Worker };
240*635a8641SAndroid Build Coastguard Worker
241*635a8641SAndroid Build Coastguard Worker Pickle pickle(sizeof(CustomHeader));
242*635a8641SAndroid Build Coastguard Worker
243*635a8641SAndroid Build Coastguard Worker pickle.WriteString("Goooooooooooogle");
244*635a8641SAndroid Build Coastguard Worker
245*635a8641SAndroid Build Coastguard Worker const char* pickle_data = static_cast<const char*>(pickle.data());
246*635a8641SAndroid Build Coastguard Worker
247*635a8641SAndroid Build Coastguard Worker size_t pickle_size;
248*635a8641SAndroid Build Coastguard Worker
249*635a8641SAndroid Build Coastguard Worker // Data range doesn't contain header
250*635a8641SAndroid Build Coastguard Worker EXPECT_FALSE(Pickle::PeekNext(
251*635a8641SAndroid Build Coastguard Worker sizeof(CustomHeader),
252*635a8641SAndroid Build Coastguard Worker pickle_data,
253*635a8641SAndroid Build Coastguard Worker pickle_data + sizeof(CustomHeader) - 1,
254*635a8641SAndroid Build Coastguard Worker &pickle_size));
255*635a8641SAndroid Build Coastguard Worker
256*635a8641SAndroid Build Coastguard Worker // Data range contains header
257*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(Pickle::PeekNext(
258*635a8641SAndroid Build Coastguard Worker sizeof(CustomHeader),
259*635a8641SAndroid Build Coastguard Worker pickle_data,
260*635a8641SAndroid Build Coastguard Worker pickle_data + sizeof(CustomHeader),
261*635a8641SAndroid Build Coastguard Worker &pickle_size));
262*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(pickle_size, pickle.size());
263*635a8641SAndroid Build Coastguard Worker
264*635a8641SAndroid Build Coastguard Worker // Data range contains header and some other data
265*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(Pickle::PeekNext(
266*635a8641SAndroid Build Coastguard Worker sizeof(CustomHeader),
267*635a8641SAndroid Build Coastguard Worker pickle_data,
268*635a8641SAndroid Build Coastguard Worker pickle_data + sizeof(CustomHeader) + 1,
269*635a8641SAndroid Build Coastguard Worker &pickle_size));
270*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(pickle_size, pickle.size());
271*635a8641SAndroid Build Coastguard Worker
272*635a8641SAndroid Build Coastguard Worker // Data range contains full pickle
273*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(Pickle::PeekNext(
274*635a8641SAndroid Build Coastguard Worker sizeof(CustomHeader),
275*635a8641SAndroid Build Coastguard Worker pickle_data,
276*635a8641SAndroid Build Coastguard Worker pickle_data + pickle.size(),
277*635a8641SAndroid Build Coastguard Worker &pickle_size));
278*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(pickle_size, pickle.size());
279*635a8641SAndroid Build Coastguard Worker }
280*635a8641SAndroid Build Coastguard Worker
TEST(PickleTest,PeekNextOverflow)281*635a8641SAndroid Build Coastguard Worker TEST(PickleTest, PeekNextOverflow) {
282*635a8641SAndroid Build Coastguard Worker struct CustomHeader : base::Pickle::Header {
283*635a8641SAndroid Build Coastguard Worker int cookies[10];
284*635a8641SAndroid Build Coastguard Worker };
285*635a8641SAndroid Build Coastguard Worker
286*635a8641SAndroid Build Coastguard Worker CustomHeader header;
287*635a8641SAndroid Build Coastguard Worker
288*635a8641SAndroid Build Coastguard Worker // Check if we can wrap around at all
289*635a8641SAndroid Build Coastguard Worker if (sizeof(size_t) > sizeof(header.payload_size))
290*635a8641SAndroid Build Coastguard Worker return;
291*635a8641SAndroid Build Coastguard Worker
292*635a8641SAndroid Build Coastguard Worker const char* pickle_data = reinterpret_cast<const char*>(&header);
293*635a8641SAndroid Build Coastguard Worker
294*635a8641SAndroid Build Coastguard Worker size_t pickle_size;
295*635a8641SAndroid Build Coastguard Worker
296*635a8641SAndroid Build Coastguard Worker // Wrapping around is detected and reported as maximum size_t value
297*635a8641SAndroid Build Coastguard Worker header.payload_size = static_cast<uint32_t>(
298*635a8641SAndroid Build Coastguard Worker 1 - static_cast<int32_t>(sizeof(CustomHeader)));
299*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(Pickle::PeekNext(
300*635a8641SAndroid Build Coastguard Worker sizeof(CustomHeader),
301*635a8641SAndroid Build Coastguard Worker pickle_data,
302*635a8641SAndroid Build Coastguard Worker pickle_data + sizeof(CustomHeader),
303*635a8641SAndroid Build Coastguard Worker &pickle_size));
304*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(pickle_size, std::numeric_limits<size_t>::max());
305*635a8641SAndroid Build Coastguard Worker
306*635a8641SAndroid Build Coastguard Worker // Ridiculous pickle sizes are fine (callers are supposed to
307*635a8641SAndroid Build Coastguard Worker // verify them)
308*635a8641SAndroid Build Coastguard Worker header.payload_size =
309*635a8641SAndroid Build Coastguard Worker std::numeric_limits<uint32_t>::max() / 2 - sizeof(CustomHeader);
310*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(Pickle::PeekNext(
311*635a8641SAndroid Build Coastguard Worker sizeof(CustomHeader),
312*635a8641SAndroid Build Coastguard Worker pickle_data,
313*635a8641SAndroid Build Coastguard Worker pickle_data + sizeof(CustomHeader),
314*635a8641SAndroid Build Coastguard Worker &pickle_size));
315*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(pickle_size, std::numeric_limits<uint32_t>::max() / 2);
316*635a8641SAndroid Build Coastguard Worker }
317*635a8641SAndroid Build Coastguard Worker
TEST(PickleTest,FindNext)318*635a8641SAndroid Build Coastguard Worker TEST(PickleTest, FindNext) {
319*635a8641SAndroid Build Coastguard Worker Pickle pickle;
320*635a8641SAndroid Build Coastguard Worker pickle.WriteInt(1);
321*635a8641SAndroid Build Coastguard Worker pickle.WriteString("Domo");
322*635a8641SAndroid Build Coastguard Worker
323*635a8641SAndroid Build Coastguard Worker const char* start = reinterpret_cast<const char*>(pickle.data());
324*635a8641SAndroid Build Coastguard Worker const char* end = start + pickle.size();
325*635a8641SAndroid Build Coastguard Worker
326*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(end, Pickle::FindNext(pickle.header_size_, start, end));
327*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(nullptr, Pickle::FindNext(pickle.header_size_, start, end - 1));
328*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(end, Pickle::FindNext(pickle.header_size_, start, end + 1));
329*635a8641SAndroid Build Coastguard Worker }
330*635a8641SAndroid Build Coastguard Worker
TEST(PickleTest,FindNextWithIncompleteHeader)331*635a8641SAndroid Build Coastguard Worker TEST(PickleTest, FindNextWithIncompleteHeader) {
332*635a8641SAndroid Build Coastguard Worker size_t header_size = sizeof(Pickle::Header);
333*635a8641SAndroid Build Coastguard Worker std::unique_ptr<char[]> buffer(new char[header_size - 1]);
334*635a8641SAndroid Build Coastguard Worker memset(buffer.get(), 0x1, header_size - 1);
335*635a8641SAndroid Build Coastguard Worker
336*635a8641SAndroid Build Coastguard Worker const char* start = buffer.get();
337*635a8641SAndroid Build Coastguard Worker const char* end = start + header_size - 1;
338*635a8641SAndroid Build Coastguard Worker
339*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(nullptr, Pickle::FindNext(header_size, start, end));
340*635a8641SAndroid Build Coastguard Worker }
341*635a8641SAndroid Build Coastguard Worker
342*635a8641SAndroid Build Coastguard Worker #if defined(COMPILER_MSVC)
343*635a8641SAndroid Build Coastguard Worker #pragma warning(push)
344*635a8641SAndroid Build Coastguard Worker #pragma warning(disable: 4146)
345*635a8641SAndroid Build Coastguard Worker #endif
TEST(PickleTest,FindNextOverflow)346*635a8641SAndroid Build Coastguard Worker TEST(PickleTest, FindNextOverflow) {
347*635a8641SAndroid Build Coastguard Worker size_t header_size = sizeof(Pickle::Header);
348*635a8641SAndroid Build Coastguard Worker size_t header_size2 = 2 * header_size;
349*635a8641SAndroid Build Coastguard Worker size_t payload_received = 100;
350*635a8641SAndroid Build Coastguard Worker std::unique_ptr<char[]> buffer(new char[header_size2 + payload_received]);
351*635a8641SAndroid Build Coastguard Worker const char* start = buffer.get();
352*635a8641SAndroid Build Coastguard Worker Pickle::Header* header = reinterpret_cast<Pickle::Header*>(buffer.get());
353*635a8641SAndroid Build Coastguard Worker const char* end = start + header_size2 + payload_received;
354*635a8641SAndroid Build Coastguard Worker // It is impossible to construct an overflow test otherwise.
355*635a8641SAndroid Build Coastguard Worker if (sizeof(size_t) > sizeof(header->payload_size) ||
356*635a8641SAndroid Build Coastguard Worker sizeof(uintptr_t) > sizeof(header->payload_size))
357*635a8641SAndroid Build Coastguard Worker return;
358*635a8641SAndroid Build Coastguard Worker
359*635a8641SAndroid Build Coastguard Worker header->payload_size = -(reinterpret_cast<uintptr_t>(start) + header_size2);
360*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(nullptr, Pickle::FindNext(header_size2, start, end));
361*635a8641SAndroid Build Coastguard Worker
362*635a8641SAndroid Build Coastguard Worker header->payload_size = -header_size2;
363*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(nullptr, Pickle::FindNext(header_size2, start, end));
364*635a8641SAndroid Build Coastguard Worker
365*635a8641SAndroid Build Coastguard Worker header->payload_size = 0;
366*635a8641SAndroid Build Coastguard Worker end = start + header_size;
367*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(nullptr, Pickle::FindNext(header_size2, start, end));
368*635a8641SAndroid Build Coastguard Worker }
369*635a8641SAndroid Build Coastguard Worker #if defined(COMPILER_MSVC)
370*635a8641SAndroid Build Coastguard Worker #pragma warning(pop)
371*635a8641SAndroid Build Coastguard Worker #endif
372*635a8641SAndroid Build Coastguard Worker
TEST(PickleTest,GetReadPointerAndAdvance)373*635a8641SAndroid Build Coastguard Worker TEST(PickleTest, GetReadPointerAndAdvance) {
374*635a8641SAndroid Build Coastguard Worker Pickle pickle;
375*635a8641SAndroid Build Coastguard Worker
376*635a8641SAndroid Build Coastguard Worker PickleIterator iter(pickle);
377*635a8641SAndroid Build Coastguard Worker EXPECT_FALSE(iter.GetReadPointerAndAdvance(1));
378*635a8641SAndroid Build Coastguard Worker
379*635a8641SAndroid Build Coastguard Worker pickle.WriteInt(1);
380*635a8641SAndroid Build Coastguard Worker pickle.WriteInt(2);
381*635a8641SAndroid Build Coastguard Worker int bytes = sizeof(int) * 2;
382*635a8641SAndroid Build Coastguard Worker
383*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(PickleIterator(pickle).GetReadPointerAndAdvance(0));
384*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(PickleIterator(pickle).GetReadPointerAndAdvance(1));
385*635a8641SAndroid Build Coastguard Worker EXPECT_FALSE(PickleIterator(pickle).GetReadPointerAndAdvance(-1));
386*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(PickleIterator(pickle).GetReadPointerAndAdvance(bytes));
387*635a8641SAndroid Build Coastguard Worker EXPECT_FALSE(PickleIterator(pickle).GetReadPointerAndAdvance(bytes + 1));
388*635a8641SAndroid Build Coastguard Worker EXPECT_FALSE(PickleIterator(pickle).GetReadPointerAndAdvance(INT_MAX));
389*635a8641SAndroid Build Coastguard Worker EXPECT_FALSE(PickleIterator(pickle).GetReadPointerAndAdvance(INT_MIN));
390*635a8641SAndroid Build Coastguard Worker }
391*635a8641SAndroid Build Coastguard Worker
TEST(PickleTest,Resize)392*635a8641SAndroid Build Coastguard Worker TEST(PickleTest, Resize) {
393*635a8641SAndroid Build Coastguard Worker size_t unit = Pickle::kPayloadUnit;
394*635a8641SAndroid Build Coastguard Worker std::unique_ptr<char[]> data(new char[unit]);
395*635a8641SAndroid Build Coastguard Worker char* data_ptr = data.get();
396*635a8641SAndroid Build Coastguard Worker for (size_t i = 0; i < unit; i++)
397*635a8641SAndroid Build Coastguard Worker data_ptr[i] = 'G';
398*635a8641SAndroid Build Coastguard Worker
399*635a8641SAndroid Build Coastguard Worker // construct a message that will be exactly the size of one payload unit,
400*635a8641SAndroid Build Coastguard Worker // note that any data will have a 4-byte header indicating the size
401*635a8641SAndroid Build Coastguard Worker const size_t payload_size_after_header = unit - sizeof(uint32_t);
402*635a8641SAndroid Build Coastguard Worker Pickle pickle;
403*635a8641SAndroid Build Coastguard Worker pickle.WriteData(
404*635a8641SAndroid Build Coastguard Worker data_ptr, static_cast<int>(payload_size_after_header - sizeof(uint32_t)));
405*635a8641SAndroid Build Coastguard Worker size_t cur_payload = payload_size_after_header;
406*635a8641SAndroid Build Coastguard Worker
407*635a8641SAndroid Build Coastguard Worker // note: we assume 'unit' is a power of 2
408*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(unit, pickle.capacity_after_header());
409*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(pickle.payload_size(), payload_size_after_header);
410*635a8641SAndroid Build Coastguard Worker
411*635a8641SAndroid Build Coastguard Worker // fill out a full page (noting data header)
412*635a8641SAndroid Build Coastguard Worker pickle.WriteData(data_ptr, static_cast<int>(unit - sizeof(uint32_t)));
413*635a8641SAndroid Build Coastguard Worker cur_payload += unit;
414*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(unit * 2, pickle.capacity_after_header());
415*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(cur_payload, pickle.payload_size());
416*635a8641SAndroid Build Coastguard Worker
417*635a8641SAndroid Build Coastguard Worker // one more byte should double the capacity
418*635a8641SAndroid Build Coastguard Worker pickle.WriteData(data_ptr, 1);
419*635a8641SAndroid Build Coastguard Worker cur_payload += 8;
420*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(unit * 4, pickle.capacity_after_header());
421*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(cur_payload, pickle.payload_size());
422*635a8641SAndroid Build Coastguard Worker }
423*635a8641SAndroid Build Coastguard Worker
424*635a8641SAndroid Build Coastguard Worker namespace {
425*635a8641SAndroid Build Coastguard Worker
426*635a8641SAndroid Build Coastguard Worker struct CustomHeader : Pickle::Header {
427*635a8641SAndroid Build Coastguard Worker int blah;
428*635a8641SAndroid Build Coastguard Worker };
429*635a8641SAndroid Build Coastguard Worker
430*635a8641SAndroid Build Coastguard Worker } // namespace
431*635a8641SAndroid Build Coastguard Worker
TEST(PickleTest,HeaderPadding)432*635a8641SAndroid Build Coastguard Worker TEST(PickleTest, HeaderPadding) {
433*635a8641SAndroid Build Coastguard Worker const uint32_t kMagic = 0x12345678;
434*635a8641SAndroid Build Coastguard Worker
435*635a8641SAndroid Build Coastguard Worker Pickle pickle(sizeof(CustomHeader));
436*635a8641SAndroid Build Coastguard Worker pickle.WriteInt(kMagic);
437*635a8641SAndroid Build Coastguard Worker
438*635a8641SAndroid Build Coastguard Worker // this should not overwrite the 'int' payload
439*635a8641SAndroid Build Coastguard Worker pickle.headerT<CustomHeader>()->blah = 10;
440*635a8641SAndroid Build Coastguard Worker
441*635a8641SAndroid Build Coastguard Worker PickleIterator iter(pickle);
442*635a8641SAndroid Build Coastguard Worker int result;
443*635a8641SAndroid Build Coastguard Worker ASSERT_TRUE(iter.ReadInt(&result));
444*635a8641SAndroid Build Coastguard Worker
445*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(static_cast<uint32_t>(result), kMagic);
446*635a8641SAndroid Build Coastguard Worker }
447*635a8641SAndroid Build Coastguard Worker
TEST(PickleTest,EqualsOperator)448*635a8641SAndroid Build Coastguard Worker TEST(PickleTest, EqualsOperator) {
449*635a8641SAndroid Build Coastguard Worker Pickle source;
450*635a8641SAndroid Build Coastguard Worker source.WriteInt(1);
451*635a8641SAndroid Build Coastguard Worker
452*635a8641SAndroid Build Coastguard Worker Pickle copy_refs_source_buffer(static_cast<const char*>(source.data()),
453*635a8641SAndroid Build Coastguard Worker source.size());
454*635a8641SAndroid Build Coastguard Worker Pickle copy;
455*635a8641SAndroid Build Coastguard Worker copy = copy_refs_source_buffer;
456*635a8641SAndroid Build Coastguard Worker ASSERT_EQ(source.size(), copy.size());
457*635a8641SAndroid Build Coastguard Worker }
458*635a8641SAndroid Build Coastguard Worker
TEST(PickleTest,EvilLengths)459*635a8641SAndroid Build Coastguard Worker TEST(PickleTest, EvilLengths) {
460*635a8641SAndroid Build Coastguard Worker Pickle source;
461*635a8641SAndroid Build Coastguard Worker std::string str(100000, 'A');
462*635a8641SAndroid Build Coastguard Worker source.WriteData(str.c_str(), 100000);
463*635a8641SAndroid Build Coastguard Worker // ReadString16 used to have its read buffer length calculation wrong leading
464*635a8641SAndroid Build Coastguard Worker // to out-of-bounds reading.
465*635a8641SAndroid Build Coastguard Worker PickleIterator iter(source);
466*635a8641SAndroid Build Coastguard Worker string16 str16;
467*635a8641SAndroid Build Coastguard Worker EXPECT_FALSE(iter.ReadString16(&str16));
468*635a8641SAndroid Build Coastguard Worker
469*635a8641SAndroid Build Coastguard Worker // And check we didn't break ReadString16.
470*635a8641SAndroid Build Coastguard Worker str16 = (wchar_t) 'A';
471*635a8641SAndroid Build Coastguard Worker Pickle str16_pickle;
472*635a8641SAndroid Build Coastguard Worker str16_pickle.WriteString16(str16);
473*635a8641SAndroid Build Coastguard Worker iter = PickleIterator(str16_pickle);
474*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(iter.ReadString16(&str16));
475*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(1U, str16.length());
476*635a8641SAndroid Build Coastguard Worker
477*635a8641SAndroid Build Coastguard Worker // Check we don't fail in a length check with invalid String16 size.
478*635a8641SAndroid Build Coastguard Worker // (1<<31) * sizeof(char16) == 0, so this is particularly evil.
479*635a8641SAndroid Build Coastguard Worker Pickle bad_len;
480*635a8641SAndroid Build Coastguard Worker bad_len.WriteInt(1 << 31);
481*635a8641SAndroid Build Coastguard Worker iter = PickleIterator(bad_len);
482*635a8641SAndroid Build Coastguard Worker EXPECT_FALSE(iter.ReadString16(&str16));
483*635a8641SAndroid Build Coastguard Worker }
484*635a8641SAndroid Build Coastguard Worker
485*635a8641SAndroid Build Coastguard Worker // Check we can write zero bytes of data and 'data' can be NULL.
TEST(PickleTest,ZeroLength)486*635a8641SAndroid Build Coastguard Worker TEST(PickleTest, ZeroLength) {
487*635a8641SAndroid Build Coastguard Worker Pickle pickle;
488*635a8641SAndroid Build Coastguard Worker pickle.WriteData(nullptr, 0);
489*635a8641SAndroid Build Coastguard Worker
490*635a8641SAndroid Build Coastguard Worker PickleIterator iter(pickle);
491*635a8641SAndroid Build Coastguard Worker const char* outdata;
492*635a8641SAndroid Build Coastguard Worker int outdatalen;
493*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(iter.ReadData(&outdata, &outdatalen));
494*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(0, outdatalen);
495*635a8641SAndroid Build Coastguard Worker // We can't assert that outdata is NULL.
496*635a8641SAndroid Build Coastguard Worker }
497*635a8641SAndroid Build Coastguard Worker
498*635a8641SAndroid Build Coastguard Worker // Check that ReadBytes works properly with an iterator initialized to NULL.
TEST(PickleTest,ReadBytes)499*635a8641SAndroid Build Coastguard Worker TEST(PickleTest, ReadBytes) {
500*635a8641SAndroid Build Coastguard Worker Pickle pickle;
501*635a8641SAndroid Build Coastguard Worker int data = 0x7abcd;
502*635a8641SAndroid Build Coastguard Worker pickle.WriteBytes(&data, sizeof(data));
503*635a8641SAndroid Build Coastguard Worker
504*635a8641SAndroid Build Coastguard Worker PickleIterator iter(pickle);
505*635a8641SAndroid Build Coastguard Worker const char* outdata_char = nullptr;
506*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(iter.ReadBytes(&outdata_char, sizeof(data)));
507*635a8641SAndroid Build Coastguard Worker
508*635a8641SAndroid Build Coastguard Worker int outdata;
509*635a8641SAndroid Build Coastguard Worker memcpy(&outdata, outdata_char, sizeof(outdata));
510*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(data, outdata);
511*635a8641SAndroid Build Coastguard Worker }
512*635a8641SAndroid Build Coastguard Worker
513*635a8641SAndroid Build Coastguard Worker // Checks that when a pickle is deep-copied, the result is not larger than
514*635a8641SAndroid Build Coastguard Worker // needed.
TEST(PickleTest,DeepCopyResize)515*635a8641SAndroid Build Coastguard Worker TEST(PickleTest, DeepCopyResize) {
516*635a8641SAndroid Build Coastguard Worker Pickle pickle;
517*635a8641SAndroid Build Coastguard Worker while (pickle.capacity_after_header() != pickle.payload_size())
518*635a8641SAndroid Build Coastguard Worker pickle.WriteBool(true);
519*635a8641SAndroid Build Coastguard Worker
520*635a8641SAndroid Build Coastguard Worker // Make a deep copy.
521*635a8641SAndroid Build Coastguard Worker Pickle pickle2(pickle);
522*635a8641SAndroid Build Coastguard Worker
523*635a8641SAndroid Build Coastguard Worker // Check that there isn't any extraneous capacity.
524*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(pickle.capacity_after_header(), pickle2.capacity_after_header());
525*635a8641SAndroid Build Coastguard Worker }
526*635a8641SAndroid Build Coastguard Worker
527*635a8641SAndroid Build Coastguard Worker namespace {
528*635a8641SAndroid Build Coastguard Worker
529*635a8641SAndroid Build Coastguard Worker // Publicly exposes the ClaimBytes interface for testing.
530*635a8641SAndroid Build Coastguard Worker class TestingPickle : public Pickle {
531*635a8641SAndroid Build Coastguard Worker public:
532*635a8641SAndroid Build Coastguard Worker TestingPickle() = default;
533*635a8641SAndroid Build Coastguard Worker
ClaimBytes(size_t num_bytes)534*635a8641SAndroid Build Coastguard Worker void* ClaimBytes(size_t num_bytes) { return Pickle::ClaimBytes(num_bytes); }
535*635a8641SAndroid Build Coastguard Worker };
536*635a8641SAndroid Build Coastguard Worker
537*635a8641SAndroid Build Coastguard Worker } // namespace
538*635a8641SAndroid Build Coastguard Worker
539*635a8641SAndroid Build Coastguard Worker // Checks that claimed bytes are zero-initialized.
TEST(PickleTest,ClaimBytesInitialization)540*635a8641SAndroid Build Coastguard Worker TEST(PickleTest, ClaimBytesInitialization) {
541*635a8641SAndroid Build Coastguard Worker static const int kChunkSize = 64;
542*635a8641SAndroid Build Coastguard Worker TestingPickle pickle;
543*635a8641SAndroid Build Coastguard Worker const char* bytes = static_cast<const char*>(pickle.ClaimBytes(kChunkSize));
544*635a8641SAndroid Build Coastguard Worker for (size_t i = 0; i < kChunkSize; ++i) {
545*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(0, bytes[i]);
546*635a8641SAndroid Build Coastguard Worker }
547*635a8641SAndroid Build Coastguard Worker }
548*635a8641SAndroid Build Coastguard Worker
549*635a8641SAndroid Build Coastguard Worker // Checks that ClaimBytes properly advances the write offset.
TEST(PickleTest,ClaimBytes)550*635a8641SAndroid Build Coastguard Worker TEST(PickleTest, ClaimBytes) {
551*635a8641SAndroid Build Coastguard Worker std::string data("Hello, world!");
552*635a8641SAndroid Build Coastguard Worker
553*635a8641SAndroid Build Coastguard Worker TestingPickle pickle;
554*635a8641SAndroid Build Coastguard Worker pickle.WriteUInt32(data.size());
555*635a8641SAndroid Build Coastguard Worker void* bytes = pickle.ClaimBytes(data.size());
556*635a8641SAndroid Build Coastguard Worker pickle.WriteInt(42);
557*635a8641SAndroid Build Coastguard Worker memcpy(bytes, data.data(), data.size());
558*635a8641SAndroid Build Coastguard Worker
559*635a8641SAndroid Build Coastguard Worker PickleIterator iter(pickle);
560*635a8641SAndroid Build Coastguard Worker uint32_t out_data_length;
561*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(iter.ReadUInt32(&out_data_length));
562*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(data.size(), out_data_length);
563*635a8641SAndroid Build Coastguard Worker
564*635a8641SAndroid Build Coastguard Worker const char* out_data = nullptr;
565*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(iter.ReadBytes(&out_data, out_data_length));
566*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(data, std::string(out_data, out_data_length));
567*635a8641SAndroid Build Coastguard Worker
568*635a8641SAndroid Build Coastguard Worker int out_value;
569*635a8641SAndroid Build Coastguard Worker EXPECT_TRUE(iter.ReadInt(&out_value));
570*635a8641SAndroid Build Coastguard Worker EXPECT_EQ(42, out_value);
571*635a8641SAndroid Build Coastguard Worker }
572*635a8641SAndroid Build Coastguard Worker
573*635a8641SAndroid Build Coastguard Worker } // namespace base
574