blob: 0a0a778664b365c92ee0a41bbb20d7f786e89d30 [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
38 PyObject *archive; /* pathname of the Zip archive */
39 PyObject *prefix; /* file prefix: "a/sub/directory/" */
40 PyObject *files; /* dict with file info {path: toc_entry} */
Just van Rossum52e14d62002-12-30 22:08:05 +000041};
42
Just van Rossum52e14d62002-12-30 22:08:05 +000043static PyObject *ZipImportError;
Victor Stinnerc342fca2010-10-18 11:39:05 +000044/* read_directory() cache */
Just van Rossum52e14d62002-12-30 22:08:05 +000045static PyObject *zip_directory_cache = NULL;
46
47/* forward decls */
Victor Stinner2460a432010-08-16 17:54:28 +000048static PyObject *read_directory(PyObject *archive);
Victor Stinner60fe8d92010-08-16 23:48:11 +000049static PyObject *get_data(PyObject *archive, PyObject *toc_entry);
Just van Rossum52e14d62002-12-30 22:08:05 +000050static PyObject *get_module_code(ZipImporter *self, char *fullname,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000051 int *p_ispackage, char **p_modpath);
Just van Rossum52e14d62002-12-30 22:08:05 +000052
53
54#define ZipImporter_Check(op) PyObject_TypeCheck(op, &ZipImporter_Type)
55
56
57/* zipimporter.__init__
58 Split the "subdirectory" from the Zip archive path, lookup a matching
59 entry in sys.path_importer_cache, fetch the file directory from there
60 if found, or else read it from the archive. */
61static int
62zipimporter_init(ZipImporter *self, PyObject *args, PyObject *kwds)
63{
Victor Stinner2460a432010-08-16 17:54:28 +000064 PyObject *pathobj, *files;
Victor Stinner2b8dab72010-08-14 14:54:10 +000065 Py_UNICODE *path, *p, *prefix, buf[MAXPATHLEN+2];
66 Py_ssize_t len;
Just van Rossum52e14d62002-12-30 22:08:05 +000067
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000068 if (!_PyArg_NoKeywords("zipimporter()", kwds))
69 return -1;
Georg Brandl02c42872005-08-26 06:42:30 +000070
Victor Stinner2b8dab72010-08-14 14:54:10 +000071 if (!PyArg_ParseTuple(args, "O&:zipimporter",
72 PyUnicode_FSDecoder, &pathobj))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000073 return -1;
Just van Rossum52e14d62002-12-30 22:08:05 +000074
Victor Stinner2b8dab72010-08-14 14:54:10 +000075 /* copy path to buf */
76 len = PyUnicode_GET_SIZE(pathobj);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000077 if (len == 0) {
78 PyErr_SetString(ZipImportError, "archive path is empty");
Victor Stinner2b8dab72010-08-14 14:54:10 +000079 goto error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000080 }
81 if (len >= MAXPATHLEN) {
82 PyErr_SetString(ZipImportError,
83 "archive path too long");
Victor Stinner2b8dab72010-08-14 14:54:10 +000084 goto error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000085 }
Victor Stinner2b8dab72010-08-14 14:54:10 +000086 Py_UNICODE_strcpy(buf, PyUnicode_AS_UNICODE(pathobj));
Just van Rossum52e14d62002-12-30 22:08:05 +000087
88#ifdef ALTSEP
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000089 for (p = buf; *p; p++) {
90 if (*p == ALTSEP)
91 *p = SEP;
92 }
Just van Rossum52e14d62002-12-30 22:08:05 +000093#endif
94
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000095 path = NULL;
96 prefix = NULL;
97 for (;;) {
98 struct stat statbuf;
99 int rv;
Just van Rossum52e14d62002-12-30 22:08:05 +0000100
Victor Stinner2b8dab72010-08-14 14:54:10 +0000101 if (pathobj == NULL) {
102 pathobj = PyUnicode_FromUnicode(buf, len);
103 if (pathobj == NULL)
104 goto error;
105 }
106 rv = _Py_stat(pathobj, &statbuf);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000107 if (rv == 0) {
108 /* it exists */
109 if (S_ISREG(statbuf.st_mode))
110 /* it's a file */
111 path = buf;
112 break;
113 }
Victor Stinner2b8dab72010-08-14 14:54:10 +0000114 else if (PyErr_Occurred())
115 goto error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000116 /* back up one path element */
Victor Stinner2b8dab72010-08-14 14:54:10 +0000117 p = Py_UNICODE_strrchr(buf, SEP);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000118 if (prefix != NULL)
119 *prefix = SEP;
120 if (p == NULL)
121 break;
122 *p = '\0';
Victor Stinner2b8dab72010-08-14 14:54:10 +0000123 len = p - buf;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000124 prefix = p;
Victor Stinner2b8dab72010-08-14 14:54:10 +0000125 Py_CLEAR(pathobj);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000126 }
Victor Stinner2b8dab72010-08-14 14:54:10 +0000127 if (path == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000128 PyErr_SetString(ZipImportError, "not a Zip file");
Victor Stinner2b8dab72010-08-14 14:54:10 +0000129 goto error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000130 }
Just van Rossum52e14d62002-12-30 22:08:05 +0000131
Victor Stinner2b8dab72010-08-14 14:54:10 +0000132 files = PyDict_GetItem(zip_directory_cache, pathobj);
133 if (files == NULL) {
Victor Stinner2460a432010-08-16 17:54:28 +0000134 files = read_directory(pathobj);
Victor Stinner2b8dab72010-08-14 14:54:10 +0000135 if (files == NULL)
136 goto error;
137 if (PyDict_SetItem(zip_directory_cache, pathobj, files) != 0)
138 goto error;
139 }
140 else
141 Py_INCREF(files);
142 self->files = files;
143
144 self->archive = pathobj;
145 pathobj = NULL;
146
147 if (prefix != NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000148 prefix++;
Victor Stinner2b8dab72010-08-14 14:54:10 +0000149 len = Py_UNICODE_strlen(prefix);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000150 if (prefix[len-1] != SEP) {
151 /* add trailing SEP */
152 prefix[len] = SEP;
153 prefix[len + 1] = '\0';
Victor Stinner2b8dab72010-08-14 14:54:10 +0000154 len++;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000155 }
156 }
Victor Stinner2b8dab72010-08-14 14:54:10 +0000157 else
158 len = 0;
159 self->prefix = PyUnicode_FromUnicode(prefix, len);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000160 if (self->prefix == NULL)
Victor Stinner2b8dab72010-08-14 14:54:10 +0000161 goto error;
Just van Rossum52e14d62002-12-30 22:08:05 +0000162
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000163 return 0;
Victor Stinner2b8dab72010-08-14 14:54:10 +0000164
165error:
166 Py_XDECREF(pathobj);
167 return -1;
Just van Rossum52e14d62002-12-30 22:08:05 +0000168}
169
170/* GC support. */
171static int
172zipimporter_traverse(PyObject *obj, visitproc visit, void *arg)
173{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000174 ZipImporter *self = (ZipImporter *)obj;
175 Py_VISIT(self->files);
176 return 0;
Just van Rossum52e14d62002-12-30 22:08:05 +0000177}
178
179static void
180zipimporter_dealloc(ZipImporter *self)
181{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000182 PyObject_GC_UnTrack(self);
183 Py_XDECREF(self->archive);
184 Py_XDECREF(self->prefix);
185 Py_XDECREF(self->files);
186 Py_TYPE(self)->tp_free((PyObject *)self);
Just van Rossum52e14d62002-12-30 22:08:05 +0000187}
188
189static PyObject *
190zipimporter_repr(ZipImporter *self)
191{
Victor Stinner028dd972010-08-17 00:04:48 +0000192 if (self->archive == NULL)
193 return PyUnicode_FromString("<zipimporter object \"???\">");
194 else if (self->prefix != NULL && PyUnicode_GET_SIZE(self->prefix) != 0)
195 return PyUnicode_FromFormat("<zipimporter object \"%.300U%c%.150U\">",
196 self->archive, SEP, self->prefix);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000197 else
Victor Stinner028dd972010-08-17 00:04:48 +0000198 return PyUnicode_FromFormat("<zipimporter object \"%.300U\">",
199 self->archive);
Just van Rossum52e14d62002-12-30 22:08:05 +0000200}
201
202/* return fullname.split(".")[-1] */
203static char *
204get_subname(char *fullname)
205{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000206 char *subname = strrchr(fullname, '.');
207 if (subname == NULL)
208 subname = fullname;
209 else
210 subname++;
211 return subname;
Just van Rossum52e14d62002-12-30 22:08:05 +0000212}
213
214/* Given a (sub)modulename, write the potential file path in the
215 archive (without extension) to the path buffer. Return the
216 length of the resulting string. */
217static int
218make_filename(char *prefix, char *name, char *path)
219{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000220 size_t len;
221 char *p;
Just van Rossum52e14d62002-12-30 22:08:05 +0000222
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000223 len = strlen(prefix);
Just van Rossum52e14d62002-12-30 22:08:05 +0000224
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000225 /* self.prefix + name [+ SEP + "__init__"] + ".py[co]" */
226 if (len + strlen(name) + 13 >= MAXPATHLEN) {
227 PyErr_SetString(ZipImportError, "path too long");
228 return -1;
229 }
Just van Rossum52e14d62002-12-30 22:08:05 +0000230
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000231 strcpy(path, prefix);
232 strcpy(path + len, name);
233 for (p = path + len; *p; p++) {
234 if (*p == '.')
235 *p = SEP;
236 }
237 len += strlen(name);
238 assert(len < INT_MAX);
239 return (int)len;
Just van Rossum52e14d62002-12-30 22:08:05 +0000240}
241
Raymond Hettinger2c45c9a2004-11-10 13:08:35 +0000242enum zi_module_info {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000243 MI_ERROR,
244 MI_NOT_FOUND,
245 MI_MODULE,
246 MI_PACKAGE
Just van Rossum52e14d62002-12-30 22:08:05 +0000247};
248
249/* Return some information about a module. */
Raymond Hettinger2c45c9a2004-11-10 13:08:35 +0000250static enum zi_module_info
Just van Rossum52e14d62002-12-30 22:08:05 +0000251get_module_info(ZipImporter *self, char *fullname)
252{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000253 char *subname, path[MAXPATHLEN + 1];
254 int len;
255 struct st_zip_searchorder *zso;
Just van Rossum52e14d62002-12-30 22:08:05 +0000256
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000257 subname = get_subname(fullname);
Just van Rossum52e14d62002-12-30 22:08:05 +0000258
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000259 len = make_filename(_PyUnicode_AsString(self->prefix), subname, path);
260 if (len < 0)
261 return MI_ERROR;
Just van Rossum52e14d62002-12-30 22:08:05 +0000262
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000263 for (zso = zip_searchorder; *zso->suffix; zso++) {
264 strcpy(path + len, zso->suffix);
265 if (PyDict_GetItemString(self->files, path) != NULL) {
266 if (zso->type & IS_PACKAGE)
267 return MI_PACKAGE;
268 else
269 return MI_MODULE;
270 }
271 }
272 return MI_NOT_FOUND;
Just van Rossum52e14d62002-12-30 22:08:05 +0000273}
274
275/* Check whether we can satisfy the import of the module named by
276 'fullname'. Return self if we can, None if we can't. */
277static PyObject *
278zipimporter_find_module(PyObject *obj, PyObject *args)
279{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000280 ZipImporter *self = (ZipImporter *)obj;
281 PyObject *path = NULL;
282 char *fullname;
283 enum zi_module_info mi;
Just van Rossum52e14d62002-12-30 22:08:05 +0000284
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000285 if (!PyArg_ParseTuple(args, "s|O:zipimporter.find_module",
286 &fullname, &path))
287 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +0000288
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000289 mi = get_module_info(self, fullname);
290 if (mi == MI_ERROR)
291 return NULL;
292 if (mi == MI_NOT_FOUND) {
293 Py_INCREF(Py_None);
294 return Py_None;
295 }
296 Py_INCREF(self);
297 return (PyObject *)self;
Just van Rossum52e14d62002-12-30 22:08:05 +0000298}
299
300/* Load and return the module named by 'fullname'. */
301static PyObject *
302zipimporter_load_module(PyObject *obj, PyObject *args)
303{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000304 ZipImporter *self = (ZipImporter *)obj;
305 PyObject *code, *mod, *dict;
306 char *fullname, *modpath;
307 int ispackage;
Just van Rossum52e14d62002-12-30 22:08:05 +0000308
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000309 if (!PyArg_ParseTuple(args, "s:zipimporter.load_module",
310 &fullname))
311 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +0000312
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000313 code = get_module_code(self, fullname, &ispackage, &modpath);
314 if (code == NULL)
315 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +0000316
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000317 mod = PyImport_AddModule(fullname);
318 if (mod == NULL) {
319 Py_DECREF(code);
320 return NULL;
321 }
322 dict = PyModule_GetDict(mod);
Just van Rossum52e14d62002-12-30 22:08:05 +0000323
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000324 /* mod.__loader__ = self */
325 if (PyDict_SetItemString(dict, "__loader__", (PyObject *)self) != 0)
326 goto error;
Just van Rossum52e14d62002-12-30 22:08:05 +0000327
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000328 if (ispackage) {
329 /* add __path__ to the module *before* the code gets
330 executed */
331 PyObject *pkgpath, *fullpath;
332 char *subname = get_subname(fullname);
333 int err;
Just van Rossum52e14d62002-12-30 22:08:05 +0000334
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000335 fullpath = PyUnicode_FromFormat("%U%c%U%s",
336 self->archive, SEP,
337 self->prefix, subname);
338 if (fullpath == NULL)
339 goto error;
Just van Rossum52e14d62002-12-30 22:08:05 +0000340
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000341 pkgpath = Py_BuildValue("[O]", fullpath);
342 Py_DECREF(fullpath);
343 if (pkgpath == NULL)
344 goto error;
345 err = PyDict_SetItemString(dict, "__path__", pkgpath);
346 Py_DECREF(pkgpath);
347 if (err != 0)
348 goto error;
349 }
350 mod = PyImport_ExecCodeModuleEx(fullname, code, modpath);
351 Py_DECREF(code);
352 if (Py_VerboseFlag)
353 PySys_WriteStderr("import %s # loaded from Zip %s\n",
354 fullname, modpath);
355 return mod;
Just van Rossum52e14d62002-12-30 22:08:05 +0000356error:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000357 Py_DECREF(code);
358 Py_DECREF(mod);
359 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +0000360}
361
Nick Coghlanf088e5e2008-12-14 11:50:48 +0000362/* Return a string matching __file__ for the named module */
363static PyObject *
364zipimporter_get_filename(PyObject *obj, PyObject *args)
365{
366 ZipImporter *self = (ZipImporter *)obj;
367 PyObject *code;
368 char *fullname, *modpath;
369 int ispackage;
370
Nick Coghlan9a1d6e32009-02-08 03:37:27 +0000371 if (!PyArg_ParseTuple(args, "s:zipimporter.get_filename",
Nick Coghlanf088e5e2008-12-14 11:50:48 +0000372 &fullname))
Victor Stinnerc342fca2010-10-18 11:39:05 +0000373 return NULL;
Nick Coghlanf088e5e2008-12-14 11:50:48 +0000374
375 /* Deciding the filename requires working out where the code
376 would come from if the module was actually loaded */
377 code = get_module_code(self, fullname, &ispackage, &modpath);
378 if (code == NULL)
Victor Stinnerc342fca2010-10-18 11:39:05 +0000379 return NULL;
Nick Coghlanf088e5e2008-12-14 11:50:48 +0000380 Py_DECREF(code); /* Only need the path info */
381
382 return PyUnicode_FromString(modpath);
383}
384
Just van Rossum52e14d62002-12-30 22:08:05 +0000385/* Return a bool signifying whether the module is a package or not. */
386static PyObject *
387zipimporter_is_package(PyObject *obj, PyObject *args)
388{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000389 ZipImporter *self = (ZipImporter *)obj;
390 char *fullname;
391 enum zi_module_info mi;
Just van Rossum52e14d62002-12-30 22:08:05 +0000392
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000393 if (!PyArg_ParseTuple(args, "s:zipimporter.is_package",
394 &fullname))
395 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +0000396
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000397 mi = get_module_info(self, fullname);
398 if (mi == MI_ERROR)
399 return NULL;
400 if (mi == MI_NOT_FOUND) {
401 PyErr_Format(ZipImportError, "can't find module '%.200s'",
402 fullname);
403 return NULL;
404 }
405 return PyBool_FromLong(mi == MI_PACKAGE);
Just van Rossum52e14d62002-12-30 22:08:05 +0000406}
407
408static PyObject *
409zipimporter_get_data(PyObject *obj, PyObject *args)
410{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000411 ZipImporter *self = (ZipImporter *)obj;
Victor Stinner60fe8d92010-08-16 23:48:11 +0000412 PyObject *pathobj, *key;
413 const Py_UNICODE *path;
Just van Rossum52e14d62002-12-30 22:08:05 +0000414#ifdef ALTSEP
Victor Stinner60fe8d92010-08-16 23:48:11 +0000415 Py_UNICODE *p, buf[MAXPATHLEN + 1];
Just van Rossum52e14d62002-12-30 22:08:05 +0000416#endif
Victor Stinner60fe8d92010-08-16 23:48:11 +0000417 Py_UNICODE *archive;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000418 PyObject *toc_entry;
Victor Stinner60fe8d92010-08-16 23:48:11 +0000419 Py_ssize_t path_len, len;
Just van Rossum52e14d62002-12-30 22:08:05 +0000420
Victor Stinner60fe8d92010-08-16 23:48:11 +0000421 if (!PyArg_ParseTuple(args, "U:zipimporter.get_data", &pathobj))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000422 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +0000423
Victor Stinner60fe8d92010-08-16 23:48:11 +0000424 path_len = PyUnicode_GET_SIZE(pathobj);
425 path = PyUnicode_AS_UNICODE(pathobj);
Just van Rossum52e14d62002-12-30 22:08:05 +0000426#ifdef ALTSEP
Victor Stinner60fe8d92010-08-16 23:48:11 +0000427 if (path_len >= MAXPATHLEN) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000428 PyErr_SetString(ZipImportError, "path too long");
429 return NULL;
430 }
Victor Stinner60fe8d92010-08-16 23:48:11 +0000431 Py_UNICODE_strcpy(buf, path);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000432 for (p = buf; *p; p++) {
433 if (*p == ALTSEP)
434 *p = SEP;
435 }
436 path = buf;
Just van Rossum52e14d62002-12-30 22:08:05 +0000437#endif
Victor Stinner60fe8d92010-08-16 23:48:11 +0000438 archive = PyUnicode_AS_UNICODE(self->archive);
439 len = PyUnicode_GET_SIZE(self->archive);
440 if ((size_t)len < Py_UNICODE_strlen(path) &&
441 Py_UNICODE_strncmp(path, archive, len) == 0 &&
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000442 path[len] == SEP) {
Victor Stinner60fe8d92010-08-16 23:48:11 +0000443 path += len + 1;
444 path_len -= len + 1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000445 }
Just van Rossum52e14d62002-12-30 22:08:05 +0000446
Victor Stinner60fe8d92010-08-16 23:48:11 +0000447 key = PyUnicode_FromUnicode(path, path_len);
448 if (key == NULL)
449 return NULL;
450 toc_entry = PyDict_GetItem(self->files, key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000451 if (toc_entry == NULL) {
Victor Stinner60fe8d92010-08-16 23:48:11 +0000452 PyErr_SetFromErrnoWithFilenameObject(PyExc_IOError, key);
453 Py_DECREF(key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000454 return NULL;
455 }
Victor Stinner60fe8d92010-08-16 23:48:11 +0000456 Py_DECREF(key);
457 return get_data(self->archive, toc_entry);
Just van Rossum52e14d62002-12-30 22:08:05 +0000458}
459
460static PyObject *
461zipimporter_get_code(PyObject *obj, PyObject *args)
462{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000463 ZipImporter *self = (ZipImporter *)obj;
464 char *fullname;
Just van Rossum52e14d62002-12-30 22:08:05 +0000465
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000466 if (!PyArg_ParseTuple(args, "s:zipimporter.get_code", &fullname))
467 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +0000468
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000469 return get_module_code(self, fullname, NULL, NULL);
Just van Rossum52e14d62002-12-30 22:08:05 +0000470}
471
472static PyObject *
473zipimporter_get_source(PyObject *obj, PyObject *args)
474{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000475 ZipImporter *self = (ZipImporter *)obj;
476 PyObject *toc_entry;
477 char *fullname, *subname, path[MAXPATHLEN+1];
478 int len;
479 enum zi_module_info mi;
Just van Rossum52e14d62002-12-30 22:08:05 +0000480
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000481 if (!PyArg_ParseTuple(args, "s:zipimporter.get_source", &fullname))
482 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +0000483
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000484 mi = get_module_info(self, fullname);
485 if (mi == MI_ERROR)
486 return NULL;
487 if (mi == MI_NOT_FOUND) {
488 PyErr_Format(ZipImportError, "can't find module '%.200s'",
489 fullname);
490 return NULL;
491 }
492 subname = get_subname(fullname);
Just van Rossum52e14d62002-12-30 22:08:05 +0000493
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000494 len = make_filename(_PyUnicode_AsString(self->prefix), subname, path);
495 if (len < 0)
496 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +0000497
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000498 if (mi == MI_PACKAGE) {
499 path[len] = SEP;
500 strcpy(path + len + 1, "__init__.py");
501 }
502 else
503 strcpy(path + len, ".py");
Just van Rossum52e14d62002-12-30 22:08:05 +0000504
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000505 toc_entry = PyDict_GetItemString(self->files, path);
506 if (toc_entry != NULL) {
Victor Stinner60fe8d92010-08-16 23:48:11 +0000507 PyObject *res, *bytes;
508 bytes = get_data(self->archive, toc_entry);
509 if (bytes == NULL)
510 return NULL;
511 res = PyUnicode_FromStringAndSize(PyBytes_AS_STRING(bytes),
512 PyBytes_GET_SIZE(bytes));
513 Py_DECREF(bytes);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000514 return res;
515 }
Just van Rossum52e14d62002-12-30 22:08:05 +0000516
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000517 /* we have the module, but no source */
518 Py_INCREF(Py_None);
519 return Py_None;
Just van Rossum52e14d62002-12-30 22:08:05 +0000520}
521
522PyDoc_STRVAR(doc_find_module,
523"find_module(fullname, path=None) -> self or None.\n\
524\n\
525Search for a module specified by 'fullname'. 'fullname' must be the\n\
526fully qualified (dotted) module name. It returns the zipimporter\n\
527instance itself if the module was found, or None if it wasn't.\n\
528The optional 'path' argument is ignored -- it's there for compatibility\n\
529with the importer protocol.");
530
531PyDoc_STRVAR(doc_load_module,
532"load_module(fullname) -> module.\n\
533\n\
534Load the module specified by 'fullname'. 'fullname' must be the\n\
535fully qualified (dotted) module name. It returns the imported\n\
536module, or raises ZipImportError if it wasn't found.");
537
538PyDoc_STRVAR(doc_get_data,
539"get_data(pathname) -> string with file data.\n\
540\n\
541Return the data associated with 'pathname'. Raise IOError if\n\
542the file wasn't found.");
543
544PyDoc_STRVAR(doc_is_package,
545"is_package(fullname) -> bool.\n\
546\n\
547Return True if the module specified by fullname is a package.\n\
Brian Curtin32839732010-07-21 01:44:19 +0000548Raise ZipImportError if the module couldn't be found.");
Just van Rossum52e14d62002-12-30 22:08:05 +0000549
550PyDoc_STRVAR(doc_get_code,
551"get_code(fullname) -> code object.\n\
552\n\
553Return the code object for the specified module. Raise ZipImportError\n\
Brian Curtin32839732010-07-21 01:44:19 +0000554if the module couldn't be found.");
Just van Rossum52e14d62002-12-30 22:08:05 +0000555
556PyDoc_STRVAR(doc_get_source,
557"get_source(fullname) -> source string.\n\
558\n\
559Return the source code for the specified module. Raise ZipImportError\n\
Brian Curtin32839732010-07-21 01:44:19 +0000560if the module couldn't be found, return None if the archive does\n\
Just van Rossum52e14d62002-12-30 22:08:05 +0000561contain the module, but has no source for it.");
562
Nick Coghlanf088e5e2008-12-14 11:50:48 +0000563
564PyDoc_STRVAR(doc_get_filename,
Nick Coghlan9a1d6e32009-02-08 03:37:27 +0000565"get_filename(fullname) -> filename string.\n\
Nick Coghlanf088e5e2008-12-14 11:50:48 +0000566\n\
567Return the filename for the specified module.");
568
Just van Rossum52e14d62002-12-30 22:08:05 +0000569static PyMethodDef zipimporter_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000570 {"find_module", zipimporter_find_module, METH_VARARGS,
571 doc_find_module},
572 {"load_module", zipimporter_load_module, METH_VARARGS,
573 doc_load_module},
574 {"get_data", zipimporter_get_data, METH_VARARGS,
575 doc_get_data},
576 {"get_code", zipimporter_get_code, METH_VARARGS,
577 doc_get_code},
578 {"get_source", zipimporter_get_source, METH_VARARGS,
579 doc_get_source},
580 {"get_filename", zipimporter_get_filename, METH_VARARGS,
581 doc_get_filename},
582 {"is_package", zipimporter_is_package, METH_VARARGS,
583 doc_is_package},
584 {NULL, NULL} /* sentinel */
Just van Rossum52e14d62002-12-30 22:08:05 +0000585};
586
587static PyMemberDef zipimporter_members[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000588 {"archive", T_OBJECT, offsetof(ZipImporter, archive), READONLY},
589 {"prefix", T_OBJECT, offsetof(ZipImporter, prefix), READONLY},
590 {"_files", T_OBJECT, offsetof(ZipImporter, files), READONLY},
591 {NULL}
Just van Rossum52e14d62002-12-30 22:08:05 +0000592};
593
594PyDoc_STRVAR(zipimporter_doc,
595"zipimporter(archivepath) -> zipimporter object\n\
596\n\
597Create a new zipimporter instance. 'archivepath' must be a path to\n\
Alexandre Vassalotti8ae3e052008-05-16 00:41:41 +0000598a zipfile, or to a specific path inside a zipfile. For example, it can be\n\
599'/tmp/myimport.zip', or '/tmp/myimport.zip/mydirectory', if mydirectory is a\n\
600valid directory inside the archive.\n\
601\n\
602'ZipImportError is raised if 'archivepath' doesn't point to a valid Zip\n\
603archive.\n\
604\n\
605The 'archive' attribute of zipimporter objects contains the name of the\n\
606zipfile targeted.");
Just van Rossum52e14d62002-12-30 22:08:05 +0000607
608#define DEFERRED_ADDRESS(ADDR) 0
609
610static PyTypeObject ZipImporter_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000611 PyVarObject_HEAD_INIT(DEFERRED_ADDRESS(&PyType_Type), 0)
612 "zipimport.zipimporter",
613 sizeof(ZipImporter),
614 0, /* tp_itemsize */
615 (destructor)zipimporter_dealloc, /* tp_dealloc */
616 0, /* tp_print */
617 0, /* tp_getattr */
618 0, /* tp_setattr */
619 0, /* tp_reserved */
620 (reprfunc)zipimporter_repr, /* tp_repr */
621 0, /* tp_as_number */
622 0, /* tp_as_sequence */
623 0, /* tp_as_mapping */
624 0, /* tp_hash */
625 0, /* tp_call */
626 0, /* tp_str */
627 PyObject_GenericGetAttr, /* tp_getattro */
628 0, /* tp_setattro */
629 0, /* tp_as_buffer */
630 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE |
631 Py_TPFLAGS_HAVE_GC, /* tp_flags */
632 zipimporter_doc, /* tp_doc */
633 zipimporter_traverse, /* tp_traverse */
634 0, /* tp_clear */
635 0, /* tp_richcompare */
636 0, /* tp_weaklistoffset */
637 0, /* tp_iter */
638 0, /* tp_iternext */
639 zipimporter_methods, /* tp_methods */
640 zipimporter_members, /* tp_members */
641 0, /* tp_getset */
642 0, /* tp_base */
643 0, /* tp_dict */
644 0, /* tp_descr_get */
645 0, /* tp_descr_set */
646 0, /* tp_dictoffset */
647 (initproc)zipimporter_init, /* tp_init */
648 PyType_GenericAlloc, /* tp_alloc */
649 PyType_GenericNew, /* tp_new */
650 PyObject_GC_Del, /* tp_free */
Just van Rossum52e14d62002-12-30 22:08:05 +0000651};
652
653
654/* implementation */
655
Just van Rossum52e14d62002-12-30 22:08:05 +0000656/* Given a buffer, return the long that is represented by the first
657 4 bytes, encoded as little endian. This partially reimplements
658 marshal.c:r_long() */
659static long
660get_long(unsigned char *buf) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000661 long x;
662 x = buf[0];
663 x |= (long)buf[1] << 8;
664 x |= (long)buf[2] << 16;
665 x |= (long)buf[3] << 24;
Just van Rossum52e14d62002-12-30 22:08:05 +0000666#if SIZEOF_LONG > 4
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000667 /* Sign extension for 64-bit machines */
668 x |= -(x & 0x80000000L);
Just van Rossum52e14d62002-12-30 22:08:05 +0000669#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000670 return x;
Just van Rossum52e14d62002-12-30 22:08:05 +0000671}
672
673/*
674 read_directory(archive) -> files dict (new reference)
675
676 Given a path to a Zip archive, build a dict, mapping file names
677 (local to the archive, using SEP as a separator) to toc entries.
678
679 A toc_entry is a tuple:
680
Victor Stinnerc342fca2010-10-18 11:39:05 +0000681 (__file__, # value to use for __file__, available for all files
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000682 compress, # compression kind; 0 for uncompressed
683 data_size, # size of compressed data on disk
684 file_size, # size of decompressed data
685 file_offset, # offset of file header from start of archive
686 time, # mod time of file (in dos format)
687 date, # mod data of file (in dos format)
688 crc, # crc checksum of the data
Victor Stinnerc342fca2010-10-18 11:39:05 +0000689 )
Just van Rossum52e14d62002-12-30 22:08:05 +0000690
691 Directories can be recognized by the trailing SEP in the name,
692 data_size and file_offset are 0.
693*/
694static PyObject *
Victor Stinner2460a432010-08-16 17:54:28 +0000695read_directory(PyObject *archive_obj)
Just van Rossum52e14d62002-12-30 22:08:05 +0000696{
Victor Stinner2460a432010-08-16 17:54:28 +0000697 /* FIXME: work on Py_UNICODE* instead of char* */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000698 PyObject *files = NULL;
699 FILE *fp;
700 long compress, crc, data_size, file_size, file_offset, date, time;
701 long header_offset, name_size, header_size, header_position;
702 long i, l, count;
703 size_t length;
Victor Stinner2460a432010-08-16 17:54:28 +0000704 Py_UNICODE path[MAXPATHLEN + 5];
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000705 char name[MAXPATHLEN + 5];
Victor Stinner2460a432010-08-16 17:54:28 +0000706 PyObject *nameobj = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000707 char *p, endof_central_dir[22];
708 long arc_offset; /* offset from beginning of file to start of zip-archive */
Victor Stinner2460a432010-08-16 17:54:28 +0000709 PyObject *pathobj;
Just van Rossum52e14d62002-12-30 22:08:05 +0000710
Victor Stinner2460a432010-08-16 17:54:28 +0000711 if (PyUnicode_GET_SIZE(archive_obj) > MAXPATHLEN) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000712 PyErr_SetString(PyExc_OverflowError,
713 "Zip path name is too long");
714 return NULL;
715 }
Victor Stinner2460a432010-08-16 17:54:28 +0000716 Py_UNICODE_strcpy(path, PyUnicode_AS_UNICODE(archive_obj));
Just van Rossum52e14d62002-12-30 22:08:05 +0000717
Victor Stinner2460a432010-08-16 17:54:28 +0000718 fp = _Py_fopen(archive_obj, "rb");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000719 if (fp == NULL) {
720 PyErr_Format(ZipImportError, "can't open Zip file: "
Victor Stinner2460a432010-08-16 17:54:28 +0000721 "'%.200U'", archive_obj);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000722 return NULL;
723 }
724 fseek(fp, -22, SEEK_END);
725 header_position = ftell(fp);
726 if (fread(endof_central_dir, 1, 22, fp) != 22) {
727 fclose(fp);
728 PyErr_Format(ZipImportError, "can't read Zip file: "
Victor Stinner2460a432010-08-16 17:54:28 +0000729 "'%.200U'", archive_obj);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000730 return NULL;
731 }
732 if (get_long((unsigned char *)endof_central_dir) != 0x06054B50) {
733 /* Bad: End of Central Dir signature */
734 fclose(fp);
735 PyErr_Format(ZipImportError, "not a Zip file: "
Victor Stinner2460a432010-08-16 17:54:28 +0000736 "'%.200U'", archive_obj);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000737 return NULL;
738 }
Just van Rossum52e14d62002-12-30 22:08:05 +0000739
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000740 header_size = get_long((unsigned char *)endof_central_dir + 12);
741 header_offset = get_long((unsigned char *)endof_central_dir + 16);
742 arc_offset = header_position - header_offset - header_size;
743 header_offset += arc_offset;
Just van Rossum52e14d62002-12-30 22:08:05 +0000744
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000745 files = PyDict_New();
746 if (files == NULL)
747 goto error;
Just van Rossum52e14d62002-12-30 22:08:05 +0000748
Victor Stinner2460a432010-08-16 17:54:28 +0000749 length = Py_UNICODE_strlen(path);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000750 path[length] = SEP;
Just van Rossum52e14d62002-12-30 22:08:05 +0000751
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000752 /* Start of Central Directory */
753 count = 0;
754 for (;;) {
755 PyObject *t;
756 int err;
Just van Rossum52e14d62002-12-30 22:08:05 +0000757
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000758 fseek(fp, header_offset, 0); /* Start of file header */
759 l = PyMarshal_ReadLongFromFile(fp);
760 if (l != 0x02014B50)
761 break; /* Bad: Central Dir File Header */
762 fseek(fp, header_offset + 10, 0);
763 compress = PyMarshal_ReadShortFromFile(fp);
764 time = PyMarshal_ReadShortFromFile(fp);
765 date = PyMarshal_ReadShortFromFile(fp);
766 crc = PyMarshal_ReadLongFromFile(fp);
767 data_size = PyMarshal_ReadLongFromFile(fp);
768 file_size = PyMarshal_ReadLongFromFile(fp);
769 name_size = PyMarshal_ReadShortFromFile(fp);
770 header_size = 46 + name_size +
771 PyMarshal_ReadShortFromFile(fp) +
772 PyMarshal_ReadShortFromFile(fp);
773 fseek(fp, header_offset + 42, 0);
774 file_offset = PyMarshal_ReadLongFromFile(fp) + arc_offset;
775 if (name_size > MAXPATHLEN)
776 name_size = MAXPATHLEN;
Just van Rossum52e14d62002-12-30 22:08:05 +0000777
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000778 p = name;
779 for (i = 0; i < name_size; i++) {
780 *p = (char)getc(fp);
781 if (*p == '/')
782 *p = SEP;
783 p++;
784 }
785 *p = 0; /* Add terminating null byte */
786 header_offset += header_size;
Just van Rossum52e14d62002-12-30 22:08:05 +0000787
Victor Stinner2460a432010-08-16 17:54:28 +0000788 nameobj = PyUnicode_DecodeFSDefaultAndSize(name, name_size);
789 if (nameobj == NULL)
790 goto error;
791 Py_UNICODE_strncpy(path + length + 1, PyUnicode_AS_UNICODE(nameobj), MAXPATHLEN - length - 1);
Just van Rossum52e14d62002-12-30 22:08:05 +0000792
Victor Stinner2460a432010-08-16 17:54:28 +0000793 pathobj = PyUnicode_FromUnicode(path, Py_UNICODE_strlen(path));
794 if (pathobj == NULL)
795 goto error;
796 t = Py_BuildValue("Niiiiiii", pathobj, compress, data_size,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000797 file_size, file_offset, time, date, crc);
798 if (t == NULL)
799 goto error;
Victor Stinner2460a432010-08-16 17:54:28 +0000800 err = PyDict_SetItem(files, nameobj, t);
801 Py_CLEAR(nameobj);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000802 Py_DECREF(t);
803 if (err != 0)
804 goto error;
805 count++;
806 }
807 fclose(fp);
808 if (Py_VerboseFlag)
Victor Stinner2460a432010-08-16 17:54:28 +0000809 PySys_FormatStderr("# zipimport: found %ld names in %U\n",
810 count, archive_obj);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000811 return files;
Just van Rossum52e14d62002-12-30 22:08:05 +0000812error:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000813 fclose(fp);
814 Py_XDECREF(files);
Victor Stinner2460a432010-08-16 17:54:28 +0000815 Py_XDECREF(nameobj);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000816 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +0000817}
818
819/* Return the zlib.decompress function object, or NULL if zlib couldn't
820 be imported. The function is cached when found, so subsequent calls
821 don't import zlib again. Returns a *borrowed* reference.
822 XXX This makes zlib.decompress immortal. */
823static PyObject *
824get_decompress_func(void)
825{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000826 static PyObject *decompress = NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +0000827
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000828 if (decompress == NULL) {
829 PyObject *zlib;
830 static int importing_zlib = 0;
Just van Rossum52e14d62002-12-30 22:08:05 +0000831
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000832 if (importing_zlib != 0)
833 /* Someone has a zlib.py[co] in their Zip file;
834 let's avoid a stack overflow. */
835 return NULL;
836 importing_zlib = 1;
837 zlib = PyImport_ImportModuleNoBlock("zlib");
838 importing_zlib = 0;
839 if (zlib != NULL) {
840 decompress = PyObject_GetAttrString(zlib,
841 "decompress");
842 Py_DECREF(zlib);
843 }
844 else
845 PyErr_Clear();
846 if (Py_VerboseFlag)
847 PySys_WriteStderr("# zipimport: zlib %s\n",
848 zlib != NULL ? "available": "UNAVAILABLE");
849 }
850 return decompress;
Just van Rossum52e14d62002-12-30 22:08:05 +0000851}
852
853/* Given a path to a Zip file and a toc_entry, return the (uncompressed)
854 data as a new reference. */
855static PyObject *
Victor Stinner60fe8d92010-08-16 23:48:11 +0000856get_data(PyObject *archive, PyObject *toc_entry)
Just van Rossum52e14d62002-12-30 22:08:05 +0000857{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000858 PyObject *raw_data, *data = NULL, *decompress;
859 char *buf;
860 FILE *fp;
861 int err;
862 Py_ssize_t bytes_read = 0;
863 long l;
Victor Stinner60fe8d92010-08-16 23:48:11 +0000864 PyObject *datapath;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000865 long compress, data_size, file_size, file_offset, bytes_size;
866 long time, date, crc;
Just van Rossum52e14d62002-12-30 22:08:05 +0000867
Victor Stinner60fe8d92010-08-16 23:48:11 +0000868 if (!PyArg_ParseTuple(toc_entry, "Olllllll", &datapath, &compress,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000869 &data_size, &file_size, &file_offset, &time,
870 &date, &crc)) {
871 return NULL;
872 }
Just van Rossum52e14d62002-12-30 22:08:05 +0000873
Victor Stinner60fe8d92010-08-16 23:48:11 +0000874 fp = _Py_fopen(archive, "rb");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000875 if (!fp) {
876 PyErr_Format(PyExc_IOError,
Victor Stinner60fe8d92010-08-16 23:48:11 +0000877 "zipimport: can not open file %U", archive);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000878 return NULL;
879 }
Just van Rossum52e14d62002-12-30 22:08:05 +0000880
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000881 /* Check to make sure the local file header is correct */
882 fseek(fp, file_offset, 0);
883 l = PyMarshal_ReadLongFromFile(fp);
884 if (l != 0x04034B50) {
885 /* Bad: Local File Header */
886 PyErr_Format(ZipImportError,
Victor Stinner60fe8d92010-08-16 23:48:11 +0000887 "bad local file header in %U",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000888 archive);
889 fclose(fp);
890 return NULL;
891 }
892 fseek(fp, file_offset + 26, 0);
893 l = 30 + PyMarshal_ReadShortFromFile(fp) +
894 PyMarshal_ReadShortFromFile(fp); /* local header size */
895 file_offset += l; /* Start of file data */
Just van Rossum52e14d62002-12-30 22:08:05 +0000896
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000897 bytes_size = compress == 0 ? data_size : data_size + 1;
898 if (bytes_size == 0)
899 bytes_size++;
900 raw_data = PyBytes_FromStringAndSize((char *)NULL, bytes_size);
Just van Rossum52e14d62002-12-30 22:08:05 +0000901
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000902 if (raw_data == NULL) {
903 fclose(fp);
904 return NULL;
905 }
906 buf = PyBytes_AsString(raw_data);
Just van Rossum52e14d62002-12-30 22:08:05 +0000907
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000908 err = fseek(fp, file_offset, 0);
909 if (err == 0)
910 bytes_read = fread(buf, 1, data_size, fp);
911 fclose(fp);
912 if (err || bytes_read != data_size) {
913 PyErr_SetString(PyExc_IOError,
914 "zipimport: can't read data");
915 Py_DECREF(raw_data);
916 return NULL;
917 }
Just van Rossum52e14d62002-12-30 22:08:05 +0000918
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000919 if (compress != 0) {
920 buf[data_size] = 'Z'; /* saw this in zipfile.py */
921 data_size++;
922 }
923 buf[data_size] = '\0';
Just van Rossum52e14d62002-12-30 22:08:05 +0000924
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000925 if (compress == 0) { /* data is not compressed */
926 data = PyBytes_FromStringAndSize(buf, data_size);
927 Py_DECREF(raw_data);
928 return data;
929 }
930
931 /* Decompress with zlib */
932 decompress = get_decompress_func();
933 if (decompress == NULL) {
934 PyErr_SetString(ZipImportError,
935 "can't decompress data; "
936 "zlib not available");
937 goto error;
938 }
939 data = PyObject_CallFunction(decompress, "Oi", raw_data, -15);
Just van Rossum52e14d62002-12-30 22:08:05 +0000940error:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000941 Py_DECREF(raw_data);
942 return data;
Just van Rossum52e14d62002-12-30 22:08:05 +0000943}
944
945/* Lenient date/time comparison function. The precision of the mtime
946 in the archive is lower than the mtime stored in a .pyc: we
947 must allow a difference of at most one second. */
948static int
949eq_mtime(time_t t1, time_t t2)
950{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000951 time_t d = t1 - t2;
952 if (d < 0)
953 d = -d;
954 /* dostime only stores even seconds, so be lenient */
955 return d <= 1;
Just van Rossum52e14d62002-12-30 22:08:05 +0000956}
957
958/* Given the contents of a .py[co] file in a buffer, unmarshal the data
959 and return the code object. Return None if it the magic word doesn't
960 match (we do this instead of raising an exception as we fall back
961 to .py if available and we don't want to mask other errors).
962 Returns a new reference. */
963static PyObject *
964unmarshal_code(char *pathname, PyObject *data, time_t mtime)
965{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000966 PyObject *code;
967 char *buf = PyBytes_AsString(data);
968 Py_ssize_t size = PyBytes_Size(data);
Just van Rossum52e14d62002-12-30 22:08:05 +0000969
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000970 if (size <= 9) {
971 PyErr_SetString(ZipImportError,
972 "bad pyc data");
973 return NULL;
974 }
Just van Rossum52e14d62002-12-30 22:08:05 +0000975
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000976 if (get_long((unsigned char *)buf) != PyImport_GetMagicNumber()) {
977 if (Py_VerboseFlag)
978 PySys_WriteStderr("# %s has bad magic\n",
979 pathname);
980 Py_INCREF(Py_None);
981 return Py_None; /* signal caller to try alternative */
982 }
Just van Rossum52e14d62002-12-30 22:08:05 +0000983
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000984 if (mtime != 0 && !eq_mtime(get_long((unsigned char *)buf + 4),
985 mtime)) {
986 if (Py_VerboseFlag)
987 PySys_WriteStderr("# %s has bad mtime\n",
988 pathname);
989 Py_INCREF(Py_None);
990 return Py_None; /* signal caller to try alternative */
991 }
Just van Rossum52e14d62002-12-30 22:08:05 +0000992
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000993 code = PyMarshal_ReadObjectFromString(buf + 8, size - 8);
994 if (code == NULL)
995 return NULL;
996 if (!PyCode_Check(code)) {
997 Py_DECREF(code);
998 PyErr_Format(PyExc_TypeError,
999 "compiled module %.200s is not a code object",
1000 pathname);
1001 return NULL;
1002 }
1003 return code;
Just van Rossum52e14d62002-12-30 22:08:05 +00001004}
1005
1006/* Replace any occurances of "\r\n?" in the input string with "\n".
1007 This converts DOS and Mac line endings to Unix line endings.
1008 Also append a trailing "\n" to be compatible with
1009 PyParser_SimpleParseFile(). Returns a new reference. */
1010static PyObject *
1011normalize_line_endings(PyObject *source)
1012{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001013 char *buf, *q, *p = PyBytes_AsString(source);
1014 PyObject *fixed_source;
1015 int len = 0;
Just van Rossum52e14d62002-12-30 22:08:05 +00001016
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001017 if (!p) {
1018 return PyBytes_FromStringAndSize("\n\0", 2);
1019 }
Thomas Wouters00ee7ba2006-08-21 19:07:27 +00001020
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001021 /* one char extra for trailing \n and one for terminating \0 */
1022 buf = (char *)PyMem_Malloc(PyBytes_Size(source) + 2);
1023 if (buf == NULL) {
1024 PyErr_SetString(PyExc_MemoryError,
1025 "zipimport: no memory to allocate "
1026 "source buffer");
1027 return NULL;
1028 }
1029 /* replace "\r\n?" by "\n" */
1030 for (q = buf; *p != '\0'; p++) {
1031 if (*p == '\r') {
1032 *q++ = '\n';
1033 if (*(p + 1) == '\n')
1034 p++;
1035 }
1036 else
1037 *q++ = *p;
1038 len++;
1039 }
1040 *q++ = '\n'; /* add trailing \n */
1041 *q = '\0';
1042 fixed_source = PyBytes_FromStringAndSize(buf, len + 2);
1043 PyMem_Free(buf);
1044 return fixed_source;
Just van Rossum52e14d62002-12-30 22:08:05 +00001045}
1046
1047/* Given a string buffer containing Python source code, compile it
1048 return and return a code object as a new reference. */
1049static PyObject *
1050compile_source(char *pathname, PyObject *source)
1051{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001052 PyObject *code, *fixed_source;
Just van Rossum52e14d62002-12-30 22:08:05 +00001053
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001054 fixed_source = normalize_line_endings(source);
1055 if (fixed_source == NULL)
1056 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +00001057
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001058 code = Py_CompileString(PyBytes_AsString(fixed_source), pathname,
1059 Py_file_input);
1060 Py_DECREF(fixed_source);
1061 return code;
Just van Rossum52e14d62002-12-30 22:08:05 +00001062}
1063
1064/* Convert the date/time values found in the Zip archive to a value
1065 that's compatible with the time stamp stored in .pyc files. */
Neal Norwitz29fd2ba2003-03-23 13:21:03 +00001066static time_t
1067parse_dostime(int dostime, int dosdate)
Just van Rossum52e14d62002-12-30 22:08:05 +00001068{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001069 struct tm stm;
Just van Rossum52e14d62002-12-30 22:08:05 +00001070
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001071 memset((void *) &stm, '\0', sizeof(stm));
Christian Heimes679db4a2008-01-18 09:56:22 +00001072
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001073 stm.tm_sec = (dostime & 0x1f) * 2;
1074 stm.tm_min = (dostime >> 5) & 0x3f;
1075 stm.tm_hour = (dostime >> 11) & 0x1f;
1076 stm.tm_mday = dosdate & 0x1f;
1077 stm.tm_mon = ((dosdate >> 5) & 0x0f) - 1;
1078 stm.tm_year = ((dosdate >> 9) & 0x7f) + 80;
1079 stm.tm_isdst = -1; /* wday/yday is ignored */
Just van Rossum52e14d62002-12-30 22:08:05 +00001080
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001081 return mktime(&stm);
Just van Rossum52e14d62002-12-30 22:08:05 +00001082}
1083
1084/* Given a path to a .pyc or .pyo file in the archive, return the
1085 modifictaion time of the matching .py file, or 0 if no source
1086 is available. */
1087static time_t
1088get_mtime_of_source(ZipImporter *self, char *path)
1089{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001090 PyObject *toc_entry;
1091 time_t mtime = 0;
1092 Py_ssize_t lastchar = strlen(path) - 1;
1093 char savechar = path[lastchar];
1094 path[lastchar] = '\0'; /* strip 'c' or 'o' from *.py[co] */
1095 toc_entry = PyDict_GetItemString(self->files, path);
1096 if (toc_entry != NULL && PyTuple_Check(toc_entry) &&
1097 PyTuple_Size(toc_entry) == 8) {
1098 /* fetch the time stamp of the .py file for comparison
1099 with an embedded pyc time stamp */
1100 int time, date;
1101 time = PyLong_AsLong(PyTuple_GetItem(toc_entry, 5));
1102 date = PyLong_AsLong(PyTuple_GetItem(toc_entry, 6));
1103 mtime = parse_dostime(time, date);
1104 }
1105 path[lastchar] = savechar;
1106 return mtime;
Just van Rossum52e14d62002-12-30 22:08:05 +00001107}
1108
1109/* Return the code object for the module named by 'fullname' from the
1110 Zip archive as a new reference. */
1111static PyObject *
1112get_code_from_data(ZipImporter *self, int ispackage, int isbytecode,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001113 time_t mtime, PyObject *toc_entry)
Just van Rossum52e14d62002-12-30 22:08:05 +00001114{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001115 PyObject *data, *code;
1116 char *modpath;
Just van Rossum52e14d62002-12-30 22:08:05 +00001117
Victor Stinner60fe8d92010-08-16 23:48:11 +00001118 data = get_data(self->archive, toc_entry);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001119 if (data == NULL)
1120 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +00001121
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001122 modpath = _PyUnicode_AsString(PyTuple_GetItem(toc_entry, 0));
Victor Stinner5a7913e2010-10-16 11:29:07 +00001123 if (modpath == NULL) {
1124 Py_DECREF(data);
1125 return NULL;
1126 }
Just van Rossum52e14d62002-12-30 22:08:05 +00001127
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001128 if (isbytecode) {
1129 code = unmarshal_code(modpath, data, mtime);
1130 }
1131 else {
1132 code = compile_source(modpath, data);
1133 }
1134 Py_DECREF(data);
1135 return code;
Just van Rossum52e14d62002-12-30 22:08:05 +00001136}
1137
1138/* Get the code object assoiciated with the module specified by
1139 'fullname'. */
1140static PyObject *
1141get_module_code(ZipImporter *self, char *fullname,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001142 int *p_ispackage, char **p_modpath)
Just van Rossum52e14d62002-12-30 22:08:05 +00001143{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001144 PyObject *toc_entry;
1145 char *subname, path[MAXPATHLEN + 1];
1146 int len;
1147 struct st_zip_searchorder *zso;
Just van Rossum52e14d62002-12-30 22:08:05 +00001148
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001149 subname = get_subname(fullname);
Just van Rossum52e14d62002-12-30 22:08:05 +00001150
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001151 len = make_filename(_PyUnicode_AsString(self->prefix), subname, path);
1152 if (len < 0)
1153 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +00001154
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001155 for (zso = zip_searchorder; *zso->suffix; zso++) {
1156 PyObject *code = NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +00001157
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001158 strcpy(path + len, zso->suffix);
1159 if (Py_VerboseFlag > 1)
Victor Stinner353349c2010-10-18 11:40:40 +00001160 PySys_FormatStderr("# trying %U%c%s\n",
1161 self->archive, (int)SEP, path);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001162 toc_entry = PyDict_GetItemString(self->files, path);
1163 if (toc_entry != NULL) {
1164 time_t mtime = 0;
1165 int ispackage = zso->type & IS_PACKAGE;
1166 int isbytecode = zso->type & IS_BYTECODE;
Just van Rossum52e14d62002-12-30 22:08:05 +00001167
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001168 if (isbytecode)
1169 mtime = get_mtime_of_source(self, path);
1170 if (p_ispackage != NULL)
1171 *p_ispackage = ispackage;
1172 code = get_code_from_data(self, ispackage,
1173 isbytecode, mtime,
1174 toc_entry);
1175 if (code == Py_None) {
1176 /* bad magic number or non-matching mtime
1177 in byte code, try next */
1178 Py_DECREF(code);
1179 continue;
1180 }
1181 if (code != NULL && p_modpath != NULL)
1182 *p_modpath = _PyUnicode_AsString(
1183 PyTuple_GetItem(toc_entry, 0));
1184 return code;
1185 }
1186 }
1187 PyErr_Format(ZipImportError, "can't find module '%.200s'", fullname);
1188 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +00001189}
1190
1191
1192/* Module init */
1193
1194PyDoc_STRVAR(zipimport_doc,
1195"zipimport provides support for importing Python modules from Zip archives.\n\
1196\n\
1197This module exports three objects:\n\
1198- zipimporter: a class; its constructor takes a path to a Zip archive.\n\
Fredrik Lundhb84b35f2006-01-15 15:00:40 +00001199- ZipImportError: exception raised by zipimporter objects. It's a\n\
Just van Rossum52e14d62002-12-30 22:08:05 +00001200 subclass of ImportError, so it can be caught as ImportError, too.\n\
1201- _zip_directory_cache: a dict, mapping archive paths to zip directory\n\
1202 info dicts, as used in zipimporter._files.\n\
1203\n\
1204It is usually not needed to use the zipimport module explicitly; it is\n\
1205used by the builtin import mechanism for sys.path items that are paths\n\
1206to Zip archives.");
1207
Martin v. Löwis1a214512008-06-11 05:26:20 +00001208static struct PyModuleDef zipimportmodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001209 PyModuleDef_HEAD_INIT,
1210 "zipimport",
1211 zipimport_doc,
1212 -1,
1213 NULL,
1214 NULL,
1215 NULL,
1216 NULL,
1217 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +00001218};
1219
Just van Rossum52e14d62002-12-30 22:08:05 +00001220PyMODINIT_FUNC
Martin v. Löwis1a214512008-06-11 05:26:20 +00001221PyInit_zipimport(void)
Just van Rossum52e14d62002-12-30 22:08:05 +00001222{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001223 PyObject *mod;
Just van Rossum52e14d62002-12-30 22:08:05 +00001224
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001225 if (PyType_Ready(&ZipImporter_Type) < 0)
1226 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +00001227
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001228 /* Correct directory separator */
1229 zip_searchorder[0].suffix[0] = SEP;
1230 zip_searchorder[1].suffix[0] = SEP;
1231 zip_searchorder[2].suffix[0] = SEP;
1232 if (Py_OptimizeFlag) {
1233 /* Reverse *.pyc and *.pyo */
1234 struct st_zip_searchorder tmp;
1235 tmp = zip_searchorder[0];
1236 zip_searchorder[0] = zip_searchorder[1];
1237 zip_searchorder[1] = tmp;
1238 tmp = zip_searchorder[3];
1239 zip_searchorder[3] = zip_searchorder[4];
1240 zip_searchorder[4] = tmp;
1241 }
Just van Rossum52e14d62002-12-30 22:08:05 +00001242
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001243 mod = PyModule_Create(&zipimportmodule);
1244 if (mod == NULL)
1245 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +00001246
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001247 ZipImportError = PyErr_NewException("zipimport.ZipImportError",
1248 PyExc_ImportError, NULL);
1249 if (ZipImportError == NULL)
1250 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +00001251
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001252 Py_INCREF(ZipImportError);
1253 if (PyModule_AddObject(mod, "ZipImportError",
1254 ZipImportError) < 0)
1255 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +00001256
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001257 Py_INCREF(&ZipImporter_Type);
1258 if (PyModule_AddObject(mod, "zipimporter",
1259 (PyObject *)&ZipImporter_Type) < 0)
1260 return NULL;
Just van Rossumf8b6de12002-12-31 09:51:59 +00001261
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001262 zip_directory_cache = PyDict_New();
1263 if (zip_directory_cache == NULL)
1264 return NULL;
1265 Py_INCREF(zip_directory_cache);
1266 if (PyModule_AddObject(mod, "_zip_directory_cache",
1267 zip_directory_cache) < 0)
1268 return NULL;
1269 return mod;
Just van Rossum52e14d62002-12-30 22:08:05 +00001270}