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