blob: f822f92d85779e8a28afc477390485eb338ad2b5 [file] [log] [blame]
Just van Rossum52e14d62002-12-30 22:08:05 +00001#include "Python.h"
2#include "structmember.h"
3#include "osdefs.h"
4#include "marshal.h"
Just van Rossum52e14d62002-12-30 22:08:05 +00005#include <time.h>
6
7
8#define IS_SOURCE 0x0
9#define IS_BYTECODE 0x1
10#define IS_PACKAGE 0x2
11
12struct st_zip_searchorder {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000013 char suffix[14];
14 int type;
Just van Rossum52e14d62002-12-30 22:08:05 +000015};
16
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 Pitrouf95a1b32010-05-09 15:52:27 +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 Pitrouf95a1b32010-05-09 15:52:27 +000037 PyObject_HEAD
Victor Stinner9e40fad2010-10-18 22:34:46 +000038 PyObject *archive; /* pathname of the Zip archive,
39 decoded from the filesystem encoding */
Victor Stinner72f767e2010-10-18 11:44:21 +000040 PyObject *prefix; /* file prefix: "a/sub/directory/",
41 encoded to the filesystem encoding */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000042 PyObject *files; /* dict with file info {path: toc_entry} */
Just van Rossum52e14d62002-12-30 22:08:05 +000043};
44
Just van Rossum52e14d62002-12-30 22:08:05 +000045static PyObject *ZipImportError;
Victor Stinnerc342fca2010-10-18 11:39:05 +000046/* read_directory() cache */
Just van Rossum52e14d62002-12-30 22:08:05 +000047static PyObject *zip_directory_cache = NULL;
48
49/* forward decls */
Victor Stinner2460a432010-08-16 17:54:28 +000050static PyObject *read_directory(PyObject *archive);
Victor Stinner60fe8d92010-08-16 23:48:11 +000051static PyObject *get_data(PyObject *archive, PyObject *toc_entry);
Victor Stinnerf6b563a2011-03-14 20:46:50 -040052static PyObject *get_module_code(ZipImporter *self, PyObject *fullname,
Victor Stinner08654e12010-10-18 12:09:02 +000053 int *p_ispackage, PyObject **p_modpath);
Just van Rossum52e14d62002-12-30 22:08:05 +000054
55
56#define ZipImporter_Check(op) PyObject_TypeCheck(op, &ZipImporter_Type)
57
58
59/* zipimporter.__init__
60 Split the "subdirectory" from the Zip archive path, lookup a matching
61 entry in sys.path_importer_cache, fetch the file directory from there
62 if found, or else read it from the archive. */
63static int
64zipimporter_init(ZipImporter *self, PyObject *args, PyObject *kwds)
65{
Martin v. Löwisa72e78b2011-10-31 08:33:37 +010066 PyObject *path, *files, *tmp;
67 PyObject *filename = NULL;
68 Py_ssize_t len, flen;
69#ifdef ALTSEP
70 _Py_IDENTIFIER(replace);
71#endif
Just van Rossum52e14d62002-12-30 22:08:05 +000072
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000073 if (!_PyArg_NoKeywords("zipimporter()", kwds))
74 return -1;
Georg Brandl02c42872005-08-26 06:42:30 +000075
Victor Stinner2b8dab72010-08-14 14:54:10 +000076 if (!PyArg_ParseTuple(args, "O&:zipimporter",
Martin v. Löwisa72e78b2011-10-31 08:33:37 +010077 PyUnicode_FSDecoder, &path))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000078 return -1;
Just van Rossum52e14d62002-12-30 22:08:05 +000079
Martin v. Löwisa72e78b2011-10-31 08:33:37 +010080 if (PyUnicode_READY(path) == -1)
Martin v. Löwisd63a3b82011-09-28 07:41:54 +020081 return -1;
82
Martin v. Löwisa72e78b2011-10-31 08:33:37 +010083 len = PyUnicode_GET_LENGTH(path);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000084 if (len == 0) {
85 PyErr_SetString(ZipImportError, "archive path is empty");
Victor Stinner2b8dab72010-08-14 14:54:10 +000086 goto error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000087 }
Just van Rossum52e14d62002-12-30 22:08:05 +000088
89#ifdef ALTSEP
Martin v. Löwiscfa61292011-10-31 09:01:22 +010090 tmp = _PyObject_CallMethodId(path, &PyId_replace, "CC", ALTSEP, SEP);
Martin v. Löwisa72e78b2011-10-31 08:33:37 +010091 if (!tmp)
92 goto error;
93 Py_DECREF(path);
94 path = tmp;
Just van Rossum52e14d62002-12-30 22:08:05 +000095#endif
96
Martin v. Löwisa72e78b2011-10-31 08:33:37 +010097 filename = path;
98 Py_INCREF(filename);
99 flen = len;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000100 for (;;) {
101 struct stat statbuf;
102 int rv;
Just van Rossum52e14d62002-12-30 22:08:05 +0000103
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100104 rv = _Py_stat(filename, &statbuf);
Victor Stinnerbd0850b2011-12-18 20:47:30 +0100105 if (rv == -2)
106 goto error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000107 if (rv == 0) {
108 /* it exists */
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100109 if (!S_ISREG(statbuf.st_mode))
110 /* it's a not file */
111 Py_CLEAR(filename);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000112 break;
113 }
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100114 Py_CLEAR(filename);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000115 /* back up one path element */
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100116 flen = PyUnicode_FindChar(path, SEP, 0, flen, -1);
117 if (flen == -1)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000118 break;
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100119 filename = PyUnicode_Substring(path, 0, flen);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000120 }
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100121 if (filename == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000122 PyErr_SetString(ZipImportError, "not a Zip file");
Victor Stinner2b8dab72010-08-14 14:54:10 +0000123 goto error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000124 }
Just van Rossum52e14d62002-12-30 22:08:05 +0000125
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100126 if (PyUnicode_READY(filename) < 0)
127 goto error;
128
129 files = PyDict_GetItem(zip_directory_cache, filename);
Victor Stinner2b8dab72010-08-14 14:54:10 +0000130 if (files == NULL) {
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100131 files = read_directory(filename);
Victor Stinner2b8dab72010-08-14 14:54:10 +0000132 if (files == NULL)
133 goto error;
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100134 if (PyDict_SetItem(zip_directory_cache, filename, files) != 0)
Victor Stinner2b8dab72010-08-14 14:54:10 +0000135 goto error;
136 }
137 else
138 Py_INCREF(files);
139 self->files = files;
140
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100141 /* Transfer reference */
142 self->archive = filename;
143 filename = NULL;
Victor Stinner2b8dab72010-08-14 14:54:10 +0000144
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100145 /* Check if there is a prefix directory following the filename. */
146 if (flen != len) {
147 tmp = PyUnicode_Substring(path, flen+1,
148 PyUnicode_GET_LENGTH(path));
149 if (tmp == NULL)
150 goto error;
151 self->prefix = tmp;
152 if (PyUnicode_READ_CHAR(path, len-1) != SEP) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000153 /* add trailing SEP */
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100154 tmp = PyUnicode_FromFormat("%U%c", self->prefix, SEP);
155 if (tmp == NULL)
156 goto error;
157 Py_DECREF(self->prefix);
158 self->prefix = tmp;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000159 }
160 }
Victor Stinner2b8dab72010-08-14 14:54:10 +0000161 else
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100162 self->prefix = PyUnicode_New(0, 0);
163 Py_DECREF(path);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000164 return 0;
Victor Stinner2b8dab72010-08-14 14:54:10 +0000165
166error:
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100167 Py_DECREF(path);
168 Py_XDECREF(filename);
Victor Stinner2b8dab72010-08-14 14:54:10 +0000169 return -1;
Just van Rossum52e14d62002-12-30 22:08:05 +0000170}
171
172/* GC support. */
173static int
174zipimporter_traverse(PyObject *obj, visitproc visit, void *arg)
175{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000176 ZipImporter *self = (ZipImporter *)obj;
177 Py_VISIT(self->files);
178 return 0;
Just van Rossum52e14d62002-12-30 22:08:05 +0000179}
180
181static void
182zipimporter_dealloc(ZipImporter *self)
183{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000184 PyObject_GC_UnTrack(self);
185 Py_XDECREF(self->archive);
186 Py_XDECREF(self->prefix);
187 Py_XDECREF(self->files);
188 Py_TYPE(self)->tp_free((PyObject *)self);
Just van Rossum52e14d62002-12-30 22:08:05 +0000189}
190
191static PyObject *
192zipimporter_repr(ZipImporter *self)
193{
Victor Stinner028dd972010-08-17 00:04:48 +0000194 if (self->archive == NULL)
195 return PyUnicode_FromString("<zipimporter object \"???\">");
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200196 else if (self->prefix != NULL && PyUnicode_GET_LENGTH(self->prefix) != 0)
Victor Stinner07298a12010-10-18 22:45:54 +0000197 return PyUnicode_FromFormat("<zipimporter object \"%U%c%U\">",
Victor Stinner028dd972010-08-17 00:04:48 +0000198 self->archive, SEP, self->prefix);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000199 else
Victor Stinner07298a12010-10-18 22:45:54 +0000200 return PyUnicode_FromFormat("<zipimporter object \"%U\">",
Victor Stinner028dd972010-08-17 00:04:48 +0000201 self->archive);
Just van Rossum52e14d62002-12-30 22:08:05 +0000202}
203
204/* return fullname.split(".")[-1] */
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400205static PyObject *
206get_subname(PyObject *fullname)
Just van Rossum52e14d62002-12-30 22:08:05 +0000207{
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100208 Py_ssize_t len, dot;
209 if (PyUnicode_READY(fullname) < 0)
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200210 return NULL;
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100211 len = PyUnicode_GET_LENGTH(fullname);
212 dot = PyUnicode_FindChar(fullname, '.', 0, len, -1);
213 if (dot == -1) {
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400214 Py_INCREF(fullname);
215 return fullname;
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100216 } else
217 return PyUnicode_Substring(fullname, dot+1, len);
Just van Rossum52e14d62002-12-30 22:08:05 +0000218}
219
220/* Given a (sub)modulename, write the potential file path in the
221 archive (without extension) to the path buffer. Return the
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400222 length of the resulting string.
223
224 return self.prefix + name.replace('.', os.sep) */
225static PyObject*
226make_filename(PyObject *prefix, PyObject *name)
Just van Rossum52e14d62002-12-30 22:08:05 +0000227{
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400228 PyObject *pathobj;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200229 Py_UCS4 *p, *buf;
230 Py_ssize_t len;
Just van Rossum52e14d62002-12-30 22:08:05 +0000231
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200232 len = PyUnicode_GET_LENGTH(prefix) + PyUnicode_GET_LENGTH(name) + 1;
233 p = buf = PyMem_Malloc(sizeof(Py_UCS4) * len);
234 if (buf == NULL) {
235 PyErr_NoMemory();
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400236 return NULL;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200237 }
Just van Rossum52e14d62002-12-30 22:08:05 +0000238
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200239 if (!PyUnicode_AsUCS4(prefix, p, len, 0))
240 return NULL;
241 p += PyUnicode_GET_LENGTH(prefix);
242 len -= PyUnicode_GET_LENGTH(prefix);
243 if (!PyUnicode_AsUCS4(name, p, len, 1))
244 return NULL;
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400245 for (; *p; p++) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000246 if (*p == '.')
247 *p = SEP;
248 }
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200249 pathobj = PyUnicode_FromKindAndData(PyUnicode_4BYTE_KIND,
250 buf, p-buf);
251 PyMem_Free(buf);
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400252 return pathobj;
Just van Rossum52e14d62002-12-30 22:08:05 +0000253}
254
Raymond Hettinger2c45c9a2004-11-10 13:08:35 +0000255enum zi_module_info {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000256 MI_ERROR,
257 MI_NOT_FOUND,
258 MI_MODULE,
259 MI_PACKAGE
Just van Rossum52e14d62002-12-30 22:08:05 +0000260};
261
262/* Return some information about a module. */
Raymond Hettinger2c45c9a2004-11-10 13:08:35 +0000263static enum zi_module_info
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400264get_module_info(ZipImporter *self, PyObject *fullname)
Just van Rossum52e14d62002-12-30 22:08:05 +0000265{
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400266 PyObject *subname;
267 PyObject *path, *fullpath, *item;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000268 struct st_zip_searchorder *zso;
Just van Rossum52e14d62002-12-30 22:08:05 +0000269
Victor Stinner965a8a12010-10-18 21:44:33 +0000270 subname = get_subname(fullname);
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400271 if (subname == NULL)
272 return MI_ERROR;
Just van Rossum52e14d62002-12-30 22:08:05 +0000273
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400274 path = make_filename(self->prefix, subname);
275 Py_DECREF(subname);
276 if (path == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000277 return MI_ERROR;
Just van Rossum52e14d62002-12-30 22:08:05 +0000278
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000279 for (zso = zip_searchorder; *zso->suffix; zso++) {
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400280 fullpath = PyUnicode_FromFormat("%U%s", path, zso->suffix);
281 if (fullpath == NULL) {
282 Py_DECREF(path);
283 return MI_ERROR;
284 }
285 item = PyDict_GetItem(self->files, fullpath);
286 Py_DECREF(fullpath);
287 if (item != NULL) {
288 Py_DECREF(path);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000289 if (zso->type & IS_PACKAGE)
290 return MI_PACKAGE;
291 else
292 return MI_MODULE;
293 }
294 }
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400295 Py_DECREF(path);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000296 return MI_NOT_FOUND;
Just van Rossum52e14d62002-12-30 22:08:05 +0000297}
298
299/* Check whether we can satisfy the import of the module named by
300 'fullname'. Return self if we can, None if we can't. */
301static PyObject *
302zipimporter_find_module(PyObject *obj, PyObject *args)
303{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000304 ZipImporter *self = (ZipImporter *)obj;
305 PyObject *path = NULL;
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400306 PyObject *fullname;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000307 enum zi_module_info mi;
Just van Rossum52e14d62002-12-30 22:08:05 +0000308
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400309 if (!PyArg_ParseTuple(args, "U|O:zipimporter.find_module",
Victor Stinner965a8a12010-10-18 21:44:33 +0000310 &fullname, &path))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000311 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +0000312
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000313 mi = get_module_info(self, fullname);
314 if (mi == MI_ERROR)
315 return NULL;
316 if (mi == MI_NOT_FOUND) {
317 Py_INCREF(Py_None);
318 return Py_None;
319 }
320 Py_INCREF(self);
321 return (PyObject *)self;
Just van Rossum52e14d62002-12-30 22:08:05 +0000322}
323
324/* Load and return the module named by 'fullname'. */
325static PyObject *
326zipimporter_load_module(PyObject *obj, PyObject *args)
327{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000328 ZipImporter *self = (ZipImporter *)obj;
Victor Stinner26fabe12010-10-18 12:03:25 +0000329 PyObject *code = NULL, *mod, *dict;
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400330 PyObject *fullname;
331 PyObject *modpath = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000332 int ispackage;
Just van Rossum52e14d62002-12-30 22:08:05 +0000333
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400334 if (!PyArg_ParseTuple(args, "U:zipimporter.load_module",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000335 &fullname))
336 return NULL;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200337 if (PyUnicode_READY(fullname) == -1)
338 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +0000339
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000340 code = get_module_code(self, fullname, &ispackage, &modpath);
341 if (code == NULL)
Victor Stinner26fabe12010-10-18 12:03:25 +0000342 goto error;
Just van Rossum52e14d62002-12-30 22:08:05 +0000343
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400344 mod = PyImport_AddModuleObject(fullname);
Victor Stinner26fabe12010-10-18 12:03:25 +0000345 if (mod == NULL)
346 goto error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000347 dict = PyModule_GetDict(mod);
Just van Rossum52e14d62002-12-30 22:08:05 +0000348
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000349 /* mod.__loader__ = self */
350 if (PyDict_SetItemString(dict, "__loader__", (PyObject *)self) != 0)
351 goto error;
Just van Rossum52e14d62002-12-30 22:08:05 +0000352
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000353 if (ispackage) {
354 /* add __path__ to the module *before* the code gets
355 executed */
356 PyObject *pkgpath, *fullpath;
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400357 PyObject *subname = get_subname(fullname);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000358 int err;
Just van Rossum52e14d62002-12-30 22:08:05 +0000359
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400360 fullpath = PyUnicode_FromFormat("%U%c%U%U",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000361 self->archive, SEP,
362 self->prefix, subname);
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400363 Py_DECREF(subname);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000364 if (fullpath == NULL)
365 goto error;
Just van Rossum52e14d62002-12-30 22:08:05 +0000366
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400367 pkgpath = Py_BuildValue("[N]", fullpath);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000368 if (pkgpath == NULL)
369 goto error;
370 err = PyDict_SetItemString(dict, "__path__", pkgpath);
371 Py_DECREF(pkgpath);
372 if (err != 0)
373 goto error;
374 }
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400375 mod = PyImport_ExecCodeModuleObject(fullname, code, modpath, NULL);
Victor Stinner26fabe12010-10-18 12:03:25 +0000376 Py_CLEAR(code);
377 if (mod == NULL)
378 goto error;
379
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000380 if (Py_VerboseFlag)
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400381 PySys_FormatStderr("import %U # loaded from Zip %U\n",
Victor Stinner08654e12010-10-18 12:09:02 +0000382 fullname, modpath);
383 Py_DECREF(modpath);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000384 return mod;
Just van Rossum52e14d62002-12-30 22:08:05 +0000385error:
Victor Stinner26fabe12010-10-18 12:03:25 +0000386 Py_XDECREF(code);
Victor Stinner08654e12010-10-18 12:09:02 +0000387 Py_XDECREF(modpath);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000388 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +0000389}
390
Nick Coghlanf088e5e2008-12-14 11:50:48 +0000391/* Return a string matching __file__ for the named module */
392static PyObject *
393zipimporter_get_filename(PyObject *obj, PyObject *args)
394{
395 ZipImporter *self = (ZipImporter *)obj;
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400396 PyObject *fullname, *code, *modpath;
Nick Coghlanf088e5e2008-12-14 11:50:48 +0000397 int ispackage;
398
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400399 if (!PyArg_ParseTuple(args, "U:zipimporter.get_filename",
Victor Stinner9e40fad2010-10-18 22:34:46 +0000400 &fullname))
Victor Stinnerc342fca2010-10-18 11:39:05 +0000401 return NULL;
Nick Coghlanf088e5e2008-12-14 11:50:48 +0000402
403 /* Deciding the filename requires working out where the code
404 would come from if the module was actually loaded */
405 code = get_module_code(self, fullname, &ispackage, &modpath);
406 if (code == NULL)
Victor Stinnerc342fca2010-10-18 11:39:05 +0000407 return NULL;
Nick Coghlanf088e5e2008-12-14 11:50:48 +0000408 Py_DECREF(code); /* Only need the path info */
409
Victor Stinner08654e12010-10-18 12:09:02 +0000410 return modpath;
Nick Coghlanf088e5e2008-12-14 11:50:48 +0000411}
412
Just van Rossum52e14d62002-12-30 22:08:05 +0000413/* Return a bool signifying whether the module is a package or not. */
414static PyObject *
415zipimporter_is_package(PyObject *obj, PyObject *args)
416{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000417 ZipImporter *self = (ZipImporter *)obj;
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400418 PyObject *fullname;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000419 enum zi_module_info mi;
Just van Rossum52e14d62002-12-30 22:08:05 +0000420
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400421 if (!PyArg_ParseTuple(args, "U:zipimporter.is_package",
Victor Stinner965a8a12010-10-18 21:44:33 +0000422 &fullname))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000423 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +0000424
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000425 mi = get_module_info(self, fullname);
426 if (mi == MI_ERROR)
Victor Stinner965a8a12010-10-18 21:44:33 +0000427 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000428 if (mi == MI_NOT_FOUND) {
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400429 PyErr_Format(ZipImportError, "can't find module %R", fullname);
Victor Stinner965a8a12010-10-18 21:44:33 +0000430 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000431 }
432 return PyBool_FromLong(mi == MI_PACKAGE);
Just van Rossum52e14d62002-12-30 22:08:05 +0000433}
434
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200435
Just van Rossum52e14d62002-12-30 22:08:05 +0000436static PyObject *
437zipimporter_get_data(PyObject *obj, PyObject *args)
438{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000439 ZipImporter *self = (ZipImporter *)obj;
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100440 PyObject *path, *key;
Just van Rossum52e14d62002-12-30 22:08:05 +0000441#ifdef ALTSEP
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100442 _Py_IDENTIFIER(replace);
Just van Rossum52e14d62002-12-30 22:08:05 +0000443#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000444 PyObject *toc_entry;
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100445 Py_ssize_t path_start, path_len, len;
Just van Rossum52e14d62002-12-30 22:08:05 +0000446
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100447 if (!PyArg_ParseTuple(args, "U:zipimporter.get_data", &path))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000448 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +0000449
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200450#ifdef ALTSEP
Martin v. Löwiscfa61292011-10-31 09:01:22 +0100451 path = _PyObject_CallMethodId(path, &PyId_replace, "CC", ALTSEP, SEP);
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100452 if (!path)
453 return NULL;
454#else
455 Py_INCREF(path);
Just van Rossum52e14d62002-12-30 22:08:05 +0000456#endif
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100457 if (PyUnicode_READY(path) == -1)
458 goto error;
459
460 path_len = PyUnicode_GET_LENGTH(path);
461
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200462 len = PyUnicode_GET_LENGTH(self->archive);
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100463 path_start = 0;
464 if (PyUnicode_Tailmatch(path, self->archive, 0, len, -1)
465 && PyUnicode_READ_CHAR(path, len) == SEP) {
466 path_start = len + 1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000467 }
Just van Rossum52e14d62002-12-30 22:08:05 +0000468
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100469 key = PyUnicode_Substring(path, path_start, path_len);
Victor Stinner60fe8d92010-08-16 23:48:11 +0000470 if (key == NULL)
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100471 goto error;
Victor Stinner60fe8d92010-08-16 23:48:11 +0000472 toc_entry = PyDict_GetItem(self->files, key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000473 if (toc_entry == NULL) {
Victor Stinner60fe8d92010-08-16 23:48:11 +0000474 PyErr_SetFromErrnoWithFilenameObject(PyExc_IOError, key);
475 Py_DECREF(key);
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100476 goto error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000477 }
Victor Stinner60fe8d92010-08-16 23:48:11 +0000478 Py_DECREF(key);
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100479 Py_DECREF(path);
Victor Stinner60fe8d92010-08-16 23:48:11 +0000480 return get_data(self->archive, toc_entry);
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100481 error:
482 Py_DECREF(path);
483 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +0000484}
485
486static PyObject *
487zipimporter_get_code(PyObject *obj, PyObject *args)
488{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000489 ZipImporter *self = (ZipImporter *)obj;
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400490 PyObject *fullname;
Just van Rossum52e14d62002-12-30 22:08:05 +0000491
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400492 if (!PyArg_ParseTuple(args, "U:zipimporter.get_code", &fullname))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000493 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +0000494
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000495 return get_module_code(self, fullname, NULL, NULL);
Just van Rossum52e14d62002-12-30 22:08:05 +0000496}
497
498static PyObject *
499zipimporter_get_source(PyObject *obj, PyObject *args)
500{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000501 ZipImporter *self = (ZipImporter *)obj;
502 PyObject *toc_entry;
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400503 PyObject *fullname, *subname, *path, *fullpath;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000504 enum zi_module_info mi;
Just van Rossum52e14d62002-12-30 22:08:05 +0000505
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400506 if (!PyArg_ParseTuple(args, "U:zipimporter.get_source", &fullname))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000507 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +0000508
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000509 mi = get_module_info(self, fullname);
Victor Stinner965a8a12010-10-18 21:44:33 +0000510 if (mi == MI_ERROR)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000511 return NULL;
Victor Stinner04106562010-10-18 20:44:08 +0000512 if (mi == MI_NOT_FOUND) {
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400513 PyErr_Format(ZipImportError, "can't find module %R", fullname);
Victor Stinner04106562010-10-18 20:44:08 +0000514 return NULL;
515 }
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400516
Victor Stinner965a8a12010-10-18 21:44:33 +0000517 subname = get_subname(fullname);
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400518 if (subname == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000519 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +0000520
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400521 path = make_filename(self->prefix, subname);
522 Py_DECREF(subname);
523 if (path == NULL)
524 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +0000525
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400526 if (mi == MI_PACKAGE)
527 fullpath = PyUnicode_FromFormat("%U%c__init__.py", path, SEP);
528 else
529 fullpath = PyUnicode_FromFormat("%U.py", path);
530 Py_DECREF(path);
531 if (fullpath == NULL)
532 return NULL;
533
534 toc_entry = PyDict_GetItem(self->files, fullpath);
535 Py_DECREF(fullpath);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000536 if (toc_entry != NULL) {
Victor Stinner60fe8d92010-08-16 23:48:11 +0000537 PyObject *res, *bytes;
538 bytes = get_data(self->archive, toc_entry);
539 if (bytes == NULL)
540 return NULL;
541 res = PyUnicode_FromStringAndSize(PyBytes_AS_STRING(bytes),
542 PyBytes_GET_SIZE(bytes));
543 Py_DECREF(bytes);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000544 return res;
545 }
Just van Rossum52e14d62002-12-30 22:08:05 +0000546
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000547 /* we have the module, but no source */
548 Py_INCREF(Py_None);
549 return Py_None;
Just van Rossum52e14d62002-12-30 22:08:05 +0000550}
551
552PyDoc_STRVAR(doc_find_module,
553"find_module(fullname, path=None) -> self or None.\n\
554\n\
555Search for a module specified by 'fullname'. 'fullname' must be the\n\
556fully qualified (dotted) module name. It returns the zipimporter\n\
557instance itself if the module was found, or None if it wasn't.\n\
558The optional 'path' argument is ignored -- it's there for compatibility\n\
559with the importer protocol.");
560
561PyDoc_STRVAR(doc_load_module,
562"load_module(fullname) -> module.\n\
563\n\
564Load the module specified by 'fullname'. 'fullname' must be the\n\
565fully qualified (dotted) module name. It returns the imported\n\
566module, or raises ZipImportError if it wasn't found.");
567
568PyDoc_STRVAR(doc_get_data,
569"get_data(pathname) -> string with file data.\n\
570\n\
571Return the data associated with 'pathname'. Raise IOError if\n\
572the file wasn't found.");
573
574PyDoc_STRVAR(doc_is_package,
575"is_package(fullname) -> bool.\n\
576\n\
577Return True if the module specified by fullname is a package.\n\
Brian Curtin32839732010-07-21 01:44:19 +0000578Raise ZipImportError if the module couldn't be found.");
Just van Rossum52e14d62002-12-30 22:08:05 +0000579
580PyDoc_STRVAR(doc_get_code,
581"get_code(fullname) -> code object.\n\
582\n\
583Return the code object for the specified module. Raise ZipImportError\n\
Brian Curtin32839732010-07-21 01:44:19 +0000584if the module couldn't be found.");
Just van Rossum52e14d62002-12-30 22:08:05 +0000585
586PyDoc_STRVAR(doc_get_source,
587"get_source(fullname) -> source string.\n\
588\n\
589Return the source code for the specified module. Raise ZipImportError\n\
Brian Curtin32839732010-07-21 01:44:19 +0000590if the module couldn't be found, return None if the archive does\n\
Just van Rossum52e14d62002-12-30 22:08:05 +0000591contain the module, but has no source for it.");
592
Nick Coghlanf088e5e2008-12-14 11:50:48 +0000593
594PyDoc_STRVAR(doc_get_filename,
Nick Coghlan9a1d6e32009-02-08 03:37:27 +0000595"get_filename(fullname) -> filename string.\n\
Nick Coghlanf088e5e2008-12-14 11:50:48 +0000596\n\
597Return the filename for the specified module.");
598
Just van Rossum52e14d62002-12-30 22:08:05 +0000599static PyMethodDef zipimporter_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000600 {"find_module", zipimporter_find_module, METH_VARARGS,
601 doc_find_module},
602 {"load_module", zipimporter_load_module, METH_VARARGS,
603 doc_load_module},
604 {"get_data", zipimporter_get_data, METH_VARARGS,
605 doc_get_data},
606 {"get_code", zipimporter_get_code, METH_VARARGS,
607 doc_get_code},
608 {"get_source", zipimporter_get_source, METH_VARARGS,
609 doc_get_source},
610 {"get_filename", zipimporter_get_filename, METH_VARARGS,
611 doc_get_filename},
612 {"is_package", zipimporter_is_package, METH_VARARGS,
613 doc_is_package},
614 {NULL, NULL} /* sentinel */
Just van Rossum52e14d62002-12-30 22:08:05 +0000615};
616
617static PyMemberDef zipimporter_members[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000618 {"archive", T_OBJECT, offsetof(ZipImporter, archive), READONLY},
619 {"prefix", T_OBJECT, offsetof(ZipImporter, prefix), READONLY},
620 {"_files", T_OBJECT, offsetof(ZipImporter, files), READONLY},
621 {NULL}
Just van Rossum52e14d62002-12-30 22:08:05 +0000622};
623
624PyDoc_STRVAR(zipimporter_doc,
625"zipimporter(archivepath) -> zipimporter object\n\
626\n\
627Create a new zipimporter instance. 'archivepath' must be a path to\n\
Alexandre Vassalotti8ae3e052008-05-16 00:41:41 +0000628a zipfile, or to a specific path inside a zipfile. For example, it can be\n\
629'/tmp/myimport.zip', or '/tmp/myimport.zip/mydirectory', if mydirectory is a\n\
630valid directory inside the archive.\n\
631\n\
632'ZipImportError is raised if 'archivepath' doesn't point to a valid Zip\n\
633archive.\n\
634\n\
635The 'archive' attribute of zipimporter objects contains the name of the\n\
636zipfile targeted.");
Just van Rossum52e14d62002-12-30 22:08:05 +0000637
638#define DEFERRED_ADDRESS(ADDR) 0
639
640static PyTypeObject ZipImporter_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000641 PyVarObject_HEAD_INIT(DEFERRED_ADDRESS(&PyType_Type), 0)
642 "zipimport.zipimporter",
643 sizeof(ZipImporter),
644 0, /* tp_itemsize */
645 (destructor)zipimporter_dealloc, /* tp_dealloc */
646 0, /* tp_print */
647 0, /* tp_getattr */
648 0, /* tp_setattr */
649 0, /* tp_reserved */
650 (reprfunc)zipimporter_repr, /* tp_repr */
651 0, /* tp_as_number */
652 0, /* tp_as_sequence */
653 0, /* tp_as_mapping */
654 0, /* tp_hash */
655 0, /* tp_call */
656 0, /* tp_str */
657 PyObject_GenericGetAttr, /* tp_getattro */
658 0, /* tp_setattro */
659 0, /* tp_as_buffer */
660 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE |
661 Py_TPFLAGS_HAVE_GC, /* tp_flags */
662 zipimporter_doc, /* tp_doc */
663 zipimporter_traverse, /* tp_traverse */
664 0, /* tp_clear */
665 0, /* tp_richcompare */
666 0, /* tp_weaklistoffset */
667 0, /* tp_iter */
668 0, /* tp_iternext */
669 zipimporter_methods, /* tp_methods */
670 zipimporter_members, /* tp_members */
671 0, /* tp_getset */
672 0, /* tp_base */
673 0, /* tp_dict */
674 0, /* tp_descr_get */
675 0, /* tp_descr_set */
676 0, /* tp_dictoffset */
677 (initproc)zipimporter_init, /* tp_init */
678 PyType_GenericAlloc, /* tp_alloc */
679 PyType_GenericNew, /* tp_new */
680 PyObject_GC_Del, /* tp_free */
Just van Rossum52e14d62002-12-30 22:08:05 +0000681};
682
683
684/* implementation */
685
Just van Rossum52e14d62002-12-30 22:08:05 +0000686/* Given a buffer, return the long that is represented by the first
687 4 bytes, encoded as little endian. This partially reimplements
688 marshal.c:r_long() */
689static long
690get_long(unsigned char *buf) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000691 long x;
692 x = buf[0];
693 x |= (long)buf[1] << 8;
694 x |= (long)buf[2] << 16;
695 x |= (long)buf[3] << 24;
Just van Rossum52e14d62002-12-30 22:08:05 +0000696#if SIZEOF_LONG > 4
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000697 /* Sign extension for 64-bit machines */
698 x |= -(x & 0x80000000L);
Just van Rossum52e14d62002-12-30 22:08:05 +0000699#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000700 return x;
Just van Rossum52e14d62002-12-30 22:08:05 +0000701}
702
703/*
704 read_directory(archive) -> files dict (new reference)
705
706 Given a path to a Zip archive, build a dict, mapping file names
707 (local to the archive, using SEP as a separator) to toc entries.
708
709 A toc_entry is a tuple:
710
Victor Stinner08654e12010-10-18 12:09:02 +0000711 (__file__, # value to use for __file__, available for all files,
712 # encoded to the filesystem encoding
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000713 compress, # compression kind; 0 for uncompressed
714 data_size, # size of compressed data on disk
715 file_size, # size of decompressed data
716 file_offset, # offset of file header from start of archive
717 time, # mod time of file (in dos format)
718 date, # mod data of file (in dos format)
719 crc, # crc checksum of the data
Victor Stinnerc342fca2010-10-18 11:39:05 +0000720 )
Just van Rossum52e14d62002-12-30 22:08:05 +0000721
722 Directories can be recognized by the trailing SEP in the name,
723 data_size and file_offset are 0.
724*/
725static PyObject *
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400726read_directory(PyObject *archive)
Just van Rossum52e14d62002-12-30 22:08:05 +0000727{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000728 PyObject *files = NULL;
729 FILE *fp;
Victor Stinnerd36c8212010-10-18 12:13:46 +0000730 unsigned short flags;
Gregory P. Smithab320662012-01-30 15:17:33 -0800731 short compress, time, date, name_size;
732 long crc, data_size, file_size, header_size;
733 Py_ssize_t file_offset, header_position, header_offset;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200734 long l, count;
735 Py_ssize_t i;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000736 char name[MAXPATHLEN + 5];
Victor Stinner2460a432010-08-16 17:54:28 +0000737 PyObject *nameobj = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000738 char *p, endof_central_dir[22];
Gregory P. Smithab320662012-01-30 15:17:33 -0800739 Py_ssize_t arc_offset; /* Absolute offset to start of the zip-archive. */
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100740 PyObject *path;
Victor Stinnerd36c8212010-10-18 12:13:46 +0000741 const char *charset;
Victor Stinner4ee65a92011-01-22 10:30:29 +0000742 int bootstrap;
Just van Rossum52e14d62002-12-30 22:08:05 +0000743
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400744 fp = _Py_fopen(archive, "rb");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000745 if (fp == NULL) {
Victor Stinnerbd206e22011-12-18 21:04:17 +0100746 if (!PyErr_Occurred())
Victor Stinner35734762011-12-18 21:05:22 +0100747 PyErr_Format(ZipImportError, "can't open Zip file: %R", archive);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000748 return NULL;
749 }
750 fseek(fp, -22, SEEK_END);
751 header_position = ftell(fp);
752 if (fread(endof_central_dir, 1, 22, fp) != 22) {
753 fclose(fp);
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400754 PyErr_Format(ZipImportError, "can't read Zip file: %R", archive);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000755 return NULL;
756 }
757 if (get_long((unsigned char *)endof_central_dir) != 0x06054B50) {
758 /* Bad: End of Central Dir signature */
759 fclose(fp);
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400760 PyErr_Format(ZipImportError, "not a Zip file: %R", archive);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000761 return NULL;
762 }
Just van Rossum52e14d62002-12-30 22:08:05 +0000763
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000764 header_size = get_long((unsigned char *)endof_central_dir + 12);
765 header_offset = get_long((unsigned char *)endof_central_dir + 16);
766 arc_offset = header_position - header_offset - header_size;
767 header_offset += arc_offset;
Just van Rossum52e14d62002-12-30 22:08:05 +0000768
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000769 files = PyDict_New();
770 if (files == NULL)
771 goto error;
Just van Rossum52e14d62002-12-30 22:08:05 +0000772
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000773 /* Start of Central Directory */
774 count = 0;
775 for (;;) {
776 PyObject *t;
777 int err;
Just van Rossum52e14d62002-12-30 22:08:05 +0000778
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000779 fseek(fp, header_offset, 0); /* Start of file header */
780 l = PyMarshal_ReadLongFromFile(fp);
781 if (l != 0x02014B50)
782 break; /* Bad: Central Dir File Header */
Victor Stinnerd36c8212010-10-18 12:13:46 +0000783 fseek(fp, header_offset + 8, 0);
784 flags = (unsigned short)PyMarshal_ReadShortFromFile(fp);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000785 compress = PyMarshal_ReadShortFromFile(fp);
786 time = PyMarshal_ReadShortFromFile(fp);
787 date = PyMarshal_ReadShortFromFile(fp);
788 crc = PyMarshal_ReadLongFromFile(fp);
789 data_size = PyMarshal_ReadLongFromFile(fp);
790 file_size = PyMarshal_ReadLongFromFile(fp);
791 name_size = PyMarshal_ReadShortFromFile(fp);
792 header_size = 46 + name_size +
793 PyMarshal_ReadShortFromFile(fp) +
794 PyMarshal_ReadShortFromFile(fp);
795 fseek(fp, header_offset + 42, 0);
796 file_offset = PyMarshal_ReadLongFromFile(fp) + arc_offset;
797 if (name_size > MAXPATHLEN)
798 name_size = MAXPATHLEN;
Just van Rossum52e14d62002-12-30 22:08:05 +0000799
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000800 p = name;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200801 for (i = 0; i < (Py_ssize_t)name_size; i++) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000802 *p = (char)getc(fp);
803 if (*p == '/')
804 *p = SEP;
805 p++;
806 }
807 *p = 0; /* Add terminating null byte */
808 header_offset += header_size;
Just van Rossum52e14d62002-12-30 22:08:05 +0000809
Victor Stinner4ee65a92011-01-22 10:30:29 +0000810 bootstrap = 0;
Victor Stinnerd36c8212010-10-18 12:13:46 +0000811 if (flags & 0x0800)
812 charset = "utf-8";
Victor Stinner4ee65a92011-01-22 10:30:29 +0000813 else if (!PyThreadState_GET()->interp->codecs_initialized) {
814 /* During bootstrap, we may need to load the encodings
815 package from a ZIP file. But the cp437 encoding is implemented
816 in Python in the encodings package.
817
818 Break out of this dependency by assuming that the path to
819 the encodings module is ASCII-only. */
820 charset = "ascii";
821 bootstrap = 1;
822 }
Victor Stinnerd36c8212010-10-18 12:13:46 +0000823 else
824 charset = "cp437";
825 nameobj = PyUnicode_Decode(name, name_size, charset, NULL);
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200826 if (PyUnicode_READY(nameobj) == -1)
827 goto error;
Victor Stinner4ee65a92011-01-22 10:30:29 +0000828 if (nameobj == NULL) {
829 if (bootstrap)
830 PyErr_Format(PyExc_NotImplementedError,
831 "bootstrap issue: python%i%i.zip contains non-ASCII "
832 "filenames without the unicode flag",
833 PY_MAJOR_VERSION, PY_MINOR_VERSION);
Victor Stinner2460a432010-08-16 17:54:28 +0000834 goto error;
Victor Stinner4ee65a92011-01-22 10:30:29 +0000835 }
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100836 path = PyUnicode_FromFormat("%U%c%U", archive, SEP, nameobj);
837 if (path == NULL)
Victor Stinner2460a432010-08-16 17:54:28 +0000838 goto error;
Gregory P. Smithcc6abd52012-01-30 15:55:29 -0800839 t = Py_BuildValue("Nhllnhhl", path, compress, data_size,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000840 file_size, file_offset, time, date, crc);
841 if (t == NULL)
842 goto error;
Victor Stinner2460a432010-08-16 17:54:28 +0000843 err = PyDict_SetItem(files, nameobj, t);
844 Py_CLEAR(nameobj);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000845 Py_DECREF(t);
846 if (err != 0)
847 goto error;
848 count++;
849 }
850 fclose(fp);
851 if (Py_VerboseFlag)
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400852 PySys_FormatStderr("# zipimport: found %ld names in %R\n",
853 count, archive);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000854 return files;
Just van Rossum52e14d62002-12-30 22:08:05 +0000855error:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000856 fclose(fp);
857 Py_XDECREF(files);
Victor Stinner2460a432010-08-16 17:54:28 +0000858 Py_XDECREF(nameobj);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000859 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +0000860}
861
862/* Return the zlib.decompress function object, or NULL if zlib couldn't
863 be imported. The function is cached when found, so subsequent calls
Victor Stinner4925cde2011-05-20 00:16:09 +0200864 don't import zlib again. */
Just van Rossum52e14d62002-12-30 22:08:05 +0000865static PyObject *
866get_decompress_func(void)
867{
Victor Stinner4925cde2011-05-20 00:16:09 +0200868 static int importing_zlib = 0;
869 PyObject *zlib;
870 PyObject *decompress;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +0200871 _Py_IDENTIFIER(decompress);
Just van Rossum52e14d62002-12-30 22:08:05 +0000872
Victor Stinner4925cde2011-05-20 00:16:09 +0200873 if (importing_zlib != 0)
874 /* Someone has a zlib.py[co] in their Zip file;
875 let's avoid a stack overflow. */
876 return NULL;
877 importing_zlib = 1;
878 zlib = PyImport_ImportModuleNoBlock("zlib");
879 importing_zlib = 0;
880 if (zlib != NULL) {
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +0200881 decompress = _PyObject_GetAttrId(zlib,
882 &PyId_decompress);
Victor Stinner4925cde2011-05-20 00:16:09 +0200883 Py_DECREF(zlib);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000884 }
Victor Stinner4925cde2011-05-20 00:16:09 +0200885 else {
886 PyErr_Clear();
887 decompress = NULL;
888 }
889 if (Py_VerboseFlag)
890 PySys_WriteStderr("# zipimport: zlib %s\n",
891 zlib != NULL ? "available": "UNAVAILABLE");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000892 return decompress;
Just van Rossum52e14d62002-12-30 22:08:05 +0000893}
894
895/* Given a path to a Zip file and a toc_entry, return the (uncompressed)
896 data as a new reference. */
897static PyObject *
Victor Stinner60fe8d92010-08-16 23:48:11 +0000898get_data(PyObject *archive, PyObject *toc_entry)
Just van Rossum52e14d62002-12-30 22:08:05 +0000899{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000900 PyObject *raw_data, *data = NULL, *decompress;
901 char *buf;
902 FILE *fp;
903 int err;
904 Py_ssize_t bytes_read = 0;
905 long l;
Victor Stinner60fe8d92010-08-16 23:48:11 +0000906 PyObject *datapath;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000907 long compress, data_size, file_size, file_offset, bytes_size;
908 long time, date, crc;
Just van Rossum52e14d62002-12-30 22:08:05 +0000909
Victor Stinner60fe8d92010-08-16 23:48:11 +0000910 if (!PyArg_ParseTuple(toc_entry, "Olllllll", &datapath, &compress,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000911 &data_size, &file_size, &file_offset, &time,
912 &date, &crc)) {
913 return NULL;
914 }
Just van Rossum52e14d62002-12-30 22:08:05 +0000915
Victor Stinner60fe8d92010-08-16 23:48:11 +0000916 fp = _Py_fopen(archive, "rb");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000917 if (!fp) {
Victor Stinnerbd206e22011-12-18 21:04:17 +0100918 if (!PyErr_Occurred())
919 PyErr_Format(PyExc_IOError,
920 "zipimport: can not open file %U", archive);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000921 return NULL;
922 }
Just van Rossum52e14d62002-12-30 22:08:05 +0000923
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000924 /* Check to make sure the local file header is correct */
925 fseek(fp, file_offset, 0);
926 l = PyMarshal_ReadLongFromFile(fp);
927 if (l != 0x04034B50) {
928 /* Bad: Local File Header */
929 PyErr_Format(ZipImportError,
Victor Stinner60fe8d92010-08-16 23:48:11 +0000930 "bad local file header in %U",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000931 archive);
932 fclose(fp);
933 return NULL;
934 }
935 fseek(fp, file_offset + 26, 0);
936 l = 30 + PyMarshal_ReadShortFromFile(fp) +
937 PyMarshal_ReadShortFromFile(fp); /* local header size */
938 file_offset += l; /* Start of file data */
Just van Rossum52e14d62002-12-30 22:08:05 +0000939
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000940 bytes_size = compress == 0 ? data_size : data_size + 1;
941 if (bytes_size == 0)
942 bytes_size++;
943 raw_data = PyBytes_FromStringAndSize((char *)NULL, bytes_size);
Just van Rossum52e14d62002-12-30 22:08:05 +0000944
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000945 if (raw_data == NULL) {
946 fclose(fp);
947 return NULL;
948 }
949 buf = PyBytes_AsString(raw_data);
Just van Rossum52e14d62002-12-30 22:08:05 +0000950
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000951 err = fseek(fp, file_offset, 0);
952 if (err == 0)
953 bytes_read = fread(buf, 1, data_size, fp);
954 fclose(fp);
955 if (err || bytes_read != data_size) {
956 PyErr_SetString(PyExc_IOError,
957 "zipimport: can't read data");
958 Py_DECREF(raw_data);
959 return NULL;
960 }
Just van Rossum52e14d62002-12-30 22:08:05 +0000961
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000962 if (compress != 0) {
963 buf[data_size] = 'Z'; /* saw this in zipfile.py */
964 data_size++;
965 }
966 buf[data_size] = '\0';
Just van Rossum52e14d62002-12-30 22:08:05 +0000967
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000968 if (compress == 0) { /* data is not compressed */
969 data = PyBytes_FromStringAndSize(buf, data_size);
970 Py_DECREF(raw_data);
971 return data;
972 }
973
974 /* Decompress with zlib */
975 decompress = get_decompress_func();
976 if (decompress == NULL) {
977 PyErr_SetString(ZipImportError,
978 "can't decompress data; "
979 "zlib not available");
980 goto error;
981 }
982 data = PyObject_CallFunction(decompress, "Oi", raw_data, -15);
Victor Stinner4925cde2011-05-20 00:16:09 +0200983 Py_DECREF(decompress);
Just van Rossum52e14d62002-12-30 22:08:05 +0000984error:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000985 Py_DECREF(raw_data);
986 return data;
Just van Rossum52e14d62002-12-30 22:08:05 +0000987}
988
989/* Lenient date/time comparison function. The precision of the mtime
990 in the archive is lower than the mtime stored in a .pyc: we
991 must allow a difference of at most one second. */
992static int
993eq_mtime(time_t t1, time_t t2)
994{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000995 time_t d = t1 - t2;
996 if (d < 0)
997 d = -d;
998 /* dostime only stores even seconds, so be lenient */
999 return d <= 1;
Just van Rossum52e14d62002-12-30 22:08:05 +00001000}
1001
1002/* Given the contents of a .py[co] file in a buffer, unmarshal the data
1003 and return the code object. Return None if it the magic word doesn't
1004 match (we do this instead of raising an exception as we fall back
1005 to .py if available and we don't want to mask other errors).
1006 Returns a new reference. */
1007static PyObject *
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001008unmarshal_code(PyObject *pathname, PyObject *data, time_t mtime)
Just van Rossum52e14d62002-12-30 22:08:05 +00001009{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001010 PyObject *code;
1011 char *buf = PyBytes_AsString(data);
1012 Py_ssize_t size = PyBytes_Size(data);
Just van Rossum52e14d62002-12-30 22:08:05 +00001013
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001014 if (size <= 9) {
1015 PyErr_SetString(ZipImportError,
1016 "bad pyc data");
1017 return NULL;
1018 }
Just van Rossum52e14d62002-12-30 22:08:05 +00001019
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001020 if (get_long((unsigned char *)buf) != PyImport_GetMagicNumber()) {
1021 if (Py_VerboseFlag)
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001022 PySys_FormatStderr("# %R has bad magic\n",
1023 pathname);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001024 Py_INCREF(Py_None);
1025 return Py_None; /* signal caller to try alternative */
1026 }
Just van Rossum52e14d62002-12-30 22:08:05 +00001027
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001028 if (mtime != 0 && !eq_mtime(get_long((unsigned char *)buf + 4),
1029 mtime)) {
1030 if (Py_VerboseFlag)
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001031 PySys_FormatStderr("# %R has bad mtime\n",
1032 pathname);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001033 Py_INCREF(Py_None);
1034 return Py_None; /* signal caller to try alternative */
1035 }
Just van Rossum52e14d62002-12-30 22:08:05 +00001036
Antoine Pitrou5136ac02012-01-13 18:52:16 +01001037 /* XXX the pyc's size field is ignored; timestamp collisions are probably
1038 unimportant with zip files. */
1039 code = PyMarshal_ReadObjectFromString(buf + 12, size - 12);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001040 if (code == NULL)
1041 return NULL;
1042 if (!PyCode_Check(code)) {
1043 Py_DECREF(code);
1044 PyErr_Format(PyExc_TypeError,
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001045 "compiled module %R is not a code object",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001046 pathname);
1047 return NULL;
1048 }
1049 return code;
Just van Rossum52e14d62002-12-30 22:08:05 +00001050}
1051
1052/* Replace any occurances of "\r\n?" in the input string with "\n".
1053 This converts DOS and Mac line endings to Unix line endings.
1054 Also append a trailing "\n" to be compatible with
1055 PyParser_SimpleParseFile(). Returns a new reference. */
1056static PyObject *
1057normalize_line_endings(PyObject *source)
1058{
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001059 char *buf, *q, *p;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001060 PyObject *fixed_source;
1061 int len = 0;
Just van Rossum52e14d62002-12-30 22:08:05 +00001062
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001063 p = PyBytes_AsString(source);
1064 if (p == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001065 return PyBytes_FromStringAndSize("\n\0", 2);
1066 }
Thomas Wouters00ee7ba2006-08-21 19:07:27 +00001067
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001068 /* one char extra for trailing \n and one for terminating \0 */
1069 buf = (char *)PyMem_Malloc(PyBytes_Size(source) + 2);
1070 if (buf == NULL) {
1071 PyErr_SetString(PyExc_MemoryError,
1072 "zipimport: no memory to allocate "
1073 "source buffer");
1074 return NULL;
1075 }
1076 /* replace "\r\n?" by "\n" */
1077 for (q = buf; *p != '\0'; p++) {
1078 if (*p == '\r') {
1079 *q++ = '\n';
1080 if (*(p + 1) == '\n')
1081 p++;
1082 }
1083 else
1084 *q++ = *p;
1085 len++;
1086 }
1087 *q++ = '\n'; /* add trailing \n */
1088 *q = '\0';
1089 fixed_source = PyBytes_FromStringAndSize(buf, len + 2);
1090 PyMem_Free(buf);
1091 return fixed_source;
Just van Rossum52e14d62002-12-30 22:08:05 +00001092}
1093
1094/* Given a string buffer containing Python source code, compile it
1095 return and return a code object as a new reference. */
1096static PyObject *
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001097compile_source(PyObject *pathname, PyObject *source)
Just van Rossum52e14d62002-12-30 22:08:05 +00001098{
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001099 PyObject *code, *fixed_source, *pathbytes;
Just van Rossum52e14d62002-12-30 22:08:05 +00001100
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001101 pathbytes = PyUnicode_EncodeFSDefault(pathname);
1102 if (pathbytes == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001103 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +00001104
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001105 fixed_source = normalize_line_endings(source);
1106 if (fixed_source == NULL) {
1107 Py_DECREF(pathbytes);
1108 return NULL;
1109 }
1110
1111 code = Py_CompileString(PyBytes_AsString(fixed_source),
1112 PyBytes_AsString(pathbytes),
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001113 Py_file_input);
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001114 Py_DECREF(pathbytes);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001115 Py_DECREF(fixed_source);
1116 return code;
Just van Rossum52e14d62002-12-30 22:08:05 +00001117}
1118
1119/* Convert the date/time values found in the Zip archive to a value
1120 that's compatible with the time stamp stored in .pyc files. */
Neal Norwitz29fd2ba2003-03-23 13:21:03 +00001121static time_t
1122parse_dostime(int dostime, int dosdate)
Just van Rossum52e14d62002-12-30 22:08:05 +00001123{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001124 struct tm stm;
Just van Rossum52e14d62002-12-30 22:08:05 +00001125
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001126 memset((void *) &stm, '\0', sizeof(stm));
Christian Heimes679db4a2008-01-18 09:56:22 +00001127
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001128 stm.tm_sec = (dostime & 0x1f) * 2;
1129 stm.tm_min = (dostime >> 5) & 0x3f;
1130 stm.tm_hour = (dostime >> 11) & 0x1f;
1131 stm.tm_mday = dosdate & 0x1f;
1132 stm.tm_mon = ((dosdate >> 5) & 0x0f) - 1;
1133 stm.tm_year = ((dosdate >> 9) & 0x7f) + 80;
1134 stm.tm_isdst = -1; /* wday/yday is ignored */
Just van Rossum52e14d62002-12-30 22:08:05 +00001135
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001136 return mktime(&stm);
Just van Rossum52e14d62002-12-30 22:08:05 +00001137}
1138
1139/* Given a path to a .pyc or .pyo file in the archive, return the
Ezio Melotti13925002011-03-16 11:05:33 +02001140 modification time of the matching .py file, or 0 if no source
Just van Rossum52e14d62002-12-30 22:08:05 +00001141 is available. */
1142static time_t
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001143get_mtime_of_source(ZipImporter *self, PyObject *path)
Just van Rossum52e14d62002-12-30 22:08:05 +00001144{
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001145 PyObject *toc_entry, *stripped;
1146 time_t mtime;
1147
1148 /* strip 'c' or 'o' from *.py[co] */
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001149 if (PyUnicode_READY(path) == -1)
1150 return (time_t)-1;
1151 stripped = PyUnicode_FromKindAndData(PyUnicode_KIND(path),
1152 PyUnicode_DATA(path),
1153 PyUnicode_GET_LENGTH(path) - 1);
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001154 if (stripped == NULL)
1155 return (time_t)-1;
1156
1157 toc_entry = PyDict_GetItem(self->files, stripped);
1158 Py_DECREF(stripped);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001159 if (toc_entry != NULL && PyTuple_Check(toc_entry) &&
1160 PyTuple_Size(toc_entry) == 8) {
1161 /* fetch the time stamp of the .py file for comparison
1162 with an embedded pyc time stamp */
1163 int time, date;
1164 time = PyLong_AsLong(PyTuple_GetItem(toc_entry, 5));
1165 date = PyLong_AsLong(PyTuple_GetItem(toc_entry, 6));
1166 mtime = parse_dostime(time, date);
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001167 } else
1168 mtime = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001169 return mtime;
Just van Rossum52e14d62002-12-30 22:08:05 +00001170}
1171
1172/* Return the code object for the module named by 'fullname' from the
1173 Zip archive as a new reference. */
1174static PyObject *
1175get_code_from_data(ZipImporter *self, int ispackage, int isbytecode,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001176 time_t mtime, PyObject *toc_entry)
Just van Rossum52e14d62002-12-30 22:08:05 +00001177{
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001178 PyObject *data, *modpath, *code;
Just van Rossum52e14d62002-12-30 22:08:05 +00001179
Victor Stinner60fe8d92010-08-16 23:48:11 +00001180 data = get_data(self->archive, toc_entry);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001181 if (data == NULL)
1182 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +00001183
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001184 modpath = PyTuple_GetItem(toc_entry, 0);
Victor Stinner2a94f4c2010-10-18 12:15:34 +00001185 if (isbytecode)
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001186 code = unmarshal_code(modpath, data, mtime);
Victor Stinner2a94f4c2010-10-18 12:15:34 +00001187 else
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001188 code = compile_source(modpath, data);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001189 Py_DECREF(data);
1190 return code;
Just van Rossum52e14d62002-12-30 22:08:05 +00001191}
1192
Ezio Melotti42da6632011-03-15 05:18:48 +02001193/* Get the code object associated with the module specified by
Just van Rossum52e14d62002-12-30 22:08:05 +00001194 'fullname'. */
1195static PyObject *
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001196get_module_code(ZipImporter *self, PyObject *fullname,
Victor Stinner08654e12010-10-18 12:09:02 +00001197 int *p_ispackage, PyObject **p_modpath)
Just van Rossum52e14d62002-12-30 22:08:05 +00001198{
Gregory P. Smith95c7c462011-05-21 05:19:42 -07001199 PyObject *code = NULL, *toc_entry, *subname;
Victor Stinner9a2261a2011-05-26 13:59:41 +02001200 PyObject *path, *fullpath = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001201 struct st_zip_searchorder *zso;
Just van Rossum52e14d62002-12-30 22:08:05 +00001202
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001203 subname = get_subname(fullname);
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001204 if (subname == NULL)
1205 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +00001206
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001207 path = make_filename(self->prefix, subname);
1208 Py_DECREF(subname);
1209 if (path == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001210 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +00001211
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001212 for (zso = zip_searchorder; *zso->suffix; zso++) {
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001213 code = NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +00001214
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001215 fullpath = PyUnicode_FromFormat("%U%s", path, zso->suffix);
1216 if (fullpath == NULL)
1217 goto exit;
1218
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001219 if (Py_VerboseFlag > 1)
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001220 PySys_FormatStderr("# trying %U%c%U\n",
1221 self->archive, (int)SEP, fullpath);
1222 toc_entry = PyDict_GetItem(self->files, fullpath);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001223 if (toc_entry != NULL) {
1224 time_t mtime = 0;
1225 int ispackage = zso->type & IS_PACKAGE;
1226 int isbytecode = zso->type & IS_BYTECODE;
Just van Rossum52e14d62002-12-30 22:08:05 +00001227
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001228 if (isbytecode) {
1229 mtime = get_mtime_of_source(self, fullpath);
1230 if (mtime == (time_t)-1 && PyErr_Occurred()) {
1231 goto exit;
1232 }
1233 }
1234 Py_CLEAR(fullpath);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001235 if (p_ispackage != NULL)
1236 *p_ispackage = ispackage;
1237 code = get_code_from_data(self, ispackage,
1238 isbytecode, mtime,
1239 toc_entry);
1240 if (code == Py_None) {
1241 /* bad magic number or non-matching mtime
1242 in byte code, try next */
1243 Py_DECREF(code);
1244 continue;
1245 }
Victor Stinner08654e12010-10-18 12:09:02 +00001246 if (code != NULL && p_modpath != NULL) {
1247 *p_modpath = PyTuple_GetItem(toc_entry, 0);
1248 Py_INCREF(*p_modpath);
1249 }
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001250 goto exit;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001251 }
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001252 else
1253 Py_CLEAR(fullpath);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001254 }
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001255 PyErr_Format(ZipImportError, "can't find module %R", fullname);
1256exit:
1257 Py_DECREF(path);
1258 Py_XDECREF(fullpath);
1259 return code;
Just van Rossum52e14d62002-12-30 22:08:05 +00001260}
1261
1262
1263/* Module init */
1264
1265PyDoc_STRVAR(zipimport_doc,
1266"zipimport provides support for importing Python modules from Zip archives.\n\
1267\n\
1268This module exports three objects:\n\
1269- zipimporter: a class; its constructor takes a path to a Zip archive.\n\
Fredrik Lundhb84b35f2006-01-15 15:00:40 +00001270- ZipImportError: exception raised by zipimporter objects. It's a\n\
Just van Rossum52e14d62002-12-30 22:08:05 +00001271 subclass of ImportError, so it can be caught as ImportError, too.\n\
1272- _zip_directory_cache: a dict, mapping archive paths to zip directory\n\
1273 info dicts, as used in zipimporter._files.\n\
1274\n\
1275It is usually not needed to use the zipimport module explicitly; it is\n\
1276used by the builtin import mechanism for sys.path items that are paths\n\
1277to Zip archives.");
1278
Martin v. Löwis1a214512008-06-11 05:26:20 +00001279static struct PyModuleDef zipimportmodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001280 PyModuleDef_HEAD_INIT,
1281 "zipimport",
1282 zipimport_doc,
1283 -1,
1284 NULL,
1285 NULL,
1286 NULL,
1287 NULL,
1288 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +00001289};
1290
Just van Rossum52e14d62002-12-30 22:08:05 +00001291PyMODINIT_FUNC
Martin v. Löwis1a214512008-06-11 05:26:20 +00001292PyInit_zipimport(void)
Just van Rossum52e14d62002-12-30 22:08:05 +00001293{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001294 PyObject *mod;
Just van Rossum52e14d62002-12-30 22:08:05 +00001295
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001296 if (PyType_Ready(&ZipImporter_Type) < 0)
1297 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +00001298
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001299 /* Correct directory separator */
1300 zip_searchorder[0].suffix[0] = SEP;
1301 zip_searchorder[1].suffix[0] = SEP;
1302 zip_searchorder[2].suffix[0] = SEP;
1303 if (Py_OptimizeFlag) {
1304 /* Reverse *.pyc and *.pyo */
1305 struct st_zip_searchorder tmp;
1306 tmp = zip_searchorder[0];
1307 zip_searchorder[0] = zip_searchorder[1];
1308 zip_searchorder[1] = tmp;
1309 tmp = zip_searchorder[3];
1310 zip_searchorder[3] = zip_searchorder[4];
1311 zip_searchorder[4] = tmp;
1312 }
Just van Rossum52e14d62002-12-30 22:08:05 +00001313
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001314 mod = PyModule_Create(&zipimportmodule);
1315 if (mod == NULL)
1316 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +00001317
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001318 ZipImportError = PyErr_NewException("zipimport.ZipImportError",
1319 PyExc_ImportError, NULL);
1320 if (ZipImportError == NULL)
1321 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +00001322
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001323 Py_INCREF(ZipImportError);
1324 if (PyModule_AddObject(mod, "ZipImportError",
1325 ZipImportError) < 0)
1326 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +00001327
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001328 Py_INCREF(&ZipImporter_Type);
1329 if (PyModule_AddObject(mod, "zipimporter",
1330 (PyObject *)&ZipImporter_Type) < 0)
1331 return NULL;
Just van Rossumf8b6de12002-12-31 09:51:59 +00001332
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001333 zip_directory_cache = PyDict_New();
1334 if (zip_directory_cache == NULL)
1335 return NULL;
1336 Py_INCREF(zip_directory_cache);
1337 if (PyModule_AddObject(mod, "_zip_directory_cache",
1338 zip_directory_cache) < 0)
1339 return NULL;
1340 return mod;
Just van Rossum52e14d62002-12-30 22:08:05 +00001341}