blob: 4df4ba9f8b822940b67082708ae3a76f41caeeff [file] [log] [blame]
Just van Rossum52e14d62002-12-30 22:08:05 +00001#include "Python.h"
Eric Snow2ebc5ce2017-09-07 23:51:28 -06002#include "internal/pystate.h"
Just van Rossum52e14d62002-12-30 22:08:05 +00003#include "structmember.h"
4#include "osdefs.h"
5#include "marshal.h"
Just van Rossum52e14d62002-12-30 22:08:05 +00006#include <time.h>
7
8
9#define IS_SOURCE 0x0
10#define IS_BYTECODE 0x1
11#define IS_PACKAGE 0x2
12
13struct st_zip_searchorder {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000014 char suffix[14];
15 int type;
Just van Rossum52e14d62002-12-30 22:08:05 +000016};
17
Victor Stinner651f9f72013-11-12 21:44:18 +010018#ifdef ALTSEP
19_Py_IDENTIFIER(replace);
20#endif
21
Just van Rossum52e14d62002-12-30 22:08:05 +000022/* zip_searchorder defines how we search for a module in the Zip
23 archive: we first search for a package __init__, then for
Brett Cannonf299abd2015-04-13 14:21:02 -040024 non-package .pyc, and .py entries. The .pyc entries
Just van Rossum52e14d62002-12-30 22:08:05 +000025 are swapped by initzipimport() if we run in optimized mode. Also,
26 '/' is replaced by SEP there. */
Neal Norwitz29fd2ba2003-03-23 13:21:03 +000027static struct st_zip_searchorder zip_searchorder[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000028 {"/__init__.pyc", IS_PACKAGE | IS_BYTECODE},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000029 {"/__init__.py", IS_PACKAGE | IS_SOURCE},
30 {".pyc", IS_BYTECODE},
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000031 {".py", IS_SOURCE},
32 {"", 0}
Just van Rossum52e14d62002-12-30 22:08:05 +000033};
34
35/* zipimporter object definition and support */
36
37typedef struct _zipimporter ZipImporter;
38
39struct _zipimporter {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000040 PyObject_HEAD
Victor Stinner9e40fad2010-10-18 22:34:46 +000041 PyObject *archive; /* pathname of the Zip archive,
42 decoded from the filesystem encoding */
Victor Stinner72f767e2010-10-18 11:44:21 +000043 PyObject *prefix; /* file prefix: "a/sub/directory/",
44 encoded to the filesystem encoding */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +000045 PyObject *files; /* dict with file info {path: toc_entry} */
Just van Rossum52e14d62002-12-30 22:08:05 +000046};
47
Just van Rossum52e14d62002-12-30 22:08:05 +000048static PyObject *ZipImportError;
Victor Stinnerc342fca2010-10-18 11:39:05 +000049/* read_directory() cache */
Just van Rossum52e14d62002-12-30 22:08:05 +000050static PyObject *zip_directory_cache = NULL;
51
52/* forward decls */
Benjamin Peterson34c15402014-02-16 14:17:28 -050053static PyObject *read_directory(PyObject *archive);
54static PyObject *get_data(PyObject *archive, PyObject *toc_entry);
Victor Stinnerf6b563a2011-03-14 20:46:50 -040055static PyObject *get_module_code(ZipImporter *self, PyObject *fullname,
Victor Stinner08654e12010-10-18 12:09:02 +000056 int *p_ispackage, PyObject **p_modpath);
Just van Rossum52e14d62002-12-30 22:08:05 +000057
Yaron de Leeuw02f3b7d2017-08-18 14:41:13 -040058static PyTypeObject ZipImporter_Type;
Just van Rossum52e14d62002-12-30 22:08:05 +000059
60#define ZipImporter_Check(op) PyObject_TypeCheck(op, &ZipImporter_Type)
61
Yaron de Leeuw02f3b7d2017-08-18 14:41:13 -040062/*[clinic input]
63module zipimport
64class zipimport.zipimporter "ZipImporter *" "&ZipImporter_Type"
65[clinic start generated code]*/
66/*[clinic end generated code: output=da39a3ee5e6b4b0d input=9db8b61557d911e7]*/
67#include "clinic/zipimport.c.h"
68
Just van Rossum52e14d62002-12-30 22:08:05 +000069
70/* zipimporter.__init__
71 Split the "subdirectory" from the Zip archive path, lookup a matching
72 entry in sys.path_importer_cache, fetch the file directory from there
73 if found, or else read it from the archive. */
Yaron de Leeuw02f3b7d2017-08-18 14:41:13 -040074
75/*[clinic input]
76zipimport.zipimporter.__init__
77
78 archivepath as path: object(converter="PyUnicode_FSDecoder")
79 A path-like object to a zipfile, or to a specific path inside
80 a zipfile.
81 /
82
83Create a new zipimporter instance.
84
85'archivepath' must be a path-like object to a zipfile, or to a specific path
86inside a zipfile. For example, it can be '/tmp/myimport.zip', or
87'/tmp/myimport.zip/mydirectory', if mydirectory is a valid directory inside
88the archive.
89
90'ZipImportError' is raised if 'archivepath' doesn't point to a valid Zip
91archive.
92
93The 'archive' attribute of the zipimporter object contains the name of the
94zipfile targeted.
95
96[clinic start generated code]*/
97
Just van Rossum52e14d62002-12-30 22:08:05 +000098static int
Yaron de Leeuw02f3b7d2017-08-18 14:41:13 -040099zipimport_zipimporter___init___impl(ZipImporter *self, PyObject *path)
100/*[clinic end generated code: output=141558fefdb46dc8 input=92b9ebeed1f6a704]*/
Just van Rossum52e14d62002-12-30 22:08:05 +0000101{
Yaron de Leeuw02f3b7d2017-08-18 14:41:13 -0400102 PyObject *files, *tmp;
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100103 PyObject *filename = NULL;
104 Py_ssize_t len, flen;
Just van Rossum52e14d62002-12-30 22:08:05 +0000105
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100106 if (PyUnicode_READY(path) == -1)
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200107 return -1;
108
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100109 len = PyUnicode_GET_LENGTH(path);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000110 if (len == 0) {
111 PyErr_SetString(ZipImportError, "archive path is empty");
Victor Stinner2b8dab72010-08-14 14:54:10 +0000112 goto error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000113 }
Just van Rossum52e14d62002-12-30 22:08:05 +0000114
115#ifdef ALTSEP
Martin v. Löwiscfa61292011-10-31 09:01:22 +0100116 tmp = _PyObject_CallMethodId(path, &PyId_replace, "CC", ALTSEP, SEP);
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100117 if (!tmp)
118 goto error;
119 Py_DECREF(path);
120 path = tmp;
Just van Rossum52e14d62002-12-30 22:08:05 +0000121#endif
122
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100123 filename = path;
124 Py_INCREF(filename);
125 flen = len;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000126 for (;;) {
127 struct stat statbuf;
128 int rv;
Just van Rossum52e14d62002-12-30 22:08:05 +0000129
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100130 rv = _Py_stat(filename, &statbuf);
Victor Stinnerbd0850b2011-12-18 20:47:30 +0100131 if (rv == -2)
132 goto error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000133 if (rv == 0) {
134 /* it exists */
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100135 if (!S_ISREG(statbuf.st_mode))
136 /* it's a not file */
137 Py_CLEAR(filename);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000138 break;
139 }
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100140 Py_CLEAR(filename);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000141 /* back up one path element */
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100142 flen = PyUnicode_FindChar(path, SEP, 0, flen, -1);
143 if (flen == -1)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000144 break;
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100145 filename = PyUnicode_Substring(path, 0, flen);
Victor Stinneraf8b7e82013-10-29 01:46:24 +0100146 if (filename == NULL)
147 goto error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000148 }
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100149 if (filename == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000150 PyErr_SetString(ZipImportError, "not a Zip file");
Victor Stinner2b8dab72010-08-14 14:54:10 +0000151 goto error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000152 }
Just van Rossum52e14d62002-12-30 22:08:05 +0000153
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100154 if (PyUnicode_READY(filename) < 0)
155 goto error;
156
157 files = PyDict_GetItem(zip_directory_cache, filename);
Victor Stinner2b8dab72010-08-14 14:54:10 +0000158 if (files == NULL) {
Benjamin Peterson34c15402014-02-16 14:17:28 -0500159 files = read_directory(filename);
160 if (files == NULL)
Victor Stinner2b8dab72010-08-14 14:54:10 +0000161 goto error;
Benjamin Peterson34c15402014-02-16 14:17:28 -0500162 if (PyDict_SetItem(zip_directory_cache, filename, files) != 0)
Victor Stinner2b8dab72010-08-14 14:54:10 +0000163 goto error;
164 }
165 else
166 Py_INCREF(files);
Oren Milmanc0cabc22017-10-09 18:06:19 +0300167 Py_XSETREF(self->files, files);
Victor Stinner2b8dab72010-08-14 14:54:10 +0000168
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100169 /* Transfer reference */
Oren Milmanc0cabc22017-10-09 18:06:19 +0300170 Py_XSETREF(self->archive, filename);
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100171 filename = NULL;
Victor Stinner2b8dab72010-08-14 14:54:10 +0000172
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100173 /* Check if there is a prefix directory following the filename. */
174 if (flen != len) {
175 tmp = PyUnicode_Substring(path, flen+1,
176 PyUnicode_GET_LENGTH(path));
177 if (tmp == NULL)
178 goto error;
Oren Milmanc0cabc22017-10-09 18:06:19 +0300179 Py_XSETREF(self->prefix, tmp);
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100180 if (PyUnicode_READ_CHAR(path, len-1) != SEP) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000181 /* add trailing SEP */
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100182 tmp = PyUnicode_FromFormat("%U%c", self->prefix, SEP);
183 if (tmp == NULL)
184 goto error;
Serhiy Storchaka57a01d32016-04-10 18:05:40 +0300185 Py_SETREF(self->prefix, tmp);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000186 }
187 }
Oren Milmanc0cabc22017-10-09 18:06:19 +0300188 else {
189 Py_XSETREF(self->prefix, PyUnicode_New(0, 0));
190 }
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100191 Py_DECREF(path);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000192 return 0;
Victor Stinner2b8dab72010-08-14 14:54:10 +0000193
194error:
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100195 Py_DECREF(path);
196 Py_XDECREF(filename);
Victor Stinner2b8dab72010-08-14 14:54:10 +0000197 return -1;
Just van Rossum52e14d62002-12-30 22:08:05 +0000198}
199
200/* GC support. */
201static int
202zipimporter_traverse(PyObject *obj, visitproc visit, void *arg)
203{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000204 ZipImporter *self = (ZipImporter *)obj;
205 Py_VISIT(self->files);
206 return 0;
Just van Rossum52e14d62002-12-30 22:08:05 +0000207}
208
209static void
210zipimporter_dealloc(ZipImporter *self)
211{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000212 PyObject_GC_UnTrack(self);
213 Py_XDECREF(self->archive);
214 Py_XDECREF(self->prefix);
215 Py_XDECREF(self->files);
216 Py_TYPE(self)->tp_free((PyObject *)self);
Just van Rossum52e14d62002-12-30 22:08:05 +0000217}
218
219static PyObject *
220zipimporter_repr(ZipImporter *self)
221{
Victor Stinner028dd972010-08-17 00:04:48 +0000222 if (self->archive == NULL)
223 return PyUnicode_FromString("<zipimporter object \"???\">");
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200224 else if (self->prefix != NULL && PyUnicode_GET_LENGTH(self->prefix) != 0)
Victor Stinner07298a12010-10-18 22:45:54 +0000225 return PyUnicode_FromFormat("<zipimporter object \"%U%c%U\">",
Victor Stinner028dd972010-08-17 00:04:48 +0000226 self->archive, SEP, self->prefix);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000227 else
Victor Stinner07298a12010-10-18 22:45:54 +0000228 return PyUnicode_FromFormat("<zipimporter object \"%U\">",
Victor Stinner028dd972010-08-17 00:04:48 +0000229 self->archive);
Just van Rossum52e14d62002-12-30 22:08:05 +0000230}
231
232/* return fullname.split(".")[-1] */
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400233static PyObject *
234get_subname(PyObject *fullname)
Just van Rossum52e14d62002-12-30 22:08:05 +0000235{
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100236 Py_ssize_t len, dot;
237 if (PyUnicode_READY(fullname) < 0)
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200238 return NULL;
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100239 len = PyUnicode_GET_LENGTH(fullname);
240 dot = PyUnicode_FindChar(fullname, '.', 0, len, -1);
241 if (dot == -1) {
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400242 Py_INCREF(fullname);
243 return fullname;
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100244 } else
245 return PyUnicode_Substring(fullname, dot+1, len);
Just van Rossum52e14d62002-12-30 22:08:05 +0000246}
247
248/* Given a (sub)modulename, write the potential file path in the
249 archive (without extension) to the path buffer. Return the
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400250 length of the resulting string.
251
252 return self.prefix + name.replace('.', os.sep) */
253static PyObject*
254make_filename(PyObject *prefix, PyObject *name)
Just van Rossum52e14d62002-12-30 22:08:05 +0000255{
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400256 PyObject *pathobj;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200257 Py_UCS4 *p, *buf;
258 Py_ssize_t len;
Just van Rossum52e14d62002-12-30 22:08:05 +0000259
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200260 len = PyUnicode_GET_LENGTH(prefix) + PyUnicode_GET_LENGTH(name) + 1;
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +0200261 p = buf = PyMem_New(Py_UCS4, len);
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200262 if (buf == NULL) {
263 PyErr_NoMemory();
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400264 return NULL;
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200265 }
Just van Rossum52e14d62002-12-30 22:08:05 +0000266
Christian Heimes1b5c76a2012-09-10 02:00:34 +0200267 if (!PyUnicode_AsUCS4(prefix, p, len, 0)) {
268 PyMem_Free(buf);
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200269 return NULL;
Christian Heimes1b5c76a2012-09-10 02:00:34 +0200270 }
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200271 p += PyUnicode_GET_LENGTH(prefix);
272 len -= PyUnicode_GET_LENGTH(prefix);
Christian Heimes1b5c76a2012-09-10 02:00:34 +0200273 if (!PyUnicode_AsUCS4(name, p, len, 1)) {
274 PyMem_Free(buf);
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200275 return NULL;
Christian Heimes1b5c76a2012-09-10 02:00:34 +0200276 }
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400277 for (; *p; p++) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000278 if (*p == '.')
279 *p = SEP;
280 }
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200281 pathobj = PyUnicode_FromKindAndData(PyUnicode_4BYTE_KIND,
282 buf, p-buf);
283 PyMem_Free(buf);
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400284 return pathobj;
Just van Rossum52e14d62002-12-30 22:08:05 +0000285}
286
Raymond Hettinger2c45c9a2004-11-10 13:08:35 +0000287enum zi_module_info {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000288 MI_ERROR,
289 MI_NOT_FOUND,
290 MI_MODULE,
291 MI_PACKAGE
Just van Rossum52e14d62002-12-30 22:08:05 +0000292};
293
Eric V. Smith984b11f2012-05-24 20:21:04 -0400294/* Does this path represent a directory?
295 on error, return < 0
296 if not a dir, return 0
297 if a dir, return 1
298*/
299static int
300check_is_directory(ZipImporter *self, PyObject* prefix, PyObject *path)
301{
302 PyObject *dirpath;
Benjamin Peterson18eac4a2012-05-25 00:24:42 -0700303 int res;
Eric V. Smith984b11f2012-05-24 20:21:04 -0400304
305 /* See if this is a "directory". If so, it's eligible to be part
306 of a namespace package. We test by seeing if the name, with an
307 appended path separator, exists. */
308 dirpath = PyUnicode_FromFormat("%U%U%c", prefix, path, SEP);
309 if (dirpath == NULL)
310 return -1;
311 /* If dirpath is present in self->files, we have a directory. */
Benjamin Peterson18eac4a2012-05-25 00:24:42 -0700312 res = PyDict_Contains(self->files, dirpath);
Eric V. Smith984b11f2012-05-24 20:21:04 -0400313 Py_DECREF(dirpath);
Benjamin Peterson18eac4a2012-05-25 00:24:42 -0700314 return res;
Eric V. Smith984b11f2012-05-24 20:21:04 -0400315}
316
Just van Rossum52e14d62002-12-30 22:08:05 +0000317/* Return some information about a module. */
Raymond Hettinger2c45c9a2004-11-10 13:08:35 +0000318static enum zi_module_info
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400319get_module_info(ZipImporter *self, PyObject *fullname)
Just van Rossum52e14d62002-12-30 22:08:05 +0000320{
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400321 PyObject *subname;
322 PyObject *path, *fullpath, *item;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000323 struct st_zip_searchorder *zso;
Just van Rossum52e14d62002-12-30 22:08:05 +0000324
Oren Milmandb60a5b2017-10-20 23:42:35 +0300325 if (self->prefix == NULL) {
326 PyErr_SetString(PyExc_ValueError,
327 "zipimporter.__init__() wasn't called");
328 return MI_ERROR;
329 }
330
Victor Stinner965a8a12010-10-18 21:44:33 +0000331 subname = get_subname(fullname);
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400332 if (subname == NULL)
333 return MI_ERROR;
Just van Rossum52e14d62002-12-30 22:08:05 +0000334
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400335 path = make_filename(self->prefix, subname);
336 Py_DECREF(subname);
337 if (path == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000338 return MI_ERROR;
Just van Rossum52e14d62002-12-30 22:08:05 +0000339
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000340 for (zso = zip_searchorder; *zso->suffix; zso++) {
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400341 fullpath = PyUnicode_FromFormat("%U%s", path, zso->suffix);
342 if (fullpath == NULL) {
343 Py_DECREF(path);
344 return MI_ERROR;
345 }
346 item = PyDict_GetItem(self->files, fullpath);
347 Py_DECREF(fullpath);
348 if (item != NULL) {
349 Py_DECREF(path);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000350 if (zso->type & IS_PACKAGE)
351 return MI_PACKAGE;
352 else
353 return MI_MODULE;
354 }
355 }
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400356 Py_DECREF(path);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000357 return MI_NOT_FOUND;
Just van Rossum52e14d62002-12-30 22:08:05 +0000358}
359
Benjamin Peterson5ed7bd72012-05-24 22:54:15 -0700360typedef enum {
Brett Cannon56aae8f2016-01-15 11:22:19 -0800361 FL_ERROR = -1, /* error */
362 FL_NOT_FOUND, /* no loader or namespace portions found */
363 FL_MODULE_FOUND, /* module/package found */
364 FL_NS_FOUND /* namespace portion found: */
365 /* *namespace_portion will point to the name */
Benjamin Peterson5ed7bd72012-05-24 22:54:15 -0700366} find_loader_result;
367
Brett Cannon56aae8f2016-01-15 11:22:19 -0800368/* The guts of "find_loader" and "find_module".
Eric V. Smith984b11f2012-05-24 20:21:04 -0400369*/
Benjamin Peterson5ed7bd72012-05-24 22:54:15 -0700370static find_loader_result
Eric V. Smith984b11f2012-05-24 20:21:04 -0400371find_loader(ZipImporter *self, PyObject *fullname, PyObject **namespace_portion)
372{
373 enum zi_module_info mi;
374
375 *namespace_portion = NULL;
376
377 mi = get_module_info(self, fullname);
378 if (mi == MI_ERROR)
Benjamin Peterson46c214d2012-05-25 10:22:29 -0700379 return FL_ERROR;
Eric V. Smith984b11f2012-05-24 20:21:04 -0400380 if (mi == MI_NOT_FOUND) {
381 /* Not a module or regular package. See if this is a directory, and
382 therefore possibly a portion of a namespace package. */
Brett Cannon56aae8f2016-01-15 11:22:19 -0800383 find_loader_result result = FL_NOT_FOUND;
384 PyObject *subname;
385 int is_dir;
386
387 /* We're only interested in the last path component of fullname;
388 earlier components are recorded in self->prefix. */
389 subname = get_subname(fullname);
390 if (subname == NULL) {
391 return FL_ERROR;
392 }
393
394 is_dir = check_is_directory(self, self->prefix, subname);
Eric V. Smith984b11f2012-05-24 20:21:04 -0400395 if (is_dir < 0)
Brett Cannon56aae8f2016-01-15 11:22:19 -0800396 result = FL_ERROR;
397 else if (is_dir) {
Eric V. Smith984b11f2012-05-24 20:21:04 -0400398 /* This is possibly a portion of a namespace
399 package. Return the string representing its path,
400 without a trailing separator. */
401 *namespace_portion = PyUnicode_FromFormat("%U%c%U%U",
402 self->archive, SEP,
Brett Cannon56aae8f2016-01-15 11:22:19 -0800403 self->prefix, subname);
Eric V. Smith984b11f2012-05-24 20:21:04 -0400404 if (*namespace_portion == NULL)
Brett Cannon56aae8f2016-01-15 11:22:19 -0800405 result = FL_ERROR;
406 else
407 result = FL_NS_FOUND;
Eric V. Smith984b11f2012-05-24 20:21:04 -0400408 }
Brett Cannon56aae8f2016-01-15 11:22:19 -0800409 Py_DECREF(subname);
410 return result;
Eric V. Smith984b11f2012-05-24 20:21:04 -0400411 }
412 /* This is a module or package. */
Benjamin Peterson46c214d2012-05-25 10:22:29 -0700413 return FL_MODULE_FOUND;
Eric V. Smith984b11f2012-05-24 20:21:04 -0400414}
415
Yaron de Leeuw02f3b7d2017-08-18 14:41:13 -0400416/*[clinic input]
417zipimport.zipimporter.find_module
Eric V. Smith984b11f2012-05-24 20:21:04 -0400418
Yaron de Leeuw02f3b7d2017-08-18 14:41:13 -0400419 fullname: unicode
420 path: object = None
421 /
422
423Search for a module specified by 'fullname'.
424
425'fullname' must be the fully qualified (dotted) module name. It returns the
426zipimporter instance itself if the module was found, or None if it wasn't.
427The optional 'path' argument is ignored -- it's there for compatibility
428with the importer protocol.
429
430[clinic start generated code]*/
431
Just van Rossum52e14d62002-12-30 22:08:05 +0000432static PyObject *
Yaron de Leeuw02f3b7d2017-08-18 14:41:13 -0400433zipimport_zipimporter_find_module_impl(ZipImporter *self, PyObject *fullname,
434 PyObject *path)
435/*[clinic end generated code: output=506087f609466dc7 input=e3528520e075063f]*/
Just van Rossum52e14d62002-12-30 22:08:05 +0000436{
Benjamin Peterson5ed7bd72012-05-24 22:54:15 -0700437 PyObject *namespace_portion = NULL;
438 PyObject *result = NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +0000439
Eric V. Smith984b11f2012-05-24 20:21:04 -0400440 switch (find_loader(self, fullname, &namespace_portion)) {
Benjamin Peterson46c214d2012-05-25 10:22:29 -0700441 case FL_ERROR:
Benjamin Petersona6a7a1a2012-05-25 00:22:04 -0700442 return NULL;
Benjamin Peterson46c214d2012-05-25 10:22:29 -0700443 case FL_NS_FOUND:
Benjamin Peterson5ed7bd72012-05-24 22:54:15 -0700444 /* A namespace portion is not allowed via find_module, so return None. */
Eric V. Smith984b11f2012-05-24 20:21:04 -0400445 Py_DECREF(namespace_portion);
Benjamin Peterson5ed7bd72012-05-24 22:54:15 -0700446 /* FALL THROUGH */
Benjamin Peterson46c214d2012-05-25 10:22:29 -0700447 case FL_NOT_FOUND:
Benjamin Peterson5ed7bd72012-05-24 22:54:15 -0700448 result = Py_None;
449 break;
Benjamin Peterson46c214d2012-05-25 10:22:29 -0700450 case FL_MODULE_FOUND:
Benjamin Peterson5ed7bd72012-05-24 22:54:15 -0700451 result = (PyObject *)self;
452 break;
Brett Cannon56aae8f2016-01-15 11:22:19 -0800453 default:
454 PyErr_BadInternalCall();
455 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000456 }
Benjamin Petersona6a7a1a2012-05-25 00:22:04 -0700457 Py_INCREF(result);
Benjamin Peterson2d12e142012-05-25 00:19:40 -0700458 return result;
Eric V. Smith984b11f2012-05-24 20:21:04 -0400459}
460
461
Yaron de Leeuw02f3b7d2017-08-18 14:41:13 -0400462/*[clinic input]
463zipimport.zipimporter.find_loader
464
465 fullname: unicode
466 path: object = None
467 /
468
469Search for a module specified by 'fullname'.
470
471'fullname' must be the fully qualified (dotted) module name. It returns the
472zipimporter instance itself if the module was found, a string containing the
473full path name if it's possibly a portion of a namespace package,
474or None otherwise. The optional 'path' argument is ignored -- it's
475there for compatibility with the importer protocol.
476
477[clinic start generated code]*/
478
Eric V. Smith984b11f2012-05-24 20:21:04 -0400479static PyObject *
Yaron de Leeuw02f3b7d2017-08-18 14:41:13 -0400480zipimport_zipimporter_find_loader_impl(ZipImporter *self, PyObject *fullname,
481 PyObject *path)
482/*[clinic end generated code: output=601599a43bc0f49a input=dc73f275b0d5be23]*/
Eric V. Smith984b11f2012-05-24 20:21:04 -0400483{
Eric V. Smith984b11f2012-05-24 20:21:04 -0400484 PyObject *result = NULL;
485 PyObject *namespace_portion = NULL;
486
Eric V. Smith984b11f2012-05-24 20:21:04 -0400487 switch (find_loader(self, fullname, &namespace_portion)) {
Benjamin Peterson46c214d2012-05-25 10:22:29 -0700488 case FL_ERROR:
Benjamin Peterson5ed7bd72012-05-24 22:54:15 -0700489 return NULL;
Benjamin Peterson46c214d2012-05-25 10:22:29 -0700490 case FL_NOT_FOUND: /* Not found, return (None, []) */
Benjamin Peterson5ed7bd72012-05-24 22:54:15 -0700491 result = Py_BuildValue("O[]", Py_None);
492 break;
Benjamin Peterson46c214d2012-05-25 10:22:29 -0700493 case FL_MODULE_FOUND: /* Return (self, []) */
Benjamin Peterson5ed7bd72012-05-24 22:54:15 -0700494 result = Py_BuildValue("O[]", self);
495 break;
Benjamin Peterson46c214d2012-05-25 10:22:29 -0700496 case FL_NS_FOUND: /* Return (None, [namespace_portion]) */
Benjamin Peterson5ed7bd72012-05-24 22:54:15 -0700497 result = Py_BuildValue("O[O]", Py_None, namespace_portion);
Benjamin Peterson209e04c2012-05-24 22:35:39 -0700498 Py_DECREF(namespace_portion);
Eric V. Smith984b11f2012-05-24 20:21:04 -0400499 return result;
Brett Cannon56aae8f2016-01-15 11:22:19 -0800500 default:
501 PyErr_BadInternalCall();
502 return NULL;
Eric V. Smith984b11f2012-05-24 20:21:04 -0400503 }
Benjamin Peterson5ed7bd72012-05-24 22:54:15 -0700504 return result;
Just van Rossum52e14d62002-12-30 22:08:05 +0000505}
506
Yaron de Leeuw02f3b7d2017-08-18 14:41:13 -0400507/*[clinic input]
508zipimport.zipimporter.load_module
509
510 fullname: unicode
511 /
512
513Load the module specified by 'fullname'.
514
515'fullname' must be the fully qualified (dotted) module name. It returns the
516imported module, or raises ZipImportError if it wasn't found.
517
518[clinic start generated code]*/
519
Just van Rossum52e14d62002-12-30 22:08:05 +0000520static PyObject *
Yaron de Leeuw02f3b7d2017-08-18 14:41:13 -0400521zipimport_zipimporter_load_module_impl(ZipImporter *self, PyObject *fullname)
522/*[clinic end generated code: output=7303cebf88d47953 input=c236e2e8621f04ef]*/
Just van Rossum52e14d62002-12-30 22:08:05 +0000523{
Victor Stinner26fabe12010-10-18 12:03:25 +0000524 PyObject *code = NULL, *mod, *dict;
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400525 PyObject *modpath = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000526 int ispackage;
Just van Rossum52e14d62002-12-30 22:08:05 +0000527
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200528 if (PyUnicode_READY(fullname) == -1)
529 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +0000530
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000531 code = get_module_code(self, fullname, &ispackage, &modpath);
532 if (code == NULL)
Victor Stinner26fabe12010-10-18 12:03:25 +0000533 goto error;
Just van Rossum52e14d62002-12-30 22:08:05 +0000534
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400535 mod = PyImport_AddModuleObject(fullname);
Victor Stinner26fabe12010-10-18 12:03:25 +0000536 if (mod == NULL)
537 goto error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000538 dict = PyModule_GetDict(mod);
Just van Rossum52e14d62002-12-30 22:08:05 +0000539
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000540 /* mod.__loader__ = self */
541 if (PyDict_SetItemString(dict, "__loader__", (PyObject *)self) != 0)
542 goto error;
Just van Rossum52e14d62002-12-30 22:08:05 +0000543
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000544 if (ispackage) {
545 /* add __path__ to the module *before* the code gets
546 executed */
Victor Stinneraf8b7e82013-10-29 01:46:24 +0100547 PyObject *pkgpath, *fullpath, *subname;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000548 int err;
Just van Rossum52e14d62002-12-30 22:08:05 +0000549
Victor Stinneraf8b7e82013-10-29 01:46:24 +0100550 subname = get_subname(fullname);
551 if (subname == NULL)
552 goto error;
553
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400554 fullpath = PyUnicode_FromFormat("%U%c%U%U",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000555 self->archive, SEP,
556 self->prefix, subname);
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400557 Py_DECREF(subname);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000558 if (fullpath == NULL)
559 goto error;
Just van Rossum52e14d62002-12-30 22:08:05 +0000560
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400561 pkgpath = Py_BuildValue("[N]", fullpath);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000562 if (pkgpath == NULL)
563 goto error;
564 err = PyDict_SetItemString(dict, "__path__", pkgpath);
565 Py_DECREF(pkgpath);
566 if (err != 0)
567 goto error;
568 }
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400569 mod = PyImport_ExecCodeModuleObject(fullname, code, modpath, NULL);
Victor Stinner26fabe12010-10-18 12:03:25 +0000570 Py_CLEAR(code);
571 if (mod == NULL)
572 goto error;
573
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000574 if (Py_VerboseFlag)
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400575 PySys_FormatStderr("import %U # loaded from Zip %U\n",
Victor Stinner08654e12010-10-18 12:09:02 +0000576 fullname, modpath);
577 Py_DECREF(modpath);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000578 return mod;
Just van Rossum52e14d62002-12-30 22:08:05 +0000579error:
Victor Stinner26fabe12010-10-18 12:03:25 +0000580 Py_XDECREF(code);
Victor Stinner08654e12010-10-18 12:09:02 +0000581 Py_XDECREF(modpath);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000582 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +0000583}
584
Yaron de Leeuw02f3b7d2017-08-18 14:41:13 -0400585/*[clinic input]
586zipimport.zipimporter.get_filename
Nick Coghlanf088e5e2008-12-14 11:50:48 +0000587
Yaron de Leeuw02f3b7d2017-08-18 14:41:13 -0400588 fullname: unicode
589 /
590
591Return the filename for the specified module.
592[clinic start generated code]*/
593
594static PyObject *
595zipimport_zipimporter_get_filename_impl(ZipImporter *self,
596 PyObject *fullname)
597/*[clinic end generated code: output=c5b92b58bea86506 input=28d2eb57e4f25c8a]*/
598{
599 PyObject *code, *modpath;
600 int ispackage;
Nick Coghlanf088e5e2008-12-14 11:50:48 +0000601
602 /* Deciding the filename requires working out where the code
603 would come from if the module was actually loaded */
604 code = get_module_code(self, fullname, &ispackage, &modpath);
605 if (code == NULL)
Victor Stinnerc342fca2010-10-18 11:39:05 +0000606 return NULL;
Nick Coghlanf088e5e2008-12-14 11:50:48 +0000607 Py_DECREF(code); /* Only need the path info */
608
Victor Stinner08654e12010-10-18 12:09:02 +0000609 return modpath;
Nick Coghlanf088e5e2008-12-14 11:50:48 +0000610}
611
Yaron de Leeuw02f3b7d2017-08-18 14:41:13 -0400612/*[clinic input]
613zipimport.zipimporter.is_package
Just van Rossum52e14d62002-12-30 22:08:05 +0000614
Yaron de Leeuw02f3b7d2017-08-18 14:41:13 -0400615 fullname: unicode
616 /
617
618Return True if the module specified by fullname is a package.
619
620Raise ZipImportError if the module couldn't be found.
621
622[clinic start generated code]*/
623
624static PyObject *
625zipimport_zipimporter_is_package_impl(ZipImporter *self, PyObject *fullname)
626/*[clinic end generated code: output=c32958c2a5216ae6 input=a7ba752f64345062]*/
627{
628 enum zi_module_info mi;
Just van Rossum52e14d62002-12-30 22:08:05 +0000629
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000630 mi = get_module_info(self, fullname);
631 if (mi == MI_ERROR)
Victor Stinner965a8a12010-10-18 21:44:33 +0000632 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000633 if (mi == MI_NOT_FOUND) {
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400634 PyErr_Format(ZipImportError, "can't find module %R", fullname);
Victor Stinner965a8a12010-10-18 21:44:33 +0000635 return NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000636 }
637 return PyBool_FromLong(mi == MI_PACKAGE);
Just van Rossum52e14d62002-12-30 22:08:05 +0000638}
639
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200640
Yaron de Leeuw02f3b7d2017-08-18 14:41:13 -0400641/*[clinic input]
642zipimport.zipimporter.get_data
643
644 pathname as path: unicode
645 /
646
647Return the data associated with 'pathname'.
648
649Raise OSError if the file was not found.
650
651[clinic start generated code]*/
652
Just van Rossum52e14d62002-12-30 22:08:05 +0000653static PyObject *
Yaron de Leeuw02f3b7d2017-08-18 14:41:13 -0400654zipimport_zipimporter_get_data_impl(ZipImporter *self, PyObject *path)
655/*[clinic end generated code: output=65dc506aaa268436 input=fa6428b74843c4ae]*/
Just van Rossum52e14d62002-12-30 22:08:05 +0000656{
Yaron de Leeuw02f3b7d2017-08-18 14:41:13 -0400657 PyObject *key;
Benjamin Peterson34c15402014-02-16 14:17:28 -0500658 PyObject *toc_entry;
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100659 Py_ssize_t path_start, path_len, len;
Just van Rossum52e14d62002-12-30 22:08:05 +0000660
Oren Milmandb60a5b2017-10-20 23:42:35 +0300661 if (self->archive == NULL) {
662 PyErr_SetString(PyExc_ValueError,
663 "zipimporter.__init__() wasn't called");
664 return NULL;
665 }
666
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200667#ifdef ALTSEP
Oren Milman631fdee2017-08-29 20:40:15 +0300668 path = _PyObject_CallMethodId((PyObject *)&PyUnicode_Type, &PyId_replace,
669 "OCC", path, ALTSEP, SEP);
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100670 if (!path)
671 return NULL;
672#else
673 Py_INCREF(path);
Just van Rossum52e14d62002-12-30 22:08:05 +0000674#endif
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100675 if (PyUnicode_READY(path) == -1)
676 goto error;
677
678 path_len = PyUnicode_GET_LENGTH(path);
679
Martin v. Löwisd63a3b82011-09-28 07:41:54 +0200680 len = PyUnicode_GET_LENGTH(self->archive);
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100681 path_start = 0;
682 if (PyUnicode_Tailmatch(path, self->archive, 0, len, -1)
683 && PyUnicode_READ_CHAR(path, len) == SEP) {
684 path_start = len + 1;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000685 }
Just van Rossum52e14d62002-12-30 22:08:05 +0000686
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100687 key = PyUnicode_Substring(path, path_start, path_len);
Victor Stinner60fe8d92010-08-16 23:48:11 +0000688 if (key == NULL)
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100689 goto error;
Victor Stinner60fe8d92010-08-16 23:48:11 +0000690 toc_entry = PyDict_GetItem(self->files, key);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000691 if (toc_entry == NULL) {
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +0300692 PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, key);
Victor Stinner60fe8d92010-08-16 23:48:11 +0000693 Py_DECREF(key);
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100694 goto error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000695 }
Victor Stinner60fe8d92010-08-16 23:48:11 +0000696 Py_DECREF(key);
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100697 Py_DECREF(path);
Benjamin Peterson34c15402014-02-16 14:17:28 -0500698 return get_data(self->archive, toc_entry);
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100699 error:
700 Py_DECREF(path);
701 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +0000702}
703
Yaron de Leeuw02f3b7d2017-08-18 14:41:13 -0400704/*[clinic input]
705zipimport.zipimporter.get_code
706
707 fullname: unicode
708 /
709
710Return the code object for the specified module.
711
712Raise ZipImportError if the module couldn't be found.
713
714[clinic start generated code]*/
715
Just van Rossum52e14d62002-12-30 22:08:05 +0000716static PyObject *
Yaron de Leeuw02f3b7d2017-08-18 14:41:13 -0400717zipimport_zipimporter_get_code_impl(ZipImporter *self, PyObject *fullname)
718/*[clinic end generated code: output=b923c37fa99cbac4 input=2761412bc37f3549]*/
Just van Rossum52e14d62002-12-30 22:08:05 +0000719{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000720 return get_module_code(self, fullname, NULL, NULL);
Just van Rossum52e14d62002-12-30 22:08:05 +0000721}
722
Yaron de Leeuw02f3b7d2017-08-18 14:41:13 -0400723/*[clinic input]
724zipimport.zipimporter.get_source
Just van Rossum52e14d62002-12-30 22:08:05 +0000725
Yaron de Leeuw02f3b7d2017-08-18 14:41:13 -0400726 fullname: unicode
727 /
728
729Return the source code for the specified module.
730
731Raise ZipImportError if the module couldn't be found, return None if the
732archive does contain the module, but has no source for it.
733
734[clinic start generated code]*/
735
736static PyObject *
737zipimport_zipimporter_get_source_impl(ZipImporter *self, PyObject *fullname)
738/*[clinic end generated code: output=bc059301b0c33729 input=4e4b186f2e690716]*/
739{
740 PyObject *toc_entry;
741 PyObject *subname, *path, *fullpath;
742 enum zi_module_info mi;
Just van Rossum52e14d62002-12-30 22:08:05 +0000743
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000744 mi = get_module_info(self, fullname);
Victor Stinner965a8a12010-10-18 21:44:33 +0000745 if (mi == MI_ERROR)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000746 return NULL;
Victor Stinner04106562010-10-18 20:44:08 +0000747 if (mi == MI_NOT_FOUND) {
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400748 PyErr_Format(ZipImportError, "can't find module %R", fullname);
Victor Stinner04106562010-10-18 20:44:08 +0000749 return NULL;
750 }
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400751
Victor Stinner965a8a12010-10-18 21:44:33 +0000752 subname = get_subname(fullname);
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400753 if (subname == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000754 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +0000755
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400756 path = make_filename(self->prefix, subname);
757 Py_DECREF(subname);
758 if (path == NULL)
759 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +0000760
Victor Stinnerf6b563a2011-03-14 20:46:50 -0400761 if (mi == MI_PACKAGE)
762 fullpath = PyUnicode_FromFormat("%U%c__init__.py", path, SEP);
763 else
764 fullpath = PyUnicode_FromFormat("%U.py", path);
765 Py_DECREF(path);
766 if (fullpath == NULL)
767 return NULL;
768
769 toc_entry = PyDict_GetItem(self->files, fullpath);
770 Py_DECREF(fullpath);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000771 if (toc_entry != NULL) {
Victor Stinner60fe8d92010-08-16 23:48:11 +0000772 PyObject *res, *bytes;
Benjamin Peterson34c15402014-02-16 14:17:28 -0500773 bytes = get_data(self->archive, toc_entry);
Victor Stinner60fe8d92010-08-16 23:48:11 +0000774 if (bytes == NULL)
775 return NULL;
776 res = PyUnicode_FromStringAndSize(PyBytes_AS_STRING(bytes),
777 PyBytes_GET_SIZE(bytes));
778 Py_DECREF(bytes);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000779 return res;
780 }
Just van Rossum52e14d62002-12-30 22:08:05 +0000781
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000782 /* we have the module, but no source */
Serhiy Storchaka228b12e2017-01-23 09:47:21 +0200783 Py_RETURN_NONE;
Just van Rossum52e14d62002-12-30 22:08:05 +0000784}
785
Barry Warsaw6f6eb352018-01-24 15:36:21 -0500786/*[clinic input]
787zipimport.zipimporter.get_resource_reader
788
789 fullname: unicode
790 /
791
792Return the ResourceReader for a package in a zip file.
793
794If 'fullname' is a package within the zip file, return the 'ResourceReader'
795object for the package. Otherwise return None.
796
797[clinic start generated code]*/
798
799static PyObject *
800zipimport_zipimporter_get_resource_reader_impl(ZipImporter *self,
801 PyObject *fullname)
802/*[clinic end generated code: output=5e367d431f830726 input=bfab94d736e99151]*/
803{
804 PyObject *module = PyImport_ImportModule("importlib.resources");
805 if (module == NULL) {
806 return NULL;
807 }
808 PyObject *retval = PyObject_CallMethod(
809 module, "_zipimport_get_resource_reader",
810 "OO", (PyObject *)self, fullname);
811 Py_DECREF(module);
812 return retval;
813}
814
Nick Coghlanf088e5e2008-12-14 11:50:48 +0000815
Just van Rossum52e14d62002-12-30 22:08:05 +0000816static PyMethodDef zipimporter_methods[] = {
Yaron de Leeuw02f3b7d2017-08-18 14:41:13 -0400817 ZIPIMPORT_ZIPIMPORTER_FIND_MODULE_METHODDEF
818 ZIPIMPORT_ZIPIMPORTER_FIND_LOADER_METHODDEF
819 ZIPIMPORT_ZIPIMPORTER_LOAD_MODULE_METHODDEF
820 ZIPIMPORT_ZIPIMPORTER_GET_FILENAME_METHODDEF
821 ZIPIMPORT_ZIPIMPORTER_IS_PACKAGE_METHODDEF
822 ZIPIMPORT_ZIPIMPORTER_GET_DATA_METHODDEF
823 ZIPIMPORT_ZIPIMPORTER_GET_CODE_METHODDEF
824 ZIPIMPORT_ZIPIMPORTER_GET_SOURCE_METHODDEF
Barry Warsaw6f6eb352018-01-24 15:36:21 -0500825 ZIPIMPORT_ZIPIMPORTER_GET_RESOURCE_READER_METHODDEF
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000826 {NULL, NULL} /* sentinel */
Just van Rossum52e14d62002-12-30 22:08:05 +0000827};
828
829static PyMemberDef zipimporter_members[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000830 {"archive", T_OBJECT, offsetof(ZipImporter, archive), READONLY},
831 {"prefix", T_OBJECT, offsetof(ZipImporter, prefix), READONLY},
832 {"_files", T_OBJECT, offsetof(ZipImporter, files), READONLY},
833 {NULL}
Just van Rossum52e14d62002-12-30 22:08:05 +0000834};
835
Just van Rossum52e14d62002-12-30 22:08:05 +0000836#define DEFERRED_ADDRESS(ADDR) 0
837
838static PyTypeObject ZipImporter_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000839 PyVarObject_HEAD_INIT(DEFERRED_ADDRESS(&PyType_Type), 0)
840 "zipimport.zipimporter",
841 sizeof(ZipImporter),
842 0, /* tp_itemsize */
843 (destructor)zipimporter_dealloc, /* tp_dealloc */
844 0, /* tp_print */
845 0, /* tp_getattr */
846 0, /* tp_setattr */
847 0, /* tp_reserved */
848 (reprfunc)zipimporter_repr, /* tp_repr */
849 0, /* tp_as_number */
850 0, /* tp_as_sequence */
851 0, /* tp_as_mapping */
852 0, /* tp_hash */
853 0, /* tp_call */
854 0, /* tp_str */
855 PyObject_GenericGetAttr, /* tp_getattro */
856 0, /* tp_setattro */
857 0, /* tp_as_buffer */
858 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE |
859 Py_TPFLAGS_HAVE_GC, /* tp_flags */
Yaron de Leeuw02f3b7d2017-08-18 14:41:13 -0400860 zipimport_zipimporter___init____doc__, /* tp_doc */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000861 zipimporter_traverse, /* tp_traverse */
862 0, /* tp_clear */
863 0, /* tp_richcompare */
864 0, /* tp_weaklistoffset */
865 0, /* tp_iter */
866 0, /* tp_iternext */
867 zipimporter_methods, /* tp_methods */
868 zipimporter_members, /* tp_members */
869 0, /* tp_getset */
870 0, /* tp_base */
871 0, /* tp_dict */
872 0, /* tp_descr_get */
873 0, /* tp_descr_set */
874 0, /* tp_dictoffset */
Yaron de Leeuw02f3b7d2017-08-18 14:41:13 -0400875 (initproc)zipimport_zipimporter___init__, /* tp_init */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000876 PyType_GenericAlloc, /* tp_alloc */
877 PyType_GenericNew, /* tp_new */
878 PyObject_GC_Del, /* tp_free */
Just van Rossum52e14d62002-12-30 22:08:05 +0000879};
880
881
882/* implementation */
883
Serhiy Storchakad5db5732016-01-28 21:30:16 +0200884/* Given a buffer, return the unsigned int that is represented by the first
Just van Rossum52e14d62002-12-30 22:08:05 +0000885 4 bytes, encoded as little endian. This partially reimplements
886 marshal.c:r_long() */
Serhiy Storchakad5db5732016-01-28 21:30:16 +0200887static unsigned int
888get_uint32(const unsigned char *buf)
889{
890 unsigned int x;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000891 x = buf[0];
Serhiy Storchakad5db5732016-01-28 21:30:16 +0200892 x |= (unsigned int)buf[1] << 8;
893 x |= (unsigned int)buf[2] << 16;
894 x |= (unsigned int)buf[3] << 24;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000895 return x;
Just van Rossum52e14d62002-12-30 22:08:05 +0000896}
897
Serhiy Storchakad5db5732016-01-28 21:30:16 +0200898/* Given a buffer, return the unsigned int that is represented by the first
899 2 bytes, encoded as little endian. This partially reimplements
900 marshal.c:r_short() */
901static unsigned short
902get_uint16(const unsigned char *buf)
903{
904 unsigned short x;
905 x = buf[0];
906 x |= (unsigned short)buf[1] << 8;
907 return x;
908}
909
910static void
911set_file_error(PyObject *archive, int eof)
912{
913 if (eof) {
914 PyErr_SetString(PyExc_EOFError, "EOF read where not expected");
915 }
916 else {
917 PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, archive);
918 }
919}
920
Gregory P. Smith2bcbc142014-01-07 18:30:07 -0800921/*
Benjamin Peterson34c15402014-02-16 14:17:28 -0500922 read_directory(archive) -> files dict (new reference)
Gregory P. Smith2bcbc142014-01-07 18:30:07 -0800923
Benjamin Peterson34c15402014-02-16 14:17:28 -0500924 Given a path to a Zip archive, build a dict, mapping file names
Just van Rossum52e14d62002-12-30 22:08:05 +0000925 (local to the archive, using SEP as a separator) to toc entries.
926
927 A toc_entry is a tuple:
928
Victor Stinner08654e12010-10-18 12:09:02 +0000929 (__file__, # value to use for __file__, available for all files,
930 # encoded to the filesystem encoding
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000931 compress, # compression kind; 0 for uncompressed
932 data_size, # size of compressed data on disk
933 file_size, # size of decompressed data
934 file_offset, # offset of file header from start of archive
935 time, # mod time of file (in dos format)
936 date, # mod data of file (in dos format)
937 crc, # crc checksum of the data
Victor Stinnerc342fca2010-10-18 11:39:05 +0000938 )
Just van Rossum52e14d62002-12-30 22:08:05 +0000939
940 Directories can be recognized by the trailing SEP in the name,
941 data_size and file_offset are 0.
942*/
943static PyObject *
Benjamin Peterson34c15402014-02-16 14:17:28 -0500944read_directory(PyObject *archive)
Just van Rossum52e14d62002-12-30 22:08:05 +0000945{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000946 PyObject *files = NULL;
Benjamin Peterson34c15402014-02-16 14:17:28 -0500947 FILE *fp;
Serhiy Storchakad5db5732016-01-28 21:30:16 +0200948 unsigned short flags, compress, time, date, name_size;
949 unsigned int crc, data_size, file_size, header_size, header_offset;
950 unsigned long file_offset, header_position;
951 unsigned long arc_offset; /* Absolute offset to start of the zip-archive. */
952 unsigned int count, i;
953 unsigned char buffer[46];
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000954 char name[MAXPATHLEN + 5];
Victor Stinner2460a432010-08-16 17:54:28 +0000955 PyObject *nameobj = NULL;
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100956 PyObject *path;
Victor Stinnerd36c8212010-10-18 12:13:46 +0000957 const char *charset;
Victor Stinner4ee65a92011-01-22 10:30:29 +0000958 int bootstrap;
Serhiy Storchakad5db5732016-01-28 21:30:16 +0200959 const char *errmsg = NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +0000960
Benjamin Peterson34c15402014-02-16 14:17:28 -0500961 fp = _Py_fopen_obj(archive, "rb");
962 if (fp == NULL) {
Victor Stinnerfbd6f9e2015-03-20 10:52:25 +0100963 if (PyErr_ExceptionMatches(PyExc_OSError)) {
Serhiy Storchaka467ab192016-10-21 17:09:17 +0300964 _PyErr_FormatFromCause(ZipImportError,
965 "can't open Zip file: %R", archive);
Victor Stinnerfbd6f9e2015-03-20 10:52:25 +0100966 }
Benjamin Peterson34c15402014-02-16 14:17:28 -0500967 return NULL;
968 }
969
Jesus Cea09bf7a72012-10-03 02:13:05 +0200970 if (fseek(fp, -22, SEEK_END) == -1) {
Serhiy Storchakad5db5732016-01-28 21:30:16 +0200971 goto file_error;
Jesus Cea09bf7a72012-10-03 02:13:05 +0200972 }
Serhiy Storchakad5db5732016-01-28 21:30:16 +0200973 header_position = (unsigned long)ftell(fp);
974 if (header_position == (unsigned long)-1) {
975 goto file_error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000976 }
Serhiy Storchakad5db5732016-01-28 21:30:16 +0200977 assert(header_position <= (unsigned long)LONG_MAX);
978 if (fread(buffer, 1, 22, fp) != 22) {
979 goto file_error;
980 }
981 if (get_uint32(buffer) != 0x06054B50u) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000982 /* Bad: End of Central Dir signature */
Serhiy Storchakad5db5732016-01-28 21:30:16 +0200983 errmsg = "not a Zip file";
984 goto invalid_header;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000985 }
Just van Rossum52e14d62002-12-30 22:08:05 +0000986
Serhiy Storchakad5db5732016-01-28 21:30:16 +0200987 header_size = get_uint32(buffer + 12);
988 header_offset = get_uint32(buffer + 16);
989 if (header_position < header_size) {
990 errmsg = "bad central directory size";
991 goto invalid_header;
992 }
993 if (header_position < header_offset) {
994 errmsg = "bad central directory offset";
995 goto invalid_header;
996 }
997 if (header_position - header_size < header_offset) {
998 errmsg = "bad central directory size or offset";
999 goto invalid_header;
1000 }
1001 header_position -= header_size;
1002 arc_offset = header_position - header_offset;
Just van Rossum52e14d62002-12-30 22:08:05 +00001003
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001004 files = PyDict_New();
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001005 if (files == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001006 goto error;
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001007 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001008 /* Start of Central Directory */
1009 count = 0;
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001010 if (fseek(fp, (long)header_position, 0) == -1) {
Serhiy Storchaka0e6b7b52013-02-16 17:43:45 +02001011 goto file_error;
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001012 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001013 for (;;) {
1014 PyObject *t;
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001015 size_t n;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001016 int err;
Just van Rossum52e14d62002-12-30 22:08:05 +00001017
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001018 n = fread(buffer, 1, 46, fp);
1019 if (n < 4) {
1020 goto eof_error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001021 }
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001022 /* Start of file header */
1023 if (get_uint32(buffer) != 0x02014B50u) {
1024 break; /* Bad: Central Dir File Header */
1025 }
1026 if (n != 46) {
1027 goto eof_error;
1028 }
1029 flags = get_uint16(buffer + 8);
1030 compress = get_uint16(buffer + 10);
1031 time = get_uint16(buffer + 12);
1032 date = get_uint16(buffer + 14);
1033 crc = get_uint32(buffer + 16);
1034 data_size = get_uint32(buffer + 20);
1035 file_size = get_uint32(buffer + 24);
1036 name_size = get_uint16(buffer + 28);
1037 header_size = (unsigned int)name_size +
1038 get_uint16(buffer + 30) /* extra field */ +
1039 get_uint16(buffer + 32) /* comment */;
1040
1041 file_offset = get_uint32(buffer + 42);
1042 if (file_offset > header_offset) {
1043 errmsg = "bad local header offset";
1044 goto invalid_header;
1045 }
1046 file_offset += arc_offset;
1047
1048 if (name_size > MAXPATHLEN) {
1049 name_size = MAXPATHLEN;
1050 }
1051 if (fread(name, 1, name_size, fp) != name_size) {
1052 goto file_error;
1053 }
1054 name[name_size] = '\0'; /* Add terminating null byte */
Victor Stinner44d9bea2016-12-05 17:55:36 +01001055#if SEP != '/'
1056 for (i = 0; i < name_size; i++) {
1057 if (name[i] == '/') {
1058 name[i] = SEP;
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001059 }
1060 }
Victor Stinner44d9bea2016-12-05 17:55:36 +01001061#endif
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001062 /* Skip the rest of the header.
1063 * On Windows, calling fseek to skip over the fields we don't use is
1064 * slower than reading the data because fseek flushes stdio's
1065 * internal buffers. See issue #8745. */
1066 assert(header_size <= 3*0xFFFFu);
1067 for (i = name_size; i < header_size; i++) {
1068 if (getc(fp) == EOF) {
Serhiy Storchaka0e6b7b52013-02-16 17:43:45 +02001069 goto file_error;
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001070 }
1071 }
Just van Rossum52e14d62002-12-30 22:08:05 +00001072
Victor Stinner4ee65a92011-01-22 10:30:29 +00001073 bootstrap = 0;
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001074 if (flags & 0x0800) {
Victor Stinnerd36c8212010-10-18 12:13:46 +00001075 charset = "utf-8";
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001076 }
Victor Stinnercaba55b2018-08-03 15:33:52 +02001077 else if (!_PyInterpreterState_Get()->codecs_initialized) {
Victor Stinner4ee65a92011-01-22 10:30:29 +00001078 /* During bootstrap, we may need to load the encodings
1079 package from a ZIP file. But the cp437 encoding is implemented
1080 in Python in the encodings package.
1081
1082 Break out of this dependency by assuming that the path to
1083 the encodings module is ASCII-only. */
1084 charset = "ascii";
1085 bootstrap = 1;
1086 }
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001087 else {
Victor Stinnerd36c8212010-10-18 12:13:46 +00001088 charset = "cp437";
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001089 }
Victor Stinnerd36c8212010-10-18 12:13:46 +00001090 nameobj = PyUnicode_Decode(name, name_size, charset, NULL);
Victor Stinner4ee65a92011-01-22 10:30:29 +00001091 if (nameobj == NULL) {
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001092 if (bootstrap) {
Victor Stinner4ee65a92011-01-22 10:30:29 +00001093 PyErr_Format(PyExc_NotImplementedError,
1094 "bootstrap issue: python%i%i.zip contains non-ASCII "
1095 "filenames without the unicode flag",
1096 PY_MAJOR_VERSION, PY_MINOR_VERSION);
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001097 }
Victor Stinner2460a432010-08-16 17:54:28 +00001098 goto error;
Victor Stinner4ee65a92011-01-22 10:30:29 +00001099 }
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001100 if (PyUnicode_READY(nameobj) == -1) {
Stefan Krah000fde92012-08-20 14:14:49 +02001101 goto error;
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001102 }
Martin v. Löwisa72e78b2011-10-31 08:33:37 +01001103 path = PyUnicode_FromFormat("%U%c%U", archive, SEP, nameobj);
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001104 if (path == NULL) {
Victor Stinner2460a432010-08-16 17:54:28 +00001105 goto error;
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001106 }
1107 t = Py_BuildValue("NHIIkHHI", path, compress, data_size,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001108 file_size, file_offset, time, date, crc);
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001109 if (t == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001110 goto error;
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001111 }
Victor Stinner2460a432010-08-16 17:54:28 +00001112 err = PyDict_SetItem(files, nameobj, t);
1113 Py_CLEAR(nameobj);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001114 Py_DECREF(t);
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001115 if (err != 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001116 goto error;
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001117 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001118 count++;
1119 }
Benjamin Peterson34c15402014-02-16 14:17:28 -05001120 fclose(fp);
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001121 if (Py_VerboseFlag) {
1122 PySys_FormatStderr("# zipimport: found %u names in %R\n",
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001123 count, archive);
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001124 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001125 return files;
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001126
1127eof_error:
1128 set_file_error(archive, !ferror(fp));
1129 goto error;
1130
Serhiy Storchaka0e6b7b52013-02-16 17:43:45 +02001131file_error:
Jesus Cea09bf7a72012-10-03 02:13:05 +02001132 PyErr_Format(ZipImportError, "can't read Zip file: %R", archive);
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001133 goto error;
1134
1135invalid_header:
1136 assert(errmsg != NULL);
1137 PyErr_Format(ZipImportError, "%s: %R", errmsg, archive);
1138 goto error;
1139
Just van Rossum52e14d62002-12-30 22:08:05 +00001140error:
Benjamin Peterson34c15402014-02-16 14:17:28 -05001141 fclose(fp);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001142 Py_XDECREF(files);
Victor Stinner2460a432010-08-16 17:54:28 +00001143 Py_XDECREF(nameobj);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001144 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +00001145}
1146
1147/* Return the zlib.decompress function object, or NULL if zlib couldn't
1148 be imported. The function is cached when found, so subsequent calls
Victor Stinner4925cde2011-05-20 00:16:09 +02001149 don't import zlib again. */
Just van Rossum52e14d62002-12-30 22:08:05 +00001150static PyObject *
1151get_decompress_func(void)
1152{
Victor Stinner4925cde2011-05-20 00:16:09 +02001153 static int importing_zlib = 0;
1154 PyObject *zlib;
1155 PyObject *decompress;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02001156 _Py_IDENTIFIER(decompress);
Just van Rossum52e14d62002-12-30 22:08:05 +00001157
Victor Stinner4925cde2011-05-20 00:16:09 +02001158 if (importing_zlib != 0)
Xiang Zhang0710d752017-03-11 13:02:52 +08001159 /* Someone has a zlib.pyc in their Zip file;
Victor Stinner4925cde2011-05-20 00:16:09 +02001160 let's avoid a stack overflow. */
1161 return NULL;
1162 importing_zlib = 1;
1163 zlib = PyImport_ImportModuleNoBlock("zlib");
1164 importing_zlib = 0;
1165 if (zlib != NULL) {
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02001166 decompress = _PyObject_GetAttrId(zlib,
1167 &PyId_decompress);
Victor Stinner4925cde2011-05-20 00:16:09 +02001168 Py_DECREF(zlib);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001169 }
Victor Stinner4925cde2011-05-20 00:16:09 +02001170 else {
1171 PyErr_Clear();
1172 decompress = NULL;
1173 }
1174 if (Py_VerboseFlag)
1175 PySys_WriteStderr("# zipimport: zlib %s\n",
1176 zlib != NULL ? "available": "UNAVAILABLE");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001177 return decompress;
Just van Rossum52e14d62002-12-30 22:08:05 +00001178}
1179
Benjamin Peterson34c15402014-02-16 14:17:28 -05001180/* Given a path to a Zip file and a toc_entry, return the (uncompressed)
Just van Rossum52e14d62002-12-30 22:08:05 +00001181 data as a new reference. */
1182static PyObject *
Benjamin Peterson34c15402014-02-16 14:17:28 -05001183get_data(PyObject *archive, PyObject *toc_entry)
Just van Rossum52e14d62002-12-30 22:08:05 +00001184{
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001185 PyObject *raw_data = NULL, *data, *decompress;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001186 char *buf;
Benjamin Peterson34c15402014-02-16 14:17:28 -05001187 FILE *fp;
Victor Stinner60fe8d92010-08-16 23:48:11 +00001188 PyObject *datapath;
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001189 unsigned short compress, time, date;
1190 unsigned int crc;
1191 Py_ssize_t data_size, file_size, bytes_size;
1192 long file_offset, header_size;
1193 unsigned char buffer[30];
1194 const char *errmsg = NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +00001195
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001196 if (!PyArg_ParseTuple(toc_entry, "OHnnlHHI", &datapath, &compress,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001197 &data_size, &file_size, &file_offset, &time,
1198 &date, &crc)) {
1199 return NULL;
1200 }
Benjamin Petersonb1db7582016-01-21 22:02:46 -08001201 if (data_size < 0) {
1202 PyErr_Format(ZipImportError, "negative data size");
1203 return NULL;
1204 }
Just van Rossum52e14d62002-12-30 22:08:05 +00001205
Benjamin Peterson34c15402014-02-16 14:17:28 -05001206 fp = _Py_fopen_obj(archive, "rb");
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001207 if (!fp) {
Benjamin Peterson34c15402014-02-16 14:17:28 -05001208 return NULL;
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001209 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001210 /* Check to make sure the local file header is correct */
Jesus Cea09bf7a72012-10-03 02:13:05 +02001211 if (fseek(fp, file_offset, 0) == -1) {
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001212 goto file_error;
Jesus Cea09bf7a72012-10-03 02:13:05 +02001213 }
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001214 if (fread(buffer, 1, 30, fp) != 30) {
1215 goto eof_error;
1216 }
1217 if (get_uint32(buffer) != 0x04034B50u) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001218 /* Bad: Local File Header */
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001219 errmsg = "bad local file header";
1220 goto invalid_header;
Jesus Cea09bf7a72012-10-03 02:13:05 +02001221 }
1222
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001223 header_size = (unsigned int)30 +
1224 get_uint16(buffer + 26) /* file name */ +
1225 get_uint16(buffer + 28) /* extra field */;
1226 if (file_offset > LONG_MAX - header_size) {
1227 errmsg = "bad local file header size";
1228 goto invalid_header;
Victor Stinner73660af2013-10-29 01:43:44 +01001229 }
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001230 file_offset += header_size; /* Start of file data */
Just van Rossum52e14d62002-12-30 22:08:05 +00001231
Benjamin Petersonc4032da2016-01-20 22:23:44 -08001232 if (data_size > LONG_MAX - 1) {
1233 fclose(fp);
1234 PyErr_NoMemory();
1235 return NULL;
1236 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001237 bytes_size = compress == 0 ? data_size : data_size + 1;
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001238 if (bytes_size == 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001239 bytes_size++;
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001240 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001241 raw_data = PyBytes_FromStringAndSize((char *)NULL, bytes_size);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001242 if (raw_data == NULL) {
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001243 goto error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001244 }
1245 buf = PyBytes_AsString(raw_data);
Just van Rossum52e14d62002-12-30 22:08:05 +00001246
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001247 if (fseek(fp, file_offset, 0) == -1) {
1248 goto file_error;
Jesus Cea09bf7a72012-10-03 02:13:05 +02001249 }
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001250 if (fread(buf, 1, data_size, fp) != (size_t)data_size) {
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +03001251 PyErr_SetString(PyExc_OSError,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001252 "zipimport: can't read data");
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001253 goto error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001254 }
Just van Rossum52e14d62002-12-30 22:08:05 +00001255
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001256 fclose(fp);
1257 fp = NULL;
1258
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001259 if (compress != 0) {
1260 buf[data_size] = 'Z'; /* saw this in zipfile.py */
1261 data_size++;
1262 }
1263 buf[data_size] = '\0';
Just van Rossum52e14d62002-12-30 22:08:05 +00001264
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001265 if (compress == 0) { /* data is not compressed */
1266 data = PyBytes_FromStringAndSize(buf, data_size);
1267 Py_DECREF(raw_data);
1268 return data;
1269 }
1270
1271 /* Decompress with zlib */
1272 decompress = get_decompress_func();
1273 if (decompress == NULL) {
1274 PyErr_SetString(ZipImportError,
1275 "can't decompress data; "
1276 "zlib not available");
1277 goto error;
1278 }
1279 data = PyObject_CallFunction(decompress, "Oi", raw_data, -15);
Victor Stinner4925cde2011-05-20 00:16:09 +02001280 Py_DECREF(decompress);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001281 Py_DECREF(raw_data);
Oren Milman01c6a882017-09-29 21:34:31 +03001282 if (data != NULL && !PyBytes_Check(data)) {
1283 PyErr_Format(PyExc_TypeError,
1284 "zlib.decompress() must return a bytes object, not "
1285 "%.200s",
1286 Py_TYPE(data)->tp_name);
1287 Py_DECREF(data);
1288 return NULL;
1289 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001290 return data;
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001291
1292eof_error:
1293 set_file_error(archive, !ferror(fp));
1294 goto error;
1295
1296file_error:
1297 PyErr_Format(ZipImportError, "can't read Zip file: %R", archive);
1298 goto error;
1299
1300invalid_header:
1301 assert(errmsg != NULL);
1302 PyErr_Format(ZipImportError, "%s: %R", errmsg, archive);
1303 goto error;
1304
1305error:
1306 if (fp != NULL) {
1307 fclose(fp);
1308 }
1309 Py_XDECREF(raw_data);
1310 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +00001311}
1312
1313/* Lenient date/time comparison function. The precision of the mtime
1314 in the archive is lower than the mtime stored in a .pyc: we
1315 must allow a difference of at most one second. */
1316static int
1317eq_mtime(time_t t1, time_t t2)
1318{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001319 time_t d = t1 - t2;
1320 if (d < 0)
1321 d = -d;
1322 /* dostime only stores even seconds, so be lenient */
1323 return d <= 1;
Just van Rossum52e14d62002-12-30 22:08:05 +00001324}
1325
Xiang Zhang0710d752017-03-11 13:02:52 +08001326/* Given the contents of a .pyc file in a buffer, unmarshal the data
Just van Rossum52e14d62002-12-30 22:08:05 +00001327 and return the code object. Return None if it the magic word doesn't
1328 match (we do this instead of raising an exception as we fall back
1329 to .py if available and we don't want to mask other errors).
1330 Returns a new reference. */
1331static PyObject *
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001332unmarshal_code(PyObject *pathname, PyObject *data, time_t mtime)
Just van Rossum52e14d62002-12-30 22:08:05 +00001333{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001334 PyObject *code;
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001335 unsigned char *buf = (unsigned char *)PyBytes_AsString(data);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001336 Py_ssize_t size = PyBytes_Size(data);
Just van Rossum52e14d62002-12-30 22:08:05 +00001337
Benjamin Peterson42aa93b2017-12-09 10:26:52 -08001338 if (size < 16) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001339 PyErr_SetString(ZipImportError,
1340 "bad pyc data");
1341 return NULL;
1342 }
Just van Rossum52e14d62002-12-30 22:08:05 +00001343
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001344 if (get_uint32(buf) != (unsigned int)PyImport_GetMagicNumber()) {
1345 if (Py_VerboseFlag) {
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001346 PySys_FormatStderr("# %R has bad magic\n",
1347 pathname);
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001348 }
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02001349 Py_RETURN_NONE; /* signal caller to try alternative */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001350 }
Just van Rossum52e14d62002-12-30 22:08:05 +00001351
Benjamin Peterson42aa93b2017-12-09 10:26:52 -08001352 uint32_t flags = get_uint32(buf + 4);
1353 if (flags != 0) {
Victor Stinnercaba55b2018-08-03 15:33:52 +02001354 _PyCoreConfig *config = &_PyInterpreterState_Get()->core_config;
Benjamin Peterson42aa93b2017-12-09 10:26:52 -08001355 // 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.
Victor Stinner80b762f2018-08-01 18:18:07 +02001359 if (strcmp(config->_check_hash_pycs_mode, "never") &&
1360 (flags != 0x1 || !strcmp(config->_check_hash_pycs_mode, "always")))
Benjamin Peterson42aa93b2017-12-09 10:26:52 -08001361 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}