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