zipimport.c revision f299abdafa0f2b6eb7abae274861b19b361c96bc
1#include "Python.h"
2#include "structmember.h"
3#include "osdefs.h"
4#include "marshal.h"
5#include <time.h>
6
7
8#define IS_SOURCE   0x0
9#define IS_BYTECODE 0x1
10#define IS_PACKAGE  0x2
11
12struct st_zip_searchorder {
13    char suffix[14];
14    int type;
15};
16
17#ifdef ALTSEP
18_Py_IDENTIFIER(replace);
19#endif
20
21/* zip_searchorder defines how we search for a module in the Zip
22   archive: we first search for a package __init__, then for
23   non-package .pyc, and .py entries. The .pyc entries
24   are swapped by initzipimport() if we run in optimized mode. Also,
25   '/' is replaced by SEP there. */
26static struct st_zip_searchorder zip_searchorder[] = {
27    {"/__init__.pyc", IS_PACKAGE | IS_BYTECODE},
28    {"/__init__.py", IS_PACKAGE | IS_SOURCE},
29    {".pyc", IS_BYTECODE},
30    {".py", IS_SOURCE},
31    {"", 0}
32};
33
34/* zipimporter object definition and support */
35
36typedef struct _zipimporter ZipImporter;
37
38struct _zipimporter {
39    PyObject_HEAD
40    PyObject *archive;  /* pathname of the Zip archive,
41                           decoded from the filesystem encoding */
42    PyObject *prefix;   /* file prefix: "a/sub/directory/",
43                           encoded to the filesystem encoding */
44    PyObject *files;    /* dict with file info {path: toc_entry} */
45};
46
47static PyObject *ZipImportError;
48/* read_directory() cache */
49static PyObject *zip_directory_cache = NULL;
50
51/* forward decls */
52static PyObject *read_directory(PyObject *archive);
53static PyObject *get_data(PyObject *archive, PyObject *toc_entry);
54static PyObject *get_module_code(ZipImporter *self, PyObject *fullname,
55                                 int *p_ispackage, PyObject **p_modpath);
56
57
58#define ZipImporter_Check(op) PyObject_TypeCheck(op, &ZipImporter_Type)
59
60
61/* zipimporter.__init__
62   Split the "subdirectory" from the Zip archive path, lookup a matching
63   entry in sys.path_importer_cache, fetch the file directory from there
64   if found, or else read it from the archive. */
65static int
66zipimporter_init(ZipImporter *self, PyObject *args, PyObject *kwds)
67{
68    PyObject *path, *files, *tmp;
69    PyObject *filename = NULL;
70    Py_ssize_t len, flen;
71
72    if (!_PyArg_NoKeywords("zipimporter()", kwds))
73        return -1;
74
75    if (!PyArg_ParseTuple(args, "O&:zipimporter",
76                          PyUnicode_FSDecoder, &path))
77        return -1;
78
79    if (PyUnicode_READY(path) == -1)
80        return -1;
81
82    len = PyUnicode_GET_LENGTH(path);
83    if (len == 0) {
84        PyErr_SetString(ZipImportError, "archive path is empty");
85        goto error;
86    }
87
88#ifdef ALTSEP
89    tmp = _PyObject_CallMethodId(path, &PyId_replace, "CC", ALTSEP, SEP);
90    if (!tmp)
91        goto error;
92    Py_DECREF(path);
93    path = tmp;
94#endif
95
96    filename = path;
97    Py_INCREF(filename);
98    flen = len;
99    for (;;) {
100        struct stat statbuf;
101        int rv;
102
103        rv = _Py_stat(filename, &statbuf);
104        if (rv == -2)
105            goto error;
106        if (rv == 0) {
107            /* it exists */
108            if (!S_ISREG(statbuf.st_mode))
109                /* it's a not file */
110                Py_CLEAR(filename);
111            break;
112        }
113        Py_CLEAR(filename);
114        /* back up one path element */
115        flen = PyUnicode_FindChar(path, SEP, 0, flen, -1);
116        if (flen == -1)
117            break;
118        filename = PyUnicode_Substring(path, 0, flen);
119        if (filename == NULL)
120            goto error;
121    }
122    if (filename == NULL) {
123        PyErr_SetString(ZipImportError, "not a Zip file");
124        goto error;
125    }
126
127    if (PyUnicode_READY(filename) < 0)
128        goto error;
129
130    files = PyDict_GetItem(zip_directory_cache, filename);
131    if (files == NULL) {
132        files = read_directory(filename);
133        if (files == NULL)
134            goto error;
135        if (PyDict_SetItem(zip_directory_cache, filename, files) != 0)
136            goto error;
137    }
138    else
139        Py_INCREF(files);
140    self->files = files;
141
142    /* Transfer reference */
143    self->archive = filename;
144    filename = NULL;
145
146    /* Check if there is a prefix directory following the filename. */
147    if (flen != len) {
148        tmp = PyUnicode_Substring(path, flen+1,
149                                  PyUnicode_GET_LENGTH(path));
150        if (tmp == NULL)
151            goto error;
152        self->prefix = tmp;
153        if (PyUnicode_READ_CHAR(path, len-1) != SEP) {
154            /* add trailing SEP */
155            tmp = PyUnicode_FromFormat("%U%c", self->prefix, SEP);
156            if (tmp == NULL)
157                goto error;
158            Py_DECREF(self->prefix);
159            self->prefix = tmp;
160        }
161    }
162    else
163        self->prefix = PyUnicode_New(0, 0);
164    Py_DECREF(path);
165    return 0;
166
167error:
168    Py_DECREF(path);
169    Py_XDECREF(filename);
170    return -1;
171}
172
173/* GC support. */
174static int
175zipimporter_traverse(PyObject *obj, visitproc visit, void *arg)
176{
177    ZipImporter *self = (ZipImporter *)obj;
178    Py_VISIT(self->files);
179    return 0;
180}
181
182static void
183zipimporter_dealloc(ZipImporter *self)
184{
185    PyObject_GC_UnTrack(self);
186    Py_XDECREF(self->archive);
187    Py_XDECREF(self->prefix);
188    Py_XDECREF(self->files);
189    Py_TYPE(self)->tp_free((PyObject *)self);
190}
191
192static PyObject *
193zipimporter_repr(ZipImporter *self)
194{
195    if (self->archive == NULL)
196        return PyUnicode_FromString("<zipimporter object \"???\">");
197    else if (self->prefix != NULL && PyUnicode_GET_LENGTH(self->prefix) != 0)
198        return PyUnicode_FromFormat("<zipimporter object \"%U%c%U\">",
199                                    self->archive, SEP, self->prefix);
200    else
201        return PyUnicode_FromFormat("<zipimporter object \"%U\">",
202                                    self->archive);
203}
204
205/* return fullname.split(".")[-1] */
206static PyObject *
207get_subname(PyObject *fullname)
208{
209    Py_ssize_t len, dot;
210    if (PyUnicode_READY(fullname) < 0)
211        return NULL;
212    len = PyUnicode_GET_LENGTH(fullname);
213    dot = PyUnicode_FindChar(fullname, '.', 0, len, -1);
214    if (dot == -1) {
215        Py_INCREF(fullname);
216        return fullname;
217    } else
218        return PyUnicode_Substring(fullname, dot+1, len);
219}
220
221/* Given a (sub)modulename, write the potential file path in the
222   archive (without extension) to the path buffer. Return the
223   length of the resulting string.
224
225   return self.prefix + name.replace('.', os.sep) */
226static PyObject*
227make_filename(PyObject *prefix, PyObject *name)
228{
229    PyObject *pathobj;
230    Py_UCS4 *p, *buf;
231    Py_ssize_t len;
232
233    len = PyUnicode_GET_LENGTH(prefix) + PyUnicode_GET_LENGTH(name) + 1;
234    p = buf = PyMem_New(Py_UCS4, len);
235    if (buf == NULL) {
236        PyErr_NoMemory();
237        return NULL;
238    }
239
240    if (!PyUnicode_AsUCS4(prefix, p, len, 0)) {
241        PyMem_Free(buf);
242        return NULL;
243    }
244    p += PyUnicode_GET_LENGTH(prefix);
245    len -= PyUnicode_GET_LENGTH(prefix);
246    if (!PyUnicode_AsUCS4(name, p, len, 1)) {
247        PyMem_Free(buf);
248        return NULL;
249    }
250    for (; *p; p++) {
251        if (*p == '.')
252            *p = SEP;
253    }
254    pathobj = PyUnicode_FromKindAndData(PyUnicode_4BYTE_KIND,
255                                        buf, p-buf);
256    PyMem_Free(buf);
257    return pathobj;
258}
259
260enum zi_module_info {
261    MI_ERROR,
262    MI_NOT_FOUND,
263    MI_MODULE,
264    MI_PACKAGE
265};
266
267/* Does this path represent a directory?
268   on error, return < 0
269   if not a dir, return 0
270   if a dir, return 1
271*/
272static int
273check_is_directory(ZipImporter *self, PyObject* prefix, PyObject *path)
274{
275    PyObject *dirpath;
276    int res;
277
278    /* See if this is a "directory". If so, it's eligible to be part
279       of a namespace package. We test by seeing if the name, with an
280       appended path separator, exists. */
281    dirpath = PyUnicode_FromFormat("%U%U%c", prefix, path, SEP);
282    if (dirpath == NULL)
283        return -1;
284    /* If dirpath is present in self->files, we have a directory. */
285    res = PyDict_Contains(self->files, dirpath);
286    Py_DECREF(dirpath);
287    return res;
288}
289
290/* Return some information about a module. */
291static enum zi_module_info
292get_module_info(ZipImporter *self, PyObject *fullname)
293{
294    PyObject *subname;
295    PyObject *path, *fullpath, *item;
296    struct st_zip_searchorder *zso;
297
298    subname = get_subname(fullname);
299    if (subname == NULL)
300        return MI_ERROR;
301
302    path = make_filename(self->prefix, subname);
303    Py_DECREF(subname);
304    if (path == NULL)
305        return MI_ERROR;
306
307    for (zso = zip_searchorder; *zso->suffix; zso++) {
308        fullpath = PyUnicode_FromFormat("%U%s", path, zso->suffix);
309        if (fullpath == NULL) {
310            Py_DECREF(path);
311            return MI_ERROR;
312        }
313        item = PyDict_GetItem(self->files, fullpath);
314        Py_DECREF(fullpath);
315        if (item != NULL) {
316            Py_DECREF(path);
317            if (zso->type & IS_PACKAGE)
318                return MI_PACKAGE;
319            else
320                return MI_MODULE;
321        }
322    }
323    Py_DECREF(path);
324    return MI_NOT_FOUND;
325}
326
327typedef enum {
328    FL_ERROR,
329    FL_NOT_FOUND,
330    FL_MODULE_FOUND,
331    FL_NS_FOUND
332} find_loader_result;
333
334/* The guts of "find_loader" and "find_module". Return values:
335   -1: error
336    0: no loader or namespace portions found
337    1: module/package found
338    2: namespace portion found: *namespace_portion will point to the name
339*/
340static find_loader_result
341find_loader(ZipImporter *self, PyObject *fullname, PyObject **namespace_portion)
342{
343    enum zi_module_info mi;
344
345    *namespace_portion = NULL;
346
347    mi = get_module_info(self, fullname);
348    if (mi == MI_ERROR)
349        return FL_ERROR;
350    if (mi == MI_NOT_FOUND) {
351        /* Not a module or regular package. See if this is a directory, and
352           therefore possibly a portion of a namespace package. */
353        int is_dir = check_is_directory(self, self->prefix, fullname);
354        if (is_dir < 0)
355            return -1;
356        if (is_dir) {
357            /* This is possibly a portion of a namespace
358               package. Return the string representing its path,
359               without a trailing separator. */
360            *namespace_portion = PyUnicode_FromFormat("%U%c%U%U",
361                                                      self->archive, SEP,
362                                                      self->prefix, fullname);
363            if (*namespace_portion == NULL)
364                return FL_ERROR;
365            return FL_NS_FOUND;
366        }
367        return FL_NOT_FOUND;
368    }
369    /* This is a module or package. */
370    return FL_MODULE_FOUND;
371}
372
373
374/* Check whether we can satisfy the import of the module named by
375   'fullname'. Return self if we can, None if we can't. */
376static PyObject *
377zipimporter_find_module(PyObject *obj, PyObject *args)
378{
379    ZipImporter *self = (ZipImporter *)obj;
380    PyObject *path = NULL;
381    PyObject *fullname;
382    PyObject *namespace_portion = NULL;
383    PyObject *result = NULL;
384
385    if (!PyArg_ParseTuple(args, "U|O:zipimporter.find_module", &fullname, &path))
386        return NULL;
387
388    switch (find_loader(self, fullname, &namespace_portion)) {
389    case FL_ERROR:
390        return NULL;
391    case FL_NS_FOUND:
392        /* A namespace portion is not allowed via find_module, so return None. */
393        Py_DECREF(namespace_portion);
394        /* FALL THROUGH */
395    case FL_NOT_FOUND:
396        result = Py_None;
397        break;
398    case FL_MODULE_FOUND:
399        result = (PyObject *)self;
400        break;
401    }
402    Py_INCREF(result);
403    return result;
404}
405
406
407/* Check whether we can satisfy the import of the module named by
408   'fullname', or whether it could be a portion of a namespace
409   package. Return self if we can load it, a string containing the
410   full path if it's a possible namespace portion, None if we
411   can't load it. */
412static PyObject *
413zipimporter_find_loader(PyObject *obj, PyObject *args)
414{
415    ZipImporter *self = (ZipImporter *)obj;
416    PyObject *path = NULL;
417    PyObject *fullname;
418    PyObject *result = NULL;
419    PyObject *namespace_portion = NULL;
420
421    if (!PyArg_ParseTuple(args, "U|O:zipimporter.find_module", &fullname, &path))
422        return NULL;
423
424    switch (find_loader(self, fullname, &namespace_portion)) {
425    case FL_ERROR:
426        return NULL;
427    case FL_NOT_FOUND:        /* Not found, return (None, []) */
428        result = Py_BuildValue("O[]", Py_None);
429        break;
430    case FL_MODULE_FOUND:     /* Return (self, []) */
431        result = Py_BuildValue("O[]", self);
432        break;
433    case FL_NS_FOUND:         /* Return (None, [namespace_portion]) */
434        result = Py_BuildValue("O[O]", Py_None, namespace_portion);
435        Py_DECREF(namespace_portion);
436        return result;
437    }
438    return result;
439}
440
441/* Load and return the module named by 'fullname'. */
442static PyObject *
443zipimporter_load_module(PyObject *obj, PyObject *args)
444{
445    ZipImporter *self = (ZipImporter *)obj;
446    PyObject *code = NULL, *mod, *dict;
447    PyObject *fullname;
448    PyObject *modpath = NULL;
449    int ispackage;
450
451    if (!PyArg_ParseTuple(args, "U:zipimporter.load_module",
452                          &fullname))
453        return NULL;
454    if (PyUnicode_READY(fullname) == -1)
455        return NULL;
456
457    code = get_module_code(self, fullname, &ispackage, &modpath);
458    if (code == NULL)
459        goto error;
460
461    mod = PyImport_AddModuleObject(fullname);
462    if (mod == NULL)
463        goto error;
464    dict = PyModule_GetDict(mod);
465
466    /* mod.__loader__ = self */
467    if (PyDict_SetItemString(dict, "__loader__", (PyObject *)self) != 0)
468        goto error;
469
470    if (ispackage) {
471        /* add __path__ to the module *before* the code gets
472           executed */
473        PyObject *pkgpath, *fullpath, *subname;
474        int err;
475
476        subname = get_subname(fullname);
477        if (subname == NULL)
478            goto error;
479
480        fullpath = PyUnicode_FromFormat("%U%c%U%U",
481                                self->archive, SEP,
482                                self->prefix, subname);
483        Py_DECREF(subname);
484        if (fullpath == NULL)
485            goto error;
486
487        pkgpath = Py_BuildValue("[N]", fullpath);
488        if (pkgpath == NULL)
489            goto error;
490        err = PyDict_SetItemString(dict, "__path__", pkgpath);
491        Py_DECREF(pkgpath);
492        if (err != 0)
493            goto error;
494    }
495    mod = PyImport_ExecCodeModuleObject(fullname, code, modpath, NULL);
496    Py_CLEAR(code);
497    if (mod == NULL)
498        goto error;
499
500    if (Py_VerboseFlag)
501        PySys_FormatStderr("import %U # loaded from Zip %U\n",
502                           fullname, modpath);
503    Py_DECREF(modpath);
504    return mod;
505error:
506    Py_XDECREF(code);
507    Py_XDECREF(modpath);
508    return NULL;
509}
510
511/* Return a string matching __file__ for the named module */
512static PyObject *
513zipimporter_get_filename(PyObject *obj, PyObject *args)
514{
515    ZipImporter *self = (ZipImporter *)obj;
516    PyObject *fullname, *code, *modpath;
517    int ispackage;
518
519    if (!PyArg_ParseTuple(args, "U:zipimporter.get_filename",
520                          &fullname))
521        return NULL;
522
523    /* Deciding the filename requires working out where the code
524       would come from if the module was actually loaded */
525    code = get_module_code(self, fullname, &ispackage, &modpath);
526    if (code == NULL)
527        return NULL;
528    Py_DECREF(code); /* Only need the path info */
529
530    return modpath;
531}
532
533/* Return a bool signifying whether the module is a package or not. */
534static PyObject *
535zipimporter_is_package(PyObject *obj, PyObject *args)
536{
537    ZipImporter *self = (ZipImporter *)obj;
538    PyObject *fullname;
539    enum zi_module_info mi;
540
541    if (!PyArg_ParseTuple(args, "U:zipimporter.is_package",
542                          &fullname))
543        return NULL;
544
545    mi = get_module_info(self, fullname);
546    if (mi == MI_ERROR)
547        return NULL;
548    if (mi == MI_NOT_FOUND) {
549        PyErr_Format(ZipImportError, "can't find module %R", fullname);
550        return NULL;
551    }
552    return PyBool_FromLong(mi == MI_PACKAGE);
553}
554
555
556static PyObject *
557zipimporter_get_data(PyObject *obj, PyObject *args)
558{
559    ZipImporter *self = (ZipImporter *)obj;
560    PyObject *path, *key;
561    PyObject *toc_entry;
562    Py_ssize_t path_start, path_len, len;
563
564    if (!PyArg_ParseTuple(args, "U:zipimporter.get_data", &path))
565        return NULL;
566
567#ifdef ALTSEP
568    path = _PyObject_CallMethodId(path, &PyId_replace, "CC", ALTSEP, SEP);
569    if (!path)
570        return NULL;
571#else
572    Py_INCREF(path);
573#endif
574    if (PyUnicode_READY(path) == -1)
575        goto error;
576
577    path_len = PyUnicode_GET_LENGTH(path);
578
579    len = PyUnicode_GET_LENGTH(self->archive);
580    path_start = 0;
581    if (PyUnicode_Tailmatch(path, self->archive, 0, len, -1)
582        && PyUnicode_READ_CHAR(path, len) == SEP) {
583        path_start = len + 1;
584    }
585
586    key = PyUnicode_Substring(path, path_start, path_len);
587    if (key == NULL)
588        goto error;
589    toc_entry = PyDict_GetItem(self->files, key);
590    if (toc_entry == NULL) {
591        PyErr_SetFromErrnoWithFilenameObject(PyExc_IOError, key);
592        Py_DECREF(key);
593        goto error;
594    }
595    Py_DECREF(key);
596    Py_DECREF(path);
597    return get_data(self->archive, toc_entry);
598  error:
599    Py_DECREF(path);
600    return NULL;
601}
602
603static PyObject *
604zipimporter_get_code(PyObject *obj, PyObject *args)
605{
606    ZipImporter *self = (ZipImporter *)obj;
607    PyObject *fullname;
608
609    if (!PyArg_ParseTuple(args, "U:zipimporter.get_code", &fullname))
610        return NULL;
611
612    return get_module_code(self, fullname, NULL, NULL);
613}
614
615static PyObject *
616zipimporter_get_source(PyObject *obj, PyObject *args)
617{
618    ZipImporter *self = (ZipImporter *)obj;
619    PyObject *toc_entry;
620    PyObject *fullname, *subname, *path, *fullpath;
621    enum zi_module_info mi;
622
623    if (!PyArg_ParseTuple(args, "U:zipimporter.get_source", &fullname))
624        return NULL;
625
626    mi = get_module_info(self, fullname);
627    if (mi == MI_ERROR)
628        return NULL;
629    if (mi == MI_NOT_FOUND) {
630        PyErr_Format(ZipImportError, "can't find module %R", fullname);
631        return NULL;
632    }
633
634    subname = get_subname(fullname);
635    if (subname == NULL)
636        return NULL;
637
638    path = make_filename(self->prefix, subname);
639    Py_DECREF(subname);
640    if (path == NULL)
641        return NULL;
642
643    if (mi == MI_PACKAGE)
644        fullpath = PyUnicode_FromFormat("%U%c__init__.py", path, SEP);
645    else
646        fullpath = PyUnicode_FromFormat("%U.py", path);
647    Py_DECREF(path);
648    if (fullpath == NULL)
649        return NULL;
650
651    toc_entry = PyDict_GetItem(self->files, fullpath);
652    Py_DECREF(fullpath);
653    if (toc_entry != NULL) {
654        PyObject *res, *bytes;
655        bytes = get_data(self->archive, toc_entry);
656        if (bytes == NULL)
657            return NULL;
658        res = PyUnicode_FromStringAndSize(PyBytes_AS_STRING(bytes),
659                                          PyBytes_GET_SIZE(bytes));
660        Py_DECREF(bytes);
661        return res;
662    }
663
664    /* we have the module, but no source */
665    Py_INCREF(Py_None);
666    return Py_None;
667}
668
669PyDoc_STRVAR(doc_find_module,
670"find_module(fullname, path=None) -> self or None.\n\
671\n\
672Search for a module specified by 'fullname'. 'fullname' must be the\n\
673fully qualified (dotted) module name. It returns the zipimporter\n\
674instance itself if the module was found, or None if it wasn't.\n\
675The optional 'path' argument is ignored -- it's there for compatibility\n\
676with the importer protocol.");
677
678PyDoc_STRVAR(doc_find_loader,
679"find_loader(fullname, path=None) -> self, str or None.\n\
680\n\
681Search for a module specified by 'fullname'. 'fullname' must be the\n\
682fully qualified (dotted) module name. It returns the zipimporter\n\
683instance itself if the module was found, a string containing the\n\
684full path name if it's possibly a portion of a namespace package,\n\
685or None otherwise. The optional 'path' argument is ignored -- it's\n\
686 there for compatibility with the importer protocol.");
687
688PyDoc_STRVAR(doc_load_module,
689"load_module(fullname) -> module.\n\
690\n\
691Load the module specified by 'fullname'. 'fullname' must be the\n\
692fully qualified (dotted) module name. It returns the imported\n\
693module, or raises ZipImportError if it wasn't found.");
694
695PyDoc_STRVAR(doc_get_data,
696"get_data(pathname) -> string with file data.\n\
697\n\
698Return the data associated with 'pathname'. Raise IOError if\n\
699the file wasn't found.");
700
701PyDoc_STRVAR(doc_is_package,
702"is_package(fullname) -> bool.\n\
703\n\
704Return True if the module specified by fullname is a package.\n\
705Raise ZipImportError if the module couldn't be found.");
706
707PyDoc_STRVAR(doc_get_code,
708"get_code(fullname) -> code object.\n\
709\n\
710Return the code object for the specified module. Raise ZipImportError\n\
711if the module couldn't be found.");
712
713PyDoc_STRVAR(doc_get_source,
714"get_source(fullname) -> source string.\n\
715\n\
716Return the source code for the specified module. Raise ZipImportError\n\
717if the module couldn't be found, return None if the archive does\n\
718contain the module, but has no source for it.");
719
720
721PyDoc_STRVAR(doc_get_filename,
722"get_filename(fullname) -> filename string.\n\
723\n\
724Return the filename for the specified module.");
725
726static PyMethodDef zipimporter_methods[] = {
727    {"find_module", zipimporter_find_module, METH_VARARGS,
728     doc_find_module},
729    {"find_loader", zipimporter_find_loader, METH_VARARGS,
730     doc_find_loader},
731    {"load_module", zipimporter_load_module, METH_VARARGS,
732     doc_load_module},
733    {"get_data", zipimporter_get_data, METH_VARARGS,
734     doc_get_data},
735    {"get_code", zipimporter_get_code, METH_VARARGS,
736     doc_get_code},
737    {"get_source", zipimporter_get_source, METH_VARARGS,
738     doc_get_source},
739    {"get_filename", zipimporter_get_filename, METH_VARARGS,
740     doc_get_filename},
741    {"is_package", zipimporter_is_package, METH_VARARGS,
742     doc_is_package},
743    {NULL,              NULL}   /* sentinel */
744};
745
746static PyMemberDef zipimporter_members[] = {
747    {"archive",  T_OBJECT, offsetof(ZipImporter, archive),  READONLY},
748    {"prefix",   T_OBJECT, offsetof(ZipImporter, prefix),   READONLY},
749    {"_files",   T_OBJECT, offsetof(ZipImporter, files),    READONLY},
750    {NULL}
751};
752
753PyDoc_STRVAR(zipimporter_doc,
754"zipimporter(archivepath) -> zipimporter object\n\
755\n\
756Create a new zipimporter instance. 'archivepath' must be a path to\n\
757a zipfile, or to a specific path inside a zipfile. For example, it can be\n\
758'/tmp/myimport.zip', or '/tmp/myimport.zip/mydirectory', if mydirectory is a\n\
759valid directory inside the archive.\n\
760\n\
761'ZipImportError is raised if 'archivepath' doesn't point to a valid Zip\n\
762archive.\n\
763\n\
764The 'archive' attribute of zipimporter objects contains the name of the\n\
765zipfile targeted.");
766
767#define DEFERRED_ADDRESS(ADDR) 0
768
769static PyTypeObject ZipImporter_Type = {
770    PyVarObject_HEAD_INIT(DEFERRED_ADDRESS(&PyType_Type), 0)
771    "zipimport.zipimporter",
772    sizeof(ZipImporter),
773    0,                                          /* tp_itemsize */
774    (destructor)zipimporter_dealloc,            /* tp_dealloc */
775    0,                                          /* tp_print */
776    0,                                          /* tp_getattr */
777    0,                                          /* tp_setattr */
778    0,                                          /* tp_reserved */
779    (reprfunc)zipimporter_repr,                 /* tp_repr */
780    0,                                          /* tp_as_number */
781    0,                                          /* tp_as_sequence */
782    0,                                          /* tp_as_mapping */
783    0,                                          /* tp_hash */
784    0,                                          /* tp_call */
785    0,                                          /* tp_str */
786    PyObject_GenericGetAttr,                    /* tp_getattro */
787    0,                                          /* tp_setattro */
788    0,                                          /* tp_as_buffer */
789    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE |
790        Py_TPFLAGS_HAVE_GC,                     /* tp_flags */
791    zipimporter_doc,                            /* tp_doc */
792    zipimporter_traverse,                       /* tp_traverse */
793    0,                                          /* tp_clear */
794    0,                                          /* tp_richcompare */
795    0,                                          /* tp_weaklistoffset */
796    0,                                          /* tp_iter */
797    0,                                          /* tp_iternext */
798    zipimporter_methods,                        /* tp_methods */
799    zipimporter_members,                        /* tp_members */
800    0,                                          /* tp_getset */
801    0,                                          /* tp_base */
802    0,                                          /* tp_dict */
803    0,                                          /* tp_descr_get */
804    0,                                          /* tp_descr_set */
805    0,                                          /* tp_dictoffset */
806    (initproc)zipimporter_init,                 /* tp_init */
807    PyType_GenericAlloc,                        /* tp_alloc */
808    PyType_GenericNew,                          /* tp_new */
809    PyObject_GC_Del,                            /* tp_free */
810};
811
812
813/* implementation */
814
815/* Given a buffer, return the long that is represented by the first
816   4 bytes, encoded as little endian. This partially reimplements
817   marshal.c:r_long() */
818static long
819get_long(unsigned char *buf) {
820    long x;
821    x =  buf[0];
822    x |= (long)buf[1] <<  8;
823    x |= (long)buf[2] << 16;
824    x |= (long)buf[3] << 24;
825#if SIZEOF_LONG > 4
826    /* Sign extension for 64-bit machines */
827    x |= -(x & 0x80000000L);
828#endif
829    return x;
830}
831
832/*
833   read_directory(archive) -> files dict (new reference)
834
835   Given a path to a Zip archive, build a dict, mapping file names
836   (local to the archive, using SEP as a separator) to toc entries.
837
838   A toc_entry is a tuple:
839
840   (__file__,      # value to use for __file__, available for all files,
841                   # encoded to the filesystem encoding
842    compress,      # compression kind; 0 for uncompressed
843    data_size,     # size of compressed data on disk
844    file_size,     # size of decompressed data
845    file_offset,   # offset of file header from start of archive
846    time,          # mod time of file (in dos format)
847    date,          # mod data of file (in dos format)
848    crc,           # crc checksum of the data
849   )
850
851   Directories can be recognized by the trailing SEP in the name,
852   data_size and file_offset are 0.
853*/
854static PyObject *
855read_directory(PyObject *archive)
856{
857    PyObject *files = NULL;
858    FILE *fp;
859    unsigned short flags;
860    short compress, time, date, name_size;
861    long crc, data_size, file_size, header_size;
862    Py_ssize_t file_offset, header_position, header_offset;
863    long l, count;
864    Py_ssize_t i;
865    char name[MAXPATHLEN + 5];
866    char dummy[8]; /* Buffer to read unused header values into */
867    PyObject *nameobj = NULL;
868    char *p, endof_central_dir[22];
869    Py_ssize_t arc_offset;  /* Absolute offset to start of the zip-archive. */
870    PyObject *path;
871    const char *charset;
872    int bootstrap;
873
874    fp = _Py_fopen_obj(archive, "rb");
875    if (fp == NULL) {
876        if (PyErr_ExceptionMatches(PyExc_OSError)) {
877            PyObject *exc, *val, *tb;
878            PyErr_Fetch(&exc, &val, &tb);
879            PyErr_Format(ZipImportError, "can't open Zip file: %R", archive);
880            _PyErr_ChainExceptions(exc, val, tb);
881        }
882        return NULL;
883    }
884
885    if (fseek(fp, -22, SEEK_END) == -1) {
886        fclose(fp);
887        PyErr_Format(ZipImportError, "can't read Zip file: %R", archive);
888        return NULL;
889    }
890    header_position = ftell(fp);
891    if (fread(endof_central_dir, 1, 22, fp) != 22) {
892        fclose(fp);
893        PyErr_Format(ZipImportError, "can't read Zip file: %R", archive);
894        return NULL;
895    }
896    if (get_long((unsigned char *)endof_central_dir) != 0x06054B50) {
897        /* Bad: End of Central Dir signature */
898        fclose(fp);
899        PyErr_Format(ZipImportError, "not a Zip file: %R", archive);
900        return NULL;
901    }
902
903    header_size = get_long((unsigned char *)endof_central_dir + 12);
904    header_offset = get_long((unsigned char *)endof_central_dir + 16);
905    arc_offset = header_position - header_offset - header_size;
906    header_offset += arc_offset;
907
908    files = PyDict_New();
909    if (files == NULL)
910        goto error;
911
912    /* Start of Central Directory */
913    count = 0;
914    if (fseek(fp, header_offset, 0) == -1)
915        goto file_error;
916    for (;;) {
917        PyObject *t;
918        int err;
919
920        /* Start of file header */
921        l = PyMarshal_ReadLongFromFile(fp);
922        if (l == -1 && PyErr_Occurred())
923            goto error;
924        if (l != 0x02014B50)
925            break;              /* Bad: Central Dir File Header */
926
927        /* On Windows, calling fseek to skip over the fields we don't use is
928        slower than reading the data into a dummy buffer because fseek flushes
929        stdio's internal buffers. See issue #8745. */
930        if (fread(dummy, 1, 4, fp) != 4) /* Skip unused fields, avoid fseek */
931            goto file_error;
932
933        flags = (unsigned short)PyMarshal_ReadShortFromFile(fp);
934        compress = PyMarshal_ReadShortFromFile(fp);
935        time = PyMarshal_ReadShortFromFile(fp);
936        date = PyMarshal_ReadShortFromFile(fp);
937        crc = PyMarshal_ReadLongFromFile(fp);
938        data_size = PyMarshal_ReadLongFromFile(fp);
939        file_size = PyMarshal_ReadLongFromFile(fp);
940        name_size = PyMarshal_ReadShortFromFile(fp);
941        header_size = name_size +
942           PyMarshal_ReadShortFromFile(fp) +
943           PyMarshal_ReadShortFromFile(fp);
944        if (PyErr_Occurred())
945            goto error;
946
947        if (fread(dummy, 1, 8, fp) != 8) /* Skip unused fields, avoid fseek */
948            goto file_error;
949        file_offset = PyMarshal_ReadLongFromFile(fp) + arc_offset;
950        if (PyErr_Occurred())
951            goto error;
952
953        if (name_size > MAXPATHLEN)
954            name_size = MAXPATHLEN;
955
956        p = name;
957        for (i = 0; i < (Py_ssize_t)name_size; i++) {
958            *p = (char)getc(fp);
959            if (*p == '/')
960                *p = SEP;
961            p++;
962        }
963        *p = 0;         /* Add terminating null byte */
964        for (; i < header_size; i++) /* Skip the rest of the header */
965            if(getc(fp) == EOF) /* Avoid fseek */
966                goto file_error;
967
968        bootstrap = 0;
969        if (flags & 0x0800)
970            charset = "utf-8";
971        else if (!PyThreadState_GET()->interp->codecs_initialized) {
972            /* During bootstrap, we may need to load the encodings
973               package from a ZIP file. But the cp437 encoding is implemented
974               in Python in the encodings package.
975
976               Break out of this dependency by assuming that the path to
977               the encodings module is ASCII-only. */
978            charset = "ascii";
979            bootstrap = 1;
980        }
981        else
982            charset = "cp437";
983        nameobj = PyUnicode_Decode(name, name_size, charset, NULL);
984        if (nameobj == NULL) {
985            if (bootstrap)
986                PyErr_Format(PyExc_NotImplementedError,
987                    "bootstrap issue: python%i%i.zip contains non-ASCII "
988                    "filenames without the unicode flag",
989                    PY_MAJOR_VERSION, PY_MINOR_VERSION);
990            goto error;
991        }
992        if (PyUnicode_READY(nameobj) == -1)
993            goto error;
994        path = PyUnicode_FromFormat("%U%c%U", archive, SEP, nameobj);
995        if (path == NULL)
996            goto error;
997        t = Py_BuildValue("Nhllnhhl", path, compress, data_size,
998                          file_size, file_offset, time, date, crc);
999        if (t == NULL)
1000            goto error;
1001        err = PyDict_SetItem(files, nameobj, t);
1002        Py_CLEAR(nameobj);
1003        Py_DECREF(t);
1004        if (err != 0)
1005            goto error;
1006        count++;
1007    }
1008    fclose(fp);
1009    if (Py_VerboseFlag)
1010        PySys_FormatStderr("# zipimport: found %ld names in %R\n",
1011                           count, archive);
1012    return files;
1013file_error:
1014    fclose(fp);
1015    Py_XDECREF(files);
1016    Py_XDECREF(nameobj);
1017    PyErr_Format(ZipImportError, "can't read Zip file: %R", archive);
1018    return NULL;
1019error:
1020    fclose(fp);
1021    Py_XDECREF(files);
1022    Py_XDECREF(nameobj);
1023    return NULL;
1024}
1025
1026/* Return the zlib.decompress function object, or NULL if zlib couldn't
1027   be imported. The function is cached when found, so subsequent calls
1028   don't import zlib again. */
1029static PyObject *
1030get_decompress_func(void)
1031{
1032    static int importing_zlib = 0;
1033    PyObject *zlib;
1034    PyObject *decompress;
1035    _Py_IDENTIFIER(decompress);
1036
1037    if (importing_zlib != 0)
1038        /* Someone has a zlib.py[co] in their Zip file;
1039           let's avoid a stack overflow. */
1040        return NULL;
1041    importing_zlib = 1;
1042    zlib = PyImport_ImportModuleNoBlock("zlib");
1043    importing_zlib = 0;
1044    if (zlib != NULL) {
1045        decompress = _PyObject_GetAttrId(zlib,
1046                                         &PyId_decompress);
1047        Py_DECREF(zlib);
1048    }
1049    else {
1050        PyErr_Clear();
1051        decompress = NULL;
1052    }
1053    if (Py_VerboseFlag)
1054        PySys_WriteStderr("# zipimport: zlib %s\n",
1055            zlib != NULL ? "available": "UNAVAILABLE");
1056    return decompress;
1057}
1058
1059/* Given a path to a Zip file and a toc_entry, return the (uncompressed)
1060   data as a new reference. */
1061static PyObject *
1062get_data(PyObject *archive, PyObject *toc_entry)
1063{
1064    PyObject *raw_data, *data = NULL, *decompress;
1065    char *buf;
1066    FILE *fp;
1067    int err;
1068    Py_ssize_t bytes_read = 0;
1069    long l;
1070    PyObject *datapath;
1071    long compress, data_size, file_size, file_offset, bytes_size;
1072    long time, date, crc;
1073
1074    if (!PyArg_ParseTuple(toc_entry, "Olllllll", &datapath, &compress,
1075                          &data_size, &file_size, &file_offset, &time,
1076                          &date, &crc)) {
1077        return NULL;
1078    }
1079
1080    fp = _Py_fopen_obj(archive, "rb");
1081    if (!fp)
1082        return NULL;
1083
1084    /* Check to make sure the local file header is correct */
1085    if (fseek(fp, file_offset, 0) == -1) {
1086        fclose(fp);
1087        PyErr_Format(ZipImportError, "can't read Zip file: %R", archive);
1088        return NULL;
1089    }
1090
1091    l = PyMarshal_ReadLongFromFile(fp);
1092    if (l != 0x04034B50) {
1093        /* Bad: Local File Header */
1094        if (!PyErr_Occurred())
1095            PyErr_Format(ZipImportError,
1096                         "bad local file header in %U",
1097                         archive);
1098        fclose(fp);
1099        return NULL;
1100    }
1101    if (fseek(fp, file_offset + 26, 0) == -1) {
1102        fclose(fp);
1103        PyErr_Format(ZipImportError, "can't read Zip file: %R", archive);
1104        return NULL;
1105    }
1106
1107    l = 30 + PyMarshal_ReadShortFromFile(fp) +
1108        PyMarshal_ReadShortFromFile(fp);        /* local header size */
1109    if (PyErr_Occurred()) {
1110        fclose(fp);
1111        return NULL;
1112    }
1113    file_offset += l;           /* Start of file data */
1114
1115    bytes_size = compress == 0 ? data_size : data_size + 1;
1116    if (bytes_size == 0)
1117        bytes_size++;
1118    raw_data = PyBytes_FromStringAndSize((char *)NULL, bytes_size);
1119
1120    if (raw_data == NULL) {
1121        fclose(fp);
1122        return NULL;
1123    }
1124    buf = PyBytes_AsString(raw_data);
1125
1126    err = fseek(fp, file_offset, 0);
1127    if (err == 0) {
1128        bytes_read = fread(buf, 1, data_size, fp);
1129    } else {
1130        fclose(fp);
1131        PyErr_Format(ZipImportError, "can't read Zip file: %R", archive);
1132        return NULL;
1133    }
1134    fclose(fp);
1135    if (err || bytes_read != data_size) {
1136        PyErr_SetString(PyExc_IOError,
1137                        "zipimport: can't read data");
1138        Py_DECREF(raw_data);
1139        return NULL;
1140    }
1141
1142    if (compress != 0) {
1143        buf[data_size] = 'Z';  /* saw this in zipfile.py */
1144        data_size++;
1145    }
1146    buf[data_size] = '\0';
1147
1148    if (compress == 0) {  /* data is not compressed */
1149        data = PyBytes_FromStringAndSize(buf, data_size);
1150        Py_DECREF(raw_data);
1151        return data;
1152    }
1153
1154    /* Decompress with zlib */
1155    decompress = get_decompress_func();
1156    if (decompress == NULL) {
1157        PyErr_SetString(ZipImportError,
1158                        "can't decompress data; "
1159                        "zlib not available");
1160        goto error;
1161    }
1162    data = PyObject_CallFunction(decompress, "Oi", raw_data, -15);
1163    Py_DECREF(decompress);
1164error:
1165    Py_DECREF(raw_data);
1166    return data;
1167}
1168
1169/* Lenient date/time comparison function. The precision of the mtime
1170   in the archive is lower than the mtime stored in a .pyc: we
1171   must allow a difference of at most one second. */
1172static int
1173eq_mtime(time_t t1, time_t t2)
1174{
1175    time_t d = t1 - t2;
1176    if (d < 0)
1177        d = -d;
1178    /* dostime only stores even seconds, so be lenient */
1179    return d <= 1;
1180}
1181
1182/* Given the contents of a .py[co] file in a buffer, unmarshal the data
1183   and return the code object. Return None if it the magic word doesn't
1184   match (we do this instead of raising an exception as we fall back
1185   to .py if available and we don't want to mask other errors).
1186   Returns a new reference. */
1187static PyObject *
1188unmarshal_code(PyObject *pathname, PyObject *data, time_t mtime)
1189{
1190    PyObject *code;
1191    char *buf = PyBytes_AsString(data);
1192    Py_ssize_t size = PyBytes_Size(data);
1193
1194    if (size <= 9) {
1195        PyErr_SetString(ZipImportError,
1196                        "bad pyc data");
1197        return NULL;
1198    }
1199
1200    if (get_long((unsigned char *)buf) != PyImport_GetMagicNumber()) {
1201        if (Py_VerboseFlag)
1202            PySys_FormatStderr("# %R has bad magic\n",
1203                               pathname);
1204        Py_INCREF(Py_None);
1205        return Py_None;  /* signal caller to try alternative */
1206    }
1207
1208    if (mtime != 0 && !eq_mtime(get_long((unsigned char *)buf + 4),
1209                                mtime)) {
1210        if (Py_VerboseFlag)
1211            PySys_FormatStderr("# %R has bad mtime\n",
1212                               pathname);
1213        Py_INCREF(Py_None);
1214        return Py_None;  /* signal caller to try alternative */
1215    }
1216
1217    /* XXX the pyc's size field is ignored; timestamp collisions are probably
1218       unimportant with zip files. */
1219    code = PyMarshal_ReadObjectFromString(buf + 12, size - 12);
1220    if (code == NULL)
1221        return NULL;
1222    if (!PyCode_Check(code)) {
1223        Py_DECREF(code);
1224        PyErr_Format(PyExc_TypeError,
1225             "compiled module %R is not a code object",
1226             pathname);
1227        return NULL;
1228    }
1229    return code;
1230}
1231
1232/* Replace any occurances of "\r\n?" in the input string with "\n".
1233   This converts DOS and Mac line endings to Unix line endings.
1234   Also append a trailing "\n" to be compatible with
1235   PyParser_SimpleParseFile(). Returns a new reference. */
1236static PyObject *
1237normalize_line_endings(PyObject *source)
1238{
1239    char *buf, *q, *p;
1240    PyObject *fixed_source;
1241    int len = 0;
1242
1243    p = PyBytes_AsString(source);
1244    if (p == NULL) {
1245        return PyBytes_FromStringAndSize("\n\0", 2);
1246    }
1247
1248    /* one char extra for trailing \n and one for terminating \0 */
1249    buf = (char *)PyMem_Malloc(PyBytes_Size(source) + 2);
1250    if (buf == NULL) {
1251        PyErr_SetString(PyExc_MemoryError,
1252                        "zipimport: no memory to allocate "
1253                        "source buffer");
1254        return NULL;
1255    }
1256    /* replace "\r\n?" by "\n" */
1257    for (q = buf; *p != '\0'; p++) {
1258        if (*p == '\r') {
1259            *q++ = '\n';
1260            if (*(p + 1) == '\n')
1261                p++;
1262        }
1263        else
1264            *q++ = *p;
1265        len++;
1266    }
1267    *q++ = '\n';  /* add trailing \n */
1268    *q = '\0';
1269    fixed_source = PyBytes_FromStringAndSize(buf, len + 2);
1270    PyMem_Free(buf);
1271    return fixed_source;
1272}
1273
1274/* Given a string buffer containing Python source code, compile it
1275   and return a code object as a new reference. */
1276static PyObject *
1277compile_source(PyObject *pathname, PyObject *source)
1278{
1279    PyObject *code, *fixed_source, *pathbytes;
1280
1281    pathbytes = PyUnicode_EncodeFSDefault(pathname);
1282    if (pathbytes == NULL)
1283        return NULL;
1284
1285    fixed_source = normalize_line_endings(source);
1286    if (fixed_source == NULL) {
1287        Py_DECREF(pathbytes);
1288        return NULL;
1289    }
1290
1291    code = Py_CompileString(PyBytes_AsString(fixed_source),
1292                            PyBytes_AsString(pathbytes),
1293                            Py_file_input);
1294    Py_DECREF(pathbytes);
1295    Py_DECREF(fixed_source);
1296    return code;
1297}
1298
1299/* Convert the date/time values found in the Zip archive to a value
1300   that's compatible with the time stamp stored in .pyc files. */
1301static time_t
1302parse_dostime(int dostime, int dosdate)
1303{
1304    struct tm stm;
1305
1306    memset((void *) &stm, '\0', sizeof(stm));
1307
1308    stm.tm_sec   =  (dostime        & 0x1f) * 2;
1309    stm.tm_min   =  (dostime >> 5)  & 0x3f;
1310    stm.tm_hour  =  (dostime >> 11) & 0x1f;
1311    stm.tm_mday  =   dosdate        & 0x1f;
1312    stm.tm_mon   = ((dosdate >> 5)  & 0x0f) - 1;
1313    stm.tm_year  = ((dosdate >> 9)  & 0x7f) + 80;
1314    stm.tm_isdst =   -1; /* wday/yday is ignored */
1315
1316    return mktime(&stm);
1317}
1318
1319/* Given a path to a .pyc file in the archive, return the
1320   modification time of the matching .py file, or 0 if no source
1321   is available. */
1322static time_t
1323get_mtime_of_source(ZipImporter *self, PyObject *path)
1324{
1325    PyObject *toc_entry, *stripped;
1326    time_t mtime;
1327
1328    /* strip 'c' or 'o' from *.py[co] */
1329    if (PyUnicode_READY(path) == -1)
1330        return (time_t)-1;
1331    stripped = PyUnicode_FromKindAndData(PyUnicode_KIND(path),
1332                                         PyUnicode_DATA(path),
1333                                         PyUnicode_GET_LENGTH(path) - 1);
1334    if (stripped == NULL)
1335        return (time_t)-1;
1336
1337    toc_entry = PyDict_GetItem(self->files, stripped);
1338    Py_DECREF(stripped);
1339    if (toc_entry != NULL && PyTuple_Check(toc_entry) &&
1340        PyTuple_Size(toc_entry) == 8) {
1341        /* fetch the time stamp of the .py file for comparison
1342           with an embedded pyc time stamp */
1343        int time, date;
1344        time = PyLong_AsLong(PyTuple_GetItem(toc_entry, 5));
1345        date = PyLong_AsLong(PyTuple_GetItem(toc_entry, 6));
1346        mtime = parse_dostime(time, date);
1347    } else
1348        mtime = 0;
1349    return mtime;
1350}
1351
1352/* Return the code object for the module named by 'fullname' from the
1353   Zip archive as a new reference. */
1354static PyObject *
1355get_code_from_data(ZipImporter *self, int ispackage, int isbytecode,
1356                   time_t mtime, PyObject *toc_entry)
1357{
1358    PyObject *data, *modpath, *code;
1359
1360    data = get_data(self->archive, toc_entry);
1361    if (data == NULL)
1362        return NULL;
1363
1364    modpath = PyTuple_GetItem(toc_entry, 0);
1365    if (isbytecode)
1366        code = unmarshal_code(modpath, data, mtime);
1367    else
1368        code = compile_source(modpath, data);
1369    Py_DECREF(data);
1370    return code;
1371}
1372
1373/* Get the code object associated with the module specified by
1374   'fullname'. */
1375static PyObject *
1376get_module_code(ZipImporter *self, PyObject *fullname,
1377                int *p_ispackage, PyObject **p_modpath)
1378{
1379    PyObject *code = NULL, *toc_entry, *subname;
1380    PyObject *path, *fullpath = NULL;
1381    struct st_zip_searchorder *zso;
1382
1383    subname = get_subname(fullname);
1384    if (subname == NULL)
1385        return NULL;
1386
1387    path = make_filename(self->prefix, subname);
1388    Py_DECREF(subname);
1389    if (path == NULL)
1390        return NULL;
1391
1392    for (zso = zip_searchorder; *zso->suffix; zso++) {
1393        code = NULL;
1394
1395        fullpath = PyUnicode_FromFormat("%U%s", path, zso->suffix);
1396        if (fullpath == NULL)
1397            goto exit;
1398
1399        if (Py_VerboseFlag > 1)
1400            PySys_FormatStderr("# trying %U%c%U\n",
1401                               self->archive, (int)SEP, fullpath);
1402        toc_entry = PyDict_GetItem(self->files, fullpath);
1403        if (toc_entry != NULL) {
1404            time_t mtime = 0;
1405            int ispackage = zso->type & IS_PACKAGE;
1406            int isbytecode = zso->type & IS_BYTECODE;
1407
1408            if (isbytecode) {
1409                mtime = get_mtime_of_source(self, fullpath);
1410                if (mtime == (time_t)-1 && PyErr_Occurred()) {
1411                    goto exit;
1412                }
1413            }
1414            Py_CLEAR(fullpath);
1415            if (p_ispackage != NULL)
1416                *p_ispackage = ispackage;
1417            code = get_code_from_data(self, ispackage,
1418                                      isbytecode, mtime,
1419                                      toc_entry);
1420            if (code == Py_None) {
1421                /* bad magic number or non-matching mtime
1422                   in byte code, try next */
1423                Py_DECREF(code);
1424                continue;
1425            }
1426            if (code != NULL && p_modpath != NULL) {
1427                *p_modpath = PyTuple_GetItem(toc_entry, 0);
1428                Py_INCREF(*p_modpath);
1429            }
1430            goto exit;
1431        }
1432        else
1433            Py_CLEAR(fullpath);
1434    }
1435    PyErr_Format(ZipImportError, "can't find module %R", fullname);
1436exit:
1437    Py_DECREF(path);
1438    Py_XDECREF(fullpath);
1439    return code;
1440}
1441
1442
1443/* Module init */
1444
1445PyDoc_STRVAR(zipimport_doc,
1446"zipimport provides support for importing Python modules from Zip archives.\n\
1447\n\
1448This module exports three objects:\n\
1449- zipimporter: a class; its constructor takes a path to a Zip archive.\n\
1450- ZipImportError: exception raised by zipimporter objects. It's a\n\
1451  subclass of ImportError, so it can be caught as ImportError, too.\n\
1452- _zip_directory_cache: a dict, mapping archive paths to zip directory\n\
1453  info dicts, as used in zipimporter._files.\n\
1454\n\
1455It is usually not needed to use the zipimport module explicitly; it is\n\
1456used by the builtin import mechanism for sys.path items that are paths\n\
1457to Zip archives.");
1458
1459static struct PyModuleDef zipimportmodule = {
1460    PyModuleDef_HEAD_INIT,
1461    "zipimport",
1462    zipimport_doc,
1463    -1,
1464    NULL,
1465    NULL,
1466    NULL,
1467    NULL,
1468    NULL
1469};
1470
1471PyMODINIT_FUNC
1472PyInit_zipimport(void)
1473{
1474    PyObject *mod;
1475
1476    if (PyType_Ready(&ZipImporter_Type) < 0)
1477        return NULL;
1478
1479    /* Correct directory separator */
1480    zip_searchorder[0].suffix[0] = SEP;
1481    zip_searchorder[1].suffix[0] = SEP;
1482
1483    mod = PyModule_Create(&zipimportmodule);
1484    if (mod == NULL)
1485        return NULL;
1486
1487    ZipImportError = PyErr_NewException("zipimport.ZipImportError",
1488                                        PyExc_ImportError, NULL);
1489    if (ZipImportError == NULL)
1490        return NULL;
1491
1492    Py_INCREF(ZipImportError);
1493    if (PyModule_AddObject(mod, "ZipImportError",
1494                           ZipImportError) < 0)
1495        return NULL;
1496
1497    Py_INCREF(&ZipImporter_Type);
1498    if (PyModule_AddObject(mod, "zipimporter",
1499                           (PyObject *)&ZipImporter_Type) < 0)
1500        return NULL;
1501
1502    zip_directory_cache = PyDict_New();
1503    if (zip_directory_cache == NULL)
1504        return NULL;
1505    Py_INCREF(zip_directory_cache);
1506    if (PyModule_AddObject(mod, "_zip_directory_cache",
1507                           zip_directory_cache) < 0)
1508        return NULL;
1509    return mod;
1510}
1511