• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
TEST_F(BinaryStreamBasicTest,ReadU8)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 
TEST_F(BinaryStreamBasicTest,ReadU16)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 
TEST_F(BinaryStreamBasicTest,ReadU32)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 
TEST_F(BinaryStreamBasicTest,ReadU64)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 
TEST_F(BinaryStreamBasicTest,ReadString)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 
TEST_F(BinaryStreamBasicTest,ReadEmptyString)132 TEST_F(BinaryStreamBasicTest, ReadEmptyString) {
133   string s("abc");
134   stream << string("");
135   stream >> s;
136   EXPECT_EQ("", s);
137 }
138 
TEST_F(BinaryStreamBasicTest,ReadMultiU8)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 
TEST_F(BinaryStreamBasicTest,ReadMultiU16)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 
TEST_F(BinaryStreamBasicTest,ReadMultiU32)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 
TEST_F(BinaryStreamBasicTest,ReadMultiU64)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 
TEST_F(BinaryStreamBasicTest,ReadMixed)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 
TEST_F(BinaryStreamBasicTest,ReadStringMissing)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 
TEST_F(BinaryStreamBasicTest,ReadStringTruncated)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 
TEST_F(BinaryStreamBasicTest,StreamByteLength)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 
TEST_F(BinaryStreamBasicTest,AppendStreamResultsByteLength)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 
TEST_F(BinaryStreamBasicTest,StreamSetStr)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 
SetUp()346   void SetUp() {
347     stream << (uint8_t)1;
348   }
349 };
350 
TEST_F(BinaryStreamU8Test,ReadU16)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 
TEST_F(BinaryStreamU8Test,ReadU32)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 
TEST_F(BinaryStreamU8Test,ReadU64)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 
TEST_F(BinaryStreamU8Test,ReadString)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 
TEST(BinaryStreamTest,InitWithData)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 
TEST(BinaryStreamTest,InitWithDataLeadingNull)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 
TEST(BinaryStreamTest,InitWithDataVector)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 
main(int argc,char * argv[])429 int main(int argc, char *argv[]) {
430   ::testing::InitGoogleTest(&argc, argv);
431   return RUN_ALL_TESTS();
432 }
433