blob: 8ff952baab2dc28450d3e94b1a3eaffedfea655b [file] [log] [blame]
Brian Carlstromb0460ea2011-07-29 10:08:05 -07001/*
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
Brian Carlstromfc0e3212013-07-17 14:40:12 -070017#ifndef ART_RUNTIME_ZIP_ARCHIVE_H_
18#define ART_RUNTIME_ZIP_ARCHIVE_H_
Brian Carlstromb0460ea2011-07-29 10:08:05 -070019
Brian Carlstromb0460ea2011-07-29 10:08:05 -070020#include <stdint.h>
Brian Carlstromb0460ea2011-07-29 10:08:05 -070021#include <zlib.h>
Ian Rogers8d31bbd2013-10-13 10:44:14 -070022#include <string>
Brian Carlstromb0460ea2011-07-29 10:08:05 -070023
Elliott Hughes07ed66b2012-12-12 18:34:25 -080024#include "base/logging.h"
Elliott Hughese222ee02012-12-13 14:41:43 -080025#include "base/stringpiece.h"
Elliott Hughes76160052012-12-12 16:31:20 -080026#include "base/unix_file/random_access_file.h"
Brian Carlstromb0460ea2011-07-29 10:08:05 -070027#include "globals.h"
Brian Carlstromdb4d5402011-08-09 12:18:28 -070028#include "mem_map.h"
Elliott Hughes76160052012-12-12 16:31:20 -080029#include "os.h"
Elliott Hughesa0e18062012-04-13 15:59:59 -070030#include "safe_map.h"
Elliott Hughese5448b52012-01-18 16:44:06 -080031#include "UniquePtr.h"
Brian Carlstromb0460ea2011-07-29 10:08:05 -070032
33namespace art {
34
35class ZipArchive;
36class MemMap;
37
38class ZipEntry {
Brian Carlstromb0460ea2011-07-29 10:08:05 -070039 public:
Ian Rogers8d31bbd2013-10-13 10:44:14 -070040 bool ExtractToFile(File& file, std::string* error_msg);
41 bool ExtractToMemory(uint8_t* begin, size_t size, std::string* error_msg);
42 MemMap* ExtractToMemMap(const char* entry_filename, std::string* error_msg);
Brian Carlstromb0460ea2011-07-29 10:08:05 -070043
Brian Carlstrom89521892011-12-07 22:05:07 -080044 uint32_t GetUncompressedLength();
Brian Carlstromb0460ea2011-07-29 10:08:05 -070045 uint32_t GetCrc32();
46
47 private:
Brian Carlstroma6cc8932012-01-04 14:44:07 -080048 ZipEntry(const ZipArchive* zip_archive, const byte* ptr) : zip_archive_(zip_archive), ptr_(ptr) {}
Brian Carlstromb0460ea2011-07-29 10:08:05 -070049
50 // Zip compression methods
51 enum {
52 kCompressStored = 0, // no compression
53 kCompressDeflated = 8, // standard deflate
54 };
55
56 // kCompressStored, kCompressDeflated, ...
57 uint16_t GetCompressionMethod();
58
59 uint32_t GetCompressedLength();
60
Brian Carlstromb0460ea2011-07-29 10:08:05 -070061 // returns -1 on error
Kenny Root72fcca22013-09-19 09:25:34 -070062 off64_t GetDataOffset();
Brian Carlstromb0460ea2011-07-29 10:08:05 -070063
Brian Carlstroma6cc8932012-01-04 14:44:07 -080064 const ZipArchive* zip_archive_;
Brian Carlstromb0460ea2011-07-29 10:08:05 -070065
66 // pointer to zip entry within central directory
Brian Carlstromdb4d5402011-08-09 12:18:28 -070067 const byte* ptr_;
Brian Carlstromb0460ea2011-07-29 10:08:05 -070068
69 friend class ZipArchive;
Elliott Hughesa21039c2012-06-21 12:09:25 -070070 DISALLOW_COPY_AND_ASSIGN(ZipEntry);
Brian Carlstromb0460ea2011-07-29 10:08:05 -070071};
72
Brian Carlstromb0460ea2011-07-29 10:08:05 -070073class ZipArchive {
74 public:
Brian Carlstromb0460ea2011-07-29 10:08:05 -070075 // Zip file constants.
Kenny Root72fcca22013-09-19 09:25:34 -070076 static const uint32_t kEOCDSignature = 0x06054b50;
77 static const int32_t kEOCDLen = 22;
78 static const int32_t kEOCDDiskNumber = 4; // number of the current disk
79 static const int32_t kEOCDDiskNumberForCD = 6; // disk number with the Central Directory
80 static const int32_t kEOCDNumEntries = 8; // offset to #of entries in file
81 static const int32_t kEOCDTotalNumEntries = 10; // offset to total #of entries in spanned archives
82 static const int32_t kEOCDSize = 12; // size of the central directory
83 static const int32_t kEOCDFileOffset = 16; // offset to central directory
84 static const int32_t kEOCDCommentSize = 20; // offset to the length of the file comment
Brian Carlstromb0460ea2011-07-29 10:08:05 -070085
86 static const int32_t kMaxCommentLen = 65535; // longest possible in uint16_t
87 static const int32_t kMaxEOCDSearch = (kMaxCommentLen + kEOCDLen);
88
89 static const uint32_t kLFHSignature = 0x04034b50;
90 static const int32_t kLFHLen = 30; // excluding variable-len fields
Kenny Root72fcca22013-09-19 09:25:34 -070091 static const int32_t kLFHGPBFlags = 6; // offset to GPB flags
Brian Carlstromb0460ea2011-07-29 10:08:05 -070092 static const int32_t kLFHNameLen = 26; // offset to filename length
93 static const int32_t kLFHExtraLen = 28; // offset to extra length
94
95 static const uint32_t kCDESignature = 0x02014b50;
96 static const int32_t kCDELen = 46; // excluding variable-len fields
Kenny Root72fcca22013-09-19 09:25:34 -070097 static const int32_t kCDEGPBFlags = 8; // offset to GPB flags
Brian Carlstromb0460ea2011-07-29 10:08:05 -070098 static const int32_t kCDEMethod = 10; // offset to compression method
99 static const int32_t kCDEModWhen = 12; // offset to modification timestamp
100 static const int32_t kCDECRC = 16; // offset to entry CRC
101 static const int32_t kCDECompLen = 20; // offset to compressed length
102 static const int32_t kCDEUncompLen = 24; // offset to uncompressed length
103 static const int32_t kCDENameLen = 28; // offset to filename length
104 static const int32_t kCDEExtraLen = 30; // offset to extra length
105 static const int32_t kCDECommentLen = 32; // offset to comment length
106 static const int32_t kCDELocalOffset = 42; // offset to local hdr
107
Kenny Root72fcca22013-09-19 09:25:34 -0700108 // General Purpose Bit Flag
109 static const int32_t kGPFEncryptedFlag = (1 << 0);
110 static const int32_t kGPFUnsupportedMask = (kGPFEncryptedFlag);
111
Brian Carlstromb7bbba42011-10-13 14:58:47 -0700112 // return new ZipArchive instance on success, NULL on error.
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700113 static ZipArchive* Open(const char* filename, std::string* error_msg);
114 static ZipArchive* OpenFromFd(int fd, const char* filename, std::string* error_msg);
Brian Carlstromb7bbba42011-10-13 14:58:47 -0700115
Brian Carlstroma6cc8932012-01-04 14:44:07 -0800116 ZipEntry* Find(const char* name) const;
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700117
118 ~ZipArchive() {
119 Close();
120 }
121
122 private:
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700123 explicit ZipArchive(int fd, const char* filename)
124 : fd_(fd), num_entries_(0), dir_offset_(0), filename_(filename) {}
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700125
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700126 bool MapCentralDirectory(std::string* error_msg);
127 bool Parse(std::string* error_msg);
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700128 void Close();
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700129 std::string ErrorStringPrintf(const char* fmt, ...)
130 __attribute__((__format__(__printf__, 2, 3))) COLD_ATTR;
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700131
132 int fd_;
133 uint16_t num_entries_;
Kenny Root72fcca22013-09-19 09:25:34 -0700134 off64_t dir_offset_;
Elliott Hughes90a33692011-08-30 13:27:07 -0700135 UniquePtr<MemMap> dir_map_;
Elliott Hughesa0e18062012-04-13 15:59:59 -0700136 typedef SafeMap<StringPiece, const byte*> DirEntries;
Brian Carlstrom7e93b502011-08-04 14:16:22 -0700137 DirEntries dir_entries_;
Ian Rogers8d31bbd2013-10-13 10:44:14 -0700138 // Containing file for error reporting.
139 const std::string filename_;
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700140
141 friend class ZipEntry;
Elliott Hughesa21039c2012-06-21 12:09:25 -0700142
143 DISALLOW_COPY_AND_ASSIGN(ZipArchive);
Brian Carlstromb0460ea2011-07-29 10:08:05 -0700144};
145
146} // namespace art
147
Brian Carlstromfc0e3212013-07-17 14:40:12 -0700148#endif // ART_RUNTIME_ZIP_ARCHIVE_H_