Home | History | Annotate | Download | only in processor
      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