blob: 8e167502ff3128f960f46973d72460269085ebd0 [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 }
Victor Stinner3f528f02011-10-11 22:28:56 +0200871 for (i = 0; (i < (MAXPATHLEN - (Py_ssize_t)length - 1)) &&
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200872 (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;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +0200911 _Py_IDENTIFIER(decompress);
Just van Rossum52e14d62002-12-30 22:08:05 +0000912
Victor Stinner4925cde2011-05-20 00:16:09 +0200913 if (importing_zlib != 0)
914 /* Someone has a zlib.py[co] in their Zip file;
915 let's avoid a stack overflow. */
916 return NULL;
917 importing_zlib = 1;
918 zlib = PyImport_ImportModuleNoBlock("zlib");
919 importing_zlib = 0;
920 if (zlib != NULL) {
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +0200921 decompress = _PyObject_GetAttrId(zlib,
922 &PyId_decompress);
Victor Stinner4925cde2011-05-20 00:16:09 +0200923 Py_DECREF(zlib);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000924 }
Victor Stinner4925cde2011-05-20 00:16:09 +0200925 else {
926 PyErr_Clear();
927 decompress = NULL;
928 }
929 if (Py_VerboseFlag)
930 PySys_WriteStderr("# zipimport: zlib %s\n",
931 zlib != NULL ? "available": "UNAVAILABLE");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000932 return decompress;
Just van Rossum52e14d62002-12-30 22:08:05 +0000933}
934
935/* Given a path to a Zip file and a toc_entry, return the (uncompressed)
936 data as a new reference. */
937static PyObject *
Victor Stinner60fe8d92010-08-16 23:48:11 +0000938get_data(PyObject *archive, PyObject *toc_entry)
Just van Rossum52e14d62002-12-30 22:08:05 +0000939{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000940 PyObject *raw_data, *data = NULL, *decompress;
941 char *buf;
942 FILE *fp;
943 int err;
944 Py_ssize_t bytes_read = 0;
945 long l;
Victor Stinner60fe8d92010-08-16 23:48:11 +0000946 PyObject *datapath;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000947 long compress, data_size, file_size, file_offset, bytes_size;
948 long time, date, crc;
Just van Rossum52e14d62002-12-30 22:08:05 +0000949
Victor Stinner60fe8d92010-08-16 23:48:11 +0000950 if (!PyArg_ParseTuple(toc_entry, "Olllllll", &datapath, &compress,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000951 &data_size, &file_size, &file_offset, &time,
952 &date, &crc)) {
953 return NULL;
954 }
Just van Rossum52e14d62002-12-30 22:08:05 +0000955
Victor Stinner60fe8d92010-08-16 23:48:11 +0000956 fp = _Py_fopen(archive, "rb");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000957 if (!fp) {
958 PyErr_Format(PyExc_IOError,
Victor Stinner60fe8d92010-08-16 23:48:11 +0000959 "zipimport: can not open file %U", archive);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000960 return NULL;
961 }
Just van Rossum52e14d62002-12-30 22:08:05 +0000962
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000963 /* Check to make sure the local file header is correct */
964 fseek(fp, file_offset, 0);
965 l = PyMarshal_ReadLongFromFile(fp);
966 if (l != 0x04034B50) {
967 /* Bad: Local File Header */
968 PyErr_Format(ZipImportError,
Victor Stinner60fe8d92010-08-16 23:48:11 +0000969 "bad local file header in %U",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000970 archive);
971 fclose(fp);
972 return NULL;
973 }
974 fseek(fp, file_offset + 26, 0);
975 l = 30 + PyMarshal_ReadShortFromFile(fp) +
976 PyMarshal_ReadShortFromFile(fp); /* local header size */
977 file_offset += l; /* Start of file data */
Just van Rossum52e14d62002-12-30 22:08:05 +0000978
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000979 bytes_size = compress == 0 ? data_size : data_size + 1;
980 if (bytes_size == 0)
981 bytes_size++;
982 raw_data = PyBytes_FromStringAndSize((char *)NULL, bytes_size);
Just van Rossum52e14d62002-12-30 22:08:05 +0000983
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000984 if (raw_data == NULL) {
985 fclose(fp);
986 return NULL;
987 }
988 buf = PyBytes_AsString(raw_data);
Just van Rossum52e14d62002-12-30 22:08:05 +0000989
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000990 err = fseek(fp, file_offset, 0);
991 if (err == 0)
992 bytes_read = fread(buf, 1, data_size, fp);
993 fclose(fp);
994 if (err || bytes_read != data_size) {
995 PyErr_SetString(PyExc_IOError,
996 "zipimport: can't read data");
997 Py_DECREF(raw_data);
998 return NULL;
999 }
Just van Rossum52e14d62002-12-30 22:08:05 +00001000
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001001 if (compress != 0) {
1002 buf[data_size] = 'Z'; /* saw this in zipfile.py */
1003 data_size++;
1004 }
1005 buf[data_size] = '\0';
Just van Rossum52e14d62002-12-30 22:08:05 +00001006
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001007 if (compress == 0) { /* data is not compressed */
1008 data = PyBytes_FromStringAndSize(buf, data_size);
1009 Py_DECREF(raw_data);
1010 return data;
1011 }
1012
1013 /* Decompress with zlib */
1014 decompress = get_decompress_func();
1015 if (decompress == NULL) {
1016 PyErr_SetString(ZipImportError,
1017 "can't decompress data; "
1018 "zlib not available");
1019 goto error;
1020 }
1021 data = PyObject_CallFunction(decompress, "Oi", raw_data, -15);
Victor Stinner4925cde2011-05-20 00:16:09 +02001022 Py_DECREF(decompress);
Just van Rossum52e14d62002-12-30 22:08:05 +00001023error:
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001024 Py_DECREF(raw_data);
1025 return data;
Just van Rossum52e14d62002-12-30 22:08:05 +00001026}
1027
1028/* Lenient date/time comparison function. The precision of the mtime
1029 in the archive is lower than the mtime stored in a .pyc: we
1030 must allow a difference of at most one second. */
1031static int
1032eq_mtime(time_t t1, time_t t2)
1033{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001034 time_t d = t1 - t2;
1035 if (d < 0)
1036 d = -d;
1037 /* dostime only stores even seconds, so be lenient */
1038 return d <= 1;
Just van Rossum52e14d62002-12-30 22:08:05 +00001039}
1040
1041/* Given the contents of a .py[co] file in a buffer, unmarshal the data
1042 and return the code object. Return None if it the magic word doesn't
1043 match (we do this instead of raising an exception as we fall back
1044 to .py if available and we don't want to mask other errors).
1045 Returns a new reference. */
1046static PyObject *
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001047unmarshal_code(PyObject *pathname, PyObject *data, time_t mtime)
Just van Rossum52e14d62002-12-30 22:08:05 +00001048{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001049 PyObject *code;
1050 char *buf = PyBytes_AsString(data);
1051 Py_ssize_t size = PyBytes_Size(data);
Just van Rossum52e14d62002-12-30 22:08:05 +00001052
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001053 if (size <= 9) {
1054 PyErr_SetString(ZipImportError,
1055 "bad pyc data");
1056 return NULL;
1057 }
Just van Rossum52e14d62002-12-30 22:08:05 +00001058
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001059 if (get_long((unsigned char *)buf) != PyImport_GetMagicNumber()) {
1060 if (Py_VerboseFlag)
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001061 PySys_FormatStderr("# %R has bad magic\n",
1062 pathname);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001063 Py_INCREF(Py_None);
1064 return Py_None; /* signal caller to try alternative */
1065 }
Just van Rossum52e14d62002-12-30 22:08:05 +00001066
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001067 if (mtime != 0 && !eq_mtime(get_long((unsigned char *)buf + 4),
1068 mtime)) {
1069 if (Py_VerboseFlag)
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001070 PySys_FormatStderr("# %R has bad mtime\n",
1071 pathname);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001072 Py_INCREF(Py_None);
1073 return Py_None; /* signal caller to try alternative */
1074 }
Just van Rossum52e14d62002-12-30 22:08:05 +00001075
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001076 code = PyMarshal_ReadObjectFromString(buf + 8, size - 8);
1077 if (code == NULL)
1078 return NULL;
1079 if (!PyCode_Check(code)) {
1080 Py_DECREF(code);
1081 PyErr_Format(PyExc_TypeError,
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001082 "compiled module %R is not a code object",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001083 pathname);
1084 return NULL;
1085 }
1086 return code;
Just van Rossum52e14d62002-12-30 22:08:05 +00001087}
1088
1089/* Replace any occurances of "\r\n?" in the input string with "\n".
1090 This converts DOS and Mac line endings to Unix line endings.
1091 Also append a trailing "\n" to be compatible with
1092 PyParser_SimpleParseFile(). Returns a new reference. */
1093static PyObject *
1094normalize_line_endings(PyObject *source)
1095{
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001096 char *buf, *q, *p;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001097 PyObject *fixed_source;
1098 int len = 0;
Just van Rossum52e14d62002-12-30 22:08:05 +00001099
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001100 p = PyBytes_AsString(source);
1101 if (p == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001102 return PyBytes_FromStringAndSize("\n\0", 2);
1103 }
Thomas Wouters00ee7ba2006-08-21 19:07:27 +00001104
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001105 /* one char extra for trailing \n and one for terminating \0 */
1106 buf = (char *)PyMem_Malloc(PyBytes_Size(source) + 2);
1107 if (buf == NULL) {
1108 PyErr_SetString(PyExc_MemoryError,
1109 "zipimport: no memory to allocate "
1110 "source buffer");
1111 return NULL;
1112 }
1113 /* replace "\r\n?" by "\n" */
1114 for (q = buf; *p != '\0'; p++) {
1115 if (*p == '\r') {
1116 *q++ = '\n';
1117 if (*(p + 1) == '\n')
1118 p++;
1119 }
1120 else
1121 *q++ = *p;
1122 len++;
1123 }
1124 *q++ = '\n'; /* add trailing \n */
1125 *q = '\0';
1126 fixed_source = PyBytes_FromStringAndSize(buf, len + 2);
1127 PyMem_Free(buf);
1128 return fixed_source;
Just van Rossum52e14d62002-12-30 22:08:05 +00001129}
1130
1131/* Given a string buffer containing Python source code, compile it
1132 return and return a code object as a new reference. */
1133static PyObject *
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001134compile_source(PyObject *pathname, PyObject *source)
Just van Rossum52e14d62002-12-30 22:08:05 +00001135{
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001136 PyObject *code, *fixed_source, *pathbytes;
Just van Rossum52e14d62002-12-30 22:08:05 +00001137
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001138 pathbytes = PyUnicode_EncodeFSDefault(pathname);
1139 if (pathbytes == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001140 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +00001141
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001142 fixed_source = normalize_line_endings(source);
1143 if (fixed_source == NULL) {
1144 Py_DECREF(pathbytes);
1145 return NULL;
1146 }
1147
1148 code = Py_CompileString(PyBytes_AsString(fixed_source),
1149 PyBytes_AsString(pathbytes),
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001150 Py_file_input);
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001151 Py_DECREF(pathbytes);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001152 Py_DECREF(fixed_source);
1153 return code;
Just van Rossum52e14d62002-12-30 22:08:05 +00001154}
1155
1156/* Convert the date/time values found in the Zip archive to a value
1157 that's compatible with the time stamp stored in .pyc files. */
Neal Norwitz29fd2ba2003-03-23 13:21:03 +00001158static time_t
1159parse_dostime(int dostime, int dosdate)
Just van Rossum52e14d62002-12-30 22:08:05 +00001160{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001161 struct tm stm;
Just van Rossum52e14d62002-12-30 22:08:05 +00001162
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001163 memset((void *) &stm, '\0', sizeof(stm));
Christian Heimes679db4a2008-01-18 09:56:22 +00001164
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001165 stm.tm_sec = (dostime & 0x1f) * 2;
1166 stm.tm_min = (dostime >> 5) & 0x3f;
1167 stm.tm_hour = (dostime >> 11) & 0x1f;
1168 stm.tm_mday = dosdate & 0x1f;
1169 stm.tm_mon = ((dosdate >> 5) & 0x0f) - 1;
1170 stm.tm_year = ((dosdate >> 9) & 0x7f) + 80;
1171 stm.tm_isdst = -1; /* wday/yday is ignored */
Just van Rossum52e14d62002-12-30 22:08:05 +00001172
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001173 return mktime(&stm);
Just van Rossum52e14d62002-12-30 22:08:05 +00001174}
1175
1176/* Given a path to a .pyc or .pyo file in the archive, return the
Ezio Melotti13925002011-03-16 11:05:33 +02001177 modification time of the matching .py file, or 0 if no source
Just van Rossum52e14d62002-12-30 22:08:05 +00001178 is available. */
1179static time_t
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001180get_mtime_of_source(ZipImporter *self, PyObject *path)
Just van Rossum52e14d62002-12-30 22:08:05 +00001181{
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001182 PyObject *toc_entry, *stripped;
1183 time_t mtime;
1184
1185 /* strip 'c' or 'o' from *.py[co] */
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001186 if (PyUnicode_READY(path) == -1)
1187 return (time_t)-1;
1188 stripped = PyUnicode_FromKindAndData(PyUnicode_KIND(path),
1189 PyUnicode_DATA(path),
1190 PyUnicode_GET_LENGTH(path) - 1);
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001191 if (stripped == NULL)
1192 return (time_t)-1;
1193
1194 toc_entry = PyDict_GetItem(self->files, stripped);
1195 Py_DECREF(stripped);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001196 if (toc_entry != NULL && PyTuple_Check(toc_entry) &&
1197 PyTuple_Size(toc_entry) == 8) {
1198 /* fetch the time stamp of the .py file for comparison
1199 with an embedded pyc time stamp */
1200 int time, date;
1201 time = PyLong_AsLong(PyTuple_GetItem(toc_entry, 5));
1202 date = PyLong_AsLong(PyTuple_GetItem(toc_entry, 6));
1203 mtime = parse_dostime(time, date);
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001204 } else
1205 mtime = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001206 return mtime;
Just van Rossum52e14d62002-12-30 22:08:05 +00001207}
1208
1209/* Return the code object for the module named by 'fullname' from the
1210 Zip archive as a new reference. */
1211static PyObject *
1212get_code_from_data(ZipImporter *self, int ispackage, int isbytecode,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001213 time_t mtime, PyObject *toc_entry)
Just van Rossum52e14d62002-12-30 22:08:05 +00001214{
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001215 PyObject *data, *modpath, *code;
Just van Rossum52e14d62002-12-30 22:08:05 +00001216
Victor Stinner60fe8d92010-08-16 23:48:11 +00001217 data = get_data(self->archive, toc_entry);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001218 if (data == NULL)
1219 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +00001220
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001221 modpath = PyTuple_GetItem(toc_entry, 0);
Victor Stinner2a94f4c2010-10-18 12:15:34 +00001222 if (isbytecode)
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001223 code = unmarshal_code(modpath, data, mtime);
Victor Stinner2a94f4c2010-10-18 12:15:34 +00001224 else
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001225 code = compile_source(modpath, data);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001226 Py_DECREF(data);
1227 return code;
Just van Rossum52e14d62002-12-30 22:08:05 +00001228}
1229
Ezio Melotti42da6632011-03-15 05:18:48 +02001230/* Get the code object associated with the module specified by
Just van Rossum52e14d62002-12-30 22:08:05 +00001231 'fullname'. */
1232static PyObject *
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001233get_module_code(ZipImporter *self, PyObject *fullname,
Victor Stinner08654e12010-10-18 12:09:02 +00001234 int *p_ispackage, PyObject **p_modpath)
Just van Rossum52e14d62002-12-30 22:08:05 +00001235{
Gregory P. Smith95c7c462011-05-21 05:19:42 -07001236 PyObject *code = NULL, *toc_entry, *subname;
Victor Stinner9a2261a2011-05-26 13:59:41 +02001237 PyObject *path, *fullpath = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001238 struct st_zip_searchorder *zso;
Just van Rossum52e14d62002-12-30 22:08:05 +00001239
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001240 subname = get_subname(fullname);
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001241 if (subname == NULL)
1242 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +00001243
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001244 path = make_filename(self->prefix, subname);
1245 Py_DECREF(subname);
1246 if (path == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001247 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +00001248
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001249 for (zso = zip_searchorder; *zso->suffix; zso++) {
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001250 code = NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +00001251
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001252 fullpath = PyUnicode_FromFormat("%U%s", path, zso->suffix);
1253 if (fullpath == NULL)
1254 goto exit;
1255
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001256 if (Py_VerboseFlag > 1)
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001257 PySys_FormatStderr("# trying %U%c%U\n",
1258 self->archive, (int)SEP, fullpath);
1259 toc_entry = PyDict_GetItem(self->files, fullpath);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001260 if (toc_entry != NULL) {
1261 time_t mtime = 0;
1262 int ispackage = zso->type & IS_PACKAGE;
1263 int isbytecode = zso->type & IS_BYTECODE;
Just van Rossum52e14d62002-12-30 22:08:05 +00001264
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001265 if (isbytecode) {
1266 mtime = get_mtime_of_source(self, fullpath);
1267 if (mtime == (time_t)-1 && PyErr_Occurred()) {
1268 goto exit;
1269 }
1270 }
1271 Py_CLEAR(fullpath);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001272 if (p_ispackage != NULL)
1273 *p_ispackage = ispackage;
1274 code = get_code_from_data(self, ispackage,
1275 isbytecode, mtime,
1276 toc_entry);
1277 if (code == Py_None) {
1278 /* bad magic number or non-matching mtime
1279 in byte code, try next */
1280 Py_DECREF(code);
1281 continue;
1282 }
Victor Stinner08654e12010-10-18 12:09:02 +00001283 if (code != NULL && p_modpath != NULL) {
1284 *p_modpath = PyTuple_GetItem(toc_entry, 0);
1285 Py_INCREF(*p_modpath);
1286 }
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001287 goto exit;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001288 }
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001289 else
1290 Py_CLEAR(fullpath);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001291 }
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001292 PyErr_Format(ZipImportError, "can't find module %R", fullname);
1293exit:
1294 Py_DECREF(path);
1295 Py_XDECREF(fullpath);
1296 return code;
Just van Rossum52e14d62002-12-30 22:08:05 +00001297}
1298
1299
1300/* Module init */
1301
1302PyDoc_STRVAR(zipimport_doc,
1303"zipimport provides support for importing Python modules from Zip archives.\n\
1304\n\
1305This module exports three objects:\n\
1306- zipimporter: a class; its constructor takes a path to a Zip archive.\n\
Fredrik Lundhb84b35f2006-01-15 15:00:40 +00001307- ZipImportError: exception raised by zipimporter objects. It's a\n\
Just van Rossum52e14d62002-12-30 22:08:05 +00001308 subclass of ImportError, so it can be caught as ImportError, too.\n\
1309- _zip_directory_cache: a dict, mapping archive paths to zip directory\n\
1310 info dicts, as used in zipimporter._files.\n\
1311\n\
1312It is usually not needed to use the zipimport module explicitly; it is\n\
1313used by the builtin import mechanism for sys.path items that are paths\n\
1314to Zip archives.");
1315
Martin v. Löwis1a214512008-06-11 05:26:20 +00001316static struct PyModuleDef zipimportmodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001317 PyModuleDef_HEAD_INIT,
1318 "zipimport",
1319 zipimport_doc,
1320 -1,
1321 NULL,
1322 NULL,
1323 NULL,
1324 NULL,
1325 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +00001326};
1327
Just van Rossum52e14d62002-12-30 22:08:05 +00001328PyMODINIT_FUNC
Martin v. Löwis1a214512008-06-11 05:26:20 +00001329PyInit_zipimport(void)
Just van Rossum52e14d62002-12-30 22:08:05 +00001330{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001331 PyObject *mod;
Just van Rossum52e14d62002-12-30 22:08:05 +00001332
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001333 if (PyType_Ready(&ZipImporter_Type) < 0)
1334 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +00001335
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001336 /* Correct directory separator */
1337 zip_searchorder[0].suffix[0] = SEP;
1338 zip_searchorder[1].suffix[0] = SEP;
1339 zip_searchorder[2].suffix[0] = SEP;
1340 if (Py_OptimizeFlag) {
1341 /* Reverse *.pyc and *.pyo */
1342 struct st_zip_searchorder tmp;
1343 tmp = zip_searchorder[0];
1344 zip_searchorder[0] = zip_searchorder[1];
1345 zip_searchorder[1] = tmp;
1346 tmp = zip_searchorder[3];
1347 zip_searchorder[3] = zip_searchorder[4];
1348 zip_searchorder[4] = tmp;
1349 }
Just van Rossum52e14d62002-12-30 22:08:05 +00001350
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001351 mod = PyModule_Create(&zipimportmodule);
1352 if (mod == NULL)
1353 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +00001354
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001355 ZipImportError = PyErr_NewException("zipimport.ZipImportError",
1356 PyExc_ImportError, NULL);
1357 if (ZipImportError == NULL)
1358 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +00001359
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001360 Py_INCREF(ZipImportError);
1361 if (PyModule_AddObject(mod, "ZipImportError",
1362 ZipImportError) < 0)
1363 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +00001364
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001365 Py_INCREF(&ZipImporter_Type);
1366 if (PyModule_AddObject(mod, "zipimporter",
1367 (PyObject *)&ZipImporter_Type) < 0)
1368 return NULL;
Just van Rossumf8b6de12002-12-31 09:51:59 +00001369
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001370 zip_directory_cache = PyDict_New();
1371 if (zip_directory_cache == NULL)
1372 return NULL;
1373 Py_INCREF(zip_directory_cache);
1374 if (PyModule_AddObject(mod, "_zip_directory_cache",
1375 zip_directory_cache) < 0)
1376 return NULL;
1377 return mod;
Just van Rossum52e14d62002-12-30 22:08:05 +00001378}