12#include "llvm/Support/Endian.h"
15using namespace llvm::support;
24 static constexpr char kSignature[] = {0x50, 0x4b, 0x05, 0x06};
25 char signature[
sizeof(kSignature)];
26 unaligned_uint16_t disks;
27 unaligned_uint16_t cd_start_disk;
28 unaligned_uint16_t cds_on_this_disk;
29 unaligned_uint16_t cd_records;
30 unaligned_uint32_t cd_size;
31 unaligned_uint32_t cd_offset;
32 unaligned_uint16_t comment_length;
36const size_t kEocdRecordFindLimit =
38 std::numeric_limits<
decltype(EocdRecord::comment_length)>::max();
42 static constexpr char kSignature[] = {0x50, 0x4b, 0x01, 0x02};
43 char signature[
sizeof(kSignature)];
44 unaligned_uint16_t version_made_by;
45 unaligned_uint16_t version_needed_to_extract;
46 unaligned_uint16_t general_purpose_bit_flag;
47 unaligned_uint16_t compression_method;
48 unaligned_uint16_t last_modification_time;
49 unaligned_uint16_t last_modification_date;
50 unaligned_uint32_t crc32;
51 unaligned_uint32_t compressed_size;
52 unaligned_uint32_t uncompressed_size;
53 unaligned_uint16_t file_name_length;
54 unaligned_uint16_t extra_field_length;
55 unaligned_uint16_t comment_length;
56 unaligned_uint16_t file_start_disk;
57 unaligned_uint16_t internal_file_attributes;
58 unaligned_uint32_t external_file_attributes;
59 unaligned_uint32_t local_file_header_offset;
67struct LocalFileHeader {
68 static constexpr char kSignature[] = {0x50, 0x4b, 0x03, 0x04};
69 char signature[
sizeof(kSignature)];
70 unaligned_uint16_t version_needed_to_extract;
71 unaligned_uint16_t general_purpose_bit_flag;
72 unaligned_uint16_t compression_method;
73 unaligned_uint16_t last_modification_time;
74 unaligned_uint16_t last_modification_date;
75 unaligned_uint32_t crc32;
76 unaligned_uint32_t compressed_size;
77 unaligned_uint32_t uncompressed_size;
78 unaligned_uint16_t file_name_length;
79 unaligned_uint16_t extra_field_length;
89 const uint8_t *zip_data_end = zip_data->GetBytes() + zip_data->GetByteSize();
90 const uint8_t *find_limit = zip_data_end - kEocdRecordFindLimit;
91 const uint8_t *p = zip_data_end -
sizeof(EocdRecord);
92 for (; p >= zip_data->GetBytes() && p >= find_limit; p--) {
93 auto eocd =
reinterpret_cast<const EocdRecord *
>(p);
94 if (::memcmp(eocd->signature, EocdRecord::kSignature,
95 sizeof(EocdRecord::kSignature)) == 0) {
97 if (eocd->cd_records *
sizeof(CdRecord) > eocd->cd_size ||
98 zip_data->GetBytes() + eocd->cd_offset + eocd->cd_size > p)
110 auto local_file_header =
reinterpret_cast<const LocalFileHeader *
>(
111 zip_data->GetBytes() + local_file_header_offset);
113 if (::memcmp(local_file_header->signature, LocalFileHeader::kSignature,
114 sizeof(LocalFileHeader::kSignature)) != 0)
117 auto file_data =
reinterpret_cast<const uint8_t *
>(local_file_header + 1) +
118 local_file_header->file_name_length +
119 local_file_header->extra_field_length;
121 if (local_file_header->compressed_size !=
122 local_file_header->uncompressed_size)
126 file_offset = file_data - zip_data->GetBytes();
127 file_size = local_file_header->uncompressed_size;
135 auto cd =
reinterpret_cast<const CdRecord *
>(zip_data->GetBytes() +
137 size_t cd_records = eocd->cd_records;
138 for (
size_t i = 0; i < cd_records; i++) {
140 if (::memcmp(cd->signature, CdRecord::kSignature,
141 sizeof(CdRecord::kSignature)) != 0)
145 auto file_name =
reinterpret_cast<const char *
>(cd + 1);
146 size_t file_name_length = cd->file_name_length;
147 if (file_name + file_name_length >=
reinterpret_cast<const char *
>(eocd) ||
148 file_name_length == 0)
152 if (file_path == llvm::StringRef(file_name, file_name_length)) {
154 return GetFile(zip_data, cd->local_file_header_offset, file_offset,
158 cd =
reinterpret_cast<const CdRecord *
>(
159 reinterpret_cast<const char *
>(cd) +
sizeof(CdRecord) +
160 cd->file_name_length + cd->extra_field_length + cd->comment_length);
162 if (
reinterpret_cast<const char *
>(cd) >=
163 reinterpret_cast<const char *
>(eocd))
175 const EocdRecord *eocd = FindEocdRecord(zip_data);
179 return FindFile(zip_data, eocd, file_path, file_offset, file_size);
static bool Find(lldb::DataBufferSP zip_data, const llvm::StringRef file_path, lldb::offset_t &file_offset, lldb::offset_t &file_size)
A class that represents a running process on the host machine.
std::shared_ptr< lldb_private::DataBuffer > DataBufferSP