| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2012 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/memory/scoped_ptr.h" | |
| 9 #include "base/pickle.h" | |
| 10 #include "base/strings/string16.h" | |
| 11 #include "base/strings/utf_string_conversions.h" | |
| 12 #include "testing/gtest/include/gtest/gtest.h" | |
| 13 | |
| 14 namespace base { | |
| 15 | |
| 16 namespace { | |
| 17 | |
| 18 const bool testbool1 = false; | |
| 19 const bool testbool2 = true; | |
| 20 const int testint = 2093847192; | |
| 21 const long testlong = 1093847192; | |
| 22 const uint16 testuint16 = 32123; | |
| 23 const uint32 testuint32 = 1593847192; | |
| 24 const int64 testint64 = -0x7E8CA9253104BDFCLL; | |
| 25 const uint64 testuint64 = 0xCE8CA9253104BDF7ULL; | |
| 26 const size_t testsizet = 0xFEDC7654; | |
| 27 const float testfloat = 3.1415926935f; | |
| 28 const double testdouble = 2.71828182845904523; | |
| 29 const std::string teststring("Hello world"); // note non-aligned string length | |
| 30 const std::wstring testwstring(L"Hello, world"); | |
| 31 const string16 teststring16(ASCIIToUTF16("Hello, world")); | |
| 32 const char testrawstring[] = "Hello new world"; // Test raw string writing | |
| 33 // Test raw char16 writing, assumes UTF16 encoding is ANSI for alpha chars. | |
| 34 const char16 testrawstring16[] = {'A', 'l', 'o', 'h', 'a', 0}; | |
| 35 const char testdata[] = "AAA\0BBB\0"; | |
| 36 const int testdatalen = arraysize(testdata) - 1; | |
| 37 | |
| 38 // checks that the results can be read correctly from the Pickle | |
| 39 void VerifyResult(const Pickle& pickle) { | |
| 40 PickleIterator iter(pickle); | |
| 41 | |
| 42 bool outbool; | |
| 43 EXPECT_TRUE(iter.ReadBool(&outbool)); | |
| 44 EXPECT_FALSE(outbool); | |
| 45 EXPECT_TRUE(iter.ReadBool(&outbool)); | |
| 46 EXPECT_TRUE(outbool); | |
| 47 | |
| 48 int outint; | |
| 49 EXPECT_TRUE(iter.ReadInt(&outint)); | |
| 50 EXPECT_EQ(testint, outint); | |
| 51 | |
| 52 long outlong; | |
| 53 EXPECT_TRUE(iter.ReadLong(&outlong)); | |
| 54 EXPECT_EQ(testlong, outlong); | |
| 55 | |
| 56 uint16 outuint16; | |
| 57 EXPECT_TRUE(iter.ReadUInt16(&outuint16)); | |
| 58 EXPECT_EQ(testuint16, outuint16); | |
| 59 | |
| 60 uint32 outuint32; | |
| 61 EXPECT_TRUE(iter.ReadUInt32(&outuint32)); | |
| 62 EXPECT_EQ(testuint32, outuint32); | |
| 63 | |
| 64 int64 outint64; | |
| 65 EXPECT_TRUE(iter.ReadInt64(&outint64)); | |
| 66 EXPECT_EQ(testint64, outint64); | |
| 67 | |
| 68 uint64 outuint64; | |
| 69 EXPECT_TRUE(iter.ReadUInt64(&outuint64)); | |
| 70 EXPECT_EQ(testuint64, outuint64); | |
| 71 | |
| 72 size_t outsizet; | |
| 73 EXPECT_TRUE(iter.ReadSizeT(&outsizet)); | |
| 74 EXPECT_EQ(testsizet, outsizet); | |
| 75 | |
| 76 float outfloat; | |
| 77 EXPECT_TRUE(iter.ReadFloat(&outfloat)); | |
| 78 EXPECT_EQ(testfloat, outfloat); | |
| 79 | |
| 80 double outdouble; | |
| 81 EXPECT_TRUE(iter.ReadDouble(&outdouble)); | |
| 82 EXPECT_EQ(testdouble, outdouble); | |
| 83 | |
| 84 std::string outstring; | |
| 85 EXPECT_TRUE(iter.ReadString(&outstring)); | |
| 86 EXPECT_EQ(teststring, outstring); | |
| 87 | |
| 88 string16 outstring16; | |
| 89 EXPECT_TRUE(iter.ReadString16(&outstring16)); | |
| 90 EXPECT_EQ(teststring16, outstring16); | |
| 91 | |
| 92 StringPiece outstringpiece; | |
| 93 EXPECT_TRUE(iter.ReadStringPiece(&outstringpiece)); | |
| 94 EXPECT_EQ(testrawstring, outstringpiece); | |
| 95 | |
| 96 StringPiece16 outstringpiece16; | |
| 97 EXPECT_TRUE(iter.ReadStringPiece16(&outstringpiece16)); | |
| 98 EXPECT_EQ(testrawstring16, outstringpiece16); | |
| 99 | |
| 100 const char* outdata; | |
| 101 int outdatalen; | |
| 102 EXPECT_TRUE(iter.ReadData(&outdata, &outdatalen)); | |
| 103 EXPECT_EQ(testdatalen, outdatalen); | |
| 104 EXPECT_EQ(memcmp(testdata, outdata, outdatalen), 0); | |
| 105 | |
| 106 // reads past the end should fail | |
| 107 EXPECT_FALSE(iter.ReadInt(&outint)); | |
| 108 } | |
| 109 | |
| 110 } // namespace | |
| 111 | |
| 112 TEST(PickleTest, EncodeDecode) { | |
| 113 Pickle pickle; | |
| 114 | |
| 115 EXPECT_TRUE(pickle.WriteBool(testbool1)); | |
| 116 EXPECT_TRUE(pickle.WriteBool(testbool2)); | |
| 117 EXPECT_TRUE(pickle.WriteInt(testint)); | |
| 118 EXPECT_TRUE( | |
| 119 pickle.WriteLongUsingDangerousNonPortableLessPersistableForm(testlong)); | |
| 120 EXPECT_TRUE(pickle.WriteUInt16(testuint16)); | |
| 121 EXPECT_TRUE(pickle.WriteUInt32(testuint32)); | |
| 122 EXPECT_TRUE(pickle.WriteInt64(testint64)); | |
| 123 EXPECT_TRUE(pickle.WriteUInt64(testuint64)); | |
| 124 EXPECT_TRUE(pickle.WriteSizeT(testsizet)); | |
| 125 EXPECT_TRUE(pickle.WriteFloat(testfloat)); | |
| 126 EXPECT_TRUE(pickle.WriteDouble(testdouble)); | |
| 127 EXPECT_TRUE(pickle.WriteString(teststring)); | |
| 128 EXPECT_TRUE(pickle.WriteString16(teststring16)); | |
| 129 EXPECT_TRUE(pickle.WriteString(testrawstring)); | |
| 130 EXPECT_TRUE(pickle.WriteString16(testrawstring16)); | |
| 131 EXPECT_TRUE(pickle.WriteData(testdata, testdatalen)); | |
| 132 VerifyResult(pickle); | |
| 133 | |
| 134 // test copy constructor | |
| 135 Pickle pickle2(pickle); | |
| 136 VerifyResult(pickle2); | |
| 137 | |
| 138 // test operator= | |
| 139 Pickle pickle3; | |
| 140 pickle3 = pickle; | |
| 141 VerifyResult(pickle3); | |
| 142 } | |
| 143 | |
| 144 // Tests that reading/writing a size_t works correctly when the source process | |
| 145 // is 64-bit. We rely on having both 32- and 64-bit trybots to validate both | |
| 146 // arms of the conditional in this test. | |
| 147 TEST(PickleTest, SizeTFrom64Bit) { | |
| 148 Pickle pickle; | |
| 149 // Under the hood size_t is always written as a 64-bit value, so simulate a | |
| 150 // 64-bit size_t even on 32-bit architectures by explicitly writing a uint64. | |
| 151 EXPECT_TRUE(pickle.WriteUInt64(testuint64)); | |
| 152 | |
| 153 PickleIterator iter(pickle); | |
| 154 size_t outsizet; | |
| 155 if (sizeof(size_t) < sizeof(uint64)) { | |
| 156 // ReadSizeT() should return false when the original written value can't be | |
| 157 // represented as a size_t. | |
| 158 EXPECT_FALSE(iter.ReadSizeT(&outsizet)); | |
| 159 } else { | |
| 160 EXPECT_TRUE(iter.ReadSizeT(&outsizet)); | |
| 161 EXPECT_EQ(testuint64, outsizet); | |
| 162 } | |
| 163 } | |
| 164 | |
| 165 // Tests that we can handle really small buffers. | |
| 166 TEST(PickleTest, SmallBuffer) { | |
| 167 scoped_ptr<char[]> buffer(new char[1]); | |
| 168 | |
| 169 // We should not touch the buffer. | |
| 170 Pickle pickle(buffer.get(), 1); | |
| 171 | |
| 172 PickleIterator iter(pickle); | |
| 173 int data; | |
| 174 EXPECT_FALSE(iter.ReadInt(&data)); | |
| 175 } | |
| 176 | |
| 177 // Tests that we can handle improper headers. | |
| 178 TEST(PickleTest, BigSize) { | |
| 179 int buffer[] = { 0x56035200, 25, 40, 50 }; | |
| 180 | |
| 181 Pickle pickle(reinterpret_cast<char*>(buffer), sizeof(buffer)); | |
| 182 | |
| 183 PickleIterator iter(pickle); | |
| 184 int data; | |
| 185 EXPECT_FALSE(iter.ReadInt(&data)); | |
| 186 } | |
| 187 | |
| 188 TEST(PickleTest, UnalignedSize) { | |
| 189 int buffer[] = { 10, 25, 40, 50 }; | |
| 190 | |
| 191 Pickle pickle(reinterpret_cast<char*>(buffer), sizeof(buffer)); | |
| 192 | |
| 193 PickleIterator iter(pickle); | |
| 194 int data; | |
| 195 EXPECT_FALSE(iter.ReadInt(&data)); | |
| 196 } | |
| 197 | |
| 198 TEST(PickleTest, ZeroLenStr) { | |
| 199 Pickle pickle; | |
| 200 EXPECT_TRUE(pickle.WriteString(std::string())); | |
| 201 | |
| 202 PickleIterator iter(pickle); | |
| 203 std::string outstr; | |
| 204 EXPECT_TRUE(iter.ReadString(&outstr)); | |
| 205 EXPECT_EQ("", outstr); | |
| 206 } | |
| 207 | |
| 208 TEST(PickleTest, ZeroLenStr16) { | |
| 209 Pickle pickle; | |
| 210 EXPECT_TRUE(pickle.WriteString16(string16())); | |
| 211 | |
| 212 PickleIterator iter(pickle); | |
| 213 std::string outstr; | |
| 214 EXPECT_TRUE(iter.ReadString(&outstr)); | |
| 215 EXPECT_EQ("", outstr); | |
| 216 } | |
| 217 | |
| 218 TEST(PickleTest, BadLenStr) { | |
| 219 Pickle pickle; | |
| 220 EXPECT_TRUE(pickle.WriteInt(-2)); | |
| 221 | |
| 222 PickleIterator iter(pickle); | |
| 223 std::string outstr; | |
| 224 EXPECT_FALSE(iter.ReadString(&outstr)); | |
| 225 } | |
| 226 | |
| 227 TEST(PickleTest, BadLenStr16) { | |
| 228 Pickle pickle; | |
| 229 EXPECT_TRUE(pickle.WriteInt(-1)); | |
| 230 | |
| 231 PickleIterator iter(pickle); | |
| 232 string16 outstr; | |
| 233 EXPECT_FALSE(iter.ReadString16(&outstr)); | |
| 234 } | |
| 235 | |
| 236 TEST(PickleTest, FindNext) { | |
| 237 Pickle pickle; | |
| 238 EXPECT_TRUE(pickle.WriteInt(1)); | |
| 239 EXPECT_TRUE(pickle.WriteString("Domo")); | |
| 240 | |
| 241 const char* start = reinterpret_cast<const char*>(pickle.data()); | |
| 242 const char* end = start + pickle.size(); | |
| 243 | |
| 244 EXPECT_TRUE(end == Pickle::FindNext(pickle.header_size_, start, end)); | |
| 245 EXPECT_TRUE(NULL == Pickle::FindNext(pickle.header_size_, start, end - 1)); | |
| 246 EXPECT_TRUE(end == Pickle::FindNext(pickle.header_size_, start, end + 1)); | |
| 247 } | |
| 248 | |
| 249 TEST(PickleTest, FindNextWithIncompleteHeader) { | |
| 250 size_t header_size = sizeof(Pickle::Header); | |
| 251 scoped_ptr<char[]> buffer(new char[header_size - 1]); | |
| 252 memset(buffer.get(), 0x1, header_size - 1); | |
| 253 | |
| 254 const char* start = buffer.get(); | |
| 255 const char* end = start + header_size - 1; | |
| 256 | |
| 257 EXPECT_TRUE(NULL == Pickle::FindNext(header_size, start, end)); | |
| 258 } | |
| 259 | |
| 260 #if defined(COMPILER_MSVC) | |
| 261 #pragma warning(push) | |
| 262 #pragma warning(disable: 4146) | |
| 263 #endif | |
| 264 TEST(PickleTest, FindNextOverflow) { | |
| 265 size_t header_size = sizeof(Pickle::Header); | |
| 266 size_t header_size2 = 2 * header_size; | |
| 267 size_t payload_received = 100; | |
| 268 scoped_ptr<char[]> buffer(new char[header_size2 + payload_received]); | |
| 269 const char* start = buffer.get(); | |
| 270 Pickle::Header* header = reinterpret_cast<Pickle::Header*>(buffer.get()); | |
| 271 const char* end = start + header_size2 + payload_received; | |
| 272 // It is impossible to construct an overflow test otherwise. | |
| 273 if (sizeof(size_t) > sizeof(header->payload_size) || | |
| 274 sizeof(uintptr_t) > sizeof(header->payload_size)) | |
| 275 return; | |
| 276 | |
| 277 header->payload_size = -(reinterpret_cast<uintptr_t>(start) + header_size2); | |
| 278 EXPECT_TRUE(NULL == Pickle::FindNext(header_size2, start, end)); | |
| 279 | |
| 280 header->payload_size = -header_size2; | |
| 281 EXPECT_TRUE(NULL == Pickle::FindNext(header_size2, start, end)); | |
| 282 | |
| 283 header->payload_size = 0; | |
| 284 end = start + header_size; | |
| 285 EXPECT_TRUE(NULL == Pickle::FindNext(header_size2, start, end)); | |
| 286 } | |
| 287 #if defined(COMPILER_MSVC) | |
| 288 #pragma warning(pop) | |
| 289 #endif | |
| 290 | |
| 291 TEST(PickleTest, GetReadPointerAndAdvance) { | |
| 292 Pickle pickle; | |
| 293 | |
| 294 PickleIterator iter(pickle); | |
| 295 EXPECT_FALSE(iter.GetReadPointerAndAdvance(1)); | |
| 296 | |
| 297 EXPECT_TRUE(pickle.WriteInt(1)); | |
| 298 EXPECT_TRUE(pickle.WriteInt(2)); | |
| 299 int bytes = sizeof(int) * 2; | |
| 300 | |
| 301 EXPECT_TRUE(PickleIterator(pickle).GetReadPointerAndAdvance(0)); | |
| 302 EXPECT_TRUE(PickleIterator(pickle).GetReadPointerAndAdvance(1)); | |
| 303 EXPECT_FALSE(PickleIterator(pickle).GetReadPointerAndAdvance(-1)); | |
| 304 EXPECT_TRUE(PickleIterator(pickle).GetReadPointerAndAdvance(bytes)); | |
| 305 EXPECT_FALSE(PickleIterator(pickle).GetReadPointerAndAdvance(bytes + 1)); | |
| 306 EXPECT_FALSE(PickleIterator(pickle).GetReadPointerAndAdvance(INT_MAX)); | |
| 307 EXPECT_FALSE(PickleIterator(pickle).GetReadPointerAndAdvance(INT_MIN)); | |
| 308 } | |
| 309 | |
| 310 TEST(PickleTest, Resize) { | |
| 311 size_t unit = Pickle::kPayloadUnit; | |
| 312 scoped_ptr<char[]> data(new char[unit]); | |
| 313 char* data_ptr = data.get(); | |
| 314 for (size_t i = 0; i < unit; i++) | |
| 315 data_ptr[i] = 'G'; | |
| 316 | |
| 317 // construct a message that will be exactly the size of one payload unit, | |
| 318 // note that any data will have a 4-byte header indicating the size | |
| 319 const size_t payload_size_after_header = unit - sizeof(uint32); | |
| 320 Pickle pickle; | |
| 321 pickle.WriteData(data_ptr, | |
| 322 static_cast<int>(payload_size_after_header - sizeof(uint32))); | |
| 323 size_t cur_payload = payload_size_after_header; | |
| 324 | |
| 325 // note: we assume 'unit' is a power of 2 | |
| 326 EXPECT_EQ(unit, pickle.capacity_after_header()); | |
| 327 EXPECT_EQ(pickle.payload_size(), payload_size_after_header); | |
| 328 | |
| 329 // fill out a full page (noting data header) | |
| 330 pickle.WriteData(data_ptr, static_cast<int>(unit - sizeof(uint32))); | |
| 331 cur_payload += unit; | |
| 332 EXPECT_EQ(unit * 2, pickle.capacity_after_header()); | |
| 333 EXPECT_EQ(cur_payload, pickle.payload_size()); | |
| 334 | |
| 335 // one more byte should double the capacity | |
| 336 pickle.WriteData(data_ptr, 1); | |
| 337 cur_payload += 8; | |
| 338 EXPECT_EQ(unit * 4, pickle.capacity_after_header()); | |
| 339 EXPECT_EQ(cur_payload, pickle.payload_size()); | |
| 340 } | |
| 341 | |
| 342 namespace { | |
| 343 | |
| 344 struct CustomHeader : Pickle::Header { | |
| 345 int blah; | |
| 346 }; | |
| 347 | |
| 348 } // namespace | |
| 349 | |
| 350 TEST(PickleTest, HeaderPadding) { | |
| 351 const uint32 kMagic = 0x12345678; | |
| 352 | |
| 353 Pickle pickle(sizeof(CustomHeader)); | |
| 354 pickle.WriteInt(kMagic); | |
| 355 | |
| 356 // this should not overwrite the 'int' payload | |
| 357 pickle.headerT<CustomHeader>()->blah = 10; | |
| 358 | |
| 359 PickleIterator iter(pickle); | |
| 360 int result; | |
| 361 ASSERT_TRUE(iter.ReadInt(&result)); | |
| 362 | |
| 363 EXPECT_EQ(static_cast<uint32>(result), kMagic); | |
| 364 } | |
| 365 | |
| 366 TEST(PickleTest, EqualsOperator) { | |
| 367 Pickle source; | |
| 368 source.WriteInt(1); | |
| 369 | |
| 370 Pickle copy_refs_source_buffer(static_cast<const char*>(source.data()), | |
| 371 source.size()); | |
| 372 Pickle copy; | |
| 373 copy = copy_refs_source_buffer; | |
| 374 ASSERT_EQ(source.size(), copy.size()); | |
| 375 } | |
| 376 | |
| 377 TEST(PickleTest, EvilLengths) { | |
| 378 Pickle source; | |
| 379 std::string str(100000, 'A'); | |
| 380 EXPECT_TRUE(source.WriteData(str.c_str(), 100000)); | |
| 381 // ReadString16 used to have its read buffer length calculation wrong leading | |
| 382 // to out-of-bounds reading. | |
| 383 PickleIterator iter(source); | |
| 384 string16 str16; | |
| 385 EXPECT_FALSE(iter.ReadString16(&str16)); | |
| 386 | |
| 387 // And check we didn't break ReadString16. | |
| 388 str16 = (wchar_t) 'A'; | |
| 389 Pickle str16_pickle; | |
| 390 EXPECT_TRUE(str16_pickle.WriteString16(str16)); | |
| 391 iter = PickleIterator(str16_pickle); | |
| 392 EXPECT_TRUE(iter.ReadString16(&str16)); | |
| 393 EXPECT_EQ(1U, str16.length()); | |
| 394 | |
| 395 // Check we don't fail in a length check with invalid String16 size. | |
| 396 // (1<<31) * sizeof(char16) == 0, so this is particularly evil. | |
| 397 Pickle bad_len; | |
| 398 EXPECT_TRUE(bad_len.WriteInt(1 << 31)); | |
| 399 iter = PickleIterator(bad_len); | |
| 400 EXPECT_FALSE(iter.ReadString16(&str16)); | |
| 401 } | |
| 402 | |
| 403 // Check we can write zero bytes of data and 'data' can be NULL. | |
| 404 TEST(PickleTest, ZeroLength) { | |
| 405 Pickle pickle; | |
| 406 EXPECT_TRUE(pickle.WriteData(NULL, 0)); | |
| 407 | |
| 408 PickleIterator iter(pickle); | |
| 409 const char* outdata; | |
| 410 int outdatalen; | |
| 411 EXPECT_TRUE(iter.ReadData(&outdata, &outdatalen)); | |
| 412 EXPECT_EQ(0, outdatalen); | |
| 413 // We can't assert that outdata is NULL. | |
| 414 } | |
| 415 | |
| 416 // Check that ReadBytes works properly with an iterator initialized to NULL. | |
| 417 TEST(PickleTest, ReadBytes) { | |
| 418 Pickle pickle; | |
| 419 int data = 0x7abcd; | |
| 420 EXPECT_TRUE(pickle.WriteBytes(&data, sizeof(data))); | |
| 421 | |
| 422 PickleIterator iter(pickle); | |
| 423 const char* outdata_char = NULL; | |
| 424 EXPECT_TRUE(iter.ReadBytes(&outdata_char, sizeof(data))); | |
| 425 | |
| 426 int outdata; | |
| 427 memcpy(&outdata, outdata_char, sizeof(outdata)); | |
| 428 EXPECT_EQ(data, outdata); | |
| 429 } | |
| 430 | |
| 431 } // namespace base | |
| OLD | NEW |