1 // Copyright (c) 2010, Google Inc. 2 // All rights reserved. 3 // 4 // Redistribution and use in source and binary forms, with or without 5 // modification, are permitted provided that the following conditions are 6 // met: 7 // 8 // * Redistributions of source code must retain the above copyright 9 // notice, this list of conditions and the following disclaimer. 10 // * Redistributions in binary form must reproduce the above 11 // copyright notice, this list of conditions and the following disclaimer 12 // in the documentation and/or other materials provided with the 13 // distribution. 14 // * Neither the name of Google Inc. nor the names of its 15 // contributors may be used to endorse or promote products derived from 16 // this software without specific prior written permission. 17 // 18 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 30 #include <ios> 31 #include <string> 32 #include <vector> 33 34 #include "breakpad_googletest_includes.h" 35 #include "common/using_std_string.h" 36 #include "processor/binarystream.h" 37 38 namespace { 39 using std::ios_base; 40 using std::vector; 41 using google_breakpad::binarystream; 42 43 44 class BinaryStreamBasicTest : public ::testing::Test { 45 protected: 46 binarystream stream; 47 }; 48 49 TEST_F(BinaryStreamBasicTest, ReadU8) { 50 uint8_t u8 = 0; 51 ASSERT_FALSE(stream.eof()); 52 stream >> u8; 53 ASSERT_TRUE(stream.eof()); 54 EXPECT_EQ(0U, u8); 55 stream.rewind(); 56 stream.clear(); 57 stream << (uint8_t)1; 58 ASSERT_FALSE(stream.eof()); 59 stream >> u8; 60 EXPECT_EQ(1, u8); 61 EXPECT_FALSE(stream.eof()); 62 } 63 64 TEST_F(BinaryStreamBasicTest, ReadU16) { 65 uint16_t u16 = 0; 66 ASSERT_FALSE(stream.eof()); 67 stream >> u16; 68 ASSERT_TRUE(stream.eof()); 69 EXPECT_EQ(0U, u16); 70 stream.rewind(); 71 stream.clear(); 72 stream << (uint16_t)1; 73 ASSERT_FALSE(stream.eof()); 74 stream >> u16; 75 EXPECT_EQ(1, u16); 76 EXPECT_FALSE(stream.eof()); 77 } 78 79 TEST_F(BinaryStreamBasicTest, ReadU32) { 80 uint32_t u32 = 0; 81 ASSERT_FALSE(stream.eof()); 82 stream >> u32; 83 ASSERT_TRUE(stream.eof()); 84 EXPECT_EQ(0U, u32); 85 stream.rewind(); 86 stream.clear(); 87 stream << (uint32_t)1; 88 ASSERT_FALSE(stream.eof()); 89 stream >> u32; 90 EXPECT_EQ(1U, u32); 91 EXPECT_FALSE(stream.eof()); 92 } 93 94 TEST_F(BinaryStreamBasicTest, ReadU64) { 95 uint64_t u64 = 0; 96 ASSERT_FALSE(stream.eof()); 97 stream >> u64; 98 ASSERT_TRUE(stream.eof()); 99 EXPECT_EQ(0U, u64); 100 stream.rewind(); 101 stream.clear(); 102 stream << (uint64_t)1; 103 ASSERT_FALSE(stream.eof()); 104 stream >> u64; 105 EXPECT_EQ(1U, u64); 106 EXPECT_FALSE(stream.eof()); 107 } 108 109 TEST_F(BinaryStreamBasicTest, ReadString) { 110 string s(""); 111 ASSERT_FALSE(stream.eof()); 112 stream >> s; 113 ASSERT_TRUE(stream.eof()); 114 EXPECT_EQ("", s); 115 // write an empty string to the stream, read it back 116 s = "abcd"; 117 stream.rewind(); 118 stream.clear(); 119 stream << string(""); 120 stream >> s; 121 EXPECT_EQ("", s); 122 EXPECT_FALSE(stream.eof()); 123 stream.rewind(); 124 stream.clear(); 125 stream << string("test"); 126 ASSERT_FALSE(stream.eof()); 127 stream >> s; 128 EXPECT_EQ("test", s); 129 EXPECT_FALSE(stream.eof()); 130 } 131 132 TEST_F(BinaryStreamBasicTest, ReadEmptyString) { 133 string s("abc"); 134 stream << string(""); 135 stream >> s; 136 EXPECT_EQ("", s); 137 } 138 139 TEST_F(BinaryStreamBasicTest, ReadMultiU8) { 140 const uint8_t ea = 0, eb = 100, ec = 200, ed = 0xFF; 141 uint8_t a, b, c, d, e; 142 stream << ea << eb << ec << ed; 143 stream >> a >> b >> c >> d; 144 ASSERT_FALSE(stream.eof()); 145 EXPECT_EQ(ea, a); 146 EXPECT_EQ(eb, b); 147 EXPECT_EQ(ec, c); 148 EXPECT_EQ(ed, d); 149 ASSERT_FALSE(stream.eof()); 150 e = 0; 151 stream >> e; 152 EXPECT_EQ(0U, e); 153 ASSERT_TRUE(stream.eof()); 154 // try reading all at once, including one past eof 155 stream.rewind(); 156 stream.clear(); 157 ASSERT_FALSE(stream.eof()); 158 a = b = c = d = e = 0; 159 stream << ea << eb << ec << ed; 160 stream >> a >> b >> c >> d >> e; 161 EXPECT_EQ(ea, a); 162 EXPECT_EQ(eb, b); 163 EXPECT_EQ(ec, c); 164 EXPECT_EQ(ed, d); 165 EXPECT_EQ(0U, e); 166 EXPECT_TRUE(stream.eof()); 167 } 168 169 TEST_F(BinaryStreamBasicTest, ReadMultiU16) { 170 const uint16_t ea = 0, eb = 0x100, ec = 0x8000, ed = 0xFFFF; 171 uint16_t a, b, c, d, e; 172 stream << ea << eb << ec << ed; 173 stream >> a >> b >> c >> d; 174 ASSERT_FALSE(stream.eof()); 175 EXPECT_EQ(ea, a); 176 EXPECT_EQ(eb, b); 177 EXPECT_EQ(ec, c); 178 EXPECT_EQ(ed, d); 179 ASSERT_FALSE(stream.eof()); 180 e = 0; 181 stream >> e; 182 EXPECT_EQ(0U, e); 183 EXPECT_TRUE(stream.eof()); 184 // try reading all at once, including one past eof 185 stream.rewind(); 186 stream.clear(); 187 ASSERT_FALSE(stream.eof()); 188 a = b = c = d = e = 0; 189 stream << ea << eb << ec << ed; 190 stream >> a >> b >> c >> d >> e; 191 EXPECT_EQ(ea, a); 192 EXPECT_EQ(eb, b); 193 EXPECT_EQ(ec, c); 194 EXPECT_EQ(ed, d); 195 EXPECT_EQ(0U, e); 196 EXPECT_TRUE(stream.eof()); 197 } 198 199 TEST_F(BinaryStreamBasicTest, ReadMultiU32) { 200 const uint32_t ea = 0, eb = 0x10000, ec = 0x8000000, ed = 0xFFFFFFFF; 201 uint32_t a, b, c, d, e; 202 stream << ea << eb << ec << ed; 203 stream >> a >> b >> c >> d; 204 ASSERT_FALSE(stream.eof()); 205 EXPECT_EQ(ea, a); 206 EXPECT_EQ(eb, b); 207 EXPECT_EQ(ec, c); 208 EXPECT_EQ(ed, d); 209 ASSERT_FALSE(stream.eof()); 210 e = 0; 211 stream >> e; 212 EXPECT_EQ(0U, e); 213 EXPECT_TRUE(stream.eof()); 214 // try reading all at once, including one past eof 215 stream.rewind(); 216 stream.clear(); 217 ASSERT_FALSE(stream.eof()); 218 a = b = c = d = e = 0; 219 stream << ea << eb << ec << ed; 220 stream >> a >> b >> c >> d >> e; 221 EXPECT_EQ(ea, a); 222 EXPECT_EQ(eb, b); 223 EXPECT_EQ(ec, c); 224 EXPECT_EQ(ed, d); 225 EXPECT_EQ(0U, e); 226 EXPECT_TRUE(stream.eof()); 227 } 228 229 TEST_F(BinaryStreamBasicTest, ReadMultiU64) { 230 const uint64_t ea = 0, eb = 0x10000, ec = 0x100000000ULL, 231 ed = 0xFFFFFFFFFFFFFFFFULL; 232 uint64_t a, b, c, d, e; 233 stream << ea << eb << ec << ed; 234 stream >> a >> b >> c >> d; 235 ASSERT_FALSE(stream.eof()); 236 EXPECT_EQ(ea, a); 237 EXPECT_EQ(eb, b); 238 EXPECT_EQ(ec, c); 239 EXPECT_EQ(ed, d); 240 ASSERT_FALSE(stream.eof()); 241 e = 0; 242 stream >> e; 243 EXPECT_EQ(0U, e); 244 EXPECT_TRUE(stream.eof()); 245 // try reading all at once, including one past eof 246 stream.rewind(); 247 stream.clear(); 248 ASSERT_FALSE(stream.eof()); 249 a = b = c = d = e = 0; 250 stream << ea << eb << ec << ed; 251 stream >> a >> b >> c >> d >> e; 252 EXPECT_EQ(ea, a); 253 EXPECT_EQ(eb, b); 254 EXPECT_EQ(ec, c); 255 EXPECT_EQ(ed, d); 256 EXPECT_EQ(0U, e); 257 EXPECT_TRUE(stream.eof()); 258 } 259 260 TEST_F(BinaryStreamBasicTest, ReadMixed) { 261 const uint8_t e8 = 0x10; 262 const uint16_t e16 = 0x2020; 263 const uint32_t e32 = 0x30303030; 264 const uint64_t e64 = 0x4040404040404040ULL; 265 const string es = "test"; 266 uint8_t u8 = 0; 267 uint16_t u16 = 0; 268 uint32_t u32 = 0; 269 uint64_t u64 = 0; 270 string s("test"); 271 stream << e8 << e16 << e32 << e64 << es; 272 stream >> u8 >> u16 >> u32 >> u64 >> s; 273 EXPECT_FALSE(stream.eof()); 274 EXPECT_EQ(e8, u8); 275 EXPECT_EQ(e16, u16); 276 EXPECT_EQ(e32, u32); 277 EXPECT_EQ(e64, u64); 278 EXPECT_EQ(es, s); 279 } 280 281 TEST_F(BinaryStreamBasicTest, ReadStringMissing) { 282 // ensure that reading a string where only the length is present fails 283 uint16_t u16 = 8; 284 stream << u16; 285 stream.rewind(); 286 string s(""); 287 stream >> s; 288 EXPECT_EQ("", s); 289 EXPECT_TRUE(stream.eof()); 290 } 291 292 TEST_F(BinaryStreamBasicTest, ReadStringTruncated) { 293 // ensure that reading a string where not all the data is present fails 294 uint16_t u16 = 8; 295 stream << u16; 296 stream << (uint8_t)'t' << (uint8_t)'e' << (uint8_t)'s' << (uint8_t)'t'; 297 stream.rewind(); 298 string s(""); 299 stream >> s; 300 EXPECT_EQ("", s); 301 EXPECT_TRUE(stream.eof()); 302 } 303 304 TEST_F(BinaryStreamBasicTest, StreamByteLength) { 305 // Test that the stream buffer contains the right amount of data 306 stream << (uint8_t)0 << (uint16_t)1 << (uint32_t)2 << (uint64_t)3 307 << string("test"); 308 string s = stream.str(); 309 EXPECT_EQ(21U, s.length()); 310 } 311 312 TEST_F(BinaryStreamBasicTest, AppendStreamResultsByteLength) { 313 // Test that appending the str() results from two streams 314 // gives the right byte length 315 binarystream stream2; 316 stream << (uint8_t)0 << (uint16_t)1; 317 stream2 << (uint32_t)0 << (uint64_t)2 318 << string("test"); 319 string s = stream.str(); 320 string s2 = stream2.str(); 321 s.append(s2); 322 EXPECT_EQ(21U, s.length()); 323 } 324 325 TEST_F(BinaryStreamBasicTest, StreamSetStr) { 326 const string es("test"); 327 stream << es; 328 binarystream stream2; 329 stream2.str(stream.str()); 330 string s; 331 stream2 >> s; 332 EXPECT_FALSE(stream2.eof()); 333 EXPECT_EQ("test", s); 334 s = ""; 335 stream2.str(stream.str()); 336 stream2.rewind(); 337 stream2 >> s; 338 EXPECT_FALSE(stream2.eof()); 339 EXPECT_EQ("test", s); 340 } 341 342 class BinaryStreamU8Test : public ::testing::Test { 343 protected: 344 binarystream stream; 345 346 void SetUp() { 347 stream << (uint8_t)1; 348 } 349 }; 350 351 TEST_F(BinaryStreamU8Test, ReadU16) { 352 uint16_t u16 = 0; 353 ASSERT_FALSE(stream.eof()); 354 stream >> u16; 355 ASSERT_TRUE(stream.eof()); 356 EXPECT_EQ(0U, u16); 357 } 358 359 TEST_F(BinaryStreamU8Test, ReadU32) { 360 uint32_t u32 = 0; 361 ASSERT_FALSE(stream.eof()); 362 stream >> u32; 363 ASSERT_TRUE(stream.eof()); 364 EXPECT_EQ(0U, u32); 365 } 366 367 TEST_F(BinaryStreamU8Test, ReadU64) { 368 uint64_t u64 = 0; 369 ASSERT_FALSE(stream.eof()); 370 stream >> u64; 371 ASSERT_TRUE(stream.eof()); 372 EXPECT_EQ(0U, u64); 373 } 374 375 TEST_F(BinaryStreamU8Test, ReadString) { 376 string s(""); 377 ASSERT_FALSE(stream.eof()); 378 stream >> s; 379 ASSERT_TRUE(stream.eof()); 380 EXPECT_EQ("", s); 381 } 382 383 384 TEST(BinaryStreamTest, InitWithData) { 385 const char *data = "abcd"; 386 binarystream stream(data); 387 uint8_t a, b, c, d; 388 stream >> a >> b >> c >> d; 389 ASSERT_FALSE(stream.eof()); 390 EXPECT_EQ('a', a); 391 EXPECT_EQ('b', b); 392 EXPECT_EQ('c', c); 393 EXPECT_EQ('d', d); 394 } 395 396 TEST(BinaryStreamTest, InitWithDataLeadingNull) { 397 const char *data = "\0abcd"; 398 binarystream stream(data, 5); 399 uint8_t z, a, b, c, d; 400 stream >> z >> a >> b >> c >> d; 401 ASSERT_FALSE(stream.eof()); 402 EXPECT_EQ(0U, z); 403 EXPECT_EQ('a', a); 404 EXPECT_EQ('b', b); 405 EXPECT_EQ('c', c); 406 EXPECT_EQ('d', d); 407 } 408 409 TEST(BinaryStreamTest, InitWithDataVector) { 410 vector<char> data; 411 data.push_back('a'); 412 data.push_back('b'); 413 data.push_back('c'); 414 data.push_back('d'); 415 data.push_back('e'); 416 data.resize(4); 417 binarystream stream(&data[0], data.size()); 418 uint8_t a, b, c, d; 419 stream >> a >> b >> c >> d; 420 ASSERT_FALSE(stream.eof()); 421 EXPECT_EQ('a', a); 422 EXPECT_EQ('b', b); 423 EXPECT_EQ('c', c); 424 EXPECT_EQ('d', d); 425 } 426 427 } // namespace 428 429 int main(int argc, char *argv[]) { 430 ::testing::InitGoogleTest(&argc, argv); 431 return RUN_ALL_TESTS(); 432 } 433