blob: e840271bfd67c6be3f6478c3b26c03eb8f3b22b7 [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 */
Benjamin Peterson34c15402014-02-16 14:17:28 -0500680 Py_INCREF(Py_None);
681 return Py_None;
Just van Rossum52e14d62002-12-30 22:08:05 +0000682}
683
684PyDoc_STRVAR(doc_find_module,
685"find_module(fullname, path=None) -> self or None.\n\
686\n\
687Search for a module specified by 'fullname'. 'fullname' must be the\n\
688fully qualified (dotted) module name. It returns the zipimporter\n\
689instance itself if the module was found, or None if it wasn't.\n\
690The optional 'path' argument is ignored -- it's there for compatibility\n\
691with the importer protocol.");
692
Eric V. Smith984b11f2012-05-24 20:21:04 -0400693PyDoc_STRVAR(doc_find_loader,
694"find_loader(fullname, path=None) -> self, str or None.\n\
695\n\
696Search for a module specified by 'fullname'. 'fullname' must be the\n\
697fully qualified (dotted) module name. It returns the zipimporter\n\
698instance itself if the module was found, a string containing the\n\
699full path name if it's possibly a portion of a namespace package,\n\
700or None otherwise. The optional 'path' argument is ignored -- it's\n\
701 there for compatibility with the importer protocol.");
702
Just van Rossum52e14d62002-12-30 22:08:05 +0000703PyDoc_STRVAR(doc_load_module,
704"load_module(fullname) -> module.\n\
705\n\
706Load the module specified by 'fullname'. 'fullname' must be the\n\
707fully qualified (dotted) module name. It returns the imported\n\
708module, or raises ZipImportError if it wasn't found.");
709
710PyDoc_STRVAR(doc_get_data,
711"get_data(pathname) -> string with file data.\n\
712\n\
713Return the data associated with 'pathname'. Raise IOError if\n\
714the file wasn't found.");
715
716PyDoc_STRVAR(doc_is_package,
717"is_package(fullname) -> bool.\n\
718\n\
719Return True if the module specified by fullname is a package.\n\
Brian Curtin32839732010-07-21 01:44:19 +0000720Raise ZipImportError if the module couldn't be found.");
Just van Rossum52e14d62002-12-30 22:08:05 +0000721
722PyDoc_STRVAR(doc_get_code,
723"get_code(fullname) -> code object.\n\
724\n\
725Return the code object for the specified module. Raise ZipImportError\n\
Brian Curtin32839732010-07-21 01:44:19 +0000726if the module couldn't be found.");
Just van Rossum52e14d62002-12-30 22:08:05 +0000727
728PyDoc_STRVAR(doc_get_source,
729"get_source(fullname) -> source string.\n\
730\n\
731Return the source code for the specified module. Raise ZipImportError\n\
Brian Curtin32839732010-07-21 01:44:19 +0000732if the module couldn't be found, return None if the archive does\n\
Just van Rossum52e14d62002-12-30 22:08:05 +0000733contain the module, but has no source for it.");
734
Nick Coghlanf088e5e2008-12-14 11:50:48 +0000735
736PyDoc_STRVAR(doc_get_filename,
Nick Coghlan9a1d6e32009-02-08 03:37:27 +0000737"get_filename(fullname) -> filename string.\n\
Nick Coghlanf088e5e2008-12-14 11:50:48 +0000738\n\
739Return the filename for the specified module.");
740
Just van Rossum52e14d62002-12-30 22:08:05 +0000741static PyMethodDef zipimporter_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000742 {"find_module", zipimporter_find_module, METH_VARARGS,
743 doc_find_module},
Eric V. Smith984b11f2012-05-24 20:21:04 -0400744 {"find_loader", zipimporter_find_loader, METH_VARARGS,
745 doc_find_loader},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000746 {"load_module", zipimporter_load_module, METH_VARARGS,
747 doc_load_module},
748 {"get_data", zipimporter_get_data, METH_VARARGS,
749 doc_get_data},
750 {"get_code", zipimporter_get_code, METH_VARARGS,
751 doc_get_code},
752 {"get_source", zipimporter_get_source, METH_VARARGS,
753 doc_get_source},
754 {"get_filename", zipimporter_get_filename, METH_VARARGS,
755 doc_get_filename},
756 {"is_package", zipimporter_is_package, METH_VARARGS,
757 doc_is_package},
758 {NULL, NULL} /* sentinel */
Just van Rossum52e14d62002-12-30 22:08:05 +0000759};
760
761static PyMemberDef zipimporter_members[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000762 {"archive", T_OBJECT, offsetof(ZipImporter, archive), READONLY},
763 {"prefix", T_OBJECT, offsetof(ZipImporter, prefix), READONLY},
764 {"_files", T_OBJECT, offsetof(ZipImporter, files), READONLY},
765 {NULL}
Just van Rossum52e14d62002-12-30 22:08:05 +0000766};
767
768PyDoc_STRVAR(zipimporter_doc,
769"zipimporter(archivepath) -> zipimporter object\n\
770\n\
771Create a new zipimporter instance. 'archivepath' must be a path to\n\
Alexandre Vassalotti8ae3e052008-05-16 00:41:41 +0000772a zipfile, or to a specific path inside a zipfile. For example, it can be\n\
773'/tmp/myimport.zip', or '/tmp/myimport.zip/mydirectory', if mydirectory is a\n\
774valid directory inside the archive.\n\
775\n\
776'ZipImportError is raised if 'archivepath' doesn't point to a valid Zip\n\
777archive.\n\
778\n\
779The 'archive' attribute of zipimporter objects contains the name of the\n\
780zipfile targeted.");
Just van Rossum52e14d62002-12-30 22:08:05 +0000781
782#define DEFERRED_ADDRESS(ADDR) 0
783
784static PyTypeObject ZipImporter_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000785 PyVarObject_HEAD_INIT(DEFERRED_ADDRESS(&PyType_Type), 0)
786 "zipimport.zipimporter",
787 sizeof(ZipImporter),
788 0, /* tp_itemsize */
789 (destructor)zipimporter_dealloc, /* tp_dealloc */
790 0, /* tp_print */
791 0, /* tp_getattr */
792 0, /* tp_setattr */
793 0, /* tp_reserved */
794 (reprfunc)zipimporter_repr, /* tp_repr */
795 0, /* tp_as_number */
796 0, /* tp_as_sequence */
797 0, /* tp_as_mapping */
798 0, /* tp_hash */
799 0, /* tp_call */
800 0, /* tp_str */
801 PyObject_GenericGetAttr, /* tp_getattro */
802 0, /* tp_setattro */
803 0, /* tp_as_buffer */
804 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE |
805 Py_TPFLAGS_HAVE_GC, /* tp_flags */
806 zipimporter_doc, /* tp_doc */
807 zipimporter_traverse, /* tp_traverse */
808 0, /* tp_clear */
809 0, /* tp_richcompare */
810 0, /* tp_weaklistoffset */
811 0, /* tp_iter */
812 0, /* tp_iternext */
813 zipimporter_methods, /* tp_methods */
814 zipimporter_members, /* tp_members */
815 0, /* tp_getset */
816 0, /* tp_base */
817 0, /* tp_dict */
818 0, /* tp_descr_get */
819 0, /* tp_descr_set */
820 0, /* tp_dictoffset */
821 (initproc)zipimporter_init, /* tp_init */
822 PyType_GenericAlloc, /* tp_alloc */
823 PyType_GenericNew, /* tp_new */
824 PyObject_GC_Del, /* tp_free */
Just van Rossum52e14d62002-12-30 22:08:05 +0000825};
826
827
828/* implementation */
829
Serhiy Storchakad5db5732016-01-28 21:30:16 +0200830/* Given a buffer, return the unsigned int that is represented by the first
Just van Rossum52e14d62002-12-30 22:08:05 +0000831 4 bytes, encoded as little endian. This partially reimplements
832 marshal.c:r_long() */
Serhiy Storchakad5db5732016-01-28 21:30:16 +0200833static unsigned int
834get_uint32(const unsigned char *buf)
835{
836 unsigned int x;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000837 x = buf[0];
Serhiy Storchakad5db5732016-01-28 21:30:16 +0200838 x |= (unsigned int)buf[1] << 8;
839 x |= (unsigned int)buf[2] << 16;
840 x |= (unsigned int)buf[3] << 24;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000841 return x;
Just van Rossum52e14d62002-12-30 22:08:05 +0000842}
843
Serhiy Storchakad5db5732016-01-28 21:30:16 +0200844/* Given a buffer, return the unsigned int that is represented by the first
845 2 bytes, encoded as little endian. This partially reimplements
846 marshal.c:r_short() */
847static unsigned short
848get_uint16(const unsigned char *buf)
849{
850 unsigned short x;
851 x = buf[0];
852 x |= (unsigned short)buf[1] << 8;
853 return x;
854}
855
856static void
857set_file_error(PyObject *archive, int eof)
858{
859 if (eof) {
860 PyErr_SetString(PyExc_EOFError, "EOF read where not expected");
861 }
862 else {
863 PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, archive);
864 }
865}
866
Gregory P. Smith2bcbc142014-01-07 18:30:07 -0800867/*
Benjamin Peterson34c15402014-02-16 14:17:28 -0500868 read_directory(archive) -> files dict (new reference)
Gregory P. Smith2bcbc142014-01-07 18:30:07 -0800869
Benjamin Peterson34c15402014-02-16 14:17:28 -0500870 Given a path to a Zip archive, build a dict, mapping file names
Just van Rossum52e14d62002-12-30 22:08:05 +0000871 (local to the archive, using SEP as a separator) to toc entries.
872
873 A toc_entry is a tuple:
874
Victor Stinner08654e12010-10-18 12:09:02 +0000875 (__file__, # value to use for __file__, available for all files,
876 # encoded to the filesystem encoding
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000877 compress, # compression kind; 0 for uncompressed
878 data_size, # size of compressed data on disk
879 file_size, # size of decompressed data
880 file_offset, # offset of file header from start of archive
881 time, # mod time of file (in dos format)
882 date, # mod data of file (in dos format)
883 crc, # crc checksum of the data
Victor Stinnerc342fca2010-10-18 11:39:05 +0000884 )
Just van Rossum52e14d62002-12-30 22:08:05 +0000885
886 Directories can be recognized by the trailing SEP in the name,
887 data_size and file_offset are 0.
888*/
889static PyObject *
Benjamin Peterson34c15402014-02-16 14:17:28 -0500890read_directory(PyObject *archive)
Just van Rossum52e14d62002-12-30 22:08:05 +0000891{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000892 PyObject *files = NULL;
Benjamin Peterson34c15402014-02-16 14:17:28 -0500893 FILE *fp;
Serhiy Storchakad5db5732016-01-28 21:30:16 +0200894 unsigned short flags, compress, time, date, name_size;
895 unsigned int crc, data_size, file_size, header_size, header_offset;
896 unsigned long file_offset, header_position;
897 unsigned long arc_offset; /* Absolute offset to start of the zip-archive. */
898 unsigned int count, i;
899 unsigned char buffer[46];
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000900 char name[MAXPATHLEN + 5];
Victor Stinner2460a432010-08-16 17:54:28 +0000901 PyObject *nameobj = NULL;
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100902 PyObject *path;
Victor Stinnerd36c8212010-10-18 12:13:46 +0000903 const char *charset;
Victor Stinner4ee65a92011-01-22 10:30:29 +0000904 int bootstrap;
Serhiy Storchakad5db5732016-01-28 21:30:16 +0200905 const char *errmsg = NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +0000906
Benjamin Peterson34c15402014-02-16 14:17:28 -0500907 fp = _Py_fopen_obj(archive, "rb");
908 if (fp == NULL) {
Victor Stinnerfbd6f9e2015-03-20 10:52:25 +0100909 if (PyErr_ExceptionMatches(PyExc_OSError)) {
910 PyObject *exc, *val, *tb;
911 PyErr_Fetch(&exc, &val, &tb);
Benjamin Peterson34c15402014-02-16 14:17:28 -0500912 PyErr_Format(ZipImportError, "can't open Zip file: %R", archive);
Victor Stinnerfbd6f9e2015-03-20 10:52:25 +0100913 _PyErr_ChainExceptions(exc, val, tb);
914 }
Benjamin Peterson34c15402014-02-16 14:17:28 -0500915 return NULL;
916 }
917
Jesus Cea09bf7a72012-10-03 02:13:05 +0200918 if (fseek(fp, -22, SEEK_END) == -1) {
Serhiy Storchakad5db5732016-01-28 21:30:16 +0200919 goto file_error;
Jesus Cea09bf7a72012-10-03 02:13:05 +0200920 }
Serhiy Storchakad5db5732016-01-28 21:30:16 +0200921 header_position = (unsigned long)ftell(fp);
922 if (header_position == (unsigned long)-1) {
923 goto file_error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000924 }
Serhiy Storchakad5db5732016-01-28 21:30:16 +0200925 assert(header_position <= (unsigned long)LONG_MAX);
926 if (fread(buffer, 1, 22, fp) != 22) {
927 goto file_error;
928 }
929 if (get_uint32(buffer) != 0x06054B50u) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000930 /* Bad: End of Central Dir signature */
Serhiy Storchakad5db5732016-01-28 21:30:16 +0200931 errmsg = "not a Zip file";
932 goto invalid_header;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000933 }
Just van Rossum52e14d62002-12-30 22:08:05 +0000934
Serhiy Storchakad5db5732016-01-28 21:30:16 +0200935 header_size = get_uint32(buffer + 12);
936 header_offset = get_uint32(buffer + 16);
937 if (header_position < header_size) {
938 errmsg = "bad central directory size";
939 goto invalid_header;
940 }
941 if (header_position < header_offset) {
942 errmsg = "bad central directory offset";
943 goto invalid_header;
944 }
945 if (header_position - header_size < header_offset) {
946 errmsg = "bad central directory size or offset";
947 goto invalid_header;
948 }
949 header_position -= header_size;
950 arc_offset = header_position - header_offset;
Just van Rossum52e14d62002-12-30 22:08:05 +0000951
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000952 files = PyDict_New();
Serhiy Storchakad5db5732016-01-28 21:30:16 +0200953 if (files == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000954 goto error;
Serhiy Storchakad5db5732016-01-28 21:30:16 +0200955 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000956 /* Start of Central Directory */
957 count = 0;
Serhiy Storchakad5db5732016-01-28 21:30:16 +0200958 if (fseek(fp, (long)header_position, 0) == -1) {
Serhiy Storchaka0e6b7b52013-02-16 17:43:45 +0200959 goto file_error;
Serhiy Storchakad5db5732016-01-28 21:30:16 +0200960 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000961 for (;;) {
962 PyObject *t;
Serhiy Storchakad5db5732016-01-28 21:30:16 +0200963 size_t n;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000964 int err;
Just van Rossum52e14d62002-12-30 22:08:05 +0000965
Serhiy Storchakad5db5732016-01-28 21:30:16 +0200966 n = fread(buffer, 1, 46, fp);
967 if (n < 4) {
968 goto eof_error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000969 }
Serhiy Storchakad5db5732016-01-28 21:30:16 +0200970 /* Start of file header */
971 if (get_uint32(buffer) != 0x02014B50u) {
972 break; /* Bad: Central Dir File Header */
973 }
974 if (n != 46) {
975 goto eof_error;
976 }
977 flags = get_uint16(buffer + 8);
978 compress = get_uint16(buffer + 10);
979 time = get_uint16(buffer + 12);
980 date = get_uint16(buffer + 14);
981 crc = get_uint32(buffer + 16);
982 data_size = get_uint32(buffer + 20);
983 file_size = get_uint32(buffer + 24);
984 name_size = get_uint16(buffer + 28);
985 header_size = (unsigned int)name_size +
986 get_uint16(buffer + 30) /* extra field */ +
987 get_uint16(buffer + 32) /* comment */;
988
989 file_offset = get_uint32(buffer + 42);
990 if (file_offset > header_offset) {
991 errmsg = "bad local header offset";
992 goto invalid_header;
993 }
994 file_offset += arc_offset;
995
996 if (name_size > MAXPATHLEN) {
997 name_size = MAXPATHLEN;
998 }
999 if (fread(name, 1, name_size, fp) != name_size) {
1000 goto file_error;
1001 }
1002 name[name_size] = '\0'; /* Add terminating null byte */
1003 if (SEP != '/') {
1004 for (i = 0; i < name_size; i++) {
1005 if (name[i] == '/') {
1006 name[i] = SEP;
1007 }
1008 }
1009 }
1010 /* Skip the rest of the header.
1011 * On Windows, calling fseek to skip over the fields we don't use is
1012 * slower than reading the data because fseek flushes stdio's
1013 * internal buffers. See issue #8745. */
1014 assert(header_size <= 3*0xFFFFu);
1015 for (i = name_size; i < header_size; i++) {
1016 if (getc(fp) == EOF) {
Serhiy Storchaka0e6b7b52013-02-16 17:43:45 +02001017 goto file_error;
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001018 }
1019 }
Just van Rossum52e14d62002-12-30 22:08:05 +00001020
Victor Stinner4ee65a92011-01-22 10:30:29 +00001021 bootstrap = 0;
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001022 if (flags & 0x0800) {
Victor Stinnerd36c8212010-10-18 12:13:46 +00001023 charset = "utf-8";
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001024 }
Victor Stinner4ee65a92011-01-22 10:30:29 +00001025 else if (!PyThreadState_GET()->interp->codecs_initialized) {
1026 /* During bootstrap, we may need to load the encodings
1027 package from a ZIP file. But the cp437 encoding is implemented
1028 in Python in the encodings package.
1029
1030 Break out of this dependency by assuming that the path to
1031 the encodings module is ASCII-only. */
1032 charset = "ascii";
1033 bootstrap = 1;
1034 }
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001035 else {
Victor Stinnerd36c8212010-10-18 12:13:46 +00001036 charset = "cp437";
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001037 }
Victor Stinnerd36c8212010-10-18 12:13:46 +00001038 nameobj = PyUnicode_Decode(name, name_size, charset, NULL);
Victor Stinner4ee65a92011-01-22 10:30:29 +00001039 if (nameobj == NULL) {
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001040 if (bootstrap) {
Victor Stinner4ee65a92011-01-22 10:30:29 +00001041 PyErr_Format(PyExc_NotImplementedError,
1042 "bootstrap issue: python%i%i.zip contains non-ASCII "
1043 "filenames without the unicode flag",
1044 PY_MAJOR_VERSION, PY_MINOR_VERSION);
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001045 }
Victor Stinner2460a432010-08-16 17:54:28 +00001046 goto error;
Victor Stinner4ee65a92011-01-22 10:30:29 +00001047 }
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001048 if (PyUnicode_READY(nameobj) == -1) {
Stefan Krah000fde92012-08-20 14:14:49 +02001049 goto error;
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001050 }
Martin v. Löwisa72e78b2011-10-31 08:33:37 +01001051 path = PyUnicode_FromFormat("%U%c%U", archive, SEP, nameobj);
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001052 if (path == NULL) {
Victor Stinner2460a432010-08-16 17:54:28 +00001053 goto error;
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001054 }
1055 t = Py_BuildValue("NHIIkHHI", path, compress, data_size,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001056 file_size, file_offset, time, date, crc);
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001057 if (t == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001058 goto error;
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001059 }
Victor Stinner2460a432010-08-16 17:54:28 +00001060 err = PyDict_SetItem(files, nameobj, t);
1061 Py_CLEAR(nameobj);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001062 Py_DECREF(t);
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001063 if (err != 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001064 goto error;
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001065 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001066 count++;
1067 }
Benjamin Peterson34c15402014-02-16 14:17:28 -05001068 fclose(fp);
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001069 if (Py_VerboseFlag) {
1070 PySys_FormatStderr("# zipimport: found %u names in %R\n",
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001071 count, archive);
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001072 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001073 return files;
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001074
1075eof_error:
1076 set_file_error(archive, !ferror(fp));
1077 goto error;
1078
Serhiy Storchaka0e6b7b52013-02-16 17:43:45 +02001079file_error:
Jesus Cea09bf7a72012-10-03 02:13:05 +02001080 PyErr_Format(ZipImportError, "can't read Zip file: %R", archive);
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001081 goto error;
1082
1083invalid_header:
1084 assert(errmsg != NULL);
1085 PyErr_Format(ZipImportError, "%s: %R", errmsg, archive);
1086 goto error;
1087
Just van Rossum52e14d62002-12-30 22:08:05 +00001088error:
Benjamin Peterson34c15402014-02-16 14:17:28 -05001089 fclose(fp);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001090 Py_XDECREF(files);
Victor Stinner2460a432010-08-16 17:54:28 +00001091 Py_XDECREF(nameobj);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001092 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +00001093}
1094
1095/* Return the zlib.decompress function object, or NULL if zlib couldn't
1096 be imported. The function is cached when found, so subsequent calls
Victor Stinner4925cde2011-05-20 00:16:09 +02001097 don't import zlib again. */
Just van Rossum52e14d62002-12-30 22:08:05 +00001098static PyObject *
1099get_decompress_func(void)
1100{
Victor Stinner4925cde2011-05-20 00:16:09 +02001101 static int importing_zlib = 0;
1102 PyObject *zlib;
1103 PyObject *decompress;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02001104 _Py_IDENTIFIER(decompress);
Just van Rossum52e14d62002-12-30 22:08:05 +00001105
Victor Stinner4925cde2011-05-20 00:16:09 +02001106 if (importing_zlib != 0)
1107 /* Someone has a zlib.py[co] in their Zip file;
1108 let's avoid a stack overflow. */
1109 return NULL;
1110 importing_zlib = 1;
1111 zlib = PyImport_ImportModuleNoBlock("zlib");
1112 importing_zlib = 0;
1113 if (zlib != NULL) {
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02001114 decompress = _PyObject_GetAttrId(zlib,
1115 &PyId_decompress);
Victor Stinner4925cde2011-05-20 00:16:09 +02001116 Py_DECREF(zlib);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001117 }
Victor Stinner4925cde2011-05-20 00:16:09 +02001118 else {
1119 PyErr_Clear();
1120 decompress = NULL;
1121 }
1122 if (Py_VerboseFlag)
1123 PySys_WriteStderr("# zipimport: zlib %s\n",
1124 zlib != NULL ? "available": "UNAVAILABLE");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001125 return decompress;
Just van Rossum52e14d62002-12-30 22:08:05 +00001126}
1127
Benjamin Peterson34c15402014-02-16 14:17:28 -05001128/* Given a path to a Zip file and a toc_entry, return the (uncompressed)
Just van Rossum52e14d62002-12-30 22:08:05 +00001129 data as a new reference. */
1130static PyObject *
Benjamin Peterson34c15402014-02-16 14:17:28 -05001131get_data(PyObject *archive, PyObject *toc_entry)
Just van Rossum52e14d62002-12-30 22:08:05 +00001132{
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001133 PyObject *raw_data = NULL, *data, *decompress;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001134 char *buf;
Benjamin Peterson34c15402014-02-16 14:17:28 -05001135 FILE *fp;
Victor Stinner60fe8d92010-08-16 23:48:11 +00001136 PyObject *datapath;
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001137 unsigned short compress, time, date;
1138 unsigned int crc;
1139 Py_ssize_t data_size, file_size, bytes_size;
1140 long file_offset, header_size;
1141 unsigned char buffer[30];
1142 const char *errmsg = NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +00001143
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001144 if (!PyArg_ParseTuple(toc_entry, "OHnnlHHI", &datapath, &compress,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001145 &data_size, &file_size, &file_offset, &time,
1146 &date, &crc)) {
1147 return NULL;
1148 }
Benjamin Petersonb1db7582016-01-21 22:02:46 -08001149 if (data_size < 0) {
1150 PyErr_Format(ZipImportError, "negative data size");
1151 return NULL;
1152 }
Just van Rossum52e14d62002-12-30 22:08:05 +00001153
Benjamin Peterson34c15402014-02-16 14:17:28 -05001154 fp = _Py_fopen_obj(archive, "rb");
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001155 if (!fp) {
Benjamin Peterson34c15402014-02-16 14:17:28 -05001156 return NULL;
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001157 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001158 /* Check to make sure the local file header is correct */
Jesus Cea09bf7a72012-10-03 02:13:05 +02001159 if (fseek(fp, file_offset, 0) == -1) {
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001160 goto file_error;
Jesus Cea09bf7a72012-10-03 02:13:05 +02001161 }
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001162 if (fread(buffer, 1, 30, fp) != 30) {
1163 goto eof_error;
1164 }
1165 if (get_uint32(buffer) != 0x04034B50u) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001166 /* Bad: Local File Header */
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001167 errmsg = "bad local file header";
1168 goto invalid_header;
Jesus Cea09bf7a72012-10-03 02:13:05 +02001169 }
1170
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001171 header_size = (unsigned int)30 +
1172 get_uint16(buffer + 26) /* file name */ +
1173 get_uint16(buffer + 28) /* extra field */;
1174 if (file_offset > LONG_MAX - header_size) {
1175 errmsg = "bad local file header size";
1176 goto invalid_header;
Victor Stinner73660af2013-10-29 01:43:44 +01001177 }
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001178 file_offset += header_size; /* Start of file data */
Just van Rossum52e14d62002-12-30 22:08:05 +00001179
Benjamin Petersonc4032da2016-01-20 22:23:44 -08001180 if (data_size > LONG_MAX - 1) {
1181 fclose(fp);
1182 PyErr_NoMemory();
1183 return NULL;
1184 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001185 bytes_size = compress == 0 ? data_size : data_size + 1;
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001186 if (bytes_size == 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001187 bytes_size++;
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001188 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001189 raw_data = PyBytes_FromStringAndSize((char *)NULL, bytes_size);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001190 if (raw_data == NULL) {
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001191 goto error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001192 }
1193 buf = PyBytes_AsString(raw_data);
Just van Rossum52e14d62002-12-30 22:08:05 +00001194
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001195 if (fseek(fp, file_offset, 0) == -1) {
1196 goto file_error;
Jesus Cea09bf7a72012-10-03 02:13:05 +02001197 }
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001198 if (fread(buf, 1, data_size, fp) != (size_t)data_size) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001199 PyErr_SetString(PyExc_IOError,
1200 "zipimport: can't read data");
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001201 goto error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001202 }
Just van Rossum52e14d62002-12-30 22:08:05 +00001203
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001204 fclose(fp);
1205 fp = NULL;
1206
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001207 if (compress != 0) {
1208 buf[data_size] = 'Z'; /* saw this in zipfile.py */
1209 data_size++;
1210 }
1211 buf[data_size] = '\0';
Just van Rossum52e14d62002-12-30 22:08:05 +00001212
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001213 if (compress == 0) { /* data is not compressed */
1214 data = PyBytes_FromStringAndSize(buf, data_size);
1215 Py_DECREF(raw_data);
1216 return data;
1217 }
1218
1219 /* Decompress with zlib */
1220 decompress = get_decompress_func();
1221 if (decompress == NULL) {
1222 PyErr_SetString(ZipImportError,
1223 "can't decompress data; "
1224 "zlib not available");
1225 goto error;
1226 }
1227 data = PyObject_CallFunction(decompress, "Oi", raw_data, -15);
Victor Stinner4925cde2011-05-20 00:16:09 +02001228 Py_DECREF(decompress);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001229 Py_DECREF(raw_data);
1230 return data;
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001231
1232eof_error:
1233 set_file_error(archive, !ferror(fp));
1234 goto error;
1235
1236file_error:
1237 PyErr_Format(ZipImportError, "can't read Zip file: %R", archive);
1238 goto error;
1239
1240invalid_header:
1241 assert(errmsg != NULL);
1242 PyErr_Format(ZipImportError, "%s: %R", errmsg, archive);
1243 goto error;
1244
1245error:
1246 if (fp != NULL) {
1247 fclose(fp);
1248 }
1249 Py_XDECREF(raw_data);
1250 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +00001251}
1252
1253/* Lenient date/time comparison function. The precision of the mtime
1254 in the archive is lower than the mtime stored in a .pyc: we
1255 must allow a difference of at most one second. */
1256static int
1257eq_mtime(time_t t1, time_t t2)
1258{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001259 time_t d = t1 - t2;
1260 if (d < 0)
1261 d = -d;
1262 /* dostime only stores even seconds, so be lenient */
1263 return d <= 1;
Just van Rossum52e14d62002-12-30 22:08:05 +00001264}
1265
1266/* Given the contents of a .py[co] file in a buffer, unmarshal the data
1267 and return the code object. Return None if it the magic word doesn't
1268 match (we do this instead of raising an exception as we fall back
1269 to .py if available and we don't want to mask other errors).
1270 Returns a new reference. */
1271static PyObject *
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001272unmarshal_code(PyObject *pathname, PyObject *data, time_t mtime)
Just van Rossum52e14d62002-12-30 22:08:05 +00001273{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001274 PyObject *code;
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001275 unsigned char *buf = (unsigned char *)PyBytes_AsString(data);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001276 Py_ssize_t size = PyBytes_Size(data);
Just van Rossum52e14d62002-12-30 22:08:05 +00001277
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001278 if (size < 12) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001279 PyErr_SetString(ZipImportError,
1280 "bad pyc data");
1281 return NULL;
1282 }
Just van Rossum52e14d62002-12-30 22:08:05 +00001283
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001284 if (get_uint32(buf) != (unsigned int)PyImport_GetMagicNumber()) {
1285 if (Py_VerboseFlag) {
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001286 PySys_FormatStderr("# %R has bad magic\n",
1287 pathname);
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001288 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001289 Py_INCREF(Py_None);
1290 return Py_None; /* signal caller to try alternative */
1291 }
Just van Rossum52e14d62002-12-30 22:08:05 +00001292
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001293 if (mtime != 0 && !eq_mtime(get_uint32(buf + 4), mtime)) {
1294 if (Py_VerboseFlag) {
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001295 PySys_FormatStderr("# %R has bad mtime\n",
1296 pathname);
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001297 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001298 Py_INCREF(Py_None);
1299 return Py_None; /* signal caller to try alternative */
1300 }
Just van Rossum52e14d62002-12-30 22:08:05 +00001301
Antoine Pitrou5136ac02012-01-13 18:52:16 +01001302 /* XXX the pyc's size field is ignored; timestamp collisions are probably
1303 unimportant with zip files. */
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001304 code = PyMarshal_ReadObjectFromString((char *)buf + 12, size - 12);
1305 if (code == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001306 return NULL;
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001307 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001308 if (!PyCode_Check(code)) {
1309 Py_DECREF(code);
1310 PyErr_Format(PyExc_TypeError,
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001311 "compiled module %R is not a code object",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001312 pathname);
1313 return NULL;
1314 }
1315 return code;
Just van Rossum52e14d62002-12-30 22:08:05 +00001316}
1317
1318/* Replace any occurances of "\r\n?" in the input string with "\n".
1319 This converts DOS and Mac line endings to Unix line endings.
1320 Also append a trailing "\n" to be compatible with
1321 PyParser_SimpleParseFile(). Returns a new reference. */
1322static PyObject *
1323normalize_line_endings(PyObject *source)
1324{
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001325 char *buf, *q, *p;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001326 PyObject *fixed_source;
1327 int len = 0;
Just van Rossum52e14d62002-12-30 22:08:05 +00001328
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001329 p = PyBytes_AsString(source);
1330 if (p == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001331 return PyBytes_FromStringAndSize("\n\0", 2);
1332 }
Thomas Wouters00ee7ba2006-08-21 19:07:27 +00001333
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001334 /* one char extra for trailing \n and one for terminating \0 */
1335 buf = (char *)PyMem_Malloc(PyBytes_Size(source) + 2);
1336 if (buf == NULL) {
1337 PyErr_SetString(PyExc_MemoryError,
1338 "zipimport: no memory to allocate "
1339 "source buffer");
1340 return NULL;
1341 }
1342 /* replace "\r\n?" by "\n" */
1343 for (q = buf; *p != '\0'; p++) {
1344 if (*p == '\r') {
1345 *q++ = '\n';
1346 if (*(p + 1) == '\n')
1347 p++;
1348 }
1349 else
1350 *q++ = *p;
1351 len++;
1352 }
1353 *q++ = '\n'; /* add trailing \n */
1354 *q = '\0';
1355 fixed_source = PyBytes_FromStringAndSize(buf, len + 2);
1356 PyMem_Free(buf);
1357 return fixed_source;
Just van Rossum52e14d62002-12-30 22:08:05 +00001358}
1359
1360/* Given a string buffer containing Python source code, compile it
Brett Cannon83358c92013-06-20 21:30:32 -04001361 and return a code object as a new reference. */
Just van Rossum52e14d62002-12-30 22:08:05 +00001362static PyObject *
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001363compile_source(PyObject *pathname, PyObject *source)
Just van Rossum52e14d62002-12-30 22:08:05 +00001364{
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001365 PyObject *code, *fixed_source, *pathbytes;
Just van Rossum52e14d62002-12-30 22:08:05 +00001366
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001367 pathbytes = PyUnicode_EncodeFSDefault(pathname);
1368 if (pathbytes == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001369 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +00001370
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001371 fixed_source = normalize_line_endings(source);
1372 if (fixed_source == NULL) {
1373 Py_DECREF(pathbytes);
1374 return NULL;
1375 }
1376
1377 code = Py_CompileString(PyBytes_AsString(fixed_source),
1378 PyBytes_AsString(pathbytes),
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001379 Py_file_input);
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001380 Py_DECREF(pathbytes);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001381 Py_DECREF(fixed_source);
1382 return code;
Just van Rossum52e14d62002-12-30 22:08:05 +00001383}
1384
1385/* Convert the date/time values found in the Zip archive to a value
1386 that's compatible with the time stamp stored in .pyc files. */
Neal Norwitz29fd2ba2003-03-23 13:21:03 +00001387static time_t
1388parse_dostime(int dostime, int dosdate)
Just van Rossum52e14d62002-12-30 22:08:05 +00001389{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001390 struct tm stm;
Just van Rossum52e14d62002-12-30 22:08:05 +00001391
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001392 memset((void *) &stm, '\0', sizeof(stm));
Christian Heimes679db4a2008-01-18 09:56:22 +00001393
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001394 stm.tm_sec = (dostime & 0x1f) * 2;
1395 stm.tm_min = (dostime >> 5) & 0x3f;
1396 stm.tm_hour = (dostime >> 11) & 0x1f;
1397 stm.tm_mday = dosdate & 0x1f;
1398 stm.tm_mon = ((dosdate >> 5) & 0x0f) - 1;
1399 stm.tm_year = ((dosdate >> 9) & 0x7f) + 80;
1400 stm.tm_isdst = -1; /* wday/yday is ignored */
Just van Rossum52e14d62002-12-30 22:08:05 +00001401
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001402 return mktime(&stm);
Just van Rossum52e14d62002-12-30 22:08:05 +00001403}
1404
Brett Cannonf299abd2015-04-13 14:21:02 -04001405/* Given a path to a .pyc file in the archive, return the
Ezio Melotti13925002011-03-16 11:05:33 +02001406 modification time of the matching .py file, or 0 if no source
Just van Rossum52e14d62002-12-30 22:08:05 +00001407 is available. */
1408static time_t
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001409get_mtime_of_source(ZipImporter *self, PyObject *path)
Just van Rossum52e14d62002-12-30 22:08:05 +00001410{
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001411 PyObject *toc_entry, *stripped;
1412 time_t mtime;
1413
1414 /* strip 'c' or 'o' from *.py[co] */
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001415 if (PyUnicode_READY(path) == -1)
1416 return (time_t)-1;
1417 stripped = PyUnicode_FromKindAndData(PyUnicode_KIND(path),
1418 PyUnicode_DATA(path),
1419 PyUnicode_GET_LENGTH(path) - 1);
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001420 if (stripped == NULL)
1421 return (time_t)-1;
1422
1423 toc_entry = PyDict_GetItem(self->files, stripped);
1424 Py_DECREF(stripped);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001425 if (toc_entry != NULL && PyTuple_Check(toc_entry) &&
1426 PyTuple_Size(toc_entry) == 8) {
1427 /* fetch the time stamp of the .py file for comparison
1428 with an embedded pyc time stamp */
1429 int time, date;
1430 time = PyLong_AsLong(PyTuple_GetItem(toc_entry, 5));
1431 date = PyLong_AsLong(PyTuple_GetItem(toc_entry, 6));
1432 mtime = parse_dostime(time, date);
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001433 } else
1434 mtime = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001435 return mtime;
Just van Rossum52e14d62002-12-30 22:08:05 +00001436}
1437
1438/* Return the code object for the module named by 'fullname' from the
1439 Zip archive as a new reference. */
1440static PyObject *
Benjamin Peterson34c15402014-02-16 14:17:28 -05001441get_code_from_data(ZipImporter *self, int ispackage, int isbytecode,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001442 time_t mtime, PyObject *toc_entry)
Just van Rossum52e14d62002-12-30 22:08:05 +00001443{
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001444 PyObject *data, *modpath, *code;
Just van Rossum52e14d62002-12-30 22:08:05 +00001445
Benjamin Peterson34c15402014-02-16 14:17:28 -05001446 data = get_data(self->archive, toc_entry);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001447 if (data == NULL)
1448 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +00001449
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001450 modpath = PyTuple_GetItem(toc_entry, 0);
Victor Stinner2a94f4c2010-10-18 12:15:34 +00001451 if (isbytecode)
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001452 code = unmarshal_code(modpath, data, mtime);
Victor Stinner2a94f4c2010-10-18 12:15:34 +00001453 else
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001454 code = compile_source(modpath, data);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001455 Py_DECREF(data);
1456 return code;
Just van Rossum52e14d62002-12-30 22:08:05 +00001457}
1458
Ezio Melotti42da6632011-03-15 05:18:48 +02001459/* Get the code object associated with the module specified by
Just van Rossum52e14d62002-12-30 22:08:05 +00001460 'fullname'. */
1461static PyObject *
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001462get_module_code(ZipImporter *self, PyObject *fullname,
Victor Stinner08654e12010-10-18 12:09:02 +00001463 int *p_ispackage, PyObject **p_modpath)
Just van Rossum52e14d62002-12-30 22:08:05 +00001464{
Gregory P. Smith95c7c462011-05-21 05:19:42 -07001465 PyObject *code = NULL, *toc_entry, *subname;
Victor Stinner9a2261a2011-05-26 13:59:41 +02001466 PyObject *path, *fullpath = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001467 struct st_zip_searchorder *zso;
Just van Rossum52e14d62002-12-30 22:08:05 +00001468
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001469 subname = get_subname(fullname);
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001470 if (subname == NULL)
1471 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +00001472
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001473 path = make_filename(self->prefix, subname);
1474 Py_DECREF(subname);
1475 if (path == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001476 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +00001477
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001478 for (zso = zip_searchorder; *zso->suffix; zso++) {
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001479 code = NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +00001480
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001481 fullpath = PyUnicode_FromFormat("%U%s", path, zso->suffix);
1482 if (fullpath == NULL)
1483 goto exit;
1484
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001485 if (Py_VerboseFlag > 1)
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001486 PySys_FormatStderr("# trying %U%c%U\n",
1487 self->archive, (int)SEP, fullpath);
1488 toc_entry = PyDict_GetItem(self->files, fullpath);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001489 if (toc_entry != NULL) {
1490 time_t mtime = 0;
1491 int ispackage = zso->type & IS_PACKAGE;
1492 int isbytecode = zso->type & IS_BYTECODE;
Just van Rossum52e14d62002-12-30 22:08:05 +00001493
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001494 if (isbytecode) {
1495 mtime = get_mtime_of_source(self, fullpath);
1496 if (mtime == (time_t)-1 && PyErr_Occurred()) {
1497 goto exit;
1498 }
1499 }
1500 Py_CLEAR(fullpath);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001501 if (p_ispackage != NULL)
1502 *p_ispackage = ispackage;
Benjamin Peterson34c15402014-02-16 14:17:28 -05001503 code = get_code_from_data(self, ispackage,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001504 isbytecode, mtime,
1505 toc_entry);
1506 if (code == Py_None) {
1507 /* bad magic number or non-matching mtime
1508 in byte code, try next */
1509 Py_DECREF(code);
1510 continue;
1511 }
Victor Stinner08654e12010-10-18 12:09:02 +00001512 if (code != NULL && p_modpath != NULL) {
1513 *p_modpath = PyTuple_GetItem(toc_entry, 0);
1514 Py_INCREF(*p_modpath);
1515 }
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001516 goto exit;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001517 }
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001518 else
1519 Py_CLEAR(fullpath);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001520 }
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001521 PyErr_Format(ZipImportError, "can't find module %R", fullname);
1522exit:
1523 Py_DECREF(path);
1524 Py_XDECREF(fullpath);
1525 return code;
Just van Rossum52e14d62002-12-30 22:08:05 +00001526}
1527
1528
1529/* Module init */
1530
1531PyDoc_STRVAR(zipimport_doc,
1532"zipimport provides support for importing Python modules from Zip archives.\n\
1533\n\
1534This module exports three objects:\n\
1535- zipimporter: a class; its constructor takes a path to a Zip archive.\n\
Fredrik Lundhb84b35f2006-01-15 15:00:40 +00001536- ZipImportError: exception raised by zipimporter objects. It's a\n\
Just van Rossum52e14d62002-12-30 22:08:05 +00001537 subclass of ImportError, so it can be caught as ImportError, too.\n\
1538- _zip_directory_cache: a dict, mapping archive paths to zip directory\n\
1539 info dicts, as used in zipimporter._files.\n\
1540\n\
1541It is usually not needed to use the zipimport module explicitly; it is\n\
1542used by the builtin import mechanism for sys.path items that are paths\n\
1543to Zip archives.");
1544
Martin v. Löwis1a214512008-06-11 05:26:20 +00001545static struct PyModuleDef zipimportmodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001546 PyModuleDef_HEAD_INIT,
1547 "zipimport",
1548 zipimport_doc,
1549 -1,
1550 NULL,
1551 NULL,
1552 NULL,
1553 NULL,
1554 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +00001555};
1556
Just van Rossum52e14d62002-12-30 22:08:05 +00001557PyMODINIT_FUNC
Martin v. Löwis1a214512008-06-11 05:26:20 +00001558PyInit_zipimport(void)
Just van Rossum52e14d62002-12-30 22:08:05 +00001559{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001560 PyObject *mod;
Just van Rossum52e14d62002-12-30 22:08:05 +00001561
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001562 if (PyType_Ready(&ZipImporter_Type) < 0)
1563 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +00001564
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001565 /* Correct directory separator */
1566 zip_searchorder[0].suffix[0] = SEP;
1567 zip_searchorder[1].suffix[0] = SEP;
Just van Rossum52e14d62002-12-30 22:08:05 +00001568
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001569 mod = PyModule_Create(&zipimportmodule);
1570 if (mod == NULL)
1571 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +00001572
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001573 ZipImportError = PyErr_NewException("zipimport.ZipImportError",
1574 PyExc_ImportError, NULL);
1575 if (ZipImportError == NULL)
1576 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +00001577
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001578 Py_INCREF(ZipImportError);
1579 if (PyModule_AddObject(mod, "ZipImportError",
1580 ZipImportError) < 0)
1581 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +00001582
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001583 Py_INCREF(&ZipImporter_Type);
1584 if (PyModule_AddObject(mod, "zipimporter",
1585 (PyObject *)&ZipImporter_Type) < 0)
1586 return NULL;
Just van Rossumf8b6de12002-12-31 09:51:59 +00001587
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001588 zip_directory_cache = PyDict_New();
1589 if (zip_directory_cache == NULL)
1590 return NULL;
1591 Py_INCREF(zip_directory_cache);
1592 if (PyModule_AddObject(mod, "_zip_directory_cache",
1593 zip_directory_cache) < 0)
1594 return NULL;
1595 return mod;
Just van Rossum52e14d62002-12-30 22:08:05 +00001596}