blob: 0a7cd0ffc0864992d1286af7bf13509df1ae605d [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 Pitrouc83ea132010-05-09 14:46:46 +000013 char suffix[14];
14 int type;
Just van Rossum52e14d62002-12-30 22:08:05 +000015};
16
17/* zip_searchorder defines how we search for a module in the Zip
18 archive: we first search for a package __init__, then for
19 non-package .pyc, .pyo and .py entries. The .pyc and .pyo entries
20 are swapped by initzipimport() if we run in optimized mode. Also,
21 '/' is replaced by SEP there. */
Neal Norwitz29fd2ba2003-03-23 13:21:03 +000022static struct st_zip_searchorder zip_searchorder[] = {
Antoine Pitrouc83ea132010-05-09 14:46:46 +000023 {"/__init__.pyc", IS_PACKAGE | IS_BYTECODE},
24 {"/__init__.pyo", IS_PACKAGE | IS_BYTECODE},
25 {"/__init__.py", IS_PACKAGE | IS_SOURCE},
26 {".pyc", IS_BYTECODE},
27 {".pyo", IS_BYTECODE},
28 {".py", IS_SOURCE},
29 {"", 0}
Just van Rossum52e14d62002-12-30 22:08:05 +000030};
31
32/* zipimporter object definition and support */
33
34typedef struct _zipimporter ZipImporter;
35
36struct _zipimporter {
Antoine Pitrouc83ea132010-05-09 14:46:46 +000037 PyObject_HEAD
38 PyObject *archive; /* pathname of the Zip archive */
39 PyObject *prefix; /* file prefix: "a/sub/directory/" */
40 PyObject *files; /* dict with file info {path: toc_entry} */
Just van Rossum52e14d62002-12-30 22:08:05 +000041};
42
Just van Rossum52e14d62002-12-30 22:08:05 +000043static PyObject *ZipImportError;
44static PyObject *zip_directory_cache = NULL;
45
Nan Zhangced27512017-06-19 18:01:34 -070046// GOOGLE(nanzhang): Changed two functions below to be visible to launcher so
47// that launcher can access the zip metadata section.
Just van Rossum52e14d62002-12-30 22:08:05 +000048/* forward decls */
Nan Zhangced27512017-06-19 18:01:34 -070049PyObject *read_directory(const char *archive);
50PyObject *get_data(const char *archive, PyObject *toc_entry);
Just van Rossum52e14d62002-12-30 22:08:05 +000051static PyObject *get_module_code(ZipImporter *self, char *fullname,
Antoine Pitrouc83ea132010-05-09 14:46:46 +000052 int *p_ispackage, char **p_modpath);
Just van Rossum52e14d62002-12-30 22:08:05 +000053
54
55#define ZipImporter_Check(op) PyObject_TypeCheck(op, &ZipImporter_Type)
56
57
58/* zipimporter.__init__
59 Split the "subdirectory" from the Zip archive path, lookup a matching
60 entry in sys.path_importer_cache, fetch the file directory from there
61 if found, or else read it from the archive. */
62static int
63zipimporter_init(ZipImporter *self, PyObject *args, PyObject *kwds)
64{
Benjamin Petersone9aab0f2014-02-16 14:20:14 -050065 char *path, *p, *prefix, buf[MAXPATHLEN+2];
Antoine Pitrouc83ea132010-05-09 14:46:46 +000066 size_t len;
Just van Rossum52e14d62002-12-30 22:08:05 +000067
Antoine Pitrouc83ea132010-05-09 14:46:46 +000068 if (!_PyArg_NoKeywords("zipimporter()", kwds))
69 return -1;
Georg Brandl02c42872005-08-26 06:42:30 +000070
Benjamin Petersone9aab0f2014-02-16 14:20:14 -050071 if (!PyArg_ParseTuple(args, "s:zipimporter",
72 &path))
Antoine Pitrouc83ea132010-05-09 14:46:46 +000073 return -1;
Just van Rossum52e14d62002-12-30 22:08:05 +000074
Benjamin Petersone9aab0f2014-02-16 14:20:14 -050075 len = strlen(path);
Antoine Pitrouc83ea132010-05-09 14:46:46 +000076 if (len == 0) {
77 PyErr_SetString(ZipImportError, "archive path is empty");
78 return -1;
79 }
80 if (len >= MAXPATHLEN) {
Benjamin Petersone9aab0f2014-02-16 14:20:14 -050081 PyErr_SetString(ZipImportError,
82 "archive path too long");
Antoine Pitrouc83ea132010-05-09 14:46:46 +000083 return -1;
84 }
Benjamin Petersone9aab0f2014-02-16 14:20:14 -050085 strcpy(buf, path);
Just van Rossum52e14d62002-12-30 22:08:05 +000086
87#ifdef ALTSEP
Benjamin Petersone9aab0f2014-02-16 14:20:14 -050088 for (p = buf; *p; p++) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +000089 if (*p == ALTSEP)
90 *p = SEP;
91 }
Just van Rossum52e14d62002-12-30 22:08:05 +000092#endif
93
Antoine Pitrouc83ea132010-05-09 14:46:46 +000094 path = NULL;
95 prefix = NULL;
96 for (;;) {
Martin v. Löwisa94568a2003-05-10 07:36:56 +000097#ifndef RISCOS
Antoine Pitrouc83ea132010-05-09 14:46:46 +000098 struct stat statbuf;
99 int rv;
Just van Rossum52e14d62002-12-30 22:08:05 +0000100
Benjamin Petersone9aab0f2014-02-16 14:20:14 -0500101 rv = stat(buf, &statbuf);
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000102 if (rv == 0) {
103 /* it exists */
104 if (S_ISREG(statbuf.st_mode))
105 /* it's a file */
Benjamin Petersone9aab0f2014-02-16 14:20:14 -0500106 path = buf;
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000107 break;
108 }
Martin v. Löwisa94568a2003-05-10 07:36:56 +0000109#else
Benjamin Petersone9aab0f2014-02-16 14:20:14 -0500110 if (object_exists(buf)) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000111 /* it exists */
Benjamin Petersone9aab0f2014-02-16 14:20:14 -0500112 if (isfile(buf))
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000113 /* it's a file */
Benjamin Petersone9aab0f2014-02-16 14:20:14 -0500114 path = buf;
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000115 break;
116 }
Martin v. Löwisa94568a2003-05-10 07:36:56 +0000117#endif
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000118 /* back up one path element */
Benjamin Petersone9aab0f2014-02-16 14:20:14 -0500119 p = strrchr(buf, SEP);
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000120 if (prefix != NULL)
121 *prefix = SEP;
122 if (p == NULL)
123 break;
124 *p = '\0';
125 prefix = p;
126 }
127 if (path != NULL) {
128 PyObject *files;
129 files = PyDict_GetItemString(zip_directory_cache, path);
130 if (files == NULL) {
Benjamin Peterson384e9cb2014-02-16 14:46:57 -0500131 files = read_directory(buf);
132 if (files == NULL)
Benjamin Petersone9aab0f2014-02-16 14:20:14 -0500133 return -1;
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000134 if (PyDict_SetItemString(zip_directory_cache, path,
Benjamin Peterson384e9cb2014-02-16 14:46:57 -0500135 files) != 0)
Benjamin Petersone9aab0f2014-02-16 14:20:14 -0500136 return -1;
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000137 }
Benjamin Petersone9aab0f2014-02-16 14:20:14 -0500138 else
139 Py_INCREF(files);
140 self->files = files;
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000141 }
142 else {
143 PyErr_SetString(ZipImportError, "not a Zip file");
Benjamin Petersone9aab0f2014-02-16 14:20:14 -0500144 return -1;
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000145 }
Just van Rossum52e14d62002-12-30 22:08:05 +0000146
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000147 if (prefix == NULL)
148 prefix = "";
149 else {
150 prefix++;
151 len = strlen(prefix);
152 if (prefix[len-1] != SEP) {
153 /* add trailing SEP */
154 prefix[len] = SEP;
155 prefix[len + 1] = '\0';
156 }
157 }
Just van Rossum52e14d62002-12-30 22:08:05 +0000158
Benjamin Petersone9aab0f2014-02-16 14:20:14 -0500159 self->archive = PyString_FromString(buf);
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000160 if (self->archive == NULL)
Benjamin Petersone9aab0f2014-02-16 14:20:14 -0500161 return -1;
Just van Rossum52e14d62002-12-30 22:08:05 +0000162
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000163 self->prefix = PyString_FromString(prefix);
164 if (self->prefix == NULL)
Benjamin Petersone9aab0f2014-02-16 14:20:14 -0500165 return -1;
Just van Rossum52e14d62002-12-30 22:08:05 +0000166
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000167 return 0;
Benjamin Petersone9aab0f2014-02-16 14:20:14 -0500168}
169
170/* GC support. */
171static int
172zipimporter_traverse(PyObject *obj, visitproc visit, void *arg)
173{
174 ZipImporter *self = (ZipImporter *)obj;
175 Py_VISIT(self->files);
176 return 0;
Just van Rossum52e14d62002-12-30 22:08:05 +0000177}
178
179static void
180zipimporter_dealloc(ZipImporter *self)
181{
Benjamin Petersone9aab0f2014-02-16 14:20:14 -0500182 PyObject_GC_UnTrack(self);
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000183 Py_XDECREF(self->archive);
184 Py_XDECREF(self->prefix);
Benjamin Petersone9aab0f2014-02-16 14:20:14 -0500185 Py_XDECREF(self->files);
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000186 Py_TYPE(self)->tp_free((PyObject *)self);
Just van Rossum52e14d62002-12-30 22:08:05 +0000187}
188
189static PyObject *
190zipimporter_repr(ZipImporter *self)
191{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000192 char buf[500];
193 char *archive = "???";
194 char *prefix = "";
Just van Rossum52e14d62002-12-30 22:08:05 +0000195
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000196 if (self->archive != NULL && PyString_Check(self->archive))
197 archive = PyString_AsString(self->archive);
198 if (self->prefix != NULL && PyString_Check(self->prefix))
199 prefix = PyString_AsString(self->prefix);
200 if (prefix != NULL && *prefix)
201 PyOS_snprintf(buf, sizeof(buf),
202 "<zipimporter object \"%.300s%c%.150s\">",
203 archive, SEP, prefix);
204 else
205 PyOS_snprintf(buf, sizeof(buf),
206 "<zipimporter object \"%.300s\">",
207 archive);
208 return PyString_FromString(buf);
Just van Rossum52e14d62002-12-30 22:08:05 +0000209}
210
211/* return fullname.split(".")[-1] */
212static char *
213get_subname(char *fullname)
214{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000215 char *subname = strrchr(fullname, '.');
216 if (subname == NULL)
217 subname = fullname;
218 else
219 subname++;
220 return subname;
Just van Rossum52e14d62002-12-30 22:08:05 +0000221}
222
223/* Given a (sub)modulename, write the potential file path in the
224 archive (without extension) to the path buffer. Return the
225 length of the resulting string. */
226static int
227make_filename(char *prefix, char *name, char *path)
228{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000229 size_t len;
230 char *p;
Just van Rossum52e14d62002-12-30 22:08:05 +0000231
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000232 len = strlen(prefix);
Just van Rossum52e14d62002-12-30 22:08:05 +0000233
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000234 /* self.prefix + name [+ SEP + "__init__"] + ".py[co]" */
235 if (len + strlen(name) + 13 >= MAXPATHLEN) {
236 PyErr_SetString(ZipImportError, "path too long");
237 return -1;
238 }
Just van Rossum52e14d62002-12-30 22:08:05 +0000239
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000240 strcpy(path, prefix);
241 strcpy(path + len, name);
242 for (p = path + len; *p; p++) {
243 if (*p == '.')
244 *p = SEP;
245 }
246 len += strlen(name);
247 assert(len < INT_MAX);
248 return (int)len;
Just van Rossum52e14d62002-12-30 22:08:05 +0000249}
250
Raymond Hettinger2c45c9a2004-11-10 13:08:35 +0000251enum zi_module_info {
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000252 MI_ERROR,
253 MI_NOT_FOUND,
254 MI_MODULE,
255 MI_PACKAGE
Just van Rossum52e14d62002-12-30 22:08:05 +0000256};
257
258/* Return some information about a module. */
Raymond Hettinger2c45c9a2004-11-10 13:08:35 +0000259static enum zi_module_info
Just van Rossum52e14d62002-12-30 22:08:05 +0000260get_module_info(ZipImporter *self, char *fullname)
261{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000262 char *subname, path[MAXPATHLEN + 1];
263 int len;
264 struct st_zip_searchorder *zso;
Just van Rossum52e14d62002-12-30 22:08:05 +0000265
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000266 subname = get_subname(fullname);
Just van Rossum52e14d62002-12-30 22:08:05 +0000267
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000268 len = make_filename(PyString_AsString(self->prefix), subname, path);
269 if (len < 0)
270 return MI_ERROR;
Just van Rossum52e14d62002-12-30 22:08:05 +0000271
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000272 for (zso = zip_searchorder; *zso->suffix; zso++) {
273 strcpy(path + len, zso->suffix);
Benjamin Petersone9aab0f2014-02-16 14:20:14 -0500274 if (PyDict_GetItemString(self->files, path) != NULL) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000275 if (zso->type & IS_PACKAGE)
276 return MI_PACKAGE;
277 else
278 return MI_MODULE;
279 }
280 }
281 return MI_NOT_FOUND;
Just van Rossum52e14d62002-12-30 22:08:05 +0000282}
283
284/* Check whether we can satisfy the import of the module named by
285 'fullname'. Return self if we can, None if we can't. */
286static PyObject *
287zipimporter_find_module(PyObject *obj, PyObject *args)
288{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000289 ZipImporter *self = (ZipImporter *)obj;
290 PyObject *path = NULL;
291 char *fullname;
292 enum zi_module_info mi;
Just van Rossum52e14d62002-12-30 22:08:05 +0000293
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000294 if (!PyArg_ParseTuple(args, "s|O:zipimporter.find_module",
295 &fullname, &path))
296 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +0000297
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000298 mi = get_module_info(self, fullname);
299 if (mi == MI_ERROR)
300 return NULL;
301 if (mi == MI_NOT_FOUND) {
302 Py_INCREF(Py_None);
303 return Py_None;
304 }
305 Py_INCREF(self);
306 return (PyObject *)self;
Just van Rossum52e14d62002-12-30 22:08:05 +0000307}
308
309/* Load and return the module named by 'fullname'. */
310static PyObject *
311zipimporter_load_module(PyObject *obj, PyObject *args)
312{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000313 ZipImporter *self = (ZipImporter *)obj;
314 PyObject *code, *mod, *dict;
315 char *fullname, *modpath;
316 int ispackage;
Just van Rossum52e14d62002-12-30 22:08:05 +0000317
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000318 if (!PyArg_ParseTuple(args, "s:zipimporter.load_module",
319 &fullname))
320 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +0000321
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000322 code = get_module_code(self, fullname, &ispackage, &modpath);
323 if (code == NULL)
324 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +0000325
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000326 mod = PyImport_AddModule(fullname);
327 if (mod == NULL) {
328 Py_DECREF(code);
329 return NULL;
330 }
331 dict = PyModule_GetDict(mod);
Just van Rossum52e14d62002-12-30 22:08:05 +0000332
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000333 /* mod.__loader__ = self */
334 if (PyDict_SetItemString(dict, "__loader__", (PyObject *)self) != 0)
335 goto error;
Just van Rossum52e14d62002-12-30 22:08:05 +0000336
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000337 if (ispackage) {
338 /* add __path__ to the module *before* the code gets
339 executed */
340 PyObject *pkgpath, *fullpath;
341 char *prefix = PyString_AsString(self->prefix);
342 char *subname = get_subname(fullname);
343 int err;
Just van Rossum52e14d62002-12-30 22:08:05 +0000344
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000345 fullpath = PyString_FromFormat("%s%c%s%s",
346 PyString_AsString(self->archive),
347 SEP,
348 *prefix ? prefix : "",
349 subname);
350 if (fullpath == NULL)
351 goto error;
Just van Rossum52e14d62002-12-30 22:08:05 +0000352
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000353 pkgpath = Py_BuildValue("[O]", fullpath);
354 Py_DECREF(fullpath);
355 if (pkgpath == NULL)
356 goto error;
357 err = PyDict_SetItemString(dict, "__path__", pkgpath);
358 Py_DECREF(pkgpath);
359 if (err != 0)
360 goto error;
361 }
362 mod = PyImport_ExecCodeModuleEx(fullname, code, modpath);
363 Py_DECREF(code);
364 if (Py_VerboseFlag)
365 PySys_WriteStderr("import %s # loaded from Zip %s\n",
366 fullname, modpath);
367 return mod;
Just van Rossum52e14d62002-12-30 22:08:05 +0000368error:
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000369 Py_DECREF(code);
370 Py_DECREF(mod);
371 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +0000372}
373
Nick Coghlana2053472008-12-14 10:54:50 +0000374/* Return a string matching __file__ for the named module */
375static PyObject *
376zipimporter_get_filename(PyObject *obj, PyObject *args)
377{
378 ZipImporter *self = (ZipImporter *)obj;
379 PyObject *code;
380 char *fullname, *modpath;
381 int ispackage;
382
Nick Coghlan0194f5b2009-02-08 03:17:00 +0000383 if (!PyArg_ParseTuple(args, "s:zipimporter.get_filename",
Nick Coghlana2053472008-12-14 10:54:50 +0000384 &fullname))
Martin Panter5f755022016-09-15 01:50:53 +0000385 return NULL;
Nick Coghlana2053472008-12-14 10:54:50 +0000386
387 /* Deciding the filename requires working out where the code
388 would come from if the module was actually loaded */
389 code = get_module_code(self, fullname, &ispackage, &modpath);
390 if (code == NULL)
Martin Panter5f755022016-09-15 01:50:53 +0000391 return NULL;
Nick Coghlana2053472008-12-14 10:54:50 +0000392 Py_DECREF(code); /* Only need the path info */
393
394 return PyString_FromString(modpath);
395}
396
Just van Rossum52e14d62002-12-30 22:08:05 +0000397/* Return a bool signifying whether the module is a package or not. */
398static PyObject *
399zipimporter_is_package(PyObject *obj, PyObject *args)
400{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000401 ZipImporter *self = (ZipImporter *)obj;
402 char *fullname;
403 enum zi_module_info mi;
Just van Rossum52e14d62002-12-30 22:08:05 +0000404
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000405 if (!PyArg_ParseTuple(args, "s:zipimporter.is_package",
406 &fullname))
407 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +0000408
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000409 mi = get_module_info(self, fullname);
410 if (mi == MI_ERROR)
411 return NULL;
412 if (mi == MI_NOT_FOUND) {
413 PyErr_Format(ZipImportError, "can't find module '%.200s'",
414 fullname);
415 return NULL;
416 }
417 return PyBool_FromLong(mi == MI_PACKAGE);
Just van Rossum52e14d62002-12-30 22:08:05 +0000418}
419
420static PyObject *
421zipimporter_get_data(PyObject *obj, PyObject *args)
422{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000423 ZipImporter *self = (ZipImporter *)obj;
Benjamin Peterson384e9cb2014-02-16 14:46:57 -0500424 char *path;
Just van Rossum52e14d62002-12-30 22:08:05 +0000425#ifdef ALTSEP
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000426 char *p, buf[MAXPATHLEN + 1];
Just van Rossum52e14d62002-12-30 22:08:05 +0000427#endif
Benjamin Peterson384e9cb2014-02-16 14:46:57 -0500428 PyObject *toc_entry;
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000429 Py_ssize_t len;
Just van Rossum52e14d62002-12-30 22:08:05 +0000430
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000431 if (!PyArg_ParseTuple(args, "s:zipimporter.get_data", &path))
432 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +0000433
434#ifdef ALTSEP
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000435 if (strlen(path) >= MAXPATHLEN) {
436 PyErr_SetString(ZipImportError, "path too long");
437 return NULL;
438 }
439 strcpy(buf, path);
440 for (p = buf; *p; p++) {
441 if (*p == ALTSEP)
442 *p = SEP;
443 }
444 path = buf;
Just van Rossum52e14d62002-12-30 22:08:05 +0000445#endif
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000446 len = PyString_Size(self->archive);
447 if ((size_t)len < strlen(path) &&
448 strncmp(path, PyString_AsString(self->archive), len) == 0 &&
449 path[len] == SEP) {
450 path = path + len + 1;
451 }
Just van Rossum52e14d62002-12-30 22:08:05 +0000452
Benjamin Petersone9aab0f2014-02-16 14:20:14 -0500453 toc_entry = PyDict_GetItemString(self->files, path);
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000454 if (toc_entry == NULL) {
455 PyErr_SetFromErrnoWithFilename(PyExc_IOError, path);
456 return NULL;
457 }
Benjamin Peterson384e9cb2014-02-16 14:46:57 -0500458 return get_data(PyString_AsString(self->archive), toc_entry);
Just van Rossum52e14d62002-12-30 22:08:05 +0000459}
460
461static PyObject *
462zipimporter_get_code(PyObject *obj, PyObject *args)
463{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000464 ZipImporter *self = (ZipImporter *)obj;
465 char *fullname;
Just van Rossum52e14d62002-12-30 22:08:05 +0000466
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000467 if (!PyArg_ParseTuple(args, "s:zipimporter.get_code", &fullname))
468 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +0000469
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000470 return get_module_code(self, fullname, NULL, NULL);
Just van Rossum52e14d62002-12-30 22:08:05 +0000471}
472
473static PyObject *
474zipimporter_get_source(PyObject *obj, PyObject *args)
475{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000476 ZipImporter *self = (ZipImporter *)obj;
Benjamin Petersone9aab0f2014-02-16 14:20:14 -0500477 PyObject *toc_entry;
Benjamin Peterson384e9cb2014-02-16 14:46:57 -0500478 char *fullname, *subname, path[MAXPATHLEN+1];
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000479 int len;
480 enum zi_module_info mi;
Just van Rossum52e14d62002-12-30 22:08:05 +0000481
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000482 if (!PyArg_ParseTuple(args, "s:zipimporter.get_source", &fullname))
483 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +0000484
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000485 mi = get_module_info(self, fullname);
486 if (mi == MI_ERROR)
487 return NULL;
488 if (mi == MI_NOT_FOUND) {
489 PyErr_Format(ZipImportError, "can't find module '%.200s'",
490 fullname);
491 return NULL;
492 }
493 subname = get_subname(fullname);
Just van Rossum52e14d62002-12-30 22:08:05 +0000494
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000495 len = make_filename(PyString_AsString(self->prefix), subname, path);
496 if (len < 0)
497 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +0000498
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000499 if (mi == MI_PACKAGE) {
500 path[len] = SEP;
501 strcpy(path + len + 1, "__init__.py");
502 }
503 else
504 strcpy(path + len, ".py");
Just van Rossum52e14d62002-12-30 22:08:05 +0000505
Benjamin Petersone9aab0f2014-02-16 14:20:14 -0500506 toc_entry = PyDict_GetItemString(self->files, path);
Benjamin Peterson384e9cb2014-02-16 14:46:57 -0500507 if (toc_entry != NULL)
508 return get_data(PyString_AsString(self->archive), toc_entry);
Just van Rossum52e14d62002-12-30 22:08:05 +0000509
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000510 /* we have the module, but no source */
Benjamin Peterson384e9cb2014-02-16 14:46:57 -0500511 Py_INCREF(Py_None);
512 return Py_None;
Just van Rossum52e14d62002-12-30 22:08:05 +0000513}
514
515PyDoc_STRVAR(doc_find_module,
516"find_module(fullname, path=None) -> self or None.\n\
517\n\
518Search for a module specified by 'fullname'. 'fullname' must be the\n\
519fully qualified (dotted) module name. It returns the zipimporter\n\
520instance itself if the module was found, or None if it wasn't.\n\
521The optional 'path' argument is ignored -- it's there for compatibility\n\
522with the importer protocol.");
523
524PyDoc_STRVAR(doc_load_module,
525"load_module(fullname) -> module.\n\
526\n\
527Load the module specified by 'fullname'. 'fullname' must be the\n\
528fully qualified (dotted) module name. It returns the imported\n\
529module, or raises ZipImportError if it wasn't found.");
530
531PyDoc_STRVAR(doc_get_data,
532"get_data(pathname) -> string with file data.\n\
533\n\
534Return the data associated with 'pathname'. Raise IOError if\n\
535the file wasn't found.");
536
537PyDoc_STRVAR(doc_is_package,
538"is_package(fullname) -> bool.\n\
539\n\
540Return True if the module specified by fullname is a package.\n\
Brian Curtin13b43e72010-07-21 01:35:46 +0000541Raise ZipImportError if the module couldn't be found.");
Just van Rossum52e14d62002-12-30 22:08:05 +0000542
543PyDoc_STRVAR(doc_get_code,
544"get_code(fullname) -> code object.\n\
545\n\
546Return the code object for the specified module. Raise ZipImportError\n\
Brian Curtin13b43e72010-07-21 01:35:46 +0000547if the module couldn't be found.");
Just van Rossum52e14d62002-12-30 22:08:05 +0000548
549PyDoc_STRVAR(doc_get_source,
550"get_source(fullname) -> source string.\n\
551\n\
552Return the source code for the specified module. Raise ZipImportError\n\
Brian Curtin13b43e72010-07-21 01:35:46 +0000553if the module couldn't be found, return None if the archive does\n\
Just van Rossum52e14d62002-12-30 22:08:05 +0000554contain the module, but has no source for it.");
555
Nick Coghlana2053472008-12-14 10:54:50 +0000556
557PyDoc_STRVAR(doc_get_filename,
Nick Coghlan0194f5b2009-02-08 03:17:00 +0000558"get_filename(fullname) -> filename string.\n\
Nick Coghlana2053472008-12-14 10:54:50 +0000559\n\
560Return the filename for the specified module.");
561
Just van Rossum52e14d62002-12-30 22:08:05 +0000562static PyMethodDef zipimporter_methods[] = {
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000563 {"find_module", zipimporter_find_module, METH_VARARGS,
564 doc_find_module},
565 {"load_module", zipimporter_load_module, METH_VARARGS,
566 doc_load_module},
567 {"get_data", zipimporter_get_data, METH_VARARGS,
568 doc_get_data},
569 {"get_code", zipimporter_get_code, METH_VARARGS,
570 doc_get_code},
571 {"get_source", zipimporter_get_source, METH_VARARGS,
572 doc_get_source},
573 {"get_filename", zipimporter_get_filename, METH_VARARGS,
574 doc_get_filename},
575 {"is_package", zipimporter_is_package, METH_VARARGS,
576 doc_is_package},
577 {NULL, NULL} /* sentinel */
Just van Rossum52e14d62002-12-30 22:08:05 +0000578};
579
580static PyMemberDef zipimporter_members[] = {
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000581 {"archive", T_OBJECT, offsetof(ZipImporter, archive), READONLY},
582 {"prefix", T_OBJECT, offsetof(ZipImporter, prefix), READONLY},
583 {"_files", T_OBJECT, offsetof(ZipImporter, files), READONLY},
584 {NULL}
Just van Rossum52e14d62002-12-30 22:08:05 +0000585};
586
587PyDoc_STRVAR(zipimporter_doc,
588"zipimporter(archivepath) -> zipimporter object\n\
589\n\
590Create a new zipimporter instance. 'archivepath' must be a path to\n\
Georg Brandl6a57c082008-05-11 15:05:13 +0000591a zipfile, or to a specific path inside a zipfile. For example, it can be\n\
592'/tmp/myimport.zip', or '/tmp/myimport.zip/mydirectory', if mydirectory is a\n\
593valid directory inside the archive.\n\
594\n\
595'ZipImportError is raised if 'archivepath' doesn't point to a valid Zip\n\
596archive.\n\
597\n\
598The 'archive' attribute of zipimporter objects contains the name of the\n\
599zipfile targeted.");
Just van Rossum52e14d62002-12-30 22:08:05 +0000600
601#define DEFERRED_ADDRESS(ADDR) 0
602
603static PyTypeObject ZipImporter_Type = {
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000604 PyVarObject_HEAD_INIT(DEFERRED_ADDRESS(&PyType_Type), 0)
605 "zipimport.zipimporter",
606 sizeof(ZipImporter),
607 0, /* tp_itemsize */
608 (destructor)zipimporter_dealloc, /* tp_dealloc */
609 0, /* tp_print */
610 0, /* tp_getattr */
611 0, /* tp_setattr */
612 0, /* tp_compare */
613 (reprfunc)zipimporter_repr, /* tp_repr */
614 0, /* tp_as_number */
615 0, /* tp_as_sequence */
616 0, /* tp_as_mapping */
617 0, /* tp_hash */
618 0, /* tp_call */
619 0, /* tp_str */
620 PyObject_GenericGetAttr, /* tp_getattro */
621 0, /* tp_setattro */
622 0, /* tp_as_buffer */
Benjamin Petersone9aab0f2014-02-16 14:20:14 -0500623 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE |
624 Py_TPFLAGS_HAVE_GC, /* tp_flags */
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000625 zipimporter_doc, /* tp_doc */
Benjamin Petersone9aab0f2014-02-16 14:20:14 -0500626 zipimporter_traverse, /* tp_traverse */
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000627 0, /* tp_clear */
628 0, /* tp_richcompare */
629 0, /* tp_weaklistoffset */
630 0, /* tp_iter */
631 0, /* tp_iternext */
632 zipimporter_methods, /* tp_methods */
633 zipimporter_members, /* tp_members */
634 0, /* tp_getset */
635 0, /* tp_base */
636 0, /* tp_dict */
637 0, /* tp_descr_get */
638 0, /* tp_descr_set */
639 0, /* tp_dictoffset */
640 (initproc)zipimporter_init, /* tp_init */
641 PyType_GenericAlloc, /* tp_alloc */
642 PyType_GenericNew, /* tp_new */
Benjamin Petersone9aab0f2014-02-16 14:20:14 -0500643 PyObject_GC_Del, /* tp_free */
Just van Rossum52e14d62002-12-30 22:08:05 +0000644};
645
646
647/* implementation */
648
Serhiy Storchakac4ef3842016-01-28 21:32:53 +0200649/* Given a buffer, return the unsigned int that is represented by the first
Just van Rossum52e14d62002-12-30 22:08:05 +0000650 4 bytes, encoded as little endian. This partially reimplements
651 marshal.c:r_long() */
Serhiy Storchakac4ef3842016-01-28 21:32:53 +0200652static unsigned int
653get_uint32(const unsigned char *buf)
654{
655 unsigned int x;
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000656 x = buf[0];
Serhiy Storchakac4ef3842016-01-28 21:32:53 +0200657 x |= (unsigned int)buf[1] << 8;
658 x |= (unsigned int)buf[2] << 16;
659 x |= (unsigned int)buf[3] << 24;
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000660 return x;
Just van Rossum52e14d62002-12-30 22:08:05 +0000661}
662
Serhiy Storchakac4ef3842016-01-28 21:32:53 +0200663/* Given a buffer, return the unsigned int that is represented by the first
664 2 bytes, encoded as little endian. This partially reimplements
665 marshal.c:r_short() */
666static unsigned short
667get_uint16(const unsigned char *buf)
668{
669 unsigned short x;
670 x = buf[0];
671 x |= (unsigned short)buf[1] << 8;
672 return x;
673}
674
675static void
676set_file_error(const char *archive, int eof)
677{
678 if (eof) {
679 PyErr_SetString(PyExc_EOFError, "EOF read where not expected");
680 }
681 else {
682 PyErr_SetFromErrnoWithFilename(PyExc_IOError, archive);
683 }
684}
685
Just van Rossum52e14d62002-12-30 22:08:05 +0000686/*
Benjamin Peterson384e9cb2014-02-16 14:46:57 -0500687 read_directory(archive) -> files dict (new reference)
Just van Rossum52e14d62002-12-30 22:08:05 +0000688
689 Given a path to a Zip archive, build a dict, mapping file names
690 (local to the archive, using SEP as a separator) to toc entries.
691
692 A toc_entry is a tuple:
693
Martin Panter5f755022016-09-15 01:50:53 +0000694 (__file__, # value to use for __file__, available for all files
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000695 compress, # compression kind; 0 for uncompressed
696 data_size, # size of compressed data on disk
697 file_size, # size of decompressed data
698 file_offset, # offset of file header from start of archive
699 time, # mod time of file (in dos format)
700 date, # mod data of file (in dos format)
701 crc, # crc checksum of the data
Martin Panter5f755022016-09-15 01:50:53 +0000702 )
Just van Rossum52e14d62002-12-30 22:08:05 +0000703
704 Directories can be recognized by the trailing SEP in the name,
705 data_size and file_offset are 0.
706*/
Nan Zhangced27512017-06-19 18:01:34 -0700707PyObject *
Serhiy Storchakac4ef3842016-01-28 21:32:53 +0200708read_directory(const char *archive)
Just van Rossum52e14d62002-12-30 22:08:05 +0000709{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000710 PyObject *files = NULL;
Benjamin Peterson384e9cb2014-02-16 14:46:57 -0500711 FILE *fp;
Serhiy Storchakac4ef3842016-01-28 21:32:53 +0200712 unsigned short compress, time, date, name_size;
713 unsigned int crc, data_size, file_size, header_size, header_offset;
714 unsigned long file_offset, header_position;
715 unsigned long arc_offset; /* Absolute offset to start of the zip-archive. */
716 unsigned int count, i;
717 unsigned char buffer[46];
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000718 size_t length;
719 char path[MAXPATHLEN + 5];
720 char name[MAXPATHLEN + 5];
Serhiy Storchakac4ef3842016-01-28 21:32:53 +0200721 const char *errmsg = NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +0000722
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000723 if (strlen(archive) > MAXPATHLEN) {
724 PyErr_SetString(PyExc_OverflowError,
725 "Zip path name is too long");
726 return NULL;
727 }
728 strcpy(path, archive);
Just van Rossum52e14d62002-12-30 22:08:05 +0000729
Benjamin Peterson384e9cb2014-02-16 14:46:57 -0500730 fp = fopen(archive, "rb");
731 if (fp == NULL) {
732 PyErr_Format(ZipImportError, "can't open Zip file: "
733 "'%.200s'", archive);
734 return NULL;
735 }
736
Jesus Ceae884be62012-10-03 02:13:05 +0200737 if (fseek(fp, -22, SEEK_END) == -1) {
Serhiy Storchakac4ef3842016-01-28 21:32:53 +0200738 goto file_error;
Jesus Ceae884be62012-10-03 02:13:05 +0200739 }
Serhiy Storchakac4ef3842016-01-28 21:32:53 +0200740 header_position = (unsigned long)ftell(fp);
741 if (header_position == (unsigned long)-1) {
742 goto file_error;
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000743 }
Serhiy Storchakac4ef3842016-01-28 21:32:53 +0200744 assert(header_position <= (unsigned long)LONG_MAX);
745 if (fread(buffer, 1, 22, fp) != 22) {
746 goto file_error;
747 }
748 if (get_uint32(buffer) != 0x06054B50u) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000749 /* Bad: End of Central Dir signature */
Serhiy Storchakac4ef3842016-01-28 21:32:53 +0200750 errmsg = "not a Zip file";
751 goto invalid_header;
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000752 }
Just van Rossum52e14d62002-12-30 22:08:05 +0000753
Serhiy Storchakac4ef3842016-01-28 21:32:53 +0200754 header_size = get_uint32(buffer + 12);
755 header_offset = get_uint32(buffer + 16);
756 if (header_position < header_size) {
757 errmsg = "bad central directory size";
758 goto invalid_header;
759 }
760 if (header_position < header_offset) {
761 errmsg = "bad central directory offset";
762 goto invalid_header;
763 }
764 if (header_position - header_size < header_offset) {
765 errmsg = "bad central directory size or offset";
766 goto invalid_header;
767 }
768 header_position -= header_size;
769 arc_offset = header_position - header_offset;
Just van Rossum52e14d62002-12-30 22:08:05 +0000770
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000771 files = PyDict_New();
Serhiy Storchakac4ef3842016-01-28 21:32:53 +0200772 if (files == NULL) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000773 goto error;
Serhiy Storchakac4ef3842016-01-28 21:32:53 +0200774 }
Just van Rossum52e14d62002-12-30 22:08:05 +0000775
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000776 length = (long)strlen(path);
777 path[length] = SEP;
Just van Rossum52e14d62002-12-30 22:08:05 +0000778
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000779 /* Start of Central Directory */
780 count = 0;
Serhiy Storchaka13ea0c52016-01-29 00:37:28 +0200781 if (fseek(fp, (long)header_position, 0) == -1) {
782 goto file_error;
783 }
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000784 for (;;) {
785 PyObject *t;
Serhiy Storchakac4ef3842016-01-28 21:32:53 +0200786 size_t n;
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000787 int err;
Just van Rossum52e14d62002-12-30 22:08:05 +0000788
Serhiy Storchakac4ef3842016-01-28 21:32:53 +0200789 n = fread(buffer, 1, 46, fp);
790 if (n < 4) {
791 goto eof_error;
792 }
793 /* Start of file header */
794 if (get_uint32(buffer) != 0x02014B50u) {
795 break; /* Bad: Central Dir File Header */
796 }
797 if (n != 46) {
798 goto eof_error;
799 }
800 compress = get_uint16(buffer + 10);
801 time = get_uint16(buffer + 12);
802 date = get_uint16(buffer + 14);
803 crc = get_uint32(buffer + 16);
804 data_size = get_uint32(buffer + 20);
805 file_size = get_uint32(buffer + 24);
806 name_size = get_uint16(buffer + 28);
807 header_size = (unsigned int)name_size +
808 get_uint16(buffer + 30) /* extra field */ +
809 get_uint16(buffer + 32) /* comment */;
810
811 file_offset = get_uint32(buffer + 42);
812 if (file_offset > header_offset) {
813 errmsg = "bad local header offset";
814 goto invalid_header;
815 }
816 file_offset += arc_offset;
817
818 if (name_size > MAXPATHLEN) {
819 name_size = MAXPATHLEN;
820 }
821 if (fread(name, 1, name_size, fp) != name_size) {
822 goto file_error;
823 }
824 name[name_size] = '\0'; /* Add terminating null byte */
825 if (SEP != '/') {
826 for (i = 0; i < name_size; i++) {
827 if (name[i] == '/') {
828 name[i] = SEP;
829 }
830 }
831 }
832 /* Skip the rest of the header.
833 * On Windows, calling fseek to skip over the fields we don't use is
834 * slower than reading the data because fseek flushes stdio's
835 * internal buffers. See issue #8745. */
836 assert(header_size <= 3*0xFFFFu);
837 for (i = name_size; i < header_size; i++) {
838 if (getc(fp) == EOF) {
839 goto file_error;
840 }
841 }
Just van Rossum52e14d62002-12-30 22:08:05 +0000842
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000843 strncpy(path + length + 1, name, MAXPATHLEN - length - 1);
Just van Rossum52e14d62002-12-30 22:08:05 +0000844
Serhiy Storchakac4ef3842016-01-28 21:32:53 +0200845 t = Py_BuildValue("sHIIkHHI", path, compress, data_size,
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000846 file_size, file_offset, time, date, crc);
Serhiy Storchakac4ef3842016-01-28 21:32:53 +0200847 if (t == NULL) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000848 goto error;
Serhiy Storchakac4ef3842016-01-28 21:32:53 +0200849 }
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000850 err = PyDict_SetItemString(files, name, t);
851 Py_DECREF(t);
Serhiy Storchakac4ef3842016-01-28 21:32:53 +0200852 if (err != 0) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000853 goto error;
Serhiy Storchakac4ef3842016-01-28 21:32:53 +0200854 }
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000855 count++;
856 }
Benjamin Peterson384e9cb2014-02-16 14:46:57 -0500857 fclose(fp);
Serhiy Storchakac4ef3842016-01-28 21:32:53 +0200858 if (Py_VerboseFlag) {
859 PySys_WriteStderr("# zipimport: found %u names in %.200s\n",
860 count, archive);
861 }
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000862 return files;
Serhiy Storchakac4ef3842016-01-28 21:32:53 +0200863
864eof_error:
865 set_file_error(archive, !ferror(fp));
866 goto error;
867
868file_error:
869 PyErr_Format(ZipImportError, "can't read Zip file: %.200s", archive);
870 goto error;
871
872invalid_header:
873 assert(errmsg != NULL);
874 PyErr_Format(ZipImportError, "%s: %.200s", errmsg, archive);
875 goto error;
876
Just van Rossum52e14d62002-12-30 22:08:05 +0000877error:
Benjamin Peterson384e9cb2014-02-16 14:46:57 -0500878 fclose(fp);
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000879 Py_XDECREF(files);
880 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +0000881}
882
883/* Return the zlib.decompress function object, or NULL if zlib couldn't
884 be imported. The function is cached when found, so subsequent calls
Victor Stinnerf58f1c32011-05-21 02:13:22 +0200885 don't import zlib again. */
Just van Rossum52e14d62002-12-30 22:08:05 +0000886static PyObject *
887get_decompress_func(void)
888{
Victor Stinnerf58f1c32011-05-21 02:13:22 +0200889 static int importing_zlib = 0;
890 PyObject *zlib;
891 PyObject *decompress;
Just van Rossum52e14d62002-12-30 22:08:05 +0000892
Victor Stinnerf58f1c32011-05-21 02:13:22 +0200893 if (importing_zlib != 0)
894 /* Someone has a zlib.py[co] in their Zip file;
895 let's avoid a stack overflow. */
896 return NULL;
897 importing_zlib = 1;
898 zlib = PyImport_ImportModuleNoBlock("zlib");
899 importing_zlib = 0;
900 if (zlib != NULL) {
901 decompress = PyObject_GetAttrString(zlib,
902 "decompress");
903 Py_DECREF(zlib);
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000904 }
Victor Stinnerf58f1c32011-05-21 02:13:22 +0200905 else {
906 PyErr_Clear();
907 decompress = NULL;
908 }
909 if (Py_VerboseFlag)
910 PySys_WriteStderr("# zipimport: zlib %s\n",
911 zlib != NULL ? "available": "UNAVAILABLE");
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000912 return decompress;
Just van Rossum52e14d62002-12-30 22:08:05 +0000913}
914
Benjamin Peterson384e9cb2014-02-16 14:46:57 -0500915/* Given a path to a Zip file and a toc_entry, return the (uncompressed)
Just van Rossum52e14d62002-12-30 22:08:05 +0000916 data as a new reference. */
Nan Zhangced27512017-06-19 18:01:34 -0700917PyObject *
Serhiy Storchakac4ef3842016-01-28 21:32:53 +0200918get_data(const char *archive, PyObject *toc_entry)
Just van Rossum52e14d62002-12-30 22:08:05 +0000919{
Serhiy Storchakac4ef3842016-01-28 21:32:53 +0200920 PyObject *raw_data = NULL, *data, *decompress;
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000921 char *buf;
Benjamin Peterson384e9cb2014-02-16 14:46:57 -0500922 FILE *fp;
Serhiy Storchakac4ef3842016-01-28 21:32:53 +0200923 const char *datapath;
924 unsigned short compress, time, date;
925 unsigned int crc;
926 Py_ssize_t data_size, file_size;
927 long file_offset, header_size;
928 unsigned char buffer[30];
929 const char *errmsg = NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +0000930
Serhiy Storchakac4ef3842016-01-28 21:32:53 +0200931 if (!PyArg_ParseTuple(toc_entry, "sHnnlHHI", &datapath, &compress,
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000932 &data_size, &file_size, &file_offset, &time,
933 &date, &crc)) {
934 return NULL;
935 }
Benjamin Peterson5640bbb2016-01-21 22:02:46 -0800936 if (data_size < 0) {
937 PyErr_Format(ZipImportError, "negative data size");
938 return NULL;
939 }
Just van Rossum52e14d62002-12-30 22:08:05 +0000940
Benjamin Peterson384e9cb2014-02-16 14:46:57 -0500941 fp = fopen(archive, "rb");
942 if (!fp) {
943 PyErr_Format(PyExc_IOError,
944 "zipimport: can not open file %s", archive);
945 return NULL;
946 }
947
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000948 /* Check to make sure the local file header is correct */
Jesus Ceae884be62012-10-03 02:13:05 +0200949 if (fseek(fp, file_offset, 0) == -1) {
Serhiy Storchakac4ef3842016-01-28 21:32:53 +0200950 goto file_error;
Jesus Ceae884be62012-10-03 02:13:05 +0200951 }
Serhiy Storchakac4ef3842016-01-28 21:32:53 +0200952 if (fread(buffer, 1, 30, fp) != 30) {
953 goto eof_error;
954 }
955 if (get_uint32(buffer) != 0x04034B50u) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000956 /* Bad: Local File Header */
Serhiy Storchakac4ef3842016-01-28 21:32:53 +0200957 errmsg = "bad local file header";
958 goto invalid_header;
Jesus Ceae884be62012-10-03 02:13:05 +0200959 }
960
Serhiy Storchakac4ef3842016-01-28 21:32:53 +0200961 header_size = (unsigned int)30 +
962 get_uint16(buffer + 26) /* file name */ +
963 get_uint16(buffer + 28) /* extra field */;
964 if (file_offset > LONG_MAX - header_size) {
965 errmsg = "bad local file header size";
966 goto invalid_header;
967 }
968 file_offset += header_size; /* Start of file data */
Just van Rossum52e14d62002-12-30 22:08:05 +0000969
Benjamin Peterson64ea1922016-01-20 22:23:44 -0800970 if (data_size > LONG_MAX - 1) {
971 fclose(fp);
972 PyErr_NoMemory();
973 return NULL;
974 }
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000975 raw_data = PyString_FromStringAndSize((char *)NULL, compress == 0 ?
976 data_size : data_size + 1);
Serhiy Storchakac4ef3842016-01-28 21:32:53 +0200977
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000978 if (raw_data == NULL) {
Serhiy Storchakac4ef3842016-01-28 21:32:53 +0200979 goto error;
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000980 }
981 buf = PyString_AsString(raw_data);
Just van Rossum52e14d62002-12-30 22:08:05 +0000982
Serhiy Storchakac4ef3842016-01-28 21:32:53 +0200983 if (fseek(fp, file_offset, 0) == -1) {
984 goto file_error;
Jesus Ceae884be62012-10-03 02:13:05 +0200985 }
Serhiy Storchakac4ef3842016-01-28 21:32:53 +0200986 if (fread(buf, 1, data_size, fp) != (size_t)data_size) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000987 PyErr_SetString(PyExc_IOError,
988 "zipimport: can't read data");
Serhiy Storchakac4ef3842016-01-28 21:32:53 +0200989 goto error;
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000990 }
Just van Rossum52e14d62002-12-30 22:08:05 +0000991
Serhiy Storchakac4ef3842016-01-28 21:32:53 +0200992 fclose(fp);
993 fp = NULL;
994
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000995 if (compress != 0) {
996 buf[data_size] = 'Z'; /* saw this in zipfile.py */
997 data_size++;
998 }
999 buf[data_size] = '\0';
Just van Rossum52e14d62002-12-30 22:08:05 +00001000
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001001 if (compress == 0) /* data is not compressed */
1002 return raw_data;
Just van Rossum52e14d62002-12-30 22:08:05 +00001003
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001004 /* Decompress with zlib */
1005 decompress = get_decompress_func();
1006 if (decompress == NULL) {
1007 PyErr_SetString(ZipImportError,
1008 "can't decompress data; "
1009 "zlib not available");
1010 goto error;
1011 }
1012 data = PyObject_CallFunction(decompress, "Oi", raw_data, -15);
Victor Stinnerf58f1c32011-05-21 02:13:22 +02001013 Py_DECREF(decompress);
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001014 Py_DECREF(raw_data);
1015 return data;
Serhiy Storchakac4ef3842016-01-28 21:32:53 +02001016
1017eof_error:
1018 set_file_error(archive, !ferror(fp));
1019 goto error;
1020
1021file_error:
1022 PyErr_Format(ZipImportError, "can't read Zip file: %.200s", archive);
1023 goto error;
1024
1025invalid_header:
1026 assert(errmsg != NULL);
1027 PyErr_Format(ZipImportError, "%s: %.200s", errmsg, archive);
1028 goto error;
1029
1030error:
1031 if (fp != NULL) {
1032 fclose(fp);
1033 }
1034 Py_XDECREF(raw_data);
1035 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +00001036}
1037
1038/* Lenient date/time comparison function. The precision of the mtime
1039 in the archive is lower than the mtime stored in a .pyc: we
1040 must allow a difference of at most one second. */
1041static int
1042eq_mtime(time_t t1, time_t t2)
1043{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001044 time_t d = t1 - t2;
1045 if (d < 0)
1046 d = -d;
1047 /* dostime only stores even seconds, so be lenient */
1048 return d <= 1;
Just van Rossum52e14d62002-12-30 22:08:05 +00001049}
1050
1051/* Given the contents of a .py[co] file in a buffer, unmarshal the data
1052 and return the code object. Return None if it the magic word doesn't
1053 match (we do this instead of raising an exception as we fall back
1054 to .py if available and we don't want to mask other errors).
1055 Returns a new reference. */
1056static PyObject *
Serhiy Storchakac4ef3842016-01-28 21:32:53 +02001057unmarshal_code(const char *pathname, PyObject *data, time_t mtime)
Just van Rossum52e14d62002-12-30 22:08:05 +00001058{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001059 PyObject *code;
Serhiy Storchakac4ef3842016-01-28 21:32:53 +02001060 unsigned char *buf = (unsigned char *)PyString_AsString(data);
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001061 Py_ssize_t size = PyString_Size(data);
Just van Rossum52e14d62002-12-30 22:08:05 +00001062
Serhiy Storchakac4ef3842016-01-28 21:32:53 +02001063 if (size < 8) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001064 PyErr_SetString(ZipImportError,
1065 "bad pyc data");
1066 return NULL;
1067 }
Just van Rossum52e14d62002-12-30 22:08:05 +00001068
Serhiy Storchakac4ef3842016-01-28 21:32:53 +02001069 if (get_uint32(buf) != (unsigned int)PyImport_GetMagicNumber()) {
1070 if (Py_VerboseFlag) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001071 PySys_WriteStderr("# %s has bad magic\n",
1072 pathname);
Serhiy Storchakac4ef3842016-01-28 21:32:53 +02001073 }
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001074 Py_INCREF(Py_None);
1075 return Py_None; /* signal caller to try alternative */
1076 }
Just van Rossum52e14d62002-12-30 22:08:05 +00001077
Serhiy Storchakac4ef3842016-01-28 21:32:53 +02001078 if (mtime != 0 && !eq_mtime(get_uint32(buf + 4), mtime)) {
1079 if (Py_VerboseFlag) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001080 PySys_WriteStderr("# %s has bad mtime\n",
1081 pathname);
Serhiy Storchakac4ef3842016-01-28 21:32:53 +02001082 }
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001083 Py_INCREF(Py_None);
1084 return Py_None; /* signal caller to try alternative */
1085 }
Just van Rossum52e14d62002-12-30 22:08:05 +00001086
Serhiy Storchakac4ef3842016-01-28 21:32:53 +02001087 code = PyMarshal_ReadObjectFromString((char *)buf + 8, size - 8);
1088 if (code == NULL) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001089 return NULL;
Serhiy Storchakac4ef3842016-01-28 21:32:53 +02001090 }
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001091 if (!PyCode_Check(code)) {
1092 Py_DECREF(code);
1093 PyErr_Format(PyExc_TypeError,
1094 "compiled module %.200s is not a code object",
1095 pathname);
1096 return NULL;
1097 }
1098 return code;
Just van Rossum52e14d62002-12-30 22:08:05 +00001099}
1100
Martin Panter65076572016-09-07 12:03:06 +00001101/* Replace any occurrences of "\r\n?" in the input string with "\n".
Just van Rossum52e14d62002-12-30 22:08:05 +00001102 This converts DOS and Mac line endings to Unix line endings.
1103 Also append a trailing "\n" to be compatible with
1104 PyParser_SimpleParseFile(). Returns a new reference. */
1105static PyObject *
1106normalize_line_endings(PyObject *source)
1107{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001108 char *buf, *q, *p = PyString_AsString(source);
1109 PyObject *fixed_source;
Just van Rossum52e14d62002-12-30 22:08:05 +00001110
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001111 if (!p)
1112 return NULL;
Neal Norwitzee7c8f92006-08-13 18:12:03 +00001113
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001114 /* one char extra for trailing \n and one for terminating \0 */
1115 buf = (char *)PyMem_Malloc(PyString_Size(source) + 2);
1116 if (buf == NULL) {
1117 PyErr_SetString(PyExc_MemoryError,
1118 "zipimport: no memory to allocate "
1119 "source buffer");
1120 return NULL;
1121 }
1122 /* replace "\r\n?" by "\n" */
1123 for (q = buf; *p != '\0'; p++) {
1124 if (*p == '\r') {
1125 *q++ = '\n';
1126 if (*(p + 1) == '\n')
1127 p++;
1128 }
1129 else
1130 *q++ = *p;
1131 }
1132 *q++ = '\n'; /* add trailing \n */
1133 *q = '\0';
1134 fixed_source = PyString_FromString(buf);
1135 PyMem_Free(buf);
1136 return fixed_source;
Just van Rossum52e14d62002-12-30 22:08:05 +00001137}
1138
1139/* Given a string buffer containing Python source code, compile it
1140 return and return a code object as a new reference. */
1141static PyObject *
1142compile_source(char *pathname, PyObject *source)
1143{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001144 PyObject *code, *fixed_source;
Just van Rossum52e14d62002-12-30 22:08:05 +00001145
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001146 fixed_source = normalize_line_endings(source);
1147 if (fixed_source == NULL)
1148 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +00001149
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001150 code = Py_CompileString(PyString_AsString(fixed_source), pathname,
1151 Py_file_input);
1152 Py_DECREF(fixed_source);
1153 return code;
Just van Rossum52e14d62002-12-30 22:08:05 +00001154}
1155
1156/* Convert the date/time values found in the Zip archive to a value
1157 that's compatible with the time stamp stored in .pyc files. */
Neal Norwitz29fd2ba2003-03-23 13:21:03 +00001158static time_t
1159parse_dostime(int dostime, int dosdate)
Just van Rossum52e14d62002-12-30 22:08:05 +00001160{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001161 struct tm stm;
Just van Rossum52e14d62002-12-30 22:08:05 +00001162
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001163 memset((void *) &stm, '\0', sizeof(stm));
Christian Heimes62a8e952008-01-18 07:30:20 +00001164
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001165 stm.tm_sec = (dostime & 0x1f) * 2;
1166 stm.tm_min = (dostime >> 5) & 0x3f;
1167 stm.tm_hour = (dostime >> 11) & 0x1f;
1168 stm.tm_mday = dosdate & 0x1f;
1169 stm.tm_mon = ((dosdate >> 5) & 0x0f) - 1;
1170 stm.tm_year = ((dosdate >> 9) & 0x7f) + 80;
1171 stm.tm_isdst = -1; /* wday/yday is ignored */
Just van Rossum52e14d62002-12-30 22:08:05 +00001172
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001173 return mktime(&stm);
Just van Rossum52e14d62002-12-30 22:08:05 +00001174}
1175
1176/* Given a path to a .pyc or .pyo file in the archive, return the
Ezio Melottic2077b02011-03-16 12:34:31 +02001177 modification time of the matching .py file, or 0 if no source
Just van Rossum52e14d62002-12-30 22:08:05 +00001178 is available. */
1179static time_t
1180get_mtime_of_source(ZipImporter *self, char *path)
1181{
Benjamin Petersone9aab0f2014-02-16 14:20:14 -05001182 PyObject *toc_entry;
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001183 time_t mtime = 0;
1184 Py_ssize_t lastchar = strlen(path) - 1;
1185 char savechar = path[lastchar];
1186 path[lastchar] = '\0'; /* strip 'c' or 'o' from *.py[co] */
Benjamin Petersone9aab0f2014-02-16 14:20:14 -05001187 toc_entry = PyDict_GetItemString(self->files, path);
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001188 if (toc_entry != NULL && PyTuple_Check(toc_entry) &&
1189 PyTuple_Size(toc_entry) == 8) {
1190 /* fetch the time stamp of the .py file for comparison
1191 with an embedded pyc time stamp */
1192 int time, date;
1193 time = PyInt_AsLong(PyTuple_GetItem(toc_entry, 5));
1194 date = PyInt_AsLong(PyTuple_GetItem(toc_entry, 6));
1195 mtime = parse_dostime(time, date);
1196 }
1197 path[lastchar] = savechar;
1198 return mtime;
Just van Rossum52e14d62002-12-30 22:08:05 +00001199}
1200
1201/* Return the code object for the module named by 'fullname' from the
1202 Zip archive as a new reference. */
1203static PyObject *
Benjamin Peterson384e9cb2014-02-16 14:46:57 -05001204get_code_from_data(ZipImporter *self, int ispackage, int isbytecode,
1205 time_t mtime, PyObject *toc_entry)
Just van Rossum52e14d62002-12-30 22:08:05 +00001206{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001207 PyObject *data, *code;
1208 char *modpath;
Benjamin Peterson384e9cb2014-02-16 14:46:57 -05001209 char *archive = PyString_AsString(self->archive);
Just van Rossum52e14d62002-12-30 22:08:05 +00001210
Benjamin Peterson384e9cb2014-02-16 14:46:57 -05001211 if (archive == NULL)
1212 return NULL;
1213
1214 data = get_data(archive, toc_entry);
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001215 if (data == NULL)
1216 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +00001217
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001218 modpath = PyString_AsString(PyTuple_GetItem(toc_entry, 0));
Just van Rossum52e14d62002-12-30 22:08:05 +00001219
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001220 if (isbytecode) {
1221 code = unmarshal_code(modpath, data, mtime);
1222 }
1223 else {
1224 code = compile_source(modpath, data);
1225 }
1226 Py_DECREF(data);
1227 return code;
Just van Rossum52e14d62002-12-30 22:08:05 +00001228}
1229
Ezio Melotti24b07bc2011-03-15 18:55:01 +02001230/* Get the code object associated with the module specified by
Just van Rossum52e14d62002-12-30 22:08:05 +00001231 'fullname'. */
1232static PyObject *
1233get_module_code(ZipImporter *self, char *fullname,
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001234 int *p_ispackage, char **p_modpath)
Just van Rossum52e14d62002-12-30 22:08:05 +00001235{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001236 PyObject *toc_entry;
1237 char *subname, path[MAXPATHLEN + 1];
1238 int len;
1239 struct st_zip_searchorder *zso;
Just van Rossum52e14d62002-12-30 22:08:05 +00001240
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001241 subname = get_subname(fullname);
Just van Rossum52e14d62002-12-30 22:08:05 +00001242
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001243 len = make_filename(PyString_AsString(self->prefix), subname, path);
1244 if (len < 0)
1245 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +00001246
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001247 for (zso = zip_searchorder; *zso->suffix; zso++) {
Benjamin Petersone9aab0f2014-02-16 14:20:14 -05001248 PyObject *code = NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +00001249
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001250 strcpy(path + len, zso->suffix);
1251 if (Py_VerboseFlag > 1)
1252 PySys_WriteStderr("# trying %s%c%s\n",
1253 PyString_AsString(self->archive),
1254 SEP, path);
Benjamin Petersone9aab0f2014-02-16 14:20:14 -05001255 toc_entry = PyDict_GetItemString(self->files, path);
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001256 if (toc_entry != NULL) {
1257 time_t mtime = 0;
1258 int ispackage = zso->type & IS_PACKAGE;
1259 int isbytecode = zso->type & IS_BYTECODE;
Just van Rossum52e14d62002-12-30 22:08:05 +00001260
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001261 if (isbytecode)
1262 mtime = get_mtime_of_source(self, path);
1263 if (p_ispackage != NULL)
1264 *p_ispackage = ispackage;
Benjamin Peterson384e9cb2014-02-16 14:46:57 -05001265 code = get_code_from_data(self, ispackage,
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001266 isbytecode, mtime,
1267 toc_entry);
1268 if (code == Py_None) {
1269 /* bad magic number or non-matching mtime
1270 in byte code, try next */
1271 Py_DECREF(code);
1272 continue;
1273 }
1274 if (code != NULL && p_modpath != NULL)
1275 *p_modpath = PyString_AsString(
1276 PyTuple_GetItem(toc_entry, 0));
1277 return code;
1278 }
1279 }
1280 PyErr_Format(ZipImportError, "can't find module '%.200s'", fullname);
1281 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +00001282}
1283
1284
1285/* Module init */
1286
1287PyDoc_STRVAR(zipimport_doc,
1288"zipimport provides support for importing Python modules from Zip archives.\n\
1289\n\
1290This module exports three objects:\n\
1291- zipimporter: a class; its constructor takes a path to a Zip archive.\n\
Fredrik Lundhb84b35f2006-01-15 15:00:40 +00001292- ZipImportError: exception raised by zipimporter objects. It's a\n\
Just van Rossum52e14d62002-12-30 22:08:05 +00001293 subclass of ImportError, so it can be caught as ImportError, too.\n\
1294- _zip_directory_cache: a dict, mapping archive paths to zip directory\n\
1295 info dicts, as used in zipimporter._files.\n\
1296\n\
1297It is usually not needed to use the zipimport module explicitly; it is\n\
1298used by the builtin import mechanism for sys.path items that are paths\n\
1299to Zip archives.");
1300
1301PyMODINIT_FUNC
1302initzipimport(void)
1303{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001304 PyObject *mod;
Just van Rossum52e14d62002-12-30 22:08:05 +00001305
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001306 if (PyType_Ready(&ZipImporter_Type) < 0)
1307 return;
Just van Rossum52e14d62002-12-30 22:08:05 +00001308
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001309 /* Correct directory separator */
1310 zip_searchorder[0].suffix[0] = SEP;
1311 zip_searchorder[1].suffix[0] = SEP;
1312 zip_searchorder[2].suffix[0] = SEP;
1313 if (Py_OptimizeFlag) {
1314 /* Reverse *.pyc and *.pyo */
1315 struct st_zip_searchorder tmp;
1316 tmp = zip_searchorder[0];
1317 zip_searchorder[0] = zip_searchorder[1];
1318 zip_searchorder[1] = tmp;
1319 tmp = zip_searchorder[3];
1320 zip_searchorder[3] = zip_searchorder[4];
1321 zip_searchorder[4] = tmp;
1322 }
Just van Rossum52e14d62002-12-30 22:08:05 +00001323
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001324 mod = Py_InitModule4("zipimport", NULL, zipimport_doc,
1325 NULL, PYTHON_API_VERSION);
1326 if (mod == NULL)
1327 return;
Just van Rossum52e14d62002-12-30 22:08:05 +00001328
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001329 ZipImportError = PyErr_NewException("zipimport.ZipImportError",
1330 PyExc_ImportError, NULL);
1331 if (ZipImportError == NULL)
1332 return;
Just van Rossum52e14d62002-12-30 22:08:05 +00001333
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001334 Py_INCREF(ZipImportError);
1335 if (PyModule_AddObject(mod, "ZipImportError",
1336 ZipImportError) < 0)
1337 return;
Just van Rossum52e14d62002-12-30 22:08:05 +00001338
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001339 Py_INCREF(&ZipImporter_Type);
1340 if (PyModule_AddObject(mod, "zipimporter",
1341 (PyObject *)&ZipImporter_Type) < 0)
1342 return;
Just van Rossumf8b6de12002-12-31 09:51:59 +00001343
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001344 zip_directory_cache = PyDict_New();
1345 if (zip_directory_cache == NULL)
1346 return;
1347 Py_INCREF(zip_directory_cache);
1348 if (PyModule_AddObject(mod, "_zip_directory_cache",
1349 zip_directory_cache) < 0)
1350 return;
Just van Rossum52e14d62002-12-30 22:08:05 +00001351}