| 662 | info->offset = cdOffset64; |
| 663 | info->size = cdSize64; |
| 664 | info->entries = totalEntries64; |
| 665 | info->zip64 = true; |
| 666 | } |
| 667 | |
| 668 | return true; |
| 669 | } |
| 670 | |
| 671 | std::vector<ZipEntryInfo> listEntriesInZip(const std::string &zipPath) |
| 672 | { |
| 673 | std::vector<ZipEntryInfo> ents; |
| 674 | |
| 675 | kt_stat64_t st{}; |
| 676 | if (kt_stat64(zipPath.c_str(), &st) < 0 || !S_ISREG(st.st_mode)) |
| 677 | return ents; |
| 678 | |
| 679 | if (!S_ISREG(st.st_mode) || static_cast<uint64_t>(st.st_size) < KT_MIN_EOCD_SIZE) |
| 680 | return ents; |
| 681 | |
| 682 | const uint64_t fileSize = static_cast<uint64_t>(st.st_size); |
| 683 | if (fileSize < KT_MIN_EOCD_SIZE) |
| 684 | return ents; |
| 685 | |
| 686 | KTScopedFD fd(KT_EINTR_RETRY(open(zipPath.c_str(), O_RDONLY))); |
| 687 | if (fd.get() < 0) |
| 688 | return ents; |
| 689 | |
| 690 | KTScopedMMap map(mmap(nullptr, fileSize, PROT_READ, MAP_PRIVATE, fd.get(), 0), fileSize); |
| 691 | if (!map.valid()) |
| 692 | return ents; |
| 693 | |
| 694 | const uint8_t *data = static_cast<const uint8_t *>(map.data()); |
| 695 | |
| 696 | CentralDirectoryInfo cd{}; |
| 697 | |
| 698 | if (!findCentralDirectory(data, fileSize, &cd)) |
| 699 | return ents; |
| 700 | |
| 701 | if (cd.size == 0 && cd.entries == 0) |
| 702 | return ents; |
| 703 | |
| 704 | if (cd.offset > fileSize) |
| 705 | return ents; |
| 706 | |
| 707 | if (cd.size > fileSize - cd.offset) |
| 708 | return ents; |
| 709 | |
| 710 | // |
| 711 | // Avoid pathological allocations. |
| 712 | // |
| 713 | if (cd.entries > static_cast<uint64_t>(SIZE_MAX)) |
| 714 | return ents; |
| 715 | |
| 716 | ents.reserve(static_cast<size_t>(cd.entries)); |
| 717 | |
| 718 | uint64_t cdEnd; |
no test coverage detected