blob: 2293e66a6b91eb40a36325172ae5ba6ed6c51efe [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{
Victor Stinner2460a432010-08-16 17:54:28 +000066 PyObject *pathobj, *files;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +020067 Py_UCS4 *path, *p, *prefix, buf[MAXPATHLEN+2];
Victor Stinner2b8dab72010-08-14 14:54:10 +000068 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
Martin v. Löwisd63a3b82011-09-28 07:41:54 +020077 if (PyUnicode_READY(pathobj) == -1)
78 return -1;
79
Victor Stinner2b8dab72010-08-14 14:54:10 +000080 /* copy path to buf */
Martin v. Löwisd63a3b82011-09-28 07:41:54 +020081 len = PyUnicode_GET_LENGTH(pathobj);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000082 if (len == 0) {
83 PyErr_SetString(ZipImportError, "archive path is empty");
Victor Stinner2b8dab72010-08-14 14:54:10 +000084 goto error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000085 }
86 if (len >= MAXPATHLEN) {
87 PyErr_SetString(ZipImportError,
88 "archive path too long");
Victor Stinner2b8dab72010-08-14 14:54:10 +000089 goto error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000090 }
Georg Brandl4cb0de22011-09-28 21:49:49 +020091 if (!PyUnicode_AsUCS4(pathobj, buf, Py_ARRAY_LENGTH(buf), 1))
Martin v. Löwisd63a3b82011-09-28 07:41:54 +020092 goto error;
Just van Rossum52e14d62002-12-30 22:08:05 +000093
94#ifdef ALTSEP
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000095 for (p = buf; *p; p++) {
96 if (*p == ALTSEP)
97 *p = SEP;
98 }
Just van Rossum52e14d62002-12-30 22:08:05 +000099#endif
100
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000101 path = NULL;
102 prefix = NULL;
103 for (;;) {
104 struct stat statbuf;
105 int rv;
Just van Rossum52e14d62002-12-30 22:08:05 +0000106
Victor Stinner2b8dab72010-08-14 14:54:10 +0000107 if (pathobj == NULL) {
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200108 pathobj = PyUnicode_FromKindAndData(PyUnicode_4BYTE_KIND,
109 buf, len);
Victor Stinner2b8dab72010-08-14 14:54:10 +0000110 if (pathobj == NULL)
111 goto error;
112 }
113 rv = _Py_stat(pathobj, &statbuf);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000114 if (rv == 0) {
115 /* it exists */
116 if (S_ISREG(statbuf.st_mode))
117 /* it's a file */
118 path = buf;
119 break;
120 }
Victor Stinner2b8dab72010-08-14 14:54:10 +0000121 else if (PyErr_Occurred())
122 goto error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000123 /* back up one path element */
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200124 p = Py_UCS4_strrchr(buf, SEP);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000125 if (prefix != NULL)
126 *prefix = SEP;
127 if (p == NULL)
128 break;
129 *p = '\0';
Victor Stinner2b8dab72010-08-14 14:54:10 +0000130 len = p - buf;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000131 prefix = p;
Victor Stinner2b8dab72010-08-14 14:54:10 +0000132 Py_CLEAR(pathobj);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000133 }
Victor Stinner2b8dab72010-08-14 14:54:10 +0000134 if (path == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000135 PyErr_SetString(ZipImportError, "not a Zip file");
Victor Stinner2b8dab72010-08-14 14:54:10 +0000136 goto error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000137 }
Just van Rossum52e14d62002-12-30 22:08:05 +0000138
Victor Stinner2b8dab72010-08-14 14:54:10 +0000139 files = PyDict_GetItem(zip_directory_cache, pathobj);
140 if (files == NULL) {
Victor Stinner2460a432010-08-16 17:54:28 +0000141 files = read_directory(pathobj);
Victor Stinner2b8dab72010-08-14 14:54:10 +0000142 if (files == NULL)
143 goto error;
144 if (PyDict_SetItem(zip_directory_cache, pathobj, files) != 0)
145 goto error;
146 }
147 else
148 Py_INCREF(files);
149 self->files = files;
150
151 self->archive = pathobj;
152 pathobj = NULL;
153
154 if (prefix != NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000155 prefix++;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200156 len = Py_UCS4_strlen(prefix);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000157 if (prefix[len-1] != SEP) {
158 /* add trailing SEP */
159 prefix[len] = SEP;
160 prefix[len + 1] = '\0';
Victor Stinner2b8dab72010-08-14 14:54:10 +0000161 len++;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000162 }
163 }
Victor Stinner2b8dab72010-08-14 14:54:10 +0000164 else
165 len = 0;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200166 self->prefix = PyUnicode_FromKindAndData(PyUnicode_4BYTE_KIND,
167 prefix, len);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000168 if (self->prefix == NULL)
Victor Stinner2b8dab72010-08-14 14:54:10 +0000169 goto error;
Just van Rossum52e14d62002-12-30 22:08:05 +0000170
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000171 return 0;
Victor Stinner2b8dab72010-08-14 14:54:10 +0000172
173error:
174 Py_XDECREF(pathobj);
175 return -1;
Just van Rossum52e14d62002-12-30 22:08:05 +0000176}
177
178/* GC support. */
179static int
180zipimporter_traverse(PyObject *obj, visitproc visit, void *arg)
181{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000182 ZipImporter *self = (ZipImporter *)obj;
183 Py_VISIT(self->files);
184 return 0;
Just van Rossum52e14d62002-12-30 22:08:05 +0000185}
186
187static void
188zipimporter_dealloc(ZipImporter *self)
189{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000190 PyObject_GC_UnTrack(self);
191 Py_XDECREF(self->archive);
192 Py_XDECREF(self->prefix);
193 Py_XDECREF(self->files);
194 Py_TYPE(self)->tp_free((PyObject *)self);
Just van Rossum52e14d62002-12-30 22:08:05 +0000195}
196
197static PyObject *
198zipimporter_repr(ZipImporter *self)
199{
Victor Stinner028dd972010-08-17 00:04:48 +0000200 if (self->archive == NULL)
201 return PyUnicode_FromString("<zipimporter object \"???\">");
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200202 else if (self->prefix != NULL && PyUnicode_GET_LENGTH(self->prefix) != 0)
Victor Stinner07298a12010-10-18 22:45:54 +0000203 return PyUnicode_FromFormat("<zipimporter object \"%U%c%U\">",
Victor Stinner028dd972010-08-17 00:04:48 +0000204 self->archive, SEP, self->prefix);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000205 else
Victor Stinner07298a12010-10-18 22:45:54 +0000206 return PyUnicode_FromFormat("<zipimporter object \"%U\">",
Victor Stinner028dd972010-08-17 00:04:48 +0000207 self->archive);
Just van Rossum52e14d62002-12-30 22:08:05 +0000208}
209
210/* return fullname.split(".")[-1] */
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400211static PyObject *
212get_subname(PyObject *fullname)
Just van Rossum52e14d62002-12-30 22:08:05 +0000213{
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400214 Py_ssize_t len;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200215 Py_UCS4 *subname, *fullname_ucs4;
216 fullname_ucs4 = PyUnicode_AsUCS4Copy(fullname);
217 if (!fullname_ucs4)
218 return NULL;
219 subname = Py_UCS4_strrchr(fullname_ucs4, '.');
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400220 if (subname == NULL) {
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200221 PyMem_Free(fullname_ucs4);
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400222 Py_INCREF(fullname);
223 return fullname;
224 } else {
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200225 PyObject *result;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000226 subname++;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200227 len = PyUnicode_GET_LENGTH(fullname);
228 len -= subname - fullname_ucs4;
229 result = PyUnicode_FromKindAndData(PyUnicode_4BYTE_KIND,
230 subname, len);
231 PyMem_Free(fullname_ucs4);
232 return result;
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400233 }
Just van Rossum52e14d62002-12-30 22:08:05 +0000234}
235
236/* Given a (sub)modulename, write the potential file path in the
237 archive (without extension) to the path buffer. Return the
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400238 length of the resulting string.
239
240 return self.prefix + name.replace('.', os.sep) */
241static PyObject*
242make_filename(PyObject *prefix, PyObject *name)
Just van Rossum52e14d62002-12-30 22:08:05 +0000243{
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400244 PyObject *pathobj;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200245 Py_UCS4 *p, *buf;
246 Py_ssize_t len;
Just van Rossum52e14d62002-12-30 22:08:05 +0000247
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200248 len = PyUnicode_GET_LENGTH(prefix) + PyUnicode_GET_LENGTH(name) + 1;
249 p = buf = PyMem_Malloc(sizeof(Py_UCS4) * len);
250 if (buf == NULL) {
251 PyErr_NoMemory();
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400252 return NULL;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200253 }
Just van Rossum52e14d62002-12-30 22:08:05 +0000254
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200255 if (!PyUnicode_AsUCS4(prefix, p, len, 0))
256 return NULL;
257 p += PyUnicode_GET_LENGTH(prefix);
258 len -= PyUnicode_GET_LENGTH(prefix);
259 if (!PyUnicode_AsUCS4(name, p, len, 1))
260 return NULL;
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400261 for (; *p; p++) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000262 if (*p == '.')
263 *p = SEP;
264 }
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200265 pathobj = PyUnicode_FromKindAndData(PyUnicode_4BYTE_KIND,
266 buf, p-buf);
267 PyMem_Free(buf);
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400268 return pathobj;
Just van Rossum52e14d62002-12-30 22:08:05 +0000269}
270
Raymond Hettinger2c45c9a2004-11-10 13:08:35 +0000271enum zi_module_info {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000272 MI_ERROR,
273 MI_NOT_FOUND,
274 MI_MODULE,
275 MI_PACKAGE
Just van Rossum52e14d62002-12-30 22:08:05 +0000276};
277
278/* Return some information about a module. */
Raymond Hettinger2c45c9a2004-11-10 13:08:35 +0000279static enum zi_module_info
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400280get_module_info(ZipImporter *self, PyObject *fullname)
Just van Rossum52e14d62002-12-30 22:08:05 +0000281{
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400282 PyObject *subname;
283 PyObject *path, *fullpath, *item;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000284 struct st_zip_searchorder *zso;
Just van Rossum52e14d62002-12-30 22:08:05 +0000285
Victor Stinner965a8a12010-10-18 21:44:33 +0000286 subname = get_subname(fullname);
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400287 if (subname == NULL)
288 return MI_ERROR;
Just van Rossum52e14d62002-12-30 22:08:05 +0000289
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400290 path = make_filename(self->prefix, subname);
291 Py_DECREF(subname);
292 if (path == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000293 return MI_ERROR;
Just van Rossum52e14d62002-12-30 22:08:05 +0000294
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000295 for (zso = zip_searchorder; *zso->suffix; zso++) {
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400296 fullpath = PyUnicode_FromFormat("%U%s", path, zso->suffix);
297 if (fullpath == NULL) {
298 Py_DECREF(path);
299 return MI_ERROR;
300 }
301 item = PyDict_GetItem(self->files, fullpath);
302 Py_DECREF(fullpath);
303 if (item != NULL) {
304 Py_DECREF(path);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000305 if (zso->type & IS_PACKAGE)
306 return MI_PACKAGE;
307 else
308 return MI_MODULE;
309 }
310 }
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400311 Py_DECREF(path);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000312 return MI_NOT_FOUND;
Just van Rossum52e14d62002-12-30 22:08:05 +0000313}
314
315/* Check whether we can satisfy the import of the module named by
316 'fullname'. Return self if we can, None if we can't. */
317static PyObject *
318zipimporter_find_module(PyObject *obj, PyObject *args)
319{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000320 ZipImporter *self = (ZipImporter *)obj;
321 PyObject *path = NULL;
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400322 PyObject *fullname;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000323 enum zi_module_info mi;
Just van Rossum52e14d62002-12-30 22:08:05 +0000324
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400325 if (!PyArg_ParseTuple(args, "U|O:zipimporter.find_module",
Victor Stinner965a8a12010-10-18 21:44:33 +0000326 &fullname, &path))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000327 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +0000328
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000329 mi = get_module_info(self, fullname);
330 if (mi == MI_ERROR)
331 return NULL;
332 if (mi == MI_NOT_FOUND) {
333 Py_INCREF(Py_None);
334 return Py_None;
335 }
336 Py_INCREF(self);
337 return (PyObject *)self;
Just van Rossum52e14d62002-12-30 22:08:05 +0000338}
339
340/* Load and return the module named by 'fullname'. */
341static PyObject *
342zipimporter_load_module(PyObject *obj, PyObject *args)
343{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000344 ZipImporter *self = (ZipImporter *)obj;
Victor Stinner26fabe12010-10-18 12:03:25 +0000345 PyObject *code = NULL, *mod, *dict;
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400346 PyObject *fullname;
347 PyObject *modpath = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000348 int ispackage;
Just van Rossum52e14d62002-12-30 22:08:05 +0000349
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400350 if (!PyArg_ParseTuple(args, "U:zipimporter.load_module",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000351 &fullname))
352 return NULL;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200353 if (PyUnicode_READY(fullname) == -1)
354 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +0000355
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000356 code = get_module_code(self, fullname, &ispackage, &modpath);
357 if (code == NULL)
Victor Stinner26fabe12010-10-18 12:03:25 +0000358 goto error;
Just van Rossum52e14d62002-12-30 22:08:05 +0000359
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400360 mod = PyImport_AddModuleObject(fullname);
Victor Stinner26fabe12010-10-18 12:03:25 +0000361 if (mod == NULL)
362 goto error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000363 dict = PyModule_GetDict(mod);
Just van Rossum52e14d62002-12-30 22:08:05 +0000364
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000365 /* mod.__loader__ = self */
366 if (PyDict_SetItemString(dict, "__loader__", (PyObject *)self) != 0)
367 goto error;
Just van Rossum52e14d62002-12-30 22:08:05 +0000368
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000369 if (ispackage) {
370 /* add __path__ to the module *before* the code gets
371 executed */
372 PyObject *pkgpath, *fullpath;
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400373 PyObject *subname = get_subname(fullname);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000374 int err;
Just van Rossum52e14d62002-12-30 22:08:05 +0000375
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400376 fullpath = PyUnicode_FromFormat("%U%c%U%U",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000377 self->archive, SEP,
378 self->prefix, subname);
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400379 Py_DECREF(subname);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000380 if (fullpath == NULL)
381 goto error;
Just van Rossum52e14d62002-12-30 22:08:05 +0000382
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400383 pkgpath = Py_BuildValue("[N]", fullpath);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000384 if (pkgpath == NULL)
385 goto error;
386 err = PyDict_SetItemString(dict, "__path__", pkgpath);
387 Py_DECREF(pkgpath);
388 if (err != 0)
389 goto error;
390 }
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400391 mod = PyImport_ExecCodeModuleObject(fullname, code, modpath, NULL);
Victor Stinner26fabe12010-10-18 12:03:25 +0000392 Py_CLEAR(code);
393 if (mod == NULL)
394 goto error;
395
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000396 if (Py_VerboseFlag)
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400397 PySys_FormatStderr("import %U # loaded from Zip %U\n",
Victor Stinner08654e12010-10-18 12:09:02 +0000398 fullname, modpath);
399 Py_DECREF(modpath);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000400 return mod;
Just van Rossum52e14d62002-12-30 22:08:05 +0000401error:
Victor Stinner26fabe12010-10-18 12:03:25 +0000402 Py_XDECREF(code);
Victor Stinner08654e12010-10-18 12:09:02 +0000403 Py_XDECREF(modpath);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000404 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +0000405}
406
Nick Coghlanf088e5e2008-12-14 11:50:48 +0000407/* Return a string matching __file__ for the named module */
408static PyObject *
409zipimporter_get_filename(PyObject *obj, PyObject *args)
410{
411 ZipImporter *self = (ZipImporter *)obj;
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400412 PyObject *fullname, *code, *modpath;
Nick Coghlanf088e5e2008-12-14 11:50:48 +0000413 int ispackage;
414
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400415 if (!PyArg_ParseTuple(args, "U:zipimporter.get_filename",
Victor Stinner9e40fad2010-10-18 22:34:46 +0000416 &fullname))
Victor Stinnerc342fca2010-10-18 11:39:05 +0000417 return NULL;
Nick Coghlanf088e5e2008-12-14 11:50:48 +0000418
419 /* Deciding the filename requires working out where the code
420 would come from if the module was actually loaded */
421 code = get_module_code(self, fullname, &ispackage, &modpath);
422 if (code == NULL)
Victor Stinnerc342fca2010-10-18 11:39:05 +0000423 return NULL;
Nick Coghlanf088e5e2008-12-14 11:50:48 +0000424 Py_DECREF(code); /* Only need the path info */
425
Victor Stinner08654e12010-10-18 12:09:02 +0000426 return modpath;
Nick Coghlanf088e5e2008-12-14 11:50:48 +0000427}
428
Just van Rossum52e14d62002-12-30 22:08:05 +0000429/* Return a bool signifying whether the module is a package or not. */
430static PyObject *
431zipimporter_is_package(PyObject *obj, PyObject *args)
432{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000433 ZipImporter *self = (ZipImporter *)obj;
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400434 PyObject *fullname;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000435 enum zi_module_info mi;
Just van Rossum52e14d62002-12-30 22:08:05 +0000436
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400437 if (!PyArg_ParseTuple(args, "U:zipimporter.is_package",
Victor Stinner965a8a12010-10-18 21:44:33 +0000438 &fullname))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000439 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +0000440
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000441 mi = get_module_info(self, fullname);
442 if (mi == MI_ERROR)
Victor Stinner965a8a12010-10-18 21:44:33 +0000443 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000444 if (mi == MI_NOT_FOUND) {
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400445 PyErr_Format(ZipImportError, "can't find module %R", fullname);
Victor Stinner965a8a12010-10-18 21:44:33 +0000446 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000447 }
448 return PyBool_FromLong(mi == MI_PACKAGE);
Just van Rossum52e14d62002-12-30 22:08:05 +0000449}
450
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200451
Just van Rossum52e14d62002-12-30 22:08:05 +0000452static PyObject *
453zipimporter_get_data(PyObject *obj, PyObject *args)
454{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000455 ZipImporter *self = (ZipImporter *)obj;
Victor Stinner60fe8d92010-08-16 23:48:11 +0000456 PyObject *pathobj, *key;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200457 const Py_UCS4 *path;
Just van Rossum52e14d62002-12-30 22:08:05 +0000458#ifdef ALTSEP
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200459 Py_UCS4 *p;
Just van Rossum52e14d62002-12-30 22:08:05 +0000460#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000461 PyObject *toc_entry;
Victor Stinner60fe8d92010-08-16 23:48:11 +0000462 Py_ssize_t path_len, len;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200463 Py_UCS4 buf[MAXPATHLEN + 1], archive[MAXPATHLEN + 1];
Just van Rossum52e14d62002-12-30 22:08:05 +0000464
Victor Stinner60fe8d92010-08-16 23:48:11 +0000465 if (!PyArg_ParseTuple(args, "U:zipimporter.get_data", &pathobj))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000466 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +0000467
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200468 if (PyUnicode_READY(pathobj) == -1)
469 return NULL;
470
471 path_len = PyUnicode_GET_LENGTH(pathobj);
Victor Stinner60fe8d92010-08-16 23:48:11 +0000472 if (path_len >= MAXPATHLEN) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000473 PyErr_SetString(ZipImportError, "path too long");
474 return NULL;
475 }
Georg Brandl4cb0de22011-09-28 21:49:49 +0200476 if (!PyUnicode_AsUCS4(pathobj, buf, Py_ARRAY_LENGTH(buf), 1))
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200477 return NULL;
478 path = buf;
479#ifdef ALTSEP
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000480 for (p = buf; *p; p++) {
481 if (*p == ALTSEP)
482 *p = SEP;
483 }
Just van Rossum52e14d62002-12-30 22:08:05 +0000484#endif
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200485 len = PyUnicode_GET_LENGTH(self->archive);
486 if ((size_t)len < Py_UCS4_strlen(path)) {
Georg Brandl4cb0de22011-09-28 21:49:49 +0200487 if (!PyUnicode_AsUCS4(self->archive, archive, Py_ARRAY_LENGTH(archive), 1))
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200488 return NULL;
489 if (Py_UCS4_strncmp(path, archive, len) == 0 &&
490 path[len] == SEP) {
491 path += len + 1;
492 path_len -= len + 1;
493 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000494 }
Just van Rossum52e14d62002-12-30 22:08:05 +0000495
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200496 key = PyUnicode_FromKindAndData(PyUnicode_4BYTE_KIND,
497 path, path_len);
Victor Stinner60fe8d92010-08-16 23:48:11 +0000498 if (key == NULL)
499 return NULL;
500 toc_entry = PyDict_GetItem(self->files, key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000501 if (toc_entry == NULL) {
Victor Stinner60fe8d92010-08-16 23:48:11 +0000502 PyErr_SetFromErrnoWithFilenameObject(PyExc_IOError, key);
503 Py_DECREF(key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000504 return NULL;
505 }
Victor Stinner60fe8d92010-08-16 23:48:11 +0000506 Py_DECREF(key);
507 return get_data(self->archive, toc_entry);
Just van Rossum52e14d62002-12-30 22:08:05 +0000508}
509
510static PyObject *
511zipimporter_get_code(PyObject *obj, PyObject *args)
512{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000513 ZipImporter *self = (ZipImporter *)obj;
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400514 PyObject *fullname;
Just van Rossum52e14d62002-12-30 22:08:05 +0000515
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400516 if (!PyArg_ParseTuple(args, "U:zipimporter.get_code", &fullname))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000517 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +0000518
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000519 return get_module_code(self, fullname, NULL, NULL);
Just van Rossum52e14d62002-12-30 22:08:05 +0000520}
521
522static PyObject *
523zipimporter_get_source(PyObject *obj, PyObject *args)
524{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000525 ZipImporter *self = (ZipImporter *)obj;
526 PyObject *toc_entry;
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400527 PyObject *fullname, *subname, *path, *fullpath;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000528 enum zi_module_info mi;
Just van Rossum52e14d62002-12-30 22:08:05 +0000529
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400530 if (!PyArg_ParseTuple(args, "U:zipimporter.get_source", &fullname))
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000531 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +0000532
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000533 mi = get_module_info(self, fullname);
Victor Stinner965a8a12010-10-18 21:44:33 +0000534 if (mi == MI_ERROR)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000535 return NULL;
Victor Stinner04106562010-10-18 20:44:08 +0000536 if (mi == MI_NOT_FOUND) {
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400537 PyErr_Format(ZipImportError, "can't find module %R", fullname);
Victor Stinner04106562010-10-18 20:44:08 +0000538 return NULL;
539 }
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400540
Victor Stinner965a8a12010-10-18 21:44:33 +0000541 subname = get_subname(fullname);
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400542 if (subname == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000543 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +0000544
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400545 path = make_filename(self->prefix, subname);
546 Py_DECREF(subname);
547 if (path == NULL)
548 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +0000549
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400550 if (mi == MI_PACKAGE)
551 fullpath = PyUnicode_FromFormat("%U%c__init__.py", path, SEP);
552 else
553 fullpath = PyUnicode_FromFormat("%U.py", path);
554 Py_DECREF(path);
555 if (fullpath == NULL)
556 return NULL;
557
558 toc_entry = PyDict_GetItem(self->files, fullpath);
559 Py_DECREF(fullpath);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000560 if (toc_entry != NULL) {
Victor Stinner60fe8d92010-08-16 23:48:11 +0000561 PyObject *res, *bytes;
562 bytes = get_data(self->archive, toc_entry);
563 if (bytes == NULL)
564 return NULL;
565 res = PyUnicode_FromStringAndSize(PyBytes_AS_STRING(bytes),
566 PyBytes_GET_SIZE(bytes));
567 Py_DECREF(bytes);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000568 return res;
569 }
Just van Rossum52e14d62002-12-30 22:08:05 +0000570
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000571 /* we have the module, but no source */
572 Py_INCREF(Py_None);
573 return Py_None;
Just van Rossum52e14d62002-12-30 22:08:05 +0000574}
575
576PyDoc_STRVAR(doc_find_module,
577"find_module(fullname, path=None) -> self or None.\n\
578\n\
579Search for a module specified by 'fullname'. 'fullname' must be the\n\
580fully qualified (dotted) module name. It returns the zipimporter\n\
581instance itself if the module was found, or None if it wasn't.\n\
582The optional 'path' argument is ignored -- it's there for compatibility\n\
583with the importer protocol.");
584
585PyDoc_STRVAR(doc_load_module,
586"load_module(fullname) -> module.\n\
587\n\
588Load the module specified by 'fullname'. 'fullname' must be the\n\
589fully qualified (dotted) module name. It returns the imported\n\
590module, or raises ZipImportError if it wasn't found.");
591
592PyDoc_STRVAR(doc_get_data,
593"get_data(pathname) -> string with file data.\n\
594\n\
595Return the data associated with 'pathname'. Raise IOError if\n\
596the file wasn't found.");
597
598PyDoc_STRVAR(doc_is_package,
599"is_package(fullname) -> bool.\n\
600\n\
601Return True if the module specified by fullname is a package.\n\
Brian Curtin32839732010-07-21 01:44:19 +0000602Raise ZipImportError if the module couldn't be found.");
Just van Rossum52e14d62002-12-30 22:08:05 +0000603
604PyDoc_STRVAR(doc_get_code,
605"get_code(fullname) -> code object.\n\
606\n\
607Return the code object for the specified module. Raise ZipImportError\n\
Brian Curtin32839732010-07-21 01:44:19 +0000608if the module couldn't be found.");
Just van Rossum52e14d62002-12-30 22:08:05 +0000609
610PyDoc_STRVAR(doc_get_source,
611"get_source(fullname) -> source string.\n\
612\n\
613Return the source code for the specified module. Raise ZipImportError\n\
Brian Curtin32839732010-07-21 01:44:19 +0000614if the module couldn't be found, return None if the archive does\n\
Just van Rossum52e14d62002-12-30 22:08:05 +0000615contain the module, but has no source for it.");
616
Nick Coghlanf088e5e2008-12-14 11:50:48 +0000617
618PyDoc_STRVAR(doc_get_filename,
Nick Coghlan9a1d6e32009-02-08 03:37:27 +0000619"get_filename(fullname) -> filename string.\n\
Nick Coghlanf088e5e2008-12-14 11:50:48 +0000620\n\
621Return the filename for the specified module.");
622
Just van Rossum52e14d62002-12-30 22:08:05 +0000623static PyMethodDef zipimporter_methods[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000624 {"find_module", zipimporter_find_module, METH_VARARGS,
625 doc_find_module},
626 {"load_module", zipimporter_load_module, METH_VARARGS,
627 doc_load_module},
628 {"get_data", zipimporter_get_data, METH_VARARGS,
629 doc_get_data},
630 {"get_code", zipimporter_get_code, METH_VARARGS,
631 doc_get_code},
632 {"get_source", zipimporter_get_source, METH_VARARGS,
633 doc_get_source},
634 {"get_filename", zipimporter_get_filename, METH_VARARGS,
635 doc_get_filename},
636 {"is_package", zipimporter_is_package, METH_VARARGS,
637 doc_is_package},
638 {NULL, NULL} /* sentinel */
Just van Rossum52e14d62002-12-30 22:08:05 +0000639};
640
641static PyMemberDef zipimporter_members[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000642 {"archive", T_OBJECT, offsetof(ZipImporter, archive), READONLY},
643 {"prefix", T_OBJECT, offsetof(ZipImporter, prefix), READONLY},
644 {"_files", T_OBJECT, offsetof(ZipImporter, files), READONLY},
645 {NULL}
Just van Rossum52e14d62002-12-30 22:08:05 +0000646};
647
648PyDoc_STRVAR(zipimporter_doc,
649"zipimporter(archivepath) -> zipimporter object\n\
650\n\
651Create a new zipimporter instance. 'archivepath' must be a path to\n\
Alexandre Vassalotti8ae3e052008-05-16 00:41:41 +0000652a zipfile, or to a specific path inside a zipfile. For example, it can be\n\
653'/tmp/myimport.zip', or '/tmp/myimport.zip/mydirectory', if mydirectory is a\n\
654valid directory inside the archive.\n\
655\n\
656'ZipImportError is raised if 'archivepath' doesn't point to a valid Zip\n\
657archive.\n\
658\n\
659The 'archive' attribute of zipimporter objects contains the name of the\n\
660zipfile targeted.");
Just van Rossum52e14d62002-12-30 22:08:05 +0000661
662#define DEFERRED_ADDRESS(ADDR) 0
663
664static PyTypeObject ZipImporter_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000665 PyVarObject_HEAD_INIT(DEFERRED_ADDRESS(&PyType_Type), 0)
666 "zipimport.zipimporter",
667 sizeof(ZipImporter),
668 0, /* tp_itemsize */
669 (destructor)zipimporter_dealloc, /* tp_dealloc */
670 0, /* tp_print */
671 0, /* tp_getattr */
672 0, /* tp_setattr */
673 0, /* tp_reserved */
674 (reprfunc)zipimporter_repr, /* tp_repr */
675 0, /* tp_as_number */
676 0, /* tp_as_sequence */
677 0, /* tp_as_mapping */
678 0, /* tp_hash */
679 0, /* tp_call */
680 0, /* tp_str */
681 PyObject_GenericGetAttr, /* tp_getattro */
682 0, /* tp_setattro */
683 0, /* tp_as_buffer */
684 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE |
685 Py_TPFLAGS_HAVE_GC, /* tp_flags */
686 zipimporter_doc, /* tp_doc */
687 zipimporter_traverse, /* tp_traverse */
688 0, /* tp_clear */
689 0, /* tp_richcompare */
690 0, /* tp_weaklistoffset */
691 0, /* tp_iter */
692 0, /* tp_iternext */
693 zipimporter_methods, /* tp_methods */
694 zipimporter_members, /* tp_members */
695 0, /* tp_getset */
696 0, /* tp_base */
697 0, /* tp_dict */
698 0, /* tp_descr_get */
699 0, /* tp_descr_set */
700 0, /* tp_dictoffset */
701 (initproc)zipimporter_init, /* tp_init */
702 PyType_GenericAlloc, /* tp_alloc */
703 PyType_GenericNew, /* tp_new */
704 PyObject_GC_Del, /* tp_free */
Just van Rossum52e14d62002-12-30 22:08:05 +0000705};
706
707
708/* implementation */
709
Just van Rossum52e14d62002-12-30 22:08:05 +0000710/* Given a buffer, return the long that is represented by the first
711 4 bytes, encoded as little endian. This partially reimplements
712 marshal.c:r_long() */
713static long
714get_long(unsigned char *buf) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000715 long x;
716 x = buf[0];
717 x |= (long)buf[1] << 8;
718 x |= (long)buf[2] << 16;
719 x |= (long)buf[3] << 24;
Just van Rossum52e14d62002-12-30 22:08:05 +0000720#if SIZEOF_LONG > 4
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000721 /* Sign extension for 64-bit machines */
722 x |= -(x & 0x80000000L);
Just van Rossum52e14d62002-12-30 22:08:05 +0000723#endif
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000724 return x;
Just van Rossum52e14d62002-12-30 22:08:05 +0000725}
726
727/*
728 read_directory(archive) -> files dict (new reference)
729
730 Given a path to a Zip archive, build a dict, mapping file names
731 (local to the archive, using SEP as a separator) to toc entries.
732
733 A toc_entry is a tuple:
734
Victor Stinner08654e12010-10-18 12:09:02 +0000735 (__file__, # value to use for __file__, available for all files,
736 # encoded to the filesystem encoding
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000737 compress, # compression kind; 0 for uncompressed
738 data_size, # size of compressed data on disk
739 file_size, # size of decompressed data
740 file_offset, # offset of file header from start of archive
741 time, # mod time of file (in dos format)
742 date, # mod data of file (in dos format)
743 crc, # crc checksum of the data
Victor Stinnerc342fca2010-10-18 11:39:05 +0000744 )
Just van Rossum52e14d62002-12-30 22:08:05 +0000745
746 Directories can be recognized by the trailing SEP in the name,
747 data_size and file_offset are 0.
748*/
749static PyObject *
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400750read_directory(PyObject *archive)
Just van Rossum52e14d62002-12-30 22:08:05 +0000751{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000752 PyObject *files = NULL;
753 FILE *fp;
Victor Stinnerd36c8212010-10-18 12:13:46 +0000754 unsigned short flags;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000755 long compress, crc, data_size, file_size, file_offset, date, time;
756 long header_offset, name_size, header_size, header_position;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200757 long l, count;
758 Py_ssize_t i;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000759 size_t length;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200760 Py_UCS4 path[MAXPATHLEN + 5];
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000761 char name[MAXPATHLEN + 5];
Victor Stinner2460a432010-08-16 17:54:28 +0000762 PyObject *nameobj = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000763 char *p, endof_central_dir[22];
764 long arc_offset; /* offset from beginning of file to start of zip-archive */
Victor Stinner2460a432010-08-16 17:54:28 +0000765 PyObject *pathobj;
Victor Stinnerd36c8212010-10-18 12:13:46 +0000766 const char *charset;
Victor Stinner4ee65a92011-01-22 10:30:29 +0000767 int bootstrap;
Just van Rossum52e14d62002-12-30 22:08:05 +0000768
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200769 if (PyUnicode_GET_LENGTH(archive) > MAXPATHLEN) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000770 PyErr_SetString(PyExc_OverflowError,
771 "Zip path name is too long");
772 return NULL;
773 }
Georg Brandl4cb0de22011-09-28 21:49:49 +0200774 if (!PyUnicode_AsUCS4(archive, path, Py_ARRAY_LENGTH(path), 1))
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200775 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +0000776
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400777 fp = _Py_fopen(archive, "rb");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000778 if (fp == NULL) {
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400779 PyErr_Format(ZipImportError, "can't open Zip file: %R", archive);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000780 return NULL;
781 }
782 fseek(fp, -22, SEEK_END);
783 header_position = ftell(fp);
784 if (fread(endof_central_dir, 1, 22, fp) != 22) {
785 fclose(fp);
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400786 PyErr_Format(ZipImportError, "can't read Zip file: %R", archive);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000787 return NULL;
788 }
789 if (get_long((unsigned char *)endof_central_dir) != 0x06054B50) {
790 /* Bad: End of Central Dir signature */
791 fclose(fp);
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400792 PyErr_Format(ZipImportError, "not a Zip file: %R", archive);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000793 return NULL;
794 }
Just van Rossum52e14d62002-12-30 22:08:05 +0000795
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000796 header_size = get_long((unsigned char *)endof_central_dir + 12);
797 header_offset = get_long((unsigned char *)endof_central_dir + 16);
798 arc_offset = header_position - header_offset - header_size;
799 header_offset += arc_offset;
Just van Rossum52e14d62002-12-30 22:08:05 +0000800
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000801 files = PyDict_New();
802 if (files == NULL)
803 goto error;
Just van Rossum52e14d62002-12-30 22:08:05 +0000804
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200805 length = Py_UCS4_strlen(path);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000806 path[length] = SEP;
Just van Rossum52e14d62002-12-30 22:08:05 +0000807
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000808 /* Start of Central Directory */
809 count = 0;
810 for (;;) {
811 PyObject *t;
812 int err;
Just van Rossum52e14d62002-12-30 22:08:05 +0000813
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000814 fseek(fp, header_offset, 0); /* Start of file header */
815 l = PyMarshal_ReadLongFromFile(fp);
816 if (l != 0x02014B50)
817 break; /* Bad: Central Dir File Header */
Victor Stinnerd36c8212010-10-18 12:13:46 +0000818 fseek(fp, header_offset + 8, 0);
819 flags = (unsigned short)PyMarshal_ReadShortFromFile(fp);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000820 compress = PyMarshal_ReadShortFromFile(fp);
821 time = PyMarshal_ReadShortFromFile(fp);
822 date = PyMarshal_ReadShortFromFile(fp);
823 crc = PyMarshal_ReadLongFromFile(fp);
824 data_size = PyMarshal_ReadLongFromFile(fp);
825 file_size = PyMarshal_ReadLongFromFile(fp);
826 name_size = PyMarshal_ReadShortFromFile(fp);
827 header_size = 46 + name_size +
828 PyMarshal_ReadShortFromFile(fp) +
829 PyMarshal_ReadShortFromFile(fp);
830 fseek(fp, header_offset + 42, 0);
831 file_offset = PyMarshal_ReadLongFromFile(fp) + arc_offset;
832 if (name_size > MAXPATHLEN)
833 name_size = MAXPATHLEN;
Just van Rossum52e14d62002-12-30 22:08:05 +0000834
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000835 p = name;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200836 for (i = 0; i < (Py_ssize_t)name_size; i++) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000837 *p = (char)getc(fp);
838 if (*p == '/')
839 *p = SEP;
840 p++;
841 }
842 *p = 0; /* Add terminating null byte */
843 header_offset += header_size;
Just van Rossum52e14d62002-12-30 22:08:05 +0000844
Victor Stinner4ee65a92011-01-22 10:30:29 +0000845 bootstrap = 0;
Victor Stinnerd36c8212010-10-18 12:13:46 +0000846 if (flags & 0x0800)
847 charset = "utf-8";
Victor Stinner4ee65a92011-01-22 10:30:29 +0000848 else if (!PyThreadState_GET()->interp->codecs_initialized) {
849 /* During bootstrap, we may need to load the encodings
850 package from a ZIP file. But the cp437 encoding is implemented
851 in Python in the encodings package.
852
853 Break out of this dependency by assuming that the path to
854 the encodings module is ASCII-only. */
855 charset = "ascii";
856 bootstrap = 1;
857 }
Victor Stinnerd36c8212010-10-18 12:13:46 +0000858 else
859 charset = "cp437";
860 nameobj = PyUnicode_Decode(name, name_size, charset, NULL);
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200861 if (PyUnicode_READY(nameobj) == -1)
862 goto error;
Victor Stinner4ee65a92011-01-22 10:30:29 +0000863 if (nameobj == NULL) {
864 if (bootstrap)
865 PyErr_Format(PyExc_NotImplementedError,
866 "bootstrap issue: python%i%i.zip contains non-ASCII "
867 "filenames without the unicode flag",
868 PY_MAJOR_VERSION, PY_MINOR_VERSION);
Victor Stinner2460a432010-08-16 17:54:28 +0000869 goto error;
Victor Stinner4ee65a92011-01-22 10:30:29 +0000870 }
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200871 for (i = 0; (i < MAXPATHLEN - length - 1) &&
872 (i < PyUnicode_GET_LENGTH(nameobj)); i++)
873 path[length + 1 + i] = PyUnicode_READ_CHAR(nameobj, i);
874 path[length + 1 + i] = 0;
875 pathobj = PyUnicode_FromKindAndData(PyUnicode_4BYTE_KIND,
876 path, Py_UCS4_strlen(path));
Victor Stinner2460a432010-08-16 17:54:28 +0000877 if (pathobj == NULL)
878 goto error;
879 t = Py_BuildValue("Niiiiiii", pathobj, compress, data_size,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000880 file_size, file_offset, time, date, crc);
881 if (t == NULL)
882 goto error;
Victor Stinner2460a432010-08-16 17:54:28 +0000883 err = PyDict_SetItem(files, nameobj, t);
884 Py_CLEAR(nameobj);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000885 Py_DECREF(t);
886 if (err != 0)
887 goto error;
888 count++;
889 }
890 fclose(fp);
891 if (Py_VerboseFlag)
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400892 PySys_FormatStderr("# zipimport: found %ld names in %R\n",
893 count, archive);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000894 return files;
Just van Rossum52e14d62002-12-30 22:08:05 +0000895error:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000896 fclose(fp);
897 Py_XDECREF(files);
Victor Stinner2460a432010-08-16 17:54:28 +0000898 Py_XDECREF(nameobj);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000899 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +0000900}
901
902/* Return the zlib.decompress function object, or NULL if zlib couldn't
903 be imported. The function is cached when found, so subsequent calls
Victor Stinner4925cde2011-05-20 00:16:09 +0200904 don't import zlib again. */
Just van Rossum52e14d62002-12-30 22:08:05 +0000905static PyObject *
906get_decompress_func(void)
907{
Victor Stinner4925cde2011-05-20 00:16:09 +0200908 static int importing_zlib = 0;
909 PyObject *zlib;
910 PyObject *decompress;
Just van Rossum52e14d62002-12-30 22:08:05 +0000911
Victor Stinner4925cde2011-05-20 00:16:09 +0200912 if (importing_zlib != 0)
913 /* Someone has a zlib.py[co] in their Zip file;
914 let's avoid a stack overflow. */
915 return NULL;
916 importing_zlib = 1;
917 zlib = PyImport_ImportModuleNoBlock("zlib");
918 importing_zlib = 0;
919 if (zlib != NULL) {
920 decompress = PyObject_GetAttrString(zlib,
921 "decompress");
922 Py_DECREF(zlib);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000923 }
Victor Stinner4925cde2011-05-20 00:16:09 +0200924 else {
925 PyErr_Clear();
926 decompress = NULL;
927 }
928 if (Py_VerboseFlag)
929 PySys_WriteStderr("# zipimport: zlib %s\n",
930 zlib != NULL ? "available": "UNAVAILABLE");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000931 return decompress;
Just van Rossum52e14d62002-12-30 22:08:05 +0000932}
933
934/* Given a path to a Zip file and a toc_entry, return the (uncompressed)
935 data as a new reference. */
936static PyObject *
Victor Stinner60fe8d92010-08-16 23:48:11 +0000937get_data(PyObject *archive, PyObject *toc_entry)
Just van Rossum52e14d62002-12-30 22:08:05 +0000938{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000939 PyObject *raw_data, *data = NULL, *decompress;
940 char *buf;
941 FILE *fp;
942 int err;
943 Py_ssize_t bytes_read = 0;
944 long l;
Victor Stinner60fe8d92010-08-16 23:48:11 +0000945 PyObject *datapath;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000946 long compress, data_size, file_size, file_offset, bytes_size;
947 long time, date, crc;
Just van Rossum52e14d62002-12-30 22:08:05 +0000948
Victor Stinner60fe8d92010-08-16 23:48:11 +0000949 if (!PyArg_ParseTuple(toc_entry, "Olllllll", &datapath, &compress,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000950 &data_size, &file_size, &file_offset, &time,
951 &date, &crc)) {
952 return NULL;
953 }
Just van Rossum52e14d62002-12-30 22:08:05 +0000954
Victor Stinner60fe8d92010-08-16 23:48:11 +0000955 fp = _Py_fopen(archive, "rb");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000956 if (!fp) {
957 PyErr_Format(PyExc_IOError,
Victor Stinner60fe8d92010-08-16 23:48:11 +0000958 "zipimport: can not open file %U", archive);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000959 return NULL;
960 }
Just van Rossum52e14d62002-12-30 22:08:05 +0000961
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000962 /* Check to make sure the local file header is correct */
963 fseek(fp, file_offset, 0);
964 l = PyMarshal_ReadLongFromFile(fp);
965 if (l != 0x04034B50) {
966 /* Bad: Local File Header */
967 PyErr_Format(ZipImportError,
Victor Stinner60fe8d92010-08-16 23:48:11 +0000968 "bad local file header in %U",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000969 archive);
970 fclose(fp);
971 return NULL;
972 }
973 fseek(fp, file_offset + 26, 0);
974 l = 30 + PyMarshal_ReadShortFromFile(fp) +
975 PyMarshal_ReadShortFromFile(fp); /* local header size */
976 file_offset += l; /* Start of file data */
Just van Rossum52e14d62002-12-30 22:08:05 +0000977
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000978 bytes_size = compress == 0 ? data_size : data_size + 1;
979 if (bytes_size == 0)
980 bytes_size++;
981 raw_data = PyBytes_FromStringAndSize((char *)NULL, bytes_size);
Just van Rossum52e14d62002-12-30 22:08:05 +0000982
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000983 if (raw_data == NULL) {
984 fclose(fp);
985 return NULL;
986 }
987 buf = PyBytes_AsString(raw_data);
Just van Rossum52e14d62002-12-30 22:08:05 +0000988
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000989 err = fseek(fp, file_offset, 0);
990 if (err == 0)
991 bytes_read = fread(buf, 1, data_size, fp);
992 fclose(fp);
993 if (err || bytes_read != data_size) {
994 PyErr_SetString(PyExc_IOError,
995 "zipimport: can't read data");
996 Py_DECREF(raw_data);
997 return NULL;
998 }
Just van Rossum52e14d62002-12-30 22:08:05 +0000999
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001000 if (compress != 0) {
1001 buf[data_size] = 'Z'; /* saw this in zipfile.py */
1002 data_size++;
1003 }
1004 buf[data_size] = '\0';
Just van Rossum52e14d62002-12-30 22:08:05 +00001005
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001006 if (compress == 0) { /* data is not compressed */
1007 data = PyBytes_FromStringAndSize(buf, data_size);
1008 Py_DECREF(raw_data);
1009 return data;
1010 }
1011
1012 /* Decompress with zlib */
1013 decompress = get_decompress_func();
1014 if (decompress == NULL) {
1015 PyErr_SetString(ZipImportError,
1016 "can't decompress data; "
1017 "zlib not available");
1018 goto error;
1019 }
1020 data = PyObject_CallFunction(decompress, "Oi", raw_data, -15);
Victor Stinner4925cde2011-05-20 00:16:09 +02001021 Py_DECREF(decompress);
Just van Rossum52e14d62002-12-30 22:08:05 +00001022error:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001023 Py_DECREF(raw_data);
1024 return data;
Just van Rossum52e14d62002-12-30 22:08:05 +00001025}
1026
1027/* Lenient date/time comparison function. The precision of the mtime
1028 in the archive is lower than the mtime stored in a .pyc: we
1029 must allow a difference of at most one second. */
1030static int
1031eq_mtime(time_t t1, time_t t2)
1032{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001033 time_t d = t1 - t2;
1034 if (d < 0)
1035 d = -d;
1036 /* dostime only stores even seconds, so be lenient */
1037 return d <= 1;
Just van Rossum52e14d62002-12-30 22:08:05 +00001038}
1039
1040/* Given the contents of a .py[co] file in a buffer, unmarshal the data
1041 and return the code object. Return None if it the magic word doesn't
1042 match (we do this instead of raising an exception as we fall back
1043 to .py if available and we don't want to mask other errors).
1044 Returns a new reference. */
1045static PyObject *
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001046unmarshal_code(PyObject *pathname, PyObject *data, time_t mtime)
Just van Rossum52e14d62002-12-30 22:08:05 +00001047{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001048 PyObject *code;
1049 char *buf = PyBytes_AsString(data);
1050 Py_ssize_t size = PyBytes_Size(data);
Just van Rossum52e14d62002-12-30 22:08:05 +00001051
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001052 if (size <= 9) {
1053 PyErr_SetString(ZipImportError,
1054 "bad pyc data");
1055 return NULL;
1056 }
Just van Rossum52e14d62002-12-30 22:08:05 +00001057
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001058 if (get_long((unsigned char *)buf) != PyImport_GetMagicNumber()) {
1059 if (Py_VerboseFlag)
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001060 PySys_FormatStderr("# %R has bad magic\n",
1061 pathname);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001062 Py_INCREF(Py_None);
1063 return Py_None; /* signal caller to try alternative */
1064 }
Just van Rossum52e14d62002-12-30 22:08:05 +00001065
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001066 if (mtime != 0 && !eq_mtime(get_long((unsigned char *)buf + 4),
1067 mtime)) {
1068 if (Py_VerboseFlag)
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001069 PySys_FormatStderr("# %R has bad mtime\n",
1070 pathname);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001071 Py_INCREF(Py_None);
1072 return Py_None; /* signal caller to try alternative */
1073 }
Just van Rossum52e14d62002-12-30 22:08:05 +00001074
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001075 code = PyMarshal_ReadObjectFromString(buf + 8, size - 8);
1076 if (code == NULL)
1077 return NULL;
1078 if (!PyCode_Check(code)) {
1079 Py_DECREF(code);
1080 PyErr_Format(PyExc_TypeError,
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001081 "compiled module %R is not a code object",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001082 pathname);
1083 return NULL;
1084 }
1085 return code;
Just van Rossum52e14d62002-12-30 22:08:05 +00001086}
1087
1088/* Replace any occurances of "\r\n?" in the input string with "\n".
1089 This converts DOS and Mac line endings to Unix line endings.
1090 Also append a trailing "\n" to be compatible with
1091 PyParser_SimpleParseFile(). Returns a new reference. */
1092static PyObject *
1093normalize_line_endings(PyObject *source)
1094{
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001095 char *buf, *q, *p;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001096 PyObject *fixed_source;
1097 int len = 0;
Just van Rossum52e14d62002-12-30 22:08:05 +00001098
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001099 p = PyBytes_AsString(source);
1100 if (p == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001101 return PyBytes_FromStringAndSize("\n\0", 2);
1102 }
Thomas Wouters00ee7ba2006-08-21 19:07:27 +00001103
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001104 /* one char extra for trailing \n and one for terminating \0 */
1105 buf = (char *)PyMem_Malloc(PyBytes_Size(source) + 2);
1106 if (buf == NULL) {
1107 PyErr_SetString(PyExc_MemoryError,
1108 "zipimport: no memory to allocate "
1109 "source buffer");
1110 return NULL;
1111 }
1112 /* replace "\r\n?" by "\n" */
1113 for (q = buf; *p != '\0'; p++) {
1114 if (*p == '\r') {
1115 *q++ = '\n';
1116 if (*(p + 1) == '\n')
1117 p++;
1118 }
1119 else
1120 *q++ = *p;
1121 len++;
1122 }
1123 *q++ = '\n'; /* add trailing \n */
1124 *q = '\0';
1125 fixed_source = PyBytes_FromStringAndSize(buf, len + 2);
1126 PyMem_Free(buf);
1127 return fixed_source;
Just van Rossum52e14d62002-12-30 22:08:05 +00001128}
1129
1130/* Given a string buffer containing Python source code, compile it
1131 return and return a code object as a new reference. */
1132static PyObject *
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001133compile_source(PyObject *pathname, PyObject *source)
Just van Rossum52e14d62002-12-30 22:08:05 +00001134{
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001135 PyObject *code, *fixed_source, *pathbytes;
Just van Rossum52e14d62002-12-30 22:08:05 +00001136
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001137 pathbytes = PyUnicode_EncodeFSDefault(pathname);
1138 if (pathbytes == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001139 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +00001140
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001141 fixed_source = normalize_line_endings(source);
1142 if (fixed_source == NULL) {
1143 Py_DECREF(pathbytes);
1144 return NULL;
1145 }
1146
1147 code = Py_CompileString(PyBytes_AsString(fixed_source),
1148 PyBytes_AsString(pathbytes),
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001149 Py_file_input);
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001150 Py_DECREF(pathbytes);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001151 Py_DECREF(fixed_source);
1152 return code;
Just van Rossum52e14d62002-12-30 22:08:05 +00001153}
1154
1155/* Convert the date/time values found in the Zip archive to a value
1156 that's compatible with the time stamp stored in .pyc files. */
Neal Norwitz29fd2ba2003-03-23 13:21:03 +00001157static time_t
1158parse_dostime(int dostime, int dosdate)
Just van Rossum52e14d62002-12-30 22:08:05 +00001159{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001160 struct tm stm;
Just van Rossum52e14d62002-12-30 22:08:05 +00001161
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001162 memset((void *) &stm, '\0', sizeof(stm));
Christian Heimes679db4a2008-01-18 09:56:22 +00001163
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001164 stm.tm_sec = (dostime & 0x1f) * 2;
1165 stm.tm_min = (dostime >> 5) & 0x3f;
1166 stm.tm_hour = (dostime >> 11) & 0x1f;
1167 stm.tm_mday = dosdate & 0x1f;
1168 stm.tm_mon = ((dosdate >> 5) & 0x0f) - 1;
1169 stm.tm_year = ((dosdate >> 9) & 0x7f) + 80;
1170 stm.tm_isdst = -1; /* wday/yday is ignored */
Just van Rossum52e14d62002-12-30 22:08:05 +00001171
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001172 return mktime(&stm);
Just van Rossum52e14d62002-12-30 22:08:05 +00001173}
1174
1175/* Given a path to a .pyc or .pyo file in the archive, return the
Ezio Melotti13925002011-03-16 11:05:33 +02001176 modification time of the matching .py file, or 0 if no source
Just van Rossum52e14d62002-12-30 22:08:05 +00001177 is available. */
1178static time_t
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001179get_mtime_of_source(ZipImporter *self, PyObject *path)
Just van Rossum52e14d62002-12-30 22:08:05 +00001180{
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001181 PyObject *toc_entry, *stripped;
1182 time_t mtime;
1183
1184 /* strip 'c' or 'o' from *.py[co] */
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001185 if (PyUnicode_READY(path) == -1)
1186 return (time_t)-1;
1187 stripped = PyUnicode_FromKindAndData(PyUnicode_KIND(path),
1188 PyUnicode_DATA(path),
1189 PyUnicode_GET_LENGTH(path) - 1);
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001190 if (stripped == NULL)
1191 return (time_t)-1;
1192
1193 toc_entry = PyDict_GetItem(self->files, stripped);
1194 Py_DECREF(stripped);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001195 if (toc_entry != NULL && PyTuple_Check(toc_entry) &&
1196 PyTuple_Size(toc_entry) == 8) {
1197 /* fetch the time stamp of the .py file for comparison
1198 with an embedded pyc time stamp */
1199 int time, date;
1200 time = PyLong_AsLong(PyTuple_GetItem(toc_entry, 5));
1201 date = PyLong_AsLong(PyTuple_GetItem(toc_entry, 6));
1202 mtime = parse_dostime(time, date);
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001203 } else
1204 mtime = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001205 return mtime;
Just van Rossum52e14d62002-12-30 22:08:05 +00001206}
1207
1208/* Return the code object for the module named by 'fullname' from the
1209 Zip archive as a new reference. */
1210static PyObject *
1211get_code_from_data(ZipImporter *self, int ispackage, int isbytecode,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001212 time_t mtime, PyObject *toc_entry)
Just van Rossum52e14d62002-12-30 22:08:05 +00001213{
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001214 PyObject *data, *modpath, *code;
Just van Rossum52e14d62002-12-30 22:08:05 +00001215
Victor Stinner60fe8d92010-08-16 23:48:11 +00001216 data = get_data(self->archive, toc_entry);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001217 if (data == NULL)
1218 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +00001219
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001220 modpath = PyTuple_GetItem(toc_entry, 0);
Victor Stinner2a94f4c2010-10-18 12:15:34 +00001221 if (isbytecode)
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001222 code = unmarshal_code(modpath, data, mtime);
Victor Stinner2a94f4c2010-10-18 12:15:34 +00001223 else
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001224 code = compile_source(modpath, data);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001225 Py_DECREF(data);
1226 return code;
Just van Rossum52e14d62002-12-30 22:08:05 +00001227}
1228
Ezio Melotti42da6632011-03-15 05:18:48 +02001229/* Get the code object associated with the module specified by
Just van Rossum52e14d62002-12-30 22:08:05 +00001230 'fullname'. */
1231static PyObject *
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001232get_module_code(ZipImporter *self, PyObject *fullname,
Victor Stinner08654e12010-10-18 12:09:02 +00001233 int *p_ispackage, PyObject **p_modpath)
Just van Rossum52e14d62002-12-30 22:08:05 +00001234{
Gregory P. Smith95c7c462011-05-21 05:19:42 -07001235 PyObject *code = NULL, *toc_entry, *subname;
Victor Stinner9a2261a2011-05-26 13:59:41 +02001236 PyObject *path, *fullpath = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001237 struct st_zip_searchorder *zso;
Just van Rossum52e14d62002-12-30 22:08:05 +00001238
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001239 subname = get_subname(fullname);
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001240 if (subname == NULL)
1241 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +00001242
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001243 path = make_filename(self->prefix, subname);
1244 Py_DECREF(subname);
1245 if (path == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001246 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +00001247
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001248 for (zso = zip_searchorder; *zso->suffix; zso++) {
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001249 code = NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +00001250
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001251 fullpath = PyUnicode_FromFormat("%U%s", path, zso->suffix);
1252 if (fullpath == NULL)
1253 goto exit;
1254
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001255 if (Py_VerboseFlag > 1)
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001256 PySys_FormatStderr("# trying %U%c%U\n",
1257 self->archive, (int)SEP, fullpath);
1258 toc_entry = PyDict_GetItem(self->files, fullpath);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001259 if (toc_entry != NULL) {
1260 time_t mtime = 0;
1261 int ispackage = zso->type & IS_PACKAGE;
1262 int isbytecode = zso->type & IS_BYTECODE;
Just van Rossum52e14d62002-12-30 22:08:05 +00001263
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001264 if (isbytecode) {
1265 mtime = get_mtime_of_source(self, fullpath);
1266 if (mtime == (time_t)-1 && PyErr_Occurred()) {
1267 goto exit;
1268 }
1269 }
1270 Py_CLEAR(fullpath);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001271 if (p_ispackage != NULL)
1272 *p_ispackage = ispackage;
1273 code = get_code_from_data(self, ispackage,
1274 isbytecode, mtime,
1275 toc_entry);
1276 if (code == Py_None) {
1277 /* bad magic number or non-matching mtime
1278 in byte code, try next */
1279 Py_DECREF(code);
1280 continue;
1281 }
Victor Stinner08654e12010-10-18 12:09:02 +00001282 if (code != NULL && p_modpath != NULL) {
1283 *p_modpath = PyTuple_GetItem(toc_entry, 0);
1284 Py_INCREF(*p_modpath);
1285 }
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001286 goto exit;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001287 }
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001288 else
1289 Py_CLEAR(fullpath);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001290 }
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001291 PyErr_Format(ZipImportError, "can't find module %R", fullname);
1292exit:
1293 Py_DECREF(path);
1294 Py_XDECREF(fullpath);
1295 return code;
Just van Rossum52e14d62002-12-30 22:08:05 +00001296}
1297
1298
1299/* Module init */
1300
1301PyDoc_STRVAR(zipimport_doc,
1302"zipimport provides support for importing Python modules from Zip archives.\n\
1303\n\
1304This module exports three objects:\n\
1305- zipimporter: a class; its constructor takes a path to a Zip archive.\n\
Fredrik Lundhb84b35f2006-01-15 15:00:40 +00001306- ZipImportError: exception raised by zipimporter objects. It's a\n\
Just van Rossum52e14d62002-12-30 22:08:05 +00001307 subclass of ImportError, so it can be caught as ImportError, too.\n\
1308- _zip_directory_cache: a dict, mapping archive paths to zip directory\n\
1309 info dicts, as used in zipimporter._files.\n\
1310\n\
1311It is usually not needed to use the zipimport module explicitly; it is\n\
1312used by the builtin import mechanism for sys.path items that are paths\n\
1313to Zip archives.");
1314
Martin v. Löwis1a214512008-06-11 05:26:20 +00001315static struct PyModuleDef zipimportmodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001316 PyModuleDef_HEAD_INIT,
1317 "zipimport",
1318 zipimport_doc,
1319 -1,
1320 NULL,
1321 NULL,
1322 NULL,
1323 NULL,
1324 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +00001325};
1326
Just van Rossum52e14d62002-12-30 22:08:05 +00001327PyMODINIT_FUNC
Martin v. Löwis1a214512008-06-11 05:26:20 +00001328PyInit_zipimport(void)
Just van Rossum52e14d62002-12-30 22:08:05 +00001329{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001330 PyObject *mod;
Just van Rossum52e14d62002-12-30 22:08:05 +00001331
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001332 if (PyType_Ready(&ZipImporter_Type) < 0)
1333 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +00001334
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001335 /* Correct directory separator */
1336 zip_searchorder[0].suffix[0] = SEP;
1337 zip_searchorder[1].suffix[0] = SEP;
1338 zip_searchorder[2].suffix[0] = SEP;
1339 if (Py_OptimizeFlag) {
1340 /* Reverse *.pyc and *.pyo */
1341 struct st_zip_searchorder tmp;
1342 tmp = zip_searchorder[0];
1343 zip_searchorder[0] = zip_searchorder[1];
1344 zip_searchorder[1] = tmp;
1345 tmp = zip_searchorder[3];
1346 zip_searchorder[3] = zip_searchorder[4];
1347 zip_searchorder[4] = tmp;
1348 }
Just van Rossum52e14d62002-12-30 22:08:05 +00001349
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001350 mod = PyModule_Create(&zipimportmodule);
1351 if (mod == NULL)
1352 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +00001353
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001354 ZipImportError = PyErr_NewException("zipimport.ZipImportError",
1355 PyExc_ImportError, NULL);
1356 if (ZipImportError == NULL)
1357 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +00001358
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001359 Py_INCREF(ZipImportError);
1360 if (PyModule_AddObject(mod, "ZipImportError",
1361 ZipImportError) < 0)
1362 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +00001363
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001364 Py_INCREF(&ZipImporter_Type);
1365 if (PyModule_AddObject(mod, "zipimporter",
1366 (PyObject *)&ZipImporter_Type) < 0)
1367 return NULL;
Just van Rossumf8b6de12002-12-31 09:51:59 +00001368
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001369 zip_directory_cache = PyDict_New();
1370 if (zip_directory_cache == NULL)
1371 return NULL;
1372 Py_INCREF(zip_directory_cache);
1373 if (PyModule_AddObject(mod, "_zip_directory_cache",
1374 zip_directory_cache) < 0)
1375 return NULL;
1376 return mod;
Just van Rossum52e14d62002-12-30 22:08:05 +00001377}