blob: 009480bac58d25f180dac121cff6bc4fcc2ce777 [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
Nick Coghlanf088e5e2008-12-14 11:50:48 +0000786
Just van Rossum52e14d62002-12-30 22:08:05 +0000787static PyMethodDef zipimporter_methods[] = {
Yaron de Leeuw02f3b7d2017-08-18 14:41:13 -0400788 ZIPIMPORT_ZIPIMPORTER_FIND_MODULE_METHODDEF
789 ZIPIMPORT_ZIPIMPORTER_FIND_LOADER_METHODDEF
790 ZIPIMPORT_ZIPIMPORTER_LOAD_MODULE_METHODDEF
791 ZIPIMPORT_ZIPIMPORTER_GET_FILENAME_METHODDEF
792 ZIPIMPORT_ZIPIMPORTER_IS_PACKAGE_METHODDEF
793 ZIPIMPORT_ZIPIMPORTER_GET_DATA_METHODDEF
794 ZIPIMPORT_ZIPIMPORTER_GET_CODE_METHODDEF
795 ZIPIMPORT_ZIPIMPORTER_GET_SOURCE_METHODDEF
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000796 {NULL, NULL} /* sentinel */
Just van Rossum52e14d62002-12-30 22:08:05 +0000797};
798
799static PyMemberDef zipimporter_members[] = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000800 {"archive", T_OBJECT, offsetof(ZipImporter, archive), READONLY},
801 {"prefix", T_OBJECT, offsetof(ZipImporter, prefix), READONLY},
802 {"_files", T_OBJECT, offsetof(ZipImporter, files), READONLY},
803 {NULL}
Just van Rossum52e14d62002-12-30 22:08:05 +0000804};
805
Just van Rossum52e14d62002-12-30 22:08:05 +0000806#define DEFERRED_ADDRESS(ADDR) 0
807
808static PyTypeObject ZipImporter_Type = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000809 PyVarObject_HEAD_INIT(DEFERRED_ADDRESS(&PyType_Type), 0)
810 "zipimport.zipimporter",
811 sizeof(ZipImporter),
812 0, /* tp_itemsize */
813 (destructor)zipimporter_dealloc, /* tp_dealloc */
814 0, /* tp_print */
815 0, /* tp_getattr */
816 0, /* tp_setattr */
817 0, /* tp_reserved */
818 (reprfunc)zipimporter_repr, /* tp_repr */
819 0, /* tp_as_number */
820 0, /* tp_as_sequence */
821 0, /* tp_as_mapping */
822 0, /* tp_hash */
823 0, /* tp_call */
824 0, /* tp_str */
825 PyObject_GenericGetAttr, /* tp_getattro */
826 0, /* tp_setattro */
827 0, /* tp_as_buffer */
828 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE |
829 Py_TPFLAGS_HAVE_GC, /* tp_flags */
Yaron de Leeuw02f3b7d2017-08-18 14:41:13 -0400830 zipimport_zipimporter___init____doc__, /* tp_doc */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000831 zipimporter_traverse, /* tp_traverse */
832 0, /* tp_clear */
833 0, /* tp_richcompare */
834 0, /* tp_weaklistoffset */
835 0, /* tp_iter */
836 0, /* tp_iternext */
837 zipimporter_methods, /* tp_methods */
838 zipimporter_members, /* tp_members */
839 0, /* tp_getset */
840 0, /* tp_base */
841 0, /* tp_dict */
842 0, /* tp_descr_get */
843 0, /* tp_descr_set */
844 0, /* tp_dictoffset */
Yaron de Leeuw02f3b7d2017-08-18 14:41:13 -0400845 (initproc)zipimport_zipimporter___init__, /* tp_init */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000846 PyType_GenericAlloc, /* tp_alloc */
847 PyType_GenericNew, /* tp_new */
848 PyObject_GC_Del, /* tp_free */
Just van Rossum52e14d62002-12-30 22:08:05 +0000849};
850
851
852/* implementation */
853
Serhiy Storchakad5db5732016-01-28 21:30:16 +0200854/* Given a buffer, return the unsigned int that is represented by the first
Just van Rossum52e14d62002-12-30 22:08:05 +0000855 4 bytes, encoded as little endian. This partially reimplements
856 marshal.c:r_long() */
Serhiy Storchakad5db5732016-01-28 21:30:16 +0200857static unsigned int
858get_uint32(const unsigned char *buf)
859{
860 unsigned int x;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000861 x = buf[0];
Serhiy Storchakad5db5732016-01-28 21:30:16 +0200862 x |= (unsigned int)buf[1] << 8;
863 x |= (unsigned int)buf[2] << 16;
864 x |= (unsigned int)buf[3] << 24;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000865 return x;
Just van Rossum52e14d62002-12-30 22:08:05 +0000866}
867
Serhiy Storchakad5db5732016-01-28 21:30:16 +0200868/* Given a buffer, return the unsigned int that is represented by the first
869 2 bytes, encoded as little endian. This partially reimplements
870 marshal.c:r_short() */
871static unsigned short
872get_uint16(const unsigned char *buf)
873{
874 unsigned short x;
875 x = buf[0];
876 x |= (unsigned short)buf[1] << 8;
877 return x;
878}
879
880static void
881set_file_error(PyObject *archive, int eof)
882{
883 if (eof) {
884 PyErr_SetString(PyExc_EOFError, "EOF read where not expected");
885 }
886 else {
887 PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, archive);
888 }
889}
890
Gregory P. Smith2bcbc142014-01-07 18:30:07 -0800891/*
Benjamin Peterson34c15402014-02-16 14:17:28 -0500892 read_directory(archive) -> files dict (new reference)
Gregory P. Smith2bcbc142014-01-07 18:30:07 -0800893
Benjamin Peterson34c15402014-02-16 14:17:28 -0500894 Given a path to a Zip archive, build a dict, mapping file names
Just van Rossum52e14d62002-12-30 22:08:05 +0000895 (local to the archive, using SEP as a separator) to toc entries.
896
897 A toc_entry is a tuple:
898
Victor Stinner08654e12010-10-18 12:09:02 +0000899 (__file__, # value to use for __file__, available for all files,
900 # encoded to the filesystem encoding
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000901 compress, # compression kind; 0 for uncompressed
902 data_size, # size of compressed data on disk
903 file_size, # size of decompressed data
904 file_offset, # offset of file header from start of archive
905 time, # mod time of file (in dos format)
906 date, # mod data of file (in dos format)
907 crc, # crc checksum of the data
Victor Stinnerc342fca2010-10-18 11:39:05 +0000908 )
Just van Rossum52e14d62002-12-30 22:08:05 +0000909
910 Directories can be recognized by the trailing SEP in the name,
911 data_size and file_offset are 0.
912*/
913static PyObject *
Benjamin Peterson34c15402014-02-16 14:17:28 -0500914read_directory(PyObject *archive)
Just van Rossum52e14d62002-12-30 22:08:05 +0000915{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000916 PyObject *files = NULL;
Benjamin Peterson34c15402014-02-16 14:17:28 -0500917 FILE *fp;
Serhiy Storchakad5db5732016-01-28 21:30:16 +0200918 unsigned short flags, compress, time, date, name_size;
919 unsigned int crc, data_size, file_size, header_size, header_offset;
920 unsigned long file_offset, header_position;
921 unsigned long arc_offset; /* Absolute offset to start of the zip-archive. */
922 unsigned int count, i;
923 unsigned char buffer[46];
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000924 char name[MAXPATHLEN + 5];
Victor Stinner2460a432010-08-16 17:54:28 +0000925 PyObject *nameobj = NULL;
Martin v. Löwisa72e78b2011-10-31 08:33:37 +0100926 PyObject *path;
Victor Stinnerd36c8212010-10-18 12:13:46 +0000927 const char *charset;
Victor Stinner4ee65a92011-01-22 10:30:29 +0000928 int bootstrap;
Serhiy Storchakad5db5732016-01-28 21:30:16 +0200929 const char *errmsg = NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +0000930
Benjamin Peterson34c15402014-02-16 14:17:28 -0500931 fp = _Py_fopen_obj(archive, "rb");
932 if (fp == NULL) {
Victor Stinnerfbd6f9e2015-03-20 10:52:25 +0100933 if (PyErr_ExceptionMatches(PyExc_OSError)) {
Serhiy Storchaka467ab192016-10-21 17:09:17 +0300934 _PyErr_FormatFromCause(ZipImportError,
935 "can't open Zip file: %R", archive);
Victor Stinnerfbd6f9e2015-03-20 10:52:25 +0100936 }
Benjamin Peterson34c15402014-02-16 14:17:28 -0500937 return NULL;
938 }
939
Jesus Cea09bf7a72012-10-03 02:13:05 +0200940 if (fseek(fp, -22, SEEK_END) == -1) {
Serhiy Storchakad5db5732016-01-28 21:30:16 +0200941 goto file_error;
Jesus Cea09bf7a72012-10-03 02:13:05 +0200942 }
Serhiy Storchakad5db5732016-01-28 21:30:16 +0200943 header_position = (unsigned long)ftell(fp);
944 if (header_position == (unsigned long)-1) {
945 goto file_error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000946 }
Serhiy Storchakad5db5732016-01-28 21:30:16 +0200947 assert(header_position <= (unsigned long)LONG_MAX);
948 if (fread(buffer, 1, 22, fp) != 22) {
949 goto file_error;
950 }
951 if (get_uint32(buffer) != 0x06054B50u) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000952 /* Bad: End of Central Dir signature */
Serhiy Storchakad5db5732016-01-28 21:30:16 +0200953 errmsg = "not a Zip file";
954 goto invalid_header;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000955 }
Just van Rossum52e14d62002-12-30 22:08:05 +0000956
Serhiy Storchakad5db5732016-01-28 21:30:16 +0200957 header_size = get_uint32(buffer + 12);
958 header_offset = get_uint32(buffer + 16);
959 if (header_position < header_size) {
960 errmsg = "bad central directory size";
961 goto invalid_header;
962 }
963 if (header_position < header_offset) {
964 errmsg = "bad central directory offset";
965 goto invalid_header;
966 }
967 if (header_position - header_size < header_offset) {
968 errmsg = "bad central directory size or offset";
969 goto invalid_header;
970 }
971 header_position -= header_size;
972 arc_offset = header_position - header_offset;
Just van Rossum52e14d62002-12-30 22:08:05 +0000973
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000974 files = PyDict_New();
Serhiy Storchakad5db5732016-01-28 21:30:16 +0200975 if (files == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000976 goto error;
Serhiy Storchakad5db5732016-01-28 21:30:16 +0200977 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000978 /* Start of Central Directory */
979 count = 0;
Serhiy Storchakad5db5732016-01-28 21:30:16 +0200980 if (fseek(fp, (long)header_position, 0) == -1) {
Serhiy Storchaka0e6b7b52013-02-16 17:43:45 +0200981 goto file_error;
Serhiy Storchakad5db5732016-01-28 21:30:16 +0200982 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000983 for (;;) {
984 PyObject *t;
Serhiy Storchakad5db5732016-01-28 21:30:16 +0200985 size_t n;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000986 int err;
Just van Rossum52e14d62002-12-30 22:08:05 +0000987
Serhiy Storchakad5db5732016-01-28 21:30:16 +0200988 n = fread(buffer, 1, 46, fp);
989 if (n < 4) {
990 goto eof_error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +0000991 }
Serhiy Storchakad5db5732016-01-28 21:30:16 +0200992 /* Start of file header */
993 if (get_uint32(buffer) != 0x02014B50u) {
994 break; /* Bad: Central Dir File Header */
995 }
996 if (n != 46) {
997 goto eof_error;
998 }
999 flags = get_uint16(buffer + 8);
1000 compress = get_uint16(buffer + 10);
1001 time = get_uint16(buffer + 12);
1002 date = get_uint16(buffer + 14);
1003 crc = get_uint32(buffer + 16);
1004 data_size = get_uint32(buffer + 20);
1005 file_size = get_uint32(buffer + 24);
1006 name_size = get_uint16(buffer + 28);
1007 header_size = (unsigned int)name_size +
1008 get_uint16(buffer + 30) /* extra field */ +
1009 get_uint16(buffer + 32) /* comment */;
1010
1011 file_offset = get_uint32(buffer + 42);
1012 if (file_offset > header_offset) {
1013 errmsg = "bad local header offset";
1014 goto invalid_header;
1015 }
1016 file_offset += arc_offset;
1017
1018 if (name_size > MAXPATHLEN) {
1019 name_size = MAXPATHLEN;
1020 }
1021 if (fread(name, 1, name_size, fp) != name_size) {
1022 goto file_error;
1023 }
1024 name[name_size] = '\0'; /* Add terminating null byte */
Victor Stinner44d9bea2016-12-05 17:55:36 +01001025#if SEP != '/'
1026 for (i = 0; i < name_size; i++) {
1027 if (name[i] == '/') {
1028 name[i] = SEP;
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001029 }
1030 }
Victor Stinner44d9bea2016-12-05 17:55:36 +01001031#endif
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001032 /* Skip the rest of the header.
1033 * On Windows, calling fseek to skip over the fields we don't use is
1034 * slower than reading the data because fseek flushes stdio's
1035 * internal buffers. See issue #8745. */
1036 assert(header_size <= 3*0xFFFFu);
1037 for (i = name_size; i < header_size; i++) {
1038 if (getc(fp) == EOF) {
Serhiy Storchaka0e6b7b52013-02-16 17:43:45 +02001039 goto file_error;
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001040 }
1041 }
Just van Rossum52e14d62002-12-30 22:08:05 +00001042
Victor Stinner4ee65a92011-01-22 10:30:29 +00001043 bootstrap = 0;
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001044 if (flags & 0x0800) {
Victor Stinnerd36c8212010-10-18 12:13:46 +00001045 charset = "utf-8";
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001046 }
Victor Stinner4ee65a92011-01-22 10:30:29 +00001047 else if (!PyThreadState_GET()->interp->codecs_initialized) {
1048 /* During bootstrap, we may need to load the encodings
1049 package from a ZIP file. But the cp437 encoding is implemented
1050 in Python in the encodings package.
1051
1052 Break out of this dependency by assuming that the path to
1053 the encodings module is ASCII-only. */
1054 charset = "ascii";
1055 bootstrap = 1;
1056 }
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001057 else {
Victor Stinnerd36c8212010-10-18 12:13:46 +00001058 charset = "cp437";
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001059 }
Victor Stinnerd36c8212010-10-18 12:13:46 +00001060 nameobj = PyUnicode_Decode(name, name_size, charset, NULL);
Victor Stinner4ee65a92011-01-22 10:30:29 +00001061 if (nameobj == NULL) {
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001062 if (bootstrap) {
Victor Stinner4ee65a92011-01-22 10:30:29 +00001063 PyErr_Format(PyExc_NotImplementedError,
1064 "bootstrap issue: python%i%i.zip contains non-ASCII "
1065 "filenames without the unicode flag",
1066 PY_MAJOR_VERSION, PY_MINOR_VERSION);
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001067 }
Victor Stinner2460a432010-08-16 17:54:28 +00001068 goto error;
Victor Stinner4ee65a92011-01-22 10:30:29 +00001069 }
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001070 if (PyUnicode_READY(nameobj) == -1) {
Stefan Krah000fde92012-08-20 14:14:49 +02001071 goto error;
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001072 }
Martin v. Löwisa72e78b2011-10-31 08:33:37 +01001073 path = PyUnicode_FromFormat("%U%c%U", archive, SEP, nameobj);
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001074 if (path == NULL) {
Victor Stinner2460a432010-08-16 17:54:28 +00001075 goto error;
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001076 }
1077 t = Py_BuildValue("NHIIkHHI", path, compress, data_size,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001078 file_size, file_offset, time, date, crc);
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001079 if (t == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001080 goto error;
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001081 }
Victor Stinner2460a432010-08-16 17:54:28 +00001082 err = PyDict_SetItem(files, nameobj, t);
1083 Py_CLEAR(nameobj);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001084 Py_DECREF(t);
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001085 if (err != 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001086 goto error;
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001087 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001088 count++;
1089 }
Benjamin Peterson34c15402014-02-16 14:17:28 -05001090 fclose(fp);
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001091 if (Py_VerboseFlag) {
1092 PySys_FormatStderr("# zipimport: found %u names in %R\n",
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001093 count, archive);
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001094 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001095 return files;
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001096
1097eof_error:
1098 set_file_error(archive, !ferror(fp));
1099 goto error;
1100
Serhiy Storchaka0e6b7b52013-02-16 17:43:45 +02001101file_error:
Jesus Cea09bf7a72012-10-03 02:13:05 +02001102 PyErr_Format(ZipImportError, "can't read Zip file: %R", archive);
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001103 goto error;
1104
1105invalid_header:
1106 assert(errmsg != NULL);
1107 PyErr_Format(ZipImportError, "%s: %R", errmsg, archive);
1108 goto error;
1109
Just van Rossum52e14d62002-12-30 22:08:05 +00001110error:
Benjamin Peterson34c15402014-02-16 14:17:28 -05001111 fclose(fp);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001112 Py_XDECREF(files);
Victor Stinner2460a432010-08-16 17:54:28 +00001113 Py_XDECREF(nameobj);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001114 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +00001115}
1116
1117/* Return the zlib.decompress function object, or NULL if zlib couldn't
1118 be imported. The function is cached when found, so subsequent calls
Victor Stinner4925cde2011-05-20 00:16:09 +02001119 don't import zlib again. */
Just van Rossum52e14d62002-12-30 22:08:05 +00001120static PyObject *
1121get_decompress_func(void)
1122{
Victor Stinner4925cde2011-05-20 00:16:09 +02001123 static int importing_zlib = 0;
1124 PyObject *zlib;
1125 PyObject *decompress;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02001126 _Py_IDENTIFIER(decompress);
Just van Rossum52e14d62002-12-30 22:08:05 +00001127
Victor Stinner4925cde2011-05-20 00:16:09 +02001128 if (importing_zlib != 0)
Xiang Zhang0710d752017-03-11 13:02:52 +08001129 /* Someone has a zlib.pyc in their Zip file;
Victor Stinner4925cde2011-05-20 00:16:09 +02001130 let's avoid a stack overflow. */
1131 return NULL;
1132 importing_zlib = 1;
1133 zlib = PyImport_ImportModuleNoBlock("zlib");
1134 importing_zlib = 0;
1135 if (zlib != NULL) {
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02001136 decompress = _PyObject_GetAttrId(zlib,
1137 &PyId_decompress);
Victor Stinner4925cde2011-05-20 00:16:09 +02001138 Py_DECREF(zlib);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001139 }
Victor Stinner4925cde2011-05-20 00:16:09 +02001140 else {
1141 PyErr_Clear();
1142 decompress = NULL;
1143 }
1144 if (Py_VerboseFlag)
1145 PySys_WriteStderr("# zipimport: zlib %s\n",
1146 zlib != NULL ? "available": "UNAVAILABLE");
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001147 return decompress;
Just van Rossum52e14d62002-12-30 22:08:05 +00001148}
1149
Benjamin Peterson34c15402014-02-16 14:17:28 -05001150/* Given a path to a Zip file and a toc_entry, return the (uncompressed)
Just van Rossum52e14d62002-12-30 22:08:05 +00001151 data as a new reference. */
1152static PyObject *
Benjamin Peterson34c15402014-02-16 14:17:28 -05001153get_data(PyObject *archive, PyObject *toc_entry)
Just van Rossum52e14d62002-12-30 22:08:05 +00001154{
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001155 PyObject *raw_data = NULL, *data, *decompress;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001156 char *buf;
Benjamin Peterson34c15402014-02-16 14:17:28 -05001157 FILE *fp;
Victor Stinner60fe8d92010-08-16 23:48:11 +00001158 PyObject *datapath;
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001159 unsigned short compress, time, date;
1160 unsigned int crc;
1161 Py_ssize_t data_size, file_size, bytes_size;
1162 long file_offset, header_size;
1163 unsigned char buffer[30];
1164 const char *errmsg = NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +00001165
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001166 if (!PyArg_ParseTuple(toc_entry, "OHnnlHHI", &datapath, &compress,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001167 &data_size, &file_size, &file_offset, &time,
1168 &date, &crc)) {
1169 return NULL;
1170 }
Benjamin Petersonb1db7582016-01-21 22:02:46 -08001171 if (data_size < 0) {
1172 PyErr_Format(ZipImportError, "negative data size");
1173 return NULL;
1174 }
Just van Rossum52e14d62002-12-30 22:08:05 +00001175
Benjamin Peterson34c15402014-02-16 14:17:28 -05001176 fp = _Py_fopen_obj(archive, "rb");
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001177 if (!fp) {
Benjamin Peterson34c15402014-02-16 14:17:28 -05001178 return NULL;
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001179 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001180 /* Check to make sure the local file header is correct */
Jesus Cea09bf7a72012-10-03 02:13:05 +02001181 if (fseek(fp, file_offset, 0) == -1) {
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001182 goto file_error;
Jesus Cea09bf7a72012-10-03 02:13:05 +02001183 }
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001184 if (fread(buffer, 1, 30, fp) != 30) {
1185 goto eof_error;
1186 }
1187 if (get_uint32(buffer) != 0x04034B50u) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001188 /* Bad: Local File Header */
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001189 errmsg = "bad local file header";
1190 goto invalid_header;
Jesus Cea09bf7a72012-10-03 02:13:05 +02001191 }
1192
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001193 header_size = (unsigned int)30 +
1194 get_uint16(buffer + 26) /* file name */ +
1195 get_uint16(buffer + 28) /* extra field */;
1196 if (file_offset > LONG_MAX - header_size) {
1197 errmsg = "bad local file header size";
1198 goto invalid_header;
Victor Stinner73660af2013-10-29 01:43:44 +01001199 }
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001200 file_offset += header_size; /* Start of file data */
Just van Rossum52e14d62002-12-30 22:08:05 +00001201
Benjamin Petersonc4032da2016-01-20 22:23:44 -08001202 if (data_size > LONG_MAX - 1) {
1203 fclose(fp);
1204 PyErr_NoMemory();
1205 return NULL;
1206 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001207 bytes_size = compress == 0 ? data_size : data_size + 1;
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001208 if (bytes_size == 0) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001209 bytes_size++;
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001210 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001211 raw_data = PyBytes_FromStringAndSize((char *)NULL, bytes_size);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001212 if (raw_data == NULL) {
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001213 goto error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001214 }
1215 buf = PyBytes_AsString(raw_data);
Just van Rossum52e14d62002-12-30 22:08:05 +00001216
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001217 if (fseek(fp, file_offset, 0) == -1) {
1218 goto file_error;
Jesus Cea09bf7a72012-10-03 02:13:05 +02001219 }
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001220 if (fread(buf, 1, data_size, fp) != (size_t)data_size) {
Serhiy Storchaka55fe1ae2017-04-16 10:46:38 +03001221 PyErr_SetString(PyExc_OSError,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001222 "zipimport: can't read data");
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001223 goto error;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001224 }
Just van Rossum52e14d62002-12-30 22:08:05 +00001225
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001226 fclose(fp);
1227 fp = NULL;
1228
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001229 if (compress != 0) {
1230 buf[data_size] = 'Z'; /* saw this in zipfile.py */
1231 data_size++;
1232 }
1233 buf[data_size] = '\0';
Just van Rossum52e14d62002-12-30 22:08:05 +00001234
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001235 if (compress == 0) { /* data is not compressed */
1236 data = PyBytes_FromStringAndSize(buf, data_size);
1237 Py_DECREF(raw_data);
1238 return data;
1239 }
1240
1241 /* Decompress with zlib */
1242 decompress = get_decompress_func();
1243 if (decompress == NULL) {
1244 PyErr_SetString(ZipImportError,
1245 "can't decompress data; "
1246 "zlib not available");
1247 goto error;
1248 }
1249 data = PyObject_CallFunction(decompress, "Oi", raw_data, -15);
Victor Stinner4925cde2011-05-20 00:16:09 +02001250 Py_DECREF(decompress);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001251 Py_DECREF(raw_data);
Oren Milman01c6a882017-09-29 21:34:31 +03001252 if (data != NULL && !PyBytes_Check(data)) {
1253 PyErr_Format(PyExc_TypeError,
1254 "zlib.decompress() must return a bytes object, not "
1255 "%.200s",
1256 Py_TYPE(data)->tp_name);
1257 Py_DECREF(data);
1258 return NULL;
1259 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001260 return data;
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001261
1262eof_error:
1263 set_file_error(archive, !ferror(fp));
1264 goto error;
1265
1266file_error:
1267 PyErr_Format(ZipImportError, "can't read Zip file: %R", archive);
1268 goto error;
1269
1270invalid_header:
1271 assert(errmsg != NULL);
1272 PyErr_Format(ZipImportError, "%s: %R", errmsg, archive);
1273 goto error;
1274
1275error:
1276 if (fp != NULL) {
1277 fclose(fp);
1278 }
1279 Py_XDECREF(raw_data);
1280 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +00001281}
1282
1283/* Lenient date/time comparison function. The precision of the mtime
1284 in the archive is lower than the mtime stored in a .pyc: we
1285 must allow a difference of at most one second. */
1286static int
1287eq_mtime(time_t t1, time_t t2)
1288{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001289 time_t d = t1 - t2;
1290 if (d < 0)
1291 d = -d;
1292 /* dostime only stores even seconds, so be lenient */
1293 return d <= 1;
Just van Rossum52e14d62002-12-30 22:08:05 +00001294}
1295
Xiang Zhang0710d752017-03-11 13:02:52 +08001296/* Given the contents of a .pyc file in a buffer, unmarshal the data
Just van Rossum52e14d62002-12-30 22:08:05 +00001297 and return the code object. Return None if it the magic word doesn't
1298 match (we do this instead of raising an exception as we fall back
1299 to .py if available and we don't want to mask other errors).
1300 Returns a new reference. */
1301static PyObject *
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001302unmarshal_code(PyObject *pathname, PyObject *data, time_t mtime)
Just van Rossum52e14d62002-12-30 22:08:05 +00001303{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001304 PyObject *code;
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001305 unsigned char *buf = (unsigned char *)PyBytes_AsString(data);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001306 Py_ssize_t size = PyBytes_Size(data);
Just van Rossum52e14d62002-12-30 22:08:05 +00001307
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001308 if (size < 12) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001309 PyErr_SetString(ZipImportError,
1310 "bad pyc data");
1311 return NULL;
1312 }
Just van Rossum52e14d62002-12-30 22:08:05 +00001313
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001314 if (get_uint32(buf) != (unsigned int)PyImport_GetMagicNumber()) {
1315 if (Py_VerboseFlag) {
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001316 PySys_FormatStderr("# %R has bad magic\n",
1317 pathname);
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001318 }
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02001319 Py_RETURN_NONE; /* signal caller to try alternative */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001320 }
Just van Rossum52e14d62002-12-30 22:08:05 +00001321
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001322 if (mtime != 0 && !eq_mtime(get_uint32(buf + 4), mtime)) {
1323 if (Py_VerboseFlag) {
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001324 PySys_FormatStderr("# %R has bad mtime\n",
1325 pathname);
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001326 }
Serhiy Storchaka228b12e2017-01-23 09:47:21 +02001327 Py_RETURN_NONE; /* signal caller to try alternative */
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001328 }
Just van Rossum52e14d62002-12-30 22:08:05 +00001329
Antoine Pitrou5136ac02012-01-13 18:52:16 +01001330 /* XXX the pyc's size field is ignored; timestamp collisions are probably
1331 unimportant with zip files. */
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001332 code = PyMarshal_ReadObjectFromString((char *)buf + 12, size - 12);
1333 if (code == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001334 return NULL;
Serhiy Storchakad5db5732016-01-28 21:30:16 +02001335 }
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001336 if (!PyCode_Check(code)) {
1337 Py_DECREF(code);
1338 PyErr_Format(PyExc_TypeError,
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001339 "compiled module %R is not a code object",
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001340 pathname);
1341 return NULL;
1342 }
1343 return code;
Just van Rossum52e14d62002-12-30 22:08:05 +00001344}
1345
Martin Panter0be894b2016-09-07 12:03:06 +00001346/* Replace any occurrences of "\r\n?" in the input string with "\n".
Just van Rossum52e14d62002-12-30 22:08:05 +00001347 This converts DOS and Mac line endings to Unix line endings.
1348 Also append a trailing "\n" to be compatible with
1349 PyParser_SimpleParseFile(). Returns a new reference. */
1350static PyObject *
1351normalize_line_endings(PyObject *source)
1352{
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001353 char *buf, *q, *p;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001354 PyObject *fixed_source;
1355 int len = 0;
Just van Rossum52e14d62002-12-30 22:08:05 +00001356
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001357 p = PyBytes_AsString(source);
1358 if (p == NULL) {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001359 return PyBytes_FromStringAndSize("\n\0", 2);
1360 }
Thomas Wouters00ee7ba2006-08-21 19:07:27 +00001361
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001362 /* one char extra for trailing \n and one for terminating \0 */
1363 buf = (char *)PyMem_Malloc(PyBytes_Size(source) + 2);
1364 if (buf == NULL) {
1365 PyErr_SetString(PyExc_MemoryError,
1366 "zipimport: no memory to allocate "
1367 "source buffer");
1368 return NULL;
1369 }
1370 /* replace "\r\n?" by "\n" */
1371 for (q = buf; *p != '\0'; p++) {
1372 if (*p == '\r') {
1373 *q++ = '\n';
1374 if (*(p + 1) == '\n')
1375 p++;
1376 }
1377 else
1378 *q++ = *p;
1379 len++;
1380 }
1381 *q++ = '\n'; /* add trailing \n */
1382 *q = '\0';
1383 fixed_source = PyBytes_FromStringAndSize(buf, len + 2);
1384 PyMem_Free(buf);
1385 return fixed_source;
Just van Rossum52e14d62002-12-30 22:08:05 +00001386}
1387
1388/* Given a string buffer containing Python source code, compile it
Brett Cannon83358c92013-06-20 21:30:32 -04001389 and return a code object as a new reference. */
Just van Rossum52e14d62002-12-30 22:08:05 +00001390static PyObject *
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001391compile_source(PyObject *pathname, PyObject *source)
Just van Rossum52e14d62002-12-30 22:08:05 +00001392{
Steve Dower8dcc48e2016-09-09 17:27:33 -07001393 PyObject *code, *fixed_source;
Just van Rossum52e14d62002-12-30 22:08:05 +00001394
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001395 fixed_source = normalize_line_endings(source);
1396 if (fixed_source == NULL) {
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001397 return NULL;
1398 }
1399
Steve Dower8dcc48e2016-09-09 17:27:33 -07001400 code = Py_CompileStringObject(PyBytes_AsString(fixed_source),
Berker Peksag4aa74c42016-09-14 08:09:48 +03001401 pathname, Py_file_input, NULL, -1);
Steve Dower8dcc48e2016-09-09 17:27:33 -07001402
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001403 Py_DECREF(fixed_source);
1404 return code;
Just van Rossum52e14d62002-12-30 22:08:05 +00001405}
1406
1407/* Convert the date/time values found in the Zip archive to a value
1408 that's compatible with the time stamp stored in .pyc files. */
Neal Norwitz29fd2ba2003-03-23 13:21:03 +00001409static time_t
1410parse_dostime(int dostime, int dosdate)
Just van Rossum52e14d62002-12-30 22:08:05 +00001411{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001412 struct tm stm;
Just van Rossum52e14d62002-12-30 22:08:05 +00001413
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001414 memset((void *) &stm, '\0', sizeof(stm));
Christian Heimes679db4a2008-01-18 09:56:22 +00001415
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001416 stm.tm_sec = (dostime & 0x1f) * 2;
1417 stm.tm_min = (dostime >> 5) & 0x3f;
1418 stm.tm_hour = (dostime >> 11) & 0x1f;
1419 stm.tm_mday = dosdate & 0x1f;
1420 stm.tm_mon = ((dosdate >> 5) & 0x0f) - 1;
1421 stm.tm_year = ((dosdate >> 9) & 0x7f) + 80;
1422 stm.tm_isdst = -1; /* wday/yday is ignored */
Just van Rossum52e14d62002-12-30 22:08:05 +00001423
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001424 return mktime(&stm);
Just van Rossum52e14d62002-12-30 22:08:05 +00001425}
1426
Brett Cannonf299abd2015-04-13 14:21:02 -04001427/* Given a path to a .pyc file in the archive, return the
Ezio Melotti13925002011-03-16 11:05:33 +02001428 modification time of the matching .py file, or 0 if no source
Just van Rossum52e14d62002-12-30 22:08:05 +00001429 is available. */
1430static time_t
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001431get_mtime_of_source(ZipImporter *self, PyObject *path)
Just van Rossum52e14d62002-12-30 22:08:05 +00001432{
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001433 PyObject *toc_entry, *stripped;
1434 time_t mtime;
1435
Xiang Zhang0710d752017-03-11 13:02:52 +08001436 /* strip 'c' from *.pyc */
Martin v. Löwisd63a3b82011-09-28 07:41:54 +02001437 if (PyUnicode_READY(path) == -1)
1438 return (time_t)-1;
1439 stripped = PyUnicode_FromKindAndData(PyUnicode_KIND(path),
1440 PyUnicode_DATA(path),
1441 PyUnicode_GET_LENGTH(path) - 1);
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001442 if (stripped == NULL)
1443 return (time_t)-1;
1444
1445 toc_entry = PyDict_GetItem(self->files, stripped);
1446 Py_DECREF(stripped);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001447 if (toc_entry != NULL && PyTuple_Check(toc_entry) &&
1448 PyTuple_Size(toc_entry) == 8) {
1449 /* fetch the time stamp of the .py file for comparison
1450 with an embedded pyc time stamp */
1451 int time, date;
1452 time = PyLong_AsLong(PyTuple_GetItem(toc_entry, 5));
1453 date = PyLong_AsLong(PyTuple_GetItem(toc_entry, 6));
1454 mtime = parse_dostime(time, date);
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001455 } else
1456 mtime = 0;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001457 return mtime;
Just van Rossum52e14d62002-12-30 22:08:05 +00001458}
1459
1460/* Return the code object for the module named by 'fullname' from the
1461 Zip archive as a new reference. */
1462static PyObject *
Benjamin Peterson34c15402014-02-16 14:17:28 -05001463get_code_from_data(ZipImporter *self, int ispackage, int isbytecode,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001464 time_t mtime, PyObject *toc_entry)
Just van Rossum52e14d62002-12-30 22:08:05 +00001465{
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001466 PyObject *data, *modpath, *code;
Just van Rossum52e14d62002-12-30 22:08:05 +00001467
Benjamin Peterson34c15402014-02-16 14:17:28 -05001468 data = get_data(self->archive, toc_entry);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001469 if (data == NULL)
1470 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +00001471
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001472 modpath = PyTuple_GetItem(toc_entry, 0);
Victor Stinner2a94f4c2010-10-18 12:15:34 +00001473 if (isbytecode)
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001474 code = unmarshal_code(modpath, data, mtime);
Victor Stinner2a94f4c2010-10-18 12:15:34 +00001475 else
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001476 code = compile_source(modpath, data);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001477 Py_DECREF(data);
1478 return code;
Just van Rossum52e14d62002-12-30 22:08:05 +00001479}
1480
Ezio Melotti42da6632011-03-15 05:18:48 +02001481/* Get the code object associated with the module specified by
Just van Rossum52e14d62002-12-30 22:08:05 +00001482 'fullname'. */
1483static PyObject *
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001484get_module_code(ZipImporter *self, PyObject *fullname,
Victor Stinner08654e12010-10-18 12:09:02 +00001485 int *p_ispackage, PyObject **p_modpath)
Just van Rossum52e14d62002-12-30 22:08:05 +00001486{
Gregory P. Smith95c7c462011-05-21 05:19:42 -07001487 PyObject *code = NULL, *toc_entry, *subname;
Victor Stinner9a2261a2011-05-26 13:59:41 +02001488 PyObject *path, *fullpath = NULL;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001489 struct st_zip_searchorder *zso;
Just van Rossum52e14d62002-12-30 22:08:05 +00001490
Oren Milmandb60a5b2017-10-20 23:42:35 +03001491 if (self->prefix == NULL) {
1492 PyErr_SetString(PyExc_ValueError,
1493 "zipimporter.__init__() wasn't called");
1494 return NULL;
1495 }
1496
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001497 subname = get_subname(fullname);
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001498 if (subname == NULL)
1499 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +00001500
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001501 path = make_filename(self->prefix, subname);
1502 Py_DECREF(subname);
1503 if (path == NULL)
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001504 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +00001505
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001506 for (zso = zip_searchorder; *zso->suffix; zso++) {
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001507 code = NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +00001508
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001509 fullpath = PyUnicode_FromFormat("%U%s", path, zso->suffix);
1510 if (fullpath == NULL)
1511 goto exit;
1512
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001513 if (Py_VerboseFlag > 1)
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001514 PySys_FormatStderr("# trying %U%c%U\n",
1515 self->archive, (int)SEP, fullpath);
1516 toc_entry = PyDict_GetItem(self->files, fullpath);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001517 if (toc_entry != NULL) {
1518 time_t mtime = 0;
1519 int ispackage = zso->type & IS_PACKAGE;
1520 int isbytecode = zso->type & IS_BYTECODE;
Just van Rossum52e14d62002-12-30 22:08:05 +00001521
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001522 if (isbytecode) {
1523 mtime = get_mtime_of_source(self, fullpath);
1524 if (mtime == (time_t)-1 && PyErr_Occurred()) {
1525 goto exit;
1526 }
1527 }
1528 Py_CLEAR(fullpath);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001529 if (p_ispackage != NULL)
1530 *p_ispackage = ispackage;
Benjamin Peterson34c15402014-02-16 14:17:28 -05001531 code = get_code_from_data(self, ispackage,
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001532 isbytecode, mtime,
1533 toc_entry);
1534 if (code == Py_None) {
1535 /* bad magic number or non-matching mtime
1536 in byte code, try next */
1537 Py_DECREF(code);
1538 continue;
1539 }
Victor Stinner08654e12010-10-18 12:09:02 +00001540 if (code != NULL && p_modpath != NULL) {
1541 *p_modpath = PyTuple_GetItem(toc_entry, 0);
1542 Py_INCREF(*p_modpath);
1543 }
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001544 goto exit;
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001545 }
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001546 else
1547 Py_CLEAR(fullpath);
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001548 }
Victor Stinnerf6b563a2011-03-14 20:46:50 -04001549 PyErr_Format(ZipImportError, "can't find module %R", fullname);
1550exit:
1551 Py_DECREF(path);
1552 Py_XDECREF(fullpath);
1553 return code;
Just van Rossum52e14d62002-12-30 22:08:05 +00001554}
1555
1556
1557/* Module init */
1558
1559PyDoc_STRVAR(zipimport_doc,
1560"zipimport provides support for importing Python modules from Zip archives.\n\
1561\n\
1562This module exports three objects:\n\
1563- zipimporter: a class; its constructor takes a path to a Zip archive.\n\
Fredrik Lundhb84b35f2006-01-15 15:00:40 +00001564- ZipImportError: exception raised by zipimporter objects. It's a\n\
Just van Rossum52e14d62002-12-30 22:08:05 +00001565 subclass of ImportError, so it can be caught as ImportError, too.\n\
1566- _zip_directory_cache: a dict, mapping archive paths to zip directory\n\
1567 info dicts, as used in zipimporter._files.\n\
1568\n\
1569It is usually not needed to use the zipimport module explicitly; it is\n\
1570used by the builtin import mechanism for sys.path items that are paths\n\
1571to Zip archives.");
1572
Martin v. Löwis1a214512008-06-11 05:26:20 +00001573static struct PyModuleDef zipimportmodule = {
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001574 PyModuleDef_HEAD_INIT,
1575 "zipimport",
1576 zipimport_doc,
1577 -1,
1578 NULL,
1579 NULL,
1580 NULL,
1581 NULL,
1582 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +00001583};
1584
Just van Rossum52e14d62002-12-30 22:08:05 +00001585PyMODINIT_FUNC
Martin v. Löwis1a214512008-06-11 05:26:20 +00001586PyInit_zipimport(void)
Just van Rossum52e14d62002-12-30 22:08:05 +00001587{
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001588 PyObject *mod;
Just van Rossum52e14d62002-12-30 22:08:05 +00001589
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001590 if (PyType_Ready(&ZipImporter_Type) < 0)
1591 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +00001592
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001593 /* Correct directory separator */
1594 zip_searchorder[0].suffix[0] = SEP;
1595 zip_searchorder[1].suffix[0] = SEP;
Just van Rossum52e14d62002-12-30 22:08:05 +00001596
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001597 mod = PyModule_Create(&zipimportmodule);
1598 if (mod == NULL)
1599 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +00001600
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001601 ZipImportError = PyErr_NewException("zipimport.ZipImportError",
1602 PyExc_ImportError, NULL);
1603 if (ZipImportError == NULL)
1604 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +00001605
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001606 Py_INCREF(ZipImportError);
1607 if (PyModule_AddObject(mod, "ZipImportError",
1608 ZipImportError) < 0)
1609 return NULL;
Just van Rossum52e14d62002-12-30 22:08:05 +00001610
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001611 Py_INCREF(&ZipImporter_Type);
1612 if (PyModule_AddObject(mod, "zipimporter",
1613 (PyObject *)&ZipImporter_Type) < 0)
1614 return NULL;
Just van Rossumf8b6de12002-12-31 09:51:59 +00001615
Antoine Pitrouf95a1b32010-05-09 15:52:27 +00001616 zip_directory_cache = PyDict_New();
1617 if (zip_directory_cache == NULL)
1618 return NULL;
1619 Py_INCREF(zip_directory_cache);
1620 if (PyModule_AddObject(mod, "_zip_directory_cache",
1621 zip_directory_cache) < 0)
1622 return NULL;
1623 return mod;
Just van Rossum52e14d62002-12-30 22:08:05 +00001624}