• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2013 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 /*
18  * Read-only access to Zip archives, with minimal heap allocation.
19  */
20 #ifndef LIBZIPARCHIVE_ZIPARCHIVE_H_
21 #define LIBZIPARCHIVE_ZIPARCHIVE_H_
22 
23 #include <stdint.h>
24 #include <string.h>
25 #include <sys/cdefs.h>
26 #include <sys/types.h>
27 #include <utils/Compat.h>
28 
29 __BEGIN_DECLS
30 
31 /* Zip compression methods we support */
32 enum {
33   kCompressStored     = 0,        // no compression
34   kCompressDeflated   = 8,        // standard deflate
35 };
36 
37 struct ZipString {
38   const uint8_t* name;
39   uint16_t name_length;
40 
ZipStringZipString41   ZipString() {}
42 
43   /*
44    * entry_name has to be an c-style string with only ASCII characters.
45    */
ZipStringZipString46   explicit ZipString(const char* entry_name)
47       : name(reinterpret_cast<const uint8_t*>(entry_name)), name_length(strlen(entry_name)) {}
48 
49   bool operator==(const ZipString& rhs) const {
50     return name && (name_length == rhs.name_length) &&
51         (memcmp(name, rhs.name, name_length) == 0);
52   }
53 
StartsWithZipString54   bool StartsWith(const ZipString& prefix) const {
55     return name && (name_length >= prefix.name_length) &&
56         (memcmp(name, prefix.name, prefix.name_length) == 0);
57   }
58 
EndsWithZipString59   bool EndsWith(const ZipString& suffix) const {
60     return name && (name_length >= suffix.name_length) &&
61         (memcmp(name + name_length - suffix.name_length, suffix.name,
62                 suffix.name_length) == 0);
63   }
64 };
65 
66 /*
67  * Represents information about a zip entry in a zip file.
68  */
69 struct ZipEntry {
70   // Compression method: One of kCompressStored or
71   // kCompressDeflated.
72   uint16_t method;
73 
74   // Modification time. The zipfile format specifies
75   // that the first two little endian bytes contain the time
76   // and the last two little endian bytes contain the date.
77   uint32_t mod_time;
78 
79   // 1 if this entry contains a data descriptor segment, 0
80   // otherwise.
81   uint8_t has_data_descriptor;
82 
83   // Crc32 value of this ZipEntry. This information might
84   // either be stored in the local file header or in a special
85   // Data descriptor footer at the end of the file entry.
86   uint32_t crc32;
87 
88   // Compressed length of this ZipEntry. Might be present
89   // either in the local file header or in the data descriptor
90   // footer.
91   uint32_t compressed_length;
92 
93   // Uncompressed length of this ZipEntry. Might be present
94   // either in the local file header or in the data descriptor
95   // footer.
96   uint32_t uncompressed_length;
97 
98   // The offset to the start of data for this ZipEntry.
99   off64_t offset;
100 };
101 
102 typedef void* ZipArchiveHandle;
103 
104 /*
105  * Open a Zip archive, and sets handle to the value of the opaque
106  * handle for the file. This handle must be released by calling
107  * CloseArchive with this handle.
108  *
109  * Returns 0 on success, and negative values on failure.
110  */
111 int32_t OpenArchive(const char* fileName, ZipArchiveHandle* handle);
112 
113 /*
114  * Like OpenArchive, but takes a file descriptor open for reading
115  * at the start of the file.  The descriptor must be mappable (this does
116  * not allow access to a stream).
117  *
118  * Sets handle to the value of the opaque handle for this file descriptor.
119  * This handle must be released by calling CloseArchive with this handle.
120  *
121  * If assume_ownership parameter is 'true' calling CloseArchive will close
122  * the file.
123  *
124  * This function maps and scans the central directory and builds a table
125  * of entries for future lookups.
126  *
127  * "debugFileName" will appear in error messages, but is not otherwise used.
128  *
129  * Returns 0 on success, and negative values on failure.
130  */
131 int32_t OpenArchiveFd(const int fd, const char* debugFileName,
132                       ZipArchiveHandle *handle, bool assume_ownership = true);
133 
134 /*
135  * Close archive, releasing resources associated with it. This will
136  * unmap the central directory of the zipfile and free all internal
137  * data structures associated with the file. It is an error to use
138  * this handle for any further operations without an intervening
139  * call to one of the OpenArchive variants.
140  */
141 void CloseArchive(ZipArchiveHandle handle);
142 
143 /*
144  * Find an entry in the Zip archive, by name. |entryName| must be a null
145  * terminated string, and |data| must point to a writeable memory location.
146  *
147  * Returns 0 if an entry is found, and populates |data| with information
148  * about this entry. Returns negative values otherwise.
149  *
150  * It's important to note that |data->crc32|, |data->compLen| and
151  * |data->uncompLen| might be set to values from the central directory
152  * if this file entry contains a data descriptor footer. To verify crc32s
153  * and length, a call to VerifyCrcAndLengths must be made after entry data
154  * has been processed.
155  *
156  * On non-Windows platforms this method does not modify internal state and
157  * can be called concurrently.
158  */
159 int32_t FindEntry(const ZipArchiveHandle handle, const ZipString& entryName,
160                   ZipEntry* data);
161 
162 /*
163  * Start iterating over all entries of a zip file. The order of iteration
164  * is not guaranteed to be the same as the order of elements
165  * in the central directory but is stable for a given zip file. |cookie| will
166  * contain the value of an opaque cookie which can be used to make one or more
167  * calls to Next. All calls to StartIteration must be matched by a call to
168  * EndIteration to free any allocated memory.
169  *
170  * This method also accepts optional prefix and suffix to restrict iteration to
171  * entry names that start with |optional_prefix| or end with |optional_suffix|.
172  *
173  * Returns 0 on success and negative values on failure.
174  */
175 int32_t StartIteration(ZipArchiveHandle handle, void** cookie_ptr,
176                        const ZipString* optional_prefix,
177                        const ZipString* optional_suffix);
178 
179 /*
180  * Advance to the next element in the zipfile in iteration order.
181  *
182  * Returns 0 on success, -1 if there are no more elements in this
183  * archive and lower negative values on failure.
184  */
185 int32_t Next(void* cookie, ZipEntry* data, ZipString* name);
186 
187 /*
188  * End iteration over all entries of a zip file and frees the memory allocated
189  * in StartIteration.
190  */
191 void EndIteration(void* cookie);
192 
193 /*
194  * Uncompress and write an entry to an open file identified by |fd|.
195  * |entry->uncompressed_length| bytes will be written to the file at
196  * its current offset, and the file will be truncated at the end of
197  * the uncompressed data.
198  *
199  * Returns 0 on success and negative values on failure.
200  */
201 int32_t ExtractEntryToFile(ZipArchiveHandle handle, ZipEntry* entry, int fd);
202 
203 /**
204  * Uncompress a given zip entry to the memory region at |begin| and of
205  * size |size|. This size is expected to be the same as the *declared*
206  * uncompressed length of the zip entry. It is an error if the *actual*
207  * number of uncompressed bytes differs from this number.
208  *
209  * Returns 0 on success and negative values on failure.
210  */
211 int32_t ExtractToMemory(ZipArchiveHandle handle, ZipEntry* entry,
212                         uint8_t* begin, uint32_t size);
213 
214 int GetFileDescriptor(const ZipArchiveHandle handle);
215 
216 const char* ErrorCodeString(int32_t error_code);
217 
218 __END_DECLS
219 
220 #endif  // LIBZIPARCHIVE_ZIPARCHIVE_H_
221