blob: 85013665d1f4bc796deb41a45032607856f7e5c9 [file] [log] [blame]
Just van Rossum52e14d62002-12-30 22:08:05 +00001#include "Python.h"
Benjamin Peterson42aa93b2017-12-09 10:26:52 -08002#include "internal/import.h"
Eric Snow2ebc5ce2017-09-07 23:51:28 -06003#include "internal/pystate.h"
Just van Rossum52e14d62002-12-30 22:08:05 +00004#include "structmember.h"
5#include "osdefs.h"
6#include "marshal.h"
Just van Rossum52e14d62002-12-30 22:08:05 +00007#include <time.h>
8
9
10#define IS_SOURCE 0x0
11#define IS_BYTECODE 0x1
12#define IS_PACKAGE 0x2
13
14struct st_zip_searchorder {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000015 char suffix[14];
16 int type;
Just van Rossum52e14d62002-12-30 22:08:05 +000017};
18
Victor Stinner651f9f72013-11-12 21:44:18 +010019#ifdef ALTSEP
20_Py_IDENTIFIER(replace);
21#endif
22
Just van Rossum52e14d62002-12-30 22:08:05 +000023/* zip_searchorder defines how we search for a module in the Zip
24 archive: we first search for a package __init__, then for
Brett Cannonf299abd2015-04-13 14:21:02 -040025 non-package .pyc, and .py entries. The .pyc entries
Just van Rossum52e14d62002-12-30 22:08:05 +000026 are swapped by initzipimport() if we run in optimized mode. Also,
27 '/' is replaced by SEP there. */
Neal Norwitz29fd2ba2003-03-23 13:21:03 +000028static struct st_zip_searchorder zip_searchorder[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000029 {"/__init__.pyc", IS_PACKAGE | IS_BYTECODE},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000030 {"/__init__.py", IS_PACKAGE | IS_SOURCE},
31 {".pyc", IS_BYTECODE},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000032 {".py", IS_SOURCE},
33 {"", 0}
Just van Rossum52e14d62002-12-30 22:08:05 +000034};
35
36/* zipimporter object definition and support */
37
38typedef struct _zipimporter ZipImporter;
39
40struct _zipimporter {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000041 PyObject_HEAD
Victor Stinner9e40fad2010-10-18 22:34:46 +000042 PyObject *archive; /* pathname of the Zip archive,
43 decoded from the filesystem encoding */
Victor Stinner72f767e2010-10-18 11:44:21 +000044 PyObject *prefix; /* file prefix: "a/sub/directory/",
45 encoded to the filesystem encoding */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000046 PyObject *files; /* dict with file info {path: toc_entry} */
Just van Rossum52e14d62002-12-30 22:08:05 +000047};
48
Just van Rossum52e14d62002-12-30 22:08:05 +000049static PyObject *ZipImportError;
Victor Stinnerc342fca2010-10-18 11:39:05 +000050/* read_directory() cache */
Just van Rossum52e14d62002-12-30 22:08:05 +000051static PyObject *zip_directory_cache = NULL;
52
53/* forward decls */
Benjamin Peterson34c15402014-02-16 14:17:28 -050054static PyObject *read_directory(PyObject *archive);
55static PyObject *get_data(PyObject *archive, PyObject *toc_entry);
Victor Stinnerf6b563a2011-03-14 20:46:50 -040056static PyObject *get_module_code(ZipImporter *self, PyObject *fullname,
Victor Stinner08654e12010-10-18 12:09:02 +000057 int *p_ispackage, PyObject **p_modpath);
Just van Rossum52e14d62002-12-30 22:08:05 +000058
Yaron de Leeuw02f3b7d2017-08-18 14:41:13 -040059static PyTypeObject ZipImporter_Type;
Just van Rossum52e14d62002-12-30 22:08:05 +000060
61#define ZipImporter_Check(op) PyObject_TypeCheck(op, &ZipImporter_Type)
62
Yaron de Leeuw02f3b7d2017-08-18 14:41:13 -040063/*[clinic input]
64module zipimport
65class zipimport.zipimporter "ZipImporter *" "&ZipImporter_Type"
66[clinic start generated code]*/
67/*[clinic end generated code: output=da39a3ee5e6b4b0d input=9db8b61557d911e7]*/
68#include "clinic/zipimport.c.h"
69
Just van Rossum52e14d62002-12-30 22:08:05 +000070
71/* zipimporter.__init__
72 Split the "subdirectory" from the Zip archive path, lookup a matching
73 entry in sys.path_importer_cache, fetch the file directory from there
74 if found, or else read it from the archive. */
Yaron de Leeuw02f3b7d2017-08-18 14:41:13 -040075
76/*[clinic input]
77zipimport.zipimporter.__init__
78
79 archivepath as path: object(converter="PyUnicode_FSDecoder")
80 A path-like object to a zipfile, or to a specific path inside
81 a zipfile.
82 /
83
84Create a new zipimporter instance.
85
86'archivepath' must be a path-like object to a zipfile, or to a specific path
87inside a zipfile. For example, it can be '/tmp/myimport.zip', or
88'/tmp/myimport.zip/mydirectory', if mydirectory is a valid directory inside
89the archive.
90
91'ZipImportError' is raised if 'archivepath' doesn't point to a valid Zip
92archive.
93
94The 'archive' attribute of the zipimporter object contains the name of the
95zipfile targeted.
96
97[clinic start generated code]*/
98
Just van Rossum52e14d62002-12-30 22:08:05 +000099static int
Yaron de Leeuw02f3b7d2017-08-18 14:41:13 -0400100zipimport_zipimporter___init___impl(ZipImporter *self, PyObject *path)
101/*[clinic end generated code: output=141558fefdb46dc8 input=92b9ebeed1f6a704]*/
Just van Rossum52e14d62002-12-30 22:08:05 +0000102{
Yaron de Leeuw02f3b7d2017-08-18 14:41:13 -0400103 PyObject *files, *tmp;
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100104 PyObject *filename = NULL;
105 Py_ssize_t len, flen;
Just van Rossum52e14d62002-12-30 22:08:05 +0000106
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100107 if (PyUnicode_READY(path) == -1)
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200108 return -1;
109
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100110 len = PyUnicode_GET_LENGTH(path);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000111 if (len == 0) {
112 PyErr_SetString(ZipImportError, "archive path is empty");
Victor Stinner2b8dab72010-08-14 14:54:10 +0000113 goto error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000114 }
Just van Rossum52e14d62002-12-30 22:08:05 +0000115
116#ifdef ALTSEP
Martin v. Löwiscfa61292011-10-31 09:01:22 +0100117 tmp = _PyObject_CallMethodId(path, &PyId_replace, "CC", ALTSEP, SEP);
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100118 if (!tmp)
119 goto error;
120 Py_DECREF(path);
121 path = tmp;
Just van Rossum52e14d62002-12-30 22:08:05 +0000122#endif
123
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100124 filename = path;
125 Py_INCREF(filename);
126 flen = len;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000127 for (;;) {
128 struct stat statbuf;
129 int rv;
Just van Rossum52e14d62002-12-30 22:08:05 +0000130
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100131 rv = _Py_stat(filename, &statbuf);
Victor Stinnerbd0850b2011-12-18 20:47:30 +0100132 if (rv == -2)
133 goto error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000134 if (rv == 0) {
135 /* it exists */
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100136 if (!S_ISREG(statbuf.st_mode))
137 /* it's a not file */
138 Py_CLEAR(filename);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000139 break;
140 }
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100141 Py_CLEAR(filename);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000142 /* back up one path element */
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100143 flen = PyUnicode_FindChar(path, SEP, 0, flen, -1);
144 if (flen == -1)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000145 break;
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100146 filename = PyUnicode_Substring(path, 0, flen);
Victor Stinneraf8b7e82013-10-29 01:46:24 +0100147 if (filename == NULL)
148 goto error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000149 }
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100150 if (filename == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000151 PyErr_SetString(ZipImportError, "not a Zip file");
Victor Stinner2b8dab72010-08-14 14:54:10 +0000152 goto error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000153 }
Just van Rossum52e14d62002-12-30 22:08:05 +0000154
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100155 if (PyUnicode_READY(filename) < 0)
156 goto error;
157
158 files = PyDict_GetItem(zip_directory_cache, filename);
Victor Stinner2b8dab72010-08-14 14:54:10 +0000159 if (files == NULL) {
Benjamin Peterson34c15402014-02-16 14:17:28 -0500160 files = read_directory(filename);
161 if (files == NULL)
Victor Stinner2b8dab72010-08-14 14:54:10 +0000162 goto error;
Benjamin Peterson34c15402014-02-16 14:17:28 -0500163 if (PyDict_SetItem(zip_directory_cache, filename, files) != 0)
Victor Stinner2b8dab72010-08-14 14:54:10 +0000164 goto error;
165 }
166 else
167 Py_INCREF(files);
Oren Milmanc0cabc22017-10-09 18:06:19 +0300168 Py_XSETREF(self->files, files);
Victor Stinner2b8dab72010-08-14 14:54:10 +0000169
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100170 /* Transfer reference */
Oren Milmanc0cabc22017-10-09 18:06:19 +0300171 Py_XSETREF(self->archive, filename);
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100172 filename = NULL;
Victor Stinner2b8dab72010-08-14 14:54:10 +0000173
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100174 /* Check if there is a prefix directory following the filename. */
175 if (flen != len) {
176 tmp = PyUnicode_Substring(path, flen+1,
177 PyUnicode_GET_LENGTH(path));
178 if (tmp == NULL)
179 goto error;
Oren Milmanc0cabc22017-10-09 18:06:19 +0300180 Py_XSETREF(self->prefix, tmp);
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100181 if (PyUnicode_READ_CHAR(path, len-1) != SEP) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000182 /* add trailing SEP */
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100183 tmp = PyUnicode_FromFormat("%U%c", self->prefix, SEP);
184 if (tmp == NULL)
185 goto error;
Serhiy Storchaka57a01d32016-04-10 18:05:40 +0300186 Py_SETREF(self->prefix, tmp);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000187 }
188 }
Oren Milmanc0cabc22017-10-09 18:06:19 +0300189 else {
190 Py_XSETREF(self->prefix, PyUnicode_New(0, 0));
191 }
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100192 Py_DECREF(path);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000193 return 0;
Victor Stinner2b8dab72010-08-14 14:54:10 +0000194
195error:
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100196 Py_DECREF(path);
197 Py_XDECREF(filename);
Victor Stinner2b8dab72010-08-14 14:54:10 +0000198 return -1;
Just van Rossum52e14d62002-12-30 22:08:05 +0000199}
200
201/* GC support. */
202static int
203zipimporter_traverse(PyObject *obj, visitproc visit, void *arg)
204{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000205 ZipImporter *self = (ZipImporter *)obj;
206 Py_VISIT(self->files);
207 return 0;
Just van Rossum52e14d62002-12-30 22:08:05 +0000208}
209
210static void
211zipimporter_dealloc(ZipImporter *self)
212{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000213 PyObject_GC_UnTrack(self);
214 Py_XDECREF(self->archive);
215 Py_XDECREF(self->prefix);
216 Py_XDECREF(self->files);
217 Py_TYPE(self)->tp_free((PyObject *)self);
Just van Rossum52e14d62002-12-30 22:08:05 +0000218}
219
220static PyObject *
221zipimporter_repr(ZipImporter *self)
222{
Victor Stinner028dd972010-08-17 00:04:48 +0000223 if (self->archive == NULL)
224 return PyUnicode_FromString("<zipimporter object \"???\">");
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200225 else if (self->prefix != NULL && PyUnicode_GET_LENGTH(self->prefix) != 0)
Victor Stinner07298a12010-10-18 22:45:54 +0000226 return PyUnicode_FromFormat("<zipimporter object \"%U%c%U\">",
Victor Stinner028dd972010-08-17 00:04:48 +0000227 self->archive, SEP, self->prefix);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000228 else
Victor Stinner07298a12010-10-18 22:45:54 +0000229 return PyUnicode_FromFormat("<zipimporter object \"%U\">",
Victor Stinner028dd972010-08-17 00:04:48 +0000230 self->archive);
Just van Rossum52e14d62002-12-30 22:08:05 +0000231}
232
233/* return fullname.split(".")[-1] */
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400234static PyObject *
235get_subname(PyObject *fullname)
Just van Rossum52e14d62002-12-30 22:08:05 +0000236{
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100237 Py_ssize_t len, dot;
238 if (PyUnicode_READY(fullname) < 0)
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200239 return NULL;
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100240 len = PyUnicode_GET_LENGTH(fullname);
241 dot = PyUnicode_FindChar(fullname, '.', 0, len, -1);
242 if (dot == -1) {
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400243 Py_INCREF(fullname);
244 return fullname;
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100245 } else
246 return PyUnicode_Substring(fullname, dot+1, len);
Just van Rossum52e14d62002-12-30 22:08:05 +0000247}
248
249/* Given a (sub)modulename, write the potential file path in the
250 archive (without extension) to the path buffer. Return the
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400251 length of the resulting string.
252
253 return self.prefix + name.replace('.', os.sep) */
254static PyObject*
255make_filename(PyObject *prefix, PyObject *name)
Just van Rossum52e14d62002-12-30 22:08:05 +0000256{
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400257 PyObject *pathobj;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200258 Py_UCS4 *p, *buf;
259 Py_ssize_t len;
Just van Rossum52e14d62002-12-30 22:08:05 +0000260
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200261 len = PyUnicode_GET_LENGTH(prefix) + PyUnicode_GET_LENGTH(name) + 1;
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +0200262 p = buf = PyMem_New(Py_UCS4, len);
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200263 if (buf == NULL) {
264 PyErr_NoMemory();
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400265 return NULL;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200266 }
Just van Rossum52e14d62002-12-30 22:08:05 +0000267
Christian Heimes1b5c76a2012-09-10 02:00:34 +0200268 if (!PyUnicode_AsUCS4(prefix, p, len, 0)) {
269 PyMem_Free(buf);
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200270 return NULL;
Christian Heimes1b5c76a2012-09-10 02:00:34 +0200271 }
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200272 p += PyUnicode_GET_LENGTH(prefix);
273 len -= PyUnicode_GET_LENGTH(prefix);
Christian Heimes1b5c76a2012-09-10 02:00:34 +0200274 if (!PyUnicode_AsUCS4(name, p, len, 1)) {
275 PyMem_Free(buf);
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200276 return NULL;
Christian Heimes1b5c76a2012-09-10 02:00:34 +0200277 }
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400278 for (; *p; p++) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000279 if (*p == '.')
280 *p = SEP;
281 }
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200282 pathobj = PyUnicode_FromKindAndData(PyUnicode_4BYTE_KIND,
283 buf, p-buf);
284 PyMem_Free(buf);
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400285 return pathobj;
Just van Rossum52e14d62002-12-30 22:08:05 +0000286}
287
Raymond Hettinger2c45c9a2004-11-10 13:08:35 +0000288enum zi_module_info {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000289 MI_ERROR,
290 MI_NOT_FOUND,
291 MI_MODULE,
292 MI_PACKAGE
Just van Rossum52e14d62002-12-30 22:08:05 +0000293};
294
Eric V. Smith984b11f2012-05-24 20:21:04 -0400295/* Does this path represent a directory?
296 on error, return < 0
297 if not a dir, return 0
298 if a dir, return 1
299*/
300static int
301check_is_directory(ZipImporter *self, PyObject* prefix, PyObject *path)
302{
303 PyObject *dirpath;
Benjamin Peterson18eac4a2012-05-25 00:24:42 -0700304 int res;
Eric V. Smith984b11f2012-05-24 20:21:04 -0400305
306 /* See if this is a "directory". If so, it's eligible to be part
307 of a namespace package. We test by seeing if the name, with an
308 appended path separator, exists. */
309 dirpath = PyUnicode_FromFormat("%U%U%c", prefix, path, SEP);
310 if (dirpath == NULL)
311 return -1;
312 /* If dirpath is present in self->files, we have a directory. */
Benjamin Peterson18eac4a2012-05-25 00:24:42 -0700313 res = PyDict_Contains(self->files, dirpath);
Eric V. Smith984b11f2012-05-24 20:21:04 -0400314 Py_DECREF(dirpath);
Benjamin Peterson18eac4a2012-05-25 00:24:42 -0700315 return res;
Eric V. Smith984b11f2012-05-24 20:21:04 -0400316}
317
Just van Rossum52e14d62002-12-30 22:08:05 +0000318/* Return some information about a module. */
Raymond Hettinger2c45c9a2004-11-10 13:08:35 +0000319static enum zi_module_info
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400320get_module_info(ZipImporter *self, PyObject *fullname)
Just van Rossum52e14d62002-12-30 22:08:05 +0000321{
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400322 PyObject *subname;
323 PyObject *path, *fullpath, *item;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000324 struct st_zip_searchorder *zso;
Just van Rossum52e14d62002-12-30 22:08:05 +0000325
Oren Milmandb60a5b2017-10-20 23:42:35 +0300326 if (self->prefix == NULL) {
327 PyErr_SetString(PyExc_ValueError,
328 "zipimporter.__init__() wasn't called");
329 return MI_ERROR;
330 }
331
Victor Stinner965a8a12010-10-18 21:44:33 +0000332 subname = get_subname(fullname);
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400333 if (subname == NULL)
334 return MI_ERROR;
Just van Rossum52e14d62002-12-30 22:08:05 +0000335
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400336 path = make_filename(self->prefix, subname);
337 Py_DECREF(subname);
338 if (path == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000339 return MI_ERROR;
Just van Rossum52e14d62002-12-30 22:08:05 +0000340
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000341 for (zso = zip_searchorder; *zso->suffix; zso++) {
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400342 fullpath = PyUnicode_FromFormat("%U%s", path, zso->suffix);
343 if (fullpath == NULL) {
344 Py_DECREF(path);
345 return MI_ERROR;
346 }
347 item = PyDict_GetItem(self->files, fullpath);
348 Py_DECREF(fullpath);
349 if (item != NULL) {
350 Py_DECREF(path);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000351 if (zso->type & IS_PACKAGE)
352 return MI_PACKAGE;
353 else
354 return MI_MODULE;
355 }
356 }
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400357 Py_DECREF(path);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000358 return MI_NOT_FOUND;
Just van Rossum52e14d62002-12-30 22:08:05 +0000359}
360
Benjamin Peterson5ed7bd72012-05-24 22:54:15 -0700361typedef enum {
Brett Cannon56aae8f2016-01-15 11:22:19 -0800362 FL_ERROR = -1, /* error */
363 FL_NOT_FOUND, /* no loader or namespace portions found */
364 FL_MODULE_FOUND, /* module/package found */
365 FL_NS_FOUND /* namespace portion found: */
366 /* *namespace_portion will point to the name */
Benjamin Peterson5ed7bd72012-05-24 22:54:15 -0700367} find_loader_result;
368
Brett Cannon56aae8f2016-01-15 11:22:19 -0800369/* The guts of "find_loader" and "find_module".
Eric V. Smith984b11f2012-05-24 20:21:04 -0400370*/
Benjamin Peterson5ed7bd72012-05-24 22:54:15 -0700371static find_loader_result
Eric V. Smith984b11f2012-05-24 20:21:04 -0400372find_loader(ZipImporter *self, PyObject *fullname, PyObject **namespace_portion)
373{
374 enum zi_module_info mi;
375
376 *namespace_portion = NULL;
377
378 mi = get_module_info(self, fullname);
379 if (mi == MI_ERROR)
Benjamin Peterson46c214d2012-05-25 10:22:29 -0700380 return FL_ERROR;
Eric V. Smith984b11f2012-05-24 20:21:04 -0400381 if (mi == MI_NOT_FOUND) {
382 /* Not a module or regular package. See if this is a directory, and
383 therefore possibly a portion of a namespace package. */
Brett Cannon56aae8f2016-01-15 11:22:19 -0800384 find_loader_result result = FL_NOT_FOUND;
385 PyObject *subname;
386 int is_dir;
387
388 /* We're only interested in the last path component of fullname;
389 earlier components are recorded in self->prefix. */
390 subname = get_subname(fullname);
391 if (subname == NULL) {
392 return FL_ERROR;
393 }
394
395 is_dir = check_is_directory(self, self->prefix, subname);
Eric V. Smith984b11f2012-05-24 20:21:04 -0400396 if (is_dir < 0)
Brett Cannon56aae8f2016-01-15 11:22:19 -0800397 result = FL_ERROR;
398 else if (is_dir) {
Eric V. Smith984b11f2012-05-24 20:21:04 -0400399 /* This is possibly a portion of a namespace
400 package. Return the string representing its path,
401 without a trailing separator. */
402 *namespace_portion = PyUnicode_FromFormat("%U%c%U%U",
403 self->archive, SEP,
Brett Cannon56aae8f2016-01-15 11:22:19 -0800404 self->prefix, subname);
Eric V. Smith984b11f2012-05-24 20:21:04 -0400405 if (*namespace_portion == NULL)
Brett Cannon56aae8f2016-01-15 11:22:19 -0800406 result = FL_ERROR;
407 else
408 result = FL_NS_FOUND;
Eric V. Smith984b11f2012-05-24 20:21:04 -0400409 }
Brett Cannon56aae8f2016-01-15 11:22:19 -0800410 Py_DECREF(subname);
411 return result;
Eric V. Smith984b11f2012-05-24 20:21:04 -0400412 }
413 /* This is a module or package. */
Benjamin Peterson46c214d2012-05-25 10:22:29 -0700414 return FL_MODULE_FOUND;
Eric V. Smith984b11f2012-05-24 20:21:04 -0400415}
416
Yaron de Leeuw02f3b7d2017-08-18 14:41:13 -0400417/*[clinic input]
418zipimport.zipimporter.find_module
Eric V. Smith984b11f2012-05-24 20:21:04 -0400419
Yaron de Leeuw02f3b7d2017-08-18 14:41:13 -0400420 fullname: unicode
421 path: object = None
422 /
423
424Search for a module specified by 'fullname'.
425
426'fullname' must be the fully qualified (dotted) module name. It returns the
427zipimporter instance itself if the module was found, or None if it wasn't.
428The optional 'path' argument is ignored -- it's there for compatibility
429with the importer protocol.
430
431[clinic start generated code]*/
432
Just van Rossum52e14d62002-12-30 22:08:05 +0000433static PyObject *
Yaron de Leeuw02f3b7d2017-08-18 14:41:13 -0400434zipimport_zipimporter_find_module_impl(ZipImporter *self, PyObject *fullname,
435 PyObject *path)
436/*[clinic end generated code: output=506087f609466dc7 input=e3528520e075063f]*/
Just van Rossum52e14d62002-12-30 22:08:05 +0000437{
Benjamin Peterson5ed7bd72012-05-24 22:54:15 -0700438 PyObject *namespace_portion = NULL;
439 PyObject *result = NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +0000440
Eric V. Smith984b11f2012-05-24 20:21:04 -0400441 switch (find_loader(self, fullname, &namespace_portion)) {
Benjamin Peterson46c214d2012-05-25 10:22:29 -0700442 case FL_ERROR:
Benjamin Petersona6a7a1a2012-05-25 00:22:04 -0700443 return NULL;
Benjamin Peterson46c214d2012-05-25 10:22:29 -0700444 case FL_NS_FOUND:
Benjamin Peterson5ed7bd72012-05-24 22:54:15 -0700445 /* A namespace portion is not allowed via find_module, so return None. */
Eric V. Smith984b11f2012-05-24 20:21:04 -0400446 Py_DECREF(namespace_portion);
Benjamin Peterson5ed7bd72012-05-24 22:54:15 -0700447 /* FALL THROUGH */
Benjamin Peterson46c214d2012-05-25 10:22:29 -0700448 case FL_NOT_FOUND:
Benjamin Peterson5ed7bd72012-05-24 22:54:15 -0700449 result = Py_None;
450 break;
Benjamin Peterson46c214d2012-05-25 10:22:29 -0700451 case FL_MODULE_FOUND:
Benjamin Peterson5ed7bd72012-05-24 22:54:15 -0700452 result = (PyObject *)self;
453 break;
Brett Cannon56aae8f2016-01-15 11:22:19 -0800454 default:
455 PyErr_BadInternalCall();
456 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000457 }
Benjamin Petersona6a7a1a2012-05-25 00:22:04 -0700458 Py_INCREF(result);
Benjamin Peterson2d12e142012-05-25 00:19:40 -0700459 return result;
Eric V. Smith984b11f2012-05-24 20:21:04 -0400460}
461
462
Yaron de Leeuw02f3b7d2017-08-18 14:41:13 -0400463/*[clinic input]
464zipimport.zipimporter.find_loader
465
466 fullname: unicode
467 path: object = None
468 /
469
470Search for a module specified by 'fullname'.
471
472'fullname' must be the fully qualified (dotted) module name. It returns the
473zipimporter instance itself if the module was found, a string containing the
474full path name if it's possibly a portion of a namespace package,
475or None otherwise. The optional 'path' argument is ignored -- it's
476there for compatibility with the importer protocol.
477
478[clinic start generated code]*/
479
Eric V. Smith984b11f2012-05-24 20:21:04 -0400480static PyObject *
Yaron de Leeuw02f3b7d2017-08-18 14:41:13 -0400481zipimport_zipimporter_find_loader_impl(ZipImporter *self, PyObject *fullname,
482 PyObject *path)
483/*[clinic end generated code: output=601599a43bc0f49a input=dc73f275b0d5be23]*/
Eric V. Smith984b11f2012-05-24 20:21:04 -0400484{
Eric V. Smith984b11f2012-05-24 20:21:04 -0400485 PyObject *result = NULL;
486 PyObject *namespace_portion = NULL;
487
Eric V. Smith984b11f2012-05-24 20:21:04 -0400488 switch (find_loader(self, fullname, &namespace_portion)) {
Benjamin Peterson46c214d2012-05-25 10:22:29 -0700489 case FL_ERROR:
Benjamin Peterson5ed7bd72012-05-24 22:54:15 -0700490 return NULL;
Benjamin Peterson46c214d2012-05-25 10:22:29 -0700491 case FL_NOT_FOUND: /* Not found, return (None, []) */
Benjamin Peterson5ed7bd72012-05-24 22:54:15 -0700492 result = Py_BuildValue("O[]", Py_None);
493 break;
Benjamin Peterson46c214d2012-05-25 10:22:29 -0700494 case FL_MODULE_FOUND: /* Return (self, []) */
Benjamin Peterson5ed7bd72012-05-24 22:54:15 -0700495 result = Py_BuildValue("O[]", self);
496 break;
Benjamin Peterson46c214d2012-05-25 10:22:29 -0700497 case FL_NS_FOUND: /* Return (None, [namespace_portion]) */
Benjamin Peterson5ed7bd72012-05-24 22:54:15 -0700498 result = Py_BuildValue("O[O]", Py_None, namespace_portion);
Benjamin Peterson209e04c2012-05-24 22:35:39 -0700499 Py_DECREF(namespace_portion);
Eric V. Smith984b11f2012-05-24 20:21:04 -0400500 return result;
Brett Cannon56aae8f2016-01-15 11:22:19 -0800501 default:
502 PyErr_BadInternalCall();
503 return NULL;
Eric V. Smith984b11f2012-05-24 20:21:04 -0400504 }
Benjamin Peterson5ed7bd72012-05-24 22:54:15 -0700505 return result;
Just van Rossum52e14d62002-12-30 22:08:05 +0000506}
507
Yaron de Leeuw02f3b7d2017-08-18 14:41:13 -0400508/*[clinic input]
509zipimport.zipimporter.load_module
510
511 fullname: unicode
512 /
513
514Load the module specified by 'fullname'.
515
516'fullname' must be the fully qualified (dotted) module name. It returns the
517imported module, or raises ZipImportError if it wasn't found.
518
519[clinic start generated code]*/
520
Just van Rossum52e14d62002-12-30 22:08:05 +0000521static PyObject *
Yaron de Leeuw02f3b7d2017-08-18 14:41:13 -0400522zipimport_zipimporter_load_module_impl(ZipImporter *self, PyObject *fullname)
523/*[clinic end generated code: output=7303cebf88d47953 input=c236e2e8621f04ef]*/
Just van Rossum52e14d62002-12-30 22:08:05 +0000524{
Victor Stinner26fabe12010-10-18 12:03:25 +0000525 PyObject *code = NULL, *mod, *dict;
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400526 PyObject *modpath = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000527 int ispackage;
Just van Rossum52e14d62002-12-30 22:08:05 +0000528
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200529 if (PyUnicode_READY(fullname) == -1)
530 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +0000531
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000532 code = get_module_code(self, fullname, &ispackage, &modpath);
533 if (code == NULL)
Victor Stinner26fabe12010-10-18 12:03:25 +0000534 goto error;
Just van Rossum52e14d62002-12-30 22:08:05 +0000535
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400536 mod = PyImport_AddModuleObject(fullname);
Victor Stinner26fabe12010-10-18 12:03:25 +0000537 if (mod == NULL)
538 goto error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000539 dict = PyModule_GetDict(mod);
Just van Rossum52e14d62002-12-30 22:08:05 +0000540
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000541 /* mod.__loader__ = self */
542 if (PyDict_SetItemString(dict, "__loader__", (PyObject *)self) != 0)
543 goto error;
Just van Rossum52e14d62002-12-30 22:08:05 +0000544
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000545 if (ispackage) {
546 /* add __path__ to the module *before* the code gets
547 executed */
Victor Stinneraf8b7e82013-10-29 01:46:24 +0100548 PyObject *pkgpath, *fullpath, *subname;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000549 int err;
Just van Rossum52e14d62002-12-30 22:08:05 +0000550
Victor Stinneraf8b7e82013-10-29 01:46:24 +0100551 subname = get_subname(fullname);
552 if (subname == NULL)
553 goto error;
554
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400555 fullpath = PyUnicode_FromFormat("%U%c%U%U",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000556 self->archive, SEP,
557 self->prefix, subname);
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400558 Py_DECREF(subname);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000559 if (fullpath == NULL)
560 goto error;
Just van Rossum52e14d62002-12-30 22:08:05 +0000561
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400562 pkgpath = Py_BuildValue("[N]", fullpath);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000563 if (pkgpath == NULL)
564 goto error;
565 err = PyDict_SetItemString(dict, "__path__", pkgpath);
566 Py_DECREF(pkgpath);
567 if (err != 0)
568 goto error;
569 }
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400570 mod = PyImport_ExecCodeModuleObject(fullname, code, modpath, NULL);
Victor Stinner26fabe12010-10-18 12:03:25 +0000571 Py_CLEAR(code);
572 if (mod == NULL)
573 goto error;
574
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000575 if (Py_VerboseFlag)
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400576 PySys_FormatStderr("import %U # loaded from Zip %U\n",
Victor Stinner08654e12010-10-18 12:09:02 +0000577 fullname, modpath);
578 Py_DECREF(modpath);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000579 return mod;
Just van Rossum52e14d62002-12-30 22:08:05 +0000580error:
Victor Stinner26fabe12010-10-18 12:03:25 +0000581 Py_XDECREF(code);
Victor Stinner08654e12010-10-18 12:09:02 +0000582 Py_XDECREF(modpath);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000583 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +0000584}
585
Yaron de Leeuw02f3b7d2017-08-18 14:41:13 -0400586/*[clinic input]
587zipimport.zipimporter.get_filename
Nick Coghlanf088e5e2008-12-14 11:50:48 +0000588
Yaron de Leeuw02f3b7d2017-08-18 14:41:13 -0400589 fullname: unicode
590 /
591
592Return the filename for the specified module.
593[clinic start generated code]*/
594
595static PyObject *
596zipimport_zipimporter_get_filename_impl(ZipImporter *self,
597 PyObject *fullname)
598/*[clinic end generated code: output=c5b92b58bea86506 input=28d2eb57e4f25c8a]*/
599{
600 PyObject *code, *modpath;
601 int ispackage;
Nick Coghlanf088e5e2008-12-14 11:50:48 +0000602
603 /* Deciding the filename requires working out where the code
604 would come from if the module was actually loaded */
605 code = get_module_code(self, fullname, &ispackage, &modpath);
606 if (code == NULL)
Victor Stinnerc342fca2010-10-18 11:39:05 +0000607 return NULL;
Nick Coghlanf088e5e2008-12-14 11:50:48 +0000608 Py_DECREF(code); /* Only need the path info */
609
Victor Stinner08654e12010-10-18 12:09:02 +0000610 return modpath;
Nick Coghlanf088e5e2008-12-14 11:50:48 +0000611}
612
Yaron de Leeuw02f3b7d2017-08-18 14:41:13 -0400613/*[clinic input]
614zipimport.zipimporter.is_package
Just van Rossum52e14d62002-12-30 22:08:05 +0000615
Yaron de Leeuw02f3b7d2017-08-18 14:41:13 -0400616 fullname: unicode
617 /
618
619Return True if the module specified by fullname is a package.
620
621Raise ZipImportError if the module couldn't be found.
622
623[clinic start generated code]*/
624
625static PyObject *
626zipimport_zipimporter_is_package_impl(ZipImporter *self, PyObject *fullname)
627/*[clinic end generated code: output=c32958c2a5216ae6 input=a7ba752f64345062]*/
628{
629 enum zi_module_info mi;
Just van Rossum52e14d62002-12-30 22:08:05 +0000630
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000631 mi = get_module_info(self, fullname);
632 if (mi == MI_ERROR)
Victor Stinner965a8a12010-10-18 21:44:33 +0000633 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000634 if (mi == MI_NOT_FOUND) {
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400635 PyErr_Format(ZipImportError, "can't find module %R", fullname);
Victor Stinner965a8a12010-10-18 21:44:33 +0000636 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000637 }
638 return PyBool_FromLong(mi == MI_PACKAGE);
Just van Rossum52e14d62002-12-30 22:08:05 +0000639}
640
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200641
Yaron de Leeuw02f3b7d2017-08-18 14:41:13 -0400642/*[clinic input]
643zipimport.zipimporter.get_data
644
645 pathname as path: unicode
646 /
647
648Return the data associated with 'pathname'.
649
650Raise OSError if the file was not found.
651
652[clinic start generated code]*/
653
Just van Rossum52e14d62002-12-30 22:08:05 +0000654static PyObject *
Yaron de Leeuw02f3b7d2017-08-18 14:41:13 -0400655zipimport_zipimporter_get_data_impl(ZipImporter *self, PyObject *path)
656/*[clinic end generated code: output=65dc506aaa268436 input=fa6428b74843c4ae]*/
Just van Rossum52e14d62002-12-30 22:08:05 +0000657{
Yaron de Leeuw02f3b7d2017-08-18 14:41:13 -0400658 PyObject *key;
Benjamin Peterson34c15402014-02-16 14:17:28 -0500659 PyObject *toc_entry;
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100660 Py_ssize_t path_start, path_len, len;
Just van Rossum52e14d62002-12-30 22:08:05 +0000661
Oren Milmandb60a5b2017-10-20 23:42:35 +0300662 if (self->archive == NULL) {
663 PyErr_SetString(PyExc_ValueError,
664 "zipimporter.__init__() wasn't called");
665 return NULL;
666 }
667
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200668#ifdef ALTSEP
Oren Milman631fdee2017-08-29 20:40:15 +0300669 path = _PyObject_CallMethodId((PyObject *)&PyUnicode_Type, &PyId_replace,
670 "OCC", path, ALTSEP, SEP);
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100671 if (!path)
672 return NULL;
673#else
674 Py_INCREF(path);
Just van Rossum52e14d62002-12-30 22:08:05 +0000675#endif
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100676 if (PyUnicode_READY(path) == -1)
677 goto error;
678
679 path_len = PyUnicode_GET_LENGTH(path);
680
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200681 len = PyUnicode_GET_LENGTH(self->archive);
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100682 path_start = 0;
683 if (PyUnicode_Tailmatch(path, self->archive, 0, len, -1)
684 && PyUnicode_READ_CHAR(path, len) == SEP) {
685 path_start = len + 1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000686 }
Just van Rossum52e14d62002-12-30 22:08:05 +0000687
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100688 key = PyUnicode_Substring(path, path_start, path_len);
Victor Stinner60fe8d92010-08-16 23:48:11 +0000689 if (key == NULL)
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100690 goto error;
Victor Stinner60fe8d92010-08-16 23:48:11 +0000691 toc_entry = PyDict_GetItem(self->files, key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000692 if (toc_entry == NULL) {
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +0300693 PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, key);
Victor Stinner60fe8d92010-08-16 23:48:11 +0000694 Py_DECREF(key);
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100695 goto error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000696 }
Victor Stinner60fe8d92010-08-16 23:48:11 +0000697 Py_DECREF(key);
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100698 Py_DECREF(path);
Benjamin Peterson34c15402014-02-16 14:17:28 -0500699 return get_data(self->archive, toc_entry);
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100700 error:
701 Py_DECREF(path);
702 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +0000703}
704
Yaron de Leeuw02f3b7d2017-08-18 14:41:13 -0400705/*[clinic input]
706zipimport.zipimporter.get_code
707
708 fullname: unicode
709 /
710
711Return the code object for the specified module.
712
713Raise ZipImportError if the module couldn't be found.
714
715[clinic start generated code]*/
716
Just van Rossum52e14d62002-12-30 22:08:05 +0000717static PyObject *
Yaron de Leeuw02f3b7d2017-08-18 14:41:13 -0400718zipimport_zipimporter_get_code_impl(ZipImporter *self, PyObject *fullname)
719/*[clinic end generated code: output=b923c37fa99cbac4 input=2761412bc37f3549]*/
Just van Rossum52e14d62002-12-30 22:08:05 +0000720{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000721 return get_module_code(self, fullname, NULL, NULL);
Just van Rossum52e14d62002-12-30 22:08:05 +0000722}
723
Yaron de Leeuw02f3b7d2017-08-18 14:41:13 -0400724/*[clinic input]
725zipimport.zipimporter.get_source
Just van Rossum52e14d62002-12-30 22:08:05 +0000726
Yaron de Leeuw02f3b7d2017-08-18 14:41:13 -0400727 fullname: unicode
728 /
729
730Return the source code for the specified module.
731
732Raise ZipImportError if the module couldn't be found, return None if the
733archive does contain the module, but has no source for it.
734
735[clinic start generated code]*/
736
737static PyObject *
738zipimport_zipimporter_get_source_impl(ZipImporter *self, PyObject *fullname)
739/*[clinic end generated code: output=bc059301b0c33729 input=4e4b186f2e690716]*/
740{
741 PyObject *toc_entry;
742 PyObject *subname, *path, *fullpath;
743 enum zi_module_info mi;
Just van Rossum52e14d62002-12-30 22:08:05 +0000744
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000745 mi = get_module_info(self, fullname);
Victor Stinner965a8a12010-10-18 21:44:33 +0000746 if (mi == MI_ERROR)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000747 return NULL;
Victor Stinner04106562010-10-18 20:44:08 +0000748 if (mi == MI_NOT_FOUND) {
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400749 PyErr_Format(ZipImportError, "can't find module %R", fullname);
Victor Stinner04106562010-10-18 20:44:08 +0000750 return NULL;
751 }
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400752
Victor Stinner965a8a12010-10-18 21:44:33 +0000753 subname = get_subname(fullname);
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400754 if (subname == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000755 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +0000756
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400757 path = make_filename(self->prefix, subname);
758 Py_DECREF(subname);
759 if (path == NULL)
760 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +0000761
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400762 if (mi == MI_PACKAGE)
763 fullpath = PyUnicode_FromFormat("%U%c__init__.py", path, SEP);
764 else
765 fullpath = PyUnicode_FromFormat("%U.py", path);
766 Py_DECREF(path);
767 if (fullpath == NULL)
768 return NULL;
769
770 toc_entry = PyDict_GetItem(self->files, fullpath);
771 Py_DECREF(fullpath);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000772 if (toc_entry != NULL) {
Victor Stinner60fe8d92010-08-16 23:48:11 +0000773 PyObject *res, *bytes;
Benjamin Peterson34c15402014-02-16 14:17:28 -0500774 bytes = get_data(self->archive, toc_entry);
Victor Stinner60fe8d92010-08-16 23:48:11 +0000775 if (bytes == NULL)
776 return NULL;
777 res = PyUnicode_FromStringAndSize(PyBytes_AS_STRING(bytes),
778 PyBytes_GET_SIZE(bytes));
779 Py_DECREF(bytes);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000780 return res;
781 }
Just van Rossum52e14d62002-12-30 22:08:05 +0000782
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000783 /* we have the module, but no source */
Serhiy Storchaka228b12e2017-01-23 09:47:21 +0200784 Py_RETURN_NONE;
Just van Rossum52e14d62002-12-30 22:08:05 +0000785}
786
Barry Warsaw6f6eb352018-01-24 15:36:21 -0500787/*[clinic input]
788zipimport.zipimporter.get_resource_reader
789
790 fullname: unicode
791 /
792
793Return the ResourceReader for a package in a zip file.
794
795If 'fullname' is a package within the zip file, return the 'ResourceReader'
796object for the package. Otherwise return None.
797
798[clinic start generated code]*/
799
800static PyObject *
801zipimport_zipimporter_get_resource_reader_impl(ZipImporter *self,
802 PyObject *fullname)
803/*[clinic end generated code: output=5e367d431f830726 input=bfab94d736e99151]*/
804{
805 PyObject *module = PyImport_ImportModule("importlib.resources");
806 if (module == NULL) {
807 return NULL;
808 }
809 PyObject *retval = PyObject_CallMethod(
810 module, "_zipimport_get_resource_reader",
811 "OO", (PyObject *)self, fullname);
812 Py_DECREF(module);
813 return retval;
814}
815
Nick Coghlanf088e5e2008-12-14 11:50:48 +0000816
Just van Rossum52e14d62002-12-30 22:08:05 +0000817static PyMethodDef zipimporter_methods[] = {
Yaron de Leeuw02f3b7d2017-08-18 14:41:13 -0400818 ZIPIMPORT_ZIPIMPORTER_FIND_MODULE_METHODDEF
819 ZIPIMPORT_ZIPIMPORTER_FIND_LOADER_METHODDEF
820 ZIPIMPORT_ZIPIMPORTER_LOAD_MODULE_METHODDEF
821 ZIPIMPORT_ZIPIMPORTER_GET_FILENAME_METHODDEF
822 ZIPIMPORT_ZIPIMPORTER_IS_PACKAGE_METHODDEF
823 ZIPIMPORT_ZIPIMPORTER_GET_DATA_METHODDEF
824 ZIPIMPORT_ZIPIMPORTER_GET_CODE_METHODDEF
825 ZIPIMPORT_ZIPIMPORTER_GET_SOURCE_METHODDEF
Barry Warsaw6f6eb352018-01-24 15:36:21 -0500826 ZIPIMPORT_ZIPIMPORTER_GET_RESOURCE_READER_METHODDEF
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000827 {NULL, NULL} /* sentinel */
Just van Rossum52e14d62002-12-30 22:08:05 +0000828};
829
830static PyMemberDef zipimporter_members[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000831 {"archive", T_OBJECT, offsetof(ZipImporter, archive), READONLY},
832 {"prefix", T_OBJECT, offsetof(ZipImporter, prefix), READONLY},
833 {"_files", T_OBJECT, offsetof(ZipImporter, files), READONLY},
834 {NULL}
Just van Rossum52e14d62002-12-30 22:08:05 +0000835};
836
Just van Rossum52e14d62002-12-30 22:08:05 +0000837#define DEFERRED_ADDRESS(ADDR) 0
838
839static PyTypeObject ZipImporter_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000840 PyVarObject_HEAD_INIT(DEFERRED_ADDRESS(&PyType_Type), 0)
841 "zipimport.zipimporter",
842 sizeof(ZipImporter),
843 0, /* tp_itemsize */
844 (destructor)zipimporter_dealloc, /* tp_dealloc */
845 0, /* tp_print */
846 0, /* tp_getattr */
847 0, /* tp_setattr */
848 0, /* tp_reserved */
849 (reprfunc)zipimporter_repr, /* tp_repr */
850 0, /* tp_as_number */
851 0, /* tp_as_sequence */
852 0, /* tp_as_mapping */
853 0, /* tp_hash */
854 0, /* tp_call */
855 0, /* tp_str */
856 PyObject_GenericGetAttr, /* tp_getattro */
857 0, /* tp_setattro */
858 0, /* tp_as_buffer */
859 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE |
860 Py_TPFLAGS_HAVE_GC, /* tp_flags */
Yaron de Leeuw02f3b7d2017-08-18 14:41:13 -0400861 zipimport_zipimporter___init____doc__, /* tp_doc */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000862 zipimporter_traverse, /* tp_traverse */
863 0, /* tp_clear */
864 0, /* tp_richcompare */
865 0, /* tp_weaklistoffset */
866 0, /* tp_iter */
867 0, /* tp_iternext */
868 zipimporter_methods, /* tp_methods */
869 zipimporter_members, /* tp_members */
870 0, /* tp_getset */
871 0, /* tp_base */
872 0, /* tp_dict */
873 0, /* tp_descr_get */
874 0, /* tp_descr_set */
875 0, /* tp_dictoffset */
Yaron de Leeuw02f3b7d2017-08-18 14:41:13 -0400876 (initproc)zipimport_zipimporter___init__, /* tp_init */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000877 PyType_GenericAlloc, /* tp_alloc */
878 PyType_GenericNew, /* tp_new */
879 PyObject_GC_Del, /* tp_free */
Just van Rossum52e14d62002-12-30 22:08:05 +0000880};
881
882
883/* implementation */
884
Serhiy Storchakad5db5732016-01-28 21:30:16 +0200885/* Given a buffer, return the unsigned int that is represented by the first
Just van Rossum52e14d62002-12-30 22:08:05 +0000886 4 bytes, encoded as little endian. This partially reimplements
887 marshal.c:r_long() */
Serhiy Storchakad5db5732016-01-28 21:30:16 +0200888static unsigned int
889get_uint32(const unsigned char *buf)
890{
891 unsigned int x;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000892 x = buf[0];
Serhiy Storchakad5db5732016-01-28 21:30:16 +0200893 x |= (unsigned int)buf[1] << 8;
894 x |= (unsigned int)buf[2] << 16;
895 x |= (unsigned int)buf[3] << 24;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000896 return x;
Just van Rossum52e14d62002-12-30 22:08:05 +0000897}
898
Serhiy Storchakad5db5732016-01-28 21:30:16 +0200899/* Given a buffer, return the unsigned int that is represented by the first
900 2 bytes, encoded as little endian. This partially reimplements
901 marshal.c:r_short() */
902static unsigned short
903get_uint16(const unsigned char *buf)
904{
905 unsigned short x;
906 x = buf[0];
907 x |= (unsigned short)buf[1] << 8;
908 return x;
909}
910
911static void
912set_file_error(PyObject *archive, int eof)
913{
914 if (eof) {
915 PyErr_SetString(PyExc_EOFError, "EOF read where not expected");
916 }
917 else {
918 PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, archive);
919 }
920}
921
Gregory P. Smith2bcbc142014-01-07 18:30:07 -0800922/*
Benjamin Peterson34c15402014-02-16 14:17:28 -0500923 read_directory(archive) -> files dict (new reference)
Gregory P. Smith2bcbc142014-01-07 18:30:07 -0800924
Benjamin Peterson34c15402014-02-16 14:17:28 -0500925 Given a path to a Zip archive, build a dict, mapping file names
Just van Rossum52e14d62002-12-30 22:08:05 +0000926 (local to the archive, using SEP as a separator) to toc entries.
927
928 A toc_entry is a tuple:
929
Victor Stinner08654e12010-10-18 12:09:02 +0000930 (__file__, # value to use for __file__, available for all files,
931 # encoded to the filesystem encoding
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000932 compress, # compression kind; 0 for uncompressed
933 data_size, # size of compressed data on disk
934 file_size, # size of decompressed data
935 file_offset, # offset of file header from start of archive
936 time, # mod time of file (in dos format)
937 date, # mod data of file (in dos format)
938 crc, # crc checksum of the data
Victor Stinnerc342fca2010-10-18 11:39:05 +0000939 )
Just van Rossum52e14d62002-12-30 22:08:05 +0000940
941 Directories can be recognized by the trailing SEP in the name,
942 data_size and file_offset are 0.
943*/
944static PyObject *
Benjamin Peterson34c15402014-02-16 14:17:28 -0500945read_directory(PyObject *archive)
Just van Rossum52e14d62002-12-30 22:08:05 +0000946{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000947 PyObject *files = NULL;
Benjamin Peterson34c15402014-02-16 14:17:28 -0500948 FILE *fp;
Serhiy Storchakad5db5732016-01-28 21:30:16 +0200949 unsigned short flags, compress, time, date, name_size;
950 unsigned int crc, data_size, file_size, header_size, header_offset;
951 unsigned long file_offset, header_position;
952 unsigned long arc_offset; /* Absolute offset to start of the zip-archive. */
953 unsigned int count, i;
954 unsigned char buffer[46];
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000955 char name[MAXPATHLEN + 5];
Victor Stinner2460a432010-08-16 17:54:28 +0000956 PyObject *nameobj = NULL;
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100957 PyObject *path;
Victor Stinnerd36c8212010-10-18 12:13:46 +0000958 const char *charset;
Victor Stinner4ee65a92011-01-22 10:30:29 +0000959 int bootstrap;
Serhiy Storchakad5db5732016-01-28 21:30:16 +0200960 const char *errmsg = NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +0000961
Benjamin Peterson34c15402014-02-16 14:17:28 -0500962 fp = _Py_fopen_obj(archive, "rb");
963 if (fp == NULL) {
Victor Stinnerfbd6f9e2015-03-20 10:52:25 +0100964 if (PyErr_ExceptionMatches(PyExc_OSError)) {
Serhiy Storchaka467ab192016-10-21 17:09:17 +0300965 _PyErr_FormatFromCause(ZipImportError,
966 "can't open Zip file: %R", archive);
Victor Stinnerfbd6f9e2015-03-20 10:52:25 +0100967 }
Benjamin Peterson34c15402014-02-16 14:17:28 -0500968 return NULL;
969 }
970
Jesus Cea09bf7a72012-10-03 02:13:05 +0200971 if (fseek(fp, -22, SEEK_END) == -1) {
Serhiy Storchakad5db5732016-01-28 21:30:16 +0200972 goto file_error;
Jesus Cea09bf7a72012-10-03 02:13:05 +0200973 }
Serhiy Storchakad5db5732016-01-28 21:30:16 +0200974 header_position = (unsigned long)ftell(fp);
975 if (header_position == (unsigned long)-1) {
976 goto file_error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000977 }
Serhiy Storchakad5db5732016-01-28 21:30:16 +0200978 assert(header_position <= (unsigned long)LONG_MAX);
979 if (fread(buffer, 1, 22, fp) != 22) {
980 goto file_error;
981 }
982 if (get_uint32(buffer) != 0x06054B50u) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000983 /* Bad: End of Central Dir signature */
Serhiy Storchakad5db5732016-01-28 21:30:16 +0200984 errmsg = "not a Zip file";
985 goto invalid_header;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000986 }
Just van Rossum52e14d62002-12-30 22:08:05 +0000987
Serhiy Storchakad5db5732016-01-28 21:30:16 +0200988 header_size = get_uint32(buffer + 12);
989 header_offset = get_uint32(buffer + 16);
990 if (header_position < header_size) {
991 errmsg = "bad central directory size";
992 goto invalid_header;
993 }
994 if (header_position < header_offset) {
995 errmsg = "bad central directory offset";
996 goto invalid_header;
997 }
998 if (header_position - header_size < header_offset) {
999 errmsg = "bad central directory size or offset";
1000 goto invalid_header;
1001 }
1002 header_position -= header_size;
1003 arc_offset = header_position - header_offset;
Just van Rossum52e14d62002-12-30 22:08:05 +00001004
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001005 files = PyDict_New();
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001006 if (files == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001007 goto error;
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001008 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001009 /* Start of Central Directory */
1010 count = 0;
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001011 if (fseek(fp, (long)header_position, 0) == -1) {
Serhiy Storchaka0e6b7b52013-02-16 17:43:45 +02001012 goto file_error;
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001013 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001014 for (;;) {
1015 PyObject *t;
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001016 size_t n;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001017 int err;
Just van Rossum52e14d62002-12-30 22:08:05 +00001018
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001019 n = fread(buffer, 1, 46, fp);
1020 if (n < 4) {
1021 goto eof_error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001022 }
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001023 /* Start of file header */
1024 if (get_uint32(buffer) != 0x02014B50u) {
1025 break; /* Bad: Central Dir File Header */
1026 }
1027 if (n != 46) {
1028 goto eof_error;
1029 }
1030 flags = get_uint16(buffer + 8);
1031 compress = get_uint16(buffer + 10);
1032 time = get_uint16(buffer + 12);
1033 date = get_uint16(buffer + 14);
1034 crc = get_uint32(buffer + 16);
1035 data_size = get_uint32(buffer + 20);
1036 file_size = get_uint32(buffer + 24);
1037 name_size = get_uint16(buffer + 28);
1038 header_size = (unsigned int)name_size +
1039 get_uint16(buffer + 30) /* extra field */ +
1040 get_uint16(buffer + 32) /* comment */;
1041
1042 file_offset = get_uint32(buffer + 42);
1043 if (file_offset > header_offset) {
1044 errmsg = "bad local header offset";
1045 goto invalid_header;
1046 }
1047 file_offset += arc_offset;
1048
1049 if (name_size > MAXPATHLEN) {
1050 name_size = MAXPATHLEN;
1051 }
1052 if (fread(name, 1, name_size, fp) != name_size) {
1053 goto file_error;
1054 }
1055 name[name_size] = '\0'; /* Add terminating null byte */
Victor Stinner44d9bea2016-12-05 17:55:36 +01001056#if SEP != '/'
1057 for (i = 0; i < name_size; i++) {
1058 if (name[i] == '/') {
1059 name[i] = SEP;
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001060 }
1061 }
Victor Stinner44d9bea2016-12-05 17:55:36 +01001062#endif
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001063 /* Skip the rest of the header.
1064 * On Windows, calling fseek to skip over the fields we don't use is
1065 * slower than reading the data because fseek flushes stdio's
1066 * internal buffers. See issue #8745. */
1067 assert(header_size <= 3*0xFFFFu);
1068 for (i = name_size; i < header_size; i++) {
1069 if (getc(fp) == EOF) {
Serhiy Storchaka0e6b7b52013-02-16 17:43:45 +02001070 goto file_error;
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001071 }
1072 }
Just van Rossum52e14d62002-12-30 22:08:05 +00001073
Victor Stinner4ee65a92011-01-22 10:30:29 +00001074 bootstrap = 0;
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001075 if (flags & 0x0800) {
Victor Stinnerd36c8212010-10-18 12:13:46 +00001076 charset = "utf-8";
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001077 }
Victor Stinner4ee65a92011-01-22 10:30:29 +00001078 else if (!PyThreadState_GET()->interp->codecs_initialized) {
1079 /* During bootstrap, we may need to load the encodings
1080 package from a ZIP file. But the cp437 encoding is implemented
1081 in Python in the encodings package.
1082
1083 Break out of this dependency by assuming that the path to
1084 the encodings module is ASCII-only. */
1085 charset = "ascii";
1086 bootstrap = 1;
1087 }
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001088 else {
Victor Stinnerd36c8212010-10-18 12:13:46 +00001089 charset = "cp437";
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001090 }
Victor Stinnerd36c8212010-10-18 12:13:46 +00001091 nameobj = PyUnicode_Decode(name, name_size, charset, NULL);
Victor Stinner4ee65a92011-01-22 10:30:29 +00001092 if (nameobj == NULL) {
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001093 if (bootstrap) {
Victor Stinner4ee65a92011-01-22 10:30:29 +00001094 PyErr_Format(PyExc_NotImplementedError,
1095 "bootstrap issue: python%i%i.zip contains non-ASCII "
1096 "filenames without the unicode flag",
1097 PY_MAJOR_VERSION, PY_MINOR_VERSION);
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001098 }
Victor Stinner2460a432010-08-16 17:54:28 +00001099 goto error;
Victor Stinner4ee65a92011-01-22 10:30:29 +00001100 }
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001101 if (PyUnicode_READY(nameobj) == -1) {
Stefan Krah000fde92012-08-20 14:14:49 +02001102 goto error;
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001103 }
Martin v. Löwisa72e78b2011-10-31 08:33:37 +01001104 path = PyUnicode_FromFormat("%U%c%U", archive, SEP, nameobj);
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001105 if (path == NULL) {
Victor Stinner2460a432010-08-16 17:54:28 +00001106 goto error;
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001107 }
1108 t = Py_BuildValue("NHIIkHHI", path, compress, data_size,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001109 file_size, file_offset, time, date, crc);
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001110 if (t == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001111 goto error;
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001112 }
Victor Stinner2460a432010-08-16 17:54:28 +00001113 err = PyDict_SetItem(files, nameobj, t);
1114 Py_CLEAR(nameobj);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001115 Py_DECREF(t);
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001116 if (err != 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001117 goto error;
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001118 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001119 count++;
1120 }
Benjamin Peterson34c15402014-02-16 14:17:28 -05001121 fclose(fp);
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001122 if (Py_VerboseFlag) {
1123 PySys_FormatStderr("# zipimport: found %u names in %R\n",
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001124 count, archive);
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001125 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001126 return files;
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001127
1128eof_error:
1129 set_file_error(archive, !ferror(fp));
1130 goto error;
1131
Serhiy Storchaka0e6b7b52013-02-16 17:43:45 +02001132file_error:
Jesus Cea09bf7a72012-10-03 02:13:05 +02001133 PyErr_Format(ZipImportError, "can't read Zip file: %R", archive);
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001134 goto error;
1135
1136invalid_header:
1137 assert(errmsg != NULL);
1138 PyErr_Format(ZipImportError, "%s: %R", errmsg, archive);
1139 goto error;
1140
Just van Rossum52e14d62002-12-30 22:08:05 +00001141error:
Benjamin Peterson34c15402014-02-16 14:17:28 -05001142 fclose(fp);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001143 Py_XDECREF(files);
Victor Stinner2460a432010-08-16 17:54:28 +00001144 Py_XDECREF(nameobj);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001145 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +00001146}
1147
1148/* Return the zlib.decompress function object, or NULL if zlib couldn't
1149 be imported. The function is cached when found, so subsequent calls
Victor Stinner4925cde2011-05-20 00:16:09 +02001150 don't import zlib again. */
Just van Rossum52e14d62002-12-30 22:08:05 +00001151static PyObject *
1152get_decompress_func(void)
1153{
Victor Stinner4925cde2011-05-20 00:16:09 +02001154 static int importing_zlib = 0;
1155 PyObject *zlib;
1156 PyObject *decompress;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02001157 _Py_IDENTIFIER(decompress);
Just van Rossum52e14d62002-12-30 22:08:05 +00001158
Victor Stinner4925cde2011-05-20 00:16:09 +02001159 if (importing_zlib != 0)
Xiang Zhang0710d752017-03-11 13:02:52 +08001160 /* Someone has a zlib.pyc in their Zip file;
Victor Stinner4925cde2011-05-20 00:16:09 +02001161 let's avoid a stack overflow. */
1162 return NULL;
1163 importing_zlib = 1;
1164 zlib = PyImport_ImportModuleNoBlock("zlib");
1165 importing_zlib = 0;
1166 if (zlib != NULL) {
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02001167 decompress = _PyObject_GetAttrId(zlib,
1168 &PyId_decompress);
Victor Stinner4925cde2011-05-20 00:16:09 +02001169 Py_DECREF(zlib);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001170 }
Victor Stinner4925cde2011-05-20 00:16:09 +02001171 else {
1172 PyErr_Clear();
1173 decompress = NULL;
1174 }
1175 if (Py_VerboseFlag)
1176 PySys_WriteStderr("# zipimport: zlib %s\n",
1177 zlib != NULL ? "available": "UNAVAILABLE");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001178 return decompress;
Just van Rossum52e14d62002-12-30 22:08:05 +00001179}
1180
Benjamin Peterson34c15402014-02-16 14:17:28 -05001181/* Given a path to a Zip file and a toc_entry, return the (uncompressed)
Just van Rossum52e14d62002-12-30 22:08:05 +00001182 data as a new reference. */
1183static PyObject *
Benjamin Peterson34c15402014-02-16 14:17:28 -05001184get_data(PyObject *archive, PyObject *toc_entry)
Just van Rossum52e14d62002-12-30 22:08:05 +00001185{
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001186 PyObject *raw_data = NULL, *data, *decompress;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001187 char *buf;
Benjamin Peterson34c15402014-02-16 14:17:28 -05001188 FILE *fp;
Victor Stinner60fe8d92010-08-16 23:48:11 +00001189 PyObject *datapath;
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001190 unsigned short compress, time, date;
1191 unsigned int crc;
1192 Py_ssize_t data_size, file_size, bytes_size;
1193 long file_offset, header_size;
1194 unsigned char buffer[30];
1195 const char *errmsg = NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +00001196
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001197 if (!PyArg_ParseTuple(toc_entry, "OHnnlHHI", &datapath, &compress,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001198 &data_size, &file_size, &file_offset, &time,
1199 &date, &crc)) {
1200 return NULL;
1201 }
Benjamin Petersonb1db7582016-01-21 22:02:46 -08001202 if (data_size < 0) {
1203 PyErr_Format(ZipImportError, "negative data size");
1204 return NULL;
1205 }
Just van Rossum52e14d62002-12-30 22:08:05 +00001206
Benjamin Peterson34c15402014-02-16 14:17:28 -05001207 fp = _Py_fopen_obj(archive, "rb");
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001208 if (!fp) {
Benjamin Peterson34c15402014-02-16 14:17:28 -05001209 return NULL;
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001210 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001211 /* Check to make sure the local file header is correct */
Jesus Cea09bf7a72012-10-03 02:13:05 +02001212 if (fseek(fp, file_offset, 0) == -1) {
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001213 goto file_error;
Jesus Cea09bf7a72012-10-03 02:13:05 +02001214 }
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001215 if (fread(buffer, 1, 30, fp) != 30) {
1216 goto eof_error;
1217 }
1218 if (get_uint32(buffer) != 0x04034B50u) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001219 /* Bad: Local File Header */
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001220 errmsg = "bad local file header";
1221 goto invalid_header;
Jesus Cea09bf7a72012-10-03 02:13:05 +02001222 }
1223
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001224 header_size = (unsigned int)30 +
1225 get_uint16(buffer + 26) /* file name */ +
1226 get_uint16(buffer + 28) /* extra field */;
1227 if (file_offset > LONG_MAX - header_size) {
1228 errmsg = "bad local file header size";
1229 goto invalid_header;
Victor Stinner73660af2013-10-29 01:43:44 +01001230 }
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001231 file_offset += header_size; /* Start of file data */
Just van Rossum52e14d62002-12-30 22:08:05 +00001232
Benjamin Petersonc4032da2016-01-20 22:23:44 -08001233 if (data_size > LONG_MAX - 1) {
1234 fclose(fp);
1235 PyErr_NoMemory();
1236 return NULL;
1237 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001238 bytes_size = compress == 0 ? data_size : data_size + 1;
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001239 if (bytes_size == 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001240 bytes_size++;
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001241 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001242 raw_data = PyBytes_FromStringAndSize((char *)NULL, bytes_size);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001243 if (raw_data == NULL) {
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001244 goto error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001245 }
1246 buf = PyBytes_AsString(raw_data);
Just van Rossum52e14d62002-12-30 22:08:05 +00001247
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001248 if (fseek(fp, file_offset, 0) == -1) {
1249 goto file_error;
Jesus Cea09bf7a72012-10-03 02:13:05 +02001250 }
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001251 if (fread(buf, 1, data_size, fp) != (size_t)data_size) {
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +03001252 PyErr_SetString(PyExc_OSError,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001253 "zipimport: can't read data");
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001254 goto error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001255 }
Just van Rossum52e14d62002-12-30 22:08:05 +00001256
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001257 fclose(fp);
1258 fp = NULL;
1259
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001260 if (compress != 0) {
1261 buf[data_size] = 'Z'; /* saw this in zipfile.py */
1262 data_size++;
1263 }
1264 buf[data_size] = '\0';
Just van Rossum52e14d62002-12-30 22:08:05 +00001265
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001266 if (compress == 0) { /* data is not compressed */
1267 data = PyBytes_FromStringAndSize(buf, data_size);
1268 Py_DECREF(raw_data);
1269 return data;
1270 }
1271
1272 /* Decompress with zlib */
1273 decompress = get_decompress_func();
1274 if (decompress == NULL) {
1275 PyErr_SetString(ZipImportError,
1276 "can't decompress data; "
1277 "zlib not available");
1278 goto error;
1279 }
1280 data = PyObject_CallFunction(decompress, "Oi", raw_data, -15);
Victor Stinner4925cde2011-05-20 00:16:09 +02001281 Py_DECREF(decompress);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001282 Py_DECREF(raw_data);
Oren Milman01c6a882017-09-29 21:34:31 +03001283 if (data != NULL && !PyBytes_Check(data)) {
1284 PyErr_Format(PyExc_TypeError,
1285 "zlib.decompress() must return a bytes object, not "
1286 "%.200s",
1287 Py_TYPE(data)->tp_name);
1288 Py_DECREF(data);
1289 return NULL;
1290 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001291 return data;
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001292
1293eof_error:
1294 set_file_error(archive, !ferror(fp));
1295 goto error;
1296
1297file_error:
1298 PyErr_Format(ZipImportError, "can't read Zip file: %R", archive);
1299 goto error;
1300
1301invalid_header:
1302 assert(errmsg != NULL);
1303 PyErr_Format(ZipImportError, "%s: %R", errmsg, archive);
1304 goto error;
1305
1306error:
1307 if (fp != NULL) {
1308 fclose(fp);
1309 }
1310 Py_XDECREF(raw_data);
1311 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +00001312}
1313
1314/* Lenient date/time comparison function. The precision of the mtime
1315 in the archive is lower than the mtime stored in a .pyc: we
1316 must allow a difference of at most one second. */
1317static int
1318eq_mtime(time_t t1, time_t t2)
1319{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001320 time_t d = t1 - t2;
1321 if (d < 0)
1322 d = -d;
1323 /* dostime only stores even seconds, so be lenient */
1324 return d <= 1;
Just van Rossum52e14d62002-12-30 22:08:05 +00001325}
1326
Xiang Zhang0710d752017-03-11 13:02:52 +08001327/* Given the contents of a .pyc file in a buffer, unmarshal the data
Just van Rossum52e14d62002-12-30 22:08:05 +00001328 and return the code object. Return None if it the magic word doesn't
1329 match (we do this instead of raising an exception as we fall back
1330 to .py if available and we don't want to mask other errors).
1331 Returns a new reference. */
1332static PyObject *
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001333unmarshal_code(PyObject *pathname, PyObject *data, time_t mtime)
Just van Rossum52e14d62002-12-30 22:08:05 +00001334{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001335 PyObject *code;
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001336 unsigned char *buf = (unsigned char *)PyBytes_AsString(data);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001337 Py_ssize_t size = PyBytes_Size(data);
Just van Rossum52e14d62002-12-30 22:08:05 +00001338
Benjamin Peterson42aa93b2017-12-09 10:26:52 -08001339 if (size < 16) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001340 PyErr_SetString(ZipImportError,
1341 "bad pyc data");
1342 return NULL;
1343 }
Just van Rossum52e14d62002-12-30 22:08:05 +00001344
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001345 if (get_uint32(buf) != (unsigned int)PyImport_GetMagicNumber()) {
1346 if (Py_VerboseFlag) {
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001347 PySys_FormatStderr("# %R has bad magic\n",
1348 pathname);
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001349 }
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02001350 Py_RETURN_NONE; /* signal caller to try alternative */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001351 }
Just van Rossum52e14d62002-12-30 22:08:05 +00001352
Benjamin Peterson42aa93b2017-12-09 10:26:52 -08001353 uint32_t flags = get_uint32(buf + 4);
1354 if (flags != 0) {
1355 // Hash-based pyc. We currently refuse to handle checked hash-based
1356 // pycs. We could validate hash-based pycs against the source, but it
1357 // seems likely that most people putting hash-based pycs in a zipfile
1358 // will use unchecked ones.
1359 if (strcmp(_Py_CheckHashBasedPycsMode, "never") &&
1360 (flags != 0x1 || !strcmp(_Py_CheckHashBasedPycsMode, "always")))
1361 Py_RETURN_NONE;
1362 } else if ((mtime != 0 && !eq_mtime(get_uint32(buf + 8), mtime))) {
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001363 if (Py_VerboseFlag) {
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001364 PySys_FormatStderr("# %R has bad mtime\n",
1365 pathname);
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001366 }
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02001367 Py_RETURN_NONE; /* signal caller to try alternative */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001368 }
Just van Rossum52e14d62002-12-30 22:08:05 +00001369
Antoine Pitrou5136ac02012-01-13 18:52:16 +01001370 /* XXX the pyc's size field is ignored; timestamp collisions are probably
1371 unimportant with zip files. */
Benjamin Peterson42aa93b2017-12-09 10:26:52 -08001372 code = PyMarshal_ReadObjectFromString((char *)buf + 16, size - 16);
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001373 if (code == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001374 return NULL;
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001375 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001376 if (!PyCode_Check(code)) {
1377 Py_DECREF(code);
1378 PyErr_Format(PyExc_TypeError,
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001379 "compiled module %R is not a code object",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001380 pathname);
1381 return NULL;
1382 }
1383 return code;
Just van Rossum52e14d62002-12-30 22:08:05 +00001384}
1385
Martin Panter0be894b2016-09-07 12:03:06 +00001386/* Replace any occurrences of "\r\n?" in the input string with "\n".
Just van Rossum52e14d62002-12-30 22:08:05 +00001387 This converts DOS and Mac line endings to Unix line endings.
1388 Also append a trailing "\n" to be compatible with
1389 PyParser_SimpleParseFile(). Returns a new reference. */
1390static PyObject *
1391normalize_line_endings(PyObject *source)
1392{
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001393 char *buf, *q, *p;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001394 PyObject *fixed_source;
1395 int len = 0;
Just van Rossum52e14d62002-12-30 22:08:05 +00001396
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001397 p = PyBytes_AsString(source);
1398 if (p == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001399 return PyBytes_FromStringAndSize("\n\0", 2);
1400 }
Thomas Wouters00ee7ba2006-08-21 19:07:27 +00001401
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001402 /* one char extra for trailing \n and one for terminating \0 */
1403 buf = (char *)PyMem_Malloc(PyBytes_Size(source) + 2);
1404 if (buf == NULL) {
1405 PyErr_SetString(PyExc_MemoryError,
1406 "zipimport: no memory to allocate "
1407 "source buffer");
1408 return NULL;
1409 }
1410 /* replace "\r\n?" by "\n" */
1411 for (q = buf; *p != '\0'; p++) {
1412 if (*p == '\r') {
1413 *q++ = '\n';
1414 if (*(p + 1) == '\n')
1415 p++;
1416 }
1417 else
1418 *q++ = *p;
1419 len++;
1420 }
1421 *q++ = '\n'; /* add trailing \n */
1422 *q = '\0';
1423 fixed_source = PyBytes_FromStringAndSize(buf, len + 2);
1424 PyMem_Free(buf);
1425 return fixed_source;
Just van Rossum52e14d62002-12-30 22:08:05 +00001426}
1427
1428/* Given a string buffer containing Python source code, compile it
Brett Cannon83358c92013-06-20 21:30:32 -04001429 and return a code object as a new reference. */
Just van Rossum52e14d62002-12-30 22:08:05 +00001430static PyObject *
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001431compile_source(PyObject *pathname, PyObject *source)
Just van Rossum52e14d62002-12-30 22:08:05 +00001432{
Steve Dower8dcc48e2016-09-09 17:27:33 -07001433 PyObject *code, *fixed_source;
Just van Rossum52e14d62002-12-30 22:08:05 +00001434
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001435 fixed_source = normalize_line_endings(source);
1436 if (fixed_source == NULL) {
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001437 return NULL;
1438 }
1439
Steve Dower8dcc48e2016-09-09 17:27:33 -07001440 code = Py_CompileStringObject(PyBytes_AsString(fixed_source),
Berker Peksag4aa74c42016-09-14 08:09:48 +03001441 pathname, Py_file_input, NULL, -1);
Steve Dower8dcc48e2016-09-09 17:27:33 -07001442
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001443 Py_DECREF(fixed_source);
1444 return code;
Just van Rossum52e14d62002-12-30 22:08:05 +00001445}
1446
1447/* Convert the date/time values found in the Zip archive to a value
1448 that's compatible with the time stamp stored in .pyc files. */
Neal Norwitz29fd2ba2003-03-23 13:21:03 +00001449static time_t
1450parse_dostime(int dostime, int dosdate)
Just van Rossum52e14d62002-12-30 22:08:05 +00001451{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001452 struct tm stm;
Just van Rossum52e14d62002-12-30 22:08:05 +00001453
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001454 memset((void *) &stm, '\0', sizeof(stm));
Christian Heimes679db4a2008-01-18 09:56:22 +00001455
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001456 stm.tm_sec = (dostime & 0x1f) * 2;
1457 stm.tm_min = (dostime >> 5) & 0x3f;
1458 stm.tm_hour = (dostime >> 11) & 0x1f;
1459 stm.tm_mday = dosdate & 0x1f;
1460 stm.tm_mon = ((dosdate >> 5) & 0x0f) - 1;
1461 stm.tm_year = ((dosdate >> 9) & 0x7f) + 80;
1462 stm.tm_isdst = -1; /* wday/yday is ignored */
Just van Rossum52e14d62002-12-30 22:08:05 +00001463
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001464 return mktime(&stm);
Just van Rossum52e14d62002-12-30 22:08:05 +00001465}
1466
Brett Cannonf299abd2015-04-13 14:21:02 -04001467/* Given a path to a .pyc file in the archive, return the
Ezio Melotti13925002011-03-16 11:05:33 +02001468 modification time of the matching .py file, or 0 if no source
Just van Rossum52e14d62002-12-30 22:08:05 +00001469 is available. */
1470static time_t
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001471get_mtime_of_source(ZipImporter *self, PyObject *path)
Just van Rossum52e14d62002-12-30 22:08:05 +00001472{
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001473 PyObject *toc_entry, *stripped;
1474 time_t mtime;
1475
Xiang Zhang0710d752017-03-11 13:02:52 +08001476 /* strip 'c' from *.pyc */
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001477 if (PyUnicode_READY(path) == -1)
1478 return (time_t)-1;
1479 stripped = PyUnicode_FromKindAndData(PyUnicode_KIND(path),
1480 PyUnicode_DATA(path),
1481 PyUnicode_GET_LENGTH(path) - 1);
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001482 if (stripped == NULL)
1483 return (time_t)-1;
1484
1485 toc_entry = PyDict_GetItem(self->files, stripped);
1486 Py_DECREF(stripped);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001487 if (toc_entry != NULL && PyTuple_Check(toc_entry) &&
1488 PyTuple_Size(toc_entry) == 8) {
1489 /* fetch the time stamp of the .py file for comparison
1490 with an embedded pyc time stamp */
1491 int time, date;
1492 time = PyLong_AsLong(PyTuple_GetItem(toc_entry, 5));
1493 date = PyLong_AsLong(PyTuple_GetItem(toc_entry, 6));
1494 mtime = parse_dostime(time, date);
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001495 } else
1496 mtime = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001497 return mtime;
Just van Rossum52e14d62002-12-30 22:08:05 +00001498}
1499
1500/* Return the code object for the module named by 'fullname' from the
1501 Zip archive as a new reference. */
1502static PyObject *
Benjamin Peterson34c15402014-02-16 14:17:28 -05001503get_code_from_data(ZipImporter *self, int ispackage, int isbytecode,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001504 time_t mtime, PyObject *toc_entry)
Just van Rossum52e14d62002-12-30 22:08:05 +00001505{
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001506 PyObject *data, *modpath, *code;
Just van Rossum52e14d62002-12-30 22:08:05 +00001507
Benjamin Peterson34c15402014-02-16 14:17:28 -05001508 data = get_data(self->archive, toc_entry);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001509 if (data == NULL)
1510 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +00001511
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001512 modpath = PyTuple_GetItem(toc_entry, 0);
Victor Stinner2a94f4c2010-10-18 12:15:34 +00001513 if (isbytecode)
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001514 code = unmarshal_code(modpath, data, mtime);
Victor Stinner2a94f4c2010-10-18 12:15:34 +00001515 else
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001516 code = compile_source(modpath, data);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001517 Py_DECREF(data);
1518 return code;
Just van Rossum52e14d62002-12-30 22:08:05 +00001519}
1520
Ezio Melotti42da6632011-03-15 05:18:48 +02001521/* Get the code object associated with the module specified by
Just van Rossum52e14d62002-12-30 22:08:05 +00001522 'fullname'. */
1523static PyObject *
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001524get_module_code(ZipImporter *self, PyObject *fullname,
Victor Stinner08654e12010-10-18 12:09:02 +00001525 int *p_ispackage, PyObject **p_modpath)
Just van Rossum52e14d62002-12-30 22:08:05 +00001526{
Gregory P. Smith95c7c462011-05-21 05:19:42 -07001527 PyObject *code = NULL, *toc_entry, *subname;
Victor Stinner9a2261a2011-05-26 13:59:41 +02001528 PyObject *path, *fullpath = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001529 struct st_zip_searchorder *zso;
Just van Rossum52e14d62002-12-30 22:08:05 +00001530
Oren Milmandb60a5b2017-10-20 23:42:35 +03001531 if (self->prefix == NULL) {
1532 PyErr_SetString(PyExc_ValueError,
1533 "zipimporter.__init__() wasn't called");
1534 return NULL;
1535 }
1536
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001537 subname = get_subname(fullname);
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001538 if (subname == NULL)
1539 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +00001540
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001541 path = make_filename(self->prefix, subname);
1542 Py_DECREF(subname);
1543 if (path == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001544 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +00001545
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001546 for (zso = zip_searchorder; *zso->suffix; zso++) {
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001547 code = NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +00001548
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001549 fullpath = PyUnicode_FromFormat("%U%s", path, zso->suffix);
1550 if (fullpath == NULL)
1551 goto exit;
1552
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001553 if (Py_VerboseFlag > 1)
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001554 PySys_FormatStderr("# trying %U%c%U\n",
1555 self->archive, (int)SEP, fullpath);
1556 toc_entry = PyDict_GetItem(self->files, fullpath);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001557 if (toc_entry != NULL) {
1558 time_t mtime = 0;
1559 int ispackage = zso->type & IS_PACKAGE;
1560 int isbytecode = zso->type & IS_BYTECODE;
Just van Rossum52e14d62002-12-30 22:08:05 +00001561
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001562 if (isbytecode) {
1563 mtime = get_mtime_of_source(self, fullpath);
1564 if (mtime == (time_t)-1 && PyErr_Occurred()) {
1565 goto exit;
1566 }
1567 }
1568 Py_CLEAR(fullpath);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001569 if (p_ispackage != NULL)
1570 *p_ispackage = ispackage;
Benjamin Peterson34c15402014-02-16 14:17:28 -05001571 code = get_code_from_data(self, ispackage,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001572 isbytecode, mtime,
1573 toc_entry);
1574 if (code == Py_None) {
1575 /* bad magic number or non-matching mtime
1576 in byte code, try next */
1577 Py_DECREF(code);
1578 continue;
1579 }
Victor Stinner08654e12010-10-18 12:09:02 +00001580 if (code != NULL && p_modpath != NULL) {
1581 *p_modpath = PyTuple_GetItem(toc_entry, 0);
1582 Py_INCREF(*p_modpath);
1583 }
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001584 goto exit;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001585 }
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001586 else
1587 Py_CLEAR(fullpath);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001588 }
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001589 PyErr_Format(ZipImportError, "can't find module %R", fullname);
1590exit:
1591 Py_DECREF(path);
1592 Py_XDECREF(fullpath);
1593 return code;
Just van Rossum52e14d62002-12-30 22:08:05 +00001594}
1595
1596
1597/* Module init */
1598
1599PyDoc_STRVAR(zipimport_doc,
1600"zipimport provides support for importing Python modules from Zip archives.\n\
1601\n\
1602This module exports three objects:\n\
1603- zipimporter: a class; its constructor takes a path to a Zip archive.\n\
Fredrik Lundhb84b35f2006-01-15 15:00:40 +00001604- ZipImportError: exception raised by zipimporter objects. It's a\n\
Just van Rossum52e14d62002-12-30 22:08:05 +00001605 subclass of ImportError, so it can be caught as ImportError, too.\n\
1606- _zip_directory_cache: a dict, mapping archive paths to zip directory\n\
1607 info dicts, as used in zipimporter._files.\n\
1608\n\
1609It is usually not needed to use the zipimport module explicitly; it is\n\
1610used by the builtin import mechanism for sys.path items that are paths\n\
1611to Zip archives.");
1612
Martin v. Löwis1a214512008-06-11 05:26:20 +00001613static struct PyModuleDef zipimportmodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001614 PyModuleDef_HEAD_INIT,
1615 "zipimport",
1616 zipimport_doc,
1617 -1,
1618 NULL,
1619 NULL,
1620 NULL,
1621 NULL,
1622 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +00001623};
1624
Just van Rossum52e14d62002-12-30 22:08:05 +00001625PyMODINIT_FUNC
Martin v. Löwis1a214512008-06-11 05:26:20 +00001626PyInit_zipimport(void)
Just van Rossum52e14d62002-12-30 22:08:05 +00001627{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001628 PyObject *mod;
Just van Rossum52e14d62002-12-30 22:08:05 +00001629
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001630 if (PyType_Ready(&ZipImporter_Type) < 0)
1631 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +00001632
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001633 /* Correct directory separator */
1634 zip_searchorder[0].suffix[0] = SEP;
1635 zip_searchorder[1].suffix[0] = SEP;
Just van Rossum52e14d62002-12-30 22:08:05 +00001636
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001637 mod = PyModule_Create(&zipimportmodule);
1638 if (mod == NULL)
1639 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +00001640
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001641 ZipImportError = PyErr_NewException("zipimport.ZipImportError",
1642 PyExc_ImportError, NULL);
1643 if (ZipImportError == NULL)
1644 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +00001645
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001646 Py_INCREF(ZipImportError);
1647 if (PyModule_AddObject(mod, "ZipImportError",
1648 ZipImportError) < 0)
1649 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +00001650
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001651 Py_INCREF(&ZipImporter_Type);
1652 if (PyModule_AddObject(mod, "zipimporter",
1653 (PyObject *)&ZipImporter_Type) < 0)
1654 return NULL;
Just van Rossumf8b6de12002-12-31 09:51:59 +00001655
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001656 zip_directory_cache = PyDict_New();
1657 if (zip_directory_cache == NULL)
1658 return NULL;
1659 Py_INCREF(zip_directory_cache);
1660 if (PyModule_AddObject(mod, "_zip_directory_cache",
1661 zip_directory_cache) < 0)
1662 return NULL;
1663 return mod;
Just van Rossum52e14d62002-12-30 22:08:05 +00001664}