blob: 604363e7a96c03be1594069e3a95a38c45c46fc3 [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);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000105 if (rv == 0) {
106 /* it exists */
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100107 if (!S_ISREG(statbuf.st_mode))
108 /* it's a not file */
109 Py_CLEAR(filename);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000110 break;
111 }
Victor Stinner2b8dab72010-08-14 14:54:10 +0000112 else if (PyErr_Occurred())
113 goto error;
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 PyObject *tmp;
443 _Py_IDENTIFIER(replace);
Just van Rossum52e14d62002-12-30 22:08:05 +0000444#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000445 PyObject *toc_entry;
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100446 Py_ssize_t path_start, path_len, len;
Just van Rossum52e14d62002-12-30 22:08:05 +0000447
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100448 if (!PyArg_ParseTuple(args, "U:zipimporter.get_data", &path))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000449 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +0000450
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200451#ifdef ALTSEP
Martin v. Löwiscfa61292011-10-31 09:01:22 +0100452 path = _PyObject_CallMethodId(path, &PyId_replace, "CC", ALTSEP, SEP);
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100453 if (!path)
454 return NULL;
455#else
456 Py_INCREF(path);
Just van Rossum52e14d62002-12-30 22:08:05 +0000457#endif
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100458 if (PyUnicode_READY(path) == -1)
459 goto error;
460
461 path_len = PyUnicode_GET_LENGTH(path);
462
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200463 len = PyUnicode_GET_LENGTH(self->archive);
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100464 path_start = 0;
465 if (PyUnicode_Tailmatch(path, self->archive, 0, len, -1)
466 && PyUnicode_READ_CHAR(path, len) == SEP) {
467 path_start = len + 1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000468 }
Just van Rossum52e14d62002-12-30 22:08:05 +0000469
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100470 key = PyUnicode_Substring(path, path_start, path_len);
Victor Stinner60fe8d92010-08-16 23:48:11 +0000471 if (key == NULL)
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100472 goto error;
Victor Stinner60fe8d92010-08-16 23:48:11 +0000473 toc_entry = PyDict_GetItem(self->files, key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000474 if (toc_entry == NULL) {
Victor Stinner60fe8d92010-08-16 23:48:11 +0000475 PyErr_SetFromErrnoWithFilenameObject(PyExc_IOError, key);
476 Py_DECREF(key);
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100477 goto error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000478 }
Victor Stinner60fe8d92010-08-16 23:48:11 +0000479 Py_DECREF(key);
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100480 Py_DECREF(path);
Victor Stinner60fe8d92010-08-16 23:48:11 +0000481 return get_data(self->archive, toc_entry);
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100482 error:
483 Py_DECREF(path);
484 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +0000485}
486
487static PyObject *
488zipimporter_get_code(PyObject *obj, PyObject *args)
489{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000490 ZipImporter *self = (ZipImporter *)obj;
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400491 PyObject *fullname;
Just van Rossum52e14d62002-12-30 22:08:05 +0000492
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400493 if (!PyArg_ParseTuple(args, "U:zipimporter.get_code", &fullname))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000494 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +0000495
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000496 return get_module_code(self, fullname, NULL, NULL);
Just van Rossum52e14d62002-12-30 22:08:05 +0000497}
498
499static PyObject *
500zipimporter_get_source(PyObject *obj, PyObject *args)
501{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000502 ZipImporter *self = (ZipImporter *)obj;
503 PyObject *toc_entry;
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400504 PyObject *fullname, *subname, *path, *fullpath;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000505 enum zi_module_info mi;
Just van Rossum52e14d62002-12-30 22:08:05 +0000506
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400507 if (!PyArg_ParseTuple(args, "U:zipimporter.get_source", &fullname))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000508 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +0000509
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000510 mi = get_module_info(self, fullname);
Victor Stinner965a8a12010-10-18 21:44:33 +0000511 if (mi == MI_ERROR)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000512 return NULL;
Victor Stinner04106562010-10-18 20:44:08 +0000513 if (mi == MI_NOT_FOUND) {
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400514 PyErr_Format(ZipImportError, "can't find module %R", fullname);
Victor Stinner04106562010-10-18 20:44:08 +0000515 return NULL;
516 }
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400517
Victor Stinner965a8a12010-10-18 21:44:33 +0000518 subname = get_subname(fullname);
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400519 if (subname == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000520 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +0000521
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400522 path = make_filename(self->prefix, subname);
523 Py_DECREF(subname);
524 if (path == NULL)
525 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +0000526
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400527 if (mi == MI_PACKAGE)
528 fullpath = PyUnicode_FromFormat("%U%c__init__.py", path, SEP);
529 else
530 fullpath = PyUnicode_FromFormat("%U.py", path);
531 Py_DECREF(path);
532 if (fullpath == NULL)
533 return NULL;
534
535 toc_entry = PyDict_GetItem(self->files, fullpath);
536 Py_DECREF(fullpath);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000537 if (toc_entry != NULL) {
Victor Stinner60fe8d92010-08-16 23:48:11 +0000538 PyObject *res, *bytes;
539 bytes = get_data(self->archive, toc_entry);
540 if (bytes == NULL)
541 return NULL;
542 res = PyUnicode_FromStringAndSize(PyBytes_AS_STRING(bytes),
543 PyBytes_GET_SIZE(bytes));
544 Py_DECREF(bytes);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000545 return res;
546 }
Just van Rossum52e14d62002-12-30 22:08:05 +0000547
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000548 /* we have the module, but no source */
549 Py_INCREF(Py_None);
550 return Py_None;
Just van Rossum52e14d62002-12-30 22:08:05 +0000551}
552
553PyDoc_STRVAR(doc_find_module,
554"find_module(fullname, path=None) -> self or None.\n\
555\n\
556Search for a module specified by 'fullname'. 'fullname' must be the\n\
557fully qualified (dotted) module name. It returns the zipimporter\n\
558instance itself if the module was found, or None if it wasn't.\n\
559The optional 'path' argument is ignored -- it's there for compatibility\n\
560with the importer protocol.");
561
562PyDoc_STRVAR(doc_load_module,
563"load_module(fullname) -> module.\n\
564\n\
565Load the module specified by 'fullname'. 'fullname' must be the\n\
566fully qualified (dotted) module name. It returns the imported\n\
567module, or raises ZipImportError if it wasn't found.");
568
569PyDoc_STRVAR(doc_get_data,
570"get_data(pathname) -> string with file data.\n\
571\n\
572Return the data associated with 'pathname'. Raise IOError if\n\
573the file wasn't found.");
574
575PyDoc_STRVAR(doc_is_package,
576"is_package(fullname) -> bool.\n\
577\n\
578Return True if the module specified by fullname is a package.\n\
Brian Curtin32839732010-07-21 01:44:19 +0000579Raise ZipImportError if the module couldn't be found.");
Just van Rossum52e14d62002-12-30 22:08:05 +0000580
581PyDoc_STRVAR(doc_get_code,
582"get_code(fullname) -> code object.\n\
583\n\
584Return the code object for the specified module. Raise ZipImportError\n\
Brian Curtin32839732010-07-21 01:44:19 +0000585if the module couldn't be found.");
Just van Rossum52e14d62002-12-30 22:08:05 +0000586
587PyDoc_STRVAR(doc_get_source,
588"get_source(fullname) -> source string.\n\
589\n\
590Return the source code for the specified module. Raise ZipImportError\n\
Brian Curtin32839732010-07-21 01:44:19 +0000591if the module couldn't be found, return None if the archive does\n\
Just van Rossum52e14d62002-12-30 22:08:05 +0000592contain the module, but has no source for it.");
593
Nick Coghlanf088e5e2008-12-14 11:50:48 +0000594
595PyDoc_STRVAR(doc_get_filename,
Nick Coghlan9a1d6e32009-02-08 03:37:27 +0000596"get_filename(fullname) -> filename string.\n\
Nick Coghlanf088e5e2008-12-14 11:50:48 +0000597\n\
598Return the filename for the specified module.");
599
Just van Rossum52e14d62002-12-30 22:08:05 +0000600static PyMethodDef zipimporter_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000601 {"find_module", zipimporter_find_module, METH_VARARGS,
602 doc_find_module},
603 {"load_module", zipimporter_load_module, METH_VARARGS,
604 doc_load_module},
605 {"get_data", zipimporter_get_data, METH_VARARGS,
606 doc_get_data},
607 {"get_code", zipimporter_get_code, METH_VARARGS,
608 doc_get_code},
609 {"get_source", zipimporter_get_source, METH_VARARGS,
610 doc_get_source},
611 {"get_filename", zipimporter_get_filename, METH_VARARGS,
612 doc_get_filename},
613 {"is_package", zipimporter_is_package, METH_VARARGS,
614 doc_is_package},
615 {NULL, NULL} /* sentinel */
Just van Rossum52e14d62002-12-30 22:08:05 +0000616};
617
618static PyMemberDef zipimporter_members[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000619 {"archive", T_OBJECT, offsetof(ZipImporter, archive), READONLY},
620 {"prefix", T_OBJECT, offsetof(ZipImporter, prefix), READONLY},
621 {"_files", T_OBJECT, offsetof(ZipImporter, files), READONLY},
622 {NULL}
Just van Rossum52e14d62002-12-30 22:08:05 +0000623};
624
625PyDoc_STRVAR(zipimporter_doc,
626"zipimporter(archivepath) -> zipimporter object\n\
627\n\
628Create a new zipimporter instance. 'archivepath' must be a path to\n\
Alexandre Vassalotti8ae3e052008-05-16 00:41:41 +0000629a zipfile, or to a specific path inside a zipfile. For example, it can be\n\
630'/tmp/myimport.zip', or '/tmp/myimport.zip/mydirectory', if mydirectory is a\n\
631valid directory inside the archive.\n\
632\n\
633'ZipImportError is raised if 'archivepath' doesn't point to a valid Zip\n\
634archive.\n\
635\n\
636The 'archive' attribute of zipimporter objects contains the name of the\n\
637zipfile targeted.");
Just van Rossum52e14d62002-12-30 22:08:05 +0000638
639#define DEFERRED_ADDRESS(ADDR) 0
640
641static PyTypeObject ZipImporter_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000642 PyVarObject_HEAD_INIT(DEFERRED_ADDRESS(&PyType_Type), 0)
643 "zipimport.zipimporter",
644 sizeof(ZipImporter),
645 0, /* tp_itemsize */
646 (destructor)zipimporter_dealloc, /* tp_dealloc */
647 0, /* tp_print */
648 0, /* tp_getattr */
649 0, /* tp_setattr */
650 0, /* tp_reserved */
651 (reprfunc)zipimporter_repr, /* tp_repr */
652 0, /* tp_as_number */
653 0, /* tp_as_sequence */
654 0, /* tp_as_mapping */
655 0, /* tp_hash */
656 0, /* tp_call */
657 0, /* tp_str */
658 PyObject_GenericGetAttr, /* tp_getattro */
659 0, /* tp_setattro */
660 0, /* tp_as_buffer */
661 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE |
662 Py_TPFLAGS_HAVE_GC, /* tp_flags */
663 zipimporter_doc, /* tp_doc */
664 zipimporter_traverse, /* tp_traverse */
665 0, /* tp_clear */
666 0, /* tp_richcompare */
667 0, /* tp_weaklistoffset */
668 0, /* tp_iter */
669 0, /* tp_iternext */
670 zipimporter_methods, /* tp_methods */
671 zipimporter_members, /* tp_members */
672 0, /* tp_getset */
673 0, /* tp_base */
674 0, /* tp_dict */
675 0, /* tp_descr_get */
676 0, /* tp_descr_set */
677 0, /* tp_dictoffset */
678 (initproc)zipimporter_init, /* tp_init */
679 PyType_GenericAlloc, /* tp_alloc */
680 PyType_GenericNew, /* tp_new */
681 PyObject_GC_Del, /* tp_free */
Just van Rossum52e14d62002-12-30 22:08:05 +0000682};
683
684
685/* implementation */
686
Just van Rossum52e14d62002-12-30 22:08:05 +0000687/* Given a buffer, return the long that is represented by the first
688 4 bytes, encoded as little endian. This partially reimplements
689 marshal.c:r_long() */
690static long
691get_long(unsigned char *buf) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000692 long x;
693 x = buf[0];
694 x |= (long)buf[1] << 8;
695 x |= (long)buf[2] << 16;
696 x |= (long)buf[3] << 24;
Just van Rossum52e14d62002-12-30 22:08:05 +0000697#if SIZEOF_LONG > 4
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000698 /* Sign extension for 64-bit machines */
699 x |= -(x & 0x80000000L);
Just van Rossum52e14d62002-12-30 22:08:05 +0000700#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000701 return x;
Just van Rossum52e14d62002-12-30 22:08:05 +0000702}
703
704/*
705 read_directory(archive) -> files dict (new reference)
706
707 Given a path to a Zip archive, build a dict, mapping file names
708 (local to the archive, using SEP as a separator) to toc entries.
709
710 A toc_entry is a tuple:
711
Victor Stinner08654e12010-10-18 12:09:02 +0000712 (__file__, # value to use for __file__, available for all files,
713 # encoded to the filesystem encoding
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000714 compress, # compression kind; 0 for uncompressed
715 data_size, # size of compressed data on disk
716 file_size, # size of decompressed data
717 file_offset, # offset of file header from start of archive
718 time, # mod time of file (in dos format)
719 date, # mod data of file (in dos format)
720 crc, # crc checksum of the data
Victor Stinnerc342fca2010-10-18 11:39:05 +0000721 )
Just van Rossum52e14d62002-12-30 22:08:05 +0000722
723 Directories can be recognized by the trailing SEP in the name,
724 data_size and file_offset are 0.
725*/
726static PyObject *
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400727read_directory(PyObject *archive)
Just van Rossum52e14d62002-12-30 22:08:05 +0000728{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000729 PyObject *files = NULL;
730 FILE *fp;
Victor Stinnerd36c8212010-10-18 12:13:46 +0000731 unsigned short flags;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000732 long compress, crc, data_size, file_size, file_offset, date, time;
733 long header_offset, name_size, header_size, header_position;
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];
739 long arc_offset; /* offset from beginning of file to start of 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 Stinnerf6b563a2011-03-14 20:46:50 -0400746 PyErr_Format(ZipImportError, "can't open Zip file: %R", archive);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000747 return NULL;
748 }
749 fseek(fp, -22, SEEK_END);
750 header_position = ftell(fp);
751 if (fread(endof_central_dir, 1, 22, fp) != 22) {
752 fclose(fp);
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400753 PyErr_Format(ZipImportError, "can't read Zip file: %R", archive);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000754 return NULL;
755 }
756 if (get_long((unsigned char *)endof_central_dir) != 0x06054B50) {
757 /* Bad: End of Central Dir signature */
758 fclose(fp);
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400759 PyErr_Format(ZipImportError, "not a Zip file: %R", archive);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000760 return NULL;
761 }
Just van Rossum52e14d62002-12-30 22:08:05 +0000762
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000763 header_size = get_long((unsigned char *)endof_central_dir + 12);
764 header_offset = get_long((unsigned char *)endof_central_dir + 16);
765 arc_offset = header_position - header_offset - header_size;
766 header_offset += arc_offset;
Just van Rossum52e14d62002-12-30 22:08:05 +0000767
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000768 files = PyDict_New();
769 if (files == NULL)
770 goto error;
Just van Rossum52e14d62002-12-30 22:08:05 +0000771
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000772 /* Start of Central Directory */
773 count = 0;
774 for (;;) {
775 PyObject *t;
776 int err;
Just van Rossum52e14d62002-12-30 22:08:05 +0000777
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000778 fseek(fp, header_offset, 0); /* Start of file header */
779 l = PyMarshal_ReadLongFromFile(fp);
780 if (l != 0x02014B50)
781 break; /* Bad: Central Dir File Header */
Victor Stinnerd36c8212010-10-18 12:13:46 +0000782 fseek(fp, header_offset + 8, 0);
783 flags = (unsigned short)PyMarshal_ReadShortFromFile(fp);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000784 compress = PyMarshal_ReadShortFromFile(fp);
785 time = PyMarshal_ReadShortFromFile(fp);
786 date = PyMarshal_ReadShortFromFile(fp);
787 crc = PyMarshal_ReadLongFromFile(fp);
788 data_size = PyMarshal_ReadLongFromFile(fp);
789 file_size = PyMarshal_ReadLongFromFile(fp);
790 name_size = PyMarshal_ReadShortFromFile(fp);
791 header_size = 46 + name_size +
792 PyMarshal_ReadShortFromFile(fp) +
793 PyMarshal_ReadShortFromFile(fp);
794 fseek(fp, header_offset + 42, 0);
795 file_offset = PyMarshal_ReadLongFromFile(fp) + arc_offset;
796 if (name_size > MAXPATHLEN)
797 name_size = MAXPATHLEN;
Just van Rossum52e14d62002-12-30 22:08:05 +0000798
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000799 p = name;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200800 for (i = 0; i < (Py_ssize_t)name_size; i++) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000801 *p = (char)getc(fp);
802 if (*p == '/')
803 *p = SEP;
804 p++;
805 }
806 *p = 0; /* Add terminating null byte */
807 header_offset += header_size;
Just van Rossum52e14d62002-12-30 22:08:05 +0000808
Victor Stinner4ee65a92011-01-22 10:30:29 +0000809 bootstrap = 0;
Victor Stinnerd36c8212010-10-18 12:13:46 +0000810 if (flags & 0x0800)
811 charset = "utf-8";
Victor Stinner4ee65a92011-01-22 10:30:29 +0000812 else if (!PyThreadState_GET()->interp->codecs_initialized) {
813 /* During bootstrap, we may need to load the encodings
814 package from a ZIP file. But the cp437 encoding is implemented
815 in Python in the encodings package.
816
817 Break out of this dependency by assuming that the path to
818 the encodings module is ASCII-only. */
819 charset = "ascii";
820 bootstrap = 1;
821 }
Victor Stinnerd36c8212010-10-18 12:13:46 +0000822 else
823 charset = "cp437";
824 nameobj = PyUnicode_Decode(name, name_size, charset, NULL);
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200825 if (PyUnicode_READY(nameobj) == -1)
826 goto error;
Victor Stinner4ee65a92011-01-22 10:30:29 +0000827 if (nameobj == NULL) {
828 if (bootstrap)
829 PyErr_Format(PyExc_NotImplementedError,
830 "bootstrap issue: python%i%i.zip contains non-ASCII "
831 "filenames without the unicode flag",
832 PY_MAJOR_VERSION, PY_MINOR_VERSION);
Victor Stinner2460a432010-08-16 17:54:28 +0000833 goto error;
Victor Stinner4ee65a92011-01-22 10:30:29 +0000834 }
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100835 path = PyUnicode_FromFormat("%U%c%U", archive, SEP, nameobj);
836 if (path == NULL)
Victor Stinner2460a432010-08-16 17:54:28 +0000837 goto error;
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100838 t = Py_BuildValue("Niiiiiii", path, compress, data_size,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000839 file_size, file_offset, time, date, crc);
840 if (t == NULL)
841 goto error;
Victor Stinner2460a432010-08-16 17:54:28 +0000842 err = PyDict_SetItem(files, nameobj, t);
843 Py_CLEAR(nameobj);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000844 Py_DECREF(t);
845 if (err != 0)
846 goto error;
847 count++;
848 }
849 fclose(fp);
850 if (Py_VerboseFlag)
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400851 PySys_FormatStderr("# zipimport: found %ld names in %R\n",
852 count, archive);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000853 return files;
Just van Rossum52e14d62002-12-30 22:08:05 +0000854error:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000855 fclose(fp);
856 Py_XDECREF(files);
Victor Stinner2460a432010-08-16 17:54:28 +0000857 Py_XDECREF(nameobj);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000858 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +0000859}
860
861/* Return the zlib.decompress function object, or NULL if zlib couldn't
862 be imported. The function is cached when found, so subsequent calls
Victor Stinner4925cde2011-05-20 00:16:09 +0200863 don't import zlib again. */
Just van Rossum52e14d62002-12-30 22:08:05 +0000864static PyObject *
865get_decompress_func(void)
866{
Victor Stinner4925cde2011-05-20 00:16:09 +0200867 static int importing_zlib = 0;
868 PyObject *zlib;
869 PyObject *decompress;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +0200870 _Py_IDENTIFIER(decompress);
Just van Rossum52e14d62002-12-30 22:08:05 +0000871
Victor Stinner4925cde2011-05-20 00:16:09 +0200872 if (importing_zlib != 0)
873 /* Someone has a zlib.py[co] in their Zip file;
874 let's avoid a stack overflow. */
875 return NULL;
876 importing_zlib = 1;
877 zlib = PyImport_ImportModuleNoBlock("zlib");
878 importing_zlib = 0;
879 if (zlib != NULL) {
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +0200880 decompress = _PyObject_GetAttrId(zlib,
881 &PyId_decompress);
Victor Stinner4925cde2011-05-20 00:16:09 +0200882 Py_DECREF(zlib);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000883 }
Victor Stinner4925cde2011-05-20 00:16:09 +0200884 else {
885 PyErr_Clear();
886 decompress = NULL;
887 }
888 if (Py_VerboseFlag)
889 PySys_WriteStderr("# zipimport: zlib %s\n",
890 zlib != NULL ? "available": "UNAVAILABLE");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000891 return decompress;
Just van Rossum52e14d62002-12-30 22:08:05 +0000892}
893
894/* Given a path to a Zip file and a toc_entry, return the (uncompressed)
895 data as a new reference. */
896static PyObject *
Victor Stinner60fe8d92010-08-16 23:48:11 +0000897get_data(PyObject *archive, PyObject *toc_entry)
Just van Rossum52e14d62002-12-30 22:08:05 +0000898{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000899 PyObject *raw_data, *data = NULL, *decompress;
900 char *buf;
901 FILE *fp;
902 int err;
903 Py_ssize_t bytes_read = 0;
904 long l;
Victor Stinner60fe8d92010-08-16 23:48:11 +0000905 PyObject *datapath;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000906 long compress, data_size, file_size, file_offset, bytes_size;
907 long time, date, crc;
Just van Rossum52e14d62002-12-30 22:08:05 +0000908
Victor Stinner60fe8d92010-08-16 23:48:11 +0000909 if (!PyArg_ParseTuple(toc_entry, "Olllllll", &datapath, &compress,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000910 &data_size, &file_size, &file_offset, &time,
911 &date, &crc)) {
912 return NULL;
913 }
Just van Rossum52e14d62002-12-30 22:08:05 +0000914
Victor Stinner60fe8d92010-08-16 23:48:11 +0000915 fp = _Py_fopen(archive, "rb");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000916 if (!fp) {
917 PyErr_Format(PyExc_IOError,
Victor Stinner60fe8d92010-08-16 23:48:11 +0000918 "zipimport: can not open file %U", archive);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000919 return NULL;
920 }
Just van Rossum52e14d62002-12-30 22:08:05 +0000921
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000922 /* Check to make sure the local file header is correct */
923 fseek(fp, file_offset, 0);
924 l = PyMarshal_ReadLongFromFile(fp);
925 if (l != 0x04034B50) {
926 /* Bad: Local File Header */
927 PyErr_Format(ZipImportError,
Victor Stinner60fe8d92010-08-16 23:48:11 +0000928 "bad local file header in %U",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000929 archive);
930 fclose(fp);
931 return NULL;
932 }
933 fseek(fp, file_offset + 26, 0);
934 l = 30 + PyMarshal_ReadShortFromFile(fp) +
935 PyMarshal_ReadShortFromFile(fp); /* local header size */
936 file_offset += l; /* Start of file data */
Just van Rossum52e14d62002-12-30 22:08:05 +0000937
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000938 bytes_size = compress == 0 ? data_size : data_size + 1;
939 if (bytes_size == 0)
940 bytes_size++;
941 raw_data = PyBytes_FromStringAndSize((char *)NULL, bytes_size);
Just van Rossum52e14d62002-12-30 22:08:05 +0000942
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000943 if (raw_data == NULL) {
944 fclose(fp);
945 return NULL;
946 }
947 buf = PyBytes_AsString(raw_data);
Just van Rossum52e14d62002-12-30 22:08:05 +0000948
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000949 err = fseek(fp, file_offset, 0);
950 if (err == 0)
951 bytes_read = fread(buf, 1, data_size, fp);
952 fclose(fp);
953 if (err || bytes_read != data_size) {
954 PyErr_SetString(PyExc_IOError,
955 "zipimport: can't read data");
956 Py_DECREF(raw_data);
957 return NULL;
958 }
Just van Rossum52e14d62002-12-30 22:08:05 +0000959
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000960 if (compress != 0) {
961 buf[data_size] = 'Z'; /* saw this in zipfile.py */
962 data_size++;
963 }
964 buf[data_size] = '\0';
Just van Rossum52e14d62002-12-30 22:08:05 +0000965
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000966 if (compress == 0) { /* data is not compressed */
967 data = PyBytes_FromStringAndSize(buf, data_size);
968 Py_DECREF(raw_data);
969 return data;
970 }
971
972 /* Decompress with zlib */
973 decompress = get_decompress_func();
974 if (decompress == NULL) {
975 PyErr_SetString(ZipImportError,
976 "can't decompress data; "
977 "zlib not available");
978 goto error;
979 }
980 data = PyObject_CallFunction(decompress, "Oi", raw_data, -15);
Victor Stinner4925cde2011-05-20 00:16:09 +0200981 Py_DECREF(decompress);
Just van Rossum52e14d62002-12-30 22:08:05 +0000982error:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000983 Py_DECREF(raw_data);
984 return data;
Just van Rossum52e14d62002-12-30 22:08:05 +0000985}
986
987/* Lenient date/time comparison function. The precision of the mtime
988 in the archive is lower than the mtime stored in a .pyc: we
989 must allow a difference of at most one second. */
990static int
991eq_mtime(time_t t1, time_t t2)
992{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000993 time_t d = t1 - t2;
994 if (d < 0)
995 d = -d;
996 /* dostime only stores even seconds, so be lenient */
997 return d <= 1;
Just van Rossum52e14d62002-12-30 22:08:05 +0000998}
999
1000/* Given the contents of a .py[co] file in a buffer, unmarshal the data
1001 and return the code object. Return None if it the magic word doesn't
1002 match (we do this instead of raising an exception as we fall back
1003 to .py if available and we don't want to mask other errors).
1004 Returns a new reference. */
1005static PyObject *
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001006unmarshal_code(PyObject *pathname, PyObject *data, time_t mtime)
Just van Rossum52e14d62002-12-30 22:08:05 +00001007{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001008 PyObject *code;
1009 char *buf = PyBytes_AsString(data);
1010 Py_ssize_t size = PyBytes_Size(data);
Just van Rossum52e14d62002-12-30 22:08:05 +00001011
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001012 if (size <= 9) {
1013 PyErr_SetString(ZipImportError,
1014 "bad pyc data");
1015 return NULL;
1016 }
Just van Rossum52e14d62002-12-30 22:08:05 +00001017
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001018 if (get_long((unsigned char *)buf) != PyImport_GetMagicNumber()) {
1019 if (Py_VerboseFlag)
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001020 PySys_FormatStderr("# %R has bad magic\n",
1021 pathname);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001022 Py_INCREF(Py_None);
1023 return Py_None; /* signal caller to try alternative */
1024 }
Just van Rossum52e14d62002-12-30 22:08:05 +00001025
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001026 if (mtime != 0 && !eq_mtime(get_long((unsigned char *)buf + 4),
1027 mtime)) {
1028 if (Py_VerboseFlag)
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001029 PySys_FormatStderr("# %R has bad mtime\n",
1030 pathname);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001031 Py_INCREF(Py_None);
1032 return Py_None; /* signal caller to try alternative */
1033 }
Just van Rossum52e14d62002-12-30 22:08:05 +00001034
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001035 code = PyMarshal_ReadObjectFromString(buf + 8, size - 8);
1036 if (code == NULL)
1037 return NULL;
1038 if (!PyCode_Check(code)) {
1039 Py_DECREF(code);
1040 PyErr_Format(PyExc_TypeError,
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001041 "compiled module %R is not a code object",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001042 pathname);
1043 return NULL;
1044 }
1045 return code;
Just van Rossum52e14d62002-12-30 22:08:05 +00001046}
1047
1048/* Replace any occurances of "\r\n?" in the input string with "\n".
1049 This converts DOS and Mac line endings to Unix line endings.
1050 Also append a trailing "\n" to be compatible with
1051 PyParser_SimpleParseFile(). Returns a new reference. */
1052static PyObject *
1053normalize_line_endings(PyObject *source)
1054{
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001055 char *buf, *q, *p;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001056 PyObject *fixed_source;
1057 int len = 0;
Just van Rossum52e14d62002-12-30 22:08:05 +00001058
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001059 p = PyBytes_AsString(source);
1060 if (p == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001061 return PyBytes_FromStringAndSize("\n\0", 2);
1062 }
Thomas Wouters00ee7ba2006-08-21 19:07:27 +00001063
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001064 /* one char extra for trailing \n and one for terminating \0 */
1065 buf = (char *)PyMem_Malloc(PyBytes_Size(source) + 2);
1066 if (buf == NULL) {
1067 PyErr_SetString(PyExc_MemoryError,
1068 "zipimport: no memory to allocate "
1069 "source buffer");
1070 return NULL;
1071 }
1072 /* replace "\r\n?" by "\n" */
1073 for (q = buf; *p != '\0'; p++) {
1074 if (*p == '\r') {
1075 *q++ = '\n';
1076 if (*(p + 1) == '\n')
1077 p++;
1078 }
1079 else
1080 *q++ = *p;
1081 len++;
1082 }
1083 *q++ = '\n'; /* add trailing \n */
1084 *q = '\0';
1085 fixed_source = PyBytes_FromStringAndSize(buf, len + 2);
1086 PyMem_Free(buf);
1087 return fixed_source;
Just van Rossum52e14d62002-12-30 22:08:05 +00001088}
1089
1090/* Given a string buffer containing Python source code, compile it
1091 return and return a code object as a new reference. */
1092static PyObject *
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001093compile_source(PyObject *pathname, PyObject *source)
Just van Rossum52e14d62002-12-30 22:08:05 +00001094{
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001095 PyObject *code, *fixed_source, *pathbytes;
Just van Rossum52e14d62002-12-30 22:08:05 +00001096
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001097 pathbytes = PyUnicode_EncodeFSDefault(pathname);
1098 if (pathbytes == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001099 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +00001100
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001101 fixed_source = normalize_line_endings(source);
1102 if (fixed_source == NULL) {
1103 Py_DECREF(pathbytes);
1104 return NULL;
1105 }
1106
1107 code = Py_CompileString(PyBytes_AsString(fixed_source),
1108 PyBytes_AsString(pathbytes),
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001109 Py_file_input);
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001110 Py_DECREF(pathbytes);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001111 Py_DECREF(fixed_source);
1112 return code;
Just van Rossum52e14d62002-12-30 22:08:05 +00001113}
1114
1115/* Convert the date/time values found in the Zip archive to a value
1116 that's compatible with the time stamp stored in .pyc files. */
Neal Norwitz29fd2ba2003-03-23 13:21:03 +00001117static time_t
1118parse_dostime(int dostime, int dosdate)
Just van Rossum52e14d62002-12-30 22:08:05 +00001119{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001120 struct tm stm;
Just van Rossum52e14d62002-12-30 22:08:05 +00001121
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001122 memset((void *) &stm, '\0', sizeof(stm));
Christian Heimes679db4a2008-01-18 09:56:22 +00001123
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001124 stm.tm_sec = (dostime & 0x1f) * 2;
1125 stm.tm_min = (dostime >> 5) & 0x3f;
1126 stm.tm_hour = (dostime >> 11) & 0x1f;
1127 stm.tm_mday = dosdate & 0x1f;
1128 stm.tm_mon = ((dosdate >> 5) & 0x0f) - 1;
1129 stm.tm_year = ((dosdate >> 9) & 0x7f) + 80;
1130 stm.tm_isdst = -1; /* wday/yday is ignored */
Just van Rossum52e14d62002-12-30 22:08:05 +00001131
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001132 return mktime(&stm);
Just van Rossum52e14d62002-12-30 22:08:05 +00001133}
1134
1135/* Given a path to a .pyc or .pyo file in the archive, return the
Ezio Melotti13925002011-03-16 11:05:33 +02001136 modification time of the matching .py file, or 0 if no source
Just van Rossum52e14d62002-12-30 22:08:05 +00001137 is available. */
1138static time_t
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001139get_mtime_of_source(ZipImporter *self, PyObject *path)
Just van Rossum52e14d62002-12-30 22:08:05 +00001140{
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001141 PyObject *toc_entry, *stripped;
1142 time_t mtime;
1143
1144 /* strip 'c' or 'o' from *.py[co] */
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001145 if (PyUnicode_READY(path) == -1)
1146 return (time_t)-1;
1147 stripped = PyUnicode_FromKindAndData(PyUnicode_KIND(path),
1148 PyUnicode_DATA(path),
1149 PyUnicode_GET_LENGTH(path) - 1);
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001150 if (stripped == NULL)
1151 return (time_t)-1;
1152
1153 toc_entry = PyDict_GetItem(self->files, stripped);
1154 Py_DECREF(stripped);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001155 if (toc_entry != NULL && PyTuple_Check(toc_entry) &&
1156 PyTuple_Size(toc_entry) == 8) {
1157 /* fetch the time stamp of the .py file for comparison
1158 with an embedded pyc time stamp */
1159 int time, date;
1160 time = PyLong_AsLong(PyTuple_GetItem(toc_entry, 5));
1161 date = PyLong_AsLong(PyTuple_GetItem(toc_entry, 6));
1162 mtime = parse_dostime(time, date);
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001163 } else
1164 mtime = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001165 return mtime;
Just van Rossum52e14d62002-12-30 22:08:05 +00001166}
1167
1168/* Return the code object for the module named by 'fullname' from the
1169 Zip archive as a new reference. */
1170static PyObject *
1171get_code_from_data(ZipImporter *self, int ispackage, int isbytecode,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001172 time_t mtime, PyObject *toc_entry)
Just van Rossum52e14d62002-12-30 22:08:05 +00001173{
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001174 PyObject *data, *modpath, *code;
Just van Rossum52e14d62002-12-30 22:08:05 +00001175
Victor Stinner60fe8d92010-08-16 23:48:11 +00001176 data = get_data(self->archive, toc_entry);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001177 if (data == NULL)
1178 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +00001179
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001180 modpath = PyTuple_GetItem(toc_entry, 0);
Victor Stinner2a94f4c2010-10-18 12:15:34 +00001181 if (isbytecode)
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001182 code = unmarshal_code(modpath, data, mtime);
Victor Stinner2a94f4c2010-10-18 12:15:34 +00001183 else
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001184 code = compile_source(modpath, data);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001185 Py_DECREF(data);
1186 return code;
Just van Rossum52e14d62002-12-30 22:08:05 +00001187}
1188
Ezio Melotti42da6632011-03-15 05:18:48 +02001189/* Get the code object associated with the module specified by
Just van Rossum52e14d62002-12-30 22:08:05 +00001190 'fullname'. */
1191static PyObject *
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001192get_module_code(ZipImporter *self, PyObject *fullname,
Victor Stinner08654e12010-10-18 12:09:02 +00001193 int *p_ispackage, PyObject **p_modpath)
Just van Rossum52e14d62002-12-30 22:08:05 +00001194{
Gregory P. Smith95c7c462011-05-21 05:19:42 -07001195 PyObject *code = NULL, *toc_entry, *subname;
Victor Stinner9a2261a2011-05-26 13:59:41 +02001196 PyObject *path, *fullpath = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001197 struct st_zip_searchorder *zso;
Just van Rossum52e14d62002-12-30 22:08:05 +00001198
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001199 subname = get_subname(fullname);
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001200 if (subname == NULL)
1201 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +00001202
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001203 path = make_filename(self->prefix, subname);
1204 Py_DECREF(subname);
1205 if (path == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001206 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +00001207
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001208 for (zso = zip_searchorder; *zso->suffix; zso++) {
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001209 code = NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +00001210
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001211 fullpath = PyUnicode_FromFormat("%U%s", path, zso->suffix);
1212 if (fullpath == NULL)
1213 goto exit;
1214
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001215 if (Py_VerboseFlag > 1)
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001216 PySys_FormatStderr("# trying %U%c%U\n",
1217 self->archive, (int)SEP, fullpath);
1218 toc_entry = PyDict_GetItem(self->files, fullpath);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001219 if (toc_entry != NULL) {
1220 time_t mtime = 0;
1221 int ispackage = zso->type & IS_PACKAGE;
1222 int isbytecode = zso->type & IS_BYTECODE;
Just van Rossum52e14d62002-12-30 22:08:05 +00001223
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001224 if (isbytecode) {
1225 mtime = get_mtime_of_source(self, fullpath);
1226 if (mtime == (time_t)-1 && PyErr_Occurred()) {
1227 goto exit;
1228 }
1229 }
1230 Py_CLEAR(fullpath);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001231 if (p_ispackage != NULL)
1232 *p_ispackage = ispackage;
1233 code = get_code_from_data(self, ispackage,
1234 isbytecode, mtime,
1235 toc_entry);
1236 if (code == Py_None) {
1237 /* bad magic number or non-matching mtime
1238 in byte code, try next */
1239 Py_DECREF(code);
1240 continue;
1241 }
Victor Stinner08654e12010-10-18 12:09:02 +00001242 if (code != NULL && p_modpath != NULL) {
1243 *p_modpath = PyTuple_GetItem(toc_entry, 0);
1244 Py_INCREF(*p_modpath);
1245 }
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001246 goto exit;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001247 }
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001248 else
1249 Py_CLEAR(fullpath);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001250 }
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001251 PyErr_Format(ZipImportError, "can't find module %R", fullname);
1252exit:
1253 Py_DECREF(path);
1254 Py_XDECREF(fullpath);
1255 return code;
Just van Rossum52e14d62002-12-30 22:08:05 +00001256}
1257
1258
1259/* Module init */
1260
1261PyDoc_STRVAR(zipimport_doc,
1262"zipimport provides support for importing Python modules from Zip archives.\n\
1263\n\
1264This module exports three objects:\n\
1265- zipimporter: a class; its constructor takes a path to a Zip archive.\n\
Fredrik Lundhb84b35f2006-01-15 15:00:40 +00001266- ZipImportError: exception raised by zipimporter objects. It's a\n\
Just van Rossum52e14d62002-12-30 22:08:05 +00001267 subclass of ImportError, so it can be caught as ImportError, too.\n\
1268- _zip_directory_cache: a dict, mapping archive paths to zip directory\n\
1269 info dicts, as used in zipimporter._files.\n\
1270\n\
1271It is usually not needed to use the zipimport module explicitly; it is\n\
1272used by the builtin import mechanism for sys.path items that are paths\n\
1273to Zip archives.");
1274
Martin v. Löwis1a214512008-06-11 05:26:20 +00001275static struct PyModuleDef zipimportmodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001276 PyModuleDef_HEAD_INIT,
1277 "zipimport",
1278 zipimport_doc,
1279 -1,
1280 NULL,
1281 NULL,
1282 NULL,
1283 NULL,
1284 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +00001285};
1286
Just van Rossum52e14d62002-12-30 22:08:05 +00001287PyMODINIT_FUNC
Martin v. Löwis1a214512008-06-11 05:26:20 +00001288PyInit_zipimport(void)
Just van Rossum52e14d62002-12-30 22:08:05 +00001289{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001290 PyObject *mod;
Just van Rossum52e14d62002-12-30 22:08:05 +00001291
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001292 if (PyType_Ready(&ZipImporter_Type) < 0)
1293 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +00001294
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001295 /* Correct directory separator */
1296 zip_searchorder[0].suffix[0] = SEP;
1297 zip_searchorder[1].suffix[0] = SEP;
1298 zip_searchorder[2].suffix[0] = SEP;
1299 if (Py_OptimizeFlag) {
1300 /* Reverse *.pyc and *.pyo */
1301 struct st_zip_searchorder tmp;
1302 tmp = zip_searchorder[0];
1303 zip_searchorder[0] = zip_searchorder[1];
1304 zip_searchorder[1] = tmp;
1305 tmp = zip_searchorder[3];
1306 zip_searchorder[3] = zip_searchorder[4];
1307 zip_searchorder[4] = tmp;
1308 }
Just van Rossum52e14d62002-12-30 22:08:05 +00001309
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001310 mod = PyModule_Create(&zipimportmodule);
1311 if (mod == NULL)
1312 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +00001313
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001314 ZipImportError = PyErr_NewException("zipimport.ZipImportError",
1315 PyExc_ImportError, NULL);
1316 if (ZipImportError == NULL)
1317 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +00001318
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001319 Py_INCREF(ZipImportError);
1320 if (PyModule_AddObject(mod, "ZipImportError",
1321 ZipImportError) < 0)
1322 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +00001323
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001324 Py_INCREF(&ZipImporter_Type);
1325 if (PyModule_AddObject(mod, "zipimporter",
1326 (PyObject *)&ZipImporter_Type) < 0)
1327 return NULL;
Just van Rossumf8b6de12002-12-31 09:51:59 +00001328
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001329 zip_directory_cache = PyDict_New();
1330 if (zip_directory_cache == NULL)
1331 return NULL;
1332 Py_INCREF(zip_directory_cache);
1333 if (PyModule_AddObject(mod, "_zip_directory_cache",
1334 zip_directory_cache) < 0)
1335 return NULL;
1336 return mod;
Just van Rossum52e14d62002-12-30 22:08:05 +00001337}