1*adcb0a62SAndroid Build Coastguard Worker /* 2*adcb0a62SAndroid Build Coastguard Worker * Copyright (C) 2013 The Android Open Source Project 3*adcb0a62SAndroid Build Coastguard Worker * 4*adcb0a62SAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License"); 5*adcb0a62SAndroid Build Coastguard Worker * you may not use this file except in compliance with the License. 6*adcb0a62SAndroid Build Coastguard Worker * You may obtain a copy of the License at 7*adcb0a62SAndroid Build Coastguard Worker * 8*adcb0a62SAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0 9*adcb0a62SAndroid Build Coastguard Worker * 10*adcb0a62SAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software 11*adcb0a62SAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS, 12*adcb0a62SAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13*adcb0a62SAndroid Build Coastguard Worker * See the License for the specific language governing permissions and 14*adcb0a62SAndroid Build Coastguard Worker * limitations under the License. 15*adcb0a62SAndroid Build Coastguard Worker */ 16*adcb0a62SAndroid Build Coastguard Worker 17*adcb0a62SAndroid Build Coastguard Worker #pragma once 18*adcb0a62SAndroid Build Coastguard Worker 19*adcb0a62SAndroid Build Coastguard Worker /* 20*adcb0a62SAndroid Build Coastguard Worker * Read-only access to Zip archives, with minimal heap allocation. 21*adcb0a62SAndroid Build Coastguard Worker */ 22*adcb0a62SAndroid Build Coastguard Worker 23*adcb0a62SAndroid Build Coastguard Worker #include <stdint.h> 24*adcb0a62SAndroid Build Coastguard Worker #include <string.h> 25*adcb0a62SAndroid Build Coastguard Worker #include <sys/cdefs.h> 26*adcb0a62SAndroid Build Coastguard Worker #include <sys/types.h> 27*adcb0a62SAndroid Build Coastguard Worker 28*adcb0a62SAndroid Build Coastguard Worker #include <functional> 29*adcb0a62SAndroid Build Coastguard Worker #include <string> 30*adcb0a62SAndroid Build Coastguard Worker #include <string_view> 31*adcb0a62SAndroid Build Coastguard Worker #include <utility> 32*adcb0a62SAndroid Build Coastguard Worker 33*adcb0a62SAndroid Build Coastguard Worker #include "android-base/macros.h" 34*adcb0a62SAndroid Build Coastguard Worker #include "android-base/off64_t.h" 35*adcb0a62SAndroid Build Coastguard Worker 36*adcb0a62SAndroid Build Coastguard Worker /* Zip compression methods we support */ 37*adcb0a62SAndroid Build Coastguard Worker enum { 38*adcb0a62SAndroid Build Coastguard Worker kCompressStored = 0, // no compression 39*adcb0a62SAndroid Build Coastguard Worker kCompressDeflated = 8, // standard deflate 40*adcb0a62SAndroid Build Coastguard Worker }; 41*adcb0a62SAndroid Build Coastguard Worker 42*adcb0a62SAndroid Build Coastguard Worker // This struct holds the common information of a zip entry other than the 43*adcb0a62SAndroid Build Coastguard Worker // the entry size. The compressed and uncompressed length will be handled 44*adcb0a62SAndroid Build Coastguard Worker // separately in the derived class. 45*adcb0a62SAndroid Build Coastguard Worker struct ZipEntryCommon { 46*adcb0a62SAndroid Build Coastguard Worker // Compression method. One of kCompressStored or kCompressDeflated. 47*adcb0a62SAndroid Build Coastguard Worker // See also `gpbf` for deflate subtypes. 48*adcb0a62SAndroid Build Coastguard Worker uint16_t method; 49*adcb0a62SAndroid Build Coastguard Worker 50*adcb0a62SAndroid Build Coastguard Worker // Modification time. The zipfile format specifies 51*adcb0a62SAndroid Build Coastguard Worker // that the first two little endian bytes contain the time 52*adcb0a62SAndroid Build Coastguard Worker // and the last two little endian bytes contain the date. 53*adcb0a62SAndroid Build Coastguard Worker // See `GetModificationTime`. Use signed integer to avoid the 54*adcb0a62SAndroid Build Coastguard Worker // sub-overflow. 55*adcb0a62SAndroid Build Coastguard Worker // TODO: should be overridden by extra time field, if present. 56*adcb0a62SAndroid Build Coastguard Worker int32_t mod_time; 57*adcb0a62SAndroid Build Coastguard Worker 58*adcb0a62SAndroid Build Coastguard Worker // Returns `mod_time` as a broken-down struct tm. 59*adcb0a62SAndroid Build Coastguard Worker struct tm GetModificationTime() const; 60*adcb0a62SAndroid Build Coastguard Worker 61*adcb0a62SAndroid Build Coastguard Worker // Suggested Unix mode for this entry, from the zip archive if created on 62*adcb0a62SAndroid Build Coastguard Worker // Unix, or a default otherwise. See also `external_file_attributes`. 63*adcb0a62SAndroid Build Coastguard Worker mode_t unix_mode; 64*adcb0a62SAndroid Build Coastguard Worker 65*adcb0a62SAndroid Build Coastguard Worker // 1 if this entry contains a data descriptor segment, 0 66*adcb0a62SAndroid Build Coastguard Worker // otherwise. 67*adcb0a62SAndroid Build Coastguard Worker uint8_t has_data_descriptor; 68*adcb0a62SAndroid Build Coastguard Worker 69*adcb0a62SAndroid Build Coastguard Worker // Crc32 value of this ZipEntry. This information might 70*adcb0a62SAndroid Build Coastguard Worker // either be stored in the local file header or in a special 71*adcb0a62SAndroid Build Coastguard Worker // Data descriptor footer at the end of the file entry. 72*adcb0a62SAndroid Build Coastguard Worker uint32_t crc32; 73*adcb0a62SAndroid Build Coastguard Worker 74*adcb0a62SAndroid Build Coastguard Worker // If the value of uncompressed length and compressed length are stored in 75*adcb0a62SAndroid Build Coastguard Worker // the zip64 extended info of the extra field. 76*adcb0a62SAndroid Build Coastguard Worker bool zip64_format_size{false}; 77*adcb0a62SAndroid Build Coastguard Worker 78*adcb0a62SAndroid Build Coastguard Worker // The offset to the start of data for this ZipEntry. 79*adcb0a62SAndroid Build Coastguard Worker off64_t offset; 80*adcb0a62SAndroid Build Coastguard Worker 81*adcb0a62SAndroid Build Coastguard Worker // The version of zip and the host file system this came from (for zipinfo). 82*adcb0a62SAndroid Build Coastguard Worker uint16_t version_made_by; 83*adcb0a62SAndroid Build Coastguard Worker 84*adcb0a62SAndroid Build Coastguard Worker // The raw attributes, whose interpretation depends on the host 85*adcb0a62SAndroid Build Coastguard Worker // file system in `version_made_by` (for zipinfo). See also `unix_mode`. 86*adcb0a62SAndroid Build Coastguard Worker uint32_t external_file_attributes; 87*adcb0a62SAndroid Build Coastguard Worker 88*adcb0a62SAndroid Build Coastguard Worker // Specifics about the deflation (for zipinfo). 89*adcb0a62SAndroid Build Coastguard Worker uint16_t gpbf; 90*adcb0a62SAndroid Build Coastguard Worker // Whether this entry is believed to be text or binary (for zipinfo). 91*adcb0a62SAndroid Build Coastguard Worker bool is_text; 92*adcb0a62SAndroid Build Coastguard Worker 93*adcb0a62SAndroid Build Coastguard Worker // extra field size 94*adcb0a62SAndroid Build Coastguard Worker uint16_t extra_field_size; 95*adcb0a62SAndroid Build Coastguard Worker }; 96*adcb0a62SAndroid Build Coastguard Worker 97*adcb0a62SAndroid Build Coastguard Worker struct ZipEntry64; 98*adcb0a62SAndroid Build Coastguard Worker // Many users of the library assume the entry size is capped at UINT32_MAX. So we keep 99*adcb0a62SAndroid Build Coastguard Worker // the interface for the old ZipEntry here; and we could switch them over to the new 100*adcb0a62SAndroid Build Coastguard Worker // ZipEntry64 later. 101*adcb0a62SAndroid Build Coastguard Worker struct ZipEntry : public ZipEntryCommon { 102*adcb0a62SAndroid Build Coastguard Worker // Compressed length of this ZipEntry. The maximum value is UINT32_MAX. 103*adcb0a62SAndroid Build Coastguard Worker // Might be present either in the local file header or in the data 104*adcb0a62SAndroid Build Coastguard Worker // descriptor footer. 105*adcb0a62SAndroid Build Coastguard Worker uint32_t compressed_length{0}; 106*adcb0a62SAndroid Build Coastguard Worker 107*adcb0a62SAndroid Build Coastguard Worker // Uncompressed length of this ZipEntry. The maximum value is UINT32_MAX. 108*adcb0a62SAndroid Build Coastguard Worker // Might be present either in the local file header or in the data 109*adcb0a62SAndroid Build Coastguard Worker // descriptor footer. 110*adcb0a62SAndroid Build Coastguard Worker uint32_t uncompressed_length{0}; 111*adcb0a62SAndroid Build Coastguard Worker 112*adcb0a62SAndroid Build Coastguard Worker // Copies the contents of a ZipEntry64 object to a 32 bits ZipEntry. Returns 0 if the 113*adcb0a62SAndroid Build Coastguard Worker // size of the entry fits into uint32_t, returns a negative error code 114*adcb0a62SAndroid Build Coastguard Worker // (kUnsupportedEntrySize) otherwise. 115*adcb0a62SAndroid Build Coastguard Worker static int32_t CopyFromZipEntry64(ZipEntry* dst, const ZipEntry64* src); 116*adcb0a62SAndroid Build Coastguard Worker 117*adcb0a62SAndroid Build Coastguard Worker private: 118*adcb0a62SAndroid Build Coastguard Worker ZipEntry& operator=(const ZipEntryCommon& other) { 119*adcb0a62SAndroid Build Coastguard Worker ZipEntryCommon::operator=(other); 120*adcb0a62SAndroid Build Coastguard Worker return *this; 121*adcb0a62SAndroid Build Coastguard Worker } 122*adcb0a62SAndroid Build Coastguard Worker }; 123*adcb0a62SAndroid Build Coastguard Worker 124*adcb0a62SAndroid Build Coastguard Worker // Represents information about a zip entry in a zip file. 125*adcb0a62SAndroid Build Coastguard Worker struct ZipEntry64 : public ZipEntryCommon { 126*adcb0a62SAndroid Build Coastguard Worker // Compressed length of this ZipEntry. The maximum value is UINT64_MAX. 127*adcb0a62SAndroid Build Coastguard Worker // Might be present either in the local file header, the zip64 extended field, 128*adcb0a62SAndroid Build Coastguard Worker // or in the data descriptor footer. 129*adcb0a62SAndroid Build Coastguard Worker uint64_t compressed_length{0}; 130*adcb0a62SAndroid Build Coastguard Worker 131*adcb0a62SAndroid Build Coastguard Worker // Uncompressed length of this ZipEntry. The maximum value is UINT64_MAX. 132*adcb0a62SAndroid Build Coastguard Worker // Might be present either in the local file header, the zip64 extended field, 133*adcb0a62SAndroid Build Coastguard Worker // or in the data descriptor footer. 134*adcb0a62SAndroid Build Coastguard Worker uint64_t uncompressed_length{0}; 135*adcb0a62SAndroid Build Coastguard Worker 136*adcb0a62SAndroid Build Coastguard Worker explicit ZipEntry64() = default; ZipEntry64ZipEntry64137*adcb0a62SAndroid Build Coastguard Worker explicit ZipEntry64(const ZipEntry& zip_entry) : ZipEntryCommon(zip_entry) { 138*adcb0a62SAndroid Build Coastguard Worker compressed_length = zip_entry.compressed_length; 139*adcb0a62SAndroid Build Coastguard Worker uncompressed_length = zip_entry.uncompressed_length; 140*adcb0a62SAndroid Build Coastguard Worker } 141*adcb0a62SAndroid Build Coastguard Worker }; 142*adcb0a62SAndroid Build Coastguard Worker 143*adcb0a62SAndroid Build Coastguard Worker struct ZipArchive; 144*adcb0a62SAndroid Build Coastguard Worker typedef ZipArchive* ZipArchiveHandle; 145*adcb0a62SAndroid Build Coastguard Worker 146*adcb0a62SAndroid Build Coastguard Worker /* 147*adcb0a62SAndroid Build Coastguard Worker * Open a Zip archive, and sets handle to the value of the opaque 148*adcb0a62SAndroid Build Coastguard Worker * handle for the file. This handle must be released by calling 149*adcb0a62SAndroid Build Coastguard Worker * CloseArchive with this handle. 150*adcb0a62SAndroid Build Coastguard Worker * 151*adcb0a62SAndroid Build Coastguard Worker * Returns 0 on success, and negative values on failure. 152*adcb0a62SAndroid Build Coastguard Worker */ 153*adcb0a62SAndroid Build Coastguard Worker int32_t OpenArchive(const char* fileName, ZipArchiveHandle* handle); 154*adcb0a62SAndroid Build Coastguard Worker 155*adcb0a62SAndroid Build Coastguard Worker /* 156*adcb0a62SAndroid Build Coastguard Worker * Like OpenArchive, but takes a file descriptor open for reading 157*adcb0a62SAndroid Build Coastguard Worker * at the start of the file. The descriptor must be mappable (this does 158*adcb0a62SAndroid Build Coastguard Worker * not allow access to a stream). 159*adcb0a62SAndroid Build Coastguard Worker * 160*adcb0a62SAndroid Build Coastguard Worker * Sets handle to the value of the opaque handle for this file descriptor. 161*adcb0a62SAndroid Build Coastguard Worker * This handle must be released by calling CloseArchive with this handle. 162*adcb0a62SAndroid Build Coastguard Worker * 163*adcb0a62SAndroid Build Coastguard Worker * If assume_ownership parameter is 'true' calling CloseArchive will close 164*adcb0a62SAndroid Build Coastguard Worker * the file. 165*adcb0a62SAndroid Build Coastguard Worker * 166*adcb0a62SAndroid Build Coastguard Worker * This function maps and scans the central directory and builds a table 167*adcb0a62SAndroid Build Coastguard Worker * of entries for future lookups. 168*adcb0a62SAndroid Build Coastguard Worker * 169*adcb0a62SAndroid Build Coastguard Worker * "debugFileName" will appear in error messages, but is not otherwise used. 170*adcb0a62SAndroid Build Coastguard Worker * 171*adcb0a62SAndroid Build Coastguard Worker * Returns 0 on success, and negative values on failure. 172*adcb0a62SAndroid Build Coastguard Worker */ 173*adcb0a62SAndroid Build Coastguard Worker int32_t OpenArchiveFd(const int fd, const char* debugFileName, ZipArchiveHandle* handle, 174*adcb0a62SAndroid Build Coastguard Worker bool assume_ownership = true); 175*adcb0a62SAndroid Build Coastguard Worker 176*adcb0a62SAndroid Build Coastguard Worker int32_t OpenArchiveFdRange(const int fd, const char* debugFileName, ZipArchiveHandle* handle, 177*adcb0a62SAndroid Build Coastguard Worker off64_t length, off64_t offset, bool assume_ownership = true); 178*adcb0a62SAndroid Build Coastguard Worker 179*adcb0a62SAndroid Build Coastguard Worker int32_t OpenArchiveFromMemory(const void* address, size_t length, const char* debugFileName, 180*adcb0a62SAndroid Build Coastguard Worker ZipArchiveHandle* handle); 181*adcb0a62SAndroid Build Coastguard Worker /* 182*adcb0a62SAndroid Build Coastguard Worker * Close archive, releasing resources associated with it. This will 183*adcb0a62SAndroid Build Coastguard Worker * unmap the central directory of the zipfile and free all internal 184*adcb0a62SAndroid Build Coastguard Worker * data structures associated with the file. It is an error to use 185*adcb0a62SAndroid Build Coastguard Worker * this handle for any further operations without an intervening 186*adcb0a62SAndroid Build Coastguard Worker * call to one of the OpenArchive variants. 187*adcb0a62SAndroid Build Coastguard Worker */ 188*adcb0a62SAndroid Build Coastguard Worker void CloseArchive(ZipArchiveHandle archive); 189*adcb0a62SAndroid Build Coastguard Worker 190*adcb0a62SAndroid Build Coastguard Worker /** See GetArchiveInfo(). */ 191*adcb0a62SAndroid Build Coastguard Worker struct ZipArchiveInfo { 192*adcb0a62SAndroid Build Coastguard Worker /** The size in bytes of the archive itself. Used by zipinfo. */ 193*adcb0a62SAndroid Build Coastguard Worker off64_t archive_size; 194*adcb0a62SAndroid Build Coastguard Worker /** The number of entries in the archive. */ 195*adcb0a62SAndroid Build Coastguard Worker uint64_t entry_count; 196*adcb0a62SAndroid Build Coastguard Worker }; 197*adcb0a62SAndroid Build Coastguard Worker 198*adcb0a62SAndroid Build Coastguard Worker /** 199*adcb0a62SAndroid Build Coastguard Worker * Returns information about the given archive. 200*adcb0a62SAndroid Build Coastguard Worker */ 201*adcb0a62SAndroid Build Coastguard Worker ZipArchiveInfo GetArchiveInfo(ZipArchiveHandle archive); 202*adcb0a62SAndroid Build Coastguard Worker 203*adcb0a62SAndroid Build Coastguard Worker /* 204*adcb0a62SAndroid Build Coastguard Worker * Find an entry in the Zip archive, by name. |data| must be non-null. 205*adcb0a62SAndroid Build Coastguard Worker * 206*adcb0a62SAndroid Build Coastguard Worker * Returns 0 if an entry is found, and populates |data| with information 207*adcb0a62SAndroid Build Coastguard Worker * about this entry. Returns negative values otherwise. 208*adcb0a62SAndroid Build Coastguard Worker * 209*adcb0a62SAndroid Build Coastguard Worker * It's important to note that |data->crc32|, |data->compLen| and 210*adcb0a62SAndroid Build Coastguard Worker * |data->uncompLen| might be set to values from the central directory 211*adcb0a62SAndroid Build Coastguard Worker * if this file entry contains a data descriptor footer. To verify crc32s 212*adcb0a62SAndroid Build Coastguard Worker * and length, a call to VerifyCrcAndLengths must be made after entry data 213*adcb0a62SAndroid Build Coastguard Worker * has been processed. 214*adcb0a62SAndroid Build Coastguard Worker * 215*adcb0a62SAndroid Build Coastguard Worker * On non-Windows platforms this method does not modify internal state and 216*adcb0a62SAndroid Build Coastguard Worker * can be called concurrently. 217*adcb0a62SAndroid Build Coastguard Worker */ 218*adcb0a62SAndroid Build Coastguard Worker int32_t FindEntry(const ZipArchiveHandle archive, const std::string_view entryName, 219*adcb0a62SAndroid Build Coastguard Worker ZipEntry64* data); 220*adcb0a62SAndroid Build Coastguard Worker 221*adcb0a62SAndroid Build Coastguard Worker /* 222*adcb0a62SAndroid Build Coastguard Worker * Start iterating over all entries of a zip file. The order of iteration 223*adcb0a62SAndroid Build Coastguard Worker * is not guaranteed to be the same as the order of elements 224*adcb0a62SAndroid Build Coastguard Worker * in the central directory but is stable for a given zip file. |cookie| will 225*adcb0a62SAndroid Build Coastguard Worker * contain the value of an opaque cookie which can be used to make one or more 226*adcb0a62SAndroid Build Coastguard Worker * calls to Next. All calls to StartIteration must be matched by a call to 227*adcb0a62SAndroid Build Coastguard Worker * EndIteration to free any allocated memory. 228*adcb0a62SAndroid Build Coastguard Worker * 229*adcb0a62SAndroid Build Coastguard Worker * This method also accepts optional prefix and suffix to restrict iteration to 230*adcb0a62SAndroid Build Coastguard Worker * entry names that start with |optional_prefix| or end with |optional_suffix|. 231*adcb0a62SAndroid Build Coastguard Worker * 232*adcb0a62SAndroid Build Coastguard Worker * Returns 0 on success and negative values on failure. 233*adcb0a62SAndroid Build Coastguard Worker */ 234*adcb0a62SAndroid Build Coastguard Worker int32_t StartIteration(ZipArchiveHandle archive, void** cookie_ptr, 235*adcb0a62SAndroid Build Coastguard Worker const std::string_view optional_prefix = "", 236*adcb0a62SAndroid Build Coastguard Worker const std::string_view optional_suffix = ""); 237*adcb0a62SAndroid Build Coastguard Worker 238*adcb0a62SAndroid Build Coastguard Worker /* 239*adcb0a62SAndroid Build Coastguard Worker * Start iterating over all entries of a zip file. Use the matcher functor to 240*adcb0a62SAndroid Build Coastguard Worker * restrict iteration to entry names that make the functor return true. 241*adcb0a62SAndroid Build Coastguard Worker * 242*adcb0a62SAndroid Build Coastguard Worker * Returns 0 on success and negative values on failure. 243*adcb0a62SAndroid Build Coastguard Worker */ 244*adcb0a62SAndroid Build Coastguard Worker int32_t StartIteration(ZipArchiveHandle archive, void** cookie_ptr, 245*adcb0a62SAndroid Build Coastguard Worker std::function<bool(std::string_view entry_name)> matcher); 246*adcb0a62SAndroid Build Coastguard Worker 247*adcb0a62SAndroid Build Coastguard Worker /* 248*adcb0a62SAndroid Build Coastguard Worker * Advance to the next element in the zipfile in iteration order. 249*adcb0a62SAndroid Build Coastguard Worker * 250*adcb0a62SAndroid Build Coastguard Worker * Returns 0 on success, -1 if there are no more elements in this 251*adcb0a62SAndroid Build Coastguard Worker * archive and lower negative values on failure. 252*adcb0a62SAndroid Build Coastguard Worker */ 253*adcb0a62SAndroid Build Coastguard Worker int32_t Next(void* cookie, ZipEntry64* data, std::string_view* name); 254*adcb0a62SAndroid Build Coastguard Worker int32_t Next(void* cookie, ZipEntry64* data, std::string* name); 255*adcb0a62SAndroid Build Coastguard Worker 256*adcb0a62SAndroid Build Coastguard Worker /* 257*adcb0a62SAndroid Build Coastguard Worker * End iteration over all entries of a zip file and frees the memory allocated 258*adcb0a62SAndroid Build Coastguard Worker * in StartIteration. 259*adcb0a62SAndroid Build Coastguard Worker */ 260*adcb0a62SAndroid Build Coastguard Worker void EndIteration(void* cookie); 261*adcb0a62SAndroid Build Coastguard Worker 262*adcb0a62SAndroid Build Coastguard Worker /* 263*adcb0a62SAndroid Build Coastguard Worker * Uncompress and write an entry to an open file identified by |fd|. 264*adcb0a62SAndroid Build Coastguard Worker * |entry->uncompressed_length| bytes will be written to the file at 265*adcb0a62SAndroid Build Coastguard Worker * its current offset, and the file will be truncated at the end of 266*adcb0a62SAndroid Build Coastguard Worker * the uncompressed data (no truncation if |fd| references a block 267*adcb0a62SAndroid Build Coastguard Worker * device). 268*adcb0a62SAndroid Build Coastguard Worker * 269*adcb0a62SAndroid Build Coastguard Worker * Returns 0 on success and negative values on failure. 270*adcb0a62SAndroid Build Coastguard Worker */ 271*adcb0a62SAndroid Build Coastguard Worker int32_t ExtractEntryToFile(ZipArchiveHandle archive, const ZipEntry64* entry, int fd); 272*adcb0a62SAndroid Build Coastguard Worker 273*adcb0a62SAndroid Build Coastguard Worker /** 274*adcb0a62SAndroid Build Coastguard Worker * Uncompress a given zip entry to the memory region at |begin| and of 275*adcb0a62SAndroid Build Coastguard Worker * size |size|. This size is expected to be the same as the *declared* 276*adcb0a62SAndroid Build Coastguard Worker * uncompressed length of the zip entry. It is an error if the *actual* 277*adcb0a62SAndroid Build Coastguard Worker * number of uncompressed bytes differs from this number. 278*adcb0a62SAndroid Build Coastguard Worker * 279*adcb0a62SAndroid Build Coastguard Worker * Returns 0 on success and negative values on failure. 280*adcb0a62SAndroid Build Coastguard Worker */ 281*adcb0a62SAndroid Build Coastguard Worker int32_t ExtractToMemory(ZipArchiveHandle archive, const ZipEntry64* entry, uint8_t* begin, 282*adcb0a62SAndroid Build Coastguard Worker size_t size); 283*adcb0a62SAndroid Build Coastguard Worker 284*adcb0a62SAndroid Build Coastguard Worker int GetFileDescriptor(const ZipArchiveHandle archive); 285*adcb0a62SAndroid Build Coastguard Worker 286*adcb0a62SAndroid Build Coastguard Worker /** 287*adcb0a62SAndroid Build Coastguard Worker * Returns the offset of the zip archive in the backing file descriptor, or 0 if the zip archive is 288*adcb0a62SAndroid Build Coastguard Worker * not backed by a file descriptor. 289*adcb0a62SAndroid Build Coastguard Worker */ 290*adcb0a62SAndroid Build Coastguard Worker off64_t GetFileDescriptorOffset(const ZipArchiveHandle archive); 291*adcb0a62SAndroid Build Coastguard Worker 292*adcb0a62SAndroid Build Coastguard Worker const char* ErrorCodeString(int32_t error_code); 293*adcb0a62SAndroid Build Coastguard Worker 294*adcb0a62SAndroid Build Coastguard Worker // Many users of libziparchive assume the entry size to be 32 bits long. So we keep these 295*adcb0a62SAndroid Build Coastguard Worker // interfaces that use 32 bit ZipEntry to make old code work. TODO(xunchang) Remove the 32 bit 296*adcb0a62SAndroid Build Coastguard Worker // wrapper functions once we switch all users to recognize ZipEntry64. 297*adcb0a62SAndroid Build Coastguard Worker int32_t FindEntry(const ZipArchiveHandle archive, const std::string_view entryName, ZipEntry* data); 298*adcb0a62SAndroid Build Coastguard Worker int32_t Next(void* cookie, ZipEntry* data, std::string* name); 299*adcb0a62SAndroid Build Coastguard Worker int32_t Next(void* cookie, ZipEntry* data, std::string_view* name); 300*adcb0a62SAndroid Build Coastguard Worker int32_t ExtractEntryToFile(ZipArchiveHandle archive, const ZipEntry* entry, int fd); 301*adcb0a62SAndroid Build Coastguard Worker int32_t ExtractToMemory(ZipArchiveHandle archive, const ZipEntry* entry, uint8_t* begin, 302*adcb0a62SAndroid Build Coastguard Worker size_t size); 303*adcb0a62SAndroid Build Coastguard Worker 304*adcb0a62SAndroid Build Coastguard Worker // 305*adcb0a62SAndroid Build Coastguard Worker // This gets defined for the version of the library that need to control all 306*adcb0a62SAndroid Build Coastguard Worker // code accessing the zip file. Details in incfs_support/signal_handling.h 307*adcb0a62SAndroid Build Coastguard Worker // 308*adcb0a62SAndroid Build Coastguard Worker #if !ZIPARCHIVE_DISABLE_CALLBACK_API 309*adcb0a62SAndroid Build Coastguard Worker 310*adcb0a62SAndroid Build Coastguard Worker #if !defined(_WIN32) 311*adcb0a62SAndroid Build Coastguard Worker typedef bool (*ProcessZipEntryFunction)(const uint8_t* buf, size_t buf_size, void* cookie); 312*adcb0a62SAndroid Build Coastguard Worker 313*adcb0a62SAndroid Build Coastguard Worker /* 314*adcb0a62SAndroid Build Coastguard Worker * Stream the uncompressed data through the supplied function, 315*adcb0a62SAndroid Build Coastguard Worker * passing cookie to it each time it gets called. 316*adcb0a62SAndroid Build Coastguard Worker */ 317*adcb0a62SAndroid Build Coastguard Worker int32_t ProcessZipEntryContents(ZipArchiveHandle archive, const ZipEntry* entry, 318*adcb0a62SAndroid Build Coastguard Worker ProcessZipEntryFunction func, void* cookie); 319*adcb0a62SAndroid Build Coastguard Worker int32_t ProcessZipEntryContents(ZipArchiveHandle archive, const ZipEntry64* entry, 320*adcb0a62SAndroid Build Coastguard Worker ProcessZipEntryFunction func, void* cookie); 321*adcb0a62SAndroid Build Coastguard Worker #endif // !defined(_WIN32) 322*adcb0a62SAndroid Build Coastguard Worker 323*adcb0a62SAndroid Build Coastguard Worker #endif // !ZIPARCHIVE_DISABLE_CALLBACK_API 324*adcb0a62SAndroid Build Coastguard Worker 325*adcb0a62SAndroid Build Coastguard Worker namespace zip_archive { 326*adcb0a62SAndroid Build Coastguard Worker 327*adcb0a62SAndroid Build Coastguard Worker class Writer { 328*adcb0a62SAndroid Build Coastguard Worker public: 329*adcb0a62SAndroid Build Coastguard Worker virtual bool Append(uint8_t* buf, size_t buf_size) = 0; 330*adcb0a62SAndroid Build Coastguard Worker 331*adcb0a62SAndroid Build Coastguard Worker // Returns the internal buffer that can we written into directly. 332*adcb0a62SAndroid Build Coastguard Worker using Buffer = std::pair<uint8_t*, size_t>; 333*adcb0a62SAndroid Build Coastguard Worker virtual Buffer GetBuffer(size_t length); 334*adcb0a62SAndroid Build Coastguard Worker 335*adcb0a62SAndroid Build Coastguard Worker protected: 336*adcb0a62SAndroid Build Coastguard Worker Writer() = default; 337*adcb0a62SAndroid Build Coastguard Worker ~Writer() = default; 338*adcb0a62SAndroid Build Coastguard Worker 339*adcb0a62SAndroid Build Coastguard Worker private: 340*adcb0a62SAndroid Build Coastguard Worker DISALLOW_COPY_AND_ASSIGN(Writer); 341*adcb0a62SAndroid Build Coastguard Worker }; 342*adcb0a62SAndroid Build Coastguard Worker 343*adcb0a62SAndroid Build Coastguard Worker class LowLevelReader { 344*adcb0a62SAndroid Build Coastguard Worker public: 345*adcb0a62SAndroid Build Coastguard Worker // Get |len| bytes of data starting at |offset|, either by copying them into the supplied |buf|, 346*adcb0a62SAndroid Build Coastguard Worker // or returning an internal buffer directly. 347*adcb0a62SAndroid Build Coastguard Worker // Returns a pointer to the data (which can be different from |buf|), or |nullptr| on error. 348*adcb0a62SAndroid Build Coastguard Worker virtual const uint8_t* AccessAtOffset(uint8_t* buf, size_t len, off64_t offset) const = 0; 349*adcb0a62SAndroid Build Coastguard Worker 350*adcb0a62SAndroid Build Coastguard Worker // Returns |true| if the reader doesn't need an external buffer but instead returns its own one. 351*adcb0a62SAndroid Build Coastguard Worker virtual bool IsZeroCopy() const = 0; 352*adcb0a62SAndroid Build Coastguard Worker 353*adcb0a62SAndroid Build Coastguard Worker protected: 354*adcb0a62SAndroid Build Coastguard Worker LowLevelReader() = default; 355*adcb0a62SAndroid Build Coastguard Worker ~LowLevelReader() = default; 356*adcb0a62SAndroid Build Coastguard Worker 357*adcb0a62SAndroid Build Coastguard Worker private: 358*adcb0a62SAndroid Build Coastguard Worker DISALLOW_COPY_AND_ASSIGN(LowLevelReader); 359*adcb0a62SAndroid Build Coastguard Worker }; 360*adcb0a62SAndroid Build Coastguard Worker 361*adcb0a62SAndroid Build Coastguard Worker class Reader : public LowLevelReader { 362*adcb0a62SAndroid Build Coastguard Worker public: 363*adcb0a62SAndroid Build Coastguard Worker virtual bool ReadAtOffset(uint8_t* buf, size_t len, off64_t offset) const = 0; 364*adcb0a62SAndroid Build Coastguard Worker 365*adcb0a62SAndroid Build Coastguard Worker // Ensure the existing classes implementing Reader don't need to bother with 366*adcb0a62SAndroid Build Coastguard Worker // the new method. 367*adcb0a62SAndroid Build Coastguard Worker const uint8_t* AccessAtOffset(uint8_t* buf, size_t len, off64_t offset) const override; 368*adcb0a62SAndroid Build Coastguard Worker bool IsZeroCopy() const override; 369*adcb0a62SAndroid Build Coastguard Worker 370*adcb0a62SAndroid Build Coastguard Worker protected: 371*adcb0a62SAndroid Build Coastguard Worker Reader() = default; 372*adcb0a62SAndroid Build Coastguard Worker ~Reader() = default; 373*adcb0a62SAndroid Build Coastguard Worker 374*adcb0a62SAndroid Build Coastguard Worker private: 375*adcb0a62SAndroid Build Coastguard Worker DISALLOW_COPY_AND_ASSIGN(Reader); 376*adcb0a62SAndroid Build Coastguard Worker }; 377*adcb0a62SAndroid Build Coastguard Worker 378*adcb0a62SAndroid Build Coastguard Worker // 379*adcb0a62SAndroid Build Coastguard Worker // This gets defined for the version of the library that need to control all 380*adcb0a62SAndroid Build Coastguard Worker // code accessing the zip file. Details in incfs_support/signal_handling.h 381*adcb0a62SAndroid Build Coastguard Worker // 382*adcb0a62SAndroid Build Coastguard Worker #if !ZIPARCHIVE_DISABLE_CALLBACK_API 383*adcb0a62SAndroid Build Coastguard Worker 384*adcb0a62SAndroid Build Coastguard Worker /** 385*adcb0a62SAndroid Build Coastguard Worker * Uncompress a given zip entry to given |writer|. 386*adcb0a62SAndroid Build Coastguard Worker * 387*adcb0a62SAndroid Build Coastguard Worker * Returns 0 on success and negative values on failure. 388*adcb0a62SAndroid Build Coastguard Worker */ 389*adcb0a62SAndroid Build Coastguard Worker int32_t ExtractToWriter(ZipArchiveHandle handle, const ZipEntry64* entry, 390*adcb0a62SAndroid Build Coastguard Worker zip_archive::Writer* writer); 391*adcb0a62SAndroid Build Coastguard Worker 392*adcb0a62SAndroid Build Coastguard Worker #endif // !ZIPARCHIVE_DISABLE_CALLBACK_API 393*adcb0a62SAndroid Build Coastguard Worker 394*adcb0a62SAndroid Build Coastguard Worker /* 395*adcb0a62SAndroid Build Coastguard Worker * Inflates the first |compressed_length| bytes of |reader| to a given |writer|. 396*adcb0a62SAndroid Build Coastguard Worker * |crc_out| is set to the CRC32 checksum of the uncompressed data. 397*adcb0a62SAndroid Build Coastguard Worker * 398*adcb0a62SAndroid Build Coastguard Worker * Returns 0 on success and negative values on failure, for example if |reader| 399*adcb0a62SAndroid Build Coastguard Worker * cannot supply the right amount of data, or if the number of bytes written to 400*adcb0a62SAndroid Build Coastguard Worker * data does not match |uncompressed_length|. 401*adcb0a62SAndroid Build Coastguard Worker * 402*adcb0a62SAndroid Build Coastguard Worker * If |crc_out| is not nullptr, it is set to the crc32 checksum of the 403*adcb0a62SAndroid Build Coastguard Worker * uncompressed data. 404*adcb0a62SAndroid Build Coastguard Worker * 405*adcb0a62SAndroid Build Coastguard Worker * NOTE: in the IncFS version of the library this function remains 406*adcb0a62SAndroid Build Coastguard Worker * unprotected, because the data |reader| is supplying is under the full reader's 407*adcb0a62SAndroid Build Coastguard Worker * control; it's the reader's duty to ensure it is available and OK to access. 408*adcb0a62SAndroid Build Coastguard Worker */ 409*adcb0a62SAndroid Build Coastguard Worker int32_t Inflate(const Reader& reader, const uint64_t compressed_length, 410*adcb0a62SAndroid Build Coastguard Worker const uint64_t uncompressed_length, Writer* writer, uint64_t* crc_out); 411*adcb0a62SAndroid Build Coastguard Worker 412*adcb0a62SAndroid Build Coastguard Worker } // namespace zip_archive 413