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