15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string> 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/basictypes.h" 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h" 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/pickle.h" 10868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string16.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// Remove when this file is in the base namespace. 14a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)using base::string16; 15a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int testint = 2093847192; 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const std::string teststr("Hello world"); // note non-aligned string length 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const std::wstring testwstr(L"Hello, world"); 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char testdata[] = "AAA\0BBB\0"; 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int testdatalen = arraysize(testdata) - 1; 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const bool testbool1 = false; 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const bool testbool2 = true; 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const uint16 testuint16 = 32123; 262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const float testfloat = 3.1415926935f; 27116680a4aac90f2aa7413d9095a592090648e557Ben Murdochconst double testdouble = 2.71828182845904523; 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// checks that the result 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void VerifyResult(const Pickle& pickle) { 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PickleIterator iter(pickle); 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int outint; 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(pickle.ReadInt(&iter, &outint)); 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(testint, outint); 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string outstr; 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(pickle.ReadString(&iter, &outstr)); 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(teststr, outstr); 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::wstring outwstr; 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(pickle.ReadWString(&iter, &outwstr)); 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(testwstr, outwstr); 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool outbool; 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(pickle.ReadBool(&iter, &outbool)); 472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_FALSE(outbool); 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(pickle.ReadBool(&iter, &outbool)); 492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(outbool); 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint16 outuint16; 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(pickle.ReadUInt16(&iter, &outuint16)); 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(testuint16, outuint16); 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) float outfloat; 562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(pickle.ReadFloat(&iter, &outfloat)); 572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(testfloat, outfloat); 582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 59116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch double outdouble; 60116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch EXPECT_TRUE(pickle.ReadDouble(&iter, &outdouble)); 61116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch EXPECT_EQ(testdouble, outdouble); 62116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* outdata; 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int outdatalen; 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(pickle.ReadData(&iter, &outdata, &outdatalen)); 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(testdatalen, outdatalen); 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(memcmp(testdata, outdata, outdatalen), 0); 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // reads past the end should fail 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(pickle.ReadInt(&iter, &outint)); 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(PickleTest, EncodeDecode) { 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Pickle pickle; 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(pickle.WriteInt(testint)); 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(pickle.WriteString(teststr)); 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(pickle.WriteWString(testwstr)); 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(pickle.WriteBool(testbool1)); 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(pickle.WriteBool(testbool2)); 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(pickle.WriteUInt16(testuint16)); 842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(pickle.WriteFloat(testfloat)); 85116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch EXPECT_TRUE(pickle.WriteDouble(testdouble)); 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(pickle.WriteData(testdata, testdatalen)); 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VerifyResult(pickle); 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // test copy constructor 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Pickle pickle2(pickle); 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VerifyResult(pickle2); 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // test operator= 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Pickle pickle3; 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pickle3 = pickle; 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VerifyResult(pickle3); 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests that we can handle really small buffers. 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(PickleTest, SmallBuffer) { 1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<char[]> buffer(new char[1]); 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We should not touch the buffer. 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Pickle pickle(buffer.get(), 1); 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PickleIterator iter(pickle); 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int data; 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(pickle.ReadInt(&iter, &data)); 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests that we can handle improper headers. 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(PickleTest, BigSize) { 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int buffer[] = { 0x56035200, 25, 40, 50 }; 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Pickle pickle(reinterpret_cast<char*>(buffer), sizeof(buffer)); 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PickleIterator iter(pickle); 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int data; 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(pickle.ReadInt(&iter, &data)); 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(PickleTest, UnalignedSize) { 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int buffer[] = { 10, 25, 40, 50 }; 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Pickle pickle(reinterpret_cast<char*>(buffer), sizeof(buffer)); 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PickleIterator iter(pickle); 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int data; 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(pickle.ReadInt(&iter, &data)); 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(PickleTest, ZeroLenStr) { 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Pickle pickle; 134c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRUE(pickle.WriteString(std::string())); 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PickleIterator iter(pickle); 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string outstr; 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(pickle.ReadString(&iter, &outstr)); 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ("", outstr); 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(PickleTest, ZeroLenWStr) { 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Pickle pickle; 144c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRUE(pickle.WriteWString(std::wstring())); 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PickleIterator iter(pickle); 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string outstr; 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(pickle.ReadString(&iter, &outstr)); 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ("", outstr); 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(PickleTest, BadLenStr) { 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Pickle pickle; 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(pickle.WriteInt(-2)); 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PickleIterator iter(pickle); 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string outstr; 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(pickle.ReadString(&iter, &outstr)); 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(PickleTest, BadLenWStr) { 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Pickle pickle; 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(pickle.WriteInt(-1)); 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PickleIterator iter(pickle); 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::wstring woutstr; 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(pickle.ReadWString(&iter, &woutstr)); 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(PickleTest, FindNext) { 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Pickle pickle; 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(pickle.WriteInt(1)); 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(pickle.WriteString("Domo")); 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* start = reinterpret_cast<const char*>(pickle.data()); 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* end = start + pickle.size(); 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(end == Pickle::FindNext(pickle.header_size_, start, end)); 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(NULL == Pickle::FindNext(pickle.header_size_, start, end - 1)); 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(end == Pickle::FindNext(pickle.header_size_, start, end + 1)); 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(PickleTest, FindNextWithIncompleteHeader) { 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t header_size = sizeof(Pickle::Header); 1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<char[]> buffer(new char[header_size - 1]); 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memset(buffer.get(), 0x1, header_size - 1); 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* start = buffer.get(); 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* end = start + header_size - 1; 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(NULL == Pickle::FindNext(header_size, start, end)); 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1940f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#if defined(COMPILER_MSVC) 1950f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#pragma warning(push) 1960f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#pragma warning(disable: 4146) 1970f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#endif 1980f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)TEST(PickleTest, FindNextOverflow) { 1990f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) size_t header_size = sizeof(Pickle::Header); 2000f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) size_t header_size2 = 2 * header_size; 2010f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) size_t payload_received = 100; 2020f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) scoped_ptr<char[]> buffer(new char[header_size2 + payload_received]); 2030f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) const char* start = buffer.get(); 2040f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) Pickle::Header* header = reinterpret_cast<Pickle::Header*>(buffer.get()); 2050f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) const char* end = start + header_size2 + payload_received; 2060f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) // It is impossible to construct an overflow test otherwise. 2070f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) if (sizeof(size_t) > sizeof(header->payload_size) || 2080f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) sizeof(uintptr_t) > sizeof(header->payload_size)) 2090f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) return; 2100f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 2110f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) header->payload_size = -(reinterpret_cast<uintptr_t>(start) + header_size2); 2120f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) EXPECT_TRUE(NULL == Pickle::FindNext(header_size2, start, end)); 2130f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 2140f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) header->payload_size = -header_size2; 2150f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) EXPECT_TRUE(NULL == Pickle::FindNext(header_size2, start, end)); 2160f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 2170f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) header->payload_size = 0; 2180f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) end = start + header_size; 2190f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) EXPECT_TRUE(NULL == Pickle::FindNext(header_size2, start, end)); 2200f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)} 2210f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#if defined(COMPILER_MSVC) 2220f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#pragma warning(pop) 2230f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#endif 2240f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(PickleTest, GetReadPointerAndAdvance) { 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Pickle pickle; 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PickleIterator iter(pickle); 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(iter.GetReadPointerAndAdvance(1)); 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(pickle.WriteInt(1)); 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(pickle.WriteInt(2)); 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int bytes = sizeof(int) * 2; 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(PickleIterator(pickle).GetReadPointerAndAdvance(0)); 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(PickleIterator(pickle).GetReadPointerAndAdvance(1)); 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(PickleIterator(pickle).GetReadPointerAndAdvance(-1)); 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(PickleIterator(pickle).GetReadPointerAndAdvance(bytes)); 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(PickleIterator(pickle).GetReadPointerAndAdvance(bytes + 1)); 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(PickleIterator(pickle).GetReadPointerAndAdvance(INT_MAX)); 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(PickleIterator(pickle).GetReadPointerAndAdvance(INT_MIN)); 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(PickleTest, Resize) { 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t unit = Pickle::kPayloadUnit; 2462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<char[]> data(new char[unit]); 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char* data_ptr = data.get(); 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < unit; i++) 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data_ptr[i] = 'G'; 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // construct a message that will be exactly the size of one payload unit, 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // note that any data will have a 4-byte header indicating the size 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const size_t payload_size_after_header = unit - sizeof(uint32); 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Pickle pickle; 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pickle.WriteData(data_ptr, 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static_cast<int>(payload_size_after_header - sizeof(uint32))); 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t cur_payload = payload_size_after_header; 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // note: we assume 'unit' is a power of 2 2601e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) EXPECT_EQ(unit, pickle.capacity_after_header()); 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(pickle.payload_size(), payload_size_after_header); 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // fill out a full page (noting data header) 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pickle.WriteData(data_ptr, static_cast<int>(unit - sizeof(uint32))); 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cur_payload += unit; 2661e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) EXPECT_EQ(unit * 2, pickle.capacity_after_header()); 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(cur_payload, pickle.payload_size()); 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // one more byte should double the capacity 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pickle.WriteData(data_ptr, 1); 27146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) cur_payload += 8; 2721e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) EXPECT_EQ(unit * 4, pickle.capacity_after_header()); 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(cur_payload, pickle.payload_size()); 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct CustomHeader : Pickle::Header { 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int blah; 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(PickleTest, HeaderPadding) { 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const uint32 kMagic = 0x12345678; 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Pickle pickle(sizeof(CustomHeader)); 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pickle.WriteInt(kMagic); 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // this should not overwrite the 'int' payload 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pickle.headerT<CustomHeader>()->blah = 10; 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PickleIterator iter(pickle); 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int result; 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(pickle.ReadInt(&iter, &result)); 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(static_cast<uint32>(result), kMagic); 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(PickleTest, EqualsOperator) { 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Pickle source; 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) source.WriteInt(1); 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Pickle copy_refs_source_buffer(static_cast<const char*>(source.data()), 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) source.size()); 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Pickle copy; 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) copy = copy_refs_source_buffer; 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(source.size(), copy.size()); 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(PickleTest, EvilLengths) { 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Pickle source; 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string str(100000, 'A'); 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(source.WriteData(str.c_str(), 100000)); 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // ReadString16 used to have its read buffer length calculation wrong leading 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // to out-of-bounds reading. 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PickleIterator iter(source); 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string16 str16; 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(source.ReadString16(&iter, &str16)); 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // And check we didn't break ReadString16. 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) str16 = (wchar_t) 'A'; 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Pickle str16_pickle; 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(str16_pickle.WriteString16(str16)); 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) iter = PickleIterator(str16_pickle); 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(str16_pickle.ReadString16(&iter, &str16)); 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(1U, str16.length()); 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Check we don't fail in a length check with invalid String16 size. 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // (1<<31) * sizeof(char16) == 0, so this is particularly evil. 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Pickle bad_len; 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(bad_len.WriteInt(1 << 31)); 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) iter = PickleIterator(bad_len); 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(bad_len.ReadString16(&iter, &str16)); 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Check we don't fail in a length check with large WStrings. 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Pickle big_len; 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(big_len.WriteInt(1 << 30)); 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) iter = PickleIterator(big_len); 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::wstring wstr; 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(big_len.ReadWString(&iter, &wstr)); 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Check we can write zero bytes of data and 'data' can be NULL. 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(PickleTest, ZeroLength) { 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Pickle pickle; 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(pickle.WriteData(NULL, 0)); 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PickleIterator iter(pickle); 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* outdata; 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int outdatalen; 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(pickle.ReadData(&iter, &outdata, &outdatalen)); 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(0, outdatalen); 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We can't assert that outdata is NULL. 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Check that ReadBytes works properly with an iterator initialized to NULL. 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(PickleTest, ReadBytes) { 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Pickle pickle; 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int data = 0x7abcd; 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(pickle.WriteBytes(&data, sizeof(data))); 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PickleIterator iter(pickle); 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* outdata_char = NULL; 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(pickle.ReadBytes(&iter, &outdata_char, sizeof(data))); 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int outdata; 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memcpy(&outdata, outdata_char, sizeof(outdata)); 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(data, outdata); 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 371