blob: 2708c80e0e1753c0f707e8606b6092224379b9a7 [file] [log] [blame]
Just van Rossum52e14d62002-12-30 22:08:05 +00001#include "Python.h"
2#include "structmember.h"
3#include "osdefs.h"
4#include "marshal.h"
Just van Rossum52e14d62002-12-30 22:08:05 +00005#include <time.h>
6
7
8#define IS_SOURCE 0x0
9#define IS_BYTECODE 0x1
10#define IS_PACKAGE 0x2
11
12struct st_zip_searchorder {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000013 char suffix[14];
14 int type;
Just van Rossum52e14d62002-12-30 22:08:05 +000015};
16
17/* zip_searchorder defines how we search for a module in the Zip
18 archive: we first search for a package __init__, then for
19 non-package .pyc, .pyo and .py entries. The .pyc and .pyo entries
20 are swapped by initzipimport() if we run in optimized mode. Also,
21 '/' is replaced by SEP there. */
Neal Norwitz29fd2ba2003-03-23 13:21:03 +000022static struct st_zip_searchorder zip_searchorder[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000023 {"/__init__.pyc", IS_PACKAGE | IS_BYTECODE},
24 {"/__init__.pyo", IS_PACKAGE | IS_BYTECODE},
25 {"/__init__.py", IS_PACKAGE | IS_SOURCE},
26 {".pyc", IS_BYTECODE},
27 {".pyo", IS_BYTECODE},
28 {".py", IS_SOURCE},
29 {"", 0}
Just van Rossum52e14d62002-12-30 22:08:05 +000030};
31
32/* zipimporter object definition and support */
33
34typedef struct _zipimporter ZipImporter;
35
36struct _zipimporter {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000037 PyObject_HEAD
Victor Stinner9e40fad2010-10-18 22:34:46 +000038 PyObject *archive; /* pathname of the Zip archive,
39 decoded from the filesystem encoding */
Victor Stinner72f767e2010-10-18 11:44:21 +000040 PyObject *prefix; /* file prefix: "a/sub/directory/",
41 encoded to the filesystem encoding */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000042 PyObject *files; /* dict with file info {path: toc_entry} */
Just van Rossum52e14d62002-12-30 22:08:05 +000043};
44
Just van Rossum52e14d62002-12-30 22:08:05 +000045static PyObject *ZipImportError;
Victor Stinnerc342fca2010-10-18 11:39:05 +000046/* read_directory() cache */
Just van Rossum52e14d62002-12-30 22:08:05 +000047static PyObject *zip_directory_cache = NULL;
48
49/* forward decls */
Victor Stinner2460a432010-08-16 17:54:28 +000050static PyObject *read_directory(PyObject *archive);
Victor Stinner60fe8d92010-08-16 23:48:11 +000051static PyObject *get_data(PyObject *archive, PyObject *toc_entry);
Victor Stinnerf6b563a2011-03-14 20:46:50 -040052static PyObject *get_module_code(ZipImporter *self, PyObject *fullname,
Victor Stinner08654e12010-10-18 12:09:02 +000053 int *p_ispackage, PyObject **p_modpath);
Just van Rossum52e14d62002-12-30 22:08:05 +000054
55
56#define ZipImporter_Check(op) PyObject_TypeCheck(op, &ZipImporter_Type)
57
58
59/* zipimporter.__init__
60 Split the "subdirectory" from the Zip archive path, lookup a matching
61 entry in sys.path_importer_cache, fetch the file directory from there
62 if found, or else read it from the archive. */
63static int
64zipimporter_init(ZipImporter *self, PyObject *args, PyObject *kwds)
65{
Martin v. Löwisa72e78b2011-10-31 08:33:37 +010066 PyObject *path, *files, *tmp;
67 PyObject *filename = NULL;
68 Py_ssize_t len, flen;
69#ifdef ALTSEP
70 _Py_IDENTIFIER(replace);
71#endif
Just van Rossum52e14d62002-12-30 22:08:05 +000072
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000073 if (!_PyArg_NoKeywords("zipimporter()", kwds))
74 return -1;
Georg Brandl02c42872005-08-26 06:42:30 +000075
Victor Stinner2b8dab72010-08-14 14:54:10 +000076 if (!PyArg_ParseTuple(args, "O&:zipimporter",
Martin v. Löwisa72e78b2011-10-31 08:33:37 +010077 PyUnicode_FSDecoder, &path))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000078 return -1;
Just van Rossum52e14d62002-12-30 22:08:05 +000079
Martin v. Löwisa72e78b2011-10-31 08:33:37 +010080 if (PyUnicode_READY(path) == -1)
Martin v. Löwisd63a3b82011-09-28 07:41:54 +020081 return -1;
82
Martin v. Löwisa72e78b2011-10-31 08:33:37 +010083 len = PyUnicode_GET_LENGTH(path);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000084 if (len == 0) {
85 PyErr_SetString(ZipImportError, "archive path is empty");
Victor Stinner2b8dab72010-08-14 14:54:10 +000086 goto error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000087 }
Just van Rossum52e14d62002-12-30 22:08:05 +000088
89#ifdef ALTSEP
Martin v. Löwisa72e78b2011-10-31 08:33:37 +010090 tmp = PyObject_CallMethodId(path, &PyId_replace, "CC",
91 ALTSEP, SEP);
92 if (!tmp)
93 goto error;
94 Py_DECREF(path);
95 path = tmp;
Just van Rossum52e14d62002-12-30 22:08:05 +000096#endif
97
Martin v. Löwisa72e78b2011-10-31 08:33:37 +010098 filename = path;
99 Py_INCREF(filename);
100 flen = len;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000101 for (;;) {
102 struct stat statbuf;
103 int rv;
Just van Rossum52e14d62002-12-30 22:08:05 +0000104
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100105 rv = _Py_stat(filename, &statbuf);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000106 if (rv == 0) {
107 /* it exists */
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100108 if (!S_ISREG(statbuf.st_mode))
109 /* it's a not file */
110 Py_CLEAR(filename);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000111 break;
112 }
Victor Stinner2b8dab72010-08-14 14:54:10 +0000113 else if (PyErr_Occurred())
114 goto error;
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100115 Py_CLEAR(filename);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000116 /* back up one path element */
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100117 flen = PyUnicode_FindChar(path, SEP, 0, flen, -1);
118 if (flen == -1)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000119 break;
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100120 filename = PyUnicode_Substring(path, 0, flen);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000121 }
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100122 if (filename == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000123 PyErr_SetString(ZipImportError, "not a Zip file");
Victor Stinner2b8dab72010-08-14 14:54:10 +0000124 goto error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000125 }
Just van Rossum52e14d62002-12-30 22:08:05 +0000126
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100127 if (PyUnicode_READY(filename) < 0)
128 goto error;
129
130 files = PyDict_GetItem(zip_directory_cache, filename);
Victor Stinner2b8dab72010-08-14 14:54:10 +0000131 if (files == NULL) {
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100132 files = read_directory(filename);
Victor Stinner2b8dab72010-08-14 14:54:10 +0000133 if (files == NULL)
134 goto error;
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100135 if (PyDict_SetItem(zip_directory_cache, filename, files) != 0)
Victor Stinner2b8dab72010-08-14 14:54:10 +0000136 goto error;
137 }
138 else
139 Py_INCREF(files);
140 self->files = files;
141
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100142 /* Transfer reference */
143 self->archive = filename;
144 filename = NULL;
Victor Stinner2b8dab72010-08-14 14:54:10 +0000145
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100146 /* Check if there is a prefix directory following the filename. */
147 if (flen != len) {
148 tmp = PyUnicode_Substring(path, flen+1,
149 PyUnicode_GET_LENGTH(path));
150 if (tmp == NULL)
151 goto error;
152 self->prefix = tmp;
153 if (PyUnicode_READ_CHAR(path, len-1) != SEP) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000154 /* add trailing SEP */
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100155 tmp = PyUnicode_FromFormat("%U%c", self->prefix, SEP);
156 if (tmp == NULL)
157 goto error;
158 Py_DECREF(self->prefix);
159 self->prefix = tmp;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000160 }
161 }
Victor Stinner2b8dab72010-08-14 14:54:10 +0000162 else
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100163 self->prefix = PyUnicode_New(0, 0);
164 Py_DECREF(path);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000165 return 0;
Victor Stinner2b8dab72010-08-14 14:54:10 +0000166
167error:
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100168 Py_DECREF(path);
169 Py_XDECREF(filename);
Victor Stinner2b8dab72010-08-14 14:54:10 +0000170 return -1;
Just van Rossum52e14d62002-12-30 22:08:05 +0000171}
172
173/* GC support. */
174static int
175zipimporter_traverse(PyObject *obj, visitproc visit, void *arg)
176{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000177 ZipImporter *self = (ZipImporter *)obj;
178 Py_VISIT(self->files);
179 return 0;
Just van Rossum52e14d62002-12-30 22:08:05 +0000180}
181
182static void
183zipimporter_dealloc(ZipImporter *self)
184{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000185 PyObject_GC_UnTrack(self);
186 Py_XDECREF(self->archive);
187 Py_XDECREF(self->prefix);
188 Py_XDECREF(self->files);
189 Py_TYPE(self)->tp_free((PyObject *)self);
Just van Rossum52e14d62002-12-30 22:08:05 +0000190}
191
192static PyObject *
193zipimporter_repr(ZipImporter *self)
194{
Victor Stinner028dd972010-08-17 00:04:48 +0000195 if (self->archive == NULL)
196 return PyUnicode_FromString("<zipimporter object \"???\">");
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200197 else if (self->prefix != NULL && PyUnicode_GET_LENGTH(self->prefix) != 0)
Victor Stinner07298a12010-10-18 22:45:54 +0000198 return PyUnicode_FromFormat("<zipimporter object \"%U%c%U\">",
Victor Stinner028dd972010-08-17 00:04:48 +0000199 self->archive, SEP, self->prefix);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000200 else
Victor Stinner07298a12010-10-18 22:45:54 +0000201 return PyUnicode_FromFormat("<zipimporter object \"%U\">",
Victor Stinner028dd972010-08-17 00:04:48 +0000202 self->archive);
Just van Rossum52e14d62002-12-30 22:08:05 +0000203}
204
205/* return fullname.split(".")[-1] */
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400206static PyObject *
207get_subname(PyObject *fullname)
Just van Rossum52e14d62002-12-30 22:08:05 +0000208{
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100209 Py_ssize_t len, dot;
210 if (PyUnicode_READY(fullname) < 0)
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200211 return NULL;
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100212 len = PyUnicode_GET_LENGTH(fullname);
213 dot = PyUnicode_FindChar(fullname, '.', 0, len, -1);
214 if (dot == -1) {
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400215 Py_INCREF(fullname);
216 return fullname;
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100217 } else
218 return PyUnicode_Substring(fullname, dot+1, len);
Just van Rossum52e14d62002-12-30 22:08:05 +0000219}
220
221/* Given a (sub)modulename, write the potential file path in the
222 archive (without extension) to the path buffer. Return the
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400223 length of the resulting string.
224
225 return self.prefix + name.replace('.', os.sep) */
226static PyObject*
227make_filename(PyObject *prefix, PyObject *name)
Just van Rossum52e14d62002-12-30 22:08:05 +0000228{
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400229 PyObject *pathobj;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200230 Py_UCS4 *p, *buf;
231 Py_ssize_t len;
Just van Rossum52e14d62002-12-30 22:08:05 +0000232
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200233 len = PyUnicode_GET_LENGTH(prefix) + PyUnicode_GET_LENGTH(name) + 1;
234 p = buf = PyMem_Malloc(sizeof(Py_UCS4) * len);
235 if (buf == NULL) {
236 PyErr_NoMemory();
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400237 return NULL;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200238 }
Just van Rossum52e14d62002-12-30 22:08:05 +0000239
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200240 if (!PyUnicode_AsUCS4(prefix, p, len, 0))
241 return NULL;
242 p += PyUnicode_GET_LENGTH(prefix);
243 len -= PyUnicode_GET_LENGTH(prefix);
244 if (!PyUnicode_AsUCS4(name, p, len, 1))
245 return NULL;
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400246 for (; *p; p++) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000247 if (*p == '.')
248 *p = SEP;
249 }
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200250 pathobj = PyUnicode_FromKindAndData(PyUnicode_4BYTE_KIND,
251 buf, p-buf);
252 PyMem_Free(buf);
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400253 return pathobj;
Just van Rossum52e14d62002-12-30 22:08:05 +0000254}
255
Raymond Hettinger2c45c9a2004-11-10 13:08:35 +0000256enum zi_module_info {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000257 MI_ERROR,
258 MI_NOT_FOUND,
259 MI_MODULE,
260 MI_PACKAGE
Just van Rossum52e14d62002-12-30 22:08:05 +0000261};
262
263/* Return some information about a module. */
Raymond Hettinger2c45c9a2004-11-10 13:08:35 +0000264static enum zi_module_info
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400265get_module_info(ZipImporter *self, PyObject *fullname)
Just van Rossum52e14d62002-12-30 22:08:05 +0000266{
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400267 PyObject *subname;
268 PyObject *path, *fullpath, *item;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000269 struct st_zip_searchorder *zso;
Just van Rossum52e14d62002-12-30 22:08:05 +0000270
Victor Stinner965a8a12010-10-18 21:44:33 +0000271 subname = get_subname(fullname);
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400272 if (subname == NULL)
273 return MI_ERROR;
Just van Rossum52e14d62002-12-30 22:08:05 +0000274
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400275 path = make_filename(self->prefix, subname);
276 Py_DECREF(subname);
277 if (path == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000278 return MI_ERROR;
Just van Rossum52e14d62002-12-30 22:08:05 +0000279
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000280 for (zso = zip_searchorder; *zso->suffix; zso++) {
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400281 fullpath = PyUnicode_FromFormat("%U%s", path, zso->suffix);
282 if (fullpath == NULL) {
283 Py_DECREF(path);
284 return MI_ERROR;
285 }
286 item = PyDict_GetItem(self->files, fullpath);
287 Py_DECREF(fullpath);
288 if (item != NULL) {
289 Py_DECREF(path);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000290 if (zso->type & IS_PACKAGE)
291 return MI_PACKAGE;
292 else
293 return MI_MODULE;
294 }
295 }
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400296 Py_DECREF(path);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000297 return MI_NOT_FOUND;
Just van Rossum52e14d62002-12-30 22:08:05 +0000298}
299
300/* Check whether we can satisfy the import of the module named by
301 'fullname'. Return self if we can, None if we can't. */
302static PyObject *
303zipimporter_find_module(PyObject *obj, PyObject *args)
304{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000305 ZipImporter *self = (ZipImporter *)obj;
306 PyObject *path = NULL;
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400307 PyObject *fullname;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000308 enum zi_module_info mi;
Just van Rossum52e14d62002-12-30 22:08:05 +0000309
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400310 if (!PyArg_ParseTuple(args, "U|O:zipimporter.find_module",
Victor Stinner965a8a12010-10-18 21:44:33 +0000311 &fullname, &path))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000312 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +0000313
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000314 mi = get_module_info(self, fullname);
315 if (mi == MI_ERROR)
316 return NULL;
317 if (mi == MI_NOT_FOUND) {
318 Py_INCREF(Py_None);
319 return Py_None;
320 }
321 Py_INCREF(self);
322 return (PyObject *)self;
Just van Rossum52e14d62002-12-30 22:08:05 +0000323}
324
325/* Load and return the module named by 'fullname'. */
326static PyObject *
327zipimporter_load_module(PyObject *obj, PyObject *args)
328{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000329 ZipImporter *self = (ZipImporter *)obj;
Victor Stinner26fabe12010-10-18 12:03:25 +0000330 PyObject *code = NULL, *mod, *dict;
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400331 PyObject *fullname;
332 PyObject *modpath = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000333 int ispackage;
Just van Rossum52e14d62002-12-30 22:08:05 +0000334
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400335 if (!PyArg_ParseTuple(args, "U:zipimporter.load_module",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000336 &fullname))
337 return NULL;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200338 if (PyUnicode_READY(fullname) == -1)
339 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +0000340
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000341 code = get_module_code(self, fullname, &ispackage, &modpath);
342 if (code == NULL)
Victor Stinner26fabe12010-10-18 12:03:25 +0000343 goto error;
Just van Rossum52e14d62002-12-30 22:08:05 +0000344
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400345 mod = PyImport_AddModuleObject(fullname);
Victor Stinner26fabe12010-10-18 12:03:25 +0000346 if (mod == NULL)
347 goto error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000348 dict = PyModule_GetDict(mod);
Just van Rossum52e14d62002-12-30 22:08:05 +0000349
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000350 /* mod.__loader__ = self */
351 if (PyDict_SetItemString(dict, "__loader__", (PyObject *)self) != 0)
352 goto error;
Just van Rossum52e14d62002-12-30 22:08:05 +0000353
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000354 if (ispackage) {
355 /* add __path__ to the module *before* the code gets
356 executed */
357 PyObject *pkgpath, *fullpath;
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400358 PyObject *subname = get_subname(fullname);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000359 int err;
Just van Rossum52e14d62002-12-30 22:08:05 +0000360
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400361 fullpath = PyUnicode_FromFormat("%U%c%U%U",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000362 self->archive, SEP,
363 self->prefix, subname);
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400364 Py_DECREF(subname);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000365 if (fullpath == NULL)
366 goto error;
Just van Rossum52e14d62002-12-30 22:08:05 +0000367
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400368 pkgpath = Py_BuildValue("[N]", fullpath);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000369 if (pkgpath == NULL)
370 goto error;
371 err = PyDict_SetItemString(dict, "__path__", pkgpath);
372 Py_DECREF(pkgpath);
373 if (err != 0)
374 goto error;
375 }
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400376 mod = PyImport_ExecCodeModuleObject(fullname, code, modpath, NULL);
Victor Stinner26fabe12010-10-18 12:03:25 +0000377 Py_CLEAR(code);
378 if (mod == NULL)
379 goto error;
380
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000381 if (Py_VerboseFlag)
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400382 PySys_FormatStderr("import %U # loaded from Zip %U\n",
Victor Stinner08654e12010-10-18 12:09:02 +0000383 fullname, modpath);
384 Py_DECREF(modpath);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000385 return mod;
Just van Rossum52e14d62002-12-30 22:08:05 +0000386error:
Victor Stinner26fabe12010-10-18 12:03:25 +0000387 Py_XDECREF(code);
Victor Stinner08654e12010-10-18 12:09:02 +0000388 Py_XDECREF(modpath);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000389 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +0000390}
391
Nick Coghlanf088e5e2008-12-14 11:50:48 +0000392/* Return a string matching __file__ for the named module */
393static PyObject *
394zipimporter_get_filename(PyObject *obj, PyObject *args)
395{
396 ZipImporter *self = (ZipImporter *)obj;
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400397 PyObject *fullname, *code, *modpath;
Nick Coghlanf088e5e2008-12-14 11:50:48 +0000398 int ispackage;
399
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400400 if (!PyArg_ParseTuple(args, "U:zipimporter.get_filename",
Victor Stinner9e40fad2010-10-18 22:34:46 +0000401 &fullname))
Victor Stinnerc342fca2010-10-18 11:39:05 +0000402 return NULL;
Nick Coghlanf088e5e2008-12-14 11:50:48 +0000403
404 /* Deciding the filename requires working out where the code
405 would come from if the module was actually loaded */
406 code = get_module_code(self, fullname, &ispackage, &modpath);
407 if (code == NULL)
Victor Stinnerc342fca2010-10-18 11:39:05 +0000408 return NULL;
Nick Coghlanf088e5e2008-12-14 11:50:48 +0000409 Py_DECREF(code); /* Only need the path info */
410
Victor Stinner08654e12010-10-18 12:09:02 +0000411 return modpath;
Nick Coghlanf088e5e2008-12-14 11:50:48 +0000412}
413
Just van Rossum52e14d62002-12-30 22:08:05 +0000414/* Return a bool signifying whether the module is a package or not. */
415static PyObject *
416zipimporter_is_package(PyObject *obj, PyObject *args)
417{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000418 ZipImporter *self = (ZipImporter *)obj;
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400419 PyObject *fullname;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000420 enum zi_module_info mi;
Just van Rossum52e14d62002-12-30 22:08:05 +0000421
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400422 if (!PyArg_ParseTuple(args, "U:zipimporter.is_package",
Victor Stinner965a8a12010-10-18 21:44:33 +0000423 &fullname))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000424 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +0000425
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000426 mi = get_module_info(self, fullname);
427 if (mi == MI_ERROR)
Victor Stinner965a8a12010-10-18 21:44:33 +0000428 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000429 if (mi == MI_NOT_FOUND) {
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400430 PyErr_Format(ZipImportError, "can't find module %R", fullname);
Victor Stinner965a8a12010-10-18 21:44:33 +0000431 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000432 }
433 return PyBool_FromLong(mi == MI_PACKAGE);
Just van Rossum52e14d62002-12-30 22:08:05 +0000434}
435
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200436
Just van Rossum52e14d62002-12-30 22:08:05 +0000437static PyObject *
438zipimporter_get_data(PyObject *obj, PyObject *args)
439{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000440 ZipImporter *self = (ZipImporter *)obj;
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100441 PyObject *path, *key;
Just van Rossum52e14d62002-12-30 22:08:05 +0000442#ifdef ALTSEP
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100443 PyObject *tmp;
444 _Py_IDENTIFIER(replace);
Just van Rossum52e14d62002-12-30 22:08:05 +0000445#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000446 PyObject *toc_entry;
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100447 Py_ssize_t path_start, path_len, len;
Just van Rossum52e14d62002-12-30 22:08:05 +0000448
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100449 if (!PyArg_ParseTuple(args, "U:zipimporter.get_data", &path))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000450 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +0000451
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200452#ifdef ALTSEP
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100453 path = PyObject_CallMethodId(path, &PyId_replace, "CC", ALTSEP, SEP);
454 if (!path)
455 return NULL;
456#else
457 Py_INCREF(path);
Just van Rossum52e14d62002-12-30 22:08:05 +0000458#endif
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100459 if (PyUnicode_READY(path) == -1)
460 goto error;
461
462 path_len = PyUnicode_GET_LENGTH(path);
463
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200464 len = PyUnicode_GET_LENGTH(self->archive);
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100465 path_start = 0;
466 if (PyUnicode_Tailmatch(path, self->archive, 0, len, -1)
467 && PyUnicode_READ_CHAR(path, len) == SEP) {
468 path_start = len + 1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000469 }
Just van Rossum52e14d62002-12-30 22:08:05 +0000470
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100471 key = PyUnicode_Substring(path, path_start, path_len);
Victor Stinner60fe8d92010-08-16 23:48:11 +0000472 if (key == NULL)
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100473 goto error;
Victor Stinner60fe8d92010-08-16 23:48:11 +0000474 toc_entry = PyDict_GetItem(self->files, key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000475 if (toc_entry == NULL) {
Victor Stinner60fe8d92010-08-16 23:48:11 +0000476 PyErr_SetFromErrnoWithFilenameObject(PyExc_IOError, key);
477 Py_DECREF(key);
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100478 goto error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000479 }
Victor Stinner60fe8d92010-08-16 23:48:11 +0000480 Py_DECREF(key);
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100481 Py_DECREF(path);
Victor Stinner60fe8d92010-08-16 23:48:11 +0000482 return get_data(self->archive, toc_entry);
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100483 error:
484 Py_DECREF(path);
485 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +0000486}
487
488static PyObject *
489zipimporter_get_code(PyObject *obj, PyObject *args)
490{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000491 ZipImporter *self = (ZipImporter *)obj;
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400492 PyObject *fullname;
Just van Rossum52e14d62002-12-30 22:08:05 +0000493
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400494 if (!PyArg_ParseTuple(args, "U:zipimporter.get_code", &fullname))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000495 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +0000496
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000497 return get_module_code(self, fullname, NULL, NULL);
Just van Rossum52e14d62002-12-30 22:08:05 +0000498}
499
500static PyObject *
501zipimporter_get_source(PyObject *obj, PyObject *args)
502{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000503 ZipImporter *self = (ZipImporter *)obj;
504 PyObject *toc_entry;
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400505 PyObject *fullname, *subname, *path, *fullpath;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000506 enum zi_module_info mi;
Just van Rossum52e14d62002-12-30 22:08:05 +0000507
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400508 if (!PyArg_ParseTuple(args, "U:zipimporter.get_source", &fullname))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000509 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +0000510
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000511 mi = get_module_info(self, fullname);
Victor Stinner965a8a12010-10-18 21:44:33 +0000512 if (mi == MI_ERROR)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000513 return NULL;
Victor Stinner04106562010-10-18 20:44:08 +0000514 if (mi == MI_NOT_FOUND) {
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400515 PyErr_Format(ZipImportError, "can't find module %R", fullname);
Victor Stinner04106562010-10-18 20:44:08 +0000516 return NULL;
517 }
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400518
Victor Stinner965a8a12010-10-18 21:44:33 +0000519 subname = get_subname(fullname);
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400520 if (subname == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000521 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +0000522
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400523 path = make_filename(self->prefix, subname);
524 Py_DECREF(subname);
525 if (path == NULL)
526 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +0000527
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400528 if (mi == MI_PACKAGE)
529 fullpath = PyUnicode_FromFormat("%U%c__init__.py", path, SEP);
530 else
531 fullpath = PyUnicode_FromFormat("%U.py", path);
532 Py_DECREF(path);
533 if (fullpath == NULL)
534 return NULL;
535
536 toc_entry = PyDict_GetItem(self->files, fullpath);
537 Py_DECREF(fullpath);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000538 if (toc_entry != NULL) {
Victor Stinner60fe8d92010-08-16 23:48:11 +0000539 PyObject *res, *bytes;
540 bytes = get_data(self->archive, toc_entry);
541 if (bytes == NULL)
542 return NULL;
543 res = PyUnicode_FromStringAndSize(PyBytes_AS_STRING(bytes),
544 PyBytes_GET_SIZE(bytes));
545 Py_DECREF(bytes);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000546 return res;
547 }
Just van Rossum52e14d62002-12-30 22:08:05 +0000548
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000549 /* we have the module, but no source */
550 Py_INCREF(Py_None);
551 return Py_None;
Just van Rossum52e14d62002-12-30 22:08:05 +0000552}
553
554PyDoc_STRVAR(doc_find_module,
555"find_module(fullname, path=None) -> self or None.\n\
556\n\
557Search for a module specified by 'fullname'. 'fullname' must be the\n\
558fully qualified (dotted) module name. It returns the zipimporter\n\
559instance itself if the module was found, or None if it wasn't.\n\
560The optional 'path' argument is ignored -- it's there for compatibility\n\
561with the importer protocol.");
562
563PyDoc_STRVAR(doc_load_module,
564"load_module(fullname) -> module.\n\
565\n\
566Load the module specified by 'fullname'. 'fullname' must be the\n\
567fully qualified (dotted) module name. It returns the imported\n\
568module, or raises ZipImportError if it wasn't found.");
569
570PyDoc_STRVAR(doc_get_data,
571"get_data(pathname) -> string with file data.\n\
572\n\
573Return the data associated with 'pathname'. Raise IOError if\n\
574the file wasn't found.");
575
576PyDoc_STRVAR(doc_is_package,
577"is_package(fullname) -> bool.\n\
578\n\
579Return True if the module specified by fullname is a package.\n\
Brian Curtin32839732010-07-21 01:44:19 +0000580Raise ZipImportError if the module couldn't be found.");
Just van Rossum52e14d62002-12-30 22:08:05 +0000581
582PyDoc_STRVAR(doc_get_code,
583"get_code(fullname) -> code object.\n\
584\n\
585Return the code object for the specified module. Raise ZipImportError\n\
Brian Curtin32839732010-07-21 01:44:19 +0000586if the module couldn't be found.");
Just van Rossum52e14d62002-12-30 22:08:05 +0000587
588PyDoc_STRVAR(doc_get_source,
589"get_source(fullname) -> source string.\n\
590\n\
591Return the source code for the specified module. Raise ZipImportError\n\
Brian Curtin32839732010-07-21 01:44:19 +0000592if the module couldn't be found, return None if the archive does\n\
Just van Rossum52e14d62002-12-30 22:08:05 +0000593contain the module, but has no source for it.");
594
Nick Coghlanf088e5e2008-12-14 11:50:48 +0000595
596PyDoc_STRVAR(doc_get_filename,
Nick Coghlan9a1d6e32009-02-08 03:37:27 +0000597"get_filename(fullname) -> filename string.\n\
Nick Coghlanf088e5e2008-12-14 11:50:48 +0000598\n\
599Return the filename for the specified module.");
600
Just van Rossum52e14d62002-12-30 22:08:05 +0000601static PyMethodDef zipimporter_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000602 {"find_module", zipimporter_find_module, METH_VARARGS,
603 doc_find_module},
604 {"load_module", zipimporter_load_module, METH_VARARGS,
605 doc_load_module},
606 {"get_data", zipimporter_get_data, METH_VARARGS,
607 doc_get_data},
608 {"get_code", zipimporter_get_code, METH_VARARGS,
609 doc_get_code},
610 {"get_source", zipimporter_get_source, METH_VARARGS,
611 doc_get_source},
612 {"get_filename", zipimporter_get_filename, METH_VARARGS,
613 doc_get_filename},
614 {"is_package", zipimporter_is_package, METH_VARARGS,
615 doc_is_package},
616 {NULL, NULL} /* sentinel */
Just van Rossum52e14d62002-12-30 22:08:05 +0000617};
618
619static PyMemberDef zipimporter_members[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000620 {"archive", T_OBJECT, offsetof(ZipImporter, archive), READONLY},
621 {"prefix", T_OBJECT, offsetof(ZipImporter, prefix), READONLY},
622 {"_files", T_OBJECT, offsetof(ZipImporter, files), READONLY},
623 {NULL}
Just van Rossum52e14d62002-12-30 22:08:05 +0000624};
625
626PyDoc_STRVAR(zipimporter_doc,
627"zipimporter(archivepath) -> zipimporter object\n\
628\n\
629Create a new zipimporter instance. 'archivepath' must be a path to\n\
Alexandre Vassalotti8ae3e052008-05-16 00:41:41 +0000630a zipfile, or to a specific path inside a zipfile. For example, it can be\n\
631'/tmp/myimport.zip', or '/tmp/myimport.zip/mydirectory', if mydirectory is a\n\
632valid directory inside the archive.\n\
633\n\
634'ZipImportError is raised if 'archivepath' doesn't point to a valid Zip\n\
635archive.\n\
636\n\
637The 'archive' attribute of zipimporter objects contains the name of the\n\
638zipfile targeted.");
Just van Rossum52e14d62002-12-30 22:08:05 +0000639
640#define DEFERRED_ADDRESS(ADDR) 0
641
642static PyTypeObject ZipImporter_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000643 PyVarObject_HEAD_INIT(DEFERRED_ADDRESS(&PyType_Type), 0)
644 "zipimport.zipimporter",
645 sizeof(ZipImporter),
646 0, /* tp_itemsize */
647 (destructor)zipimporter_dealloc, /* tp_dealloc */
648 0, /* tp_print */
649 0, /* tp_getattr */
650 0, /* tp_setattr */
651 0, /* tp_reserved */
652 (reprfunc)zipimporter_repr, /* tp_repr */
653 0, /* tp_as_number */
654 0, /* tp_as_sequence */
655 0, /* tp_as_mapping */
656 0, /* tp_hash */
657 0, /* tp_call */
658 0, /* tp_str */
659 PyObject_GenericGetAttr, /* tp_getattro */
660 0, /* tp_setattro */
661 0, /* tp_as_buffer */
662 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE |
663 Py_TPFLAGS_HAVE_GC, /* tp_flags */
664 zipimporter_doc, /* tp_doc */
665 zipimporter_traverse, /* tp_traverse */
666 0, /* tp_clear */
667 0, /* tp_richcompare */
668 0, /* tp_weaklistoffset */
669 0, /* tp_iter */
670 0, /* tp_iternext */
671 zipimporter_methods, /* tp_methods */
672 zipimporter_members, /* tp_members */
673 0, /* tp_getset */
674 0, /* tp_base */
675 0, /* tp_dict */
676 0, /* tp_descr_get */
677 0, /* tp_descr_set */
678 0, /* tp_dictoffset */
679 (initproc)zipimporter_init, /* tp_init */
680 PyType_GenericAlloc, /* tp_alloc */
681 PyType_GenericNew, /* tp_new */
682 PyObject_GC_Del, /* tp_free */
Just van Rossum52e14d62002-12-30 22:08:05 +0000683};
684
685
686/* implementation */
687
Just van Rossum52e14d62002-12-30 22:08:05 +0000688/* Given a buffer, return the long that is represented by the first
689 4 bytes, encoded as little endian. This partially reimplements
690 marshal.c:r_long() */
691static long
692get_long(unsigned char *buf) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000693 long x;
694 x = buf[0];
695 x |= (long)buf[1] << 8;
696 x |= (long)buf[2] << 16;
697 x |= (long)buf[3] << 24;
Just van Rossum52e14d62002-12-30 22:08:05 +0000698#if SIZEOF_LONG > 4
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000699 /* Sign extension for 64-bit machines */
700 x |= -(x & 0x80000000L);
Just van Rossum52e14d62002-12-30 22:08:05 +0000701#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000702 return x;
Just van Rossum52e14d62002-12-30 22:08:05 +0000703}
704
705/*
706 read_directory(archive) -> files dict (new reference)
707
708 Given a path to a Zip archive, build a dict, mapping file names
709 (local to the archive, using SEP as a separator) to toc entries.
710
711 A toc_entry is a tuple:
712
Victor Stinner08654e12010-10-18 12:09:02 +0000713 (__file__, # value to use for __file__, available for all files,
714 # encoded to the filesystem encoding
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000715 compress, # compression kind; 0 for uncompressed
716 data_size, # size of compressed data on disk
717 file_size, # size of decompressed data
718 file_offset, # offset of file header from start of archive
719 time, # mod time of file (in dos format)
720 date, # mod data of file (in dos format)
721 crc, # crc checksum of the data
Victor Stinnerc342fca2010-10-18 11:39:05 +0000722 )
Just van Rossum52e14d62002-12-30 22:08:05 +0000723
724 Directories can be recognized by the trailing SEP in the name,
725 data_size and file_offset are 0.
726*/
727static PyObject *
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400728read_directory(PyObject *archive)
Just van Rossum52e14d62002-12-30 22:08:05 +0000729{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000730 PyObject *files = NULL;
731 FILE *fp;
Victor Stinnerd36c8212010-10-18 12:13:46 +0000732 unsigned short flags;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000733 long compress, crc, data_size, file_size, file_offset, date, time;
734 long header_offset, name_size, header_size, header_position;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200735 long l, count;
736 Py_ssize_t i;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000737 char name[MAXPATHLEN + 5];
Victor Stinner2460a432010-08-16 17:54:28 +0000738 PyObject *nameobj = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000739 char *p, endof_central_dir[22];
740 long arc_offset; /* offset from beginning of file to start of zip-archive */
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100741 PyObject *path;
Victor Stinnerd36c8212010-10-18 12:13:46 +0000742 const char *charset;
Victor Stinner4ee65a92011-01-22 10:30:29 +0000743 int bootstrap;
Just van Rossum52e14d62002-12-30 22:08:05 +0000744
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400745 fp = _Py_fopen(archive, "rb");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000746 if (fp == NULL) {
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400747 PyErr_Format(ZipImportError, "can't open Zip file: %R", archive);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000748 return NULL;
749 }
750 fseek(fp, -22, SEEK_END);
751 header_position = ftell(fp);
752 if (fread(endof_central_dir, 1, 22, fp) != 22) {
753 fclose(fp);
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400754 PyErr_Format(ZipImportError, "can't read Zip file: %R", archive);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000755 return NULL;
756 }
757 if (get_long((unsigned char *)endof_central_dir) != 0x06054B50) {
758 /* Bad: End of Central Dir signature */
759 fclose(fp);
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400760 PyErr_Format(ZipImportError, "not a Zip file: %R", archive);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000761 return NULL;
762 }
Just van Rossum52e14d62002-12-30 22:08:05 +0000763
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000764 header_size = get_long((unsigned char *)endof_central_dir + 12);
765 header_offset = get_long((unsigned char *)endof_central_dir + 16);
766 arc_offset = header_position - header_offset - header_size;
767 header_offset += arc_offset;
Just van Rossum52e14d62002-12-30 22:08:05 +0000768
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000769 files = PyDict_New();
770 if (files == NULL)
771 goto error;
Just van Rossum52e14d62002-12-30 22:08:05 +0000772
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000773 /* Start of Central Directory */
774 count = 0;
775 for (;;) {
776 PyObject *t;
777 int err;
Just van Rossum52e14d62002-12-30 22:08:05 +0000778
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000779 fseek(fp, header_offset, 0); /* Start of file header */
780 l = PyMarshal_ReadLongFromFile(fp);
781 if (l != 0x02014B50)
782 break; /* Bad: Central Dir File Header */
Victor Stinnerd36c8212010-10-18 12:13:46 +0000783 fseek(fp, header_offset + 8, 0);
784 flags = (unsigned short)PyMarshal_ReadShortFromFile(fp);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000785 compress = PyMarshal_ReadShortFromFile(fp);
786 time = PyMarshal_ReadShortFromFile(fp);
787 date = PyMarshal_ReadShortFromFile(fp);
788 crc = PyMarshal_ReadLongFromFile(fp);
789 data_size = PyMarshal_ReadLongFromFile(fp);
790 file_size = PyMarshal_ReadLongFromFile(fp);
791 name_size = PyMarshal_ReadShortFromFile(fp);
792 header_size = 46 + name_size +
793 PyMarshal_ReadShortFromFile(fp) +
794 PyMarshal_ReadShortFromFile(fp);
795 fseek(fp, header_offset + 42, 0);
796 file_offset = PyMarshal_ReadLongFromFile(fp) + arc_offset;
797 if (name_size > MAXPATHLEN)
798 name_size = MAXPATHLEN;
Just van Rossum52e14d62002-12-30 22:08:05 +0000799
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000800 p = name;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200801 for (i = 0; i < (Py_ssize_t)name_size; i++) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000802 *p = (char)getc(fp);
803 if (*p == '/')
804 *p = SEP;
805 p++;
806 }
807 *p = 0; /* Add terminating null byte */
808 header_offset += header_size;
Just van Rossum52e14d62002-12-30 22:08:05 +0000809
Victor Stinner4ee65a92011-01-22 10:30:29 +0000810 bootstrap = 0;
Victor Stinnerd36c8212010-10-18 12:13:46 +0000811 if (flags & 0x0800)
812 charset = "utf-8";
Victor Stinner4ee65a92011-01-22 10:30:29 +0000813 else if (!PyThreadState_GET()->interp->codecs_initialized) {
814 /* During bootstrap, we may need to load the encodings
815 package from a ZIP file. But the cp437 encoding is implemented
816 in Python in the encodings package.
817
818 Break out of this dependency by assuming that the path to
819 the encodings module is ASCII-only. */
820 charset = "ascii";
821 bootstrap = 1;
822 }
Victor Stinnerd36c8212010-10-18 12:13:46 +0000823 else
824 charset = "cp437";
825 nameobj = PyUnicode_Decode(name, name_size, charset, NULL);
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200826 if (PyUnicode_READY(nameobj) == -1)
827 goto error;
Victor Stinner4ee65a92011-01-22 10:30:29 +0000828 if (nameobj == NULL) {
829 if (bootstrap)
830 PyErr_Format(PyExc_NotImplementedError,
831 "bootstrap issue: python%i%i.zip contains non-ASCII "
832 "filenames without the unicode flag",
833 PY_MAJOR_VERSION, PY_MINOR_VERSION);
Victor Stinner2460a432010-08-16 17:54:28 +0000834 goto error;
Victor Stinner4ee65a92011-01-22 10:30:29 +0000835 }
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100836 path = PyUnicode_FromFormat("%U%c%U", archive, SEP, nameobj);
837 if (path == NULL)
Victor Stinner2460a432010-08-16 17:54:28 +0000838 goto error;
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100839 t = Py_BuildValue("Niiiiiii", path, compress, data_size,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000840 file_size, file_offset, time, date, crc);
841 if (t == NULL)
842 goto error;
Victor Stinner2460a432010-08-16 17:54:28 +0000843 err = PyDict_SetItem(files, nameobj, t);
844 Py_CLEAR(nameobj);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000845 Py_DECREF(t);
846 if (err != 0)
847 goto error;
848 count++;
849 }
850 fclose(fp);
851 if (Py_VerboseFlag)
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400852 PySys_FormatStderr("# zipimport: found %ld names in %R\n",
853 count, archive);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000854 return files;
Just van Rossum52e14d62002-12-30 22:08:05 +0000855error:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000856 fclose(fp);
857 Py_XDECREF(files);
Victor Stinner2460a432010-08-16 17:54:28 +0000858 Py_XDECREF(nameobj);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000859 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +0000860}
861
862/* Return the zlib.decompress function object, or NULL if zlib couldn't
863 be imported. The function is cached when found, so subsequent calls
Victor Stinner4925cde2011-05-20 00:16:09 +0200864 don't import zlib again. */
Just van Rossum52e14d62002-12-30 22:08:05 +0000865static PyObject *
866get_decompress_func(void)
867{
Victor Stinner4925cde2011-05-20 00:16:09 +0200868 static int importing_zlib = 0;
869 PyObject *zlib;
870 PyObject *decompress;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +0200871 _Py_IDENTIFIER(decompress);
Just van Rossum52e14d62002-12-30 22:08:05 +0000872
Victor Stinner4925cde2011-05-20 00:16:09 +0200873 if (importing_zlib != 0)
874 /* Someone has a zlib.py[co] in their Zip file;
875 let's avoid a stack overflow. */
876 return NULL;
877 importing_zlib = 1;
878 zlib = PyImport_ImportModuleNoBlock("zlib");
879 importing_zlib = 0;
880 if (zlib != NULL) {
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +0200881 decompress = _PyObject_GetAttrId(zlib,
882 &PyId_decompress);
Victor Stinner4925cde2011-05-20 00:16:09 +0200883 Py_DECREF(zlib);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000884 }
Victor Stinner4925cde2011-05-20 00:16:09 +0200885 else {
886 PyErr_Clear();
887 decompress = NULL;
888 }
889 if (Py_VerboseFlag)
890 PySys_WriteStderr("# zipimport: zlib %s\n",
891 zlib != NULL ? "available": "UNAVAILABLE");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000892 return decompress;
Just van Rossum52e14d62002-12-30 22:08:05 +0000893}
894
895/* Given a path to a Zip file and a toc_entry, return the (uncompressed)
896 data as a new reference. */
897static PyObject *
Victor Stinner60fe8d92010-08-16 23:48:11 +0000898get_data(PyObject *archive, PyObject *toc_entry)
Just van Rossum52e14d62002-12-30 22:08:05 +0000899{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000900 PyObject *raw_data, *data = NULL, *decompress;
901 char *buf;
902 FILE *fp;
903 int err;
904 Py_ssize_t bytes_read = 0;
905 long l;
Victor Stinner60fe8d92010-08-16 23:48:11 +0000906 PyObject *datapath;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000907 long compress, data_size, file_size, file_offset, bytes_size;
908 long time, date, crc;
Just van Rossum52e14d62002-12-30 22:08:05 +0000909
Victor Stinner60fe8d92010-08-16 23:48:11 +0000910 if (!PyArg_ParseTuple(toc_entry, "Olllllll", &datapath, &compress,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000911 &data_size, &file_size, &file_offset, &time,
912 &date, &crc)) {
913 return NULL;
914 }
Just van Rossum52e14d62002-12-30 22:08:05 +0000915
Victor Stinner60fe8d92010-08-16 23:48:11 +0000916 fp = _Py_fopen(archive, "rb");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000917 if (!fp) {
918 PyErr_Format(PyExc_IOError,
Victor Stinner60fe8d92010-08-16 23:48:11 +0000919 "zipimport: can not open file %U", archive);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000920 return NULL;
921 }
Just van Rossum52e14d62002-12-30 22:08:05 +0000922
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000923 /* Check to make sure the local file header is correct */
924 fseek(fp, file_offset, 0);
925 l = PyMarshal_ReadLongFromFile(fp);
926 if (l != 0x04034B50) {
927 /* Bad: Local File Header */
928 PyErr_Format(ZipImportError,
Victor Stinner60fe8d92010-08-16 23:48:11 +0000929 "bad local file header in %U",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000930 archive);
931 fclose(fp);
932 return NULL;
933 }
934 fseek(fp, file_offset + 26, 0);
935 l = 30 + PyMarshal_ReadShortFromFile(fp) +
936 PyMarshal_ReadShortFromFile(fp); /* local header size */
937 file_offset += l; /* Start of file data */
Just van Rossum52e14d62002-12-30 22:08:05 +0000938
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000939 bytes_size = compress == 0 ? data_size : data_size + 1;
940 if (bytes_size == 0)
941 bytes_size++;
942 raw_data = PyBytes_FromStringAndSize((char *)NULL, bytes_size);
Just van Rossum52e14d62002-12-30 22:08:05 +0000943
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000944 if (raw_data == NULL) {
945 fclose(fp);
946 return NULL;
947 }
948 buf = PyBytes_AsString(raw_data);
Just van Rossum52e14d62002-12-30 22:08:05 +0000949
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000950 err = fseek(fp, file_offset, 0);
951 if (err == 0)
952 bytes_read = fread(buf, 1, data_size, fp);
953 fclose(fp);
954 if (err || bytes_read != data_size) {
955 PyErr_SetString(PyExc_IOError,
956 "zipimport: can't read data");
957 Py_DECREF(raw_data);
958 return NULL;
959 }
Just van Rossum52e14d62002-12-30 22:08:05 +0000960
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000961 if (compress != 0) {
962 buf[data_size] = 'Z'; /* saw this in zipfile.py */
963 data_size++;
964 }
965 buf[data_size] = '\0';
Just van Rossum52e14d62002-12-30 22:08:05 +0000966
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000967 if (compress == 0) { /* data is not compressed */
968 data = PyBytes_FromStringAndSize(buf, data_size);
969 Py_DECREF(raw_data);
970 return data;
971 }
972
973 /* Decompress with zlib */
974 decompress = get_decompress_func();
975 if (decompress == NULL) {
976 PyErr_SetString(ZipImportError,
977 "can't decompress data; "
978 "zlib not available");
979 goto error;
980 }
981 data = PyObject_CallFunction(decompress, "Oi", raw_data, -15);
Victor Stinner4925cde2011-05-20 00:16:09 +0200982 Py_DECREF(decompress);
Just van Rossum52e14d62002-12-30 22:08:05 +0000983error:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000984 Py_DECREF(raw_data);
985 return data;
Just van Rossum52e14d62002-12-30 22:08:05 +0000986}
987
988/* Lenient date/time comparison function. The precision of the mtime
989 in the archive is lower than the mtime stored in a .pyc: we
990 must allow a difference of at most one second. */
991static int
992eq_mtime(time_t t1, time_t t2)
993{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000994 time_t d = t1 - t2;
995 if (d < 0)
996 d = -d;
997 /* dostime only stores even seconds, so be lenient */
998 return d <= 1;
Just van Rossum52e14d62002-12-30 22:08:05 +0000999}
1000
1001/* Given the contents of a .py[co] file in a buffer, unmarshal the data
1002 and return the code object. Return None if it the magic word doesn't
1003 match (we do this instead of raising an exception as we fall back
1004 to .py if available and we don't want to mask other errors).
1005 Returns a new reference. */
1006static PyObject *
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001007unmarshal_code(PyObject *pathname, PyObject *data, time_t mtime)
Just van Rossum52e14d62002-12-30 22:08:05 +00001008{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001009 PyObject *code;
1010 char *buf = PyBytes_AsString(data);
1011 Py_ssize_t size = PyBytes_Size(data);
Just van Rossum52e14d62002-12-30 22:08:05 +00001012
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001013 if (size <= 9) {
1014 PyErr_SetString(ZipImportError,
1015 "bad pyc data");
1016 return NULL;
1017 }
Just van Rossum52e14d62002-12-30 22:08:05 +00001018
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001019 if (get_long((unsigned char *)buf) != PyImport_GetMagicNumber()) {
1020 if (Py_VerboseFlag)
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001021 PySys_FormatStderr("# %R has bad magic\n",
1022 pathname);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001023 Py_INCREF(Py_None);
1024 return Py_None; /* signal caller to try alternative */
1025 }
Just van Rossum52e14d62002-12-30 22:08:05 +00001026
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001027 if (mtime != 0 && !eq_mtime(get_long((unsigned char *)buf + 4),
1028 mtime)) {
1029 if (Py_VerboseFlag)
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001030 PySys_FormatStderr("# %R has bad mtime\n",
1031 pathname);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001032 Py_INCREF(Py_None);
1033 return Py_None; /* signal caller to try alternative */
1034 }
Just van Rossum52e14d62002-12-30 22:08:05 +00001035
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001036 code = PyMarshal_ReadObjectFromString(buf + 8, size - 8);
1037 if (code == NULL)
1038 return NULL;
1039 if (!PyCode_Check(code)) {
1040 Py_DECREF(code);
1041 PyErr_Format(PyExc_TypeError,
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001042 "compiled module %R is not a code object",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001043 pathname);
1044 return NULL;
1045 }
1046 return code;
Just van Rossum52e14d62002-12-30 22:08:05 +00001047}
1048
1049/* Replace any occurances of "\r\n?" in the input string with "\n".
1050 This converts DOS and Mac line endings to Unix line endings.
1051 Also append a trailing "\n" to be compatible with
1052 PyParser_SimpleParseFile(). Returns a new reference. */
1053static PyObject *
1054normalize_line_endings(PyObject *source)
1055{
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001056 char *buf, *q, *p;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001057 PyObject *fixed_source;
1058 int len = 0;
Just van Rossum52e14d62002-12-30 22:08:05 +00001059
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001060 p = PyBytes_AsString(source);
1061 if (p == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001062 return PyBytes_FromStringAndSize("\n\0", 2);
1063 }
Thomas Wouters00ee7ba2006-08-21 19:07:27 +00001064
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001065 /* one char extra for trailing \n and one for terminating \0 */
1066 buf = (char *)PyMem_Malloc(PyBytes_Size(source) + 2);
1067 if (buf == NULL) {
1068 PyErr_SetString(PyExc_MemoryError,
1069 "zipimport: no memory to allocate "
1070 "source buffer");
1071 return NULL;
1072 }
1073 /* replace "\r\n?" by "\n" */
1074 for (q = buf; *p != '\0'; p++) {
1075 if (*p == '\r') {
1076 *q++ = '\n';
1077 if (*(p + 1) == '\n')
1078 p++;
1079 }
1080 else
1081 *q++ = *p;
1082 len++;
1083 }
1084 *q++ = '\n'; /* add trailing \n */
1085 *q = '\0';
1086 fixed_source = PyBytes_FromStringAndSize(buf, len + 2);
1087 PyMem_Free(buf);
1088 return fixed_source;
Just van Rossum52e14d62002-12-30 22:08:05 +00001089}
1090
1091/* Given a string buffer containing Python source code, compile it
1092 return and return a code object as a new reference. */
1093static PyObject *
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001094compile_source(PyObject *pathname, PyObject *source)
Just van Rossum52e14d62002-12-30 22:08:05 +00001095{
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001096 PyObject *code, *fixed_source, *pathbytes;
Just van Rossum52e14d62002-12-30 22:08:05 +00001097
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001098 pathbytes = PyUnicode_EncodeFSDefault(pathname);
1099 if (pathbytes == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001100 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +00001101
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001102 fixed_source = normalize_line_endings(source);
1103 if (fixed_source == NULL) {
1104 Py_DECREF(pathbytes);
1105 return NULL;
1106 }
1107
1108 code = Py_CompileString(PyBytes_AsString(fixed_source),
1109 PyBytes_AsString(pathbytes),
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001110 Py_file_input);
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001111 Py_DECREF(pathbytes);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001112 Py_DECREF(fixed_source);
1113 return code;
Just van Rossum52e14d62002-12-30 22:08:05 +00001114}
1115
1116/* Convert the date/time values found in the Zip archive to a value
1117 that's compatible with the time stamp stored in .pyc files. */
Neal Norwitz29fd2ba2003-03-23 13:21:03 +00001118static time_t
1119parse_dostime(int dostime, int dosdate)
Just van Rossum52e14d62002-12-30 22:08:05 +00001120{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001121 struct tm stm;
Just van Rossum52e14d62002-12-30 22:08:05 +00001122
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001123 memset((void *) &stm, '\0', sizeof(stm));
Christian Heimes679db4a2008-01-18 09:56:22 +00001124
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001125 stm.tm_sec = (dostime & 0x1f) * 2;
1126 stm.tm_min = (dostime >> 5) & 0x3f;
1127 stm.tm_hour = (dostime >> 11) & 0x1f;
1128 stm.tm_mday = dosdate & 0x1f;
1129 stm.tm_mon = ((dosdate >> 5) & 0x0f) - 1;
1130 stm.tm_year = ((dosdate >> 9) & 0x7f) + 80;
1131 stm.tm_isdst = -1; /* wday/yday is ignored */
Just van Rossum52e14d62002-12-30 22:08:05 +00001132
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001133 return mktime(&stm);
Just van Rossum52e14d62002-12-30 22:08:05 +00001134}
1135
1136/* Given a path to a .pyc or .pyo file in the archive, return the
Ezio Melotti13925002011-03-16 11:05:33 +02001137 modification time of the matching .py file, or 0 if no source
Just van Rossum52e14d62002-12-30 22:08:05 +00001138 is available. */
1139static time_t
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001140get_mtime_of_source(ZipImporter *self, PyObject *path)
Just van Rossum52e14d62002-12-30 22:08:05 +00001141{
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001142 PyObject *toc_entry, *stripped;
1143 time_t mtime;
1144
1145 /* strip 'c' or 'o' from *.py[co] */
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001146 if (PyUnicode_READY(path) == -1)
1147 return (time_t)-1;
1148 stripped = PyUnicode_FromKindAndData(PyUnicode_KIND(path),
1149 PyUnicode_DATA(path),
1150 PyUnicode_GET_LENGTH(path) - 1);
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001151 if (stripped == NULL)
1152 return (time_t)-1;
1153
1154 toc_entry = PyDict_GetItem(self->files, stripped);
1155 Py_DECREF(stripped);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001156 if (toc_entry != NULL && PyTuple_Check(toc_entry) &&
1157 PyTuple_Size(toc_entry) == 8) {
1158 /* fetch the time stamp of the .py file for comparison
1159 with an embedded pyc time stamp */
1160 int time, date;
1161 time = PyLong_AsLong(PyTuple_GetItem(toc_entry, 5));
1162 date = PyLong_AsLong(PyTuple_GetItem(toc_entry, 6));
1163 mtime = parse_dostime(time, date);
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001164 } else
1165 mtime = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001166 return mtime;
Just van Rossum52e14d62002-12-30 22:08:05 +00001167}
1168
1169/* Return the code object for the module named by 'fullname' from the
1170 Zip archive as a new reference. */
1171static PyObject *
1172get_code_from_data(ZipImporter *self, int ispackage, int isbytecode,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001173 time_t mtime, PyObject *toc_entry)
Just van Rossum52e14d62002-12-30 22:08:05 +00001174{
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001175 PyObject *data, *modpath, *code;
Just van Rossum52e14d62002-12-30 22:08:05 +00001176
Victor Stinner60fe8d92010-08-16 23:48:11 +00001177 data = get_data(self->archive, toc_entry);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001178 if (data == NULL)
1179 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +00001180
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001181 modpath = PyTuple_GetItem(toc_entry, 0);
Victor Stinner2a94f4c2010-10-18 12:15:34 +00001182 if (isbytecode)
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001183 code = unmarshal_code(modpath, data, mtime);
Victor Stinner2a94f4c2010-10-18 12:15:34 +00001184 else
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001185 code = compile_source(modpath, data);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001186 Py_DECREF(data);
1187 return code;
Just van Rossum52e14d62002-12-30 22:08:05 +00001188}
1189
Ezio Melotti42da6632011-03-15 05:18:48 +02001190/* Get the code object associated with the module specified by
Just van Rossum52e14d62002-12-30 22:08:05 +00001191 'fullname'. */
1192static PyObject *
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001193get_module_code(ZipImporter *self, PyObject *fullname,
Victor Stinner08654e12010-10-18 12:09:02 +00001194 int *p_ispackage, PyObject **p_modpath)
Just van Rossum52e14d62002-12-30 22:08:05 +00001195{
Gregory P. Smith95c7c462011-05-21 05:19:42 -07001196 PyObject *code = NULL, *toc_entry, *subname;
Victor Stinner9a2261a2011-05-26 13:59:41 +02001197 PyObject *path, *fullpath = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001198 struct st_zip_searchorder *zso;
Just van Rossum52e14d62002-12-30 22:08:05 +00001199
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001200 subname = get_subname(fullname);
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001201 if (subname == NULL)
1202 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +00001203
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001204 path = make_filename(self->prefix, subname);
1205 Py_DECREF(subname);
1206 if (path == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001207 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +00001208
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001209 for (zso = zip_searchorder; *zso->suffix; zso++) {
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001210 code = NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +00001211
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001212 fullpath = PyUnicode_FromFormat("%U%s", path, zso->suffix);
1213 if (fullpath == NULL)
1214 goto exit;
1215
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001216 if (Py_VerboseFlag > 1)
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001217 PySys_FormatStderr("# trying %U%c%U\n",
1218 self->archive, (int)SEP, fullpath);
1219 toc_entry = PyDict_GetItem(self->files, fullpath);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001220 if (toc_entry != NULL) {
1221 time_t mtime = 0;
1222 int ispackage = zso->type & IS_PACKAGE;
1223 int isbytecode = zso->type & IS_BYTECODE;
Just van Rossum52e14d62002-12-30 22:08:05 +00001224
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001225 if (isbytecode) {
1226 mtime = get_mtime_of_source(self, fullpath);
1227 if (mtime == (time_t)-1 && PyErr_Occurred()) {
1228 goto exit;
1229 }
1230 }
1231 Py_CLEAR(fullpath);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001232 if (p_ispackage != NULL)
1233 *p_ispackage = ispackage;
1234 code = get_code_from_data(self, ispackage,
1235 isbytecode, mtime,
1236 toc_entry);
1237 if (code == Py_None) {
1238 /* bad magic number or non-matching mtime
1239 in byte code, try next */
1240 Py_DECREF(code);
1241 continue;
1242 }
Victor Stinner08654e12010-10-18 12:09:02 +00001243 if (code != NULL && p_modpath != NULL) {
1244 *p_modpath = PyTuple_GetItem(toc_entry, 0);
1245 Py_INCREF(*p_modpath);
1246 }
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001247 goto exit;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001248 }
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001249 else
1250 Py_CLEAR(fullpath);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001251 }
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001252 PyErr_Format(ZipImportError, "can't find module %R", fullname);
1253exit:
1254 Py_DECREF(path);
1255 Py_XDECREF(fullpath);
1256 return code;
Just van Rossum52e14d62002-12-30 22:08:05 +00001257}
1258
1259
1260/* Module init */
1261
1262PyDoc_STRVAR(zipimport_doc,
1263"zipimport provides support for importing Python modules from Zip archives.\n\
1264\n\
1265This module exports three objects:\n\
1266- zipimporter: a class; its constructor takes a path to a Zip archive.\n\
Fredrik Lundhb84b35f2006-01-15 15:00:40 +00001267- ZipImportError: exception raised by zipimporter objects. It's a\n\
Just van Rossum52e14d62002-12-30 22:08:05 +00001268 subclass of ImportError, so it can be caught as ImportError, too.\n\
1269- _zip_directory_cache: a dict, mapping archive paths to zip directory\n\
1270 info dicts, as used in zipimporter._files.\n\
1271\n\
1272It is usually not needed to use the zipimport module explicitly; it is\n\
1273used by the builtin import mechanism for sys.path items that are paths\n\
1274to Zip archives.");
1275
Martin v. Löwis1a214512008-06-11 05:26:20 +00001276static struct PyModuleDef zipimportmodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001277 PyModuleDef_HEAD_INIT,
1278 "zipimport",
1279 zipimport_doc,
1280 -1,
1281 NULL,
1282 NULL,
1283 NULL,
1284 NULL,
1285 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +00001286};
1287
Just van Rossum52e14d62002-12-30 22:08:05 +00001288PyMODINIT_FUNC
Martin v. Löwis1a214512008-06-11 05:26:20 +00001289PyInit_zipimport(void)
Just van Rossum52e14d62002-12-30 22:08:05 +00001290{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001291 PyObject *mod;
Just van Rossum52e14d62002-12-30 22:08:05 +00001292
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001293 if (PyType_Ready(&ZipImporter_Type) < 0)
1294 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +00001295
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001296 /* Correct directory separator */
1297 zip_searchorder[0].suffix[0] = SEP;
1298 zip_searchorder[1].suffix[0] = SEP;
1299 zip_searchorder[2].suffix[0] = SEP;
1300 if (Py_OptimizeFlag) {
1301 /* Reverse *.pyc and *.pyo */
1302 struct st_zip_searchorder tmp;
1303 tmp = zip_searchorder[0];
1304 zip_searchorder[0] = zip_searchorder[1];
1305 zip_searchorder[1] = tmp;
1306 tmp = zip_searchorder[3];
1307 zip_searchorder[3] = zip_searchorder[4];
1308 zip_searchorder[4] = tmp;
1309 }
Just van Rossum52e14d62002-12-30 22:08:05 +00001310
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001311 mod = PyModule_Create(&zipimportmodule);
1312 if (mod == NULL)
1313 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +00001314
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001315 ZipImportError = PyErr_NewException("zipimport.ZipImportError",
1316 PyExc_ImportError, NULL);
1317 if (ZipImportError == NULL)
1318 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +00001319
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001320 Py_INCREF(ZipImportError);
1321 if (PyModule_AddObject(mod, "ZipImportError",
1322 ZipImportError) < 0)
1323 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +00001324
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001325 Py_INCREF(&ZipImporter_Type);
1326 if (PyModule_AddObject(mod, "zipimporter",
1327 (PyObject *)&ZipImporter_Type) < 0)
1328 return NULL;
Just van Rossumf8b6de12002-12-31 09:51:59 +00001329
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001330 zip_directory_cache = PyDict_New();
1331 if (zip_directory_cache == NULL)
1332 return NULL;
1333 Py_INCREF(zip_directory_cache);
1334 if (PyModule_AddObject(mod, "_zip_directory_cache",
1335 zip_directory_cache) < 0)
1336 return NULL;
1337 return mod;
Just van Rossum52e14d62002-12-30 22:08:05 +00001338}