1 | //===- llvm/unittest/Support/DataExtractorTest.cpp - DataExtractor tests --===// |
2 | // |
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | // See https://llvm.org/LICENSE.txt for license information. |
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | |
9 | #include "llvm/Support/DataExtractor.h" |
10 | |
11 | #include "llvm/ADT/StringExtras.h" |
12 | #include "llvm/Testing/Support/Error.h" |
13 | #include "gtest/gtest.h" |
14 | using namespace llvm; |
15 | |
16 | namespace { |
17 | |
18 | const char numberData[] = "\x80\x90\xFF\xFF\x80\x00\x00\x00" ; |
19 | const char leb128data[] = "\xA6\x49" ; |
20 | const char bigleb128data[] = "\xAA\xA9\xFF\xAA\xFF\xAA\xFF\x4A" ; |
21 | |
22 | TEST(DataExtractorTest, OffsetOverflow) { |
23 | DataExtractor DE(StringRef(numberData, sizeof(numberData)-1), false, 8); |
24 | EXPECT_FALSE(DE.isValidOffsetForDataOfSize(-2U, 5)); |
25 | } |
26 | |
27 | TEST(DataExtractorTest, UnsignedNumbers) { |
28 | DataExtractor DE(StringRef(numberData, sizeof(numberData)-1), false, 8); |
29 | uint64_t offset = 0; |
30 | |
31 | EXPECT_EQ(0x80U, DE.getU8(&offset)); |
32 | EXPECT_EQ(1U, offset); |
33 | offset = 0; |
34 | EXPECT_EQ(0x8090U, DE.getU16(&offset)); |
35 | EXPECT_EQ(2U, offset); |
36 | offset = 0; |
37 | EXPECT_EQ(0x8090FFFFU, DE.getU32(&offset)); |
38 | EXPECT_EQ(4U, offset); |
39 | offset = 0; |
40 | EXPECT_EQ(0x8090FFFF80000000ULL, DE.getU64(&offset)); |
41 | EXPECT_EQ(8U, offset); |
42 | offset = 0; |
43 | EXPECT_EQ(0x8090FFFF80000000ULL, DE.getAddress(&offset)); |
44 | EXPECT_EQ(8U, offset); |
45 | offset = 0; |
46 | |
47 | uint32_t data[2]; |
48 | EXPECT_EQ(data, DE.getU32(&offset, data, 2)); |
49 | EXPECT_EQ(0x8090FFFFU, data[0]); |
50 | EXPECT_EQ(0x80000000U, data[1]); |
51 | EXPECT_EQ(8U, offset); |
52 | offset = 0; |
53 | |
54 | // Now for little endian. |
55 | DE = DataExtractor(StringRef(numberData, sizeof(numberData)-1), true, 4); |
56 | EXPECT_EQ(0x9080U, DE.getU16(&offset)); |
57 | EXPECT_EQ(2U, offset); |
58 | offset = 0; |
59 | EXPECT_EQ(0xFFFF9080U, DE.getU32(&offset)); |
60 | EXPECT_EQ(4U, offset); |
61 | offset = 0; |
62 | EXPECT_EQ(0x80FFFF9080ULL, DE.getU64(&offset)); |
63 | EXPECT_EQ(8U, offset); |
64 | offset = 0; |
65 | EXPECT_EQ(0xFFFF9080U, DE.getAddress(&offset)); |
66 | EXPECT_EQ(4U, offset); |
67 | offset = 0; |
68 | |
69 | EXPECT_EQ(data, DE.getU32(&offset, data, 2)); |
70 | EXPECT_EQ(0xFFFF9080U, data[0]); |
71 | EXPECT_EQ(0x80U, data[1]); |
72 | EXPECT_EQ(8U, offset); |
73 | } |
74 | |
75 | TEST(DataExtractorTest, SignedNumbers) { |
76 | DataExtractor DE(StringRef(numberData, sizeof(numberData)-1), false, 8); |
77 | uint64_t offset = 0; |
78 | |
79 | EXPECT_EQ(-128, DE.getSigned(&offset, 1)); |
80 | EXPECT_EQ(1U, offset); |
81 | offset = 0; |
82 | EXPECT_EQ(-32624, DE.getSigned(&offset, 2)); |
83 | EXPECT_EQ(2U, offset); |
84 | offset = 0; |
85 | EXPECT_EQ(-2137980929, DE.getSigned(&offset, 4)); |
86 | EXPECT_EQ(4U, offset); |
87 | offset = 0; |
88 | EXPECT_EQ(-9182558167379214336LL, DE.getSigned(&offset, 8)); |
89 | EXPECT_EQ(8U, offset); |
90 | } |
91 | |
92 | TEST(DataExtractorTest, Strings) { |
93 | const char stringData[] = "hellohello\0hello" ; |
94 | DataExtractor DE(StringRef(stringData, sizeof(stringData)-1), false, 8); |
95 | uint64_t offset = 0; |
96 | |
97 | EXPECT_EQ(stringData, DE.getCStr(&offset)); |
98 | EXPECT_EQ(11U, offset); |
99 | EXPECT_EQ(nullptr, DE.getCStr(&offset)); |
100 | EXPECT_EQ(11U, offset); |
101 | |
102 | DataExtractor::Cursor C(0); |
103 | EXPECT_EQ(stringData, DE.getCStr(C)); |
104 | EXPECT_EQ(11U, C.tell()); |
105 | EXPECT_EQ(nullptr, DE.getCStr(C)); |
106 | EXPECT_EQ(11U, C.tell()); |
107 | EXPECT_THAT_ERROR( |
108 | C.takeError(), |
109 | FailedWithMessage("no null terminated string at offset 0xb" )); |
110 | } |
111 | |
112 | TEST(DataExtractorTest, LEB128) { |
113 | DataExtractor DE(StringRef(leb128data, sizeof(leb128data)-1), false, 8); |
114 | uint64_t offset = 0; |
115 | |
116 | EXPECT_EQ(9382ULL, DE.getULEB128(&offset)); |
117 | EXPECT_EQ(2U, offset); |
118 | offset = 0; |
119 | EXPECT_EQ(-7002LL, DE.getSLEB128(&offset)); |
120 | EXPECT_EQ(2U, offset); |
121 | |
122 | DataExtractor BDE(StringRef(bigleb128data, sizeof(bigleb128data)-1), false,8); |
123 | offset = 0; |
124 | EXPECT_EQ(42218325750568106ULL, BDE.getULEB128(&offset)); |
125 | EXPECT_EQ(8U, offset); |
126 | offset = 0; |
127 | EXPECT_EQ(-29839268287359830LL, BDE.getSLEB128(&offset)); |
128 | EXPECT_EQ(8U, offset); |
129 | } |
130 | |
131 | TEST(DataExtractorTest, LEB128_error) { |
132 | DataExtractor DE(StringRef("\x81" ), false, 8); |
133 | uint64_t Offset = 0; |
134 | EXPECT_EQ(0U, DE.getULEB128(&Offset)); |
135 | EXPECT_EQ(0U, Offset); |
136 | |
137 | Offset = 0; |
138 | EXPECT_EQ(0U, DE.getSLEB128(&Offset)); |
139 | EXPECT_EQ(0U, Offset); |
140 | |
141 | DataExtractor::Cursor C(0); |
142 | EXPECT_EQ(0U, DE.getULEB128(C)); |
143 | EXPECT_THAT_ERROR( |
144 | C.takeError(), |
145 | FailedWithMessage("unable to decode LEB128 at offset 0x00000000: " |
146 | "malformed uleb128, extends past end" )); |
147 | |
148 | C = DataExtractor::Cursor(0); |
149 | EXPECT_EQ(0U, DE.getSLEB128(C)); |
150 | EXPECT_THAT_ERROR( |
151 | C.takeError(), |
152 | FailedWithMessage("unable to decode LEB128 at offset 0x00000000: " |
153 | "malformed sleb128, extends past end" )); |
154 | |
155 | // Show non-zero offsets are reported appropriately. |
156 | C = DataExtractor::Cursor(1); |
157 | EXPECT_EQ(0U, DE.getULEB128(C)); |
158 | EXPECT_THAT_ERROR( |
159 | C.takeError(), |
160 | FailedWithMessage("unable to decode LEB128 at offset 0x00000001: " |
161 | "malformed uleb128, extends past end" )); |
162 | } |
163 | |
164 | TEST(DataExtractorTest, Cursor_tell) { |
165 | DataExtractor DE(StringRef("AB" ), false, 8); |
166 | DataExtractor::Cursor C(0); |
167 | // A successful read operation advances the cursor |
168 | EXPECT_EQ('A', DE.getU8(C)); |
169 | EXPECT_EQ(1u, C.tell()); |
170 | |
171 | // An unsuccessful one doesn't. |
172 | EXPECT_EQ(0u, DE.getU16(C)); |
173 | EXPECT_EQ(1u, C.tell()); |
174 | |
175 | // And neither do any subsequent operations. |
176 | EXPECT_EQ(0, DE.getU8(C)); |
177 | EXPECT_EQ(1u, C.tell()); |
178 | |
179 | consumeError(Err: C.takeError()); |
180 | } |
181 | |
182 | TEST(DataExtractorTest, Cursor_seek) { |
183 | DataExtractor::Cursor C(5); |
184 | |
185 | C.seek(NewOffSet: 3); |
186 | EXPECT_EQ(3u, C.tell()); |
187 | |
188 | C.seek(NewOffSet: 8); |
189 | EXPECT_EQ(8u, C.tell()); |
190 | |
191 | EXPECT_THAT_ERROR(C.takeError(), Succeeded()); |
192 | } |
193 | |
194 | TEST(DataExtractorTest, Cursor_takeError) { |
195 | DataExtractor DE(StringRef("AB" ), false, 8); |
196 | DataExtractor::Cursor C(0); |
197 | // Initially, the cursor is in the "success" state. |
198 | EXPECT_THAT_ERROR(C.takeError(), Succeeded()); |
199 | |
200 | // It remains "success" after a successful read. |
201 | EXPECT_EQ('A', DE.getU8(C)); |
202 | EXPECT_THAT_ERROR(C.takeError(), Succeeded()); |
203 | |
204 | // An unsuccessful read sets the error state. |
205 | EXPECT_EQ(0u, DE.getU32(C)); |
206 | EXPECT_THAT_ERROR(C.takeError(), Failed()); |
207 | |
208 | // Once set the error sticks until explicitly cleared. |
209 | EXPECT_EQ(0u, DE.getU32(C)); |
210 | EXPECT_EQ(0, DE.getU8(C)); |
211 | EXPECT_THAT_ERROR(C.takeError(), Failed()); |
212 | |
213 | // At which point reads can be succeed again. |
214 | EXPECT_EQ('B', DE.getU8(C)); |
215 | EXPECT_THAT_ERROR(C.takeError(), Succeeded()); |
216 | } |
217 | |
218 | TEST(DataExtractorTest, Cursor_chaining) { |
219 | DataExtractor DE(StringRef("ABCD" ), false, 8); |
220 | DataExtractor::Cursor C(0); |
221 | |
222 | // Multiple reads can be chained without trigerring any assertions. |
223 | EXPECT_EQ('A', DE.getU8(C)); |
224 | EXPECT_EQ('B', DE.getU8(C)); |
225 | EXPECT_EQ('C', DE.getU8(C)); |
226 | EXPECT_EQ('D', DE.getU8(C)); |
227 | // And the error checked at the end. |
228 | EXPECT_THAT_ERROR(C.takeError(), Succeeded()); |
229 | } |
230 | |
231 | #if defined(GTEST_HAS_DEATH_TEST) && defined(_DEBUG) && \ |
232 | LLVM_ENABLE_ABI_BREAKING_CHECKS |
233 | TEST(DataExtractorDeathTest, Cursor) { |
234 | DataExtractor DE(StringRef("AB" ), false, 8); |
235 | |
236 | // Even an unused cursor must be checked for errors: |
237 | EXPECT_DEATH(DataExtractor::Cursor(0), |
238 | "Success values must still be checked prior to being destroyed" ); |
239 | |
240 | { |
241 | auto C = std::make_unique<DataExtractor::Cursor>(args: 0); |
242 | EXPECT_EQ(0u, DE.getU32(*C)); |
243 | // It must also be checked after an unsuccessful operation. |
244 | // destruction. |
245 | EXPECT_DEATH(C.reset(), "unexpected end of data" ); |
246 | EXPECT_THAT_ERROR(C->takeError(), Failed()); |
247 | } |
248 | { |
249 | auto C = std::make_unique<DataExtractor::Cursor>(args: 0); |
250 | EXPECT_EQ('A', DE.getU8(*C)); |
251 | // Same goes for a successful one. |
252 | EXPECT_DEATH( |
253 | C.reset(), |
254 | "Success values must still be checked prior to being destroyed" ); |
255 | EXPECT_THAT_ERROR(C->takeError(), Succeeded()); |
256 | } |
257 | { |
258 | auto C = std::make_unique<DataExtractor::Cursor>(args: 0); |
259 | EXPECT_EQ('A', DE.getU8(*C)); |
260 | EXPECT_EQ(0u, DE.getU32(*C)); |
261 | // Even if a successful operation is followed by an unsuccessful one. |
262 | EXPECT_DEATH(C.reset(), "unexpected end of data" ); |
263 | EXPECT_THAT_ERROR(C->takeError(), Failed()); |
264 | } |
265 | { |
266 | auto C = std::make_unique<DataExtractor::Cursor>(args: 0); |
267 | EXPECT_EQ(0u, DE.getU32(*C)); |
268 | EXPECT_EQ(0, DE.getU8(*C)); |
269 | // Even if an unsuccessful operation is followed by one that would normally |
270 | // succeed. |
271 | EXPECT_DEATH(C.reset(), "unexpected end of data" ); |
272 | EXPECT_THAT_ERROR(C->takeError(), Failed()); |
273 | } |
274 | } |
275 | #endif |
276 | |
277 | TEST(DataExtractorTest, getU8_vector) { |
278 | DataExtractor DE(StringRef("AB" ), false, 8); |
279 | DataExtractor::Cursor C(0); |
280 | SmallVector<uint8_t, 2> S; |
281 | |
282 | DE.getU8(C, Dst&: S, Count: 4); |
283 | EXPECT_THAT_ERROR(C.takeError(), Failed()); |
284 | EXPECT_EQ("" , toStringRef(S)); |
285 | |
286 | DE.getU8(C, Dst&: S, Count: 2); |
287 | EXPECT_THAT_ERROR(C.takeError(), Succeeded()); |
288 | EXPECT_EQ("AB" , toStringRef(S)); |
289 | |
290 | C = DataExtractor::Cursor(0x47); |
291 | DE.getU8(C, Dst&: S, Count: 2); |
292 | EXPECT_THAT_ERROR( |
293 | C.takeError(), |
294 | FailedWithMessage("offset 0x47 is beyond the end of data at 0x2" )); |
295 | } |
296 | |
297 | TEST(DataExtractorTest, getU24) { |
298 | DataExtractor DE(StringRef("ABCD" ), false, 8); |
299 | DataExtractor::Cursor C(0); |
300 | |
301 | EXPECT_EQ(0x414243u, DE.getU24(C)); |
302 | EXPECT_EQ(0u, DE.getU24(C)); |
303 | EXPECT_EQ(3u, C.tell()); |
304 | EXPECT_THAT_ERROR(C.takeError(), Failed()); |
305 | } |
306 | |
307 | TEST(DataExtractorTest, skip) { |
308 | DataExtractor DE(StringRef("AB" ), false, 8); |
309 | DataExtractor::Cursor C(0); |
310 | |
311 | DE.skip(C, Length: 4); |
312 | EXPECT_THAT_ERROR(C.takeError(), Failed()); |
313 | EXPECT_EQ(0u, C.tell()); |
314 | |
315 | DE.skip(C, Length: 2); |
316 | EXPECT_THAT_ERROR(C.takeError(), Succeeded()); |
317 | EXPECT_EQ(2u, C.tell()); |
318 | } |
319 | |
320 | TEST(DataExtractorTest, eof) { |
321 | DataExtractor DE(StringRef("A" ), false, 8); |
322 | DataExtractor::Cursor C(0); |
323 | |
324 | EXPECT_FALSE(DE.eof(C)); |
325 | |
326 | EXPECT_EQ(0, DE.getU16(C)); |
327 | EXPECT_FALSE(DE.eof(C)); |
328 | EXPECT_THAT_ERROR(C.takeError(), Failed()); |
329 | |
330 | EXPECT_EQ('A', DE.getU8(C)); |
331 | EXPECT_TRUE(DE.eof(C)); |
332 | EXPECT_THAT_ERROR(C.takeError(), Succeeded()); |
333 | } |
334 | |
335 | TEST(DataExtractorTest, size) { |
336 | uint8_t Data[] = {'A', 'B', 'C', 'D'}; |
337 | DataExtractor DE1(StringRef(reinterpret_cast<char *>(Data), sizeof(Data)), |
338 | false, 8); |
339 | EXPECT_EQ(DE1.size(), sizeof(Data)); |
340 | DataExtractor DE2(ArrayRef<uint8_t>(Data), false, 8); |
341 | EXPECT_EQ(DE2.size(), sizeof(Data)); |
342 | } |
343 | |
344 | TEST(DataExtractorTest, FixedLengthString) { |
345 | const char Data[] = "hello\x00\x00\x00world \thola\x00" ; |
346 | DataExtractor DE(StringRef(Data, sizeof(Data)-1), false, 8); |
347 | uint64_t Offset = 0; |
348 | StringRef Str; |
349 | // Test extracting too many bytes doesn't modify Offset and returns |
350 | // std::nullopt. |
351 | Str = DE.getFixedLengthString(OffsetPtr: &Offset, Length: sizeof(Data)); |
352 | EXPECT_TRUE(Str.empty()); |
353 | EXPECT_EQ(Offset, 0u); |
354 | |
355 | // Test extracting a fixed width C string with trailing NULL characters. |
356 | Str = DE.getFixedLengthString(OffsetPtr: &Offset, Length: 8); |
357 | EXPECT_EQ(Offset, 8u); |
358 | EXPECT_EQ(Str.size(), 5u); |
359 | EXPECT_EQ(Str, "hello" ); |
360 | // Test extracting a fixed width C string with trailing space and tab |
361 | // characters. |
362 | Str = DE.getFixedLengthString(OffsetPtr: &Offset, Length: 8, TrimChars: " \t" ); |
363 | EXPECT_EQ(Offset, 16u); |
364 | EXPECT_EQ(Str.size(), 5u); |
365 | EXPECT_EQ(Str, "world" ); |
366 | // Now extract a normal C string. |
367 | Str = DE.getCStrRef(OffsetPtr: &Offset); |
368 | EXPECT_EQ(Str.size(), 4u); |
369 | EXPECT_EQ(Str, "hola" ); |
370 | } |
371 | |
372 | |
373 | TEST(DataExtractorTest, GetBytes) { |
374 | // Use data with an embedded NULL character for good measure. |
375 | const char Data[] = "\x01\x02\x00\x04" ; |
376 | StringRef Bytes(Data, sizeof(Data)-1); |
377 | DataExtractor DE(Bytes, false, 8); |
378 | uint64_t Offset = 0; |
379 | StringRef Str; |
380 | // Test extracting too many bytes doesn't modify Offset and returns |
381 | // std::nullopt. |
382 | Str = DE.getBytes(OffsetPtr: &Offset, Length: sizeof(Data)); |
383 | EXPECT_TRUE(Str.empty()); |
384 | EXPECT_EQ(Offset, 0u); |
385 | // Test extracting 4 bytes from the stream. |
386 | Str = DE.getBytes(OffsetPtr: &Offset, Length: 4); |
387 | EXPECT_EQ(Offset, 4u); |
388 | EXPECT_EQ(Str.size(), 4u); |
389 | EXPECT_EQ(Str, Bytes); |
390 | |
391 | DataExtractor::Cursor C(0); |
392 | EXPECT_EQ(StringRef("\x01\x02" ), DE.getBytes(C, 2)); |
393 | EXPECT_EQ(StringRef("\x00\x04" , 2), DE.getBytes(C, 2)); |
394 | EXPECT_EQ(StringRef(), DE.getBytes(C, 2)); |
395 | EXPECT_EQ(StringRef(), DE.getBytes(C, 2)); |
396 | EXPECT_EQ(4u, C.tell()); |
397 | EXPECT_THAT_ERROR(C.takeError(), Failed()); |
398 | } |
399 | |
400 | } |
401 | |