blob: 7ae4f0a0513b4ed801266b8c509f6aa5c03919ec [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);
Just van Rossum52e14d62002-12-30 22:08:05 +000052static PyObject *get_module_code(ZipImporter *self, char *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{
Victor Stinner2460a432010-08-16 17:54:28 +000066 PyObject *pathobj, *files;
Victor Stinner2b8dab72010-08-14 14:54:10 +000067 Py_UNICODE *path, *p, *prefix, buf[MAXPATHLEN+2];
68 Py_ssize_t len;
Just van Rossum52e14d62002-12-30 22:08:05 +000069
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000070 if (!_PyArg_NoKeywords("zipimporter()", kwds))
71 return -1;
Georg Brandl02c42872005-08-26 06:42:30 +000072
Victor Stinner2b8dab72010-08-14 14:54:10 +000073 if (!PyArg_ParseTuple(args, "O&:zipimporter",
Victor Stinner9e40fad2010-10-18 22:34:46 +000074 PyUnicode_FSDecoder, &pathobj))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000075 return -1;
Just van Rossum52e14d62002-12-30 22:08:05 +000076
Victor Stinner2b8dab72010-08-14 14:54:10 +000077 /* copy path to buf */
78 len = PyUnicode_GET_SIZE(pathobj);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000079 if (len == 0) {
80 PyErr_SetString(ZipImportError, "archive path is empty");
Victor Stinner2b8dab72010-08-14 14:54:10 +000081 goto error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000082 }
83 if (len >= MAXPATHLEN) {
84 PyErr_SetString(ZipImportError,
85 "archive path too long");
Victor Stinner2b8dab72010-08-14 14:54:10 +000086 goto error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000087 }
Victor Stinner2b8dab72010-08-14 14:54:10 +000088 Py_UNICODE_strcpy(buf, PyUnicode_AS_UNICODE(pathobj));
Just van Rossum52e14d62002-12-30 22:08:05 +000089
90#ifdef ALTSEP
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000091 for (p = buf; *p; p++) {
92 if (*p == ALTSEP)
93 *p = SEP;
94 }
Just van Rossum52e14d62002-12-30 22:08:05 +000095#endif
96
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000097 path = NULL;
98 prefix = NULL;
99 for (;;) {
100 struct stat statbuf;
101 int rv;
Just van Rossum52e14d62002-12-30 22:08:05 +0000102
Victor Stinner2b8dab72010-08-14 14:54:10 +0000103 if (pathobj == NULL) {
104 pathobj = PyUnicode_FromUnicode(buf, len);
105 if (pathobj == NULL)
106 goto error;
107 }
108 rv = _Py_stat(pathobj, &statbuf);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000109 if (rv == 0) {
110 /* it exists */
111 if (S_ISREG(statbuf.st_mode))
112 /* it's a file */
113 path = buf;
114 break;
115 }
Victor Stinner2b8dab72010-08-14 14:54:10 +0000116 else if (PyErr_Occurred())
117 goto error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000118 /* back up one path element */
Victor Stinner2b8dab72010-08-14 14:54:10 +0000119 p = Py_UNICODE_strrchr(buf, SEP);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000120 if (prefix != NULL)
121 *prefix = SEP;
122 if (p == NULL)
123 break;
124 *p = '\0';
Victor Stinner2b8dab72010-08-14 14:54:10 +0000125 len = p - buf;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000126 prefix = p;
Victor Stinner2b8dab72010-08-14 14:54:10 +0000127 Py_CLEAR(pathobj);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000128 }
Victor Stinner2b8dab72010-08-14 14:54:10 +0000129 if (path == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000130 PyErr_SetString(ZipImportError, "not a Zip file");
Victor Stinner2b8dab72010-08-14 14:54:10 +0000131 goto error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000132 }
Just van Rossum52e14d62002-12-30 22:08:05 +0000133
Victor Stinner2b8dab72010-08-14 14:54:10 +0000134 files = PyDict_GetItem(zip_directory_cache, pathobj);
135 if (files == NULL) {
Victor Stinner2460a432010-08-16 17:54:28 +0000136 files = read_directory(pathobj);
Victor Stinner2b8dab72010-08-14 14:54:10 +0000137 if (files == NULL)
138 goto error;
139 if (PyDict_SetItem(zip_directory_cache, pathobj, files) != 0)
140 goto error;
141 }
142 else
143 Py_INCREF(files);
144 self->files = files;
145
146 self->archive = pathobj;
147 pathobj = NULL;
148
149 if (prefix != NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000150 prefix++;
Victor Stinner2b8dab72010-08-14 14:54:10 +0000151 len = Py_UNICODE_strlen(prefix);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000152 if (prefix[len-1] != SEP) {
153 /* add trailing SEP */
154 prefix[len] = SEP;
155 prefix[len + 1] = '\0';
Victor Stinner2b8dab72010-08-14 14:54:10 +0000156 len++;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000157 }
158 }
Victor Stinner2b8dab72010-08-14 14:54:10 +0000159 else
160 len = 0;
161 self->prefix = PyUnicode_FromUnicode(prefix, len);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000162 if (self->prefix == NULL)
Victor Stinner2b8dab72010-08-14 14:54:10 +0000163 goto error;
Just van Rossum52e14d62002-12-30 22:08:05 +0000164
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000165 return 0;
Victor Stinner2b8dab72010-08-14 14:54:10 +0000166
167error:
168 Py_XDECREF(pathobj);
169 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 \"???\">");
196 else if (self->prefix != NULL && PyUnicode_GET_SIZE(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] */
205static char *
206get_subname(char *fullname)
207{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000208 char *subname = strrchr(fullname, '.');
209 if (subname == NULL)
210 subname = fullname;
211 else
212 subname++;
213 return subname;
Just van Rossum52e14d62002-12-30 22:08:05 +0000214}
215
216/* Given a (sub)modulename, write the potential file path in the
217 archive (without extension) to the path buffer. Return the
218 length of the resulting string. */
219static int
Victor Stinner269aeb72010-10-18 20:40:59 +0000220make_filename(PyObject *prefix_obj, char *name, char *path, size_t pathsize)
Just van Rossum52e14d62002-12-30 22:08:05 +0000221{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000222 size_t len;
223 char *p;
Victor Stinner72f767e2010-10-18 11:44:21 +0000224 PyObject *prefix;
Just van Rossum52e14d62002-12-30 22:08:05 +0000225
Victor Stinner72f767e2010-10-18 11:44:21 +0000226 prefix = PyUnicode_EncodeFSDefault(prefix_obj);
227 if (prefix == NULL)
228 return -1;
229 len = PyBytes_GET_SIZE(prefix);
Just van Rossum52e14d62002-12-30 22:08:05 +0000230
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000231 /* self.prefix + name [+ SEP + "__init__"] + ".py[co]" */
Victor Stinner269aeb72010-10-18 20:40:59 +0000232 if (len + strlen(name) + 13 >= pathsize - 1) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000233 PyErr_SetString(ZipImportError, "path too long");
Victor Stinner72f767e2010-10-18 11:44:21 +0000234 Py_DECREF(prefix);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000235 return -1;
236 }
Just van Rossum52e14d62002-12-30 22:08:05 +0000237
Victor Stinner72f767e2010-10-18 11:44:21 +0000238 strcpy(path, PyBytes_AS_STRING(prefix));
239 Py_DECREF(prefix);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000240 strcpy(path + len, name);
241 for (p = path + len; *p; p++) {
242 if (*p == '.')
243 *p = SEP;
244 }
245 len += strlen(name);
246 assert(len < INT_MAX);
247 return (int)len;
Just van Rossum52e14d62002-12-30 22:08:05 +0000248}
249
Raymond Hettinger2c45c9a2004-11-10 13:08:35 +0000250enum zi_module_info {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000251 MI_ERROR,
252 MI_NOT_FOUND,
253 MI_MODULE,
254 MI_PACKAGE
Just van Rossum52e14d62002-12-30 22:08:05 +0000255};
256
257/* Return some information about a module. */
Raymond Hettinger2c45c9a2004-11-10 13:08:35 +0000258static enum zi_module_info
Victor Stinner965a8a12010-10-18 21:44:33 +0000259get_module_info(ZipImporter *self, char *fullname)
Just van Rossum52e14d62002-12-30 22:08:05 +0000260{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000261 char *subname, path[MAXPATHLEN + 1];
262 int len;
263 struct st_zip_searchorder *zso;
Just van Rossum52e14d62002-12-30 22:08:05 +0000264
Victor Stinner965a8a12010-10-18 21:44:33 +0000265 subname = get_subname(fullname);
Just van Rossum52e14d62002-12-30 22:08:05 +0000266
Victor Stinner269aeb72010-10-18 20:40:59 +0000267 len = make_filename(self->prefix, subname, path, sizeof(path));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000268 if (len < 0)
269 return MI_ERROR;
Just van Rossum52e14d62002-12-30 22:08:05 +0000270
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000271 for (zso = zip_searchorder; *zso->suffix; zso++) {
272 strcpy(path + len, zso->suffix);
273 if (PyDict_GetItemString(self->files, path) != NULL) {
274 if (zso->type & IS_PACKAGE)
275 return MI_PACKAGE;
276 else
277 return MI_MODULE;
278 }
279 }
280 return MI_NOT_FOUND;
Just van Rossum52e14d62002-12-30 22:08:05 +0000281}
282
283/* Check whether we can satisfy the import of the module named by
284 'fullname'. Return self if we can, None if we can't. */
285static PyObject *
286zipimporter_find_module(PyObject *obj, PyObject *args)
287{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000288 ZipImporter *self = (ZipImporter *)obj;
289 PyObject *path = NULL;
Victor Stinner965a8a12010-10-18 21:44:33 +0000290 char *fullname;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000291 enum zi_module_info mi;
Just van Rossum52e14d62002-12-30 22:08:05 +0000292
Victor Stinner965a8a12010-10-18 21:44:33 +0000293 if (!PyArg_ParseTuple(args, "s|O:zipimporter.find_module",
294 &fullname, &path))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000295 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +0000296
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000297 mi = get_module_info(self, fullname);
298 if (mi == MI_ERROR)
299 return NULL;
300 if (mi == MI_NOT_FOUND) {
301 Py_INCREF(Py_None);
302 return Py_None;
303 }
304 Py_INCREF(self);
305 return (PyObject *)self;
Just van Rossum52e14d62002-12-30 22:08:05 +0000306}
307
308/* Load and return the module named by 'fullname'. */
309static PyObject *
310zipimporter_load_module(PyObject *obj, PyObject *args)
311{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000312 ZipImporter *self = (ZipImporter *)obj;
Victor Stinner26fabe12010-10-18 12:03:25 +0000313 PyObject *code = NULL, *mod, *dict;
Victor Stinner08654e12010-10-18 12:09:02 +0000314 char *fullname;
315 PyObject *modpath = NULL, *modpath_bytes;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000316 int ispackage;
Just van Rossum52e14d62002-12-30 22:08:05 +0000317
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000318 if (!PyArg_ParseTuple(args, "s:zipimporter.load_module",
319 &fullname))
320 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +0000321
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000322 code = get_module_code(self, fullname, &ispackage, &modpath);
323 if (code == NULL)
Victor Stinner26fabe12010-10-18 12:03:25 +0000324 goto error;
Just van Rossum52e14d62002-12-30 22:08:05 +0000325
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000326 mod = PyImport_AddModule(fullname);
Victor Stinner26fabe12010-10-18 12:03:25 +0000327 if (mod == NULL)
328 goto error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000329 dict = PyModule_GetDict(mod);
Just van Rossum52e14d62002-12-30 22:08:05 +0000330
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000331 /* mod.__loader__ = self */
332 if (PyDict_SetItemString(dict, "__loader__", (PyObject *)self) != 0)
333 goto error;
Just van Rossum52e14d62002-12-30 22:08:05 +0000334
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000335 if (ispackage) {
336 /* add __path__ to the module *before* the code gets
337 executed */
338 PyObject *pkgpath, *fullpath;
339 char *subname = get_subname(fullname);
340 int err;
Just van Rossum52e14d62002-12-30 22:08:05 +0000341
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000342 fullpath = PyUnicode_FromFormat("%U%c%U%s",
343 self->archive, SEP,
344 self->prefix, subname);
345 if (fullpath == NULL)
346 goto error;
Just van Rossum52e14d62002-12-30 22:08:05 +0000347
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000348 pkgpath = Py_BuildValue("[O]", fullpath);
349 Py_DECREF(fullpath);
350 if (pkgpath == NULL)
351 goto error;
352 err = PyDict_SetItemString(dict, "__path__", pkgpath);
353 Py_DECREF(pkgpath);
354 if (err != 0)
355 goto error;
356 }
Victor Stinner08654e12010-10-18 12:09:02 +0000357 modpath_bytes = PyUnicode_EncodeFSDefault(modpath);
358 if (modpath_bytes == NULL)
359 goto error;
360 mod = PyImport_ExecCodeModuleEx(fullname, code,
361 PyBytes_AS_STRING(modpath_bytes));
362 Py_DECREF(modpath_bytes);
Victor Stinner26fabe12010-10-18 12:03:25 +0000363 Py_CLEAR(code);
364 if (mod == NULL)
365 goto error;
366
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000367 if (Py_VerboseFlag)
Victor Stinner08654e12010-10-18 12:09:02 +0000368 PySys_FormatStderr("import %s # loaded from Zip %U\n",
369 fullname, modpath);
370 Py_DECREF(modpath);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000371 return mod;
Just van Rossum52e14d62002-12-30 22:08:05 +0000372error:
Victor Stinner26fabe12010-10-18 12:03:25 +0000373 Py_XDECREF(code);
Victor Stinner08654e12010-10-18 12:09:02 +0000374 Py_XDECREF(modpath);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000375 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +0000376}
377
Nick Coghlanf088e5e2008-12-14 11:50:48 +0000378/* Return a string matching __file__ for the named module */
379static PyObject *
380zipimporter_get_filename(PyObject *obj, PyObject *args)
381{
382 ZipImporter *self = (ZipImporter *)obj;
383 PyObject *code;
Victor Stinner08654e12010-10-18 12:09:02 +0000384 char *fullname;
385 PyObject *modpath;
Nick Coghlanf088e5e2008-12-14 11:50:48 +0000386 int ispackage;
387
Nick Coghlan9a1d6e32009-02-08 03:37:27 +0000388 if (!PyArg_ParseTuple(args, "s:zipimporter.get_filename",
Victor Stinner9e40fad2010-10-18 22:34:46 +0000389 &fullname))
Victor Stinnerc342fca2010-10-18 11:39:05 +0000390 return NULL;
Nick Coghlanf088e5e2008-12-14 11:50:48 +0000391
392 /* Deciding the filename requires working out where the code
393 would come from if the module was actually loaded */
394 code = get_module_code(self, fullname, &ispackage, &modpath);
395 if (code == NULL)
Victor Stinnerc342fca2010-10-18 11:39:05 +0000396 return NULL;
Nick Coghlanf088e5e2008-12-14 11:50:48 +0000397 Py_DECREF(code); /* Only need the path info */
398
Victor Stinner08654e12010-10-18 12:09:02 +0000399 return modpath;
Nick Coghlanf088e5e2008-12-14 11:50:48 +0000400}
401
Just van Rossum52e14d62002-12-30 22:08:05 +0000402/* Return a bool signifying whether the module is a package or not. */
403static PyObject *
404zipimporter_is_package(PyObject *obj, PyObject *args)
405{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000406 ZipImporter *self = (ZipImporter *)obj;
Victor Stinner965a8a12010-10-18 21:44:33 +0000407 char *fullname;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000408 enum zi_module_info mi;
Just van Rossum52e14d62002-12-30 22:08:05 +0000409
Victor Stinner965a8a12010-10-18 21:44:33 +0000410 if (!PyArg_ParseTuple(args, "s:zipimporter.is_package",
411 &fullname))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000412 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +0000413
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000414 mi = get_module_info(self, fullname);
415 if (mi == MI_ERROR)
Victor Stinner965a8a12010-10-18 21:44:33 +0000416 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000417 if (mi == MI_NOT_FOUND) {
Victor Stinner07298a12010-10-18 22:45:54 +0000418 PyErr_Format(ZipImportError, "can't find module '%s'", fullname);
Victor Stinner965a8a12010-10-18 21:44:33 +0000419 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000420 }
421 return PyBool_FromLong(mi == MI_PACKAGE);
Just van Rossum52e14d62002-12-30 22:08:05 +0000422}
423
424static PyObject *
425zipimporter_get_data(PyObject *obj, PyObject *args)
426{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000427 ZipImporter *self = (ZipImporter *)obj;
Victor Stinner60fe8d92010-08-16 23:48:11 +0000428 PyObject *pathobj, *key;
429 const Py_UNICODE *path;
Just van Rossum52e14d62002-12-30 22:08:05 +0000430#ifdef ALTSEP
Victor Stinner60fe8d92010-08-16 23:48:11 +0000431 Py_UNICODE *p, buf[MAXPATHLEN + 1];
Just van Rossum52e14d62002-12-30 22:08:05 +0000432#endif
Victor Stinner60fe8d92010-08-16 23:48:11 +0000433 Py_UNICODE *archive;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000434 PyObject *toc_entry;
Victor Stinner60fe8d92010-08-16 23:48:11 +0000435 Py_ssize_t path_len, len;
Just van Rossum52e14d62002-12-30 22:08:05 +0000436
Victor Stinner60fe8d92010-08-16 23:48:11 +0000437 if (!PyArg_ParseTuple(args, "U:zipimporter.get_data", &pathobj))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000438 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +0000439
Victor Stinner60fe8d92010-08-16 23:48:11 +0000440 path_len = PyUnicode_GET_SIZE(pathobj);
441 path = PyUnicode_AS_UNICODE(pathobj);
Just van Rossum52e14d62002-12-30 22:08:05 +0000442#ifdef ALTSEP
Victor Stinner60fe8d92010-08-16 23:48:11 +0000443 if (path_len >= MAXPATHLEN) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000444 PyErr_SetString(ZipImportError, "path too long");
445 return NULL;
446 }
Victor Stinner60fe8d92010-08-16 23:48:11 +0000447 Py_UNICODE_strcpy(buf, path);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000448 for (p = buf; *p; p++) {
449 if (*p == ALTSEP)
450 *p = SEP;
451 }
452 path = buf;
Just van Rossum52e14d62002-12-30 22:08:05 +0000453#endif
Victor Stinner60fe8d92010-08-16 23:48:11 +0000454 archive = PyUnicode_AS_UNICODE(self->archive);
455 len = PyUnicode_GET_SIZE(self->archive);
456 if ((size_t)len < Py_UNICODE_strlen(path) &&
457 Py_UNICODE_strncmp(path, archive, len) == 0 &&
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000458 path[len] == SEP) {
Victor Stinner60fe8d92010-08-16 23:48:11 +0000459 path += len + 1;
460 path_len -= len + 1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000461 }
Just van Rossum52e14d62002-12-30 22:08:05 +0000462
Victor Stinner60fe8d92010-08-16 23:48:11 +0000463 key = PyUnicode_FromUnicode(path, path_len);
464 if (key == NULL)
465 return NULL;
466 toc_entry = PyDict_GetItem(self->files, key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000467 if (toc_entry == NULL) {
Victor Stinner60fe8d92010-08-16 23:48:11 +0000468 PyErr_SetFromErrnoWithFilenameObject(PyExc_IOError, key);
469 Py_DECREF(key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000470 return NULL;
471 }
Victor Stinner60fe8d92010-08-16 23:48:11 +0000472 Py_DECREF(key);
473 return get_data(self->archive, toc_entry);
Just van Rossum52e14d62002-12-30 22:08:05 +0000474}
475
476static PyObject *
477zipimporter_get_code(PyObject *obj, PyObject *args)
478{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000479 ZipImporter *self = (ZipImporter *)obj;
480 char *fullname;
Just van Rossum52e14d62002-12-30 22:08:05 +0000481
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000482 if (!PyArg_ParseTuple(args, "s:zipimporter.get_code", &fullname))
483 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +0000484
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000485 return get_module_code(self, fullname, NULL, NULL);
Just van Rossum52e14d62002-12-30 22:08:05 +0000486}
487
488static PyObject *
489zipimporter_get_source(PyObject *obj, PyObject *args)
490{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000491 ZipImporter *self = (ZipImporter *)obj;
492 PyObject *toc_entry;
Victor Stinner965a8a12010-10-18 21:44:33 +0000493 char *fullname, *subname, path[MAXPATHLEN+1];
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000494 int len;
495 enum zi_module_info mi;
Just van Rossum52e14d62002-12-30 22:08:05 +0000496
Victor Stinner965a8a12010-10-18 21:44:33 +0000497 if (!PyArg_ParseTuple(args, "s:zipimporter.get_source", &fullname))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000498 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +0000499
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000500 mi = get_module_info(self, fullname);
Victor Stinner965a8a12010-10-18 21:44:33 +0000501 if (mi == MI_ERROR)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000502 return NULL;
Victor Stinner04106562010-10-18 20:44:08 +0000503 if (mi == MI_NOT_FOUND) {
Victor Stinner07298a12010-10-18 22:45:54 +0000504 PyErr_Format(ZipImportError, "can't find module '%s'", fullname);
Victor Stinner04106562010-10-18 20:44:08 +0000505 return NULL;
506 }
Victor Stinner965a8a12010-10-18 21:44:33 +0000507 subname = get_subname(fullname);
Just van Rossum52e14d62002-12-30 22:08:05 +0000508
Victor Stinner269aeb72010-10-18 20:40:59 +0000509 len = make_filename(self->prefix, subname, path, sizeof(path));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000510 if (len < 0)
511 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +0000512
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000513 if (mi == MI_PACKAGE) {
514 path[len] = SEP;
515 strcpy(path + len + 1, "__init__.py");
516 }
517 else
518 strcpy(path + len, ".py");
Just van Rossum52e14d62002-12-30 22:08:05 +0000519
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000520 toc_entry = PyDict_GetItemString(self->files, path);
521 if (toc_entry != NULL) {
Victor Stinner60fe8d92010-08-16 23:48:11 +0000522 PyObject *res, *bytes;
523 bytes = get_data(self->archive, toc_entry);
524 if (bytes == NULL)
525 return NULL;
526 res = PyUnicode_FromStringAndSize(PyBytes_AS_STRING(bytes),
527 PyBytes_GET_SIZE(bytes));
528 Py_DECREF(bytes);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000529 return res;
530 }
Just van Rossum52e14d62002-12-30 22:08:05 +0000531
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000532 /* we have the module, but no source */
533 Py_INCREF(Py_None);
534 return Py_None;
Just van Rossum52e14d62002-12-30 22:08:05 +0000535}
536
537PyDoc_STRVAR(doc_find_module,
538"find_module(fullname, path=None) -> self or None.\n\
539\n\
540Search for a module specified by 'fullname'. 'fullname' must be the\n\
541fully qualified (dotted) module name. It returns the zipimporter\n\
542instance itself if the module was found, or None if it wasn't.\n\
543The optional 'path' argument is ignored -- it's there for compatibility\n\
544with the importer protocol.");
545
546PyDoc_STRVAR(doc_load_module,
547"load_module(fullname) -> module.\n\
548\n\
549Load the module specified by 'fullname'. 'fullname' must be the\n\
550fully qualified (dotted) module name. It returns the imported\n\
551module, or raises ZipImportError if it wasn't found.");
552
553PyDoc_STRVAR(doc_get_data,
554"get_data(pathname) -> string with file data.\n\
555\n\
556Return the data associated with 'pathname'. Raise IOError if\n\
557the file wasn't found.");
558
559PyDoc_STRVAR(doc_is_package,
560"is_package(fullname) -> bool.\n\
561\n\
562Return True if the module specified by fullname is a package.\n\
Brian Curtin32839732010-07-21 01:44:19 +0000563Raise ZipImportError if the module couldn't be found.");
Just van Rossum52e14d62002-12-30 22:08:05 +0000564
565PyDoc_STRVAR(doc_get_code,
566"get_code(fullname) -> code object.\n\
567\n\
568Return the code object for the specified module. Raise ZipImportError\n\
Brian Curtin32839732010-07-21 01:44:19 +0000569if the module couldn't be found.");
Just van Rossum52e14d62002-12-30 22:08:05 +0000570
571PyDoc_STRVAR(doc_get_source,
572"get_source(fullname) -> source string.\n\
573\n\
574Return the source code for the specified module. Raise ZipImportError\n\
Brian Curtin32839732010-07-21 01:44:19 +0000575if the module couldn't be found, return None if the archive does\n\
Just van Rossum52e14d62002-12-30 22:08:05 +0000576contain the module, but has no source for it.");
577
Nick Coghlanf088e5e2008-12-14 11:50:48 +0000578
579PyDoc_STRVAR(doc_get_filename,
Nick Coghlan9a1d6e32009-02-08 03:37:27 +0000580"get_filename(fullname) -> filename string.\n\
Nick Coghlanf088e5e2008-12-14 11:50:48 +0000581\n\
582Return the filename for the specified module.");
583
Just van Rossum52e14d62002-12-30 22:08:05 +0000584static PyMethodDef zipimporter_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000585 {"find_module", zipimporter_find_module, METH_VARARGS,
586 doc_find_module},
587 {"load_module", zipimporter_load_module, METH_VARARGS,
588 doc_load_module},
589 {"get_data", zipimporter_get_data, METH_VARARGS,
590 doc_get_data},
591 {"get_code", zipimporter_get_code, METH_VARARGS,
592 doc_get_code},
593 {"get_source", zipimporter_get_source, METH_VARARGS,
594 doc_get_source},
595 {"get_filename", zipimporter_get_filename, METH_VARARGS,
596 doc_get_filename},
597 {"is_package", zipimporter_is_package, METH_VARARGS,
598 doc_is_package},
599 {NULL, NULL} /* sentinel */
Just van Rossum52e14d62002-12-30 22:08:05 +0000600};
601
602static PyMemberDef zipimporter_members[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000603 {"archive", T_OBJECT, offsetof(ZipImporter, archive), READONLY},
604 {"prefix", T_OBJECT, offsetof(ZipImporter, prefix), READONLY},
605 {"_files", T_OBJECT, offsetof(ZipImporter, files), READONLY},
606 {NULL}
Just van Rossum52e14d62002-12-30 22:08:05 +0000607};
608
609PyDoc_STRVAR(zipimporter_doc,
610"zipimporter(archivepath) -> zipimporter object\n\
611\n\
612Create a new zipimporter instance. 'archivepath' must be a path to\n\
Alexandre Vassalotti8ae3e052008-05-16 00:41:41 +0000613a zipfile, or to a specific path inside a zipfile. For example, it can be\n\
614'/tmp/myimport.zip', or '/tmp/myimport.zip/mydirectory', if mydirectory is a\n\
615valid directory inside the archive.\n\
616\n\
617'ZipImportError is raised if 'archivepath' doesn't point to a valid Zip\n\
618archive.\n\
619\n\
620The 'archive' attribute of zipimporter objects contains the name of the\n\
621zipfile targeted.");
Just van Rossum52e14d62002-12-30 22:08:05 +0000622
623#define DEFERRED_ADDRESS(ADDR) 0
624
625static PyTypeObject ZipImporter_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000626 PyVarObject_HEAD_INIT(DEFERRED_ADDRESS(&PyType_Type), 0)
627 "zipimport.zipimporter",
628 sizeof(ZipImporter),
629 0, /* tp_itemsize */
630 (destructor)zipimporter_dealloc, /* tp_dealloc */
631 0, /* tp_print */
632 0, /* tp_getattr */
633 0, /* tp_setattr */
634 0, /* tp_reserved */
635 (reprfunc)zipimporter_repr, /* tp_repr */
636 0, /* tp_as_number */
637 0, /* tp_as_sequence */
638 0, /* tp_as_mapping */
639 0, /* tp_hash */
640 0, /* tp_call */
641 0, /* tp_str */
642 PyObject_GenericGetAttr, /* tp_getattro */
643 0, /* tp_setattro */
644 0, /* tp_as_buffer */
645 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE |
646 Py_TPFLAGS_HAVE_GC, /* tp_flags */
647 zipimporter_doc, /* tp_doc */
648 zipimporter_traverse, /* tp_traverse */
649 0, /* tp_clear */
650 0, /* tp_richcompare */
651 0, /* tp_weaklistoffset */
652 0, /* tp_iter */
653 0, /* tp_iternext */
654 zipimporter_methods, /* tp_methods */
655 zipimporter_members, /* tp_members */
656 0, /* tp_getset */
657 0, /* tp_base */
658 0, /* tp_dict */
659 0, /* tp_descr_get */
660 0, /* tp_descr_set */
661 0, /* tp_dictoffset */
662 (initproc)zipimporter_init, /* tp_init */
663 PyType_GenericAlloc, /* tp_alloc */
664 PyType_GenericNew, /* tp_new */
665 PyObject_GC_Del, /* tp_free */
Just van Rossum52e14d62002-12-30 22:08:05 +0000666};
667
668
669/* implementation */
670
Just van Rossum52e14d62002-12-30 22:08:05 +0000671/* Given a buffer, return the long that is represented by the first
672 4 bytes, encoded as little endian. This partially reimplements
673 marshal.c:r_long() */
674static long
675get_long(unsigned char *buf) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000676 long x;
677 x = buf[0];
678 x |= (long)buf[1] << 8;
679 x |= (long)buf[2] << 16;
680 x |= (long)buf[3] << 24;
Just van Rossum52e14d62002-12-30 22:08:05 +0000681#if SIZEOF_LONG > 4
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000682 /* Sign extension for 64-bit machines */
683 x |= -(x & 0x80000000L);
Just van Rossum52e14d62002-12-30 22:08:05 +0000684#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000685 return x;
Just van Rossum52e14d62002-12-30 22:08:05 +0000686}
687
688/*
689 read_directory(archive) -> files dict (new reference)
690
691 Given a path to a Zip archive, build a dict, mapping file names
692 (local to the archive, using SEP as a separator) to toc entries.
693
694 A toc_entry is a tuple:
695
Victor Stinner08654e12010-10-18 12:09:02 +0000696 (__file__, # value to use for __file__, available for all files,
697 # encoded to the filesystem encoding
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000698 compress, # compression kind; 0 for uncompressed
699 data_size, # size of compressed data on disk
700 file_size, # size of decompressed data
701 file_offset, # offset of file header from start of archive
702 time, # mod time of file (in dos format)
703 date, # mod data of file (in dos format)
704 crc, # crc checksum of the data
Victor Stinnerc342fca2010-10-18 11:39:05 +0000705 )
Just van Rossum52e14d62002-12-30 22:08:05 +0000706
707 Directories can be recognized by the trailing SEP in the name,
708 data_size and file_offset are 0.
709*/
710static PyObject *
Victor Stinner2460a432010-08-16 17:54:28 +0000711read_directory(PyObject *archive_obj)
Just van Rossum52e14d62002-12-30 22:08:05 +0000712{
Victor Stinner2460a432010-08-16 17:54:28 +0000713 /* FIXME: work on Py_UNICODE* instead of char* */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000714 PyObject *files = NULL;
715 FILE *fp;
Victor Stinnerd36c8212010-10-18 12:13:46 +0000716 unsigned short flags;
Gregory P. Smithab320662012-01-30 15:17:33 -0800717 short compress, time, date, name_size;
718 long crc, data_size, file_size, header_size;
719 Py_ssize_t file_offset, header_position, header_offset;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000720 long i, l, count;
721 size_t length;
Victor Stinner2460a432010-08-16 17:54:28 +0000722 Py_UNICODE path[MAXPATHLEN + 5];
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000723 char name[MAXPATHLEN + 5];
Victor Stinner2460a432010-08-16 17:54:28 +0000724 PyObject *nameobj = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000725 char *p, endof_central_dir[22];
Gregory P. Smithab320662012-01-30 15:17:33 -0800726 Py_ssize_t arc_offset; /* Absolute offset to start of the zip-archive. */
Victor Stinner2460a432010-08-16 17:54:28 +0000727 PyObject *pathobj;
Victor Stinnerd36c8212010-10-18 12:13:46 +0000728 const char *charset;
Victor Stinner4ee65a92011-01-22 10:30:29 +0000729 int bootstrap;
Just van Rossum52e14d62002-12-30 22:08:05 +0000730
Victor Stinner2460a432010-08-16 17:54:28 +0000731 if (PyUnicode_GET_SIZE(archive_obj) > MAXPATHLEN) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000732 PyErr_SetString(PyExc_OverflowError,
733 "Zip path name is too long");
734 return NULL;
735 }
Victor Stinner2460a432010-08-16 17:54:28 +0000736 Py_UNICODE_strcpy(path, PyUnicode_AS_UNICODE(archive_obj));
Just van Rossum52e14d62002-12-30 22:08:05 +0000737
Victor Stinner2460a432010-08-16 17:54:28 +0000738 fp = _Py_fopen(archive_obj, "rb");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000739 if (fp == NULL) {
Victor Stinnerbd206e22011-12-18 21:04:17 +0100740 if (!PyErr_Occurred())
741 PyErr_Format(ZipImportError, "can't open Zip file: '%U'", archive_obj);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000742 return NULL;
743 }
Jesus Cea09bf7a72012-10-03 02:13:05 +0200744
745 if (fseek(fp, -22, SEEK_END) == -1) {
746 fclose(fp);
Jesus Ceacf453252012-10-03 03:16:42 +0200747 PyErr_Format(ZipImportError, "can't read Zip file: %U", archive_obj);
Jesus Cea09bf7a72012-10-03 02:13:05 +0200748 return NULL;
749 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000750 header_position = ftell(fp);
751 if (fread(endof_central_dir, 1, 22, fp) != 22) {
752 fclose(fp);
Victor Stinner07298a12010-10-18 22:45:54 +0000753 PyErr_Format(ZipImportError, "can't read Zip file: '%U'", archive_obj);
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 Stinner07298a12010-10-18 22:45:54 +0000759 PyErr_Format(ZipImportError, "not a Zip file: '%U'", archive_obj);
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
Victor Stinner2460a432010-08-16 17:54:28 +0000772 length = Py_UNICODE_strlen(path);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000773 path[length] = SEP;
Just van Rossum52e14d62002-12-30 22:08:05 +0000774
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000775 /* Start of Central Directory */
776 count = 0;
777 for (;;) {
778 PyObject *t;
779 int err;
Just van Rossum52e14d62002-12-30 22:08:05 +0000780
Jesus Cea09bf7a72012-10-03 02:13:05 +0200781 if (fseek(fp, header_offset, 0) == -1) /* Start of file header */
782 goto fseek_error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000783 l = PyMarshal_ReadLongFromFile(fp);
784 if (l != 0x02014B50)
785 break; /* Bad: Central Dir File Header */
Jesus Cea09bf7a72012-10-03 02:13:05 +0200786 if (fseek(fp, header_offset + 8, 0) == -1)
787 goto fseek_error;
Victor Stinnerd36c8212010-10-18 12:13:46 +0000788 flags = (unsigned short)PyMarshal_ReadShortFromFile(fp);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000789 compress = PyMarshal_ReadShortFromFile(fp);
790 time = PyMarshal_ReadShortFromFile(fp);
791 date = PyMarshal_ReadShortFromFile(fp);
792 crc = PyMarshal_ReadLongFromFile(fp);
793 data_size = PyMarshal_ReadLongFromFile(fp);
794 file_size = PyMarshal_ReadLongFromFile(fp);
795 name_size = PyMarshal_ReadShortFromFile(fp);
796 header_size = 46 + name_size +
797 PyMarshal_ReadShortFromFile(fp) +
798 PyMarshal_ReadShortFromFile(fp);
Jesus Cea09bf7a72012-10-03 02:13:05 +0200799 if (fseek(fp, header_offset + 42, 0) == -1)
800 goto fseek_error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000801 file_offset = PyMarshal_ReadLongFromFile(fp) + arc_offset;
802 if (name_size > MAXPATHLEN)
803 name_size = MAXPATHLEN;
Just van Rossum52e14d62002-12-30 22:08:05 +0000804
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000805 p = name;
806 for (i = 0; i < name_size; i++) {
807 *p = (char)getc(fp);
808 if (*p == '/')
809 *p = SEP;
810 p++;
811 }
812 *p = 0; /* Add terminating null byte */
813 header_offset += header_size;
Just van Rossum52e14d62002-12-30 22:08:05 +0000814
Victor Stinner4ee65a92011-01-22 10:30:29 +0000815 bootstrap = 0;
Victor Stinnerd36c8212010-10-18 12:13:46 +0000816 if (flags & 0x0800)
817 charset = "utf-8";
Victor Stinner4ee65a92011-01-22 10:30:29 +0000818 else if (!PyThreadState_GET()->interp->codecs_initialized) {
819 /* During bootstrap, we may need to load the encodings
820 package from a ZIP file. But the cp437 encoding is implemented
821 in Python in the encodings package.
822
823 Break out of this dependency by assuming that the path to
824 the encodings module is ASCII-only. */
825 charset = "ascii";
826 bootstrap = 1;
827 }
Victor Stinnerd36c8212010-10-18 12:13:46 +0000828 else
829 charset = "cp437";
830 nameobj = PyUnicode_Decode(name, name_size, charset, NULL);
Victor Stinner4ee65a92011-01-22 10:30:29 +0000831 if (nameobj == NULL) {
832 if (bootstrap)
833 PyErr_Format(PyExc_NotImplementedError,
834 "bootstrap issue: python%i%i.zip contains non-ASCII "
835 "filenames without the unicode flag",
836 PY_MAJOR_VERSION, PY_MINOR_VERSION);
Victor Stinner2460a432010-08-16 17:54:28 +0000837 goto error;
Victor Stinner4ee65a92011-01-22 10:30:29 +0000838 }
Victor Stinner2460a432010-08-16 17:54:28 +0000839 Py_UNICODE_strncpy(path + length + 1, PyUnicode_AS_UNICODE(nameobj), MAXPATHLEN - length - 1);
Just van Rossum52e14d62002-12-30 22:08:05 +0000840
Victor Stinner2460a432010-08-16 17:54:28 +0000841 pathobj = PyUnicode_FromUnicode(path, Py_UNICODE_strlen(path));
842 if (pathobj == NULL)
843 goto error;
Gregory P. Smithab320662012-01-30 15:17:33 -0800844 t = Py_BuildValue("Nhllnhhl", pathobj, compress, data_size,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000845 file_size, file_offset, time, date, crc);
846 if (t == NULL)
847 goto error;
Victor Stinner2460a432010-08-16 17:54:28 +0000848 err = PyDict_SetItem(files, nameobj, t);
849 Py_CLEAR(nameobj);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000850 Py_DECREF(t);
851 if (err != 0)
852 goto error;
853 count++;
854 }
855 fclose(fp);
856 if (Py_VerboseFlag)
Victor Stinner2460a432010-08-16 17:54:28 +0000857 PySys_FormatStderr("# zipimport: found %ld names in %U\n",
858 count, archive_obj);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000859 return files;
Jesus Cea09bf7a72012-10-03 02:13:05 +0200860fseek_error:
861 fclose(fp);
862 Py_XDECREF(files);
863 Py_XDECREF(nameobj);
Jesus Ceacf453252012-10-03 03:16:42 +0200864 PyErr_Format(ZipImportError, "can't read Zip file: %U", archive_obj);
Jesus Cea09bf7a72012-10-03 02:13:05 +0200865 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +0000866error:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000867 fclose(fp);
868 Py_XDECREF(files);
Victor Stinner2460a432010-08-16 17:54:28 +0000869 Py_XDECREF(nameobj);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000870 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +0000871}
872
873/* Return the zlib.decompress function object, or NULL if zlib couldn't
874 be imported. The function is cached when found, so subsequent calls
Victor Stinner4925cde2011-05-20 00:16:09 +0200875 don't import zlib again. */
Just van Rossum52e14d62002-12-30 22:08:05 +0000876static PyObject *
877get_decompress_func(void)
878{
Victor Stinner4925cde2011-05-20 00:16:09 +0200879 static int importing_zlib = 0;
880 PyObject *zlib;
881 PyObject *decompress;
Just van Rossum52e14d62002-12-30 22:08:05 +0000882
Victor Stinner4925cde2011-05-20 00:16:09 +0200883 if (importing_zlib != 0)
884 /* Someone has a zlib.py[co] in their Zip file;
885 let's avoid a stack overflow. */
886 return NULL;
887 importing_zlib = 1;
888 zlib = PyImport_ImportModuleNoBlock("zlib");
889 importing_zlib = 0;
890 if (zlib != NULL) {
891 decompress = PyObject_GetAttrString(zlib,
892 "decompress");
893 Py_DECREF(zlib);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000894 }
Victor Stinner4925cde2011-05-20 00:16:09 +0200895 else {
896 PyErr_Clear();
897 decompress = NULL;
898 }
899 if (Py_VerboseFlag)
900 PySys_WriteStderr("# zipimport: zlib %s\n",
901 zlib != NULL ? "available": "UNAVAILABLE");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000902 return decompress;
Just van Rossum52e14d62002-12-30 22:08:05 +0000903}
904
905/* Given a path to a Zip file and a toc_entry, return the (uncompressed)
906 data as a new reference. */
907static PyObject *
Victor Stinner60fe8d92010-08-16 23:48:11 +0000908get_data(PyObject *archive, PyObject *toc_entry)
Just van Rossum52e14d62002-12-30 22:08:05 +0000909{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000910 PyObject *raw_data, *data = NULL, *decompress;
911 char *buf;
912 FILE *fp;
913 int err;
914 Py_ssize_t bytes_read = 0;
915 long l;
Victor Stinner60fe8d92010-08-16 23:48:11 +0000916 PyObject *datapath;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000917 long compress, data_size, file_size, file_offset, bytes_size;
918 long time, date, crc;
Just van Rossum52e14d62002-12-30 22:08:05 +0000919
Victor Stinner60fe8d92010-08-16 23:48:11 +0000920 if (!PyArg_ParseTuple(toc_entry, "Olllllll", &datapath, &compress,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000921 &data_size, &file_size, &file_offset, &time,
922 &date, &crc)) {
923 return NULL;
924 }
Just van Rossum52e14d62002-12-30 22:08:05 +0000925
Victor Stinner60fe8d92010-08-16 23:48:11 +0000926 fp = _Py_fopen(archive, "rb");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000927 if (!fp) {
Victor Stinnerbd206e22011-12-18 21:04:17 +0100928 if (!PyErr_Occurred())
929 PyErr_Format(PyExc_IOError,
930 "zipimport: can not open file %U", archive);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000931 return NULL;
932 }
Just van Rossum52e14d62002-12-30 22:08:05 +0000933
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000934 /* Check to make sure the local file header is correct */
Jesus Cea09bf7a72012-10-03 02:13:05 +0200935 if (fseek(fp, file_offset, 0) == -1) {
936 fclose(fp);
Jesus Ceacf453252012-10-03 03:16:42 +0200937 PyErr_Format(ZipImportError, "can't read Zip file: %U", archive);
Jesus Cea09bf7a72012-10-03 02:13:05 +0200938 return NULL;
939 }
940
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000941 l = PyMarshal_ReadLongFromFile(fp);
942 if (l != 0x04034B50) {
943 /* Bad: Local File Header */
944 PyErr_Format(ZipImportError,
Victor Stinner60fe8d92010-08-16 23:48:11 +0000945 "bad local file header in %U",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000946 archive);
947 fclose(fp);
948 return NULL;
949 }
Jesus Cea09bf7a72012-10-03 02:13:05 +0200950 if (fseek(fp, file_offset + 26, 0) == -1) {
951 fclose(fp);
Jesus Ceacf453252012-10-03 03:16:42 +0200952 PyErr_Format(ZipImportError, "can't read Zip file: %U", archive);
Jesus Cea09bf7a72012-10-03 02:13:05 +0200953 return NULL;
954 }
955
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000956 l = 30 + PyMarshal_ReadShortFromFile(fp) +
957 PyMarshal_ReadShortFromFile(fp); /* local header size */
958 file_offset += l; /* Start of file data */
Just van Rossum52e14d62002-12-30 22:08:05 +0000959
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000960 bytes_size = compress == 0 ? data_size : data_size + 1;
961 if (bytes_size == 0)
962 bytes_size++;
963 raw_data = PyBytes_FromStringAndSize((char *)NULL, bytes_size);
Just van Rossum52e14d62002-12-30 22:08:05 +0000964
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000965 if (raw_data == NULL) {
966 fclose(fp);
967 return NULL;
968 }
969 buf = PyBytes_AsString(raw_data);
Just van Rossum52e14d62002-12-30 22:08:05 +0000970
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000971 err = fseek(fp, file_offset, 0);
Jesus Cea09bf7a72012-10-03 02:13:05 +0200972 if (err == 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000973 bytes_read = fread(buf, 1, data_size, fp);
Jesus Cea09bf7a72012-10-03 02:13:05 +0200974 } else {
975 fclose(fp);
Jesus Ceacf453252012-10-03 03:16:42 +0200976 PyErr_Format(ZipImportError, "can't read Zip file: %U", archive);
Jesus Cea09bf7a72012-10-03 02:13:05 +0200977 return NULL;
978 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000979 fclose(fp);
980 if (err || bytes_read != data_size) {
981 PyErr_SetString(PyExc_IOError,
982 "zipimport: can't read data");
983 Py_DECREF(raw_data);
984 return NULL;
985 }
Just van Rossum52e14d62002-12-30 22:08:05 +0000986
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000987 if (compress != 0) {
988 buf[data_size] = 'Z'; /* saw this in zipfile.py */
989 data_size++;
990 }
991 buf[data_size] = '\0';
Just van Rossum52e14d62002-12-30 22:08:05 +0000992
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000993 if (compress == 0) { /* data is not compressed */
994 data = PyBytes_FromStringAndSize(buf, data_size);
995 Py_DECREF(raw_data);
996 return data;
997 }
998
999 /* Decompress with zlib */
1000 decompress = get_decompress_func();
1001 if (decompress == NULL) {
1002 PyErr_SetString(ZipImportError,
1003 "can't decompress data; "
1004 "zlib not available");
1005 goto error;
1006 }
1007 data = PyObject_CallFunction(decompress, "Oi", raw_data, -15);
Victor Stinner4925cde2011-05-20 00:16:09 +02001008 Py_DECREF(decompress);
Just van Rossum52e14d62002-12-30 22:08:05 +00001009error:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001010 Py_DECREF(raw_data);
1011 return data;
Just van Rossum52e14d62002-12-30 22:08:05 +00001012}
1013
1014/* Lenient date/time comparison function. The precision of the mtime
1015 in the archive is lower than the mtime stored in a .pyc: we
1016 must allow a difference of at most one second. */
1017static int
1018eq_mtime(time_t t1, time_t t2)
1019{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001020 time_t d = t1 - t2;
1021 if (d < 0)
1022 d = -d;
1023 /* dostime only stores even seconds, so be lenient */
1024 return d <= 1;
Just van Rossum52e14d62002-12-30 22:08:05 +00001025}
1026
1027/* Given the contents of a .py[co] file in a buffer, unmarshal the data
1028 and return the code object. Return None if it the magic word doesn't
1029 match (we do this instead of raising an exception as we fall back
1030 to .py if available and we don't want to mask other errors).
1031 Returns a new reference. */
1032static PyObject *
1033unmarshal_code(char *pathname, PyObject *data, time_t mtime)
1034{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001035 PyObject *code;
1036 char *buf = PyBytes_AsString(data);
1037 Py_ssize_t size = PyBytes_Size(data);
Just van Rossum52e14d62002-12-30 22:08:05 +00001038
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001039 if (size <= 9) {
1040 PyErr_SetString(ZipImportError,
1041 "bad pyc data");
1042 return NULL;
1043 }
Just van Rossum52e14d62002-12-30 22:08:05 +00001044
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001045 if (get_long((unsigned char *)buf) != PyImport_GetMagicNumber()) {
1046 if (Py_VerboseFlag)
1047 PySys_WriteStderr("# %s has bad magic\n",
1048 pathname);
1049 Py_INCREF(Py_None);
1050 return Py_None; /* signal caller to try alternative */
1051 }
Just van Rossum52e14d62002-12-30 22:08:05 +00001052
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001053 if (mtime != 0 && !eq_mtime(get_long((unsigned char *)buf + 4),
1054 mtime)) {
1055 if (Py_VerboseFlag)
1056 PySys_WriteStderr("# %s has bad mtime\n",
1057 pathname);
1058 Py_INCREF(Py_None);
1059 return Py_None; /* signal caller to try alternative */
1060 }
Just van Rossum52e14d62002-12-30 22:08:05 +00001061
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001062 code = PyMarshal_ReadObjectFromString(buf + 8, size - 8);
1063 if (code == NULL)
1064 return NULL;
1065 if (!PyCode_Check(code)) {
1066 Py_DECREF(code);
1067 PyErr_Format(PyExc_TypeError,
Victor Stinner07298a12010-10-18 22:45:54 +00001068 "compiled module %s is not a code object",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001069 pathname);
1070 return NULL;
1071 }
1072 return code;
Just van Rossum52e14d62002-12-30 22:08:05 +00001073}
1074
1075/* Replace any occurances of "\r\n?" in the input string with "\n".
1076 This converts DOS and Mac line endings to Unix line endings.
1077 Also append a trailing "\n" to be compatible with
1078 PyParser_SimpleParseFile(). Returns a new reference. */
1079static PyObject *
1080normalize_line_endings(PyObject *source)
1081{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001082 char *buf, *q, *p = PyBytes_AsString(source);
1083 PyObject *fixed_source;
1084 int len = 0;
Just van Rossum52e14d62002-12-30 22:08:05 +00001085
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001086 if (!p) {
1087 return PyBytes_FromStringAndSize("\n\0", 2);
1088 }
Thomas Wouters00ee7ba2006-08-21 19:07:27 +00001089
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001090 /* one char extra for trailing \n and one for terminating \0 */
1091 buf = (char *)PyMem_Malloc(PyBytes_Size(source) + 2);
1092 if (buf == NULL) {
1093 PyErr_SetString(PyExc_MemoryError,
1094 "zipimport: no memory to allocate "
1095 "source buffer");
1096 return NULL;
1097 }
1098 /* replace "\r\n?" by "\n" */
1099 for (q = buf; *p != '\0'; p++) {
1100 if (*p == '\r') {
1101 *q++ = '\n';
1102 if (*(p + 1) == '\n')
1103 p++;
1104 }
1105 else
1106 *q++ = *p;
1107 len++;
1108 }
1109 *q++ = '\n'; /* add trailing \n */
1110 *q = '\0';
1111 fixed_source = PyBytes_FromStringAndSize(buf, len + 2);
1112 PyMem_Free(buf);
1113 return fixed_source;
Just van Rossum52e14d62002-12-30 22:08:05 +00001114}
1115
1116/* Given a string buffer containing Python source code, compile it
1117 return and return a code object as a new reference. */
1118static PyObject *
1119compile_source(char *pathname, PyObject *source)
1120{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001121 PyObject *code, *fixed_source;
Just van Rossum52e14d62002-12-30 22:08:05 +00001122
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001123 fixed_source = normalize_line_endings(source);
1124 if (fixed_source == NULL)
1125 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +00001126
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001127 code = Py_CompileString(PyBytes_AsString(fixed_source), pathname,
1128 Py_file_input);
1129 Py_DECREF(fixed_source);
1130 return code;
Just van Rossum52e14d62002-12-30 22:08:05 +00001131}
1132
1133/* Convert the date/time values found in the Zip archive to a value
1134 that's compatible with the time stamp stored in .pyc files. */
Neal Norwitz29fd2ba2003-03-23 13:21:03 +00001135static time_t
1136parse_dostime(int dostime, int dosdate)
Just van Rossum52e14d62002-12-30 22:08:05 +00001137{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001138 struct tm stm;
Just van Rossum52e14d62002-12-30 22:08:05 +00001139
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001140 memset((void *) &stm, '\0', sizeof(stm));
Christian Heimes679db4a2008-01-18 09:56:22 +00001141
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001142 stm.tm_sec = (dostime & 0x1f) * 2;
1143 stm.tm_min = (dostime >> 5) & 0x3f;
1144 stm.tm_hour = (dostime >> 11) & 0x1f;
1145 stm.tm_mday = dosdate & 0x1f;
1146 stm.tm_mon = ((dosdate >> 5) & 0x0f) - 1;
1147 stm.tm_year = ((dosdate >> 9) & 0x7f) + 80;
1148 stm.tm_isdst = -1; /* wday/yday is ignored */
Just van Rossum52e14d62002-12-30 22:08:05 +00001149
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001150 return mktime(&stm);
Just van Rossum52e14d62002-12-30 22:08:05 +00001151}
1152
1153/* Given a path to a .pyc or .pyo file in the archive, return the
Ezio Melotti13925002011-03-16 11:05:33 +02001154 modification time of the matching .py file, or 0 if no source
Just van Rossum52e14d62002-12-30 22:08:05 +00001155 is available. */
1156static time_t
1157get_mtime_of_source(ZipImporter *self, char *path)
1158{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001159 PyObject *toc_entry;
1160 time_t mtime = 0;
1161 Py_ssize_t lastchar = strlen(path) - 1;
1162 char savechar = path[lastchar];
1163 path[lastchar] = '\0'; /* strip 'c' or 'o' from *.py[co] */
1164 toc_entry = PyDict_GetItemString(self->files, path);
1165 if (toc_entry != NULL && PyTuple_Check(toc_entry) &&
1166 PyTuple_Size(toc_entry) == 8) {
1167 /* fetch the time stamp of the .py file for comparison
1168 with an embedded pyc time stamp */
1169 int time, date;
1170 time = PyLong_AsLong(PyTuple_GetItem(toc_entry, 5));
1171 date = PyLong_AsLong(PyTuple_GetItem(toc_entry, 6));
1172 mtime = parse_dostime(time, date);
1173 }
1174 path[lastchar] = savechar;
1175 return mtime;
Just van Rossum52e14d62002-12-30 22:08:05 +00001176}
1177
1178/* Return the code object for the module named by 'fullname' from the
1179 Zip archive as a new reference. */
1180static PyObject *
1181get_code_from_data(ZipImporter *self, int ispackage, int isbytecode,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001182 time_t mtime, PyObject *toc_entry)
Just van Rossum52e14d62002-12-30 22:08:05 +00001183{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001184 PyObject *data, *code;
Victor Stinner2a94f4c2010-10-18 12:15:34 +00001185 PyObject *modpath;
Just van Rossum52e14d62002-12-30 22:08:05 +00001186
Victor Stinner60fe8d92010-08-16 23:48:11 +00001187 data = get_data(self->archive, toc_entry);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001188 if (data == NULL)
1189 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +00001190
Victor Stinner2a94f4c2010-10-18 12:15:34 +00001191 modpath = PyUnicode_EncodeFSDefault(PyTuple_GetItem(toc_entry, 0));
Victor Stinner5a7913e2010-10-16 11:29:07 +00001192 if (modpath == NULL) {
1193 Py_DECREF(data);
1194 return NULL;
1195 }
Just van Rossum52e14d62002-12-30 22:08:05 +00001196
Victor Stinner2a94f4c2010-10-18 12:15:34 +00001197 if (isbytecode)
1198 code = unmarshal_code(PyBytes_AS_STRING(modpath), data, mtime);
1199 else
1200 code = compile_source(PyBytes_AS_STRING(modpath), data);
1201 Py_DECREF(modpath);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001202 Py_DECREF(data);
1203 return code;
Just van Rossum52e14d62002-12-30 22:08:05 +00001204}
1205
Ezio Melotti42da6632011-03-15 05:18:48 +02001206/* Get the code object associated with the module specified by
Just van Rossum52e14d62002-12-30 22:08:05 +00001207 'fullname'. */
1208static PyObject *
1209get_module_code(ZipImporter *self, char *fullname,
Victor Stinner08654e12010-10-18 12:09:02 +00001210 int *p_ispackage, PyObject **p_modpath)
Just van Rossum52e14d62002-12-30 22:08:05 +00001211{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001212 PyObject *toc_entry;
1213 char *subname, path[MAXPATHLEN + 1];
1214 int len;
1215 struct st_zip_searchorder *zso;
Just van Rossum52e14d62002-12-30 22:08:05 +00001216
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001217 subname = get_subname(fullname);
Just van Rossum52e14d62002-12-30 22:08:05 +00001218
Victor Stinner269aeb72010-10-18 20:40:59 +00001219 len = make_filename(self->prefix, subname, path, sizeof(path));
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001220 if (len < 0)
1221 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +00001222
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001223 for (zso = zip_searchorder; *zso->suffix; zso++) {
1224 PyObject *code = NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +00001225
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001226 strcpy(path + len, zso->suffix);
1227 if (Py_VerboseFlag > 1)
Victor Stinner353349c2010-10-18 11:40:40 +00001228 PySys_FormatStderr("# trying %U%c%s\n",
Victor Stinner72f767e2010-10-18 11:44:21 +00001229 self->archive, (int)SEP, path);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001230 toc_entry = PyDict_GetItemString(self->files, path);
1231 if (toc_entry != NULL) {
1232 time_t mtime = 0;
1233 int ispackage = zso->type & IS_PACKAGE;
1234 int isbytecode = zso->type & IS_BYTECODE;
Just van Rossum52e14d62002-12-30 22:08:05 +00001235
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001236 if (isbytecode)
1237 mtime = get_mtime_of_source(self, path);
1238 if (p_ispackage != NULL)
1239 *p_ispackage = ispackage;
1240 code = get_code_from_data(self, ispackage,
1241 isbytecode, mtime,
1242 toc_entry);
1243 if (code == Py_None) {
1244 /* bad magic number or non-matching mtime
1245 in byte code, try next */
1246 Py_DECREF(code);
1247 continue;
1248 }
Victor Stinner08654e12010-10-18 12:09:02 +00001249 if (code != NULL && p_modpath != NULL) {
1250 *p_modpath = PyTuple_GetItem(toc_entry, 0);
1251 Py_INCREF(*p_modpath);
1252 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001253 return code;
1254 }
1255 }
Victor Stinner07298a12010-10-18 22:45:54 +00001256 PyErr_Format(ZipImportError, "can't find module '%s'", fullname);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001257 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +00001258}
1259
1260
1261/* Module init */
1262
1263PyDoc_STRVAR(zipimport_doc,
1264"zipimport provides support for importing Python modules from Zip archives.\n\
1265\n\
1266This module exports three objects:\n\
1267- zipimporter: a class; its constructor takes a path to a Zip archive.\n\
Fredrik Lundhb84b35f2006-01-15 15:00:40 +00001268- ZipImportError: exception raised by zipimporter objects. It's a\n\
Just van Rossum52e14d62002-12-30 22:08:05 +00001269 subclass of ImportError, so it can be caught as ImportError, too.\n\
1270- _zip_directory_cache: a dict, mapping archive paths to zip directory\n\
1271 info dicts, as used in zipimporter._files.\n\
1272\n\
1273It is usually not needed to use the zipimport module explicitly; it is\n\
1274used by the builtin import mechanism for sys.path items that are paths\n\
1275to Zip archives.");
1276
Martin v. Löwis1a214512008-06-11 05:26:20 +00001277static struct PyModuleDef zipimportmodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001278 PyModuleDef_HEAD_INIT,
1279 "zipimport",
1280 zipimport_doc,
1281 -1,
1282 NULL,
1283 NULL,
1284 NULL,
1285 NULL,
1286 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +00001287};
1288
Just van Rossum52e14d62002-12-30 22:08:05 +00001289PyMODINIT_FUNC
Martin v. Löwis1a214512008-06-11 05:26:20 +00001290PyInit_zipimport(void)
Just van Rossum52e14d62002-12-30 22:08:05 +00001291{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001292 PyObject *mod;
Just van Rossum52e14d62002-12-30 22:08:05 +00001293
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001294 if (PyType_Ready(&ZipImporter_Type) < 0)
1295 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +00001296
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001297 /* Correct directory separator */
1298 zip_searchorder[0].suffix[0] = SEP;
1299 zip_searchorder[1].suffix[0] = SEP;
1300 zip_searchorder[2].suffix[0] = SEP;
1301 if (Py_OptimizeFlag) {
1302 /* Reverse *.pyc and *.pyo */
1303 struct st_zip_searchorder tmp;
1304 tmp = zip_searchorder[0];
1305 zip_searchorder[0] = zip_searchorder[1];
1306 zip_searchorder[1] = tmp;
1307 tmp = zip_searchorder[3];
1308 zip_searchorder[3] = zip_searchorder[4];
1309 zip_searchorder[4] = tmp;
1310 }
Just van Rossum52e14d62002-12-30 22:08:05 +00001311
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001312 mod = PyModule_Create(&zipimportmodule);
1313 if (mod == NULL)
1314 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +00001315
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001316 ZipImportError = PyErr_NewException("zipimport.ZipImportError",
1317 PyExc_ImportError, NULL);
1318 if (ZipImportError == NULL)
1319 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +00001320
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001321 Py_INCREF(ZipImportError);
1322 if (PyModule_AddObject(mod, "ZipImportError",
1323 ZipImportError) < 0)
1324 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +00001325
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001326 Py_INCREF(&ZipImporter_Type);
1327 if (PyModule_AddObject(mod, "zipimporter",
1328 (PyObject *)&ZipImporter_Type) < 0)
1329 return NULL;
Just van Rossumf8b6de12002-12-31 09:51:59 +00001330
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001331 zip_directory_cache = PyDict_New();
1332 if (zip_directory_cache == NULL)
1333 return NULL;
1334 Py_INCREF(zip_directory_cache);
1335 if (PyModule_AddObject(mod, "_zip_directory_cache",
1336 zip_directory_cache) < 0)
1337 return NULL;
1338 return mod;
Just van Rossum52e14d62002-12-30 22:08:05 +00001339}