1b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom/* 2b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom * Copyright (C) 2008 The Android Open Source Project 3b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom * 4b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom * Licensed under the Apache License, Version 2.0 (the "License"); 5b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom * you may not use this file except in compliance with the License. 6b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom * You may obtain a copy of the License at 7b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom * 8b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom * http://www.apache.org/licenses/LICENSE-2.0 9b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom * 10b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom * Unless required by applicable law or agreed to in writing, software 11b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom * distributed under the License is distributed on an "AS IS" BASIS, 12b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom * See the License for the specific language governing permissions and 14b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom * limitations under the License. 15b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom */ 16b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom 17fc0e3219edc9a5bf81b166e82fd5db2796eb6a0dBrian Carlstrom#ifndef ART_RUNTIME_ZIP_ARCHIVE_H_ 18fc0e3219edc9a5bf81b166e82fd5db2796eb6a0dBrian Carlstrom#define ART_RUNTIME_ZIP_ARCHIVE_H_ 19b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom 20b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom#include <stdint.h> 21b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom#include <zlib.h> 22b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom 2307ed66b5ae659c452cbe1ab20c3dbf1d6f546461Elliott Hughes#include "base/logging.h" 24e222ee0b794f941af4fb1b32fb8224e32942ea7bElliott Hughes#include "base/stringpiece.h" 25761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes#include "base/unix_file/random_access_file.h" 26b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom#include "globals.h" 27db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstrom#include "mem_map.h" 28761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes#include "os.h" 29a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes#include "safe_map.h" 30e5448b5a12003b405b22cde3b94f962ab4888a87Elliott Hughes#include "UniquePtr.h" 31b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom 32b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstromnamespace art { 33b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom 34b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstromclass ZipArchive; 35b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstromclass MemMap; 36b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom 37b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstromclass ZipEntry { 38b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom public: 3989521898b56f2ebc3fb68acfb6bc6dde9b6f5c38Brian Carlstrom bool ExtractToFile(File& file); 404922e9d4e5f86e40ca89fb097cec40e191dae0a1Brian Carlstrom bool ExtractToMemory(uint8_t* begin, size_t size); 414922e9d4e5f86e40ca89fb097cec40e191dae0a1Brian Carlstrom MemMap* ExtractToMemMap(const char* entry_filename); 42b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom 4389521898b56f2ebc3fb68acfb6bc6dde9b6f5c38Brian Carlstrom uint32_t GetUncompressedLength(); 44b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom uint32_t GetCrc32(); 45b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom 46b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom private: 47a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom ZipEntry(const ZipArchive* zip_archive, const byte* ptr) : zip_archive_(zip_archive), ptr_(ptr) {} 48b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom 49b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom // Zip compression methods 50b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom enum { 51b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom kCompressStored = 0, // no compression 52b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom kCompressDeflated = 8, // standard deflate 53b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom }; 54b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom 55b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom // kCompressStored, kCompressDeflated, ... 56b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom uint16_t GetCompressionMethod(); 57b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom 58b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom uint32_t GetCompressedLength(); 59b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom 60b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom // returns -1 on error 6172fcca2477e02da2d3970aefc75465ba1f20ce9cKenny Root off64_t GetDataOffset(); 62b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom 63a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom const ZipArchive* zip_archive_; 64b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom 65b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom // pointer to zip entry within central directory 66db4d54081f09abcbe97ffdf615874f2809a9e777Brian Carlstrom const byte* ptr_; 67b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom 68b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom friend class ZipArchive; 69a21039c3ae2b20e44ceb2735251c04d0aac89afdElliott Hughes DISALLOW_COPY_AND_ASSIGN(ZipEntry); 70b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom}; 71b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom 72b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstromclass ZipArchive { 73b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom public: 74b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom // Zip file constants. 7572fcca2477e02da2d3970aefc75465ba1f20ce9cKenny Root static const uint32_t kEOCDSignature = 0x06054b50; 7672fcca2477e02da2d3970aefc75465ba1f20ce9cKenny Root static const int32_t kEOCDLen = 22; 7772fcca2477e02da2d3970aefc75465ba1f20ce9cKenny Root static const int32_t kEOCDDiskNumber = 4; // number of the current disk 7872fcca2477e02da2d3970aefc75465ba1f20ce9cKenny Root static const int32_t kEOCDDiskNumberForCD = 6; // disk number with the Central Directory 7972fcca2477e02da2d3970aefc75465ba1f20ce9cKenny Root static const int32_t kEOCDNumEntries = 8; // offset to #of entries in file 8072fcca2477e02da2d3970aefc75465ba1f20ce9cKenny Root static const int32_t kEOCDTotalNumEntries = 10; // offset to total #of entries in spanned archives 8172fcca2477e02da2d3970aefc75465ba1f20ce9cKenny Root static const int32_t kEOCDSize = 12; // size of the central directory 8272fcca2477e02da2d3970aefc75465ba1f20ce9cKenny Root static const int32_t kEOCDFileOffset = 16; // offset to central directory 8372fcca2477e02da2d3970aefc75465ba1f20ce9cKenny Root static const int32_t kEOCDCommentSize = 20; // offset to the length of the file comment 84b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom 85b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom static const int32_t kMaxCommentLen = 65535; // longest possible in uint16_t 86b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom static const int32_t kMaxEOCDSearch = (kMaxCommentLen + kEOCDLen); 87b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom 88b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom static const uint32_t kLFHSignature = 0x04034b50; 89b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom static const int32_t kLFHLen = 30; // excluding variable-len fields 9072fcca2477e02da2d3970aefc75465ba1f20ce9cKenny Root static const int32_t kLFHGPBFlags = 6; // offset to GPB flags 91b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom static const int32_t kLFHNameLen = 26; // offset to filename length 92b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom static const int32_t kLFHExtraLen = 28; // offset to extra length 93b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom 94b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom static const uint32_t kCDESignature = 0x02014b50; 95b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom static const int32_t kCDELen = 46; // excluding variable-len fields 9672fcca2477e02da2d3970aefc75465ba1f20ce9cKenny Root static const int32_t kCDEGPBFlags = 8; // offset to GPB flags 97b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom static const int32_t kCDEMethod = 10; // offset to compression method 98b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom static const int32_t kCDEModWhen = 12; // offset to modification timestamp 99b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom static const int32_t kCDECRC = 16; // offset to entry CRC 100b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom static const int32_t kCDECompLen = 20; // offset to compressed length 101b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom static const int32_t kCDEUncompLen = 24; // offset to uncompressed length 102b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom static const int32_t kCDENameLen = 28; // offset to filename length 103b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom static const int32_t kCDEExtraLen = 30; // offset to extra length 104b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom static const int32_t kCDECommentLen = 32; // offset to comment length 105b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom static const int32_t kCDELocalOffset = 42; // offset to local hdr 106b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom 10772fcca2477e02da2d3970aefc75465ba1f20ce9cKenny Root // General Purpose Bit Flag 10872fcca2477e02da2d3970aefc75465ba1f20ce9cKenny Root static const int32_t kGPFEncryptedFlag = (1 << 0); 10972fcca2477e02da2d3970aefc75465ba1f20ce9cKenny Root static const int32_t kGPFUnsupportedMask = (kGPFEncryptedFlag); 11072fcca2477e02da2d3970aefc75465ba1f20ce9cKenny Root 111b7bbba49d88eae58223d9878da4069bf6d7140bfBrian Carlstrom // return new ZipArchive instance on success, NULL on error. 112b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom static ZipArchive* Open(const std::string& filename); 113a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom static ZipArchive* OpenFromFd(int fd); 114b7bbba49d88eae58223d9878da4069bf6d7140bfBrian Carlstrom 115a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom ZipEntry* Find(const char* name) const; 116b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom 117b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom ~ZipArchive() { 118b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom Close(); 119b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom } 120b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom 121b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom private: 122a51a3dd5603daf3d368b7735067e1d9eb54c4c40Elliott Hughes explicit ZipArchive(int fd) : fd_(fd), num_entries_(0), dir_offset_(0) {} 123b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom 124b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom bool MapCentralDirectory(); 125b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom bool Parse(); 126b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom void Close(); 127b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom 128b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom int fd_; 129b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom uint16_t num_entries_; 13072fcca2477e02da2d3970aefc75465ba1f20ce9cKenny Root off64_t dir_offset_; 13190a3369d3b6238f1a4c9b19ca68978dab1c39bc4Elliott Hughes UniquePtr<MemMap> dir_map_; 132a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes typedef SafeMap<StringPiece, const byte*> DirEntries; 1337e93b50433cde2a44d99212e8040299bde498546Brian Carlstrom DirEntries dir_entries_; 134b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom 135b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom friend class ZipEntry; 136a21039c3ae2b20e44ceb2735251c04d0aac89afdElliott Hughes 137a21039c3ae2b20e44ceb2735251c04d0aac89afdElliott Hughes DISALLOW_COPY_AND_ASSIGN(ZipArchive); 138b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom}; 139b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom 140b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom} // namespace art 141b0460eaa2cb131f1dbdd5a7217bd36b9a9f1b995Brian Carlstrom 142fc0e3219edc9a5bf81b166e82fd5db2796eb6a0dBrian Carlstrom#endif // ART_RUNTIME_ZIP_ARCHIVE_H_ 143