blob: 59046aaae41f51240baa94e16c749ec539629280 [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)) {
Serhiy Storchaka467ab192016-10-21 17:09:17 +0300910 _PyErr_FormatFromCause(ZipImportError,
911 "can't open Zip file: %R", archive);
Victor Stinnerfbd6f9e2015-03-20 10:52:25 +0100912 }
Benjamin Peterson34c15402014-02-16 14:17:28 -0500913 return NULL;
914 }
915
Jesus Cea09bf7a72012-10-03 02:13:05 +0200916 if (fseek(fp, -22, SEEK_END) == -1) {
Serhiy Storchakad5db5732016-01-28 21:30:16 +0200917 goto file_error;
Jesus Cea09bf7a72012-10-03 02:13:05 +0200918 }
Serhiy Storchakad5db5732016-01-28 21:30:16 +0200919 header_position = (unsigned long)ftell(fp);
920 if (header_position == (unsigned long)-1) {
921 goto file_error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000922 }
Serhiy Storchakad5db5732016-01-28 21:30:16 +0200923 assert(header_position <= (unsigned long)LONG_MAX);
924 if (fread(buffer, 1, 22, fp) != 22) {
925 goto file_error;
926 }
927 if (get_uint32(buffer) != 0x06054B50u) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000928 /* Bad: End of Central Dir signature */
Serhiy Storchakad5db5732016-01-28 21:30:16 +0200929 errmsg = "not a Zip file";
930 goto invalid_header;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000931 }
Just van Rossum52e14d62002-12-30 22:08:05 +0000932
Serhiy Storchakad5db5732016-01-28 21:30:16 +0200933 header_size = get_uint32(buffer + 12);
934 header_offset = get_uint32(buffer + 16);
935 if (header_position < header_size) {
936 errmsg = "bad central directory size";
937 goto invalid_header;
938 }
939 if (header_position < header_offset) {
940 errmsg = "bad central directory offset";
941 goto invalid_header;
942 }
943 if (header_position - header_size < header_offset) {
944 errmsg = "bad central directory size or offset";
945 goto invalid_header;
946 }
947 header_position -= header_size;
948 arc_offset = header_position - header_offset;
Just van Rossum52e14d62002-12-30 22:08:05 +0000949
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000950 files = PyDict_New();
Serhiy Storchakad5db5732016-01-28 21:30:16 +0200951 if (files == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000952 goto error;
Serhiy Storchakad5db5732016-01-28 21:30:16 +0200953 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000954 /* Start of Central Directory */
955 count = 0;
Serhiy Storchakad5db5732016-01-28 21:30:16 +0200956 if (fseek(fp, (long)header_position, 0) == -1) {
Serhiy Storchaka0e6b7b52013-02-16 17:43:45 +0200957 goto file_error;
Serhiy Storchakad5db5732016-01-28 21:30:16 +0200958 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000959 for (;;) {
960 PyObject *t;
Serhiy Storchakad5db5732016-01-28 21:30:16 +0200961 size_t n;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000962 int err;
Just van Rossum52e14d62002-12-30 22:08:05 +0000963
Serhiy Storchakad5db5732016-01-28 21:30:16 +0200964 n = fread(buffer, 1, 46, fp);
965 if (n < 4) {
966 goto eof_error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000967 }
Serhiy Storchakad5db5732016-01-28 21:30:16 +0200968 /* Start of file header */
969 if (get_uint32(buffer) != 0x02014B50u) {
970 break; /* Bad: Central Dir File Header */
971 }
972 if (n != 46) {
973 goto eof_error;
974 }
975 flags = get_uint16(buffer + 8);
976 compress = get_uint16(buffer + 10);
977 time = get_uint16(buffer + 12);
978 date = get_uint16(buffer + 14);
979 crc = get_uint32(buffer + 16);
980 data_size = get_uint32(buffer + 20);
981 file_size = get_uint32(buffer + 24);
982 name_size = get_uint16(buffer + 28);
983 header_size = (unsigned int)name_size +
984 get_uint16(buffer + 30) /* extra field */ +
985 get_uint16(buffer + 32) /* comment */;
986
987 file_offset = get_uint32(buffer + 42);
988 if (file_offset > header_offset) {
989 errmsg = "bad local header offset";
990 goto invalid_header;
991 }
992 file_offset += arc_offset;
993
994 if (name_size > MAXPATHLEN) {
995 name_size = MAXPATHLEN;
996 }
997 if (fread(name, 1, name_size, fp) != name_size) {
998 goto file_error;
999 }
1000 name[name_size] = '\0'; /* Add terminating null byte */
1001 if (SEP != '/') {
1002 for (i = 0; i < name_size; i++) {
1003 if (name[i] == '/') {
1004 name[i] = SEP;
1005 }
1006 }
1007 }
1008 /* Skip the rest of the header.
1009 * On Windows, calling fseek to skip over the fields we don't use is
1010 * slower than reading the data because fseek flushes stdio's
1011 * internal buffers. See issue #8745. */
1012 assert(header_size <= 3*0xFFFFu);
1013 for (i = name_size; i < header_size; i++) {
1014 if (getc(fp) == EOF) {
Serhiy Storchaka0e6b7b52013-02-16 17:43:45 +02001015 goto file_error;
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001016 }
1017 }
Just van Rossum52e14d62002-12-30 22:08:05 +00001018
Victor Stinner4ee65a92011-01-22 10:30:29 +00001019 bootstrap = 0;
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001020 if (flags & 0x0800) {
Victor Stinnerd36c8212010-10-18 12:13:46 +00001021 charset = "utf-8";
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001022 }
Victor Stinner4ee65a92011-01-22 10:30:29 +00001023 else if (!PyThreadState_GET()->interp->codecs_initialized) {
1024 /* During bootstrap, we may need to load the encodings
1025 package from a ZIP file. But the cp437 encoding is implemented
1026 in Python in the encodings package.
1027
1028 Break out of this dependency by assuming that the path to
1029 the encodings module is ASCII-only. */
1030 charset = "ascii";
1031 bootstrap = 1;
1032 }
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001033 else {
Victor Stinnerd36c8212010-10-18 12:13:46 +00001034 charset = "cp437";
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001035 }
Victor Stinnerd36c8212010-10-18 12:13:46 +00001036 nameobj = PyUnicode_Decode(name, name_size, charset, NULL);
Victor Stinner4ee65a92011-01-22 10:30:29 +00001037 if (nameobj == NULL) {
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001038 if (bootstrap) {
Victor Stinner4ee65a92011-01-22 10:30:29 +00001039 PyErr_Format(PyExc_NotImplementedError,
1040 "bootstrap issue: python%i%i.zip contains non-ASCII "
1041 "filenames without the unicode flag",
1042 PY_MAJOR_VERSION, PY_MINOR_VERSION);
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001043 }
Victor Stinner2460a432010-08-16 17:54:28 +00001044 goto error;
Victor Stinner4ee65a92011-01-22 10:30:29 +00001045 }
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001046 if (PyUnicode_READY(nameobj) == -1) {
Stefan Krah000fde92012-08-20 14:14:49 +02001047 goto error;
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001048 }
Martin v. Löwisa72e78b2011-10-31 08:33:37 +01001049 path = PyUnicode_FromFormat("%U%c%U", archive, SEP, nameobj);
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001050 if (path == NULL) {
Victor Stinner2460a432010-08-16 17:54:28 +00001051 goto error;
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001052 }
1053 t = Py_BuildValue("NHIIkHHI", path, compress, data_size,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001054 file_size, file_offset, time, date, crc);
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001055 if (t == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001056 goto error;
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001057 }
Victor Stinner2460a432010-08-16 17:54:28 +00001058 err = PyDict_SetItem(files, nameobj, t);
1059 Py_CLEAR(nameobj);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001060 Py_DECREF(t);
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001061 if (err != 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001062 goto error;
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001063 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001064 count++;
1065 }
Benjamin Peterson34c15402014-02-16 14:17:28 -05001066 fclose(fp);
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001067 if (Py_VerboseFlag) {
1068 PySys_FormatStderr("# zipimport: found %u names in %R\n",
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001069 count, archive);
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001070 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001071 return files;
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001072
1073eof_error:
1074 set_file_error(archive, !ferror(fp));
1075 goto error;
1076
Serhiy Storchaka0e6b7b52013-02-16 17:43:45 +02001077file_error:
Jesus Cea09bf7a72012-10-03 02:13:05 +02001078 PyErr_Format(ZipImportError, "can't read Zip file: %R", archive);
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001079 goto error;
1080
1081invalid_header:
1082 assert(errmsg != NULL);
1083 PyErr_Format(ZipImportError, "%s: %R", errmsg, archive);
1084 goto error;
1085
Just van Rossum52e14d62002-12-30 22:08:05 +00001086error:
Benjamin Peterson34c15402014-02-16 14:17:28 -05001087 fclose(fp);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001088 Py_XDECREF(files);
Victor Stinner2460a432010-08-16 17:54:28 +00001089 Py_XDECREF(nameobj);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001090 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +00001091}
1092
1093/* Return the zlib.decompress function object, or NULL if zlib couldn't
1094 be imported. The function is cached when found, so subsequent calls
Victor Stinner4925cde2011-05-20 00:16:09 +02001095 don't import zlib again. */
Just van Rossum52e14d62002-12-30 22:08:05 +00001096static PyObject *
1097get_decompress_func(void)
1098{
Victor Stinner4925cde2011-05-20 00:16:09 +02001099 static int importing_zlib = 0;
1100 PyObject *zlib;
1101 PyObject *decompress;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02001102 _Py_IDENTIFIER(decompress);
Just van Rossum52e14d62002-12-30 22:08:05 +00001103
Victor Stinner4925cde2011-05-20 00:16:09 +02001104 if (importing_zlib != 0)
1105 /* Someone has a zlib.py[co] in their Zip file;
1106 let's avoid a stack overflow. */
1107 return NULL;
1108 importing_zlib = 1;
1109 zlib = PyImport_ImportModuleNoBlock("zlib");
1110 importing_zlib = 0;
1111 if (zlib != NULL) {
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02001112 decompress = _PyObject_GetAttrId(zlib,
1113 &PyId_decompress);
Victor Stinner4925cde2011-05-20 00:16:09 +02001114 Py_DECREF(zlib);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001115 }
Victor Stinner4925cde2011-05-20 00:16:09 +02001116 else {
1117 PyErr_Clear();
1118 decompress = NULL;
1119 }
1120 if (Py_VerboseFlag)
1121 PySys_WriteStderr("# zipimport: zlib %s\n",
1122 zlib != NULL ? "available": "UNAVAILABLE");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001123 return decompress;
Just van Rossum52e14d62002-12-30 22:08:05 +00001124}
1125
Benjamin Peterson34c15402014-02-16 14:17:28 -05001126/* Given a path to a Zip file and a toc_entry, return the (uncompressed)
Just van Rossum52e14d62002-12-30 22:08:05 +00001127 data as a new reference. */
1128static PyObject *
Benjamin Peterson34c15402014-02-16 14:17:28 -05001129get_data(PyObject *archive, PyObject *toc_entry)
Just van Rossum52e14d62002-12-30 22:08:05 +00001130{
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001131 PyObject *raw_data = NULL, *data, *decompress;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001132 char *buf;
Benjamin Peterson34c15402014-02-16 14:17:28 -05001133 FILE *fp;
Victor Stinner60fe8d92010-08-16 23:48:11 +00001134 PyObject *datapath;
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001135 unsigned short compress, time, date;
1136 unsigned int crc;
1137 Py_ssize_t data_size, file_size, bytes_size;
1138 long file_offset, header_size;
1139 unsigned char buffer[30];
1140 const char *errmsg = NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +00001141
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001142 if (!PyArg_ParseTuple(toc_entry, "OHnnlHHI", &datapath, &compress,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001143 &data_size, &file_size, &file_offset, &time,
1144 &date, &crc)) {
1145 return NULL;
1146 }
Benjamin Petersonb1db7582016-01-21 22:02:46 -08001147 if (data_size < 0) {
1148 PyErr_Format(ZipImportError, "negative data size");
1149 return NULL;
1150 }
Just van Rossum52e14d62002-12-30 22:08:05 +00001151
Benjamin Peterson34c15402014-02-16 14:17:28 -05001152 fp = _Py_fopen_obj(archive, "rb");
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001153 if (!fp) {
Benjamin Peterson34c15402014-02-16 14:17:28 -05001154 return NULL;
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001155 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001156 /* Check to make sure the local file header is correct */
Jesus Cea09bf7a72012-10-03 02:13:05 +02001157 if (fseek(fp, file_offset, 0) == -1) {
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001158 goto file_error;
Jesus Cea09bf7a72012-10-03 02:13:05 +02001159 }
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001160 if (fread(buffer, 1, 30, fp) != 30) {
1161 goto eof_error;
1162 }
1163 if (get_uint32(buffer) != 0x04034B50u) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001164 /* Bad: Local File Header */
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001165 errmsg = "bad local file header";
1166 goto invalid_header;
Jesus Cea09bf7a72012-10-03 02:13:05 +02001167 }
1168
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001169 header_size = (unsigned int)30 +
1170 get_uint16(buffer + 26) /* file name */ +
1171 get_uint16(buffer + 28) /* extra field */;
1172 if (file_offset > LONG_MAX - header_size) {
1173 errmsg = "bad local file header size";
1174 goto invalid_header;
Victor Stinner73660af2013-10-29 01:43:44 +01001175 }
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001176 file_offset += header_size; /* Start of file data */
Just van Rossum52e14d62002-12-30 22:08:05 +00001177
Benjamin Petersonc4032da2016-01-20 22:23:44 -08001178 if (data_size > LONG_MAX - 1) {
1179 fclose(fp);
1180 PyErr_NoMemory();
1181 return NULL;
1182 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001183 bytes_size = compress == 0 ? data_size : data_size + 1;
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001184 if (bytes_size == 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001185 bytes_size++;
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001186 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001187 raw_data = PyBytes_FromStringAndSize((char *)NULL, bytes_size);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001188 if (raw_data == NULL) {
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001189 goto error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001190 }
1191 buf = PyBytes_AsString(raw_data);
Just van Rossum52e14d62002-12-30 22:08:05 +00001192
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001193 if (fseek(fp, file_offset, 0) == -1) {
1194 goto file_error;
Jesus Cea09bf7a72012-10-03 02:13:05 +02001195 }
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001196 if (fread(buf, 1, data_size, fp) != (size_t)data_size) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001197 PyErr_SetString(PyExc_IOError,
1198 "zipimport: can't read data");
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001199 goto error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001200 }
Just van Rossum52e14d62002-12-30 22:08:05 +00001201
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001202 fclose(fp);
1203 fp = NULL;
1204
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001205 if (compress != 0) {
1206 buf[data_size] = 'Z'; /* saw this in zipfile.py */
1207 data_size++;
1208 }
1209 buf[data_size] = '\0';
Just van Rossum52e14d62002-12-30 22:08:05 +00001210
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001211 if (compress == 0) { /* data is not compressed */
1212 data = PyBytes_FromStringAndSize(buf, data_size);
1213 Py_DECREF(raw_data);
1214 return data;
1215 }
1216
1217 /* Decompress with zlib */
1218 decompress = get_decompress_func();
1219 if (decompress == NULL) {
1220 PyErr_SetString(ZipImportError,
1221 "can't decompress data; "
1222 "zlib not available");
1223 goto error;
1224 }
1225 data = PyObject_CallFunction(decompress, "Oi", raw_data, -15);
Victor Stinner4925cde2011-05-20 00:16:09 +02001226 Py_DECREF(decompress);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001227 Py_DECREF(raw_data);
1228 return data;
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001229
1230eof_error:
1231 set_file_error(archive, !ferror(fp));
1232 goto error;
1233
1234file_error:
1235 PyErr_Format(ZipImportError, "can't read Zip file: %R", archive);
1236 goto error;
1237
1238invalid_header:
1239 assert(errmsg != NULL);
1240 PyErr_Format(ZipImportError, "%s: %R", errmsg, archive);
1241 goto error;
1242
1243error:
1244 if (fp != NULL) {
1245 fclose(fp);
1246 }
1247 Py_XDECREF(raw_data);
1248 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +00001249}
1250
1251/* Lenient date/time comparison function. The precision of the mtime
1252 in the archive is lower than the mtime stored in a .pyc: we
1253 must allow a difference of at most one second. */
1254static int
1255eq_mtime(time_t t1, time_t t2)
1256{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001257 time_t d = t1 - t2;
1258 if (d < 0)
1259 d = -d;
1260 /* dostime only stores even seconds, so be lenient */
1261 return d <= 1;
Just van Rossum52e14d62002-12-30 22:08:05 +00001262}
1263
1264/* Given the contents of a .py[co] file in a buffer, unmarshal the data
1265 and return the code object. Return None if it the magic word doesn't
1266 match (we do this instead of raising an exception as we fall back
1267 to .py if available and we don't want to mask other errors).
1268 Returns a new reference. */
1269static PyObject *
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001270unmarshal_code(PyObject *pathname, PyObject *data, time_t mtime)
Just van Rossum52e14d62002-12-30 22:08:05 +00001271{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001272 PyObject *code;
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001273 unsigned char *buf = (unsigned char *)PyBytes_AsString(data);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001274 Py_ssize_t size = PyBytes_Size(data);
Just van Rossum52e14d62002-12-30 22:08:05 +00001275
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001276 if (size < 12) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001277 PyErr_SetString(ZipImportError,
1278 "bad pyc data");
1279 return NULL;
1280 }
Just van Rossum52e14d62002-12-30 22:08:05 +00001281
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001282 if (get_uint32(buf) != (unsigned int)PyImport_GetMagicNumber()) {
1283 if (Py_VerboseFlag) {
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001284 PySys_FormatStderr("# %R has bad magic\n",
1285 pathname);
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001286 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001287 Py_INCREF(Py_None);
1288 return Py_None; /* signal caller to try alternative */
1289 }
Just van Rossum52e14d62002-12-30 22:08:05 +00001290
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001291 if (mtime != 0 && !eq_mtime(get_uint32(buf + 4), mtime)) {
1292 if (Py_VerboseFlag) {
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001293 PySys_FormatStderr("# %R has bad mtime\n",
1294 pathname);
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001295 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001296 Py_INCREF(Py_None);
1297 return Py_None; /* signal caller to try alternative */
1298 }
Just van Rossum52e14d62002-12-30 22:08:05 +00001299
Antoine Pitrou5136ac02012-01-13 18:52:16 +01001300 /* XXX the pyc's size field is ignored; timestamp collisions are probably
1301 unimportant with zip files. */
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001302 code = PyMarshal_ReadObjectFromString((char *)buf + 12, size - 12);
1303 if (code == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001304 return NULL;
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001305 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001306 if (!PyCode_Check(code)) {
1307 Py_DECREF(code);
1308 PyErr_Format(PyExc_TypeError,
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001309 "compiled module %R is not a code object",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001310 pathname);
1311 return NULL;
1312 }
1313 return code;
Just van Rossum52e14d62002-12-30 22:08:05 +00001314}
1315
Martin Panter0be894b2016-09-07 12:03:06 +00001316/* Replace any occurrences of "\r\n?" in the input string with "\n".
Just van Rossum52e14d62002-12-30 22:08:05 +00001317 This converts DOS and Mac line endings to Unix line endings.
1318 Also append a trailing "\n" to be compatible with
1319 PyParser_SimpleParseFile(). Returns a new reference. */
1320static PyObject *
1321normalize_line_endings(PyObject *source)
1322{
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001323 char *buf, *q, *p;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001324 PyObject *fixed_source;
1325 int len = 0;
Just van Rossum52e14d62002-12-30 22:08:05 +00001326
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001327 p = PyBytes_AsString(source);
1328 if (p == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001329 return PyBytes_FromStringAndSize("\n\0", 2);
1330 }
Thomas Wouters00ee7ba2006-08-21 19:07:27 +00001331
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001332 /* one char extra for trailing \n and one for terminating \0 */
1333 buf = (char *)PyMem_Malloc(PyBytes_Size(source) + 2);
1334 if (buf == NULL) {
1335 PyErr_SetString(PyExc_MemoryError,
1336 "zipimport: no memory to allocate "
1337 "source buffer");
1338 return NULL;
1339 }
1340 /* replace "\r\n?" by "\n" */
1341 for (q = buf; *p != '\0'; p++) {
1342 if (*p == '\r') {
1343 *q++ = '\n';
1344 if (*(p + 1) == '\n')
1345 p++;
1346 }
1347 else
1348 *q++ = *p;
1349 len++;
1350 }
1351 *q++ = '\n'; /* add trailing \n */
1352 *q = '\0';
1353 fixed_source = PyBytes_FromStringAndSize(buf, len + 2);
1354 PyMem_Free(buf);
1355 return fixed_source;
Just van Rossum52e14d62002-12-30 22:08:05 +00001356}
1357
1358/* Given a string buffer containing Python source code, compile it
Brett Cannon83358c92013-06-20 21:30:32 -04001359 and return a code object as a new reference. */
Just van Rossum52e14d62002-12-30 22:08:05 +00001360static PyObject *
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001361compile_source(PyObject *pathname, PyObject *source)
Just van Rossum52e14d62002-12-30 22:08:05 +00001362{
Steve Dower8dcc48e2016-09-09 17:27:33 -07001363 PyObject *code, *fixed_source;
Just van Rossum52e14d62002-12-30 22:08:05 +00001364
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001365 fixed_source = normalize_line_endings(source);
1366 if (fixed_source == NULL) {
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001367 return NULL;
1368 }
1369
Steve Dower8dcc48e2016-09-09 17:27:33 -07001370 code = Py_CompileStringObject(PyBytes_AsString(fixed_source),
Berker Peksag4aa74c42016-09-14 08:09:48 +03001371 pathname, Py_file_input, NULL, -1);
Steve Dower8dcc48e2016-09-09 17:27:33 -07001372
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001373 Py_DECREF(fixed_source);
1374 return code;
Just van Rossum52e14d62002-12-30 22:08:05 +00001375}
1376
1377/* Convert the date/time values found in the Zip archive to a value
1378 that's compatible with the time stamp stored in .pyc files. */
Neal Norwitz29fd2ba2003-03-23 13:21:03 +00001379static time_t
1380parse_dostime(int dostime, int dosdate)
Just van Rossum52e14d62002-12-30 22:08:05 +00001381{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001382 struct tm stm;
Just van Rossum52e14d62002-12-30 22:08:05 +00001383
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001384 memset((void *) &stm, '\0', sizeof(stm));
Christian Heimes679db4a2008-01-18 09:56:22 +00001385
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001386 stm.tm_sec = (dostime & 0x1f) * 2;
1387 stm.tm_min = (dostime >> 5) & 0x3f;
1388 stm.tm_hour = (dostime >> 11) & 0x1f;
1389 stm.tm_mday = dosdate & 0x1f;
1390 stm.tm_mon = ((dosdate >> 5) & 0x0f) - 1;
1391 stm.tm_year = ((dosdate >> 9) & 0x7f) + 80;
1392 stm.tm_isdst = -1; /* wday/yday is ignored */
Just van Rossum52e14d62002-12-30 22:08:05 +00001393
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001394 return mktime(&stm);
Just van Rossum52e14d62002-12-30 22:08:05 +00001395}
1396
Brett Cannonf299abd2015-04-13 14:21:02 -04001397/* Given a path to a .pyc file in the archive, return the
Ezio Melotti13925002011-03-16 11:05:33 +02001398 modification time of the matching .py file, or 0 if no source
Just van Rossum52e14d62002-12-30 22:08:05 +00001399 is available. */
1400static time_t
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001401get_mtime_of_source(ZipImporter *self, PyObject *path)
Just van Rossum52e14d62002-12-30 22:08:05 +00001402{
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001403 PyObject *toc_entry, *stripped;
1404 time_t mtime;
1405
1406 /* strip 'c' or 'o' from *.py[co] */
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001407 if (PyUnicode_READY(path) == -1)
1408 return (time_t)-1;
1409 stripped = PyUnicode_FromKindAndData(PyUnicode_KIND(path),
1410 PyUnicode_DATA(path),
1411 PyUnicode_GET_LENGTH(path) - 1);
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001412 if (stripped == NULL)
1413 return (time_t)-1;
1414
1415 toc_entry = PyDict_GetItem(self->files, stripped);
1416 Py_DECREF(stripped);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001417 if (toc_entry != NULL && PyTuple_Check(toc_entry) &&
1418 PyTuple_Size(toc_entry) == 8) {
1419 /* fetch the time stamp of the .py file for comparison
1420 with an embedded pyc time stamp */
1421 int time, date;
1422 time = PyLong_AsLong(PyTuple_GetItem(toc_entry, 5));
1423 date = PyLong_AsLong(PyTuple_GetItem(toc_entry, 6));
1424 mtime = parse_dostime(time, date);
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001425 } else
1426 mtime = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001427 return mtime;
Just van Rossum52e14d62002-12-30 22:08:05 +00001428}
1429
1430/* Return the code object for the module named by 'fullname' from the
1431 Zip archive as a new reference. */
1432static PyObject *
Benjamin Peterson34c15402014-02-16 14:17:28 -05001433get_code_from_data(ZipImporter *self, int ispackage, int isbytecode,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001434 time_t mtime, PyObject *toc_entry)
Just van Rossum52e14d62002-12-30 22:08:05 +00001435{
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001436 PyObject *data, *modpath, *code;
Just van Rossum52e14d62002-12-30 22:08:05 +00001437
Benjamin Peterson34c15402014-02-16 14:17:28 -05001438 data = get_data(self->archive, toc_entry);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001439 if (data == NULL)
1440 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +00001441
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001442 modpath = PyTuple_GetItem(toc_entry, 0);
Victor Stinner2a94f4c2010-10-18 12:15:34 +00001443 if (isbytecode)
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001444 code = unmarshal_code(modpath, data, mtime);
Victor Stinner2a94f4c2010-10-18 12:15:34 +00001445 else
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001446 code = compile_source(modpath, data);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001447 Py_DECREF(data);
1448 return code;
Just van Rossum52e14d62002-12-30 22:08:05 +00001449}
1450
Ezio Melotti42da6632011-03-15 05:18:48 +02001451/* Get the code object associated with the module specified by
Just van Rossum52e14d62002-12-30 22:08:05 +00001452 'fullname'. */
1453static PyObject *
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001454get_module_code(ZipImporter *self, PyObject *fullname,
Victor Stinner08654e12010-10-18 12:09:02 +00001455 int *p_ispackage, PyObject **p_modpath)
Just van Rossum52e14d62002-12-30 22:08:05 +00001456{
Gregory P. Smith95c7c462011-05-21 05:19:42 -07001457 PyObject *code = NULL, *toc_entry, *subname;
Victor Stinner9a2261a2011-05-26 13:59:41 +02001458 PyObject *path, *fullpath = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001459 struct st_zip_searchorder *zso;
Just van Rossum52e14d62002-12-30 22:08:05 +00001460
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001461 subname = get_subname(fullname);
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001462 if (subname == NULL)
1463 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +00001464
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001465 path = make_filename(self->prefix, subname);
1466 Py_DECREF(subname);
1467 if (path == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001468 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +00001469
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001470 for (zso = zip_searchorder; *zso->suffix; zso++) {
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001471 code = NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +00001472
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001473 fullpath = PyUnicode_FromFormat("%U%s", path, zso->suffix);
1474 if (fullpath == NULL)
1475 goto exit;
1476
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001477 if (Py_VerboseFlag > 1)
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001478 PySys_FormatStderr("# trying %U%c%U\n",
1479 self->archive, (int)SEP, fullpath);
1480 toc_entry = PyDict_GetItem(self->files, fullpath);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001481 if (toc_entry != NULL) {
1482 time_t mtime = 0;
1483 int ispackage = zso->type & IS_PACKAGE;
1484 int isbytecode = zso->type & IS_BYTECODE;
Just van Rossum52e14d62002-12-30 22:08:05 +00001485
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001486 if (isbytecode) {
1487 mtime = get_mtime_of_source(self, fullpath);
1488 if (mtime == (time_t)-1 && PyErr_Occurred()) {
1489 goto exit;
1490 }
1491 }
1492 Py_CLEAR(fullpath);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001493 if (p_ispackage != NULL)
1494 *p_ispackage = ispackage;
Benjamin Peterson34c15402014-02-16 14:17:28 -05001495 code = get_code_from_data(self, ispackage,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001496 isbytecode, mtime,
1497 toc_entry);
1498 if (code == Py_None) {
1499 /* bad magic number or non-matching mtime
1500 in byte code, try next */
1501 Py_DECREF(code);
1502 continue;
1503 }
Victor Stinner08654e12010-10-18 12:09:02 +00001504 if (code != NULL && p_modpath != NULL) {
1505 *p_modpath = PyTuple_GetItem(toc_entry, 0);
1506 Py_INCREF(*p_modpath);
1507 }
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001508 goto exit;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001509 }
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001510 else
1511 Py_CLEAR(fullpath);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001512 }
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001513 PyErr_Format(ZipImportError, "can't find module %R", fullname);
1514exit:
1515 Py_DECREF(path);
1516 Py_XDECREF(fullpath);
1517 return code;
Just van Rossum52e14d62002-12-30 22:08:05 +00001518}
1519
1520
1521/* Module init */
1522
1523PyDoc_STRVAR(zipimport_doc,
1524"zipimport provides support for importing Python modules from Zip archives.\n\
1525\n\
1526This module exports three objects:\n\
1527- zipimporter: a class; its constructor takes a path to a Zip archive.\n\
Fredrik Lundhb84b35f2006-01-15 15:00:40 +00001528- ZipImportError: exception raised by zipimporter objects. It's a\n\
Just van Rossum52e14d62002-12-30 22:08:05 +00001529 subclass of ImportError, so it can be caught as ImportError, too.\n\
1530- _zip_directory_cache: a dict, mapping archive paths to zip directory\n\
1531 info dicts, as used in zipimporter._files.\n\
1532\n\
1533It is usually not needed to use the zipimport module explicitly; it is\n\
1534used by the builtin import mechanism for sys.path items that are paths\n\
1535to Zip archives.");
1536
Martin v. Löwis1a214512008-06-11 05:26:20 +00001537static struct PyModuleDef zipimportmodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001538 PyModuleDef_HEAD_INIT,
1539 "zipimport",
1540 zipimport_doc,
1541 -1,
1542 NULL,
1543 NULL,
1544 NULL,
1545 NULL,
1546 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +00001547};
1548
Just van Rossum52e14d62002-12-30 22:08:05 +00001549PyMODINIT_FUNC
Martin v. Löwis1a214512008-06-11 05:26:20 +00001550PyInit_zipimport(void)
Just van Rossum52e14d62002-12-30 22:08:05 +00001551{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001552 PyObject *mod;
Just van Rossum52e14d62002-12-30 22:08:05 +00001553
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001554 if (PyType_Ready(&ZipImporter_Type) < 0)
1555 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +00001556
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001557 /* Correct directory separator */
1558 zip_searchorder[0].suffix[0] = SEP;
1559 zip_searchorder[1].suffix[0] = SEP;
Just van Rossum52e14d62002-12-30 22:08:05 +00001560
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001561 mod = PyModule_Create(&zipimportmodule);
1562 if (mod == NULL)
1563 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +00001564
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001565 ZipImportError = PyErr_NewException("zipimport.ZipImportError",
1566 PyExc_ImportError, NULL);
1567 if (ZipImportError == NULL)
1568 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +00001569
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001570 Py_INCREF(ZipImportError);
1571 if (PyModule_AddObject(mod, "ZipImportError",
1572 ZipImportError) < 0)
1573 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +00001574
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001575 Py_INCREF(&ZipImporter_Type);
1576 if (PyModule_AddObject(mod, "zipimporter",
1577 (PyObject *)&ZipImporter_Type) < 0)
1578 return NULL;
Just van Rossumf8b6de12002-12-31 09:51:59 +00001579
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001580 zip_directory_cache = PyDict_New();
1581 if (zip_directory_cache == NULL)
1582 return NULL;
1583 Py_INCREF(zip_directory_cache);
1584 if (PyModule_AddObject(mod, "_zip_directory_cache",
1585 zip_directory_cache) < 0)
1586 return NULL;
1587 return mod;
Just van Rossum52e14d62002-12-30 22:08:05 +00001588}