• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2007 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  * This is similar to the more-complete ZipFile class, but no attempt
21  * has been made to make them interchangeable.  This class operates under
22  * a very different set of assumptions and constraints.
23  *
24  * One such assumption is that if you're getting file descriptors for
25  * use with this class as a child of a fork() operation, you must be on
26  * a pread() to guarantee correct operation. This is because pread() can
27  * atomically read at a file offset without worrying about a lock around an
28  * lseek() + read() pair.
29  */
30 #ifndef __LIBS_ZIPFILERO_H
31 #define __LIBS_ZIPFILERO_H
32 
33 #include <optional>
34 #include <stdint.h>
35 #include <stdio.h>
36 #include <stdlib.h>
37 #include <unistd.h>
38 #include <time.h>
39 
40 #include <util/map_ptr.h>
41 
42 #include <utils/Compat.h>
43 #include <utils/Errors.h>
44 #include <utils/FileMap.h>
45 #include <utils/threads.h>
46 
47 struct ZipArchive;
48 typedef ZipArchive* ZipArchiveHandle;
49 
50 namespace android {
51 
52 /*
53  * Trivial typedef to ensure that ZipEntryRO is not treated as a simple
54  * integer.  We use NULL to indicate an invalid value.
55  */
56 typedef void* ZipEntryRO;
57 
58 /*
59  * Open a Zip archive for reading.
60  *
61  * Implemented as a thin wrapper over system/core/libziparchive.
62  *
63  * "open" and "find entry by name" are fast operations and use as little
64  * memory as possible.
65  *
66  * We also support fast iteration over all entries in the file (with a
67  * stable, but unspecified iteration order).
68  *
69  * NOTE: If this is used on file descriptors inherited from a fork() operation,
70  * you must be on a platform that implements pread() to guarantee correctness
71  * on the shared file descriptors.
72  */
73 class ZipFileRO {
74 public:
75     /* Zip compression methods we support */
76     enum : uint16_t {
77         kCompressStored = 0,
78         kCompressDeflated = 8
79     };
80 
81     /*
82      * Open an archive.
83      */
84     static ZipFileRO* open(const char* zipFileName);
85 
86     /*
87      * Open an archive from an already open file descriptor.
88      */
89     static ZipFileRO* openFd(int fd, const char* debugFileName,
90         bool assume_ownership = true);
91 
92     /*
93      * Find an entry, by name.  Returns the entry identifier, or NULL if
94      * not found.
95      */
96     ZipEntryRO findEntryByName(const char* entryName) const;
97 
98 
99     /*
100      * Start iterating over the list of entries in the zip file. Requires
101      * a matching call to endIteration with the same cookie.
102      */
103     bool startIteration(void** cookie);
104     bool startIteration(void** cookie, const char* prefix, const char* suffix);
105 
106     /**
107      * Return the next entry in iteration order, or NULL if there are no more
108      * entries in this archive.
109      */
110     ZipEntryRO nextEntry(void* cookie);
111 
112     void endIteration(void* cookie);
113 
114     void releaseEntry(ZipEntryRO entry) const;
115 
116     /*
117      * Return the #of entries in the Zip archive.
118      */
119     int getNumEntries();
120 
121     /*
122      * Copy the filename into the supplied buffer.  Returns 0 on success,
123      * -1 if "entry" is invalid, or the filename length if it didn't fit. The
124      * length, and the returned string, include the null-termination.
125      */
126     int getEntryFileName(ZipEntryRO entry, char* buffer, size_t bufLen) const;
127 
128     /*
129      * Get the vital stats for an entry.  Pass in NULL pointers for anything
130      * you don't need.
131      *
132      * "*pOffset" holds the Zip file offset of the entry's data.
133      *
134      * Returns "false" if "entry" is bogus or if the data in the Zip file
135      * appears to be bad.
136      */
137     bool getEntryInfo(ZipEntryRO entry, uint16_t* pMethod, uint32_t* pUncompLen,
138         uint32_t* pCompLen, off64_t* pOffset, uint32_t* pModWhen,
139         uint32_t* pCrc32) const;
140 
141     /*
142      * Create a new FileMap object that maps a subset of the archive. For
143      * an uncompressed entry this effectively provides a pointer to the
144      * actual data, for a compressed entry this provides the input buffer
145      * for inflate().
146      *
147      * Use this function if the archive can never reside on IncFs.
148      */
149     FileMap* createEntryFileMap(ZipEntryRO entry) const;
150 
151     /*
152      * Create a new incfs::IncFsFileMap object that maps a subset of the archive. For
153      * an uncompressed entry this effectively provides a pointer to the
154      * actual data, for a compressed entry this provides the input buffer
155      * for inflate().
156      *
157      * Use this function if the archive can potentially reside on IncFs.
158      */
159     std::optional<incfs::IncFsFileMap> createEntryIncFsFileMap(ZipEntryRO entry) const;
160 
161     /*
162      * Uncompress the data into a buffer.  Depending on the compression
163      * format, this is either an "inflate" operation or a memcpy.
164      *
165      * Use "uncompLen" from getEntryInfo() to determine the required
166      * buffer size.
167      *
168      * Returns "true" on success.
169      */
170     bool uncompressEntry(ZipEntryRO entry, void* buffer, size_t size) const;
171 
172     /*
173      * Uncompress the data to an open file descriptor.
174      */
175     bool uncompressEntry(ZipEntryRO entry, int fd) const;
176 
177     ~ZipFileRO();
178 
179 private:
180     /* these are private and not defined */
181     ZipFileRO(const ZipFileRO& src);
182     ZipFileRO& operator=(const ZipFileRO& src);
183 
ZipFileRO(ZipArchiveHandle handle,char * fileName)184     ZipFileRO(ZipArchiveHandle handle, char* fileName) : mHandle(handle),
185         mFileName(fileName)
186     {
187     }
188 
189     const ZipArchiveHandle mHandle;
190     char* mFileName;
191 };
192 
193 }; // namespace android
194 
195 #endif /*__LIBS_ZIPFILERO_H*/
196