xref: /llvm-project/lldb/unittests/Utility/StringExtractorTest.cpp (revision 28529f607c4767cd848b910e58d0131adc47fa01)
1 #include <limits.h>
2 #include "gtest/gtest.h"
3 
4 #include "lldb/Utility/StringExtractor.h"
5 
6 namespace
7 {
8     class StringExtractorTest: public ::testing::Test
9     {
10     };
11 }
12 
13 TEST_F (StringExtractorTest, InitEmpty)
14 {
15     const char kEmptyString[] = "";
16     StringExtractor ex (kEmptyString);
17 
18     ASSERT_EQ (true, ex.IsGood());
19     ASSERT_EQ (0u, ex.GetFilePos());
20     ASSERT_STREQ (kEmptyString, ex.GetStringRef().c_str());
21     ASSERT_EQ (true, ex.Empty());
22     ASSERT_EQ (0u, ex.GetBytesLeft());
23     ASSERT_EQ (nullptr, ex.Peek());
24 }
25 
26 TEST_F (StringExtractorTest, InitMisc)
27 {
28     const char kInitMiscString[] = "Hello, StringExtractor!";
29     StringExtractor ex (kInitMiscString);
30 
31     ASSERT_EQ (true, ex.IsGood());
32     ASSERT_EQ (0u, ex.GetFilePos());
33     ASSERT_STREQ (kInitMiscString, ex.GetStringRef().c_str());
34     ASSERT_EQ (false, ex.Empty());
35     ASSERT_EQ (sizeof(kInitMiscString)-1, ex.GetBytesLeft());
36     ASSERT_EQ (kInitMiscString[0], *ex.Peek());
37 }
38 
39 TEST_F (StringExtractorTest, DecodeHexU8_Underflow)
40 {
41     const char kEmptyString[] = "";
42     StringExtractor ex (kEmptyString);
43 
44     ASSERT_EQ (-1, ex.DecodeHexU8());
45     ASSERT_EQ (true, ex.IsGood());
46     ASSERT_EQ (0u, ex.GetFilePos());
47     ASSERT_EQ (true, ex.Empty());
48     ASSERT_EQ (0u, ex.GetBytesLeft());
49     ASSERT_EQ (nullptr, ex.Peek());
50 }
51 
52 TEST_F (StringExtractorTest, DecodeHexU8_Underflow2)
53 {
54     const char kEmptyString[] = "1";
55     StringExtractor ex (kEmptyString);
56 
57     ASSERT_EQ (-1, ex.DecodeHexU8());
58     ASSERT_EQ (true, ex.IsGood());
59     ASSERT_EQ (0u, ex.GetFilePos());
60     ASSERT_EQ (1u, ex.GetBytesLeft());
61     ASSERT_EQ ('1', *ex.Peek());
62 }
63 
64 TEST_F (StringExtractorTest, DecodeHexU8_InvalidHex)
65 {
66     const char kInvalidHex[] = "xa";
67     StringExtractor ex (kInvalidHex);
68 
69     ASSERT_EQ (-1, ex.DecodeHexU8());
70     ASSERT_EQ (true, ex.IsGood());
71     ASSERT_EQ (0u, ex.GetFilePos());
72     ASSERT_EQ (2u, ex.GetBytesLeft());
73     ASSERT_EQ ('x', *ex.Peek());
74 }
75 
76 TEST_F (StringExtractorTest, DecodeHexU8_InvalidHex2)
77 {
78     const char kInvalidHex[] = "ax";
79     StringExtractor ex (kInvalidHex);
80 
81     ASSERT_EQ (-1, ex.DecodeHexU8());
82     ASSERT_EQ (true, ex.IsGood());
83     ASSERT_EQ (0u, ex.GetFilePos());
84     ASSERT_EQ (2u, ex.GetBytesLeft());
85     ASSERT_EQ ('a', *ex.Peek());
86 }
87 
88 TEST_F (StringExtractorTest, DecodeHexU8_Exact)
89 {
90     const char kValidHexPair[] = "12";
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 (0u, ex.GetBytesLeft());
97     ASSERT_EQ (nullptr, ex.Peek());
98 }
99 
100 TEST_F (StringExtractorTest, DecodeHexU8_Extra)
101 {
102     const char kValidHexPair[] = "1234";
103     StringExtractor ex (kValidHexPair);
104 
105     ASSERT_EQ (0x12, ex.DecodeHexU8());
106     ASSERT_EQ (true, ex.IsGood());
107     ASSERT_EQ (2u, ex.GetFilePos());
108     ASSERT_EQ (2u, ex.GetBytesLeft());
109     ASSERT_EQ ('3', *ex.Peek());
110 }
111 
112 TEST_F (StringExtractorTest, GetHexU8_Underflow)
113 {
114     const char kEmptyString[] = "";
115     StringExtractor ex (kEmptyString);
116 
117     ASSERT_EQ (0xab, ex.GetHexU8(0xab));
118     ASSERT_EQ (false, ex.IsGood());
119     ASSERT_EQ (UINT64_MAX, ex.GetFilePos());
120     ASSERT_EQ (true, ex.Empty());
121     ASSERT_EQ (0u, ex.GetBytesLeft());
122     ASSERT_EQ (nullptr, ex.Peek());
123 }
124 
125 TEST_F (StringExtractorTest, GetHexU8_Underflow2)
126 {
127     const char kOneNibble[] = "1";
128     StringExtractor ex (kOneNibble);
129 
130     ASSERT_EQ (0xbc, ex.GetHexU8(0xbc));
131     ASSERT_EQ (false, ex.IsGood());
132     ASSERT_EQ (UINT64_MAX, ex.GetFilePos());
133     ASSERT_EQ (0u, ex.GetBytesLeft());
134     ASSERT_EQ (nullptr, ex.Peek());
135 }
136 
137 TEST_F (StringExtractorTest, GetHexU8_InvalidHex)
138 {
139     const char kInvalidHex[] = "xx";
140     StringExtractor ex (kInvalidHex);
141 
142     ASSERT_EQ (0xcd, ex.GetHexU8(0xcd));
143     ASSERT_EQ (false, ex.IsGood());
144     ASSERT_EQ (UINT64_MAX, ex.GetFilePos());
145     ASSERT_EQ (0u, ex.GetBytesLeft());
146     ASSERT_EQ (nullptr, ex.Peek());
147 }
148 
149 TEST_F (StringExtractorTest, GetHexU8_Exact)
150 {
151     const char kValidHexPair[] = "12";
152     StringExtractor ex (kValidHexPair);
153 
154     ASSERT_EQ (0x12, ex.GetHexU8(0x12));
155     ASSERT_EQ (true, ex.IsGood());
156     ASSERT_EQ (2u, ex.GetFilePos());
157     ASSERT_EQ (0u, ex.GetBytesLeft());
158     ASSERT_EQ (nullptr, ex.Peek());
159 }
160 
161 TEST_F (StringExtractorTest, GetHexU8_Extra)
162 {
163     const char kValidHexPair[] = "1234";
164     StringExtractor ex (kValidHexPair);
165 
166     ASSERT_EQ (0x12, ex.GetHexU8(0x12));
167     ASSERT_EQ (true, ex.IsGood());
168     ASSERT_EQ (2u, ex.GetFilePos());
169     ASSERT_EQ (2u, ex.GetBytesLeft());
170     ASSERT_EQ ('3', *ex.Peek());
171 }
172 
173 TEST_F (StringExtractorTest, GetHexU8_Underflow_NoEof)
174 {
175     const char kEmptyString[] = "";
176     StringExtractor ex (kEmptyString);
177     const bool kSetEofOnFail = false;
178 
179     ASSERT_EQ (0xab, ex.GetHexU8(0xab, kSetEofOnFail));
180     ASSERT_EQ (false, ex.IsGood()); // this result seems inconsistent with kSetEofOnFail == false
181     ASSERT_EQ (UINT64_MAX, ex.GetFilePos());
182     ASSERT_EQ (true, ex.Empty());
183     ASSERT_EQ (0u, ex.GetBytesLeft());
184     ASSERT_EQ (nullptr, ex.Peek());
185 }
186 
187 TEST_F (StringExtractorTest, GetHexU8_Underflow2_NoEof)
188 {
189     const char kOneNibble[] = "1";
190     StringExtractor ex (kOneNibble);
191     const bool kSetEofOnFail = false;
192 
193     ASSERT_EQ (0xbc, ex.GetHexU8(0xbc, kSetEofOnFail));
194     ASSERT_EQ (true, ex.IsGood());
195     ASSERT_EQ (0u, ex.GetFilePos());
196     ASSERT_EQ (1u, ex.GetBytesLeft());
197     ASSERT_EQ ('1', *ex.Peek());
198 }
199 
200 TEST_F (StringExtractorTest, GetHexU8_InvalidHex_NoEof)
201 {
202     const char kInvalidHex[] = "xx";
203     StringExtractor ex (kInvalidHex);
204     const bool kSetEofOnFail = false;
205 
206     ASSERT_EQ (0xcd, ex.GetHexU8(0xcd, kSetEofOnFail));
207     ASSERT_EQ (true, ex.IsGood());
208     ASSERT_EQ (0u, ex.GetFilePos());
209     ASSERT_EQ (2u, ex.GetBytesLeft());
210     ASSERT_EQ ('x', *ex.Peek());
211 }
212 
213 TEST_F (StringExtractorTest, GetHexU8_Exact_NoEof)
214 {
215     const char kValidHexPair[] = "12";
216     StringExtractor ex (kValidHexPair);
217     const bool kSetEofOnFail = false;
218 
219     ASSERT_EQ (0x12, ex.GetHexU8(0x12, kSetEofOnFail));
220     ASSERT_EQ (true, ex.IsGood());
221     ASSERT_EQ (2u, ex.GetFilePos());
222     ASSERT_EQ (0u, ex.GetBytesLeft());
223     ASSERT_EQ (nullptr, ex.Peek());
224 }
225 
226 TEST_F (StringExtractorTest, GetHexU8_Extra_NoEof)
227 {
228     const char kValidHexPair[] = "1234";
229     StringExtractor ex (kValidHexPair);
230     const bool kSetEofOnFail = false;
231 
232     ASSERT_EQ (0x12, ex.GetHexU8(0x12, kSetEofOnFail));
233     ASSERT_EQ (true, ex.IsGood());
234     ASSERT_EQ (2u, ex.GetFilePos());
235     ASSERT_EQ (2u, ex.GetBytesLeft());
236     ASSERT_EQ ('3', *ex.Peek());
237 }
238 
239 TEST_F (StringExtractorTest, GetHexBytes)
240 {
241     const char kHexEncodedBytes[] = "abcdef0123456789xyzw";
242     const size_t kValidHexPairs = 8;
243     StringExtractor ex(kHexEncodedBytes);
244 
245     uint8_t dst[kValidHexPairs];
246     ASSERT_EQ(kValidHexPairs, ex.GetHexBytes (dst, kValidHexPairs, 0xde));
247     EXPECT_EQ(0xab,dst[0]);
248     EXPECT_EQ(0xcd,dst[1]);
249     EXPECT_EQ(0xef,dst[2]);
250     EXPECT_EQ(0x01,dst[3]);
251     EXPECT_EQ(0x23,dst[4]);
252     EXPECT_EQ(0x45,dst[5]);
253     EXPECT_EQ(0x67,dst[6]);
254     EXPECT_EQ(0x89,dst[7]);
255 
256     ASSERT_EQ(true, ex.IsGood());
257     ASSERT_EQ(2*kValidHexPairs, ex.GetFilePos());
258     ASSERT_EQ(false, ex.Empty());
259     ASSERT_EQ(4u, ex.GetBytesLeft());
260     ASSERT_EQ('x', *ex.Peek());
261 }
262 
263 TEST_F (StringExtractorTest, GetHexBytes_Underflow)
264 {
265     const char kHexEncodedBytes[] = "abcdef0123456789xyzw";
266     const size_t kValidHexPairs = 8;
267     StringExtractor ex(kHexEncodedBytes);
268 
269     uint8_t dst[12];
270     ASSERT_EQ(kValidHexPairs, ex.GetHexBytes (dst, sizeof(dst), 0xde));
271     EXPECT_EQ(0xab,dst[0]);
272     EXPECT_EQ(0xcd,dst[1]);
273     EXPECT_EQ(0xef,dst[2]);
274     EXPECT_EQ(0x01,dst[3]);
275     EXPECT_EQ(0x23,dst[4]);
276     EXPECT_EQ(0x45,dst[5]);
277     EXPECT_EQ(0x67,dst[6]);
278     EXPECT_EQ(0x89,dst[7]);
279     // these bytes should be filled with fail_fill_value 0xde
280     EXPECT_EQ(0xde,dst[8]);
281     EXPECT_EQ(0xde,dst[9]);
282     EXPECT_EQ(0xde,dst[10]);
283     EXPECT_EQ(0xde,dst[11]);
284 
285     ASSERT_EQ(false, ex.IsGood());
286     ASSERT_EQ(UINT64_MAX, ex.GetFilePos());
287     ASSERT_EQ(false, ex.Empty());
288     ASSERT_EQ(0u, ex.GetBytesLeft());
289     ASSERT_EQ(0, ex.Peek());
290 }
291 
292 TEST_F (StringExtractorTest, GetHexBytes_Partial)
293 {
294     const char kHexEncodedBytes[] = "abcdef0123456789xyzw";
295     const size_t kReadBytes = 4;
296     StringExtractor ex(kHexEncodedBytes);
297 
298     uint8_t dst[12];
299     memset(dst, 0xab, sizeof(dst));
300     ASSERT_EQ(kReadBytes, ex.GetHexBytes (dst, kReadBytes, 0xde));
301     EXPECT_EQ(0xab,dst[0]);
302     EXPECT_EQ(0xcd,dst[1]);
303     EXPECT_EQ(0xef,dst[2]);
304     EXPECT_EQ(0x01,dst[3]);
305     // these bytes should be unchanged
306     EXPECT_EQ(0xab,dst[4]);
307     EXPECT_EQ(0xab,dst[5]);
308     EXPECT_EQ(0xab,dst[6]);
309     EXPECT_EQ(0xab,dst[7]);
310     EXPECT_EQ(0xab,dst[8]);
311     EXPECT_EQ(0xab,dst[9]);
312     EXPECT_EQ(0xab,dst[10]);
313     EXPECT_EQ(0xab,dst[11]);
314 
315     ASSERT_EQ(true, ex.IsGood());
316     ASSERT_EQ(kReadBytes*2, ex.GetFilePos());
317     ASSERT_EQ(false, ex.Empty());
318     ASSERT_EQ(12u, ex.GetBytesLeft());
319     ASSERT_EQ('2', *ex.Peek());
320 }
321 
322 TEST_F (StringExtractorTest, GetHexBytesAvail)
323 {
324     const char kHexEncodedBytes[] = "abcdef0123456789xyzw";
325     const size_t kValidHexPairs = 8;
326     StringExtractor ex(kHexEncodedBytes);
327 
328     uint8_t dst[kValidHexPairs];
329     ASSERT_EQ(kValidHexPairs, ex.GetHexBytesAvail (dst, kValidHexPairs));
330     EXPECT_EQ(0xab,dst[0]);
331     EXPECT_EQ(0xcd,dst[1]);
332     EXPECT_EQ(0xef,dst[2]);
333     EXPECT_EQ(0x01,dst[3]);
334     EXPECT_EQ(0x23,dst[4]);
335     EXPECT_EQ(0x45,dst[5]);
336     EXPECT_EQ(0x67,dst[6]);
337     EXPECT_EQ(0x89,dst[7]);
338 
339     ASSERT_EQ(true, ex.IsGood());
340     ASSERT_EQ(2*kValidHexPairs, ex.GetFilePos());
341     ASSERT_EQ(false, ex.Empty());
342     ASSERT_EQ(4u, ex.GetBytesLeft());
343     ASSERT_EQ('x', *ex.Peek());
344 }
345 
346 TEST_F (StringExtractorTest, GetHexBytesAvail_Underflow)
347 {
348     const char kHexEncodedBytes[] = "abcdef0123456789xyzw";
349     const size_t kValidHexPairs = 8;
350     StringExtractor ex(kHexEncodedBytes);
351 
352     uint8_t dst[12];
353     memset(dst, 0xef, sizeof(dst));
354     ASSERT_EQ(kValidHexPairs, ex.GetHexBytesAvail (dst, sizeof(dst)));
355     EXPECT_EQ(0xab,dst[0]);
356     EXPECT_EQ(0xcd,dst[1]);
357     EXPECT_EQ(0xef,dst[2]);
358     EXPECT_EQ(0x01,dst[3]);
359     EXPECT_EQ(0x23,dst[4]);
360     EXPECT_EQ(0x45,dst[5]);
361     EXPECT_EQ(0x67,dst[6]);
362     EXPECT_EQ(0x89,dst[7]);
363     // these bytes should be unchanged
364     EXPECT_EQ(0xef,dst[8]);
365     EXPECT_EQ(0xef,dst[9]);
366     EXPECT_EQ(0xef,dst[10]);
367     EXPECT_EQ(0xef,dst[11]);
368 
369     ASSERT_EQ(true, ex.IsGood());
370     ASSERT_EQ(kValidHexPairs*2, ex.GetFilePos());
371     ASSERT_EQ(false, ex.Empty());
372     ASSERT_EQ(4u, ex.GetBytesLeft());
373     ASSERT_EQ('x', *ex.Peek());
374 }
375 
376 TEST_F (StringExtractorTest, GetHexBytesAvail_Partial)
377 {
378     const char kHexEncodedBytes[] = "abcdef0123456789xyzw";
379     const size_t kReadBytes = 4;
380     StringExtractor ex(kHexEncodedBytes);
381 
382     uint8_t dst[12];
383     memset(dst, 0xab, sizeof(dst));
384     ASSERT_EQ(kReadBytes, ex.GetHexBytesAvail (dst, kReadBytes));
385     EXPECT_EQ(0xab,dst[0]);
386     EXPECT_EQ(0xcd,dst[1]);
387     EXPECT_EQ(0xef,dst[2]);
388     EXPECT_EQ(0x01,dst[3]);
389     // these bytes should be unchanged
390     EXPECT_EQ(0xab,dst[4]);
391     EXPECT_EQ(0xab,dst[5]);
392     EXPECT_EQ(0xab,dst[6]);
393     EXPECT_EQ(0xab,dst[7]);
394     EXPECT_EQ(0xab,dst[8]);
395     EXPECT_EQ(0xab,dst[9]);
396     EXPECT_EQ(0xab,dst[10]);
397     EXPECT_EQ(0xab,dst[11]);
398 
399     ASSERT_EQ(true, ex.IsGood());
400     ASSERT_EQ(kReadBytes*2, ex.GetFilePos());
401     ASSERT_EQ(false, ex.Empty());
402     ASSERT_EQ(12u, ex.GetBytesLeft());
403     ASSERT_EQ('2', *ex.Peek());
404 }
405 
406 
407