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