| 461 | } |
| 462 | |
| 463 | static bool ReadName(const uint8_t* data, uint32_t size, uint32_t* offset, std::string* out) |
| 464 | { |
| 465 | uint32_t pos = *offset; |
| 466 | bool jumped = false; |
| 467 | uint32_t jump_count = 0; |
| 468 | out->clear(); |
| 469 | |
| 470 | while (true) |
| 471 | { |
| 472 | if (pos >= size) |
| 473 | return false; |
| 474 | |
| 475 | const uint8_t len = data[pos]; |
| 476 | if ((len & 0xC0) == 0xC0) |
| 477 | { |
| 478 | if (pos + 1 >= size) |
| 479 | return false; |
| 480 | |
| 481 | const uint16_t pointer = (uint16_t) (((len & 0x3F) << 8) | data[pos + 1]); |
| 482 | if (pointer >= size) |
| 483 | return false; |
| 484 | |
| 485 | if (!jumped) |
| 486 | { |
| 487 | *offset = pos + 2; |
| 488 | jumped = true; |
| 489 | } |
| 490 | |
| 491 | pos = pointer; |
| 492 | if (++jump_count > 16) |
| 493 | return false; |
| 494 | continue; |
| 495 | } |
| 496 | |
| 497 | ++pos; |
| 498 | if (len == 0) |
| 499 | { |
| 500 | if (!jumped) |
| 501 | *offset = pos; |
| 502 | return true; |
| 503 | } |
| 504 | |
| 505 | if (len > 63 || pos + len > size) |
| 506 | return false; |
| 507 | |
| 508 | if (!out->empty()) |
| 509 | out->append("."); |
| 510 | for (uint32_t i = 0; i < len; ++i) |
| 511 | { |
| 512 | const char c = (char) data[pos + i]; |
| 513 | if (c == '.' || c == '\\') |
| 514 | out->append("\\"); |
| 515 | out->push_back(c); |
| 516 | } |
| 517 | pos += len; |
| 518 | } |
| 519 | } |
| 520 |
no test coverage detected