blob: 4bb2863fae6a41c7eff170888f8c6c5c9014528a [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
Eric V. Smith984b11f2012-05-24 20:21:04 -0400262/* Does this path represent a directory?
263 on error, return < 0
264 if not a dir, return 0
265 if a dir, return 1
266*/
267static int
268check_is_directory(ZipImporter *self, PyObject* prefix, PyObject *path)
269{
270 PyObject *dirpath;
271 PyObject *item;
272
273 /* See if this is a "directory". If so, it's eligible to be part
274 of a namespace package. We test by seeing if the name, with an
275 appended path separator, exists. */
276 dirpath = PyUnicode_FromFormat("%U%U%c", prefix, path, SEP);
277 if (dirpath == NULL)
278 return -1;
279 /* If dirpath is present in self->files, we have a directory. */
280 item = PyDict_GetItem(self->files, dirpath);
281 Py_DECREF(dirpath);
282 return item != NULL;
283}
284
Just van Rossum52e14d62002-12-30 22:08:05 +0000285/* Return some information about a module. */
Raymond Hettinger2c45c9a2004-11-10 13:08:35 +0000286static enum zi_module_info
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400287get_module_info(ZipImporter *self, PyObject *fullname)
Just van Rossum52e14d62002-12-30 22:08:05 +0000288{
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400289 PyObject *subname;
290 PyObject *path, *fullpath, *item;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000291 struct st_zip_searchorder *zso;
Just van Rossum52e14d62002-12-30 22:08:05 +0000292
Victor Stinner965a8a12010-10-18 21:44:33 +0000293 subname = get_subname(fullname);
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400294 if (subname == NULL)
295 return MI_ERROR;
Just van Rossum52e14d62002-12-30 22:08:05 +0000296
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400297 path = make_filename(self->prefix, subname);
298 Py_DECREF(subname);
299 if (path == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000300 return MI_ERROR;
Just van Rossum52e14d62002-12-30 22:08:05 +0000301
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000302 for (zso = zip_searchorder; *zso->suffix; zso++) {
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400303 fullpath = PyUnicode_FromFormat("%U%s", path, zso->suffix);
304 if (fullpath == NULL) {
305 Py_DECREF(path);
306 return MI_ERROR;
307 }
308 item = PyDict_GetItem(self->files, fullpath);
309 Py_DECREF(fullpath);
310 if (item != NULL) {
311 Py_DECREF(path);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000312 if (zso->type & IS_PACKAGE)
313 return MI_PACKAGE;
314 else
315 return MI_MODULE;
316 }
317 }
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400318 Py_DECREF(path);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000319 return MI_NOT_FOUND;
Just van Rossum52e14d62002-12-30 22:08:05 +0000320}
321
Eric V. Smith984b11f2012-05-24 20:21:04 -0400322/* The guts of "find_loader" and "find_module". Return values:
323 -1: error
324 0: no loader or namespace portions found
325 1: module/package found
326 2: namespace portion found: *namespace_portion will point to the name
327*/
328static int
329find_loader(ZipImporter *self, PyObject *fullname, PyObject **namespace_portion)
330{
331 enum zi_module_info mi;
332
333 *namespace_portion = NULL;
334
335 mi = get_module_info(self, fullname);
336 if (mi == MI_ERROR)
337 return -1;
338 if (mi == MI_NOT_FOUND) {
339 /* Not a module or regular package. See if this is a directory, and
340 therefore possibly a portion of a namespace package. */
341 int is_dir = check_is_directory(self, self->prefix, fullname);
342 if (is_dir < 0)
343 return -1;
344 if (is_dir) {
345 /* This is possibly a portion of a namespace
346 package. Return the string representing its path,
347 without a trailing separator. */
348 *namespace_portion = PyUnicode_FromFormat("%U%c%U%U",
349 self->archive, SEP,
350 self->prefix, fullname);
351 if (*namespace_portion == NULL)
352 return -1;
353 return 2;
354 }
355 return 0;
356 }
357 /* This is a module or package. */
358 return 1;
359}
360
361
Just van Rossum52e14d62002-12-30 22:08:05 +0000362/* Check whether we can satisfy the import of the module named by
363 'fullname'. Return self if we can, None if we can't. */
364static PyObject *
365zipimporter_find_module(PyObject *obj, PyObject *args)
366{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000367 ZipImporter *self = (ZipImporter *)obj;
368 PyObject *path = NULL;
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400369 PyObject *fullname;
Eric V. Smith984b11f2012-05-24 20:21:04 -0400370 PyObject* namespace_portion = NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +0000371
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400372 if (!PyArg_ParseTuple(args, "U|O:zipimporter.find_module",
Victor Stinner965a8a12010-10-18 21:44:33 +0000373 &fullname, &path))
Eric V. Smith984b11f2012-05-24 20:21:04 -0400374 goto error;
Just van Rossum52e14d62002-12-30 22:08:05 +0000375
Eric V. Smith984b11f2012-05-24 20:21:04 -0400376 switch (find_loader(self, fullname, &namespace_portion)) {
377 case -1: /* Error */
378 goto error;
379 case 0: /* Not found, return None */
380 Py_INCREF(Py_None);
381 return Py_None;
382 case 1: /* Return self */
383 Py_INCREF(self);
384 return (PyObject *)self;
385 case 2: /* A namespace portion, but not allowed via
386 find_module, so return None */
387 Py_DECREF(namespace_portion);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000388 Py_INCREF(Py_None);
389 return Py_None;
390 }
Eric V. Smith984b11f2012-05-24 20:21:04 -0400391 /* Can't get here. */
392 assert(0);
393 return NULL;
394error:
395 Py_XDECREF(namespace_portion);
396 return NULL;
397}
398
399
400/* Check whether we can satisfy the import of the module named by
401 'fullname', or whether it could be a portion of a namespace
402 package. Return self if we can load it, a string containing the
403 full path if it's a possible namespace portion, None if we
404 can't load it. */
405static PyObject *
406zipimporter_find_loader(PyObject *obj, PyObject *args)
407{
408 ZipImporter *self = (ZipImporter *)obj;
409 PyObject *path = NULL;
410 PyObject *fullname;
411 PyObject *result = NULL;
412 PyObject *namespace_portion = NULL;
413
414 if (!PyArg_ParseTuple(args, "U|O:zipimporter.find_module",
415 &fullname, &path))
416 goto error;
417
418 switch (find_loader(self, fullname, &namespace_portion)) {
419 case -1: /* Error */
420 goto error;
421 case 0: /* Not found, return (None, []) */
422 if (!(result = Py_BuildValue("O[]", Py_None)))
423 goto error;
424 return result;
425 case 1: /* Return (self, []) */
426 if (!(result = Py_BuildValue("O[]", self)))
427 goto error;
428 return result;
429 case 2: /* Return (None, [namespace_portion]) */
430 if (!(result = Py_BuildValue("O[O]", Py_None, namespace_portion)))
431 goto error;
432 return result;
433 }
434 /* Can't get here. */
435 assert(0);
436 return NULL;
437
438error:
439 Py_XDECREF(namespace_portion);
440 Py_XDECREF(result);
441 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +0000442}
443
444/* Load and return the module named by 'fullname'. */
445static PyObject *
446zipimporter_load_module(PyObject *obj, PyObject *args)
447{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000448 ZipImporter *self = (ZipImporter *)obj;
Victor Stinner26fabe12010-10-18 12:03:25 +0000449 PyObject *code = NULL, *mod, *dict;
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400450 PyObject *fullname;
451 PyObject *modpath = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000452 int ispackage;
Just van Rossum52e14d62002-12-30 22:08:05 +0000453
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400454 if (!PyArg_ParseTuple(args, "U:zipimporter.load_module",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000455 &fullname))
456 return NULL;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200457 if (PyUnicode_READY(fullname) == -1)
458 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +0000459
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000460 code = get_module_code(self, fullname, &ispackage, &modpath);
461 if (code == NULL)
Victor Stinner26fabe12010-10-18 12:03:25 +0000462 goto error;
Just van Rossum52e14d62002-12-30 22:08:05 +0000463
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400464 mod = PyImport_AddModuleObject(fullname);
Victor Stinner26fabe12010-10-18 12:03:25 +0000465 if (mod == NULL)
466 goto error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000467 dict = PyModule_GetDict(mod);
Just van Rossum52e14d62002-12-30 22:08:05 +0000468
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000469 /* mod.__loader__ = self */
470 if (PyDict_SetItemString(dict, "__loader__", (PyObject *)self) != 0)
471 goto error;
Just van Rossum52e14d62002-12-30 22:08:05 +0000472
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000473 if (ispackage) {
474 /* add __path__ to the module *before* the code gets
475 executed */
476 PyObject *pkgpath, *fullpath;
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400477 PyObject *subname = get_subname(fullname);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000478 int err;
Just van Rossum52e14d62002-12-30 22:08:05 +0000479
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400480 fullpath = PyUnicode_FromFormat("%U%c%U%U",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000481 self->archive, SEP,
482 self->prefix, subname);
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400483 Py_DECREF(subname);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000484 if (fullpath == NULL)
485 goto error;
Just van Rossum52e14d62002-12-30 22:08:05 +0000486
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400487 pkgpath = Py_BuildValue("[N]", fullpath);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000488 if (pkgpath == NULL)
489 goto error;
490 err = PyDict_SetItemString(dict, "__path__", pkgpath);
491 Py_DECREF(pkgpath);
492 if (err != 0)
493 goto error;
494 }
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400495 mod = PyImport_ExecCodeModuleObject(fullname, code, modpath, NULL);
Victor Stinner26fabe12010-10-18 12:03:25 +0000496 Py_CLEAR(code);
497 if (mod == NULL)
498 goto error;
499
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000500 if (Py_VerboseFlag)
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400501 PySys_FormatStderr("import %U # loaded from Zip %U\n",
Victor Stinner08654e12010-10-18 12:09:02 +0000502 fullname, modpath);
503 Py_DECREF(modpath);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000504 return mod;
Just van Rossum52e14d62002-12-30 22:08:05 +0000505error:
Victor Stinner26fabe12010-10-18 12:03:25 +0000506 Py_XDECREF(code);
Victor Stinner08654e12010-10-18 12:09:02 +0000507 Py_XDECREF(modpath);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000508 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +0000509}
510
Nick Coghlanf088e5e2008-12-14 11:50:48 +0000511/* Return a string matching __file__ for the named module */
512static PyObject *
513zipimporter_get_filename(PyObject *obj, PyObject *args)
514{
515 ZipImporter *self = (ZipImporter *)obj;
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400516 PyObject *fullname, *code, *modpath;
Nick Coghlanf088e5e2008-12-14 11:50:48 +0000517 int ispackage;
518
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400519 if (!PyArg_ParseTuple(args, "U:zipimporter.get_filename",
Victor Stinner9e40fad2010-10-18 22:34:46 +0000520 &fullname))
Victor Stinnerc342fca2010-10-18 11:39:05 +0000521 return NULL;
Nick Coghlanf088e5e2008-12-14 11:50:48 +0000522
523 /* Deciding the filename requires working out where the code
524 would come from if the module was actually loaded */
525 code = get_module_code(self, fullname, &ispackage, &modpath);
526 if (code == NULL)
Victor Stinnerc342fca2010-10-18 11:39:05 +0000527 return NULL;
Nick Coghlanf088e5e2008-12-14 11:50:48 +0000528 Py_DECREF(code); /* Only need the path info */
529
Victor Stinner08654e12010-10-18 12:09:02 +0000530 return modpath;
Nick Coghlanf088e5e2008-12-14 11:50:48 +0000531}
532
Just van Rossum52e14d62002-12-30 22:08:05 +0000533/* Return a bool signifying whether the module is a package or not. */
534static PyObject *
535zipimporter_is_package(PyObject *obj, PyObject *args)
536{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000537 ZipImporter *self = (ZipImporter *)obj;
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400538 PyObject *fullname;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000539 enum zi_module_info mi;
Just van Rossum52e14d62002-12-30 22:08:05 +0000540
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400541 if (!PyArg_ParseTuple(args, "U:zipimporter.is_package",
Victor Stinner965a8a12010-10-18 21:44:33 +0000542 &fullname))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000543 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +0000544
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000545 mi = get_module_info(self, fullname);
546 if (mi == MI_ERROR)
Victor Stinner965a8a12010-10-18 21:44:33 +0000547 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000548 if (mi == MI_NOT_FOUND) {
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400549 PyErr_Format(ZipImportError, "can't find module %R", fullname);
Victor Stinner965a8a12010-10-18 21:44:33 +0000550 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000551 }
552 return PyBool_FromLong(mi == MI_PACKAGE);
Just van Rossum52e14d62002-12-30 22:08:05 +0000553}
554
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200555
Just van Rossum52e14d62002-12-30 22:08:05 +0000556static PyObject *
557zipimporter_get_data(PyObject *obj, PyObject *args)
558{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000559 ZipImporter *self = (ZipImporter *)obj;
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100560 PyObject *path, *key;
Just van Rossum52e14d62002-12-30 22:08:05 +0000561#ifdef ALTSEP
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100562 _Py_IDENTIFIER(replace);
Just van Rossum52e14d62002-12-30 22:08:05 +0000563#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000564 PyObject *toc_entry;
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100565 Py_ssize_t path_start, path_len, len;
Just van Rossum52e14d62002-12-30 22:08:05 +0000566
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100567 if (!PyArg_ParseTuple(args, "U:zipimporter.get_data", &path))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000568 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +0000569
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200570#ifdef ALTSEP
Martin v. Löwiscfa61292011-10-31 09:01:22 +0100571 path = _PyObject_CallMethodId(path, &PyId_replace, "CC", ALTSEP, SEP);
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100572 if (!path)
573 return NULL;
574#else
575 Py_INCREF(path);
Just van Rossum52e14d62002-12-30 22:08:05 +0000576#endif
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100577 if (PyUnicode_READY(path) == -1)
578 goto error;
579
580 path_len = PyUnicode_GET_LENGTH(path);
581
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200582 len = PyUnicode_GET_LENGTH(self->archive);
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100583 path_start = 0;
584 if (PyUnicode_Tailmatch(path, self->archive, 0, len, -1)
585 && PyUnicode_READ_CHAR(path, len) == SEP) {
586 path_start = len + 1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000587 }
Just van Rossum52e14d62002-12-30 22:08:05 +0000588
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100589 key = PyUnicode_Substring(path, path_start, path_len);
Victor Stinner60fe8d92010-08-16 23:48:11 +0000590 if (key == NULL)
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100591 goto error;
Victor Stinner60fe8d92010-08-16 23:48:11 +0000592 toc_entry = PyDict_GetItem(self->files, key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000593 if (toc_entry == NULL) {
Victor Stinner60fe8d92010-08-16 23:48:11 +0000594 PyErr_SetFromErrnoWithFilenameObject(PyExc_IOError, key);
595 Py_DECREF(key);
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100596 goto error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000597 }
Victor Stinner60fe8d92010-08-16 23:48:11 +0000598 Py_DECREF(key);
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100599 Py_DECREF(path);
Victor Stinner60fe8d92010-08-16 23:48:11 +0000600 return get_data(self->archive, toc_entry);
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100601 error:
602 Py_DECREF(path);
603 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +0000604}
605
606static PyObject *
607zipimporter_get_code(PyObject *obj, PyObject *args)
608{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000609 ZipImporter *self = (ZipImporter *)obj;
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400610 PyObject *fullname;
Just van Rossum52e14d62002-12-30 22:08:05 +0000611
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400612 if (!PyArg_ParseTuple(args, "U:zipimporter.get_code", &fullname))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000613 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +0000614
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000615 return get_module_code(self, fullname, NULL, NULL);
Just van Rossum52e14d62002-12-30 22:08:05 +0000616}
617
618static PyObject *
619zipimporter_get_source(PyObject *obj, PyObject *args)
620{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000621 ZipImporter *self = (ZipImporter *)obj;
622 PyObject *toc_entry;
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400623 PyObject *fullname, *subname, *path, *fullpath;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000624 enum zi_module_info mi;
Just van Rossum52e14d62002-12-30 22:08:05 +0000625
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400626 if (!PyArg_ParseTuple(args, "U:zipimporter.get_source", &fullname))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000627 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +0000628
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000629 mi = get_module_info(self, fullname);
Victor Stinner965a8a12010-10-18 21:44:33 +0000630 if (mi == MI_ERROR)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000631 return NULL;
Victor Stinner04106562010-10-18 20:44:08 +0000632 if (mi == MI_NOT_FOUND) {
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400633 PyErr_Format(ZipImportError, "can't find module %R", fullname);
Victor Stinner04106562010-10-18 20:44:08 +0000634 return NULL;
635 }
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400636
Victor Stinner965a8a12010-10-18 21:44:33 +0000637 subname = get_subname(fullname);
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400638 if (subname == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000639 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +0000640
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400641 path = make_filename(self->prefix, subname);
642 Py_DECREF(subname);
643 if (path == NULL)
644 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +0000645
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400646 if (mi == MI_PACKAGE)
647 fullpath = PyUnicode_FromFormat("%U%c__init__.py", path, SEP);
648 else
649 fullpath = PyUnicode_FromFormat("%U.py", path);
650 Py_DECREF(path);
651 if (fullpath == NULL)
652 return NULL;
653
654 toc_entry = PyDict_GetItem(self->files, fullpath);
655 Py_DECREF(fullpath);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000656 if (toc_entry != NULL) {
Victor Stinner60fe8d92010-08-16 23:48:11 +0000657 PyObject *res, *bytes;
658 bytes = get_data(self->archive, toc_entry);
659 if (bytes == NULL)
660 return NULL;
661 res = PyUnicode_FromStringAndSize(PyBytes_AS_STRING(bytes),
662 PyBytes_GET_SIZE(bytes));
663 Py_DECREF(bytes);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000664 return res;
665 }
Just van Rossum52e14d62002-12-30 22:08:05 +0000666
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000667 /* we have the module, but no source */
668 Py_INCREF(Py_None);
669 return Py_None;
Just van Rossum52e14d62002-12-30 22:08:05 +0000670}
671
672PyDoc_STRVAR(doc_find_module,
673"find_module(fullname, path=None) -> self or None.\n\
674\n\
675Search for a module specified by 'fullname'. 'fullname' must be the\n\
676fully qualified (dotted) module name. It returns the zipimporter\n\
677instance itself if the module was found, or None if it wasn't.\n\
678The optional 'path' argument is ignored -- it's there for compatibility\n\
679with the importer protocol.");
680
Eric V. Smith984b11f2012-05-24 20:21:04 -0400681PyDoc_STRVAR(doc_find_loader,
682"find_loader(fullname, path=None) -> self, str or None.\n\
683\n\
684Search for a module specified by 'fullname'. 'fullname' must be the\n\
685fully qualified (dotted) module name. It returns the zipimporter\n\
686instance itself if the module was found, a string containing the\n\
687full path name if it's possibly a portion of a namespace package,\n\
688or None otherwise. The optional 'path' argument is ignored -- it's\n\
689 there for compatibility with the importer protocol.");
690
Just van Rossum52e14d62002-12-30 22:08:05 +0000691PyDoc_STRVAR(doc_load_module,
692"load_module(fullname) -> module.\n\
693\n\
694Load the module specified by 'fullname'. 'fullname' must be the\n\
695fully qualified (dotted) module name. It returns the imported\n\
696module, or raises ZipImportError if it wasn't found.");
697
698PyDoc_STRVAR(doc_get_data,
699"get_data(pathname) -> string with file data.\n\
700\n\
701Return the data associated with 'pathname'. Raise IOError if\n\
702the file wasn't found.");
703
704PyDoc_STRVAR(doc_is_package,
705"is_package(fullname) -> bool.\n\
706\n\
707Return True if the module specified by fullname is a package.\n\
Brian Curtin32839732010-07-21 01:44:19 +0000708Raise ZipImportError if the module couldn't be found.");
Just van Rossum52e14d62002-12-30 22:08:05 +0000709
710PyDoc_STRVAR(doc_get_code,
711"get_code(fullname) -> code object.\n\
712\n\
713Return the code object for the specified module. Raise ZipImportError\n\
Brian Curtin32839732010-07-21 01:44:19 +0000714if the module couldn't be found.");
Just van Rossum52e14d62002-12-30 22:08:05 +0000715
716PyDoc_STRVAR(doc_get_source,
717"get_source(fullname) -> source string.\n\
718\n\
719Return the source code for the specified module. Raise ZipImportError\n\
Brian Curtin32839732010-07-21 01:44:19 +0000720if the module couldn't be found, return None if the archive does\n\
Just van Rossum52e14d62002-12-30 22:08:05 +0000721contain the module, but has no source for it.");
722
Nick Coghlanf088e5e2008-12-14 11:50:48 +0000723
724PyDoc_STRVAR(doc_get_filename,
Nick Coghlan9a1d6e32009-02-08 03:37:27 +0000725"get_filename(fullname) -> filename string.\n\
Nick Coghlanf088e5e2008-12-14 11:50:48 +0000726\n\
727Return the filename for the specified module.");
728
Just van Rossum52e14d62002-12-30 22:08:05 +0000729static PyMethodDef zipimporter_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000730 {"find_module", zipimporter_find_module, METH_VARARGS,
731 doc_find_module},
Eric V. Smith984b11f2012-05-24 20:21:04 -0400732 {"find_loader", zipimporter_find_loader, METH_VARARGS,
733 doc_find_loader},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000734 {"load_module", zipimporter_load_module, METH_VARARGS,
735 doc_load_module},
736 {"get_data", zipimporter_get_data, METH_VARARGS,
737 doc_get_data},
738 {"get_code", zipimporter_get_code, METH_VARARGS,
739 doc_get_code},
740 {"get_source", zipimporter_get_source, METH_VARARGS,
741 doc_get_source},
742 {"get_filename", zipimporter_get_filename, METH_VARARGS,
743 doc_get_filename},
744 {"is_package", zipimporter_is_package, METH_VARARGS,
745 doc_is_package},
746 {NULL, NULL} /* sentinel */
Just van Rossum52e14d62002-12-30 22:08:05 +0000747};
748
749static PyMemberDef zipimporter_members[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000750 {"archive", T_OBJECT, offsetof(ZipImporter, archive), READONLY},
751 {"prefix", T_OBJECT, offsetof(ZipImporter, prefix), READONLY},
752 {"_files", T_OBJECT, offsetof(ZipImporter, files), READONLY},
753 {NULL}
Just van Rossum52e14d62002-12-30 22:08:05 +0000754};
755
756PyDoc_STRVAR(zipimporter_doc,
757"zipimporter(archivepath) -> zipimporter object\n\
758\n\
759Create a new zipimporter instance. 'archivepath' must be a path to\n\
Alexandre Vassalotti8ae3e052008-05-16 00:41:41 +0000760a zipfile, or to a specific path inside a zipfile. For example, it can be\n\
761'/tmp/myimport.zip', or '/tmp/myimport.zip/mydirectory', if mydirectory is a\n\
762valid directory inside the archive.\n\
763\n\
764'ZipImportError is raised if 'archivepath' doesn't point to a valid Zip\n\
765archive.\n\
766\n\
767The 'archive' attribute of zipimporter objects contains the name of the\n\
768zipfile targeted.");
Just van Rossum52e14d62002-12-30 22:08:05 +0000769
770#define DEFERRED_ADDRESS(ADDR) 0
771
772static PyTypeObject ZipImporter_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000773 PyVarObject_HEAD_INIT(DEFERRED_ADDRESS(&PyType_Type), 0)
774 "zipimport.zipimporter",
775 sizeof(ZipImporter),
776 0, /* tp_itemsize */
777 (destructor)zipimporter_dealloc, /* tp_dealloc */
778 0, /* tp_print */
779 0, /* tp_getattr */
780 0, /* tp_setattr */
781 0, /* tp_reserved */
782 (reprfunc)zipimporter_repr, /* tp_repr */
783 0, /* tp_as_number */
784 0, /* tp_as_sequence */
785 0, /* tp_as_mapping */
786 0, /* tp_hash */
787 0, /* tp_call */
788 0, /* tp_str */
789 PyObject_GenericGetAttr, /* tp_getattro */
790 0, /* tp_setattro */
791 0, /* tp_as_buffer */
792 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE |
793 Py_TPFLAGS_HAVE_GC, /* tp_flags */
794 zipimporter_doc, /* tp_doc */
795 zipimporter_traverse, /* tp_traverse */
796 0, /* tp_clear */
797 0, /* tp_richcompare */
798 0, /* tp_weaklistoffset */
799 0, /* tp_iter */
800 0, /* tp_iternext */
801 zipimporter_methods, /* tp_methods */
802 zipimporter_members, /* tp_members */
803 0, /* tp_getset */
804 0, /* tp_base */
805 0, /* tp_dict */
806 0, /* tp_descr_get */
807 0, /* tp_descr_set */
808 0, /* tp_dictoffset */
809 (initproc)zipimporter_init, /* tp_init */
810 PyType_GenericAlloc, /* tp_alloc */
811 PyType_GenericNew, /* tp_new */
812 PyObject_GC_Del, /* tp_free */
Just van Rossum52e14d62002-12-30 22:08:05 +0000813};
814
815
816/* implementation */
817
Just van Rossum52e14d62002-12-30 22:08:05 +0000818/* Given a buffer, return the long that is represented by the first
819 4 bytes, encoded as little endian. This partially reimplements
820 marshal.c:r_long() */
821static long
822get_long(unsigned char *buf) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000823 long x;
824 x = buf[0];
825 x |= (long)buf[1] << 8;
826 x |= (long)buf[2] << 16;
827 x |= (long)buf[3] << 24;
Just van Rossum52e14d62002-12-30 22:08:05 +0000828#if SIZEOF_LONG > 4
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000829 /* Sign extension for 64-bit machines */
830 x |= -(x & 0x80000000L);
Just van Rossum52e14d62002-12-30 22:08:05 +0000831#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000832 return x;
Just van Rossum52e14d62002-12-30 22:08:05 +0000833}
834
835/*
836 read_directory(archive) -> files dict (new reference)
837
838 Given a path to a Zip archive, build a dict, mapping file names
839 (local to the archive, using SEP as a separator) to toc entries.
840
841 A toc_entry is a tuple:
842
Victor Stinner08654e12010-10-18 12:09:02 +0000843 (__file__, # value to use for __file__, available for all files,
844 # encoded to the filesystem encoding
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000845 compress, # compression kind; 0 for uncompressed
846 data_size, # size of compressed data on disk
847 file_size, # size of decompressed data
848 file_offset, # offset of file header from start of archive
849 time, # mod time of file (in dos format)
850 date, # mod data of file (in dos format)
851 crc, # crc checksum of the data
Victor Stinnerc342fca2010-10-18 11:39:05 +0000852 )
Just van Rossum52e14d62002-12-30 22:08:05 +0000853
854 Directories can be recognized by the trailing SEP in the name,
855 data_size and file_offset are 0.
856*/
857static PyObject *
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400858read_directory(PyObject *archive)
Just van Rossum52e14d62002-12-30 22:08:05 +0000859{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000860 PyObject *files = NULL;
861 FILE *fp;
Victor Stinnerd36c8212010-10-18 12:13:46 +0000862 unsigned short flags;
Gregory P. Smithab320662012-01-30 15:17:33 -0800863 short compress, time, date, name_size;
864 long crc, data_size, file_size, header_size;
865 Py_ssize_t file_offset, header_position, header_offset;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200866 long l, count;
867 Py_ssize_t i;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000868 char name[MAXPATHLEN + 5];
Victor Stinner2460a432010-08-16 17:54:28 +0000869 PyObject *nameobj = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000870 char *p, endof_central_dir[22];
Gregory P. Smithab320662012-01-30 15:17:33 -0800871 Py_ssize_t arc_offset; /* Absolute offset to start of the zip-archive. */
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100872 PyObject *path;
Victor Stinnerd36c8212010-10-18 12:13:46 +0000873 const char *charset;
Victor Stinner4ee65a92011-01-22 10:30:29 +0000874 int bootstrap;
Just van Rossum52e14d62002-12-30 22:08:05 +0000875
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400876 fp = _Py_fopen(archive, "rb");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000877 if (fp == NULL) {
Victor Stinnerbd206e22011-12-18 21:04:17 +0100878 if (!PyErr_Occurred())
Victor Stinner35734762011-12-18 21:05:22 +0100879 PyErr_Format(ZipImportError, "can't open Zip file: %R", archive);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000880 return NULL;
881 }
882 fseek(fp, -22, SEEK_END);
883 header_position = ftell(fp);
884 if (fread(endof_central_dir, 1, 22, fp) != 22) {
885 fclose(fp);
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400886 PyErr_Format(ZipImportError, "can't read Zip file: %R", archive);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000887 return NULL;
888 }
889 if (get_long((unsigned char *)endof_central_dir) != 0x06054B50) {
890 /* Bad: End of Central Dir signature */
891 fclose(fp);
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400892 PyErr_Format(ZipImportError, "not a Zip file: %R", archive);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000893 return NULL;
894 }
Just van Rossum52e14d62002-12-30 22:08:05 +0000895
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000896 header_size = get_long((unsigned char *)endof_central_dir + 12);
897 header_offset = get_long((unsigned char *)endof_central_dir + 16);
898 arc_offset = header_position - header_offset - header_size;
899 header_offset += arc_offset;
Just van Rossum52e14d62002-12-30 22:08:05 +0000900
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000901 files = PyDict_New();
902 if (files == NULL)
903 goto error;
Just van Rossum52e14d62002-12-30 22:08:05 +0000904
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000905 /* Start of Central Directory */
906 count = 0;
907 for (;;) {
908 PyObject *t;
909 int err;
Just van Rossum52e14d62002-12-30 22:08:05 +0000910
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000911 fseek(fp, header_offset, 0); /* Start of file header */
912 l = PyMarshal_ReadLongFromFile(fp);
913 if (l != 0x02014B50)
914 break; /* Bad: Central Dir File Header */
Victor Stinnerd36c8212010-10-18 12:13:46 +0000915 fseek(fp, header_offset + 8, 0);
916 flags = (unsigned short)PyMarshal_ReadShortFromFile(fp);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000917 compress = PyMarshal_ReadShortFromFile(fp);
918 time = PyMarshal_ReadShortFromFile(fp);
919 date = PyMarshal_ReadShortFromFile(fp);
920 crc = PyMarshal_ReadLongFromFile(fp);
921 data_size = PyMarshal_ReadLongFromFile(fp);
922 file_size = PyMarshal_ReadLongFromFile(fp);
923 name_size = PyMarshal_ReadShortFromFile(fp);
924 header_size = 46 + name_size +
925 PyMarshal_ReadShortFromFile(fp) +
926 PyMarshal_ReadShortFromFile(fp);
927 fseek(fp, header_offset + 42, 0);
928 file_offset = PyMarshal_ReadLongFromFile(fp) + arc_offset;
929 if (name_size > MAXPATHLEN)
930 name_size = MAXPATHLEN;
Just van Rossum52e14d62002-12-30 22:08:05 +0000931
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000932 p = name;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200933 for (i = 0; i < (Py_ssize_t)name_size; i++) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000934 *p = (char)getc(fp);
935 if (*p == '/')
936 *p = SEP;
937 p++;
938 }
939 *p = 0; /* Add terminating null byte */
940 header_offset += header_size;
Just van Rossum52e14d62002-12-30 22:08:05 +0000941
Victor Stinner4ee65a92011-01-22 10:30:29 +0000942 bootstrap = 0;
Victor Stinnerd36c8212010-10-18 12:13:46 +0000943 if (flags & 0x0800)
944 charset = "utf-8";
Victor Stinner4ee65a92011-01-22 10:30:29 +0000945 else if (!PyThreadState_GET()->interp->codecs_initialized) {
946 /* During bootstrap, we may need to load the encodings
947 package from a ZIP file. But the cp437 encoding is implemented
948 in Python in the encodings package.
949
950 Break out of this dependency by assuming that the path to
951 the encodings module is ASCII-only. */
952 charset = "ascii";
953 bootstrap = 1;
954 }
Victor Stinnerd36c8212010-10-18 12:13:46 +0000955 else
956 charset = "cp437";
957 nameobj = PyUnicode_Decode(name, name_size, charset, NULL);
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200958 if (PyUnicode_READY(nameobj) == -1)
959 goto error;
Victor Stinner4ee65a92011-01-22 10:30:29 +0000960 if (nameobj == NULL) {
961 if (bootstrap)
962 PyErr_Format(PyExc_NotImplementedError,
963 "bootstrap issue: python%i%i.zip contains non-ASCII "
964 "filenames without the unicode flag",
965 PY_MAJOR_VERSION, PY_MINOR_VERSION);
Victor Stinner2460a432010-08-16 17:54:28 +0000966 goto error;
Victor Stinner4ee65a92011-01-22 10:30:29 +0000967 }
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100968 path = PyUnicode_FromFormat("%U%c%U", archive, SEP, nameobj);
969 if (path == NULL)
Victor Stinner2460a432010-08-16 17:54:28 +0000970 goto error;
Gregory P. Smithcc6abd52012-01-30 15:55:29 -0800971 t = Py_BuildValue("Nhllnhhl", path, compress, data_size,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000972 file_size, file_offset, time, date, crc);
973 if (t == NULL)
974 goto error;
Victor Stinner2460a432010-08-16 17:54:28 +0000975 err = PyDict_SetItem(files, nameobj, t);
976 Py_CLEAR(nameobj);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000977 Py_DECREF(t);
978 if (err != 0)
979 goto error;
980 count++;
981 }
982 fclose(fp);
983 if (Py_VerboseFlag)
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400984 PySys_FormatStderr("# zipimport: found %ld names in %R\n",
985 count, archive);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000986 return files;
Just van Rossum52e14d62002-12-30 22:08:05 +0000987error:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000988 fclose(fp);
989 Py_XDECREF(files);
Victor Stinner2460a432010-08-16 17:54:28 +0000990 Py_XDECREF(nameobj);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000991 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +0000992}
993
994/* Return the zlib.decompress function object, or NULL if zlib couldn't
995 be imported. The function is cached when found, so subsequent calls
Victor Stinner4925cde2011-05-20 00:16:09 +0200996 don't import zlib again. */
Just van Rossum52e14d62002-12-30 22:08:05 +0000997static PyObject *
998get_decompress_func(void)
999{
Victor Stinner4925cde2011-05-20 00:16:09 +02001000 static int importing_zlib = 0;
1001 PyObject *zlib;
1002 PyObject *decompress;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02001003 _Py_IDENTIFIER(decompress);
Just van Rossum52e14d62002-12-30 22:08:05 +00001004
Victor Stinner4925cde2011-05-20 00:16:09 +02001005 if (importing_zlib != 0)
1006 /* Someone has a zlib.py[co] in their Zip file;
1007 let's avoid a stack overflow. */
1008 return NULL;
1009 importing_zlib = 1;
1010 zlib = PyImport_ImportModuleNoBlock("zlib");
1011 importing_zlib = 0;
1012 if (zlib != NULL) {
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02001013 decompress = _PyObject_GetAttrId(zlib,
1014 &PyId_decompress);
Victor Stinner4925cde2011-05-20 00:16:09 +02001015 Py_DECREF(zlib);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001016 }
Victor Stinner4925cde2011-05-20 00:16:09 +02001017 else {
1018 PyErr_Clear();
1019 decompress = NULL;
1020 }
1021 if (Py_VerboseFlag)
1022 PySys_WriteStderr("# zipimport: zlib %s\n",
1023 zlib != NULL ? "available": "UNAVAILABLE");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001024 return decompress;
Just van Rossum52e14d62002-12-30 22:08:05 +00001025}
1026
1027/* Given a path to a Zip file and a toc_entry, return the (uncompressed)
1028 data as a new reference. */
1029static PyObject *
Victor Stinner60fe8d92010-08-16 23:48:11 +00001030get_data(PyObject *archive, PyObject *toc_entry)
Just van Rossum52e14d62002-12-30 22:08:05 +00001031{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001032 PyObject *raw_data, *data = NULL, *decompress;
1033 char *buf;
1034 FILE *fp;
1035 int err;
1036 Py_ssize_t bytes_read = 0;
1037 long l;
Victor Stinner60fe8d92010-08-16 23:48:11 +00001038 PyObject *datapath;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001039 long compress, data_size, file_size, file_offset, bytes_size;
1040 long time, date, crc;
Just van Rossum52e14d62002-12-30 22:08:05 +00001041
Victor Stinner60fe8d92010-08-16 23:48:11 +00001042 if (!PyArg_ParseTuple(toc_entry, "Olllllll", &datapath, &compress,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001043 &data_size, &file_size, &file_offset, &time,
1044 &date, &crc)) {
1045 return NULL;
1046 }
Just van Rossum52e14d62002-12-30 22:08:05 +00001047
Victor Stinner60fe8d92010-08-16 23:48:11 +00001048 fp = _Py_fopen(archive, "rb");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001049 if (!fp) {
Victor Stinnerbd206e22011-12-18 21:04:17 +01001050 if (!PyErr_Occurred())
1051 PyErr_Format(PyExc_IOError,
1052 "zipimport: can not open file %U", archive);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001053 return NULL;
1054 }
Just van Rossum52e14d62002-12-30 22:08:05 +00001055
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001056 /* Check to make sure the local file header is correct */
1057 fseek(fp, file_offset, 0);
1058 l = PyMarshal_ReadLongFromFile(fp);
1059 if (l != 0x04034B50) {
1060 /* Bad: Local File Header */
1061 PyErr_Format(ZipImportError,
Victor Stinner60fe8d92010-08-16 23:48:11 +00001062 "bad local file header in %U",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001063 archive);
1064 fclose(fp);
1065 return NULL;
1066 }
1067 fseek(fp, file_offset + 26, 0);
1068 l = 30 + PyMarshal_ReadShortFromFile(fp) +
1069 PyMarshal_ReadShortFromFile(fp); /* local header size */
1070 file_offset += l; /* Start of file data */
Just van Rossum52e14d62002-12-30 22:08:05 +00001071
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001072 bytes_size = compress == 0 ? data_size : data_size + 1;
1073 if (bytes_size == 0)
1074 bytes_size++;
1075 raw_data = PyBytes_FromStringAndSize((char *)NULL, bytes_size);
Just van Rossum52e14d62002-12-30 22:08:05 +00001076
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001077 if (raw_data == NULL) {
1078 fclose(fp);
1079 return NULL;
1080 }
1081 buf = PyBytes_AsString(raw_data);
Just van Rossum52e14d62002-12-30 22:08:05 +00001082
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001083 err = fseek(fp, file_offset, 0);
1084 if (err == 0)
1085 bytes_read = fread(buf, 1, data_size, fp);
1086 fclose(fp);
1087 if (err || bytes_read != data_size) {
1088 PyErr_SetString(PyExc_IOError,
1089 "zipimport: can't read data");
1090 Py_DECREF(raw_data);
1091 return NULL;
1092 }
Just van Rossum52e14d62002-12-30 22:08:05 +00001093
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001094 if (compress != 0) {
1095 buf[data_size] = 'Z'; /* saw this in zipfile.py */
1096 data_size++;
1097 }
1098 buf[data_size] = '\0';
Just van Rossum52e14d62002-12-30 22:08:05 +00001099
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001100 if (compress == 0) { /* data is not compressed */
1101 data = PyBytes_FromStringAndSize(buf, data_size);
1102 Py_DECREF(raw_data);
1103 return data;
1104 }
1105
1106 /* Decompress with zlib */
1107 decompress = get_decompress_func();
1108 if (decompress == NULL) {
1109 PyErr_SetString(ZipImportError,
1110 "can't decompress data; "
1111 "zlib not available");
1112 goto error;
1113 }
1114 data = PyObject_CallFunction(decompress, "Oi", raw_data, -15);
Victor Stinner4925cde2011-05-20 00:16:09 +02001115 Py_DECREF(decompress);
Just van Rossum52e14d62002-12-30 22:08:05 +00001116error:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001117 Py_DECREF(raw_data);
1118 return data;
Just van Rossum52e14d62002-12-30 22:08:05 +00001119}
1120
1121/* Lenient date/time comparison function. The precision of the mtime
1122 in the archive is lower than the mtime stored in a .pyc: we
1123 must allow a difference of at most one second. */
1124static int
1125eq_mtime(time_t t1, time_t t2)
1126{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001127 time_t d = t1 - t2;
1128 if (d < 0)
1129 d = -d;
1130 /* dostime only stores even seconds, so be lenient */
1131 return d <= 1;
Just van Rossum52e14d62002-12-30 22:08:05 +00001132}
1133
1134/* Given the contents of a .py[co] file in a buffer, unmarshal the data
1135 and return the code object. Return None if it the magic word doesn't
1136 match (we do this instead of raising an exception as we fall back
1137 to .py if available and we don't want to mask other errors).
1138 Returns a new reference. */
1139static PyObject *
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001140unmarshal_code(PyObject *pathname, PyObject *data, time_t mtime)
Just van Rossum52e14d62002-12-30 22:08:05 +00001141{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001142 PyObject *code;
1143 char *buf = PyBytes_AsString(data);
1144 Py_ssize_t size = PyBytes_Size(data);
Just van Rossum52e14d62002-12-30 22:08:05 +00001145
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001146 if (size <= 9) {
1147 PyErr_SetString(ZipImportError,
1148 "bad pyc data");
1149 return NULL;
1150 }
Just van Rossum52e14d62002-12-30 22:08:05 +00001151
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001152 if (get_long((unsigned char *)buf) != PyImport_GetMagicNumber()) {
1153 if (Py_VerboseFlag)
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001154 PySys_FormatStderr("# %R has bad magic\n",
1155 pathname);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001156 Py_INCREF(Py_None);
1157 return Py_None; /* signal caller to try alternative */
1158 }
Just van Rossum52e14d62002-12-30 22:08:05 +00001159
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001160 if (mtime != 0 && !eq_mtime(get_long((unsigned char *)buf + 4),
1161 mtime)) {
1162 if (Py_VerboseFlag)
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001163 PySys_FormatStderr("# %R has bad mtime\n",
1164 pathname);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001165 Py_INCREF(Py_None);
1166 return Py_None; /* signal caller to try alternative */
1167 }
Just van Rossum52e14d62002-12-30 22:08:05 +00001168
Antoine Pitrou5136ac02012-01-13 18:52:16 +01001169 /* XXX the pyc's size field is ignored; timestamp collisions are probably
1170 unimportant with zip files. */
1171 code = PyMarshal_ReadObjectFromString(buf + 12, size - 12);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001172 if (code == NULL)
1173 return NULL;
1174 if (!PyCode_Check(code)) {
1175 Py_DECREF(code);
1176 PyErr_Format(PyExc_TypeError,
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001177 "compiled module %R is not a code object",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001178 pathname);
1179 return NULL;
1180 }
1181 return code;
Just van Rossum52e14d62002-12-30 22:08:05 +00001182}
1183
1184/* Replace any occurances of "\r\n?" in the input string with "\n".
1185 This converts DOS and Mac line endings to Unix line endings.
1186 Also append a trailing "\n" to be compatible with
1187 PyParser_SimpleParseFile(). Returns a new reference. */
1188static PyObject *
1189normalize_line_endings(PyObject *source)
1190{
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001191 char *buf, *q, *p;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001192 PyObject *fixed_source;
1193 int len = 0;
Just van Rossum52e14d62002-12-30 22:08:05 +00001194
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001195 p = PyBytes_AsString(source);
1196 if (p == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001197 return PyBytes_FromStringAndSize("\n\0", 2);
1198 }
Thomas Wouters00ee7ba2006-08-21 19:07:27 +00001199
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001200 /* one char extra for trailing \n and one for terminating \0 */
1201 buf = (char *)PyMem_Malloc(PyBytes_Size(source) + 2);
1202 if (buf == NULL) {
1203 PyErr_SetString(PyExc_MemoryError,
1204 "zipimport: no memory to allocate "
1205 "source buffer");
1206 return NULL;
1207 }
1208 /* replace "\r\n?" by "\n" */
1209 for (q = buf; *p != '\0'; p++) {
1210 if (*p == '\r') {
1211 *q++ = '\n';
1212 if (*(p + 1) == '\n')
1213 p++;
1214 }
1215 else
1216 *q++ = *p;
1217 len++;
1218 }
1219 *q++ = '\n'; /* add trailing \n */
1220 *q = '\0';
1221 fixed_source = PyBytes_FromStringAndSize(buf, len + 2);
1222 PyMem_Free(buf);
1223 return fixed_source;
Just van Rossum52e14d62002-12-30 22:08:05 +00001224}
1225
1226/* Given a string buffer containing Python source code, compile it
1227 return and return a code object as a new reference. */
1228static PyObject *
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001229compile_source(PyObject *pathname, PyObject *source)
Just van Rossum52e14d62002-12-30 22:08:05 +00001230{
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001231 PyObject *code, *fixed_source, *pathbytes;
Just van Rossum52e14d62002-12-30 22:08:05 +00001232
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001233 pathbytes = PyUnicode_EncodeFSDefault(pathname);
1234 if (pathbytes == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001235 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +00001236
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001237 fixed_source = normalize_line_endings(source);
1238 if (fixed_source == NULL) {
1239 Py_DECREF(pathbytes);
1240 return NULL;
1241 }
1242
1243 code = Py_CompileString(PyBytes_AsString(fixed_source),
1244 PyBytes_AsString(pathbytes),
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001245 Py_file_input);
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001246 Py_DECREF(pathbytes);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001247 Py_DECREF(fixed_source);
1248 return code;
Just van Rossum52e14d62002-12-30 22:08:05 +00001249}
1250
1251/* Convert the date/time values found in the Zip archive to a value
1252 that's compatible with the time stamp stored in .pyc files. */
Neal Norwitz29fd2ba2003-03-23 13:21:03 +00001253static time_t
1254parse_dostime(int dostime, int dosdate)
Just van Rossum52e14d62002-12-30 22:08:05 +00001255{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001256 struct tm stm;
Just van Rossum52e14d62002-12-30 22:08:05 +00001257
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001258 memset((void *) &stm, '\0', sizeof(stm));
Christian Heimes679db4a2008-01-18 09:56:22 +00001259
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001260 stm.tm_sec = (dostime & 0x1f) * 2;
1261 stm.tm_min = (dostime >> 5) & 0x3f;
1262 stm.tm_hour = (dostime >> 11) & 0x1f;
1263 stm.tm_mday = dosdate & 0x1f;
1264 stm.tm_mon = ((dosdate >> 5) & 0x0f) - 1;
1265 stm.tm_year = ((dosdate >> 9) & 0x7f) + 80;
1266 stm.tm_isdst = -1; /* wday/yday is ignored */
Just van Rossum52e14d62002-12-30 22:08:05 +00001267
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001268 return mktime(&stm);
Just van Rossum52e14d62002-12-30 22:08:05 +00001269}
1270
1271/* Given a path to a .pyc or .pyo file in the archive, return the
Ezio Melotti13925002011-03-16 11:05:33 +02001272 modification time of the matching .py file, or 0 if no source
Just van Rossum52e14d62002-12-30 22:08:05 +00001273 is available. */
1274static time_t
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001275get_mtime_of_source(ZipImporter *self, PyObject *path)
Just van Rossum52e14d62002-12-30 22:08:05 +00001276{
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001277 PyObject *toc_entry, *stripped;
1278 time_t mtime;
1279
1280 /* strip 'c' or 'o' from *.py[co] */
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001281 if (PyUnicode_READY(path) == -1)
1282 return (time_t)-1;
1283 stripped = PyUnicode_FromKindAndData(PyUnicode_KIND(path),
1284 PyUnicode_DATA(path),
1285 PyUnicode_GET_LENGTH(path) - 1);
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001286 if (stripped == NULL)
1287 return (time_t)-1;
1288
1289 toc_entry = PyDict_GetItem(self->files, stripped);
1290 Py_DECREF(stripped);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001291 if (toc_entry != NULL && PyTuple_Check(toc_entry) &&
1292 PyTuple_Size(toc_entry) == 8) {
1293 /* fetch the time stamp of the .py file for comparison
1294 with an embedded pyc time stamp */
1295 int time, date;
1296 time = PyLong_AsLong(PyTuple_GetItem(toc_entry, 5));
1297 date = PyLong_AsLong(PyTuple_GetItem(toc_entry, 6));
1298 mtime = parse_dostime(time, date);
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001299 } else
1300 mtime = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001301 return mtime;
Just van Rossum52e14d62002-12-30 22:08:05 +00001302}
1303
1304/* Return the code object for the module named by 'fullname' from the
1305 Zip archive as a new reference. */
1306static PyObject *
1307get_code_from_data(ZipImporter *self, int ispackage, int isbytecode,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001308 time_t mtime, PyObject *toc_entry)
Just van Rossum52e14d62002-12-30 22:08:05 +00001309{
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001310 PyObject *data, *modpath, *code;
Just van Rossum52e14d62002-12-30 22:08:05 +00001311
Victor Stinner60fe8d92010-08-16 23:48:11 +00001312 data = get_data(self->archive, toc_entry);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001313 if (data == NULL)
1314 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +00001315
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001316 modpath = PyTuple_GetItem(toc_entry, 0);
Victor Stinner2a94f4c2010-10-18 12:15:34 +00001317 if (isbytecode)
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001318 code = unmarshal_code(modpath, data, mtime);
Victor Stinner2a94f4c2010-10-18 12:15:34 +00001319 else
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001320 code = compile_source(modpath, data);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001321 Py_DECREF(data);
1322 return code;
Just van Rossum52e14d62002-12-30 22:08:05 +00001323}
1324
Ezio Melotti42da6632011-03-15 05:18:48 +02001325/* Get the code object associated with the module specified by
Just van Rossum52e14d62002-12-30 22:08:05 +00001326 'fullname'. */
1327static PyObject *
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001328get_module_code(ZipImporter *self, PyObject *fullname,
Victor Stinner08654e12010-10-18 12:09:02 +00001329 int *p_ispackage, PyObject **p_modpath)
Just van Rossum52e14d62002-12-30 22:08:05 +00001330{
Gregory P. Smith95c7c462011-05-21 05:19:42 -07001331 PyObject *code = NULL, *toc_entry, *subname;
Victor Stinner9a2261a2011-05-26 13:59:41 +02001332 PyObject *path, *fullpath = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001333 struct st_zip_searchorder *zso;
Just van Rossum52e14d62002-12-30 22:08:05 +00001334
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001335 subname = get_subname(fullname);
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001336 if (subname == NULL)
1337 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +00001338
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001339 path = make_filename(self->prefix, subname);
1340 Py_DECREF(subname);
1341 if (path == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001342 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +00001343
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001344 for (zso = zip_searchorder; *zso->suffix; zso++) {
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001345 code = NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +00001346
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001347 fullpath = PyUnicode_FromFormat("%U%s", path, zso->suffix);
1348 if (fullpath == NULL)
1349 goto exit;
1350
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001351 if (Py_VerboseFlag > 1)
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001352 PySys_FormatStderr("# trying %U%c%U\n",
1353 self->archive, (int)SEP, fullpath);
1354 toc_entry = PyDict_GetItem(self->files, fullpath);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001355 if (toc_entry != NULL) {
1356 time_t mtime = 0;
1357 int ispackage = zso->type & IS_PACKAGE;
1358 int isbytecode = zso->type & IS_BYTECODE;
Just van Rossum52e14d62002-12-30 22:08:05 +00001359
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001360 if (isbytecode) {
1361 mtime = get_mtime_of_source(self, fullpath);
1362 if (mtime == (time_t)-1 && PyErr_Occurred()) {
1363 goto exit;
1364 }
1365 }
1366 Py_CLEAR(fullpath);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001367 if (p_ispackage != NULL)
1368 *p_ispackage = ispackage;
1369 code = get_code_from_data(self, ispackage,
1370 isbytecode, mtime,
1371 toc_entry);
1372 if (code == Py_None) {
1373 /* bad magic number or non-matching mtime
1374 in byte code, try next */
1375 Py_DECREF(code);
1376 continue;
1377 }
Victor Stinner08654e12010-10-18 12:09:02 +00001378 if (code != NULL && p_modpath != NULL) {
1379 *p_modpath = PyTuple_GetItem(toc_entry, 0);
1380 Py_INCREF(*p_modpath);
1381 }
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001382 goto exit;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001383 }
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001384 else
1385 Py_CLEAR(fullpath);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001386 }
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001387 PyErr_Format(ZipImportError, "can't find module %R", fullname);
1388exit:
1389 Py_DECREF(path);
1390 Py_XDECREF(fullpath);
1391 return code;
Just van Rossum52e14d62002-12-30 22:08:05 +00001392}
1393
1394
1395/* Module init */
1396
1397PyDoc_STRVAR(zipimport_doc,
1398"zipimport provides support for importing Python modules from Zip archives.\n\
1399\n\
1400This module exports three objects:\n\
1401- zipimporter: a class; its constructor takes a path to a Zip archive.\n\
Fredrik Lundhb84b35f2006-01-15 15:00:40 +00001402- ZipImportError: exception raised by zipimporter objects. It's a\n\
Just van Rossum52e14d62002-12-30 22:08:05 +00001403 subclass of ImportError, so it can be caught as ImportError, too.\n\
1404- _zip_directory_cache: a dict, mapping archive paths to zip directory\n\
1405 info dicts, as used in zipimporter._files.\n\
1406\n\
1407It is usually not needed to use the zipimport module explicitly; it is\n\
1408used by the builtin import mechanism for sys.path items that are paths\n\
1409to Zip archives.");
1410
Martin v. Löwis1a214512008-06-11 05:26:20 +00001411static struct PyModuleDef zipimportmodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001412 PyModuleDef_HEAD_INIT,
1413 "zipimport",
1414 zipimport_doc,
1415 -1,
1416 NULL,
1417 NULL,
1418 NULL,
1419 NULL,
1420 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +00001421};
1422
Just van Rossum52e14d62002-12-30 22:08:05 +00001423PyMODINIT_FUNC
Martin v. Löwis1a214512008-06-11 05:26:20 +00001424PyInit_zipimport(void)
Just van Rossum52e14d62002-12-30 22:08:05 +00001425{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001426 PyObject *mod;
Just van Rossum52e14d62002-12-30 22:08:05 +00001427
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001428 if (PyType_Ready(&ZipImporter_Type) < 0)
1429 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +00001430
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001431 /* Correct directory separator */
1432 zip_searchorder[0].suffix[0] = SEP;
1433 zip_searchorder[1].suffix[0] = SEP;
1434 zip_searchorder[2].suffix[0] = SEP;
1435 if (Py_OptimizeFlag) {
1436 /* Reverse *.pyc and *.pyo */
1437 struct st_zip_searchorder tmp;
1438 tmp = zip_searchorder[0];
1439 zip_searchorder[0] = zip_searchorder[1];
1440 zip_searchorder[1] = tmp;
1441 tmp = zip_searchorder[3];
1442 zip_searchorder[3] = zip_searchorder[4];
1443 zip_searchorder[4] = tmp;
1444 }
Just van Rossum52e14d62002-12-30 22:08:05 +00001445
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001446 mod = PyModule_Create(&zipimportmodule);
1447 if (mod == NULL)
1448 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +00001449
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001450 ZipImportError = PyErr_NewException("zipimport.ZipImportError",
1451 PyExc_ImportError, NULL);
1452 if (ZipImportError == NULL)
1453 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +00001454
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001455 Py_INCREF(ZipImportError);
1456 if (PyModule_AddObject(mod, "ZipImportError",
1457 ZipImportError) < 0)
1458 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +00001459
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001460 Py_INCREF(&ZipImporter_Type);
1461 if (PyModule_AddObject(mod, "zipimporter",
1462 (PyObject *)&ZipImporter_Type) < 0)
1463 return NULL;
Just van Rossumf8b6de12002-12-31 09:51:59 +00001464
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001465 zip_directory_cache = PyDict_New();
1466 if (zip_directory_cache == NULL)
1467 return NULL;
1468 Py_INCREF(zip_directory_cache);
1469 if (PyModule_AddObject(mod, "_zip_directory_cache",
1470 zip_directory_cache) < 0)
1471 return NULL;
1472 return mod;
Just van Rossum52e14d62002-12-30 22:08:05 +00001473}