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