pickle_unittest.cc revision 9d6f8a4fbbdbaf61802f8e41de8afb692a0e3408
1// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include <string> 6 7#include "base/basictypes.h" 8#include "base/pickle.h" 9#include "base/scoped_ptr.h" 10#include "base/string16.h" 11#include "testing/gtest/include/gtest/gtest.h" 12 13namespace { 14 15const int testint = 2093847192; 16const std::string teststr("Hello world"); // note non-aligned string length 17const std::wstring testwstr(L"Hello, world"); 18const char testdata[] = "AAA\0BBB\0"; 19const int testdatalen = arraysize(testdata) - 1; 20const bool testbool1 = false; 21const bool testbool2 = true; 22 23// checks that the result 24void VerifyResult(const Pickle& pickle) { 25 void* iter = NULL; 26 27 int outint; 28 EXPECT_TRUE(pickle.ReadInt(&iter, &outint)); 29 EXPECT_EQ(testint, outint); 30 31 std::string outstr; 32 EXPECT_TRUE(pickle.ReadString(&iter, &outstr)); 33 EXPECT_EQ(teststr, outstr); 34 35 std::wstring outwstr; 36 EXPECT_TRUE(pickle.ReadWString(&iter, &outwstr)); 37 EXPECT_EQ(testwstr, outwstr); 38 39 bool outbool; 40 EXPECT_TRUE(pickle.ReadBool(&iter, &outbool)); 41 EXPECT_EQ(testbool1, outbool); 42 EXPECT_TRUE(pickle.ReadBool(&iter, &outbool)); 43 EXPECT_EQ(testbool2, outbool); 44 45 const char* outdata; 46 int outdatalen; 47 EXPECT_TRUE(pickle.ReadData(&iter, &outdata, &outdatalen)); 48 EXPECT_EQ(testdatalen, outdatalen); 49 EXPECT_EQ(memcmp(testdata, outdata, outdatalen), 0); 50 51 EXPECT_TRUE(pickle.ReadData(&iter, &outdata, &outdatalen)); 52 EXPECT_EQ(testdatalen, outdatalen); 53 EXPECT_EQ(memcmp(testdata, outdata, outdatalen), 0); 54 55 // reads past the end should fail 56 EXPECT_FALSE(pickle.ReadInt(&iter, &outint)); 57} 58 59} // namespace 60 61TEST(PickleTest, EncodeDecode) { 62 Pickle pickle; 63 64 EXPECT_TRUE(pickle.WriteInt(testint)); 65 EXPECT_TRUE(pickle.WriteString(teststr)); 66 EXPECT_TRUE(pickle.WriteWString(testwstr)); 67 EXPECT_TRUE(pickle.WriteBool(testbool1)); 68 EXPECT_TRUE(pickle.WriteBool(testbool2)); 69 EXPECT_TRUE(pickle.WriteData(testdata, testdatalen)); 70 71 // Over allocate BeginWriteData so we can test TrimWriteData. 72 char* dest = pickle.BeginWriteData(testdatalen + 100); 73 EXPECT_TRUE(dest); 74 memcpy(dest, testdata, testdatalen); 75 76 pickle.TrimWriteData(testdatalen); 77 78 VerifyResult(pickle); 79 80 // test copy constructor 81 Pickle pickle2(pickle); 82 VerifyResult(pickle2); 83 84 // test operator= 85 Pickle pickle3; 86 pickle3 = pickle; 87 VerifyResult(pickle3); 88} 89 90// Tests that we can handle really small buffers. 91TEST(PickleTest, SmallBuffer) { 92 scoped_array<char> buffer(new char[1]); 93 94 // We should not touch the buffer. 95 Pickle pickle(buffer.get(), 1); 96 97 void* iter = NULL; 98 int data; 99 EXPECT_FALSE(pickle.ReadInt(&iter, &data)); 100} 101 102// Tests that we can handle improper headers. 103TEST(PickleTest, BigSize) { 104 int buffer[] = { 0x56035200, 25, 40, 50 }; 105 106 Pickle pickle(reinterpret_cast<char*>(buffer), sizeof(buffer)); 107 108 void* iter = NULL; 109 int data; 110 EXPECT_FALSE(pickle.ReadInt(&iter, &data)); 111} 112 113TEST(PickleTest, UnalignedSize) { 114 int buffer[] = { 10, 25, 40, 50 }; 115 116 Pickle pickle(reinterpret_cast<char*>(buffer), sizeof(buffer)); 117 118 void* iter = NULL; 119 int data; 120 EXPECT_FALSE(pickle.ReadInt(&iter, &data)); 121} 122 123TEST(PickleTest, ZeroLenStr) { 124 Pickle pickle; 125 EXPECT_TRUE(pickle.WriteString("")); 126 127 void* iter = NULL; 128 std::string outstr; 129 EXPECT_TRUE(pickle.ReadString(&iter, &outstr)); 130 EXPECT_EQ("", outstr); 131} 132 133TEST(PickleTest, ZeroLenWStr) { 134 Pickle pickle; 135 EXPECT_TRUE(pickle.WriteWString(L"")); 136 137 void* iter = NULL; 138 std::string outstr; 139 EXPECT_TRUE(pickle.ReadString(&iter, &outstr)); 140 EXPECT_EQ("", outstr); 141} 142 143TEST(PickleTest, BadLenStr) { 144 Pickle pickle; 145 EXPECT_TRUE(pickle.WriteInt(-2)); 146 147 void* iter = NULL; 148 std::string outstr; 149 EXPECT_FALSE(pickle.ReadString(&iter, &outstr)); 150} 151 152TEST(PickleTest, BadLenWStr) { 153 Pickle pickle; 154 EXPECT_TRUE(pickle.WriteInt(-1)); 155 156 void* iter = NULL; 157 std::wstring woutstr; 158 EXPECT_FALSE(pickle.ReadWString(&iter, &woutstr)); 159} 160 161TEST(PickleTest, FindNext) { 162 Pickle pickle; 163 EXPECT_TRUE(pickle.WriteInt(1)); 164 EXPECT_TRUE(pickle.WriteString("Domo")); 165 166 const char* start = reinterpret_cast<const char*>(pickle.data()); 167 const char* end = start + pickle.size(); 168 169 EXPECT_TRUE(end == Pickle::FindNext(pickle.header_size_, start, end)); 170 EXPECT_TRUE(NULL == Pickle::FindNext(pickle.header_size_, start, end - 1)); 171 EXPECT_TRUE(end == Pickle::FindNext(pickle.header_size_, start, end + 1)); 172} 173 174TEST(PickleTest, FindNextWithIncompleteHeader) { 175 size_t header_size = sizeof(Pickle::Header); 176 scoped_array<char> buffer(new char[header_size - 1]); 177 memset(buffer.get(), 0x1, header_size - 1); 178 179 const char* start = buffer.get(); 180 const char* end = start + header_size - 1; 181 182 EXPECT_TRUE(NULL == Pickle::FindNext(header_size, start, end)); 183} 184 185TEST(PickleTest, IteratorHasRoom) { 186 Pickle pickle; 187 EXPECT_TRUE(pickle.WriteInt(1)); 188 EXPECT_TRUE(pickle.WriteInt(2)); 189 190 const void* iter = 0; 191 EXPECT_FALSE(pickle.IteratorHasRoomFor(iter, 1)); 192 iter = pickle.payload(); 193 EXPECT_TRUE(pickle.IteratorHasRoomFor(iter, 0)); 194 EXPECT_TRUE(pickle.IteratorHasRoomFor(iter, 1)); 195 EXPECT_FALSE(pickle.IteratorHasRoomFor(iter, -1)); 196 EXPECT_TRUE(pickle.IteratorHasRoomFor(iter, sizeof(int) * 2)); 197 EXPECT_FALSE(pickle.IteratorHasRoomFor(iter, (sizeof(int) * 2) + 1)); 198} 199 200TEST(PickleTest, Resize) { 201 size_t unit = Pickle::kPayloadUnit; 202 scoped_array<char> data(new char[unit]); 203 char* data_ptr = data.get(); 204 for (size_t i = 0; i < unit; i++) 205 data_ptr[i] = 'G'; 206 207 // construct a message that will be exactly the size of one payload unit, 208 // note that any data will have a 4-byte header indicating the size 209 const size_t payload_size_after_header = unit - sizeof(uint32); 210 Pickle pickle; 211 pickle.WriteData(data_ptr, 212 static_cast<int>(payload_size_after_header - sizeof(uint32))); 213 size_t cur_payload = payload_size_after_header; 214 215 // note: we assume 'unit' is a power of 2 216 EXPECT_EQ(unit, pickle.capacity()); 217 EXPECT_EQ(pickle.payload_size(), payload_size_after_header); 218 219 // fill out a full page (noting data header) 220 pickle.WriteData(data_ptr, static_cast<int>(unit - sizeof(uint32))); 221 cur_payload += unit; 222 EXPECT_EQ(unit * 2, pickle.capacity()); 223 EXPECT_EQ(cur_payload, pickle.payload_size()); 224 225 // one more byte should double the capacity 226 pickle.WriteData(data_ptr, 1); 227 cur_payload += 5; 228 EXPECT_EQ(unit * 4, pickle.capacity()); 229 EXPECT_EQ(cur_payload, pickle.payload_size()); 230} 231 232namespace { 233 234struct CustomHeader : Pickle::Header { 235 int blah; 236}; 237 238} // namespace 239 240TEST(PickleTest, HeaderPadding) { 241 const uint32 kMagic = 0x12345678; 242 243 Pickle pickle(sizeof(CustomHeader)); 244 pickle.WriteInt(kMagic); 245 246 // this should not overwrite the 'int' payload 247 pickle.headerT<CustomHeader>()->blah = 10; 248 249 void* iter = NULL; 250 int result; 251 ASSERT_TRUE(pickle.ReadInt(&iter, &result)); 252 253 EXPECT_EQ(static_cast<uint32>(result), kMagic); 254} 255 256TEST(PickleTest, EqualsOperator) { 257 Pickle source; 258 source.WriteInt(1); 259 260 Pickle copy_refs_source_buffer(static_cast<const char*>(source.data()), 261 source.size()); 262 Pickle copy; 263 copy = copy_refs_source_buffer; 264 ASSERT_EQ(source.size(), copy.size()); 265} 266 267TEST(PickleTest, EvilLengths) { 268 Pickle source; 269 std::string str(100000, 'A'); 270 source.WriteData(str.c_str(), 100000); 271 // ReadString16 used to have its read buffer length calculation wrong leading 272 // to out-of-bounds reading. 273 void* iter = NULL; 274 string16 str16; 275 EXPECT_FALSE(source.ReadString16(&iter, &str16)); 276 277 // And check we didn't break ReadString16. 278 str16 = (wchar_t) 'A'; 279 Pickle str16_pickle; 280 str16_pickle.WriteString16(str16); 281 iter = NULL; 282 EXPECT_TRUE(str16_pickle.ReadString16(&iter, &str16)); 283 EXPECT_EQ(1U, str16.length()); 284 285 // Check we don't fail in a length check with large WStrings. 286 Pickle big_len; 287 big_len.WriteInt(1 << 30); 288 iter = NULL; 289 std::wstring wstr; 290 EXPECT_FALSE(big_len.ReadWString(&iter, &wstr)); 291} 292 293// Check we can write zero bytes of data and 'data' can be NULL. 294TEST(PickleTest, ZeroLength) { 295 Pickle pickle; 296 EXPECT_TRUE(pickle.WriteData(NULL, 0)); 297 298 void* iter = NULL; 299 const char* outdata; 300 int outdatalen; 301 EXPECT_TRUE(pickle.ReadData(&iter, &outdata, &outdatalen)); 302 EXPECT_EQ(0, outdatalen); 303 // We can't assert that outdata is NULL. 304} 305 306// Check that ReadBytes works properly with an iterator initialized to NULL. 307TEST(PickleTest, ReadBytes) { 308 Pickle pickle; 309 int data = 0x7abcd; 310 EXPECT_TRUE(pickle.WriteBytes(&data, sizeof(data))); 311 312 void* iter = NULL; 313 const char* outdata_char; 314 EXPECT_TRUE(pickle.ReadBytes(&iter, &outdata_char, sizeof(data))); 315 316 int outdata; 317 memcpy(&outdata, outdata_char, sizeof(outdata)); 318 EXPECT_EQ(data, outdata); 319} 320