1 #include "gtest/gtest.h"
2 #include <limits.h>
3 
4 #include "lldb/Utility/StringExtractor.h"
5 
6 namespace {
7 class StringExtractorTest : public ::testing::Test {};
8 } // namespace
9 
TEST_F(StringExtractorTest,InitEmpty)10 TEST_F(StringExtractorTest, InitEmpty) {
11   llvm::StringRef kEmptyString = "";
12   StringExtractor ex(kEmptyString);
13 
14   ASSERT_EQ(true, ex.IsGood());
15   ASSERT_EQ(0u, ex.GetFilePos());
16   ASSERT_EQ(kEmptyString, ex.GetStringRef());
17   ASSERT_EQ(true, ex.Empty());
18   ASSERT_EQ(0u, ex.GetBytesLeft());
19   ASSERT_EQ(nullptr, ex.Peek());
20 }
21 
TEST_F(StringExtractorTest,InitMisc)22 TEST_F(StringExtractorTest, InitMisc) {
23   llvm::StringRef kInitMiscString = "Hello, StringExtractor!";
24   StringExtractor ex(kInitMiscString);
25 
26   ASSERT_EQ(true, ex.IsGood());
27   ASSERT_EQ(0u, ex.GetFilePos());
28   ASSERT_EQ(kInitMiscString, ex.GetStringRef());
29   ASSERT_EQ(false, ex.Empty());
30   ASSERT_EQ(kInitMiscString.size(), ex.GetBytesLeft());
31   ASSERT_EQ(kInitMiscString[0], *ex.Peek());
32 }
33 
TEST_F(StringExtractorTest,DecodeHexU8_Underflow)34 TEST_F(StringExtractorTest, DecodeHexU8_Underflow) {
35   llvm::StringRef kEmptyString = "";
36   StringExtractor ex(kEmptyString);
37 
38   ASSERT_EQ(-1, ex.DecodeHexU8());
39   ASSERT_EQ(true, ex.IsGood());
40   ASSERT_EQ(0u, ex.GetFilePos());
41   ASSERT_EQ(true, ex.Empty());
42   ASSERT_EQ(0u, ex.GetBytesLeft());
43   ASSERT_EQ(nullptr, ex.Peek());
44 }
45 
TEST_F(StringExtractorTest,DecodeHexU8_Underflow2)46 TEST_F(StringExtractorTest, DecodeHexU8_Underflow2) {
47   StringExtractor ex("1");
48 
49   ASSERT_EQ(-1, ex.DecodeHexU8());
50   ASSERT_EQ(true, ex.IsGood());
51   ASSERT_EQ(0u, ex.GetFilePos());
52   ASSERT_EQ(1u, ex.GetBytesLeft());
53   ASSERT_EQ('1', *ex.Peek());
54 }
55 
TEST_F(StringExtractorTest,DecodeHexU8_InvalidHex)56 TEST_F(StringExtractorTest, DecodeHexU8_InvalidHex) {
57   llvm::StringRef kInvalidHex = "xa";
58   StringExtractor ex(kInvalidHex);
59 
60   ASSERT_EQ(-1, ex.DecodeHexU8());
61   ASSERT_EQ(true, ex.IsGood());
62   ASSERT_EQ(0u, ex.GetFilePos());
63   ASSERT_EQ(2u, ex.GetBytesLeft());
64   ASSERT_EQ('x', *ex.Peek());
65 }
66 
TEST_F(StringExtractorTest,DecodeHexU8_InvalidHex2)67 TEST_F(StringExtractorTest, DecodeHexU8_InvalidHex2) {
68   llvm::StringRef kInvalidHex = "ax";
69   StringExtractor ex(kInvalidHex);
70 
71   ASSERT_EQ(-1, ex.DecodeHexU8());
72   ASSERT_EQ(true, ex.IsGood());
73   ASSERT_EQ(0u, ex.GetFilePos());
74   ASSERT_EQ(2u, ex.GetBytesLeft());
75   ASSERT_EQ('a', *ex.Peek());
76 }
77 
TEST_F(StringExtractorTest,DecodeHexU8_Exact)78 TEST_F(StringExtractorTest, DecodeHexU8_Exact) {
79   llvm::StringRef kValidHexPair = "12";
80   StringExtractor ex(kValidHexPair);
81 
82   ASSERT_EQ(0x12, ex.DecodeHexU8());
83   ASSERT_EQ(true, ex.IsGood());
84   ASSERT_EQ(2u, ex.GetFilePos());
85   ASSERT_EQ(0u, ex.GetBytesLeft());
86   ASSERT_EQ(nullptr, ex.Peek());
87 }
88 
TEST_F(StringExtractorTest,DecodeHexU8_Extra)89 TEST_F(StringExtractorTest, DecodeHexU8_Extra) {
90   llvm::StringRef kValidHexPair = "1234";
91   StringExtractor ex(kValidHexPair);
92 
93   ASSERT_EQ(0x12, ex.DecodeHexU8());
94   ASSERT_EQ(true, ex.IsGood());
95   ASSERT_EQ(2u, ex.GetFilePos());
96   ASSERT_EQ(2u, ex.GetBytesLeft());
97   ASSERT_EQ('3', *ex.Peek());
98 }
99 
TEST_F(StringExtractorTest,GetHexU8_Underflow)100 TEST_F(StringExtractorTest, GetHexU8_Underflow) {
101   llvm::StringRef kEmptyString = "";
102   StringExtractor ex(kEmptyString);
103 
104   ASSERT_EQ(0xab, ex.GetHexU8(0xab));
105   ASSERT_EQ(false, ex.IsGood());
106   ASSERT_EQ(UINT64_MAX, ex.GetFilePos());
107   ASSERT_EQ(true, ex.Empty());
108   ASSERT_EQ(0u, ex.GetBytesLeft());
109   ASSERT_EQ(nullptr, ex.Peek());
110 }
111 
TEST_F(StringExtractorTest,GetHexU8_Underflow2)112 TEST_F(StringExtractorTest, GetHexU8_Underflow2) {
113   llvm::StringRef kOneNibble = "1";
114   StringExtractor ex(kOneNibble);
115 
116   ASSERT_EQ(0xbc, ex.GetHexU8(0xbc));
117   ASSERT_EQ(false, ex.IsGood());
118   ASSERT_EQ(UINT64_MAX, ex.GetFilePos());
119   ASSERT_EQ(0u, ex.GetBytesLeft());
120   ASSERT_EQ(nullptr, ex.Peek());
121 }
122 
TEST_F(StringExtractorTest,GetHexU8_InvalidHex)123 TEST_F(StringExtractorTest, GetHexU8_InvalidHex) {
124   llvm::StringRef kInvalidHex = "xx";
125   StringExtractor ex(kInvalidHex);
126 
127   ASSERT_EQ(0xcd, ex.GetHexU8(0xcd));
128   ASSERT_EQ(false, ex.IsGood());
129   ASSERT_EQ(UINT64_MAX, ex.GetFilePos());
130   ASSERT_EQ(0u, ex.GetBytesLeft());
131   ASSERT_EQ(nullptr, ex.Peek());
132 }
133 
TEST_F(StringExtractorTest,GetHexU8_Exact)134 TEST_F(StringExtractorTest, GetHexU8_Exact) {
135   llvm::StringRef kValidHexPair = "12";
136   StringExtractor ex(kValidHexPair);
137 
138   ASSERT_EQ(0x12, ex.GetHexU8(0x12));
139   ASSERT_EQ(true, ex.IsGood());
140   ASSERT_EQ(2u, ex.GetFilePos());
141   ASSERT_EQ(0u, ex.GetBytesLeft());
142   ASSERT_EQ(nullptr, ex.Peek());
143 }
144 
TEST_F(StringExtractorTest,GetHexU8_Extra)145 TEST_F(StringExtractorTest, GetHexU8_Extra) {
146   llvm::StringRef kValidHexPair = "1234";
147   StringExtractor ex(kValidHexPair);
148 
149   ASSERT_EQ(0x12, ex.GetHexU8(0x12));
150   ASSERT_EQ(true, ex.IsGood());
151   ASSERT_EQ(2u, ex.GetFilePos());
152   ASSERT_EQ(2u, ex.GetBytesLeft());
153   ASSERT_EQ('3', *ex.Peek());
154 }
155 
TEST_F(StringExtractorTest,GetHexU8_Underflow_NoEof)156 TEST_F(StringExtractorTest, GetHexU8_Underflow_NoEof) {
157   llvm::StringRef kEmptyString = "";
158   StringExtractor ex(kEmptyString);
159   const bool kSetEofOnFail = false;
160 
161   ASSERT_EQ(0xab, ex.GetHexU8(0xab, kSetEofOnFail));
162   ASSERT_EQ(false, ex.IsGood()); // this result seems inconsistent with
163                                  // kSetEofOnFail == false
164   ASSERT_EQ(UINT64_MAX, ex.GetFilePos());
165   ASSERT_EQ(true, ex.Empty());
166   ASSERT_EQ(0u, ex.GetBytesLeft());
167   ASSERT_EQ(nullptr, ex.Peek());
168 }
169 
TEST_F(StringExtractorTest,GetHexU8_Underflow2_NoEof)170 TEST_F(StringExtractorTest, GetHexU8_Underflow2_NoEof) {
171   llvm::StringRef kOneNibble = "1";
172   StringExtractor ex(kOneNibble);
173   const bool kSetEofOnFail = false;
174 
175   ASSERT_EQ(0xbc, ex.GetHexU8(0xbc, kSetEofOnFail));
176   ASSERT_EQ(true, ex.IsGood());
177   ASSERT_EQ(0u, ex.GetFilePos());
178   ASSERT_EQ(1u, ex.GetBytesLeft());
179   ASSERT_EQ('1', *ex.Peek());
180 }
181 
TEST_F(StringExtractorTest,GetHexU8_InvalidHex_NoEof)182 TEST_F(StringExtractorTest, GetHexU8_InvalidHex_NoEof) {
183   llvm::StringRef kInvalidHex = "xx";
184   StringExtractor ex(kInvalidHex);
185   const bool kSetEofOnFail = false;
186 
187   ASSERT_EQ(0xcd, ex.GetHexU8(0xcd, kSetEofOnFail));
188   ASSERT_EQ(true, ex.IsGood());
189   ASSERT_EQ(0u, ex.GetFilePos());
190   ASSERT_EQ(2u, ex.GetBytesLeft());
191   ASSERT_EQ('x', *ex.Peek());
192 }
193 
TEST_F(StringExtractorTest,GetHexU8_Exact_NoEof)194 TEST_F(StringExtractorTest, GetHexU8_Exact_NoEof) {
195   llvm::StringRef kValidHexPair = "12";
196   StringExtractor ex(kValidHexPair);
197   const bool kSetEofOnFail = false;
198 
199   ASSERT_EQ(0x12, ex.GetHexU8(0x12, kSetEofOnFail));
200   ASSERT_EQ(true, ex.IsGood());
201   ASSERT_EQ(2u, ex.GetFilePos());
202   ASSERT_EQ(0u, ex.GetBytesLeft());
203   ASSERT_EQ(nullptr, ex.Peek());
204 }
205 
TEST_F(StringExtractorTest,GetHexU8_Extra_NoEof)206 TEST_F(StringExtractorTest, GetHexU8_Extra_NoEof) {
207   llvm::StringRef kValidHexPair = "1234";
208   StringExtractor ex(kValidHexPair);
209   const bool kSetEofOnFail = false;
210 
211   ASSERT_EQ(0x12, ex.GetHexU8(0x12, kSetEofOnFail));
212   ASSERT_EQ(true, ex.IsGood());
213   ASSERT_EQ(2u, ex.GetFilePos());
214   ASSERT_EQ(2u, ex.GetBytesLeft());
215   ASSERT_EQ('3', *ex.Peek());
216 }
217 
TEST_F(StringExtractorTest,GetHexBytes)218 TEST_F(StringExtractorTest, GetHexBytes) {
219   llvm::StringRef kHexEncodedBytes = "abcdef0123456789xyzw";
220   const size_t kValidHexPairs = 8;
221   StringExtractor ex(kHexEncodedBytes);
222 
223   uint8_t dst[kValidHexPairs];
224   ASSERT_EQ(kValidHexPairs, ex.GetHexBytes(dst, 0xde));
225   EXPECT_EQ(0xab, dst[0]);
226   EXPECT_EQ(0xcd, dst[1]);
227   EXPECT_EQ(0xef, dst[2]);
228   EXPECT_EQ(0x01, dst[3]);
229   EXPECT_EQ(0x23, dst[4]);
230   EXPECT_EQ(0x45, dst[5]);
231   EXPECT_EQ(0x67, dst[6]);
232   EXPECT_EQ(0x89, dst[7]);
233 
234   ASSERT_EQ(true, ex.IsGood());
235   ASSERT_EQ(2 * kValidHexPairs, ex.GetFilePos());
236   ASSERT_EQ(false, ex.Empty());
237   ASSERT_EQ(4u, ex.GetBytesLeft());
238   ASSERT_EQ('x', *ex.Peek());
239 }
240 
TEST_F(StringExtractorTest,GetHexBytes_FullString)241 TEST_F(StringExtractorTest, GetHexBytes_FullString) {
242   llvm::StringRef kHexEncodedBytes = "abcdef0123456789";
243   const size_t kValidHexPairs = 8;
244   StringExtractor ex(kHexEncodedBytes);
245 
246   uint8_t dst[kValidHexPairs];
247   ASSERT_EQ(kValidHexPairs, ex.GetHexBytes(dst, 0xde));
248   EXPECT_EQ(0xab, dst[0]);
249   EXPECT_EQ(0xcd, dst[1]);
250   EXPECT_EQ(0xef, dst[2]);
251   EXPECT_EQ(0x01, dst[3]);
252   EXPECT_EQ(0x23, dst[4]);
253   EXPECT_EQ(0x45, dst[5]);
254   EXPECT_EQ(0x67, dst[6]);
255   EXPECT_EQ(0x89, dst[7]);
256 }
257 
TEST_F(StringExtractorTest,GetHexBytes_OddPair)258 TEST_F(StringExtractorTest, GetHexBytes_OddPair) {
259   llvm::StringRef kHexEncodedBytes = "abcdef012345678w";
260   const size_t kValidHexPairs = 7;
261   StringExtractor ex(kHexEncodedBytes);
262 
263   uint8_t dst[8];
264   ASSERT_EQ(kValidHexPairs, ex.GetHexBytes(dst, 0xde));
265   EXPECT_EQ(0xab, dst[0]);
266   EXPECT_EQ(0xcd, dst[1]);
267   EXPECT_EQ(0xef, dst[2]);
268   EXPECT_EQ(0x01, dst[3]);
269   EXPECT_EQ(0x23, dst[4]);
270   EXPECT_EQ(0x45, dst[5]);
271   EXPECT_EQ(0x67, dst[6]);
272 
273   // This one should be invalid
274   EXPECT_EQ(0xde, dst[7]);
275 }
276 
TEST_F(StringExtractorTest,GetHexBytes_OddPair2)277 TEST_F(StringExtractorTest, GetHexBytes_OddPair2) {
278   llvm::StringRef kHexEncodedBytes = "abcdef012345678";
279   const size_t kValidHexPairs = 7;
280   StringExtractor ex(kHexEncodedBytes);
281 
282   uint8_t dst[8];
283   ASSERT_EQ(kValidHexPairs, ex.GetHexBytes(dst, 0xde));
284   EXPECT_EQ(0xab, dst[0]);
285   EXPECT_EQ(0xcd, dst[1]);
286   EXPECT_EQ(0xef, dst[2]);
287   EXPECT_EQ(0x01, dst[3]);
288   EXPECT_EQ(0x23, dst[4]);
289   EXPECT_EQ(0x45, dst[5]);
290   EXPECT_EQ(0x67, dst[6]);
291 
292   EXPECT_EQ(0xde, dst[7]);
293 }
294 
TEST_F(StringExtractorTest,GetHexBytes_Underflow)295 TEST_F(StringExtractorTest, GetHexBytes_Underflow) {
296   llvm::StringRef kHexEncodedBytes = "abcdef0123456789xyzw";
297   const size_t kValidHexPairs = 8;
298   StringExtractor ex(kHexEncodedBytes);
299 
300   uint8_t dst[12];
301   ASSERT_EQ(kValidHexPairs, ex.GetHexBytes(dst, 0xde));
302   EXPECT_EQ(0xab, dst[0]);
303   EXPECT_EQ(0xcd, dst[1]);
304   EXPECT_EQ(0xef, dst[2]);
305   EXPECT_EQ(0x01, dst[3]);
306   EXPECT_EQ(0x23, dst[4]);
307   EXPECT_EQ(0x45, dst[5]);
308   EXPECT_EQ(0x67, dst[6]);
309   EXPECT_EQ(0x89, dst[7]);
310   // these bytes should be filled with fail_fill_value 0xde
311   EXPECT_EQ(0xde, dst[8]);
312   EXPECT_EQ(0xde, dst[9]);
313   EXPECT_EQ(0xde, dst[10]);
314   EXPECT_EQ(0xde, dst[11]);
315 
316   ASSERT_EQ(false, ex.IsGood());
317   ASSERT_EQ(UINT64_MAX, ex.GetFilePos());
318   ASSERT_EQ(false, ex.Empty());
319   ASSERT_EQ(0u, ex.GetBytesLeft());
320   ASSERT_EQ(nullptr, ex.Peek());
321 }
322 
TEST_F(StringExtractorTest,GetHexBytes_Partial)323 TEST_F(StringExtractorTest, GetHexBytes_Partial) {
324   llvm::StringRef kHexEncodedBytes = "abcdef0123456789xyzw";
325   const size_t kReadBytes = 4;
326   StringExtractor ex(kHexEncodedBytes);
327 
328   uint8_t dst[12];
329   memset(dst, 0xab, sizeof(dst));
330   ASSERT_EQ(
331       kReadBytes,
332       ex.GetHexBytes(llvm::MutableArrayRef<uint8_t>(dst, kReadBytes), 0xde));
333   EXPECT_EQ(0xab, dst[0]);
334   EXPECT_EQ(0xcd, dst[1]);
335   EXPECT_EQ(0xef, dst[2]);
336   EXPECT_EQ(0x01, dst[3]);
337   // these bytes should be unchanged
338   EXPECT_EQ(0xab, dst[4]);
339   EXPECT_EQ(0xab, dst[5]);
340   EXPECT_EQ(0xab, dst[6]);
341   EXPECT_EQ(0xab, dst[7]);
342   EXPECT_EQ(0xab, dst[8]);
343   EXPECT_EQ(0xab, dst[9]);
344   EXPECT_EQ(0xab, dst[10]);
345   EXPECT_EQ(0xab, dst[11]);
346 
347   ASSERT_EQ(true, ex.IsGood());
348   ASSERT_EQ(kReadBytes * 2, ex.GetFilePos());
349   ASSERT_EQ(false, ex.Empty());
350   ASSERT_EQ(12u, ex.GetBytesLeft());
351   ASSERT_EQ('2', *ex.Peek());
352 }
353 
TEST_F(StringExtractorTest,GetHexBytesAvail)354 TEST_F(StringExtractorTest, GetHexBytesAvail) {
355   llvm::StringRef kHexEncodedBytes = "abcdef0123456789xyzw";
356   const size_t kValidHexPairs = 8;
357   StringExtractor ex(kHexEncodedBytes);
358 
359   uint8_t dst[kValidHexPairs];
360   ASSERT_EQ(kValidHexPairs, ex.GetHexBytesAvail(dst));
361   EXPECT_EQ(0xab, dst[0]);
362   EXPECT_EQ(0xcd, dst[1]);
363   EXPECT_EQ(0xef, dst[2]);
364   EXPECT_EQ(0x01, dst[3]);
365   EXPECT_EQ(0x23, dst[4]);
366   EXPECT_EQ(0x45, dst[5]);
367   EXPECT_EQ(0x67, dst[6]);
368   EXPECT_EQ(0x89, dst[7]);
369 
370   ASSERT_EQ(true, ex.IsGood());
371   ASSERT_EQ(2 * kValidHexPairs, ex.GetFilePos());
372   ASSERT_EQ(false, ex.Empty());
373   ASSERT_EQ(4u, ex.GetBytesLeft());
374   ASSERT_EQ('x', *ex.Peek());
375 }
376 
TEST_F(StringExtractorTest,GetHexBytesAvail_FullString)377 TEST_F(StringExtractorTest, GetHexBytesAvail_FullString) {
378   llvm::StringRef kHexEncodedBytes = "abcdef0123456789";
379   const size_t kValidHexPairs = 8;
380   StringExtractor ex(kHexEncodedBytes);
381 
382   uint8_t dst[kValidHexPairs];
383   ASSERT_EQ(kValidHexPairs, ex.GetHexBytesAvail(dst));
384   EXPECT_EQ(0xab, dst[0]);
385   EXPECT_EQ(0xcd, dst[1]);
386   EXPECT_EQ(0xef, dst[2]);
387   EXPECT_EQ(0x01, dst[3]);
388   EXPECT_EQ(0x23, dst[4]);
389   EXPECT_EQ(0x45, dst[5]);
390   EXPECT_EQ(0x67, dst[6]);
391   EXPECT_EQ(0x89, dst[7]);
392 }
393 
TEST_F(StringExtractorTest,GetHexBytesAvail_OddPair)394 TEST_F(StringExtractorTest, GetHexBytesAvail_OddPair) {
395   llvm::StringRef kHexEncodedBytes = "abcdef012345678w";
396   const size_t kValidHexPairs = 7;
397   StringExtractor ex(kHexEncodedBytes);
398 
399   uint8_t dst[8];
400   ASSERT_EQ(kValidHexPairs, ex.GetHexBytesAvail(dst));
401   EXPECT_EQ(0xab, dst[0]);
402   EXPECT_EQ(0xcd, dst[1]);
403   EXPECT_EQ(0xef, dst[2]);
404   EXPECT_EQ(0x01, dst[3]);
405   EXPECT_EQ(0x23, dst[4]);
406   EXPECT_EQ(0x45, dst[5]);
407   EXPECT_EQ(0x67, dst[6]);
408 }
409 
TEST_F(StringExtractorTest,GetHexBytesAvail_OddPair2)410 TEST_F(StringExtractorTest, GetHexBytesAvail_OddPair2) {
411   llvm::StringRef kHexEncodedBytes = "abcdef012345678";
412   const size_t kValidHexPairs = 7;
413   StringExtractor ex(kHexEncodedBytes);
414 
415   uint8_t dst[8];
416   ASSERT_EQ(kValidHexPairs, ex.GetHexBytesAvail(dst));
417   EXPECT_EQ(0xab, dst[0]);
418   EXPECT_EQ(0xcd, dst[1]);
419   EXPECT_EQ(0xef, dst[2]);
420   EXPECT_EQ(0x01, dst[3]);
421   EXPECT_EQ(0x23, dst[4]);
422   EXPECT_EQ(0x45, dst[5]);
423   EXPECT_EQ(0x67, dst[6]);
424 }
425 
TEST_F(StringExtractorTest,GetHexBytesAvail_Underflow)426 TEST_F(StringExtractorTest, GetHexBytesAvail_Underflow) {
427   llvm::StringRef kHexEncodedBytes = "abcdef0123456789xyzw";
428   const size_t kValidHexPairs = 8;
429   StringExtractor ex(kHexEncodedBytes);
430 
431   uint8_t dst[12];
432   memset(dst, 0xef, sizeof(dst));
433   ASSERT_EQ(kValidHexPairs, ex.GetHexBytesAvail(dst));
434   EXPECT_EQ(0xab, dst[0]);
435   EXPECT_EQ(0xcd, dst[1]);
436   EXPECT_EQ(0xef, dst[2]);
437   EXPECT_EQ(0x01, dst[3]);
438   EXPECT_EQ(0x23, dst[4]);
439   EXPECT_EQ(0x45, dst[5]);
440   EXPECT_EQ(0x67, dst[6]);
441   EXPECT_EQ(0x89, dst[7]);
442   // these bytes should be unchanged
443   EXPECT_EQ(0xef, dst[8]);
444   EXPECT_EQ(0xef, dst[9]);
445   EXPECT_EQ(0xef, dst[10]);
446   EXPECT_EQ(0xef, dst[11]);
447 
448   ASSERT_EQ(true, ex.IsGood());
449   ASSERT_EQ(kValidHexPairs * 2, ex.GetFilePos());
450   ASSERT_EQ(false, ex.Empty());
451   ASSERT_EQ(4u, ex.GetBytesLeft());
452   ASSERT_EQ('x', *ex.Peek());
453 }
454 
TEST_F(StringExtractorTest,GetHexBytesAvail_Partial)455 TEST_F(StringExtractorTest, GetHexBytesAvail_Partial) {
456   llvm::StringRef kHexEncodedBytes = "abcdef0123456789xyzw";
457   const size_t kReadBytes = 4;
458   StringExtractor ex(kHexEncodedBytes);
459 
460   uint8_t dst[12];
461   memset(dst, 0xab, sizeof(dst));
462   ASSERT_EQ(kReadBytes, ex.GetHexBytesAvail(
463                             llvm::MutableArrayRef<uint8_t>(dst, kReadBytes)));
464   EXPECT_EQ(0xab, dst[0]);
465   EXPECT_EQ(0xcd, dst[1]);
466   EXPECT_EQ(0xef, dst[2]);
467   EXPECT_EQ(0x01, dst[3]);
468   // these bytes should be unchanged
469   EXPECT_EQ(0xab, dst[4]);
470   EXPECT_EQ(0xab, dst[5]);
471   EXPECT_EQ(0xab, dst[6]);
472   EXPECT_EQ(0xab, dst[7]);
473   EXPECT_EQ(0xab, dst[8]);
474   EXPECT_EQ(0xab, dst[9]);
475   EXPECT_EQ(0xab, dst[10]);
476   EXPECT_EQ(0xab, dst[11]);
477 
478   ASSERT_EQ(true, ex.IsGood());
479   ASSERT_EQ(kReadBytes * 2, ex.GetFilePos());
480   ASSERT_EQ(false, ex.Empty());
481   ASSERT_EQ(12u, ex.GetBytesLeft());
482   ASSERT_EQ('2', *ex.Peek());
483 }
484 
TEST_F(StringExtractorTest,GetNameColonValueSuccess)485 TEST_F(StringExtractorTest, GetNameColonValueSuccess) {
486   llvm::StringRef kNameColonPairs = "key1:value1;key2:value2;";
487   StringExtractor ex(kNameColonPairs);
488 
489   llvm::StringRef name;
490   llvm::StringRef value;
491   EXPECT_TRUE(ex.GetNameColonValue(name, value));
492   EXPECT_EQ("key1", name);
493   EXPECT_EQ("value1", value);
494   EXPECT_TRUE(ex.GetNameColonValue(name, value));
495   EXPECT_EQ("key2", name);
496   EXPECT_EQ("value2", value);
497   EXPECT_EQ(0u, ex.GetBytesLeft());
498 }
499 
TEST_F(StringExtractorTest,GetNameColonValueContainsColon)500 TEST_F(StringExtractorTest, GetNameColonValueContainsColon) {
501   llvm::StringRef kNameColonPairs = "key1:value1:value2;key2:value3;";
502   StringExtractor ex(kNameColonPairs);
503 
504   llvm::StringRef name;
505   llvm::StringRef value;
506   EXPECT_TRUE(ex.GetNameColonValue(name, value));
507   EXPECT_EQ("key1", name);
508   EXPECT_EQ("value1:value2", value);
509   EXPECT_TRUE(ex.GetNameColonValue(name, value));
510   EXPECT_EQ("key2", name);
511   EXPECT_EQ("value3", value);
512   EXPECT_EQ(0u, ex.GetBytesLeft());
513 }
514 
TEST_F(StringExtractorTest,GetNameColonValueNoSemicolon)515 TEST_F(StringExtractorTest, GetNameColonValueNoSemicolon) {
516   llvm::StringRef kNameColonPairs = "key1:value1";
517   StringExtractor ex(kNameColonPairs);
518 
519   llvm::StringRef name;
520   llvm::StringRef value;
521   EXPECT_FALSE(ex.GetNameColonValue(name, value));
522   EXPECT_EQ(0u, ex.GetBytesLeft());
523 }
524 
TEST_F(StringExtractorTest,GetNameColonValueNoColon)525 TEST_F(StringExtractorTest, GetNameColonValueNoColon) {
526   llvm::StringRef kNameColonPairs = "key1value1;";
527   StringExtractor ex(kNameColonPairs);
528 
529   llvm::StringRef name;
530   llvm::StringRef value;
531   EXPECT_FALSE(ex.GetNameColonValue(name, value));
532   EXPECT_EQ(0u, ex.GetBytesLeft());
533 }
534 
TEST_F(StringExtractorTest,GetU32LittleEndian)535 TEST_F(StringExtractorTest, GetU32LittleEndian) {
536   StringExtractor ex("");
537   EXPECT_EQ(0x0ull, ex.GetHexMaxU32(true, 0));
538 
539   ex.Reset("0");
540   EXPECT_EQ(0x0ull, ex.GetHexMaxU32(true, 1));
541 
542   ex.Reset("1");
543   EXPECT_EQ(0x1ull, ex.GetHexMaxU32(true, 0));
544 
545   ex.Reset("01");
546   EXPECT_EQ(0x1ull, ex.GetHexMaxU32(true, 0));
547 
548   ex.Reset("001");
549   EXPECT_EQ(0x100ull, ex.GetHexMaxU32(true, 0));
550 
551   ex.Reset("12");
552   EXPECT_EQ(0x12ull, ex.GetHexMaxU32(true, 0));
553 
554   ex.Reset("123");
555   EXPECT_EQ(0x312ull, ex.GetHexMaxU32(true, 0));
556 
557   ex.Reset("1203");
558   EXPECT_EQ(0x312ull, ex.GetHexMaxU32(true, 0));
559 
560   ex.Reset("1234");
561   EXPECT_EQ(0x3412ull, ex.GetHexMaxU32(true, 0));
562 
563   ex.Reset("12340");
564   EXPECT_EQ(0x3412ull, ex.GetHexMaxU32(true, 0));
565 
566   ex.Reset("123400");
567   EXPECT_EQ(0x3412ull, ex.GetHexMaxU32(true, 0));
568 
569   ex.Reset("12345670");
570   EXPECT_EQ(0x70563412ull, ex.GetHexMaxU32(true, 0));
571 
572   ex.Reset("123456701");
573   EXPECT_EQ(0ull, ex.GetHexMaxU32(true, 0));
574 }
575 
TEST_F(StringExtractorTest,GetU32BigEndian)576 TEST_F(StringExtractorTest, GetU32BigEndian) {
577   StringExtractor ex("");
578   EXPECT_EQ(0x0ull, ex.GetHexMaxU32(false, 0));
579 
580   ex.Reset("0");
581   EXPECT_EQ(0x0ull, ex.GetHexMaxU32(false, 1));
582 
583   ex.Reset("1");
584   EXPECT_EQ(0x1ull, ex.GetHexMaxU32(false, 0));
585 
586   ex.Reset("01");
587   EXPECT_EQ(0x1ull, ex.GetHexMaxU32(false, 0));
588 
589   ex.Reset("001");
590   EXPECT_EQ(0x1ull, ex.GetHexMaxU32(false, 0));
591 
592   ex.Reset("12");
593   EXPECT_EQ(0x12ull, ex.GetHexMaxU32(false, 0));
594 
595   ex.Reset("123");
596   EXPECT_EQ(0x123ull, ex.GetHexMaxU32(false, 0));
597 
598   ex.Reset("1203");
599   EXPECT_EQ(0x1203ull, ex.GetHexMaxU32(false, 0));
600 
601   ex.Reset("1234");
602   EXPECT_EQ(0x1234ull, ex.GetHexMaxU32(false, 0));
603 
604   ex.Reset("12340");
605   EXPECT_EQ(0x12340ull, ex.GetHexMaxU32(false, 0));
606 
607   ex.Reset("123400");
608   EXPECT_EQ(0x123400ull, ex.GetHexMaxU32(false, 0));
609 
610   ex.Reset("12345670");
611   EXPECT_EQ(0x12345670ull, ex.GetHexMaxU32(false, 0));
612 
613   ex.Reset("123456700");
614   EXPECT_EQ(0ull, ex.GetHexMaxU32(false, 0));
615 }
616 
TEST_F(StringExtractorTest,GetU64LittleEndian)617 TEST_F(StringExtractorTest, GetU64LittleEndian) {
618   StringExtractor ex("");
619   EXPECT_EQ(0x0ull, ex.GetHexMaxU64(true, 0));
620 
621   ex.Reset("0");
622   EXPECT_EQ(0x0ull, ex.GetHexMaxU64(true, 1));
623 
624   ex.Reset("1");
625   EXPECT_EQ(0x1ull, ex.GetHexMaxU64(true, 0));
626 
627   ex.Reset("01");
628   EXPECT_EQ(0x1ull, ex.GetHexMaxU64(true, 0));
629 
630   ex.Reset("001");
631   EXPECT_EQ(0x100ull, ex.GetHexMaxU64(true, 0));
632 
633   ex.Reset("12");
634   EXPECT_EQ(0x12ull, ex.GetHexMaxU64(true, 0));
635 
636   ex.Reset("123");
637   EXPECT_EQ(0x312ull, ex.GetHexMaxU64(true, 0));
638 
639   ex.Reset("1203");
640   EXPECT_EQ(0x312ull, ex.GetHexMaxU64(true, 0));
641 
642   ex.Reset("1234");
643   EXPECT_EQ(0x3412ull, ex.GetHexMaxU64(true, 0));
644 
645   ex.Reset("12340");
646   EXPECT_EQ(0x3412ull, ex.GetHexMaxU64(true, 0));
647 
648   ex.Reset("123400");
649   EXPECT_EQ(0x3412ull, ex.GetHexMaxU64(true, 0));
650 
651   ex.Reset("123456789ABCDEF0");
652   EXPECT_EQ(0xF0DEBC9A78563412ULL, ex.GetHexMaxU64(true, 0));
653 
654   ex.Reset("123456789ABCDEF01");
655   EXPECT_EQ(0ull, ex.GetHexMaxU64(true, 0));
656 }
657 
TEST_F(StringExtractorTest,GetU64BigEndian)658 TEST_F(StringExtractorTest, GetU64BigEndian) {
659   StringExtractor ex("");
660   EXPECT_EQ(0x0ull, ex.GetHexMaxU64(false, 0));
661 
662   ex.Reset("0");
663   EXPECT_EQ(0x0ull, ex.GetHexMaxU64(false, 1));
664 
665   ex.Reset("1");
666   EXPECT_EQ(0x1ull, ex.GetHexMaxU64(false, 0));
667 
668   ex.Reset("01");
669   EXPECT_EQ(0x1ull, ex.GetHexMaxU64(false, 0));
670 
671   ex.Reset("001");
672   EXPECT_EQ(0x1ull, ex.GetHexMaxU64(false, 0));
673 
674   ex.Reset("12");
675   EXPECT_EQ(0x12ull, ex.GetHexMaxU64(false, 0));
676 
677   ex.Reset("123");
678   EXPECT_EQ(0x123ull, ex.GetHexMaxU64(false, 0));
679 
680   ex.Reset("1203");
681   EXPECT_EQ(0x1203ull, ex.GetHexMaxU64(false, 0));
682 
683   ex.Reset("1234");
684   EXPECT_EQ(0x1234ull, ex.GetHexMaxU64(false, 0));
685 
686   ex.Reset("12340");
687   EXPECT_EQ(0x12340ull, ex.GetHexMaxU64(false, 0));
688 
689   ex.Reset("123400");
690   EXPECT_EQ(0x123400ull, ex.GetHexMaxU64(false, 0));
691 
692   ex.Reset("123456789ABCDEF0");
693   EXPECT_EQ(0x123456789ABCDEF0ULL, ex.GetHexMaxU64(false, 0));
694 
695   ex.Reset("123456789ABCDEF000");
696   EXPECT_EQ(0ull, ex.GetHexMaxU64(false, 0));
697 }
698