pickle_unittest.cc revision 21d179b334e59e9a3bfcaed4c4430bef1bc5759d
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, IteratorHasRoom) { 175 Pickle pickle; 176 EXPECT_TRUE(pickle.WriteInt(1)); 177 EXPECT_TRUE(pickle.WriteInt(2)); 178 179 const void* iter = 0; 180 EXPECT_FALSE(pickle.IteratorHasRoomFor(iter, 1)); 181 iter = pickle.payload(); 182 EXPECT_TRUE(pickle.IteratorHasRoomFor(iter, 0)); 183 EXPECT_TRUE(pickle.IteratorHasRoomFor(iter, 1)); 184 EXPECT_FALSE(pickle.IteratorHasRoomFor(iter, -1)); 185 EXPECT_TRUE(pickle.IteratorHasRoomFor(iter, sizeof(int) * 2)); 186 EXPECT_FALSE(pickle.IteratorHasRoomFor(iter, (sizeof(int) * 2) + 1)); 187} 188 189TEST(PickleTest, Resize) { 190 size_t unit = Pickle::kPayloadUnit; 191 scoped_array<char> data(new char[unit]); 192 char* data_ptr = data.get(); 193 for (size_t i = 0; i < unit; i++) 194 data_ptr[i] = 'G'; 195 196 // construct a message that will be exactly the size of one payload unit, 197 // note that any data will have a 4-byte header indicating the size 198 const size_t payload_size_after_header = unit - sizeof(uint32); 199 Pickle pickle; 200 pickle.WriteData(data_ptr, 201 static_cast<int>(payload_size_after_header - sizeof(uint32))); 202 size_t cur_payload = payload_size_after_header; 203 204 // note: we assume 'unit' is a power of 2 205 EXPECT_EQ(unit, pickle.capacity()); 206 EXPECT_EQ(pickle.payload_size(), payload_size_after_header); 207 208 // fill out a full page (noting data header) 209 pickle.WriteData(data_ptr, static_cast<int>(unit - sizeof(uint32))); 210 cur_payload += unit; 211 EXPECT_EQ(unit * 2, pickle.capacity()); 212 EXPECT_EQ(cur_payload, pickle.payload_size()); 213 214 // one more byte should double the capacity 215 pickle.WriteData(data_ptr, 1); 216 cur_payload += 5; 217 EXPECT_EQ(unit * 4, pickle.capacity()); 218 EXPECT_EQ(cur_payload, pickle.payload_size()); 219} 220 221namespace { 222 223struct CustomHeader : Pickle::Header { 224 int blah; 225}; 226 227} // namespace 228 229TEST(PickleTest, HeaderPadding) { 230 const uint32 kMagic = 0x12345678; 231 232 Pickle pickle(sizeof(CustomHeader)); 233 pickle.WriteInt(kMagic); 234 235 // this should not overwrite the 'int' payload 236 pickle.headerT<CustomHeader>()->blah = 10; 237 238 void* iter = NULL; 239 int result; 240 ASSERT_TRUE(pickle.ReadInt(&iter, &result)); 241 242 EXPECT_EQ(static_cast<uint32>(result), kMagic); 243} 244 245TEST(PickleTest, EqualsOperator) { 246 Pickle source; 247 source.WriteInt(1); 248 249 Pickle copy_refs_source_buffer(static_cast<const char*>(source.data()), 250 source.size()); 251 Pickle copy; 252 copy = copy_refs_source_buffer; 253 ASSERT_EQ(source.size(), copy.size()); 254} 255 256TEST(PickleTest, EvilLengths) { 257 Pickle source; 258 std::string str(100000, 'A'); 259 source.WriteData(str.c_str(), 100000); 260 // ReadString16 used to have its read buffer length calculation wrong leading 261 // to out-of-bounds reading. 262 void* iter = NULL; 263 string16 str16; 264 EXPECT_FALSE(source.ReadString16(&iter, &str16)); 265 266 // And check we didn't break ReadString16. 267 str16 = (wchar_t) 'A'; 268 Pickle str16_pickle; 269 str16_pickle.WriteString16(str16); 270 iter = NULL; 271 EXPECT_TRUE(str16_pickle.ReadString16(&iter, &str16)); 272 EXPECT_EQ(1U, str16.length()); 273 274 // Check we don't fail in a length check with large WStrings. 275 Pickle big_len; 276 big_len.WriteInt(1 << 30); 277 iter = NULL; 278 std::wstring wstr; 279 EXPECT_FALSE(big_len.ReadWString(&iter, &wstr)); 280} 281 282// Check we can write zero bytes of data and 'data' can be NULL. 283TEST(PickleTest, ZeroLength) { 284 Pickle pickle; 285 EXPECT_TRUE(pickle.WriteData(NULL, 0)); 286 287 void* iter = NULL; 288 const char* outdata; 289 int outdatalen; 290 EXPECT_TRUE(pickle.ReadData(&iter, &outdata, &outdatalen)); 291 EXPECT_EQ(0, outdatalen); 292 // We can't assert that outdata is NULL. 293} 294 295// Check that ReadBytes works properly with an iterator initialized to NULL. 296TEST(PickleTest, ReadBytes) { 297 Pickle pickle; 298 int data = 0x7abcd; 299 EXPECT_TRUE(pickle.WriteBytes(&data, sizeof(data))); 300 301 void* iter = NULL; 302 const char* outdata_char; 303 EXPECT_TRUE(pickle.ReadBytes(&iter, &outdata_char, sizeof(data))); 304 305 int outdata; 306 memcpy(&outdata, outdata_char, sizeof(outdata)); 307 EXPECT_EQ(data, outdata); 308} 309