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