blob: 1691773ec10f2dd274eca9e27094725c4ca0d734 [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
46/* forward decls */
Dan Willemseneba50a52018-11-16 17:27:26 -080047static PyObject *read_directory(const char *archive);
48static PyObject *get_data(const char *archive, PyObject *toc_entry);
Just van Rossum52e14d62002-12-30 22:08:05 +000049static PyObject *get_module_code(ZipImporter *self, char *fullname,
Antoine Pitrouc83ea132010-05-09 14:46:46 +000050 int *p_ispackage, char **p_modpath);
Just van Rossum52e14d62002-12-30 22:08:05 +000051
52
53#define ZipImporter_Check(op) PyObject_TypeCheck(op, &ZipImporter_Type)
54
55
56/* zipimporter.__init__
57 Split the "subdirectory" from the Zip archive path, lookup a matching
58 entry in sys.path_importer_cache, fetch the file directory from there
59 if found, or else read it from the archive. */
60static int
61zipimporter_init(ZipImporter *self, PyObject *args, PyObject *kwds)
62{
Benjamin Petersone9aab0f2014-02-16 14:20:14 -050063 char *path, *p, *prefix, buf[MAXPATHLEN+2];
Antoine Pitrouc83ea132010-05-09 14:46:46 +000064 size_t len;
Just van Rossum52e14d62002-12-30 22:08:05 +000065
Antoine Pitrouc83ea132010-05-09 14:46:46 +000066 if (!_PyArg_NoKeywords("zipimporter()", kwds))
67 return -1;
Georg Brandl02c42872005-08-26 06:42:30 +000068
Benjamin Petersone9aab0f2014-02-16 14:20:14 -050069 if (!PyArg_ParseTuple(args, "s:zipimporter",
70 &path))
Antoine Pitrouc83ea132010-05-09 14:46:46 +000071 return -1;
Just van Rossum52e14d62002-12-30 22:08:05 +000072
Benjamin Petersone9aab0f2014-02-16 14:20:14 -050073 len = strlen(path);
Antoine Pitrouc83ea132010-05-09 14:46:46 +000074 if (len == 0) {
75 PyErr_SetString(ZipImportError, "archive path is empty");
76 return -1;
77 }
78 if (len >= MAXPATHLEN) {
Benjamin Petersone9aab0f2014-02-16 14:20:14 -050079 PyErr_SetString(ZipImportError,
80 "archive path too long");
Antoine Pitrouc83ea132010-05-09 14:46:46 +000081 return -1;
82 }
Benjamin Petersone9aab0f2014-02-16 14:20:14 -050083 strcpy(buf, path);
Just van Rossum52e14d62002-12-30 22:08:05 +000084
85#ifdef ALTSEP
Benjamin Petersone9aab0f2014-02-16 14:20:14 -050086 for (p = buf; *p; p++) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +000087 if (*p == ALTSEP)
88 *p = SEP;
89 }
Just van Rossum52e14d62002-12-30 22:08:05 +000090#endif
91
Antoine Pitrouc83ea132010-05-09 14:46:46 +000092 path = NULL;
93 prefix = NULL;
94 for (;;) {
Martin v. Löwisa94568a2003-05-10 07:36:56 +000095#ifndef RISCOS
Antoine Pitrouc83ea132010-05-09 14:46:46 +000096 struct stat statbuf;
97 int rv;
Just van Rossum52e14d62002-12-30 22:08:05 +000098
Benjamin Petersone9aab0f2014-02-16 14:20:14 -050099 rv = stat(buf, &statbuf);
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000100 if (rv == 0) {
101 /* it exists */
102 if (S_ISREG(statbuf.st_mode))
103 /* it's a file */
Benjamin Petersone9aab0f2014-02-16 14:20:14 -0500104 path = buf;
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000105 break;
106 }
Martin v. Löwisa94568a2003-05-10 07:36:56 +0000107#else
Benjamin Petersone9aab0f2014-02-16 14:20:14 -0500108 if (object_exists(buf)) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000109 /* it exists */
Benjamin Petersone9aab0f2014-02-16 14:20:14 -0500110 if (isfile(buf))
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000111 /* it's a file */
Benjamin Petersone9aab0f2014-02-16 14:20:14 -0500112 path = buf;
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000113 break;
114 }
Martin v. Löwisa94568a2003-05-10 07:36:56 +0000115#endif
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000116 /* back up one path element */
Benjamin Petersone9aab0f2014-02-16 14:20:14 -0500117 p = strrchr(buf, SEP);
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000118 if (prefix != NULL)
119 *prefix = SEP;
120 if (p == NULL)
121 break;
122 *p = '\0';
123 prefix = p;
124 }
125 if (path != NULL) {
126 PyObject *files;
127 files = PyDict_GetItemString(zip_directory_cache, path);
128 if (files == NULL) {
Benjamin Peterson384e9cb2014-02-16 14:46:57 -0500129 files = read_directory(buf);
130 if (files == NULL)
Benjamin Petersone9aab0f2014-02-16 14:20:14 -0500131 return -1;
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000132 if (PyDict_SetItemString(zip_directory_cache, path,
Benjamin Peterson384e9cb2014-02-16 14:46:57 -0500133 files) != 0)
Benjamin Petersone9aab0f2014-02-16 14:20:14 -0500134 return -1;
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000135 }
Benjamin Petersone9aab0f2014-02-16 14:20:14 -0500136 else
137 Py_INCREF(files);
138 self->files = files;
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000139 }
140 else {
141 PyErr_SetString(ZipImportError, "not a Zip file");
Benjamin Petersone9aab0f2014-02-16 14:20:14 -0500142 return -1;
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000143 }
Just van Rossum52e14d62002-12-30 22:08:05 +0000144
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000145 if (prefix == NULL)
146 prefix = "";
147 else {
148 prefix++;
149 len = strlen(prefix);
150 if (prefix[len-1] != SEP) {
151 /* add trailing SEP */
152 prefix[len] = SEP;
153 prefix[len + 1] = '\0';
154 }
155 }
Just van Rossum52e14d62002-12-30 22:08:05 +0000156
Benjamin Petersone9aab0f2014-02-16 14:20:14 -0500157 self->archive = PyString_FromString(buf);
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000158 if (self->archive == NULL)
Benjamin Petersone9aab0f2014-02-16 14:20:14 -0500159 return -1;
Just van Rossum52e14d62002-12-30 22:08:05 +0000160
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000161 self->prefix = PyString_FromString(prefix);
162 if (self->prefix == NULL)
Benjamin Petersone9aab0f2014-02-16 14:20:14 -0500163 return -1;
Just van Rossum52e14d62002-12-30 22:08:05 +0000164
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000165 return 0;
Benjamin Petersone9aab0f2014-02-16 14:20:14 -0500166}
167
168/* GC support. */
169static int
170zipimporter_traverse(PyObject *obj, visitproc visit, void *arg)
171{
172 ZipImporter *self = (ZipImporter *)obj;
173 Py_VISIT(self->files);
174 return 0;
Just van Rossum52e14d62002-12-30 22:08:05 +0000175}
176
177static void
178zipimporter_dealloc(ZipImporter *self)
179{
Benjamin Petersone9aab0f2014-02-16 14:20:14 -0500180 PyObject_GC_UnTrack(self);
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000181 Py_XDECREF(self->archive);
182 Py_XDECREF(self->prefix);
Benjamin Petersone9aab0f2014-02-16 14:20:14 -0500183 Py_XDECREF(self->files);
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000184 Py_TYPE(self)->tp_free((PyObject *)self);
Just van Rossum52e14d62002-12-30 22:08:05 +0000185}
186
187static PyObject *
188zipimporter_repr(ZipImporter *self)
189{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000190 char buf[500];
191 char *archive = "???";
192 char *prefix = "";
Just van Rossum52e14d62002-12-30 22:08:05 +0000193
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000194 if (self->archive != NULL && PyString_Check(self->archive))
195 archive = PyString_AsString(self->archive);
196 if (self->prefix != NULL && PyString_Check(self->prefix))
197 prefix = PyString_AsString(self->prefix);
198 if (prefix != NULL && *prefix)
199 PyOS_snprintf(buf, sizeof(buf),
200 "<zipimporter object \"%.300s%c%.150s\">",
201 archive, SEP, prefix);
202 else
203 PyOS_snprintf(buf, sizeof(buf),
204 "<zipimporter object \"%.300s\">",
205 archive);
206 return PyString_FromString(buf);
Just van Rossum52e14d62002-12-30 22:08:05 +0000207}
208
209/* return fullname.split(".")[-1] */
210static char *
211get_subname(char *fullname)
212{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000213 char *subname = strrchr(fullname, '.');
214 if (subname == NULL)
215 subname = fullname;
216 else
217 subname++;
218 return subname;
Just van Rossum52e14d62002-12-30 22:08:05 +0000219}
220
221/* Given a (sub)modulename, write the potential file path in the
222 archive (without extension) to the path buffer. Return the
223 length of the resulting string. */
224static int
225make_filename(char *prefix, char *name, char *path)
226{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000227 size_t len;
228 char *p;
Just van Rossum52e14d62002-12-30 22:08:05 +0000229
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000230 len = strlen(prefix);
Just van Rossum52e14d62002-12-30 22:08:05 +0000231
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000232 /* self.prefix + name [+ SEP + "__init__"] + ".py[co]" */
233 if (len + strlen(name) + 13 >= MAXPATHLEN) {
234 PyErr_SetString(ZipImportError, "path too long");
235 return -1;
236 }
Just van Rossum52e14d62002-12-30 22:08:05 +0000237
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000238 strcpy(path, prefix);
239 strcpy(path + len, name);
240 for (p = path + len; *p; p++) {
241 if (*p == '.')
242 *p = SEP;
243 }
244 len += strlen(name);
245 assert(len < INT_MAX);
246 return (int)len;
Just van Rossum52e14d62002-12-30 22:08:05 +0000247}
248
Raymond Hettinger2c45c9a2004-11-10 13:08:35 +0000249enum zi_module_info {
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000250 MI_ERROR,
251 MI_NOT_FOUND,
252 MI_MODULE,
253 MI_PACKAGE
Just van Rossum52e14d62002-12-30 22:08:05 +0000254};
255
256/* Return some information about a module. */
Raymond Hettinger2c45c9a2004-11-10 13:08:35 +0000257static enum zi_module_info
Just van Rossum52e14d62002-12-30 22:08:05 +0000258get_module_info(ZipImporter *self, char *fullname)
259{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000260 char *subname, path[MAXPATHLEN + 1];
261 int len;
262 struct st_zip_searchorder *zso;
Just van Rossum52e14d62002-12-30 22:08:05 +0000263
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000264 subname = get_subname(fullname);
Just van Rossum52e14d62002-12-30 22:08:05 +0000265
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000266 len = make_filename(PyString_AsString(self->prefix), subname, path);
267 if (len < 0)
268 return MI_ERROR;
Just van Rossum52e14d62002-12-30 22:08:05 +0000269
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000270 for (zso = zip_searchorder; *zso->suffix; zso++) {
271 strcpy(path + len, zso->suffix);
Benjamin Petersone9aab0f2014-02-16 14:20:14 -0500272 if (PyDict_GetItemString(self->files, path) != NULL) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000273 if (zso->type & IS_PACKAGE)
274 return MI_PACKAGE;
275 else
276 return MI_MODULE;
277 }
278 }
279 return MI_NOT_FOUND;
Just van Rossum52e14d62002-12-30 22:08:05 +0000280}
281
282/* Check whether we can satisfy the import of the module named by
283 'fullname'. Return self if we can, None if we can't. */
284static PyObject *
285zipimporter_find_module(PyObject *obj, PyObject *args)
286{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000287 ZipImporter *self = (ZipImporter *)obj;
288 PyObject *path = NULL;
289 char *fullname;
290 enum zi_module_info mi;
Just van Rossum52e14d62002-12-30 22:08:05 +0000291
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000292 if (!PyArg_ParseTuple(args, "s|O:zipimporter.find_module",
293 &fullname, &path))
294 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +0000295
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000296 mi = get_module_info(self, fullname);
297 if (mi == MI_ERROR)
298 return NULL;
299 if (mi == MI_NOT_FOUND) {
300 Py_INCREF(Py_None);
301 return Py_None;
302 }
303 Py_INCREF(self);
304 return (PyObject *)self;
Just van Rossum52e14d62002-12-30 22:08:05 +0000305}
306
307/* Load and return the module named by 'fullname'. */
308static PyObject *
309zipimporter_load_module(PyObject *obj, PyObject *args)
310{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000311 ZipImporter *self = (ZipImporter *)obj;
312 PyObject *code, *mod, *dict;
313 char *fullname, *modpath;
314 int ispackage;
Just van Rossum52e14d62002-12-30 22:08:05 +0000315
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000316 if (!PyArg_ParseTuple(args, "s:zipimporter.load_module",
317 &fullname))
318 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +0000319
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000320 code = get_module_code(self, fullname, &ispackage, &modpath);
321 if (code == NULL)
322 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +0000323
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000324 mod = PyImport_AddModule(fullname);
325 if (mod == NULL) {
326 Py_DECREF(code);
327 return NULL;
328 }
329 dict = PyModule_GetDict(mod);
Just van Rossum52e14d62002-12-30 22:08:05 +0000330
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000331 /* mod.__loader__ = self */
332 if (PyDict_SetItemString(dict, "__loader__", (PyObject *)self) != 0)
333 goto error;
Just van Rossum52e14d62002-12-30 22:08:05 +0000334
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000335 if (ispackage) {
336 /* add __path__ to the module *before* the code gets
337 executed */
338 PyObject *pkgpath, *fullpath;
339 char *prefix = PyString_AsString(self->prefix);
340 char *subname = get_subname(fullname);
341 int err;
Just van Rossum52e14d62002-12-30 22:08:05 +0000342
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000343 fullpath = PyString_FromFormat("%s%c%s%s",
344 PyString_AsString(self->archive),
345 SEP,
346 *prefix ? prefix : "",
347 subname);
348 if (fullpath == NULL)
349 goto error;
Just van Rossum52e14d62002-12-30 22:08:05 +0000350
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000351 pkgpath = Py_BuildValue("[O]", fullpath);
352 Py_DECREF(fullpath);
353 if (pkgpath == NULL)
354 goto error;
355 err = PyDict_SetItemString(dict, "__path__", pkgpath);
356 Py_DECREF(pkgpath);
357 if (err != 0)
358 goto error;
359 }
360 mod = PyImport_ExecCodeModuleEx(fullname, code, modpath);
361 Py_DECREF(code);
362 if (Py_VerboseFlag)
363 PySys_WriteStderr("import %s # loaded from Zip %s\n",
364 fullname, modpath);
365 return mod;
Just van Rossum52e14d62002-12-30 22:08:05 +0000366error:
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000367 Py_DECREF(code);
368 Py_DECREF(mod);
369 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +0000370}
371
Nick Coghlana2053472008-12-14 10:54:50 +0000372/* Return a string matching __file__ for the named module */
373static PyObject *
374zipimporter_get_filename(PyObject *obj, PyObject *args)
375{
376 ZipImporter *self = (ZipImporter *)obj;
377 PyObject *code;
378 char *fullname, *modpath;
379 int ispackage;
380
Nick Coghlan0194f5b2009-02-08 03:17:00 +0000381 if (!PyArg_ParseTuple(args, "s:zipimporter.get_filename",
Nick Coghlana2053472008-12-14 10:54:50 +0000382 &fullname))
Martin Panter5f755022016-09-15 01:50:53 +0000383 return NULL;
Nick Coghlana2053472008-12-14 10:54:50 +0000384
385 /* Deciding the filename requires working out where the code
386 would come from if the module was actually loaded */
387 code = get_module_code(self, fullname, &ispackage, &modpath);
388 if (code == NULL)
Martin Panter5f755022016-09-15 01:50:53 +0000389 return NULL;
Nick Coghlana2053472008-12-14 10:54:50 +0000390 Py_DECREF(code); /* Only need the path info */
391
392 return PyString_FromString(modpath);
393}
394
Just van Rossum52e14d62002-12-30 22:08:05 +0000395/* Return a bool signifying whether the module is a package or not. */
396static PyObject *
397zipimporter_is_package(PyObject *obj, PyObject *args)
398{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000399 ZipImporter *self = (ZipImporter *)obj;
400 char *fullname;
401 enum zi_module_info mi;
Just van Rossum52e14d62002-12-30 22:08:05 +0000402
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000403 if (!PyArg_ParseTuple(args, "s:zipimporter.is_package",
404 &fullname))
405 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +0000406
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000407 mi = get_module_info(self, fullname);
408 if (mi == MI_ERROR)
409 return NULL;
410 if (mi == MI_NOT_FOUND) {
411 PyErr_Format(ZipImportError, "can't find module '%.200s'",
412 fullname);
413 return NULL;
414 }
415 return PyBool_FromLong(mi == MI_PACKAGE);
Just van Rossum52e14d62002-12-30 22:08:05 +0000416}
417
418static PyObject *
419zipimporter_get_data(PyObject *obj, PyObject *args)
420{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000421 ZipImporter *self = (ZipImporter *)obj;
Benjamin Peterson384e9cb2014-02-16 14:46:57 -0500422 char *path;
Just van Rossum52e14d62002-12-30 22:08:05 +0000423#ifdef ALTSEP
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000424 char *p, buf[MAXPATHLEN + 1];
Just van Rossum52e14d62002-12-30 22:08:05 +0000425#endif
Benjamin Peterson384e9cb2014-02-16 14:46:57 -0500426 PyObject *toc_entry;
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000427 Py_ssize_t len;
Just van Rossum52e14d62002-12-30 22:08:05 +0000428
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000429 if (!PyArg_ParseTuple(args, "s:zipimporter.get_data", &path))
430 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +0000431
432#ifdef ALTSEP
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000433 if (strlen(path) >= MAXPATHLEN) {
434 PyErr_SetString(ZipImportError, "path too long");
435 return NULL;
436 }
437 strcpy(buf, path);
438 for (p = buf; *p; p++) {
439 if (*p == ALTSEP)
440 *p = SEP;
441 }
442 path = buf;
Just van Rossum52e14d62002-12-30 22:08:05 +0000443#endif
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000444 len = PyString_Size(self->archive);
445 if ((size_t)len < strlen(path) &&
446 strncmp(path, PyString_AsString(self->archive), len) == 0 &&
447 path[len] == SEP) {
448 path = path + len + 1;
449 }
Just van Rossum52e14d62002-12-30 22:08:05 +0000450
Benjamin Petersone9aab0f2014-02-16 14:20:14 -0500451 toc_entry = PyDict_GetItemString(self->files, path);
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000452 if (toc_entry == NULL) {
453 PyErr_SetFromErrnoWithFilename(PyExc_IOError, path);
454 return NULL;
455 }
Benjamin Peterson384e9cb2014-02-16 14:46:57 -0500456 return get_data(PyString_AsString(self->archive), toc_entry);
Just van Rossum52e14d62002-12-30 22:08:05 +0000457}
458
459static PyObject *
460zipimporter_get_code(PyObject *obj, PyObject *args)
461{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000462 ZipImporter *self = (ZipImporter *)obj;
463 char *fullname;
Just van Rossum52e14d62002-12-30 22:08:05 +0000464
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000465 if (!PyArg_ParseTuple(args, "s:zipimporter.get_code", &fullname))
466 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +0000467
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000468 return get_module_code(self, fullname, NULL, NULL);
Just van Rossum52e14d62002-12-30 22:08:05 +0000469}
470
471static PyObject *
472zipimporter_get_source(PyObject *obj, PyObject *args)
473{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000474 ZipImporter *self = (ZipImporter *)obj;
Benjamin Petersone9aab0f2014-02-16 14:20:14 -0500475 PyObject *toc_entry;
Benjamin Peterson384e9cb2014-02-16 14:46:57 -0500476 char *fullname, *subname, path[MAXPATHLEN+1];
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000477 int len;
478 enum zi_module_info mi;
Just van Rossum52e14d62002-12-30 22:08:05 +0000479
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000480 if (!PyArg_ParseTuple(args, "s:zipimporter.get_source", &fullname))
481 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +0000482
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000483 mi = get_module_info(self, fullname);
484 if (mi == MI_ERROR)
485 return NULL;
486 if (mi == MI_NOT_FOUND) {
487 PyErr_Format(ZipImportError, "can't find module '%.200s'",
488 fullname);
489 return NULL;
490 }
491 subname = get_subname(fullname);
Just van Rossum52e14d62002-12-30 22:08:05 +0000492
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000493 len = make_filename(PyString_AsString(self->prefix), subname, path);
494 if (len < 0)
495 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +0000496
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000497 if (mi == MI_PACKAGE) {
498 path[len] = SEP;
499 strcpy(path + len + 1, "__init__.py");
500 }
501 else
502 strcpy(path + len, ".py");
Just van Rossum52e14d62002-12-30 22:08:05 +0000503
Benjamin Petersone9aab0f2014-02-16 14:20:14 -0500504 toc_entry = PyDict_GetItemString(self->files, path);
Benjamin Peterson384e9cb2014-02-16 14:46:57 -0500505 if (toc_entry != NULL)
506 return get_data(PyString_AsString(self->archive), toc_entry);
Just van Rossum52e14d62002-12-30 22:08:05 +0000507
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000508 /* we have the module, but no source */
Benjamin Peterson384e9cb2014-02-16 14:46:57 -0500509 Py_INCREF(Py_None);
510 return Py_None;
Just van Rossum52e14d62002-12-30 22:08:05 +0000511}
512
513PyDoc_STRVAR(doc_find_module,
514"find_module(fullname, path=None) -> self or None.\n\
515\n\
516Search for a module specified by 'fullname'. 'fullname' must be the\n\
517fully qualified (dotted) module name. It returns the zipimporter\n\
518instance itself if the module was found, or None if it wasn't.\n\
519The optional 'path' argument is ignored -- it's there for compatibility\n\
520with the importer protocol.");
521
522PyDoc_STRVAR(doc_load_module,
523"load_module(fullname) -> module.\n\
524\n\
525Load the module specified by 'fullname'. 'fullname' must be the\n\
526fully qualified (dotted) module name. It returns the imported\n\
527module, or raises ZipImportError if it wasn't found.");
528
529PyDoc_STRVAR(doc_get_data,
530"get_data(pathname) -> string with file data.\n\
531\n\
532Return the data associated with 'pathname'. Raise IOError if\n\
533the file wasn't found.");
534
535PyDoc_STRVAR(doc_is_package,
536"is_package(fullname) -> bool.\n\
537\n\
538Return True if the module specified by fullname is a package.\n\
Brian Curtin13b43e72010-07-21 01:35:46 +0000539Raise ZipImportError if the module couldn't be found.");
Just van Rossum52e14d62002-12-30 22:08:05 +0000540
541PyDoc_STRVAR(doc_get_code,
542"get_code(fullname) -> code object.\n\
543\n\
544Return the code object for the specified module. Raise ZipImportError\n\
Brian Curtin13b43e72010-07-21 01:35:46 +0000545if the module couldn't be found.");
Just van Rossum52e14d62002-12-30 22:08:05 +0000546
547PyDoc_STRVAR(doc_get_source,
548"get_source(fullname) -> source string.\n\
549\n\
550Return the source code for the specified module. Raise ZipImportError\n\
Brian Curtin13b43e72010-07-21 01:35:46 +0000551if the module couldn't be found, return None if the archive does\n\
Just van Rossum52e14d62002-12-30 22:08:05 +0000552contain the module, but has no source for it.");
553
Nick Coghlana2053472008-12-14 10:54:50 +0000554
555PyDoc_STRVAR(doc_get_filename,
Nick Coghlan0194f5b2009-02-08 03:17:00 +0000556"get_filename(fullname) -> filename string.\n\
Nick Coghlana2053472008-12-14 10:54:50 +0000557\n\
558Return the filename for the specified module.");
559
Just van Rossum52e14d62002-12-30 22:08:05 +0000560static PyMethodDef zipimporter_methods[] = {
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000561 {"find_module", zipimporter_find_module, METH_VARARGS,
562 doc_find_module},
563 {"load_module", zipimporter_load_module, METH_VARARGS,
564 doc_load_module},
565 {"get_data", zipimporter_get_data, METH_VARARGS,
566 doc_get_data},
567 {"get_code", zipimporter_get_code, METH_VARARGS,
568 doc_get_code},
569 {"get_source", zipimporter_get_source, METH_VARARGS,
570 doc_get_source},
571 {"get_filename", zipimporter_get_filename, METH_VARARGS,
572 doc_get_filename},
573 {"is_package", zipimporter_is_package, METH_VARARGS,
574 doc_is_package},
575 {NULL, NULL} /* sentinel */
Just van Rossum52e14d62002-12-30 22:08:05 +0000576};
577
578static PyMemberDef zipimporter_members[] = {
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000579 {"archive", T_OBJECT, offsetof(ZipImporter, archive), READONLY},
580 {"prefix", T_OBJECT, offsetof(ZipImporter, prefix), READONLY},
581 {"_files", T_OBJECT, offsetof(ZipImporter, files), READONLY},
582 {NULL}
Just van Rossum52e14d62002-12-30 22:08:05 +0000583};
584
585PyDoc_STRVAR(zipimporter_doc,
586"zipimporter(archivepath) -> zipimporter object\n\
587\n\
588Create a new zipimporter instance. 'archivepath' must be a path to\n\
Georg Brandl6a57c082008-05-11 15:05:13 +0000589a zipfile, or to a specific path inside a zipfile. For example, it can be\n\
590'/tmp/myimport.zip', or '/tmp/myimport.zip/mydirectory', if mydirectory is a\n\
591valid directory inside the archive.\n\
592\n\
593'ZipImportError is raised if 'archivepath' doesn't point to a valid Zip\n\
594archive.\n\
595\n\
596The 'archive' attribute of zipimporter objects contains the name of the\n\
597zipfile targeted.");
Just van Rossum52e14d62002-12-30 22:08:05 +0000598
599#define DEFERRED_ADDRESS(ADDR) 0
600
601static PyTypeObject ZipImporter_Type = {
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000602 PyVarObject_HEAD_INIT(DEFERRED_ADDRESS(&PyType_Type), 0)
603 "zipimport.zipimporter",
604 sizeof(ZipImporter),
605 0, /* tp_itemsize */
606 (destructor)zipimporter_dealloc, /* tp_dealloc */
607 0, /* tp_print */
608 0, /* tp_getattr */
609 0, /* tp_setattr */
610 0, /* tp_compare */
611 (reprfunc)zipimporter_repr, /* tp_repr */
612 0, /* tp_as_number */
613 0, /* tp_as_sequence */
614 0, /* tp_as_mapping */
615 0, /* tp_hash */
616 0, /* tp_call */
617 0, /* tp_str */
618 PyObject_GenericGetAttr, /* tp_getattro */
619 0, /* tp_setattro */
620 0, /* tp_as_buffer */
Benjamin Petersone9aab0f2014-02-16 14:20:14 -0500621 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE |
622 Py_TPFLAGS_HAVE_GC, /* tp_flags */
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000623 zipimporter_doc, /* tp_doc */
Benjamin Petersone9aab0f2014-02-16 14:20:14 -0500624 zipimporter_traverse, /* tp_traverse */
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000625 0, /* tp_clear */
626 0, /* tp_richcompare */
627 0, /* tp_weaklistoffset */
628 0, /* tp_iter */
629 0, /* tp_iternext */
630 zipimporter_methods, /* tp_methods */
631 zipimporter_members, /* tp_members */
632 0, /* tp_getset */
633 0, /* tp_base */
634 0, /* tp_dict */
635 0, /* tp_descr_get */
636 0, /* tp_descr_set */
637 0, /* tp_dictoffset */
638 (initproc)zipimporter_init, /* tp_init */
639 PyType_GenericAlloc, /* tp_alloc */
640 PyType_GenericNew, /* tp_new */
Benjamin Petersone9aab0f2014-02-16 14:20:14 -0500641 PyObject_GC_Del, /* tp_free */
Just van Rossum52e14d62002-12-30 22:08:05 +0000642};
643
644
645/* implementation */
646
Serhiy Storchakac4ef3842016-01-28 21:32:53 +0200647/* Given a buffer, return the unsigned int that is represented by the first
Just van Rossum52e14d62002-12-30 22:08:05 +0000648 4 bytes, encoded as little endian. This partially reimplements
649 marshal.c:r_long() */
Serhiy Storchakac4ef3842016-01-28 21:32:53 +0200650static unsigned int
651get_uint32(const unsigned char *buf)
652{
653 unsigned int x;
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000654 x = buf[0];
Serhiy Storchakac4ef3842016-01-28 21:32:53 +0200655 x |= (unsigned int)buf[1] << 8;
656 x |= (unsigned int)buf[2] << 16;
657 x |= (unsigned int)buf[3] << 24;
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000658 return x;
Just van Rossum52e14d62002-12-30 22:08:05 +0000659}
660
Serhiy Storchakac4ef3842016-01-28 21:32:53 +0200661/* Given a buffer, return the unsigned int that is represented by the first
662 2 bytes, encoded as little endian. This partially reimplements
663 marshal.c:r_short() */
664static unsigned short
665get_uint16(const unsigned char *buf)
666{
667 unsigned short x;
668 x = buf[0];
669 x |= (unsigned short)buf[1] << 8;
670 return x;
671}
672
673static void
674set_file_error(const char *archive, int eof)
675{
676 if (eof) {
677 PyErr_SetString(PyExc_EOFError, "EOF read where not expected");
678 }
679 else {
680 PyErr_SetFromErrnoWithFilename(PyExc_IOError, archive);
681 }
682}
683
Just van Rossum52e14d62002-12-30 22:08:05 +0000684/*
Benjamin Peterson384e9cb2014-02-16 14:46:57 -0500685 read_directory(archive) -> files dict (new reference)
Just van Rossum52e14d62002-12-30 22:08:05 +0000686
687 Given a path to a Zip archive, build a dict, mapping file names
688 (local to the archive, using SEP as a separator) to toc entries.
689
690 A toc_entry is a tuple:
691
Martin Panter5f755022016-09-15 01:50:53 +0000692 (__file__, # value to use for __file__, available for all files
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000693 compress, # compression kind; 0 for uncompressed
694 data_size, # size of compressed data on disk
695 file_size, # size of decompressed data
696 file_offset, # offset of file header from start of archive
697 time, # mod time of file (in dos format)
698 date, # mod data of file (in dos format)
699 crc, # crc checksum of the data
Martin Panter5f755022016-09-15 01:50:53 +0000700 )
Just van Rossum52e14d62002-12-30 22:08:05 +0000701
702 Directories can be recognized by the trailing SEP in the name,
703 data_size and file_offset are 0.
704*/
Dan Willemseneba50a52018-11-16 17:27:26 -0800705static PyObject *
Serhiy Storchakac4ef3842016-01-28 21:32:53 +0200706read_directory(const char *archive)
Just van Rossum52e14d62002-12-30 22:08:05 +0000707{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000708 PyObject *files = NULL;
Benjamin Peterson384e9cb2014-02-16 14:46:57 -0500709 FILE *fp;
Serhiy Storchakac4ef3842016-01-28 21:32:53 +0200710 unsigned short compress, time, date, name_size;
711 unsigned int crc, data_size, file_size, header_size, header_offset;
712 unsigned long file_offset, header_position;
713 unsigned long arc_offset; /* Absolute offset to start of the zip-archive. */
714 unsigned int count, i;
715 unsigned char buffer[46];
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000716 size_t length;
717 char path[MAXPATHLEN + 5];
718 char name[MAXPATHLEN + 5];
Serhiy Storchakac4ef3842016-01-28 21:32:53 +0200719 const char *errmsg = NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +0000720
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000721 if (strlen(archive) > MAXPATHLEN) {
722 PyErr_SetString(PyExc_OverflowError,
723 "Zip path name is too long");
724 return NULL;
725 }
726 strcpy(path, archive);
Just van Rossum52e14d62002-12-30 22:08:05 +0000727
Benjamin Peterson384e9cb2014-02-16 14:46:57 -0500728 fp = fopen(archive, "rb");
729 if (fp == NULL) {
730 PyErr_Format(ZipImportError, "can't open Zip file: "
731 "'%.200s'", archive);
732 return NULL;
733 }
734
Jesus Ceae884be62012-10-03 02:13:05 +0200735 if (fseek(fp, -22, SEEK_END) == -1) {
Serhiy Storchakac4ef3842016-01-28 21:32:53 +0200736 goto file_error;
Jesus Ceae884be62012-10-03 02:13:05 +0200737 }
Serhiy Storchakac4ef3842016-01-28 21:32:53 +0200738 header_position = (unsigned long)ftell(fp);
739 if (header_position == (unsigned long)-1) {
740 goto file_error;
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000741 }
Serhiy Storchakac4ef3842016-01-28 21:32:53 +0200742 assert(header_position <= (unsigned long)LONG_MAX);
743 if (fread(buffer, 1, 22, fp) != 22) {
744 goto file_error;
745 }
746 if (get_uint32(buffer) != 0x06054B50u) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000747 /* Bad: End of Central Dir signature */
Serhiy Storchakac4ef3842016-01-28 21:32:53 +0200748 errmsg = "not a Zip file";
749 goto invalid_header;
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000750 }
Just van Rossum52e14d62002-12-30 22:08:05 +0000751
Serhiy Storchakac4ef3842016-01-28 21:32:53 +0200752 header_size = get_uint32(buffer + 12);
753 header_offset = get_uint32(buffer + 16);
754 if (header_position < header_size) {
755 errmsg = "bad central directory size";
756 goto invalid_header;
757 }
758 if (header_position < header_offset) {
759 errmsg = "bad central directory offset";
760 goto invalid_header;
761 }
762 if (header_position - header_size < header_offset) {
763 errmsg = "bad central directory size or offset";
764 goto invalid_header;
765 }
766 header_position -= header_size;
767 arc_offset = header_position - header_offset;
Just van Rossum52e14d62002-12-30 22:08:05 +0000768
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000769 files = PyDict_New();
Serhiy Storchakac4ef3842016-01-28 21:32:53 +0200770 if (files == NULL) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000771 goto error;
Serhiy Storchakac4ef3842016-01-28 21:32:53 +0200772 }
Just van Rossum52e14d62002-12-30 22:08:05 +0000773
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000774 length = (long)strlen(path);
775 path[length] = SEP;
Just van Rossum52e14d62002-12-30 22:08:05 +0000776
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000777 /* Start of Central Directory */
778 count = 0;
Serhiy Storchaka13ea0c52016-01-29 00:37:28 +0200779 if (fseek(fp, (long)header_position, 0) == -1) {
780 goto file_error;
781 }
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000782 for (;;) {
783 PyObject *t;
Serhiy Storchakac4ef3842016-01-28 21:32:53 +0200784 size_t n;
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000785 int err;
Just van Rossum52e14d62002-12-30 22:08:05 +0000786
Serhiy Storchakac4ef3842016-01-28 21:32:53 +0200787 n = fread(buffer, 1, 46, fp);
788 if (n < 4) {
789 goto eof_error;
790 }
791 /* Start of file header */
792 if (get_uint32(buffer) != 0x02014B50u) {
793 break; /* Bad: Central Dir File Header */
794 }
795 if (n != 46) {
796 goto eof_error;
797 }
798 compress = get_uint16(buffer + 10);
799 time = get_uint16(buffer + 12);
800 date = get_uint16(buffer + 14);
801 crc = get_uint32(buffer + 16);
802 data_size = get_uint32(buffer + 20);
803 file_size = get_uint32(buffer + 24);
804 name_size = get_uint16(buffer + 28);
805 header_size = (unsigned int)name_size +
806 get_uint16(buffer + 30) /* extra field */ +
807 get_uint16(buffer + 32) /* comment */;
808
809 file_offset = get_uint32(buffer + 42);
810 if (file_offset > header_offset) {
811 errmsg = "bad local header offset";
812 goto invalid_header;
813 }
814 file_offset += arc_offset;
815
816 if (name_size > MAXPATHLEN) {
817 name_size = MAXPATHLEN;
818 }
819 if (fread(name, 1, name_size, fp) != name_size) {
820 goto file_error;
821 }
822 name[name_size] = '\0'; /* Add terminating null byte */
823 if (SEP != '/') {
824 for (i = 0; i < name_size; i++) {
825 if (name[i] == '/') {
826 name[i] = SEP;
827 }
828 }
829 }
830 /* Skip the rest of the header.
831 * On Windows, calling fseek to skip over the fields we don't use is
832 * slower than reading the data because fseek flushes stdio's
833 * internal buffers. See issue #8745. */
834 assert(header_size <= 3*0xFFFFu);
835 for (i = name_size; i < header_size; i++) {
836 if (getc(fp) == EOF) {
837 goto file_error;
838 }
839 }
Just van Rossum52e14d62002-12-30 22:08:05 +0000840
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000841 strncpy(path + length + 1, name, MAXPATHLEN - length - 1);
Just van Rossum52e14d62002-12-30 22:08:05 +0000842
Serhiy Storchakac4ef3842016-01-28 21:32:53 +0200843 t = Py_BuildValue("sHIIkHHI", path, compress, data_size,
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000844 file_size, file_offset, time, date, crc);
Serhiy Storchakac4ef3842016-01-28 21:32:53 +0200845 if (t == NULL) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000846 goto error;
Serhiy Storchakac4ef3842016-01-28 21:32:53 +0200847 }
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000848 err = PyDict_SetItemString(files, name, t);
849 Py_DECREF(t);
Serhiy Storchakac4ef3842016-01-28 21:32:53 +0200850 if (err != 0) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000851 goto error;
Serhiy Storchakac4ef3842016-01-28 21:32:53 +0200852 }
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000853 count++;
854 }
Benjamin Peterson384e9cb2014-02-16 14:46:57 -0500855 fclose(fp);
Serhiy Storchakac4ef3842016-01-28 21:32:53 +0200856 if (Py_VerboseFlag) {
857 PySys_WriteStderr("# zipimport: found %u names in %.200s\n",
858 count, archive);
859 }
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000860 return files;
Serhiy Storchakac4ef3842016-01-28 21:32:53 +0200861
862eof_error:
863 set_file_error(archive, !ferror(fp));
864 goto error;
865
866file_error:
867 PyErr_Format(ZipImportError, "can't read Zip file: %.200s", archive);
868 goto error;
869
870invalid_header:
871 assert(errmsg != NULL);
872 PyErr_Format(ZipImportError, "%s: %.200s", errmsg, archive);
873 goto error;
874
Just van Rossum52e14d62002-12-30 22:08:05 +0000875error:
Benjamin Peterson384e9cb2014-02-16 14:46:57 -0500876 fclose(fp);
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000877 Py_XDECREF(files);
878 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +0000879}
880
881/* Return the zlib.decompress function object, or NULL if zlib couldn't
882 be imported. The function is cached when found, so subsequent calls
Victor Stinnerf58f1c32011-05-21 02:13:22 +0200883 don't import zlib again. */
Just van Rossum52e14d62002-12-30 22:08:05 +0000884static PyObject *
885get_decompress_func(void)
886{
Victor Stinnerf58f1c32011-05-21 02:13:22 +0200887 static int importing_zlib = 0;
888 PyObject *zlib;
889 PyObject *decompress;
Just van Rossum52e14d62002-12-30 22:08:05 +0000890
Victor Stinnerf58f1c32011-05-21 02:13:22 +0200891 if (importing_zlib != 0)
892 /* Someone has a zlib.py[co] in their Zip file;
893 let's avoid a stack overflow. */
894 return NULL;
895 importing_zlib = 1;
896 zlib = PyImport_ImportModuleNoBlock("zlib");
897 importing_zlib = 0;
898 if (zlib != NULL) {
899 decompress = PyObject_GetAttrString(zlib,
900 "decompress");
901 Py_DECREF(zlib);
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000902 }
Victor Stinnerf58f1c32011-05-21 02:13:22 +0200903 else {
904 PyErr_Clear();
905 decompress = NULL;
906 }
907 if (Py_VerboseFlag)
908 PySys_WriteStderr("# zipimport: zlib %s\n",
909 zlib != NULL ? "available": "UNAVAILABLE");
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000910 return decompress;
Just van Rossum52e14d62002-12-30 22:08:05 +0000911}
912
Benjamin Peterson384e9cb2014-02-16 14:46:57 -0500913/* Given a path to a Zip file and a toc_entry, return the (uncompressed)
Just van Rossum52e14d62002-12-30 22:08:05 +0000914 data as a new reference. */
Dan Willemseneba50a52018-11-16 17:27:26 -0800915static PyObject *
Serhiy Storchakac4ef3842016-01-28 21:32:53 +0200916get_data(const char *archive, PyObject *toc_entry)
Just van Rossum52e14d62002-12-30 22:08:05 +0000917{
Serhiy Storchakac4ef3842016-01-28 21:32:53 +0200918 PyObject *raw_data = NULL, *data, *decompress;
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000919 char *buf;
Benjamin Peterson384e9cb2014-02-16 14:46:57 -0500920 FILE *fp;
Serhiy Storchakac4ef3842016-01-28 21:32:53 +0200921 const char *datapath;
922 unsigned short compress, time, date;
923 unsigned int crc;
924 Py_ssize_t data_size, file_size;
925 long file_offset, header_size;
926 unsigned char buffer[30];
927 const char *errmsg = NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +0000928
Serhiy Storchakac4ef3842016-01-28 21:32:53 +0200929 if (!PyArg_ParseTuple(toc_entry, "sHnnlHHI", &datapath, &compress,
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000930 &data_size, &file_size, &file_offset, &time,
931 &date, &crc)) {
932 return NULL;
933 }
Benjamin Peterson5640bbb2016-01-21 22:02:46 -0800934 if (data_size < 0) {
935 PyErr_Format(ZipImportError, "negative data size");
936 return NULL;
937 }
Just van Rossum52e14d62002-12-30 22:08:05 +0000938
Benjamin Peterson384e9cb2014-02-16 14:46:57 -0500939 fp = fopen(archive, "rb");
940 if (!fp) {
941 PyErr_Format(PyExc_IOError,
942 "zipimport: can not open file %s", archive);
943 return NULL;
944 }
945
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000946 /* Check to make sure the local file header is correct */
Jesus Ceae884be62012-10-03 02:13:05 +0200947 if (fseek(fp, file_offset, 0) == -1) {
Serhiy Storchakac4ef3842016-01-28 21:32:53 +0200948 goto file_error;
Jesus Ceae884be62012-10-03 02:13:05 +0200949 }
Serhiy Storchakac4ef3842016-01-28 21:32:53 +0200950 if (fread(buffer, 1, 30, fp) != 30) {
951 goto eof_error;
952 }
953 if (get_uint32(buffer) != 0x04034B50u) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000954 /* Bad: Local File Header */
Serhiy Storchakac4ef3842016-01-28 21:32:53 +0200955 errmsg = "bad local file header";
956 goto invalid_header;
Jesus Ceae884be62012-10-03 02:13:05 +0200957 }
958
Serhiy Storchakac4ef3842016-01-28 21:32:53 +0200959 header_size = (unsigned int)30 +
960 get_uint16(buffer + 26) /* file name */ +
961 get_uint16(buffer + 28) /* extra field */;
962 if (file_offset > LONG_MAX - header_size) {
963 errmsg = "bad local file header size";
964 goto invalid_header;
965 }
966 file_offset += header_size; /* Start of file data */
Just van Rossum52e14d62002-12-30 22:08:05 +0000967
Benjamin Peterson64ea1922016-01-20 22:23:44 -0800968 if (data_size > LONG_MAX - 1) {
969 fclose(fp);
970 PyErr_NoMemory();
971 return NULL;
972 }
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000973 raw_data = PyString_FromStringAndSize((char *)NULL, compress == 0 ?
974 data_size : data_size + 1);
Serhiy Storchakac4ef3842016-01-28 21:32:53 +0200975
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000976 if (raw_data == NULL) {
Serhiy Storchakac4ef3842016-01-28 21:32:53 +0200977 goto error;
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000978 }
979 buf = PyString_AsString(raw_data);
Just van Rossum52e14d62002-12-30 22:08:05 +0000980
Serhiy Storchakac4ef3842016-01-28 21:32:53 +0200981 if (fseek(fp, file_offset, 0) == -1) {
982 goto file_error;
Jesus Ceae884be62012-10-03 02:13:05 +0200983 }
Serhiy Storchakac4ef3842016-01-28 21:32:53 +0200984 if (fread(buf, 1, data_size, fp) != (size_t)data_size) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000985 PyErr_SetString(PyExc_IOError,
986 "zipimport: can't read data");
Serhiy Storchakac4ef3842016-01-28 21:32:53 +0200987 goto error;
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000988 }
Just van Rossum52e14d62002-12-30 22:08:05 +0000989
Serhiy Storchakac4ef3842016-01-28 21:32:53 +0200990 fclose(fp);
991 fp = NULL;
992
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000993 if (compress != 0) {
994 buf[data_size] = 'Z'; /* saw this in zipfile.py */
995 data_size++;
996 }
997 buf[data_size] = '\0';
Just van Rossum52e14d62002-12-30 22:08:05 +0000998
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000999 if (compress == 0) /* data is not compressed */
1000 return raw_data;
Just van Rossum52e14d62002-12-30 22:08:05 +00001001
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001002 /* Decompress with zlib */
1003 decompress = get_decompress_func();
1004 if (decompress == NULL) {
1005 PyErr_SetString(ZipImportError,
1006 "can't decompress data; "
1007 "zlib not available");
1008 goto error;
1009 }
1010 data = PyObject_CallFunction(decompress, "Oi", raw_data, -15);
Victor Stinnerf58f1c32011-05-21 02:13:22 +02001011 Py_DECREF(decompress);
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001012 Py_DECREF(raw_data);
1013 return data;
Serhiy Storchakac4ef3842016-01-28 21:32:53 +02001014
1015eof_error:
1016 set_file_error(archive, !ferror(fp));
1017 goto error;
1018
1019file_error:
1020 PyErr_Format(ZipImportError, "can't read Zip file: %.200s", archive);
1021 goto error;
1022
1023invalid_header:
1024 assert(errmsg != NULL);
1025 PyErr_Format(ZipImportError, "%s: %.200s", errmsg, archive);
1026 goto error;
1027
1028error:
1029 if (fp != NULL) {
1030 fclose(fp);
1031 }
1032 Py_XDECREF(raw_data);
1033 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +00001034}
1035
1036/* Lenient date/time comparison function. The precision of the mtime
1037 in the archive is lower than the mtime stored in a .pyc: we
1038 must allow a difference of at most one second. */
1039static int
1040eq_mtime(time_t t1, time_t t2)
1041{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001042 time_t d = t1 - t2;
1043 if (d < 0)
1044 d = -d;
1045 /* dostime only stores even seconds, so be lenient */
1046 return d <= 1;
Just van Rossum52e14d62002-12-30 22:08:05 +00001047}
1048
1049/* Given the contents of a .py[co] file in a buffer, unmarshal the data
1050 and return the code object. Return None if it the magic word doesn't
1051 match (we do this instead of raising an exception as we fall back
1052 to .py if available and we don't want to mask other errors).
1053 Returns a new reference. */
1054static PyObject *
Serhiy Storchakac4ef3842016-01-28 21:32:53 +02001055unmarshal_code(const char *pathname, PyObject *data, time_t mtime)
Just van Rossum52e14d62002-12-30 22:08:05 +00001056{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001057 PyObject *code;
Serhiy Storchakac4ef3842016-01-28 21:32:53 +02001058 unsigned char *buf = (unsigned char *)PyString_AsString(data);
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001059 Py_ssize_t size = PyString_Size(data);
Just van Rossum52e14d62002-12-30 22:08:05 +00001060
Serhiy Storchakac4ef3842016-01-28 21:32:53 +02001061 if (size < 8) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001062 PyErr_SetString(ZipImportError,
1063 "bad pyc data");
1064 return NULL;
1065 }
Just van Rossum52e14d62002-12-30 22:08:05 +00001066
Serhiy Storchakac4ef3842016-01-28 21:32:53 +02001067 if (get_uint32(buf) != (unsigned int)PyImport_GetMagicNumber()) {
1068 if (Py_VerboseFlag) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001069 PySys_WriteStderr("# %s has bad magic\n",
1070 pathname);
Serhiy Storchakac4ef3842016-01-28 21:32:53 +02001071 }
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001072 Py_INCREF(Py_None);
1073 return Py_None; /* signal caller to try alternative */
1074 }
Just van Rossum52e14d62002-12-30 22:08:05 +00001075
Serhiy Storchakac4ef3842016-01-28 21:32:53 +02001076 if (mtime != 0 && !eq_mtime(get_uint32(buf + 4), mtime)) {
1077 if (Py_VerboseFlag) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001078 PySys_WriteStderr("# %s has bad mtime\n",
1079 pathname);
Serhiy Storchakac4ef3842016-01-28 21:32:53 +02001080 }
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001081 Py_INCREF(Py_None);
1082 return Py_None; /* signal caller to try alternative */
1083 }
Just van Rossum52e14d62002-12-30 22:08:05 +00001084
Serhiy Storchakac4ef3842016-01-28 21:32:53 +02001085 code = PyMarshal_ReadObjectFromString((char *)buf + 8, size - 8);
1086 if (code == NULL) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001087 return NULL;
Serhiy Storchakac4ef3842016-01-28 21:32:53 +02001088 }
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001089 if (!PyCode_Check(code)) {
1090 Py_DECREF(code);
1091 PyErr_Format(PyExc_TypeError,
1092 "compiled module %.200s is not a code object",
1093 pathname);
1094 return NULL;
1095 }
1096 return code;
Just van Rossum52e14d62002-12-30 22:08:05 +00001097}
1098
Martin Panter65076572016-09-07 12:03:06 +00001099/* Replace any occurrences of "\r\n?" in the input string with "\n".
Just van Rossum52e14d62002-12-30 22:08:05 +00001100 This converts DOS and Mac line endings to Unix line endings.
1101 Also append a trailing "\n" to be compatible with
1102 PyParser_SimpleParseFile(). Returns a new reference. */
1103static PyObject *
1104normalize_line_endings(PyObject *source)
1105{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001106 char *buf, *q, *p = PyString_AsString(source);
1107 PyObject *fixed_source;
Just van Rossum52e14d62002-12-30 22:08:05 +00001108
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001109 if (!p)
1110 return NULL;
Neal Norwitzee7c8f92006-08-13 18:12:03 +00001111
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001112 /* one char extra for trailing \n and one for terminating \0 */
1113 buf = (char *)PyMem_Malloc(PyString_Size(source) + 2);
1114 if (buf == NULL) {
1115 PyErr_SetString(PyExc_MemoryError,
1116 "zipimport: no memory to allocate "
1117 "source buffer");
1118 return NULL;
1119 }
1120 /* replace "\r\n?" by "\n" */
1121 for (q = buf; *p != '\0'; p++) {
1122 if (*p == '\r') {
1123 *q++ = '\n';
1124 if (*(p + 1) == '\n')
1125 p++;
1126 }
1127 else
1128 *q++ = *p;
1129 }
1130 *q++ = '\n'; /* add trailing \n */
1131 *q = '\0';
1132 fixed_source = PyString_FromString(buf);
1133 PyMem_Free(buf);
1134 return fixed_source;
Just van Rossum52e14d62002-12-30 22:08:05 +00001135}
1136
1137/* Given a string buffer containing Python source code, compile it
1138 return and return a code object as a new reference. */
1139static PyObject *
1140compile_source(char *pathname, PyObject *source)
1141{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001142 PyObject *code, *fixed_source;
Just van Rossum52e14d62002-12-30 22:08:05 +00001143
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001144 fixed_source = normalize_line_endings(source);
1145 if (fixed_source == NULL)
1146 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +00001147
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001148 code = Py_CompileString(PyString_AsString(fixed_source), pathname,
1149 Py_file_input);
1150 Py_DECREF(fixed_source);
1151 return code;
Just van Rossum52e14d62002-12-30 22:08:05 +00001152}
1153
1154/* Convert the date/time values found in the Zip archive to a value
1155 that's compatible with the time stamp stored in .pyc files. */
Neal Norwitz29fd2ba2003-03-23 13:21:03 +00001156static time_t
1157parse_dostime(int dostime, int dosdate)
Just van Rossum52e14d62002-12-30 22:08:05 +00001158{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001159 struct tm stm;
Just van Rossum52e14d62002-12-30 22:08:05 +00001160
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001161 memset((void *) &stm, '\0', sizeof(stm));
Christian Heimes62a8e952008-01-18 07:30:20 +00001162
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001163 stm.tm_sec = (dostime & 0x1f) * 2;
1164 stm.tm_min = (dostime >> 5) & 0x3f;
1165 stm.tm_hour = (dostime >> 11) & 0x1f;
1166 stm.tm_mday = dosdate & 0x1f;
1167 stm.tm_mon = ((dosdate >> 5) & 0x0f) - 1;
1168 stm.tm_year = ((dosdate >> 9) & 0x7f) + 80;
1169 stm.tm_isdst = -1; /* wday/yday is ignored */
Just van Rossum52e14d62002-12-30 22:08:05 +00001170
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001171 return mktime(&stm);
Just van Rossum52e14d62002-12-30 22:08:05 +00001172}
1173
1174/* Given a path to a .pyc or .pyo file in the archive, return the
Ezio Melottic2077b02011-03-16 12:34:31 +02001175 modification time of the matching .py file, or 0 if no source
Just van Rossum52e14d62002-12-30 22:08:05 +00001176 is available. */
1177static time_t
1178get_mtime_of_source(ZipImporter *self, char *path)
1179{
Benjamin Petersone9aab0f2014-02-16 14:20:14 -05001180 PyObject *toc_entry;
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001181 time_t mtime = 0;
1182 Py_ssize_t lastchar = strlen(path) - 1;
1183 char savechar = path[lastchar];
1184 path[lastchar] = '\0'; /* strip 'c' or 'o' from *.py[co] */
Benjamin Petersone9aab0f2014-02-16 14:20:14 -05001185 toc_entry = PyDict_GetItemString(self->files, path);
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001186 if (toc_entry != NULL && PyTuple_Check(toc_entry) &&
1187 PyTuple_Size(toc_entry) == 8) {
1188 /* fetch the time stamp of the .py file for comparison
1189 with an embedded pyc time stamp */
1190 int time, date;
1191 time = PyInt_AsLong(PyTuple_GetItem(toc_entry, 5));
1192 date = PyInt_AsLong(PyTuple_GetItem(toc_entry, 6));
1193 mtime = parse_dostime(time, date);
1194 }
1195 path[lastchar] = savechar;
1196 return mtime;
Just van Rossum52e14d62002-12-30 22:08:05 +00001197}
1198
1199/* Return the code object for the module named by 'fullname' from the
1200 Zip archive as a new reference. */
1201static PyObject *
Benjamin Peterson384e9cb2014-02-16 14:46:57 -05001202get_code_from_data(ZipImporter *self, int ispackage, int isbytecode,
1203 time_t mtime, PyObject *toc_entry)
Just van Rossum52e14d62002-12-30 22:08:05 +00001204{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001205 PyObject *data, *code;
1206 char *modpath;
Benjamin Peterson384e9cb2014-02-16 14:46:57 -05001207 char *archive = PyString_AsString(self->archive);
Just van Rossum52e14d62002-12-30 22:08:05 +00001208
Benjamin Peterson384e9cb2014-02-16 14:46:57 -05001209 if (archive == NULL)
1210 return NULL;
1211
1212 data = get_data(archive, toc_entry);
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001213 if (data == NULL)
1214 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +00001215
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001216 modpath = PyString_AsString(PyTuple_GetItem(toc_entry, 0));
Just van Rossum52e14d62002-12-30 22:08:05 +00001217
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001218 if (isbytecode) {
1219 code = unmarshal_code(modpath, data, mtime);
1220 }
1221 else {
1222 code = compile_source(modpath, data);
1223 }
1224 Py_DECREF(data);
1225 return code;
Just van Rossum52e14d62002-12-30 22:08:05 +00001226}
1227
Ezio Melotti24b07bc2011-03-15 18:55:01 +02001228/* Get the code object associated with the module specified by
Just van Rossum52e14d62002-12-30 22:08:05 +00001229 'fullname'. */
1230static PyObject *
1231get_module_code(ZipImporter *self, char *fullname,
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001232 int *p_ispackage, char **p_modpath)
Just van Rossum52e14d62002-12-30 22:08:05 +00001233{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001234 PyObject *toc_entry;
1235 char *subname, path[MAXPATHLEN + 1];
1236 int len;
1237 struct st_zip_searchorder *zso;
Just van Rossum52e14d62002-12-30 22:08:05 +00001238
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001239 subname = get_subname(fullname);
Just van Rossum52e14d62002-12-30 22:08:05 +00001240
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001241 len = make_filename(PyString_AsString(self->prefix), subname, path);
1242 if (len < 0)
1243 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +00001244
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001245 for (zso = zip_searchorder; *zso->suffix; zso++) {
Benjamin Petersone9aab0f2014-02-16 14:20:14 -05001246 PyObject *code = NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +00001247
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001248 strcpy(path + len, zso->suffix);
1249 if (Py_VerboseFlag > 1)
1250 PySys_WriteStderr("# trying %s%c%s\n",
1251 PyString_AsString(self->archive),
1252 SEP, path);
Benjamin Petersone9aab0f2014-02-16 14:20:14 -05001253 toc_entry = PyDict_GetItemString(self->files, path);
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001254 if (toc_entry != NULL) {
1255 time_t mtime = 0;
1256 int ispackage = zso->type & IS_PACKAGE;
1257 int isbytecode = zso->type & IS_BYTECODE;
Just van Rossum52e14d62002-12-30 22:08:05 +00001258
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001259 if (isbytecode)
1260 mtime = get_mtime_of_source(self, path);
1261 if (p_ispackage != NULL)
1262 *p_ispackage = ispackage;
Benjamin Peterson384e9cb2014-02-16 14:46:57 -05001263 code = get_code_from_data(self, ispackage,
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001264 isbytecode, mtime,
1265 toc_entry);
1266 if (code == Py_None) {
1267 /* bad magic number or non-matching mtime
1268 in byte code, try next */
1269 Py_DECREF(code);
1270 continue;
1271 }
1272 if (code != NULL && p_modpath != NULL)
1273 *p_modpath = PyString_AsString(
1274 PyTuple_GetItem(toc_entry, 0));
1275 return code;
1276 }
1277 }
1278 PyErr_Format(ZipImportError, "can't find module '%.200s'", fullname);
1279 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +00001280}
1281
1282
1283/* Module init */
1284
1285PyDoc_STRVAR(zipimport_doc,
1286"zipimport provides support for importing Python modules from Zip archives.\n\
1287\n\
1288This module exports three objects:\n\
1289- zipimporter: a class; its constructor takes a path to a Zip archive.\n\
Fredrik Lundhb84b35f2006-01-15 15:00:40 +00001290- ZipImportError: exception raised by zipimporter objects. It's a\n\
Just van Rossum52e14d62002-12-30 22:08:05 +00001291 subclass of ImportError, so it can be caught as ImportError, too.\n\
1292- _zip_directory_cache: a dict, mapping archive paths to zip directory\n\
1293 info dicts, as used in zipimporter._files.\n\
1294\n\
1295It is usually not needed to use the zipimport module explicitly; it is\n\
1296used by the builtin import mechanism for sys.path items that are paths\n\
1297to Zip archives.");
1298
1299PyMODINIT_FUNC
1300initzipimport(void)
1301{
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001302 PyObject *mod;
Just van Rossum52e14d62002-12-30 22:08:05 +00001303
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001304 if (PyType_Ready(&ZipImporter_Type) < 0)
1305 return;
Just van Rossum52e14d62002-12-30 22:08:05 +00001306
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001307 /* Correct directory separator */
1308 zip_searchorder[0].suffix[0] = SEP;
1309 zip_searchorder[1].suffix[0] = SEP;
1310 zip_searchorder[2].suffix[0] = SEP;
1311 if (Py_OptimizeFlag) {
1312 /* Reverse *.pyc and *.pyo */
1313 struct st_zip_searchorder tmp;
1314 tmp = zip_searchorder[0];
1315 zip_searchorder[0] = zip_searchorder[1];
1316 zip_searchorder[1] = tmp;
1317 tmp = zip_searchorder[3];
1318 zip_searchorder[3] = zip_searchorder[4];
1319 zip_searchorder[4] = tmp;
1320 }
Just van Rossum52e14d62002-12-30 22:08:05 +00001321
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001322 mod = Py_InitModule4("zipimport", NULL, zipimport_doc,
1323 NULL, PYTHON_API_VERSION);
1324 if (mod == NULL)
1325 return;
Just van Rossum52e14d62002-12-30 22:08:05 +00001326
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001327 ZipImportError = PyErr_NewException("zipimport.ZipImportError",
1328 PyExc_ImportError, NULL);
1329 if (ZipImportError == NULL)
1330 return;
Just van Rossum52e14d62002-12-30 22:08:05 +00001331
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001332 Py_INCREF(ZipImportError);
1333 if (PyModule_AddObject(mod, "ZipImportError",
1334 ZipImportError) < 0)
1335 return;
Just van Rossum52e14d62002-12-30 22:08:05 +00001336
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001337 Py_INCREF(&ZipImporter_Type);
1338 if (PyModule_AddObject(mod, "zipimporter",
1339 (PyObject *)&ZipImporter_Type) < 0)
1340 return;
Just van Rossumf8b6de12002-12-31 09:51:59 +00001341
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001342 zip_directory_cache = PyDict_New();
1343 if (zip_directory_cache == NULL)
1344 return;
1345 Py_INCREF(zip_directory_cache);
1346 if (PyModule_AddObject(mod, "_zip_directory_cache",
1347 zip_directory_cache) < 0)
1348 return;
Just van Rossum52e14d62002-12-30 22:08:05 +00001349}