blob: 18777b2a1dc9ad73f57bde3ddad6e1be235c8007 [file] [log] [blame]
Just van Rossum52e14d62002-12-30 22:08:05 +00001#include "Python.h"
2#include "structmember.h"
3#include "osdefs.h"
4#include "marshal.h"
Just van Rossum52e14d62002-12-30 22:08:05 +00005#include <time.h>
6
7
8#define IS_SOURCE 0x0
9#define IS_BYTECODE 0x1
10#define IS_PACKAGE 0x2
11
12struct st_zip_searchorder {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000013 char suffix[14];
14 int type;
Just van Rossum52e14d62002-12-30 22:08:05 +000015};
16
Victor Stinner651f9f72013-11-12 21:44:18 +010017#ifdef ALTSEP
18_Py_IDENTIFIER(replace);
19#endif
20
Just van Rossum52e14d62002-12-30 22:08:05 +000021/* zip_searchorder defines how we search for a module in the Zip
22 archive: we first search for a package __init__, then for
Brett Cannonf299abd2015-04-13 14:21:02 -040023 non-package .pyc, and .py entries. The .pyc entries
Just van Rossum52e14d62002-12-30 22:08:05 +000024 are swapped by initzipimport() if we run in optimized mode. Also,
25 '/' is replaced by SEP there. */
Neal Norwitz29fd2ba2003-03-23 13:21:03 +000026static struct st_zip_searchorder zip_searchorder[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000027 {"/__init__.pyc", IS_PACKAGE | IS_BYTECODE},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000028 {"/__init__.py", IS_PACKAGE | IS_SOURCE},
29 {".pyc", IS_BYTECODE},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000030 {".py", IS_SOURCE},
31 {"", 0}
Just van Rossum52e14d62002-12-30 22:08:05 +000032};
33
34/* zipimporter object definition and support */
35
36typedef struct _zipimporter ZipImporter;
37
38struct _zipimporter {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000039 PyObject_HEAD
Victor Stinner9e40fad2010-10-18 22:34:46 +000040 PyObject *archive; /* pathname of the Zip archive,
41 decoded from the filesystem encoding */
Victor Stinner72f767e2010-10-18 11:44:21 +000042 PyObject *prefix; /* file prefix: "a/sub/directory/",
43 encoded to the filesystem encoding */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000044 PyObject *files; /* dict with file info {path: toc_entry} */
Just van Rossum52e14d62002-12-30 22:08:05 +000045};
46
Just van Rossum52e14d62002-12-30 22:08:05 +000047static PyObject *ZipImportError;
Victor Stinnerc342fca2010-10-18 11:39:05 +000048/* read_directory() cache */
Just van Rossum52e14d62002-12-30 22:08:05 +000049static PyObject *zip_directory_cache = NULL;
50
51/* forward decls */
Benjamin Peterson34c15402014-02-16 14:17:28 -050052static PyObject *read_directory(PyObject *archive);
53static PyObject *get_data(PyObject *archive, PyObject *toc_entry);
Victor Stinnerf6b563a2011-03-14 20:46:50 -040054static PyObject *get_module_code(ZipImporter *self, PyObject *fullname,
Victor Stinner08654e12010-10-18 12:09:02 +000055 int *p_ispackage, PyObject **p_modpath);
Just van Rossum52e14d62002-12-30 22:08:05 +000056
57
58#define ZipImporter_Check(op) PyObject_TypeCheck(op, &ZipImporter_Type)
59
60
61/* zipimporter.__init__
62 Split the "subdirectory" from the Zip archive path, lookup a matching
63 entry in sys.path_importer_cache, fetch the file directory from there
64 if found, or else read it from the archive. */
65static int
66zipimporter_init(ZipImporter *self, PyObject *args, PyObject *kwds)
67{
Martin v. Löwisa72e78b2011-10-31 08:33:37 +010068 PyObject *path, *files, *tmp;
69 PyObject *filename = NULL;
70 Py_ssize_t len, flen;
Just van Rossum52e14d62002-12-30 22:08:05 +000071
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000072 if (!_PyArg_NoKeywords("zipimporter()", kwds))
73 return -1;
Georg Brandl02c42872005-08-26 06:42:30 +000074
Victor Stinner2b8dab72010-08-14 14:54:10 +000075 if (!PyArg_ParseTuple(args, "O&:zipimporter",
Martin v. Löwisa72e78b2011-10-31 08:33:37 +010076 PyUnicode_FSDecoder, &path))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000077 return -1;
Just van Rossum52e14d62002-12-30 22:08:05 +000078
Martin v. Löwisa72e78b2011-10-31 08:33:37 +010079 if (PyUnicode_READY(path) == -1)
Martin v. Löwisd63a3b82011-09-28 07:41:54 +020080 return -1;
81
Martin v. Löwisa72e78b2011-10-31 08:33:37 +010082 len = PyUnicode_GET_LENGTH(path);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000083 if (len == 0) {
84 PyErr_SetString(ZipImportError, "archive path is empty");
Victor Stinner2b8dab72010-08-14 14:54:10 +000085 goto error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000086 }
Just van Rossum52e14d62002-12-30 22:08:05 +000087
88#ifdef ALTSEP
Martin v. Löwiscfa61292011-10-31 09:01:22 +010089 tmp = _PyObject_CallMethodId(path, &PyId_replace, "CC", ALTSEP, SEP);
Martin v. Löwisa72e78b2011-10-31 08:33:37 +010090 if (!tmp)
91 goto error;
92 Py_DECREF(path);
93 path = tmp;
Just van Rossum52e14d62002-12-30 22:08:05 +000094#endif
95
Martin v. Löwisa72e78b2011-10-31 08:33:37 +010096 filename = path;
97 Py_INCREF(filename);
98 flen = len;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000099 for (;;) {
100 struct stat statbuf;
101 int rv;
Just van Rossum52e14d62002-12-30 22:08:05 +0000102
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100103 rv = _Py_stat(filename, &statbuf);
Victor Stinnerbd0850b2011-12-18 20:47:30 +0100104 if (rv == -2)
105 goto error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000106 if (rv == 0) {
107 /* it exists */
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100108 if (!S_ISREG(statbuf.st_mode))
109 /* it's a not file */
110 Py_CLEAR(filename);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000111 break;
112 }
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100113 Py_CLEAR(filename);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000114 /* back up one path element */
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100115 flen = PyUnicode_FindChar(path, SEP, 0, flen, -1);
116 if (flen == -1)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000117 break;
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100118 filename = PyUnicode_Substring(path, 0, flen);
Victor Stinneraf8b7e82013-10-29 01:46:24 +0100119 if (filename == NULL)
120 goto error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000121 }
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100122 if (filename == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000123 PyErr_SetString(ZipImportError, "not a Zip file");
Victor Stinner2b8dab72010-08-14 14:54:10 +0000124 goto error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000125 }
Just van Rossum52e14d62002-12-30 22:08:05 +0000126
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100127 if (PyUnicode_READY(filename) < 0)
128 goto error;
129
130 files = PyDict_GetItem(zip_directory_cache, filename);
Victor Stinner2b8dab72010-08-14 14:54:10 +0000131 if (files == NULL) {
Benjamin Peterson34c15402014-02-16 14:17:28 -0500132 files = read_directory(filename);
133 if (files == NULL)
Victor Stinner2b8dab72010-08-14 14:54:10 +0000134 goto error;
Benjamin Peterson34c15402014-02-16 14:17:28 -0500135 if (PyDict_SetItem(zip_directory_cache, filename, files) != 0)
Victor Stinner2b8dab72010-08-14 14:54:10 +0000136 goto error;
137 }
138 else
139 Py_INCREF(files);
140 self->files = files;
141
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100142 /* Transfer reference */
143 self->archive = filename;
144 filename = NULL;
Victor Stinner2b8dab72010-08-14 14:54:10 +0000145
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100146 /* Check if there is a prefix directory following the filename. */
147 if (flen != len) {
148 tmp = PyUnicode_Substring(path, flen+1,
149 PyUnicode_GET_LENGTH(path));
150 if (tmp == NULL)
151 goto error;
152 self->prefix = tmp;
153 if (PyUnicode_READ_CHAR(path, len-1) != SEP) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000154 /* add trailing SEP */
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100155 tmp = PyUnicode_FromFormat("%U%c", self->prefix, SEP);
156 if (tmp == NULL)
157 goto error;
Serhiy Storchaka57a01d32016-04-10 18:05:40 +0300158 Py_SETREF(self->prefix, tmp);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000159 }
160 }
Victor Stinner2b8dab72010-08-14 14:54:10 +0000161 else
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100162 self->prefix = PyUnicode_New(0, 0);
163 Py_DECREF(path);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000164 return 0;
Victor Stinner2b8dab72010-08-14 14:54:10 +0000165
166error:
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100167 Py_DECREF(path);
168 Py_XDECREF(filename);
Victor Stinner2b8dab72010-08-14 14:54:10 +0000169 return -1;
Just van Rossum52e14d62002-12-30 22:08:05 +0000170}
171
172/* GC support. */
173static int
174zipimporter_traverse(PyObject *obj, visitproc visit, void *arg)
175{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000176 ZipImporter *self = (ZipImporter *)obj;
177 Py_VISIT(self->files);
178 return 0;
Just van Rossum52e14d62002-12-30 22:08:05 +0000179}
180
181static void
182zipimporter_dealloc(ZipImporter *self)
183{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000184 PyObject_GC_UnTrack(self);
185 Py_XDECREF(self->archive);
186 Py_XDECREF(self->prefix);
187 Py_XDECREF(self->files);
188 Py_TYPE(self)->tp_free((PyObject *)self);
Just van Rossum52e14d62002-12-30 22:08:05 +0000189}
190
191static PyObject *
192zipimporter_repr(ZipImporter *self)
193{
Victor Stinner028dd972010-08-17 00:04:48 +0000194 if (self->archive == NULL)
195 return PyUnicode_FromString("<zipimporter object \"???\">");
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200196 else if (self->prefix != NULL && PyUnicode_GET_LENGTH(self->prefix) != 0)
Victor Stinner07298a12010-10-18 22:45:54 +0000197 return PyUnicode_FromFormat("<zipimporter object \"%U%c%U\">",
Victor Stinner028dd972010-08-17 00:04:48 +0000198 self->archive, SEP, self->prefix);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000199 else
Victor Stinner07298a12010-10-18 22:45:54 +0000200 return PyUnicode_FromFormat("<zipimporter object \"%U\">",
Victor Stinner028dd972010-08-17 00:04:48 +0000201 self->archive);
Just van Rossum52e14d62002-12-30 22:08:05 +0000202}
203
204/* return fullname.split(".")[-1] */
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400205static PyObject *
206get_subname(PyObject *fullname)
Just van Rossum52e14d62002-12-30 22:08:05 +0000207{
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100208 Py_ssize_t len, dot;
209 if (PyUnicode_READY(fullname) < 0)
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200210 return NULL;
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100211 len = PyUnicode_GET_LENGTH(fullname);
212 dot = PyUnicode_FindChar(fullname, '.', 0, len, -1);
213 if (dot == -1) {
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400214 Py_INCREF(fullname);
215 return fullname;
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100216 } else
217 return PyUnicode_Substring(fullname, dot+1, len);
Just van Rossum52e14d62002-12-30 22:08:05 +0000218}
219
220/* Given a (sub)modulename, write the potential file path in the
221 archive (without extension) to the path buffer. Return the
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400222 length of the resulting string.
223
224 return self.prefix + name.replace('.', os.sep) */
225static PyObject*
226make_filename(PyObject *prefix, PyObject *name)
Just van Rossum52e14d62002-12-30 22:08:05 +0000227{
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400228 PyObject *pathobj;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200229 Py_UCS4 *p, *buf;
230 Py_ssize_t len;
Just van Rossum52e14d62002-12-30 22:08:05 +0000231
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200232 len = PyUnicode_GET_LENGTH(prefix) + PyUnicode_GET_LENGTH(name) + 1;
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +0200233 p = buf = PyMem_New(Py_UCS4, len);
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200234 if (buf == NULL) {
235 PyErr_NoMemory();
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400236 return NULL;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200237 }
Just van Rossum52e14d62002-12-30 22:08:05 +0000238
Christian Heimes1b5c76a2012-09-10 02:00:34 +0200239 if (!PyUnicode_AsUCS4(prefix, p, len, 0)) {
240 PyMem_Free(buf);
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200241 return NULL;
Christian Heimes1b5c76a2012-09-10 02:00:34 +0200242 }
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200243 p += PyUnicode_GET_LENGTH(prefix);
244 len -= PyUnicode_GET_LENGTH(prefix);
Christian Heimes1b5c76a2012-09-10 02:00:34 +0200245 if (!PyUnicode_AsUCS4(name, p, len, 1)) {
246 PyMem_Free(buf);
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200247 return NULL;
Christian Heimes1b5c76a2012-09-10 02:00:34 +0200248 }
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400249 for (; *p; p++) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000250 if (*p == '.')
251 *p = SEP;
252 }
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200253 pathobj = PyUnicode_FromKindAndData(PyUnicode_4BYTE_KIND,
254 buf, p-buf);
255 PyMem_Free(buf);
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400256 return pathobj;
Just van Rossum52e14d62002-12-30 22:08:05 +0000257}
258
Raymond Hettinger2c45c9a2004-11-10 13:08:35 +0000259enum zi_module_info {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000260 MI_ERROR,
261 MI_NOT_FOUND,
262 MI_MODULE,
263 MI_PACKAGE
Just van Rossum52e14d62002-12-30 22:08:05 +0000264};
265
Eric V. Smith984b11f2012-05-24 20:21:04 -0400266/* Does this path represent a directory?
267 on error, return < 0
268 if not a dir, return 0
269 if a dir, return 1
270*/
271static int
272check_is_directory(ZipImporter *self, PyObject* prefix, PyObject *path)
273{
274 PyObject *dirpath;
Benjamin Peterson18eac4a2012-05-25 00:24:42 -0700275 int res;
Eric V. Smith984b11f2012-05-24 20:21:04 -0400276
277 /* See if this is a "directory". If so, it's eligible to be part
278 of a namespace package. We test by seeing if the name, with an
279 appended path separator, exists. */
280 dirpath = PyUnicode_FromFormat("%U%U%c", prefix, path, SEP);
281 if (dirpath == NULL)
282 return -1;
283 /* If dirpath is present in self->files, we have a directory. */
Benjamin Peterson18eac4a2012-05-25 00:24:42 -0700284 res = PyDict_Contains(self->files, dirpath);
Eric V. Smith984b11f2012-05-24 20:21:04 -0400285 Py_DECREF(dirpath);
Benjamin Peterson18eac4a2012-05-25 00:24:42 -0700286 return res;
Eric V. Smith984b11f2012-05-24 20:21:04 -0400287}
288
Just van Rossum52e14d62002-12-30 22:08:05 +0000289/* Return some information about a module. */
Raymond Hettinger2c45c9a2004-11-10 13:08:35 +0000290static enum zi_module_info
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400291get_module_info(ZipImporter *self, PyObject *fullname)
Just van Rossum52e14d62002-12-30 22:08:05 +0000292{
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400293 PyObject *subname;
294 PyObject *path, *fullpath, *item;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000295 struct st_zip_searchorder *zso;
Just van Rossum52e14d62002-12-30 22:08:05 +0000296
Victor Stinner965a8a12010-10-18 21:44:33 +0000297 subname = get_subname(fullname);
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400298 if (subname == NULL)
299 return MI_ERROR;
Just van Rossum52e14d62002-12-30 22:08:05 +0000300
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400301 path = make_filename(self->prefix, subname);
302 Py_DECREF(subname);
303 if (path == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000304 return MI_ERROR;
Just van Rossum52e14d62002-12-30 22:08:05 +0000305
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000306 for (zso = zip_searchorder; *zso->suffix; zso++) {
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400307 fullpath = PyUnicode_FromFormat("%U%s", path, zso->suffix);
308 if (fullpath == NULL) {
309 Py_DECREF(path);
310 return MI_ERROR;
311 }
312 item = PyDict_GetItem(self->files, fullpath);
313 Py_DECREF(fullpath);
314 if (item != NULL) {
315 Py_DECREF(path);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000316 if (zso->type & IS_PACKAGE)
317 return MI_PACKAGE;
318 else
319 return MI_MODULE;
320 }
321 }
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400322 Py_DECREF(path);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000323 return MI_NOT_FOUND;
Just van Rossum52e14d62002-12-30 22:08:05 +0000324}
325
Benjamin Peterson5ed7bd72012-05-24 22:54:15 -0700326typedef enum {
Brett Cannon56aae8f2016-01-15 11:22:19 -0800327 FL_ERROR = -1, /* error */
328 FL_NOT_FOUND, /* no loader or namespace portions found */
329 FL_MODULE_FOUND, /* module/package found */
330 FL_NS_FOUND /* namespace portion found: */
331 /* *namespace_portion will point to the name */
Benjamin Peterson5ed7bd72012-05-24 22:54:15 -0700332} find_loader_result;
333
Brett Cannon56aae8f2016-01-15 11:22:19 -0800334/* The guts of "find_loader" and "find_module".
Eric V. Smith984b11f2012-05-24 20:21:04 -0400335*/
Benjamin Peterson5ed7bd72012-05-24 22:54:15 -0700336static find_loader_result
Eric V. Smith984b11f2012-05-24 20:21:04 -0400337find_loader(ZipImporter *self, PyObject *fullname, PyObject **namespace_portion)
338{
339 enum zi_module_info mi;
340
341 *namespace_portion = NULL;
342
343 mi = get_module_info(self, fullname);
344 if (mi == MI_ERROR)
Benjamin Peterson46c214d2012-05-25 10:22:29 -0700345 return FL_ERROR;
Eric V. Smith984b11f2012-05-24 20:21:04 -0400346 if (mi == MI_NOT_FOUND) {
347 /* Not a module or regular package. See if this is a directory, and
348 therefore possibly a portion of a namespace package. */
Brett Cannon56aae8f2016-01-15 11:22:19 -0800349 find_loader_result result = FL_NOT_FOUND;
350 PyObject *subname;
351 int is_dir;
352
353 /* We're only interested in the last path component of fullname;
354 earlier components are recorded in self->prefix. */
355 subname = get_subname(fullname);
356 if (subname == NULL) {
357 return FL_ERROR;
358 }
359
360 is_dir = check_is_directory(self, self->prefix, subname);
Eric V. Smith984b11f2012-05-24 20:21:04 -0400361 if (is_dir < 0)
Brett Cannon56aae8f2016-01-15 11:22:19 -0800362 result = FL_ERROR;
363 else if (is_dir) {
Eric V. Smith984b11f2012-05-24 20:21:04 -0400364 /* This is possibly a portion of a namespace
365 package. Return the string representing its path,
366 without a trailing separator. */
367 *namespace_portion = PyUnicode_FromFormat("%U%c%U%U",
368 self->archive, SEP,
Brett Cannon56aae8f2016-01-15 11:22:19 -0800369 self->prefix, subname);
Eric V. Smith984b11f2012-05-24 20:21:04 -0400370 if (*namespace_portion == NULL)
Brett Cannon56aae8f2016-01-15 11:22:19 -0800371 result = FL_ERROR;
372 else
373 result = FL_NS_FOUND;
Eric V. Smith984b11f2012-05-24 20:21:04 -0400374 }
Brett Cannon56aae8f2016-01-15 11:22:19 -0800375 Py_DECREF(subname);
376 return result;
Eric V. Smith984b11f2012-05-24 20:21:04 -0400377 }
378 /* This is a module or package. */
Benjamin Peterson46c214d2012-05-25 10:22:29 -0700379 return FL_MODULE_FOUND;
Eric V. Smith984b11f2012-05-24 20:21:04 -0400380}
381
382
Just van Rossum52e14d62002-12-30 22:08:05 +0000383/* Check whether we can satisfy the import of the module named by
384 'fullname'. Return self if we can, None if we can't. */
385static PyObject *
386zipimporter_find_module(PyObject *obj, PyObject *args)
387{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000388 ZipImporter *self = (ZipImporter *)obj;
389 PyObject *path = NULL;
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400390 PyObject *fullname;
Benjamin Peterson5ed7bd72012-05-24 22:54:15 -0700391 PyObject *namespace_portion = NULL;
392 PyObject *result = NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +0000393
Benjamin Peterson5ed7bd72012-05-24 22:54:15 -0700394 if (!PyArg_ParseTuple(args, "U|O:zipimporter.find_module", &fullname, &path))
395 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +0000396
Eric V. Smith984b11f2012-05-24 20:21:04 -0400397 switch (find_loader(self, fullname, &namespace_portion)) {
Benjamin Peterson46c214d2012-05-25 10:22:29 -0700398 case FL_ERROR:
Benjamin Petersona6a7a1a2012-05-25 00:22:04 -0700399 return NULL;
Benjamin Peterson46c214d2012-05-25 10:22:29 -0700400 case FL_NS_FOUND:
Benjamin Peterson5ed7bd72012-05-24 22:54:15 -0700401 /* A namespace portion is not allowed via find_module, so return None. */
Eric V. Smith984b11f2012-05-24 20:21:04 -0400402 Py_DECREF(namespace_portion);
Benjamin Peterson5ed7bd72012-05-24 22:54:15 -0700403 /* FALL THROUGH */
Benjamin Peterson46c214d2012-05-25 10:22:29 -0700404 case FL_NOT_FOUND:
Benjamin Peterson5ed7bd72012-05-24 22:54:15 -0700405 result = Py_None;
406 break;
Benjamin Peterson46c214d2012-05-25 10:22:29 -0700407 case FL_MODULE_FOUND:
Benjamin Peterson5ed7bd72012-05-24 22:54:15 -0700408 result = (PyObject *)self;
409 break;
Brett Cannon56aae8f2016-01-15 11:22:19 -0800410 default:
411 PyErr_BadInternalCall();
412 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000413 }
Benjamin Petersona6a7a1a2012-05-25 00:22:04 -0700414 Py_INCREF(result);
Benjamin Peterson2d12e142012-05-25 00:19:40 -0700415 return result;
Eric V. Smith984b11f2012-05-24 20:21:04 -0400416}
417
418
419/* Check whether we can satisfy the import of the module named by
420 'fullname', or whether it could be a portion of a namespace
421 package. Return self if we can load it, a string containing the
422 full path if it's a possible namespace portion, None if we
423 can't load it. */
424static PyObject *
425zipimporter_find_loader(PyObject *obj, PyObject *args)
426{
427 ZipImporter *self = (ZipImporter *)obj;
428 PyObject *path = NULL;
429 PyObject *fullname;
430 PyObject *result = NULL;
431 PyObject *namespace_portion = NULL;
432
Benjamin Peterson5ed7bd72012-05-24 22:54:15 -0700433 if (!PyArg_ParseTuple(args, "U|O:zipimporter.find_module", &fullname, &path))
434 return NULL;
Eric V. Smith984b11f2012-05-24 20:21:04 -0400435
436 switch (find_loader(self, fullname, &namespace_portion)) {
Benjamin Peterson46c214d2012-05-25 10:22:29 -0700437 case FL_ERROR:
Benjamin Peterson5ed7bd72012-05-24 22:54:15 -0700438 return NULL;
Benjamin Peterson46c214d2012-05-25 10:22:29 -0700439 case FL_NOT_FOUND: /* Not found, return (None, []) */
Benjamin Peterson5ed7bd72012-05-24 22:54:15 -0700440 result = Py_BuildValue("O[]", Py_None);
441 break;
Benjamin Peterson46c214d2012-05-25 10:22:29 -0700442 case FL_MODULE_FOUND: /* Return (self, []) */
Benjamin Peterson5ed7bd72012-05-24 22:54:15 -0700443 result = Py_BuildValue("O[]", self);
444 break;
Benjamin Peterson46c214d2012-05-25 10:22:29 -0700445 case FL_NS_FOUND: /* Return (None, [namespace_portion]) */
Benjamin Peterson5ed7bd72012-05-24 22:54:15 -0700446 result = Py_BuildValue("O[O]", Py_None, namespace_portion);
Benjamin Peterson209e04c2012-05-24 22:35:39 -0700447 Py_DECREF(namespace_portion);
Eric V. Smith984b11f2012-05-24 20:21:04 -0400448 return result;
Brett Cannon56aae8f2016-01-15 11:22:19 -0800449 default:
450 PyErr_BadInternalCall();
451 return NULL;
Eric V. Smith984b11f2012-05-24 20:21:04 -0400452 }
Benjamin Peterson5ed7bd72012-05-24 22:54:15 -0700453 return result;
Just van Rossum52e14d62002-12-30 22:08:05 +0000454}
455
456/* Load and return the module named by 'fullname'. */
457static PyObject *
458zipimporter_load_module(PyObject *obj, PyObject *args)
459{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000460 ZipImporter *self = (ZipImporter *)obj;
Victor Stinner26fabe12010-10-18 12:03:25 +0000461 PyObject *code = NULL, *mod, *dict;
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400462 PyObject *fullname;
463 PyObject *modpath = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000464 int ispackage;
Just van Rossum52e14d62002-12-30 22:08:05 +0000465
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400466 if (!PyArg_ParseTuple(args, "U:zipimporter.load_module",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000467 &fullname))
468 return NULL;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200469 if (PyUnicode_READY(fullname) == -1)
470 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +0000471
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000472 code = get_module_code(self, fullname, &ispackage, &modpath);
473 if (code == NULL)
Victor Stinner26fabe12010-10-18 12:03:25 +0000474 goto error;
Just van Rossum52e14d62002-12-30 22:08:05 +0000475
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400476 mod = PyImport_AddModuleObject(fullname);
Victor Stinner26fabe12010-10-18 12:03:25 +0000477 if (mod == NULL)
478 goto error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000479 dict = PyModule_GetDict(mod);
Just van Rossum52e14d62002-12-30 22:08:05 +0000480
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000481 /* mod.__loader__ = self */
482 if (PyDict_SetItemString(dict, "__loader__", (PyObject *)self) != 0)
483 goto error;
Just van Rossum52e14d62002-12-30 22:08:05 +0000484
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000485 if (ispackage) {
486 /* add __path__ to the module *before* the code gets
487 executed */
Victor Stinneraf8b7e82013-10-29 01:46:24 +0100488 PyObject *pkgpath, *fullpath, *subname;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000489 int err;
Just van Rossum52e14d62002-12-30 22:08:05 +0000490
Victor Stinneraf8b7e82013-10-29 01:46:24 +0100491 subname = get_subname(fullname);
492 if (subname == NULL)
493 goto error;
494
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400495 fullpath = PyUnicode_FromFormat("%U%c%U%U",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000496 self->archive, SEP,
497 self->prefix, subname);
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400498 Py_DECREF(subname);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000499 if (fullpath == NULL)
500 goto error;
Just van Rossum52e14d62002-12-30 22:08:05 +0000501
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400502 pkgpath = Py_BuildValue("[N]", fullpath);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000503 if (pkgpath == NULL)
504 goto error;
505 err = PyDict_SetItemString(dict, "__path__", pkgpath);
506 Py_DECREF(pkgpath);
507 if (err != 0)
508 goto error;
509 }
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400510 mod = PyImport_ExecCodeModuleObject(fullname, code, modpath, NULL);
Victor Stinner26fabe12010-10-18 12:03:25 +0000511 Py_CLEAR(code);
512 if (mod == NULL)
513 goto error;
514
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000515 if (Py_VerboseFlag)
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400516 PySys_FormatStderr("import %U # loaded from Zip %U\n",
Victor Stinner08654e12010-10-18 12:09:02 +0000517 fullname, modpath);
518 Py_DECREF(modpath);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000519 return mod;
Just van Rossum52e14d62002-12-30 22:08:05 +0000520error:
Victor Stinner26fabe12010-10-18 12:03:25 +0000521 Py_XDECREF(code);
Victor Stinner08654e12010-10-18 12:09:02 +0000522 Py_XDECREF(modpath);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000523 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +0000524}
525
Nick Coghlanf088e5e2008-12-14 11:50:48 +0000526/* Return a string matching __file__ for the named module */
527static PyObject *
528zipimporter_get_filename(PyObject *obj, PyObject *args)
529{
530 ZipImporter *self = (ZipImporter *)obj;
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400531 PyObject *fullname, *code, *modpath;
Nick Coghlanf088e5e2008-12-14 11:50:48 +0000532 int ispackage;
533
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400534 if (!PyArg_ParseTuple(args, "U:zipimporter.get_filename",
Victor Stinner9e40fad2010-10-18 22:34:46 +0000535 &fullname))
Victor Stinnerc342fca2010-10-18 11:39:05 +0000536 return NULL;
Nick Coghlanf088e5e2008-12-14 11:50:48 +0000537
538 /* Deciding the filename requires working out where the code
539 would come from if the module was actually loaded */
540 code = get_module_code(self, fullname, &ispackage, &modpath);
541 if (code == NULL)
Victor Stinnerc342fca2010-10-18 11:39:05 +0000542 return NULL;
Nick Coghlanf088e5e2008-12-14 11:50:48 +0000543 Py_DECREF(code); /* Only need the path info */
544
Victor Stinner08654e12010-10-18 12:09:02 +0000545 return modpath;
Nick Coghlanf088e5e2008-12-14 11:50:48 +0000546}
547
Just van Rossum52e14d62002-12-30 22:08:05 +0000548/* Return a bool signifying whether the module is a package or not. */
549static PyObject *
550zipimporter_is_package(PyObject *obj, PyObject *args)
551{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000552 ZipImporter *self = (ZipImporter *)obj;
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400553 PyObject *fullname;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000554 enum zi_module_info mi;
Just van Rossum52e14d62002-12-30 22:08:05 +0000555
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400556 if (!PyArg_ParseTuple(args, "U:zipimporter.is_package",
Victor Stinner965a8a12010-10-18 21:44:33 +0000557 &fullname))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000558 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +0000559
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000560 mi = get_module_info(self, fullname);
561 if (mi == MI_ERROR)
Victor Stinner965a8a12010-10-18 21:44:33 +0000562 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000563 if (mi == MI_NOT_FOUND) {
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400564 PyErr_Format(ZipImportError, "can't find module %R", fullname);
Victor Stinner965a8a12010-10-18 21:44:33 +0000565 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000566 }
567 return PyBool_FromLong(mi == MI_PACKAGE);
Just van Rossum52e14d62002-12-30 22:08:05 +0000568}
569
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200570
Just van Rossum52e14d62002-12-30 22:08:05 +0000571static PyObject *
572zipimporter_get_data(PyObject *obj, PyObject *args)
573{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000574 ZipImporter *self = (ZipImporter *)obj;
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100575 PyObject *path, *key;
Benjamin Peterson34c15402014-02-16 14:17:28 -0500576 PyObject *toc_entry;
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100577 Py_ssize_t path_start, path_len, len;
Just van Rossum52e14d62002-12-30 22:08:05 +0000578
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100579 if (!PyArg_ParseTuple(args, "U:zipimporter.get_data", &path))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000580 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +0000581
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200582#ifdef ALTSEP
Martin v. Löwiscfa61292011-10-31 09:01:22 +0100583 path = _PyObject_CallMethodId(path, &PyId_replace, "CC", ALTSEP, SEP);
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100584 if (!path)
585 return NULL;
586#else
587 Py_INCREF(path);
Just van Rossum52e14d62002-12-30 22:08:05 +0000588#endif
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100589 if (PyUnicode_READY(path) == -1)
590 goto error;
591
592 path_len = PyUnicode_GET_LENGTH(path);
593
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200594 len = PyUnicode_GET_LENGTH(self->archive);
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100595 path_start = 0;
596 if (PyUnicode_Tailmatch(path, self->archive, 0, len, -1)
597 && PyUnicode_READ_CHAR(path, len) == SEP) {
598 path_start = len + 1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000599 }
Just van Rossum52e14d62002-12-30 22:08:05 +0000600
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100601 key = PyUnicode_Substring(path, path_start, path_len);
Victor Stinner60fe8d92010-08-16 23:48:11 +0000602 if (key == NULL)
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100603 goto error;
Victor Stinner60fe8d92010-08-16 23:48:11 +0000604 toc_entry = PyDict_GetItem(self->files, key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000605 if (toc_entry == NULL) {
Victor Stinner60fe8d92010-08-16 23:48:11 +0000606 PyErr_SetFromErrnoWithFilenameObject(PyExc_IOError, key);
607 Py_DECREF(key);
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100608 goto error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000609 }
Victor Stinner60fe8d92010-08-16 23:48:11 +0000610 Py_DECREF(key);
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100611 Py_DECREF(path);
Benjamin Peterson34c15402014-02-16 14:17:28 -0500612 return get_data(self->archive, toc_entry);
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100613 error:
614 Py_DECREF(path);
615 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +0000616}
617
618static PyObject *
619zipimporter_get_code(PyObject *obj, PyObject *args)
620{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000621 ZipImporter *self = (ZipImporter *)obj;
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400622 PyObject *fullname;
Just van Rossum52e14d62002-12-30 22:08:05 +0000623
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400624 if (!PyArg_ParseTuple(args, "U:zipimporter.get_code", &fullname))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000625 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +0000626
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000627 return get_module_code(self, fullname, NULL, NULL);
Just van Rossum52e14d62002-12-30 22:08:05 +0000628}
629
630static PyObject *
631zipimporter_get_source(PyObject *obj, PyObject *args)
632{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000633 ZipImporter *self = (ZipImporter *)obj;
634 PyObject *toc_entry;
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400635 PyObject *fullname, *subname, *path, *fullpath;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000636 enum zi_module_info mi;
Just van Rossum52e14d62002-12-30 22:08:05 +0000637
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400638 if (!PyArg_ParseTuple(args, "U:zipimporter.get_source", &fullname))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000639 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +0000640
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000641 mi = get_module_info(self, fullname);
Victor Stinner965a8a12010-10-18 21:44:33 +0000642 if (mi == MI_ERROR)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000643 return NULL;
Victor Stinner04106562010-10-18 20:44:08 +0000644 if (mi == MI_NOT_FOUND) {
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400645 PyErr_Format(ZipImportError, "can't find module %R", fullname);
Victor Stinner04106562010-10-18 20:44:08 +0000646 return NULL;
647 }
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400648
Victor Stinner965a8a12010-10-18 21:44:33 +0000649 subname = get_subname(fullname);
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400650 if (subname == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000651 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +0000652
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400653 path = make_filename(self->prefix, subname);
654 Py_DECREF(subname);
655 if (path == NULL)
656 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +0000657
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400658 if (mi == MI_PACKAGE)
659 fullpath = PyUnicode_FromFormat("%U%c__init__.py", path, SEP);
660 else
661 fullpath = PyUnicode_FromFormat("%U.py", path);
662 Py_DECREF(path);
663 if (fullpath == NULL)
664 return NULL;
665
666 toc_entry = PyDict_GetItem(self->files, fullpath);
667 Py_DECREF(fullpath);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000668 if (toc_entry != NULL) {
Victor Stinner60fe8d92010-08-16 23:48:11 +0000669 PyObject *res, *bytes;
Benjamin Peterson34c15402014-02-16 14:17:28 -0500670 bytes = get_data(self->archive, toc_entry);
Victor Stinner60fe8d92010-08-16 23:48:11 +0000671 if (bytes == NULL)
672 return NULL;
673 res = PyUnicode_FromStringAndSize(PyBytes_AS_STRING(bytes),
674 PyBytes_GET_SIZE(bytes));
675 Py_DECREF(bytes);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000676 return res;
677 }
Just van Rossum52e14d62002-12-30 22:08:05 +0000678
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000679 /* we have the module, but no source */
Serhiy Storchaka228b12e2017-01-23 09:47:21 +0200680 Py_RETURN_NONE;
Just van Rossum52e14d62002-12-30 22:08:05 +0000681}
682
683PyDoc_STRVAR(doc_find_module,
684"find_module(fullname, path=None) -> self or None.\n\
685\n\
686Search for a module specified by 'fullname'. 'fullname' must be the\n\
687fully qualified (dotted) module name. It returns the zipimporter\n\
688instance itself if the module was found, or None if it wasn't.\n\
689The optional 'path' argument is ignored -- it's there for compatibility\n\
690with the importer protocol.");
691
Eric V. Smith984b11f2012-05-24 20:21:04 -0400692PyDoc_STRVAR(doc_find_loader,
693"find_loader(fullname, path=None) -> self, str or None.\n\
694\n\
695Search for a module specified by 'fullname'. 'fullname' must be the\n\
696fully qualified (dotted) module name. It returns the zipimporter\n\
697instance itself if the module was found, a string containing the\n\
698full path name if it's possibly a portion of a namespace package,\n\
699or None otherwise. The optional 'path' argument is ignored -- it's\n\
700 there for compatibility with the importer protocol.");
701
Just van Rossum52e14d62002-12-30 22:08:05 +0000702PyDoc_STRVAR(doc_load_module,
703"load_module(fullname) -> module.\n\
704\n\
705Load the module specified by 'fullname'. 'fullname' must be the\n\
706fully qualified (dotted) module name. It returns the imported\n\
707module, or raises ZipImportError if it wasn't found.");
708
709PyDoc_STRVAR(doc_get_data,
710"get_data(pathname) -> string with file data.\n\
711\n\
712Return the data associated with 'pathname'. Raise IOError if\n\
713the file wasn't found.");
714
715PyDoc_STRVAR(doc_is_package,
716"is_package(fullname) -> bool.\n\
717\n\
718Return True if the module specified by fullname is a package.\n\
Brian Curtin32839732010-07-21 01:44:19 +0000719Raise ZipImportError if the module couldn't be found.");
Just van Rossum52e14d62002-12-30 22:08:05 +0000720
721PyDoc_STRVAR(doc_get_code,
722"get_code(fullname) -> code object.\n\
723\n\
724Return the code object for the specified module. Raise ZipImportError\n\
Brian Curtin32839732010-07-21 01:44:19 +0000725if the module couldn't be found.");
Just van Rossum52e14d62002-12-30 22:08:05 +0000726
727PyDoc_STRVAR(doc_get_source,
728"get_source(fullname) -> source string.\n\
729\n\
730Return the source code for the specified module. Raise ZipImportError\n\
Brian Curtin32839732010-07-21 01:44:19 +0000731if the module couldn't be found, return None if the archive does\n\
Just van Rossum52e14d62002-12-30 22:08:05 +0000732contain the module, but has no source for it.");
733
Nick Coghlanf088e5e2008-12-14 11:50:48 +0000734
735PyDoc_STRVAR(doc_get_filename,
Nick Coghlan9a1d6e32009-02-08 03:37:27 +0000736"get_filename(fullname) -> filename string.\n\
Nick Coghlanf088e5e2008-12-14 11:50:48 +0000737\n\
738Return the filename for the specified module.");
739
Just van Rossum52e14d62002-12-30 22:08:05 +0000740static PyMethodDef zipimporter_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000741 {"find_module", zipimporter_find_module, METH_VARARGS,
742 doc_find_module},
Eric V. Smith984b11f2012-05-24 20:21:04 -0400743 {"find_loader", zipimporter_find_loader, METH_VARARGS,
744 doc_find_loader},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000745 {"load_module", zipimporter_load_module, METH_VARARGS,
746 doc_load_module},
747 {"get_data", zipimporter_get_data, METH_VARARGS,
748 doc_get_data},
749 {"get_code", zipimporter_get_code, METH_VARARGS,
750 doc_get_code},
751 {"get_source", zipimporter_get_source, METH_VARARGS,
752 doc_get_source},
753 {"get_filename", zipimporter_get_filename, METH_VARARGS,
754 doc_get_filename},
755 {"is_package", zipimporter_is_package, METH_VARARGS,
756 doc_is_package},
757 {NULL, NULL} /* sentinel */
Just van Rossum52e14d62002-12-30 22:08:05 +0000758};
759
760static PyMemberDef zipimporter_members[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000761 {"archive", T_OBJECT, offsetof(ZipImporter, archive), READONLY},
762 {"prefix", T_OBJECT, offsetof(ZipImporter, prefix), READONLY},
763 {"_files", T_OBJECT, offsetof(ZipImporter, files), READONLY},
764 {NULL}
Just van Rossum52e14d62002-12-30 22:08:05 +0000765};
766
767PyDoc_STRVAR(zipimporter_doc,
768"zipimporter(archivepath) -> zipimporter object\n\
769\n\
770Create a new zipimporter instance. 'archivepath' must be a path to\n\
Alexandre Vassalotti8ae3e052008-05-16 00:41:41 +0000771a zipfile, or to a specific path inside a zipfile. For example, it can be\n\
772'/tmp/myimport.zip', or '/tmp/myimport.zip/mydirectory', if mydirectory is a\n\
773valid directory inside the archive.\n\
774\n\
775'ZipImportError is raised if 'archivepath' doesn't point to a valid Zip\n\
776archive.\n\
777\n\
778The 'archive' attribute of zipimporter objects contains the name of the\n\
779zipfile targeted.");
Just van Rossum52e14d62002-12-30 22:08:05 +0000780
781#define DEFERRED_ADDRESS(ADDR) 0
782
783static PyTypeObject ZipImporter_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000784 PyVarObject_HEAD_INIT(DEFERRED_ADDRESS(&PyType_Type), 0)
785 "zipimport.zipimporter",
786 sizeof(ZipImporter),
787 0, /* tp_itemsize */
788 (destructor)zipimporter_dealloc, /* tp_dealloc */
789 0, /* tp_print */
790 0, /* tp_getattr */
791 0, /* tp_setattr */
792 0, /* tp_reserved */
793 (reprfunc)zipimporter_repr, /* tp_repr */
794 0, /* tp_as_number */
795 0, /* tp_as_sequence */
796 0, /* tp_as_mapping */
797 0, /* tp_hash */
798 0, /* tp_call */
799 0, /* tp_str */
800 PyObject_GenericGetAttr, /* tp_getattro */
801 0, /* tp_setattro */
802 0, /* tp_as_buffer */
803 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE |
804 Py_TPFLAGS_HAVE_GC, /* tp_flags */
805 zipimporter_doc, /* tp_doc */
806 zipimporter_traverse, /* tp_traverse */
807 0, /* tp_clear */
808 0, /* tp_richcompare */
809 0, /* tp_weaklistoffset */
810 0, /* tp_iter */
811 0, /* tp_iternext */
812 zipimporter_methods, /* tp_methods */
813 zipimporter_members, /* tp_members */
814 0, /* tp_getset */
815 0, /* tp_base */
816 0, /* tp_dict */
817 0, /* tp_descr_get */
818 0, /* tp_descr_set */
819 0, /* tp_dictoffset */
820 (initproc)zipimporter_init, /* tp_init */
821 PyType_GenericAlloc, /* tp_alloc */
822 PyType_GenericNew, /* tp_new */
823 PyObject_GC_Del, /* tp_free */
Just van Rossum52e14d62002-12-30 22:08:05 +0000824};
825
826
827/* implementation */
828
Serhiy Storchakad5db5732016-01-28 21:30:16 +0200829/* Given a buffer, return the unsigned int that is represented by the first
Just van Rossum52e14d62002-12-30 22:08:05 +0000830 4 bytes, encoded as little endian. This partially reimplements
831 marshal.c:r_long() */
Serhiy Storchakad5db5732016-01-28 21:30:16 +0200832static unsigned int
833get_uint32(const unsigned char *buf)
834{
835 unsigned int x;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000836 x = buf[0];
Serhiy Storchakad5db5732016-01-28 21:30:16 +0200837 x |= (unsigned int)buf[1] << 8;
838 x |= (unsigned int)buf[2] << 16;
839 x |= (unsigned int)buf[3] << 24;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000840 return x;
Just van Rossum52e14d62002-12-30 22:08:05 +0000841}
842
Serhiy Storchakad5db5732016-01-28 21:30:16 +0200843/* Given a buffer, return the unsigned int that is represented by the first
844 2 bytes, encoded as little endian. This partially reimplements
845 marshal.c:r_short() */
846static unsigned short
847get_uint16(const unsigned char *buf)
848{
849 unsigned short x;
850 x = buf[0];
851 x |= (unsigned short)buf[1] << 8;
852 return x;
853}
854
855static void
856set_file_error(PyObject *archive, int eof)
857{
858 if (eof) {
859 PyErr_SetString(PyExc_EOFError, "EOF read where not expected");
860 }
861 else {
862 PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, archive);
863 }
864}
865
Gregory P. Smith2bcbc142014-01-07 18:30:07 -0800866/*
Benjamin Peterson34c15402014-02-16 14:17:28 -0500867 read_directory(archive) -> files dict (new reference)
Gregory P. Smith2bcbc142014-01-07 18:30:07 -0800868
Benjamin Peterson34c15402014-02-16 14:17:28 -0500869 Given a path to a Zip archive, build a dict, mapping file names
Just van Rossum52e14d62002-12-30 22:08:05 +0000870 (local to the archive, using SEP as a separator) to toc entries.
871
872 A toc_entry is a tuple:
873
Victor Stinner08654e12010-10-18 12:09:02 +0000874 (__file__, # value to use for __file__, available for all files,
875 # encoded to the filesystem encoding
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000876 compress, # compression kind; 0 for uncompressed
877 data_size, # size of compressed data on disk
878 file_size, # size of decompressed data
879 file_offset, # offset of file header from start of archive
880 time, # mod time of file (in dos format)
881 date, # mod data of file (in dos format)
882 crc, # crc checksum of the data
Victor Stinnerc342fca2010-10-18 11:39:05 +0000883 )
Just van Rossum52e14d62002-12-30 22:08:05 +0000884
885 Directories can be recognized by the trailing SEP in the name,
886 data_size and file_offset are 0.
887*/
888static PyObject *
Benjamin Peterson34c15402014-02-16 14:17:28 -0500889read_directory(PyObject *archive)
Just van Rossum52e14d62002-12-30 22:08:05 +0000890{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000891 PyObject *files = NULL;
Benjamin Peterson34c15402014-02-16 14:17:28 -0500892 FILE *fp;
Serhiy Storchakad5db5732016-01-28 21:30:16 +0200893 unsigned short flags, compress, time, date, name_size;
894 unsigned int crc, data_size, file_size, header_size, header_offset;
895 unsigned long file_offset, header_position;
896 unsigned long arc_offset; /* Absolute offset to start of the zip-archive. */
897 unsigned int count, i;
898 unsigned char buffer[46];
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000899 char name[MAXPATHLEN + 5];
Victor Stinner2460a432010-08-16 17:54:28 +0000900 PyObject *nameobj = NULL;
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100901 PyObject *path;
Victor Stinnerd36c8212010-10-18 12:13:46 +0000902 const char *charset;
Victor Stinner4ee65a92011-01-22 10:30:29 +0000903 int bootstrap;
Serhiy Storchakad5db5732016-01-28 21:30:16 +0200904 const char *errmsg = NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +0000905
Benjamin Peterson34c15402014-02-16 14:17:28 -0500906 fp = _Py_fopen_obj(archive, "rb");
907 if (fp == NULL) {
Victor Stinnerfbd6f9e2015-03-20 10:52:25 +0100908 if (PyErr_ExceptionMatches(PyExc_OSError)) {
Serhiy Storchaka467ab192016-10-21 17:09:17 +0300909 _PyErr_FormatFromCause(ZipImportError,
910 "can't open Zip file: %R", archive);
Victor Stinnerfbd6f9e2015-03-20 10:52:25 +0100911 }
Benjamin Peterson34c15402014-02-16 14:17:28 -0500912 return NULL;
913 }
914
Jesus Cea09bf7a72012-10-03 02:13:05 +0200915 if (fseek(fp, -22, SEEK_END) == -1) {
Serhiy Storchakad5db5732016-01-28 21:30:16 +0200916 goto file_error;
Jesus Cea09bf7a72012-10-03 02:13:05 +0200917 }
Serhiy Storchakad5db5732016-01-28 21:30:16 +0200918 header_position = (unsigned long)ftell(fp);
919 if (header_position == (unsigned long)-1) {
920 goto file_error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000921 }
Serhiy Storchakad5db5732016-01-28 21:30:16 +0200922 assert(header_position <= (unsigned long)LONG_MAX);
923 if (fread(buffer, 1, 22, fp) != 22) {
924 goto file_error;
925 }
926 if (get_uint32(buffer) != 0x06054B50u) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000927 /* Bad: End of Central Dir signature */
Serhiy Storchakad5db5732016-01-28 21:30:16 +0200928 errmsg = "not a Zip file";
929 goto invalid_header;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000930 }
Just van Rossum52e14d62002-12-30 22:08:05 +0000931
Serhiy Storchakad5db5732016-01-28 21:30:16 +0200932 header_size = get_uint32(buffer + 12);
933 header_offset = get_uint32(buffer + 16);
934 if (header_position < header_size) {
935 errmsg = "bad central directory size";
936 goto invalid_header;
937 }
938 if (header_position < header_offset) {
939 errmsg = "bad central directory offset";
940 goto invalid_header;
941 }
942 if (header_position - header_size < header_offset) {
943 errmsg = "bad central directory size or offset";
944 goto invalid_header;
945 }
946 header_position -= header_size;
947 arc_offset = header_position - header_offset;
Just van Rossum52e14d62002-12-30 22:08:05 +0000948
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000949 files = PyDict_New();
Serhiy Storchakad5db5732016-01-28 21:30:16 +0200950 if (files == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000951 goto error;
Serhiy Storchakad5db5732016-01-28 21:30:16 +0200952 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000953 /* Start of Central Directory */
954 count = 0;
Serhiy Storchakad5db5732016-01-28 21:30:16 +0200955 if (fseek(fp, (long)header_position, 0) == -1) {
Serhiy Storchaka0e6b7b52013-02-16 17:43:45 +0200956 goto file_error;
Serhiy Storchakad5db5732016-01-28 21:30:16 +0200957 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000958 for (;;) {
959 PyObject *t;
Serhiy Storchakad5db5732016-01-28 21:30:16 +0200960 size_t n;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000961 int err;
Just van Rossum52e14d62002-12-30 22:08:05 +0000962
Serhiy Storchakad5db5732016-01-28 21:30:16 +0200963 n = fread(buffer, 1, 46, fp);
964 if (n < 4) {
965 goto eof_error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000966 }
Serhiy Storchakad5db5732016-01-28 21:30:16 +0200967 /* Start of file header */
968 if (get_uint32(buffer) != 0x02014B50u) {
969 break; /* Bad: Central Dir File Header */
970 }
971 if (n != 46) {
972 goto eof_error;
973 }
974 flags = get_uint16(buffer + 8);
975 compress = get_uint16(buffer + 10);
976 time = get_uint16(buffer + 12);
977 date = get_uint16(buffer + 14);
978 crc = get_uint32(buffer + 16);
979 data_size = get_uint32(buffer + 20);
980 file_size = get_uint32(buffer + 24);
981 name_size = get_uint16(buffer + 28);
982 header_size = (unsigned int)name_size +
983 get_uint16(buffer + 30) /* extra field */ +
984 get_uint16(buffer + 32) /* comment */;
985
986 file_offset = get_uint32(buffer + 42);
987 if (file_offset > header_offset) {
988 errmsg = "bad local header offset";
989 goto invalid_header;
990 }
991 file_offset += arc_offset;
992
993 if (name_size > MAXPATHLEN) {
994 name_size = MAXPATHLEN;
995 }
996 if (fread(name, 1, name_size, fp) != name_size) {
997 goto file_error;
998 }
999 name[name_size] = '\0'; /* Add terminating null byte */
Victor Stinner44d9bea2016-12-05 17:55:36 +01001000#if SEP != '/'
1001 for (i = 0; i < name_size; i++) {
1002 if (name[i] == '/') {
1003 name[i] = SEP;
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001004 }
1005 }
Victor Stinner44d9bea2016-12-05 17:55:36 +01001006#endif
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001007 /* Skip the rest of the header.
1008 * On Windows, calling fseek to skip over the fields we don't use is
1009 * slower than reading the data because fseek flushes stdio's
1010 * internal buffers. See issue #8745. */
1011 assert(header_size <= 3*0xFFFFu);
1012 for (i = name_size; i < header_size; i++) {
1013 if (getc(fp) == EOF) {
Serhiy Storchaka0e6b7b52013-02-16 17:43:45 +02001014 goto file_error;
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001015 }
1016 }
Just van Rossum52e14d62002-12-30 22:08:05 +00001017
Victor Stinner4ee65a92011-01-22 10:30:29 +00001018 bootstrap = 0;
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001019 if (flags & 0x0800) {
Victor Stinnerd36c8212010-10-18 12:13:46 +00001020 charset = "utf-8";
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001021 }
Victor Stinner4ee65a92011-01-22 10:30:29 +00001022 else if (!PyThreadState_GET()->interp->codecs_initialized) {
1023 /* During bootstrap, we may need to load the encodings
1024 package from a ZIP file. But the cp437 encoding is implemented
1025 in Python in the encodings package.
1026
1027 Break out of this dependency by assuming that the path to
1028 the encodings module is ASCII-only. */
1029 charset = "ascii";
1030 bootstrap = 1;
1031 }
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001032 else {
Victor Stinnerd36c8212010-10-18 12:13:46 +00001033 charset = "cp437";
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001034 }
Victor Stinnerd36c8212010-10-18 12:13:46 +00001035 nameobj = PyUnicode_Decode(name, name_size, charset, NULL);
Victor Stinner4ee65a92011-01-22 10:30:29 +00001036 if (nameobj == NULL) {
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001037 if (bootstrap) {
Victor Stinner4ee65a92011-01-22 10:30:29 +00001038 PyErr_Format(PyExc_NotImplementedError,
1039 "bootstrap issue: python%i%i.zip contains non-ASCII "
1040 "filenames without the unicode flag",
1041 PY_MAJOR_VERSION, PY_MINOR_VERSION);
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001042 }
Victor Stinner2460a432010-08-16 17:54:28 +00001043 goto error;
Victor Stinner4ee65a92011-01-22 10:30:29 +00001044 }
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001045 if (PyUnicode_READY(nameobj) == -1) {
Stefan Krah000fde92012-08-20 14:14:49 +02001046 goto error;
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001047 }
Martin v. Löwisa72e78b2011-10-31 08:33:37 +01001048 path = PyUnicode_FromFormat("%U%c%U", archive, SEP, nameobj);
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001049 if (path == NULL) {
Victor Stinner2460a432010-08-16 17:54:28 +00001050 goto error;
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001051 }
1052 t = Py_BuildValue("NHIIkHHI", path, compress, data_size,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001053 file_size, file_offset, time, date, crc);
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001054 if (t == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001055 goto error;
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001056 }
Victor Stinner2460a432010-08-16 17:54:28 +00001057 err = PyDict_SetItem(files, nameobj, t);
1058 Py_CLEAR(nameobj);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001059 Py_DECREF(t);
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001060 if (err != 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001061 goto error;
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001062 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001063 count++;
1064 }
Benjamin Peterson34c15402014-02-16 14:17:28 -05001065 fclose(fp);
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001066 if (Py_VerboseFlag) {
1067 PySys_FormatStderr("# zipimport: found %u names in %R\n",
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001068 count, archive);
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001069 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001070 return files;
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001071
1072eof_error:
1073 set_file_error(archive, !ferror(fp));
1074 goto error;
1075
Serhiy Storchaka0e6b7b52013-02-16 17:43:45 +02001076file_error:
Jesus Cea09bf7a72012-10-03 02:13:05 +02001077 PyErr_Format(ZipImportError, "can't read Zip file: %R", archive);
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001078 goto error;
1079
1080invalid_header:
1081 assert(errmsg != NULL);
1082 PyErr_Format(ZipImportError, "%s: %R", errmsg, archive);
1083 goto error;
1084
Just van Rossum52e14d62002-12-30 22:08:05 +00001085error:
Benjamin Peterson34c15402014-02-16 14:17:28 -05001086 fclose(fp);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001087 Py_XDECREF(files);
Victor Stinner2460a432010-08-16 17:54:28 +00001088 Py_XDECREF(nameobj);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001089 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +00001090}
1091
1092/* Return the zlib.decompress function object, or NULL if zlib couldn't
1093 be imported. The function is cached when found, so subsequent calls
Victor Stinner4925cde2011-05-20 00:16:09 +02001094 don't import zlib again. */
Just van Rossum52e14d62002-12-30 22:08:05 +00001095static PyObject *
1096get_decompress_func(void)
1097{
Victor Stinner4925cde2011-05-20 00:16:09 +02001098 static int importing_zlib = 0;
1099 PyObject *zlib;
1100 PyObject *decompress;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02001101 _Py_IDENTIFIER(decompress);
Just van Rossum52e14d62002-12-30 22:08:05 +00001102
Victor Stinner4925cde2011-05-20 00:16:09 +02001103 if (importing_zlib != 0)
1104 /* Someone has a zlib.py[co] in their Zip file;
1105 let's avoid a stack overflow. */
1106 return NULL;
1107 importing_zlib = 1;
1108 zlib = PyImport_ImportModuleNoBlock("zlib");
1109 importing_zlib = 0;
1110 if (zlib != NULL) {
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02001111 decompress = _PyObject_GetAttrId(zlib,
1112 &PyId_decompress);
Victor Stinner4925cde2011-05-20 00:16:09 +02001113 Py_DECREF(zlib);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001114 }
Victor Stinner4925cde2011-05-20 00:16:09 +02001115 else {
1116 PyErr_Clear();
1117 decompress = NULL;
1118 }
1119 if (Py_VerboseFlag)
1120 PySys_WriteStderr("# zipimport: zlib %s\n",
1121 zlib != NULL ? "available": "UNAVAILABLE");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001122 return decompress;
Just van Rossum52e14d62002-12-30 22:08:05 +00001123}
1124
Benjamin Peterson34c15402014-02-16 14:17:28 -05001125/* Given a path to a Zip file and a toc_entry, return the (uncompressed)
Just van Rossum52e14d62002-12-30 22:08:05 +00001126 data as a new reference. */
1127static PyObject *
Benjamin Peterson34c15402014-02-16 14:17:28 -05001128get_data(PyObject *archive, PyObject *toc_entry)
Just van Rossum52e14d62002-12-30 22:08:05 +00001129{
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001130 PyObject *raw_data = NULL, *data, *decompress;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001131 char *buf;
Benjamin Peterson34c15402014-02-16 14:17:28 -05001132 FILE *fp;
Victor Stinner60fe8d92010-08-16 23:48:11 +00001133 PyObject *datapath;
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001134 unsigned short compress, time, date;
1135 unsigned int crc;
1136 Py_ssize_t data_size, file_size, bytes_size;
1137 long file_offset, header_size;
1138 unsigned char buffer[30];
1139 const char *errmsg = NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +00001140
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001141 if (!PyArg_ParseTuple(toc_entry, "OHnnlHHI", &datapath, &compress,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001142 &data_size, &file_size, &file_offset, &time,
1143 &date, &crc)) {
1144 return NULL;
1145 }
Benjamin Petersonb1db7582016-01-21 22:02:46 -08001146 if (data_size < 0) {
1147 PyErr_Format(ZipImportError, "negative data size");
1148 return NULL;
1149 }
Just van Rossum52e14d62002-12-30 22:08:05 +00001150
Benjamin Peterson34c15402014-02-16 14:17:28 -05001151 fp = _Py_fopen_obj(archive, "rb");
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001152 if (!fp) {
Benjamin Peterson34c15402014-02-16 14:17:28 -05001153 return NULL;
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001154 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001155 /* Check to make sure the local file header is correct */
Jesus Cea09bf7a72012-10-03 02:13:05 +02001156 if (fseek(fp, file_offset, 0) == -1) {
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001157 goto file_error;
Jesus Cea09bf7a72012-10-03 02:13:05 +02001158 }
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001159 if (fread(buffer, 1, 30, fp) != 30) {
1160 goto eof_error;
1161 }
1162 if (get_uint32(buffer) != 0x04034B50u) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001163 /* Bad: Local File Header */
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001164 errmsg = "bad local file header";
1165 goto invalid_header;
Jesus Cea09bf7a72012-10-03 02:13:05 +02001166 }
1167
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001168 header_size = (unsigned int)30 +
1169 get_uint16(buffer + 26) /* file name */ +
1170 get_uint16(buffer + 28) /* extra field */;
1171 if (file_offset > LONG_MAX - header_size) {
1172 errmsg = "bad local file header size";
1173 goto invalid_header;
Victor Stinner73660af2013-10-29 01:43:44 +01001174 }
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001175 file_offset += header_size; /* Start of file data */
Just van Rossum52e14d62002-12-30 22:08:05 +00001176
Benjamin Petersonc4032da2016-01-20 22:23:44 -08001177 if (data_size > LONG_MAX - 1) {
1178 fclose(fp);
1179 PyErr_NoMemory();
1180 return NULL;
1181 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001182 bytes_size = compress == 0 ? data_size : data_size + 1;
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001183 if (bytes_size == 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001184 bytes_size++;
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001185 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001186 raw_data = PyBytes_FromStringAndSize((char *)NULL, bytes_size);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001187 if (raw_data == NULL) {
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001188 goto error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001189 }
1190 buf = PyBytes_AsString(raw_data);
Just van Rossum52e14d62002-12-30 22:08:05 +00001191
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001192 if (fseek(fp, file_offset, 0) == -1) {
1193 goto file_error;
Jesus Cea09bf7a72012-10-03 02:13:05 +02001194 }
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001195 if (fread(buf, 1, data_size, fp) != (size_t)data_size) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001196 PyErr_SetString(PyExc_IOError,
1197 "zipimport: can't read data");
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001198 goto error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001199 }
Just van Rossum52e14d62002-12-30 22:08:05 +00001200
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001201 fclose(fp);
1202 fp = NULL;
1203
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001204 if (compress != 0) {
1205 buf[data_size] = 'Z'; /* saw this in zipfile.py */
1206 data_size++;
1207 }
1208 buf[data_size] = '\0';
Just van Rossum52e14d62002-12-30 22:08:05 +00001209
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001210 if (compress == 0) { /* data is not compressed */
1211 data = PyBytes_FromStringAndSize(buf, data_size);
1212 Py_DECREF(raw_data);
1213 return data;
1214 }
1215
1216 /* Decompress with zlib */
1217 decompress = get_decompress_func();
1218 if (decompress == NULL) {
1219 PyErr_SetString(ZipImportError,
1220 "can't decompress data; "
1221 "zlib not available");
1222 goto error;
1223 }
1224 data = PyObject_CallFunction(decompress, "Oi", raw_data, -15);
Victor Stinner4925cde2011-05-20 00:16:09 +02001225 Py_DECREF(decompress);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001226 Py_DECREF(raw_data);
1227 return data;
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001228
1229eof_error:
1230 set_file_error(archive, !ferror(fp));
1231 goto error;
1232
1233file_error:
1234 PyErr_Format(ZipImportError, "can't read Zip file: %R", archive);
1235 goto error;
1236
1237invalid_header:
1238 assert(errmsg != NULL);
1239 PyErr_Format(ZipImportError, "%s: %R", errmsg, archive);
1240 goto error;
1241
1242error:
1243 if (fp != NULL) {
1244 fclose(fp);
1245 }
1246 Py_XDECREF(raw_data);
1247 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +00001248}
1249
1250/* Lenient date/time comparison function. The precision of the mtime
1251 in the archive is lower than the mtime stored in a .pyc: we
1252 must allow a difference of at most one second. */
1253static int
1254eq_mtime(time_t t1, time_t t2)
1255{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001256 time_t d = t1 - t2;
1257 if (d < 0)
1258 d = -d;
1259 /* dostime only stores even seconds, so be lenient */
1260 return d <= 1;
Just van Rossum52e14d62002-12-30 22:08:05 +00001261}
1262
1263/* Given the contents of a .py[co] file in a buffer, unmarshal the data
1264 and return the code object. Return None if it the magic word doesn't
1265 match (we do this instead of raising an exception as we fall back
1266 to .py if available and we don't want to mask other errors).
1267 Returns a new reference. */
1268static PyObject *
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001269unmarshal_code(PyObject *pathname, PyObject *data, time_t mtime)
Just van Rossum52e14d62002-12-30 22:08:05 +00001270{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001271 PyObject *code;
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001272 unsigned char *buf = (unsigned char *)PyBytes_AsString(data);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001273 Py_ssize_t size = PyBytes_Size(data);
Just van Rossum52e14d62002-12-30 22:08:05 +00001274
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001275 if (size < 12) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001276 PyErr_SetString(ZipImportError,
1277 "bad pyc data");
1278 return NULL;
1279 }
Just van Rossum52e14d62002-12-30 22:08:05 +00001280
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001281 if (get_uint32(buf) != (unsigned int)PyImport_GetMagicNumber()) {
1282 if (Py_VerboseFlag) {
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001283 PySys_FormatStderr("# %R has bad magic\n",
1284 pathname);
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001285 }
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02001286 Py_RETURN_NONE; /* signal caller to try alternative */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001287 }
Just van Rossum52e14d62002-12-30 22:08:05 +00001288
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001289 if (mtime != 0 && !eq_mtime(get_uint32(buf + 4), mtime)) {
1290 if (Py_VerboseFlag) {
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001291 PySys_FormatStderr("# %R has bad mtime\n",
1292 pathname);
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001293 }
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02001294 Py_RETURN_NONE; /* signal caller to try alternative */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001295 }
Just van Rossum52e14d62002-12-30 22:08:05 +00001296
Antoine Pitrou5136ac02012-01-13 18:52:16 +01001297 /* XXX the pyc's size field is ignored; timestamp collisions are probably
1298 unimportant with zip files. */
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001299 code = PyMarshal_ReadObjectFromString((char *)buf + 12, size - 12);
1300 if (code == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001301 return NULL;
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001302 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001303 if (!PyCode_Check(code)) {
1304 Py_DECREF(code);
1305 PyErr_Format(PyExc_TypeError,
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001306 "compiled module %R is not a code object",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001307 pathname);
1308 return NULL;
1309 }
1310 return code;
Just van Rossum52e14d62002-12-30 22:08:05 +00001311}
1312
Martin Panter0be894b2016-09-07 12:03:06 +00001313/* Replace any occurrences of "\r\n?" in the input string with "\n".
Just van Rossum52e14d62002-12-30 22:08:05 +00001314 This converts DOS and Mac line endings to Unix line endings.
1315 Also append a trailing "\n" to be compatible with
1316 PyParser_SimpleParseFile(). Returns a new reference. */
1317static PyObject *
1318normalize_line_endings(PyObject *source)
1319{
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001320 char *buf, *q, *p;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001321 PyObject *fixed_source;
1322 int len = 0;
Just van Rossum52e14d62002-12-30 22:08:05 +00001323
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001324 p = PyBytes_AsString(source);
1325 if (p == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001326 return PyBytes_FromStringAndSize("\n\0", 2);
1327 }
Thomas Wouters00ee7ba2006-08-21 19:07:27 +00001328
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001329 /* one char extra for trailing \n and one for terminating \0 */
1330 buf = (char *)PyMem_Malloc(PyBytes_Size(source) + 2);
1331 if (buf == NULL) {
1332 PyErr_SetString(PyExc_MemoryError,
1333 "zipimport: no memory to allocate "
1334 "source buffer");
1335 return NULL;
1336 }
1337 /* replace "\r\n?" by "\n" */
1338 for (q = buf; *p != '\0'; p++) {
1339 if (*p == '\r') {
1340 *q++ = '\n';
1341 if (*(p + 1) == '\n')
1342 p++;
1343 }
1344 else
1345 *q++ = *p;
1346 len++;
1347 }
1348 *q++ = '\n'; /* add trailing \n */
1349 *q = '\0';
1350 fixed_source = PyBytes_FromStringAndSize(buf, len + 2);
1351 PyMem_Free(buf);
1352 return fixed_source;
Just van Rossum52e14d62002-12-30 22:08:05 +00001353}
1354
1355/* Given a string buffer containing Python source code, compile it
Brett Cannon83358c92013-06-20 21:30:32 -04001356 and return a code object as a new reference. */
Just van Rossum52e14d62002-12-30 22:08:05 +00001357static PyObject *
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001358compile_source(PyObject *pathname, PyObject *source)
Just van Rossum52e14d62002-12-30 22:08:05 +00001359{
Steve Dower8dcc48e2016-09-09 17:27:33 -07001360 PyObject *code, *fixed_source;
Just van Rossum52e14d62002-12-30 22:08:05 +00001361
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001362 fixed_source = normalize_line_endings(source);
1363 if (fixed_source == NULL) {
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001364 return NULL;
1365 }
1366
Steve Dower8dcc48e2016-09-09 17:27:33 -07001367 code = Py_CompileStringObject(PyBytes_AsString(fixed_source),
Berker Peksag4aa74c42016-09-14 08:09:48 +03001368 pathname, Py_file_input, NULL, -1);
Steve Dower8dcc48e2016-09-09 17:27:33 -07001369
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001370 Py_DECREF(fixed_source);
1371 return code;
Just van Rossum52e14d62002-12-30 22:08:05 +00001372}
1373
1374/* Convert the date/time values found in the Zip archive to a value
1375 that's compatible with the time stamp stored in .pyc files. */
Neal Norwitz29fd2ba2003-03-23 13:21:03 +00001376static time_t
1377parse_dostime(int dostime, int dosdate)
Just van Rossum52e14d62002-12-30 22:08:05 +00001378{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001379 struct tm stm;
Just van Rossum52e14d62002-12-30 22:08:05 +00001380
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001381 memset((void *) &stm, '\0', sizeof(stm));
Christian Heimes679db4a2008-01-18 09:56:22 +00001382
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001383 stm.tm_sec = (dostime & 0x1f) * 2;
1384 stm.tm_min = (dostime >> 5) & 0x3f;
1385 stm.tm_hour = (dostime >> 11) & 0x1f;
1386 stm.tm_mday = dosdate & 0x1f;
1387 stm.tm_mon = ((dosdate >> 5) & 0x0f) - 1;
1388 stm.tm_year = ((dosdate >> 9) & 0x7f) + 80;
1389 stm.tm_isdst = -1; /* wday/yday is ignored */
Just van Rossum52e14d62002-12-30 22:08:05 +00001390
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001391 return mktime(&stm);
Just van Rossum52e14d62002-12-30 22:08:05 +00001392}
1393
Brett Cannonf299abd2015-04-13 14:21:02 -04001394/* Given a path to a .pyc file in the archive, return the
Ezio Melotti13925002011-03-16 11:05:33 +02001395 modification time of the matching .py file, or 0 if no source
Just van Rossum52e14d62002-12-30 22:08:05 +00001396 is available. */
1397static time_t
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001398get_mtime_of_source(ZipImporter *self, PyObject *path)
Just van Rossum52e14d62002-12-30 22:08:05 +00001399{
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001400 PyObject *toc_entry, *stripped;
1401 time_t mtime;
1402
1403 /* strip 'c' or 'o' from *.py[co] */
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001404 if (PyUnicode_READY(path) == -1)
1405 return (time_t)-1;
1406 stripped = PyUnicode_FromKindAndData(PyUnicode_KIND(path),
1407 PyUnicode_DATA(path),
1408 PyUnicode_GET_LENGTH(path) - 1);
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001409 if (stripped == NULL)
1410 return (time_t)-1;
1411
1412 toc_entry = PyDict_GetItem(self->files, stripped);
1413 Py_DECREF(stripped);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001414 if (toc_entry != NULL && PyTuple_Check(toc_entry) &&
1415 PyTuple_Size(toc_entry) == 8) {
1416 /* fetch the time stamp of the .py file for comparison
1417 with an embedded pyc time stamp */
1418 int time, date;
1419 time = PyLong_AsLong(PyTuple_GetItem(toc_entry, 5));
1420 date = PyLong_AsLong(PyTuple_GetItem(toc_entry, 6));
1421 mtime = parse_dostime(time, date);
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001422 } else
1423 mtime = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001424 return mtime;
Just van Rossum52e14d62002-12-30 22:08:05 +00001425}
1426
1427/* Return the code object for the module named by 'fullname' from the
1428 Zip archive as a new reference. */
1429static PyObject *
Benjamin Peterson34c15402014-02-16 14:17:28 -05001430get_code_from_data(ZipImporter *self, int ispackage, int isbytecode,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001431 time_t mtime, PyObject *toc_entry)
Just van Rossum52e14d62002-12-30 22:08:05 +00001432{
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001433 PyObject *data, *modpath, *code;
Just van Rossum52e14d62002-12-30 22:08:05 +00001434
Benjamin Peterson34c15402014-02-16 14:17:28 -05001435 data = get_data(self->archive, toc_entry);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001436 if (data == NULL)
1437 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +00001438
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001439 modpath = PyTuple_GetItem(toc_entry, 0);
Victor Stinner2a94f4c2010-10-18 12:15:34 +00001440 if (isbytecode)
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001441 code = unmarshal_code(modpath, data, mtime);
Victor Stinner2a94f4c2010-10-18 12:15:34 +00001442 else
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001443 code = compile_source(modpath, data);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001444 Py_DECREF(data);
1445 return code;
Just van Rossum52e14d62002-12-30 22:08:05 +00001446}
1447
Ezio Melotti42da6632011-03-15 05:18:48 +02001448/* Get the code object associated with the module specified by
Just van Rossum52e14d62002-12-30 22:08:05 +00001449 'fullname'. */
1450static PyObject *
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001451get_module_code(ZipImporter *self, PyObject *fullname,
Victor Stinner08654e12010-10-18 12:09:02 +00001452 int *p_ispackage, PyObject **p_modpath)
Just van Rossum52e14d62002-12-30 22:08:05 +00001453{
Gregory P. Smith95c7c462011-05-21 05:19:42 -07001454 PyObject *code = NULL, *toc_entry, *subname;
Victor Stinner9a2261a2011-05-26 13:59:41 +02001455 PyObject *path, *fullpath = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001456 struct st_zip_searchorder *zso;
Just van Rossum52e14d62002-12-30 22:08:05 +00001457
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001458 subname = get_subname(fullname);
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001459 if (subname == NULL)
1460 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +00001461
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001462 path = make_filename(self->prefix, subname);
1463 Py_DECREF(subname);
1464 if (path == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001465 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +00001466
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001467 for (zso = zip_searchorder; *zso->suffix; zso++) {
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001468 code = NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +00001469
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001470 fullpath = PyUnicode_FromFormat("%U%s", path, zso->suffix);
1471 if (fullpath == NULL)
1472 goto exit;
1473
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001474 if (Py_VerboseFlag > 1)
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001475 PySys_FormatStderr("# trying %U%c%U\n",
1476 self->archive, (int)SEP, fullpath);
1477 toc_entry = PyDict_GetItem(self->files, fullpath);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001478 if (toc_entry != NULL) {
1479 time_t mtime = 0;
1480 int ispackage = zso->type & IS_PACKAGE;
1481 int isbytecode = zso->type & IS_BYTECODE;
Just van Rossum52e14d62002-12-30 22:08:05 +00001482
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001483 if (isbytecode) {
1484 mtime = get_mtime_of_source(self, fullpath);
1485 if (mtime == (time_t)-1 && PyErr_Occurred()) {
1486 goto exit;
1487 }
1488 }
1489 Py_CLEAR(fullpath);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001490 if (p_ispackage != NULL)
1491 *p_ispackage = ispackage;
Benjamin Peterson34c15402014-02-16 14:17:28 -05001492 code = get_code_from_data(self, ispackage,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001493 isbytecode, mtime,
1494 toc_entry);
1495 if (code == Py_None) {
1496 /* bad magic number or non-matching mtime
1497 in byte code, try next */
1498 Py_DECREF(code);
1499 continue;
1500 }
Victor Stinner08654e12010-10-18 12:09:02 +00001501 if (code != NULL && p_modpath != NULL) {
1502 *p_modpath = PyTuple_GetItem(toc_entry, 0);
1503 Py_INCREF(*p_modpath);
1504 }
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001505 goto exit;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001506 }
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001507 else
1508 Py_CLEAR(fullpath);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001509 }
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001510 PyErr_Format(ZipImportError, "can't find module %R", fullname);
1511exit:
1512 Py_DECREF(path);
1513 Py_XDECREF(fullpath);
1514 return code;
Just van Rossum52e14d62002-12-30 22:08:05 +00001515}
1516
1517
1518/* Module init */
1519
1520PyDoc_STRVAR(zipimport_doc,
1521"zipimport provides support for importing Python modules from Zip archives.\n\
1522\n\
1523This module exports three objects:\n\
1524- zipimporter: a class; its constructor takes a path to a Zip archive.\n\
Fredrik Lundhb84b35f2006-01-15 15:00:40 +00001525- ZipImportError: exception raised by zipimporter objects. It's a\n\
Just van Rossum52e14d62002-12-30 22:08:05 +00001526 subclass of ImportError, so it can be caught as ImportError, too.\n\
1527- _zip_directory_cache: a dict, mapping archive paths to zip directory\n\
1528 info dicts, as used in zipimporter._files.\n\
1529\n\
1530It is usually not needed to use the zipimport module explicitly; it is\n\
1531used by the builtin import mechanism for sys.path items that are paths\n\
1532to Zip archives.");
1533
Martin v. Löwis1a214512008-06-11 05:26:20 +00001534static struct PyModuleDef zipimportmodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001535 PyModuleDef_HEAD_INIT,
1536 "zipimport",
1537 zipimport_doc,
1538 -1,
1539 NULL,
1540 NULL,
1541 NULL,
1542 NULL,
1543 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +00001544};
1545
Just van Rossum52e14d62002-12-30 22:08:05 +00001546PyMODINIT_FUNC
Martin v. Löwis1a214512008-06-11 05:26:20 +00001547PyInit_zipimport(void)
Just van Rossum52e14d62002-12-30 22:08:05 +00001548{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001549 PyObject *mod;
Just van Rossum52e14d62002-12-30 22:08:05 +00001550
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001551 if (PyType_Ready(&ZipImporter_Type) < 0)
1552 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +00001553
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001554 /* Correct directory separator */
1555 zip_searchorder[0].suffix[0] = SEP;
1556 zip_searchorder[1].suffix[0] = SEP;
Just van Rossum52e14d62002-12-30 22:08:05 +00001557
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001558 mod = PyModule_Create(&zipimportmodule);
1559 if (mod == NULL)
1560 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +00001561
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001562 ZipImportError = PyErr_NewException("zipimport.ZipImportError",
1563 PyExc_ImportError, NULL);
1564 if (ZipImportError == NULL)
1565 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +00001566
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001567 Py_INCREF(ZipImportError);
1568 if (PyModule_AddObject(mod, "ZipImportError",
1569 ZipImportError) < 0)
1570 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +00001571
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001572 Py_INCREF(&ZipImporter_Type);
1573 if (PyModule_AddObject(mod, "zipimporter",
1574 (PyObject *)&ZipImporter_Type) < 0)
1575 return NULL;
Just van Rossumf8b6de12002-12-31 09:51:59 +00001576
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001577 zip_directory_cache = PyDict_New();
1578 if (zip_directory_cache == NULL)
1579 return NULL;
1580 Py_INCREF(zip_directory_cache);
1581 if (PyModule_AddObject(mod, "_zip_directory_cache",
1582 zip_directory_cache) < 0)
1583 return NULL;
1584 return mod;
Just van Rossum52e14d62002-12-30 22:08:05 +00001585}