1 /* 2 * Copyright (C) 2008 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #ifndef LIBZIPARCHIVE_ZIPARCHIVE_PRIVATE_H_ 18 #define LIBZIPARCHIVE_ZIPARCHIVE_PRIVATE_H_ 19 20 #include <stdint.h> 21 #include <stdlib.h> 22 #include <unistd.h> 23 24 #include <memory> 25 #include <vector> 26 27 #include <utils/FileMap.h> 28 #include <ziparchive/zip_archive.h> 29 30 class MappedZipFile { 31 public: MappedZipFile(const int fd)32 explicit MappedZipFile(const int fd) : 33 has_fd_(true), 34 fd_(fd), 35 base_ptr_(nullptr), 36 data_length_(0), 37 read_pos_(0) {} 38 MappedZipFile(void * address,size_t length)39 explicit MappedZipFile(void* address, size_t length) : 40 has_fd_(false), 41 fd_(-1), 42 base_ptr_(address), 43 data_length_(static_cast<off64_t>(length)), 44 read_pos_(0) {} 45 HasFd()46 bool HasFd() const {return has_fd_;} 47 48 int GetFileDescriptor() const; 49 50 void* GetBasePtr() const; 51 52 off64_t GetFileLength() const; 53 54 bool SeekToOffset(off64_t offset); 55 56 bool ReadData(uint8_t* buffer, size_t read_amount); 57 58 bool ReadAtOffset(uint8_t* buf, size_t len, off64_t off); 59 60 private: 61 // If has_fd_ is true, fd is valid and we'll read contents of a zip archive 62 // from the file. Otherwise, we're opening the archive from a memory mapped 63 // file. In that case, base_ptr_ points to the start of the memory region and 64 // data_length_ defines the file length. 65 const bool has_fd_; 66 67 const int fd_; 68 69 void* const base_ptr_; 70 const off64_t data_length_; 71 // read_pos_ is the offset to the base_ptr_ where we read data from. 72 size_t read_pos_; 73 }; 74 75 class CentralDirectory { 76 public: CentralDirectory(void)77 CentralDirectory(void) : 78 base_ptr_(nullptr), 79 length_(0) {} 80 GetBasePtr()81 const uint8_t* GetBasePtr() const {return base_ptr_;} 82 GetMapLength()83 size_t GetMapLength() const {return length_;} 84 85 void Initialize(void* map_base_ptr, off64_t cd_start_offset, size_t cd_size); 86 87 private: 88 const uint8_t* base_ptr_; 89 size_t length_; 90 }; 91 92 struct ZipArchive { 93 // open Zip archive 94 mutable MappedZipFile mapped_zip; 95 const bool close_file; 96 97 // mapped central directory area 98 off64_t directory_offset; 99 CentralDirectory central_directory; 100 std::unique_ptr<android::FileMap> directory_map; 101 102 // number of entries in the Zip archive 103 uint16_t num_entries; 104 105 // We know how many entries are in the Zip archive, so we can have a 106 // fixed-size hash table. We define a load factor of 0.75 and over 107 // allocate so the maximum number entries can never be higher than 108 // ((4 * UINT16_MAX) / 3 + 1) which can safely fit into a uint32_t. 109 uint32_t hash_table_size; 110 ZipString* hash_table; 111 ZipArchiveZipArchive112 ZipArchive(const int fd, bool assume_ownership) : 113 mapped_zip(fd), 114 close_file(assume_ownership), 115 directory_offset(0), 116 central_directory(), 117 directory_map(new android::FileMap()), 118 num_entries(0), 119 hash_table_size(0), 120 hash_table(nullptr) {} 121 ZipArchiveZipArchive122 ZipArchive(void* address, size_t length) : 123 mapped_zip(address, length), 124 close_file(false), 125 directory_offset(0), 126 central_directory(), 127 directory_map(new android::FileMap()), 128 num_entries(0), 129 hash_table_size(0), 130 hash_table(nullptr) {} 131 ~ZipArchiveZipArchive132 ~ZipArchive() { 133 if (close_file && mapped_zip.GetFileDescriptor() >= 0) { 134 close(mapped_zip.GetFileDescriptor()); 135 } 136 137 free(hash_table); 138 } 139 140 bool InitializeCentralDirectory(const char* debug_file_name, off64_t cd_start_offset, 141 size_t cd_size); 142 143 }; 144 145 #endif // LIBZIPARCHIVE_ZIPARCHIVE_PRIVATE_H_ 146