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 unsigned int that is represented by the first 831 4 bytes, encoded as little endian. This partially reimplements 832 marshal.c:r_long() */ 833static unsigned int 834get_uint32(const unsigned char *buf) 835{ 836 unsigned int x; 837 x = buf[0]; 838 x |= (unsigned int)buf[1] << 8; 839 x |= (unsigned int)buf[2] << 16; 840 x |= (unsigned int)buf[3] << 24; 841 return x; 842} 843 844/* Given a buffer, return the unsigned int that is represented by the first 845 2 bytes, encoded as little endian. This partially reimplements 846 marshal.c:r_short() */ 847static unsigned short 848get_uint16(const unsigned char *buf) 849{ 850 unsigned short x; 851 x = buf[0]; 852 x |= (unsigned short)buf[1] << 8; 853 return x; 854} 855 856static void 857set_file_error(PyObject *archive, int eof) 858{ 859 if (eof) { 860 PyErr_SetString(PyExc_EOFError, "EOF read where not expected"); 861 } 862 else { 863 PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, archive); 864 } 865} 866 867/* 868 read_directory(archive) -> files dict (new reference) 869 870 Given a path to a Zip archive, build a dict, mapping file names 871 (local to the archive, using SEP as a separator) to toc entries. 872 873 A toc_entry is a tuple: 874 875 (__file__, # value to use for __file__, available for all files, 876 # encoded to the filesystem encoding 877 compress, # compression kind; 0 for uncompressed 878 data_size, # size of compressed data on disk 879 file_size, # size of decompressed data 880 file_offset, # offset of file header from start of archive 881 time, # mod time of file (in dos format) 882 date, # mod data of file (in dos format) 883 crc, # crc checksum of the data 884 ) 885 886 Directories can be recognized by the trailing SEP in the name, 887 data_size and file_offset are 0. 888*/ 889static PyObject * 890read_directory(PyObject *archive) 891{ 892 PyObject *files = NULL; 893 FILE *fp; 894 unsigned short flags, compress, time, date, name_size; 895 unsigned int crc, data_size, file_size, header_size, header_offset; 896 unsigned long file_offset, header_position; 897 unsigned long arc_offset; /* Absolute offset to start of the zip-archive. */ 898 unsigned int count, i; 899 unsigned char buffer[46]; 900 char name[MAXPATHLEN + 5]; 901 PyObject *nameobj = NULL; 902 PyObject *path; 903 const char *charset; 904 int bootstrap; 905 const char *errmsg = NULL; 906 907 fp = _Py_fopen_obj(archive, "rb"); 908 if (fp == NULL) { 909 if (PyErr_ExceptionMatches(PyExc_OSError)) { 910 _PyErr_FormatFromCause(ZipImportError, 911 "can't open Zip file: %R", archive); 912 } 913 return NULL; 914 } 915 916 if (fseek(fp, -22, SEEK_END) == -1) { 917 goto file_error; 918 } 919 header_position = (unsigned long)ftell(fp); 920 if (header_position == (unsigned long)-1) { 921 goto file_error; 922 } 923 assert(header_position <= (unsigned long)LONG_MAX); 924 if (fread(buffer, 1, 22, fp) != 22) { 925 goto file_error; 926 } 927 if (get_uint32(buffer) != 0x06054B50u) { 928 /* Bad: End of Central Dir signature */ 929 errmsg = "not a Zip file"; 930 goto invalid_header; 931 } 932 933 header_size = get_uint32(buffer + 12); 934 header_offset = get_uint32(buffer + 16); 935 if (header_position < header_size) { 936 errmsg = "bad central directory size"; 937 goto invalid_header; 938 } 939 if (header_position < header_offset) { 940 errmsg = "bad central directory offset"; 941 goto invalid_header; 942 } 943 if (header_position - header_size < header_offset) { 944 errmsg = "bad central directory size or offset"; 945 goto invalid_header; 946 } 947 header_position -= header_size; 948 arc_offset = header_position - header_offset; 949 950 files = PyDict_New(); 951 if (files == NULL) { 952 goto error; 953 } 954 /* Start of Central Directory */ 955 count = 0; 956 if (fseek(fp, (long)header_position, 0) == -1) { 957 goto file_error; 958 } 959 for (;;) { 960 PyObject *t; 961 size_t n; 962 int err; 963 964 n = fread(buffer, 1, 46, fp); 965 if (n < 4) { 966 goto eof_error; 967 } 968 /* Start of file header */ 969 if (get_uint32(buffer) != 0x02014B50u) { 970 break; /* Bad: Central Dir File Header */ 971 } 972 if (n != 46) { 973 goto eof_error; 974 } 975 flags = get_uint16(buffer + 8); 976 compress = get_uint16(buffer + 10); 977 time = get_uint16(buffer + 12); 978 date = get_uint16(buffer + 14); 979 crc = get_uint32(buffer + 16); 980 data_size = get_uint32(buffer + 20); 981 file_size = get_uint32(buffer + 24); 982 name_size = get_uint16(buffer + 28); 983 header_size = (unsigned int)name_size + 984 get_uint16(buffer + 30) /* extra field */ + 985 get_uint16(buffer + 32) /* comment */; 986 987 file_offset = get_uint32(buffer + 42); 988 if (file_offset > header_offset) { 989 errmsg = "bad local header offset"; 990 goto invalid_header; 991 } 992 file_offset += arc_offset; 993 994 if (name_size > MAXPATHLEN) { 995 name_size = MAXPATHLEN; 996 } 997 if (fread(name, 1, name_size, fp) != name_size) { 998 goto file_error; 999 } 1000 name[name_size] = '\0'; /* Add terminating null byte */ 1001 if (SEP != '/') { 1002 for (i = 0; i < name_size; i++) { 1003 if (name[i] == '/') { 1004 name[i] = SEP; 1005 } 1006 } 1007 } 1008 /* Skip the rest of the header. 1009 * On Windows, calling fseek to skip over the fields we don't use is 1010 * slower than reading the data because fseek flushes stdio's 1011 * internal buffers. See issue #8745. */ 1012 assert(header_size <= 3*0xFFFFu); 1013 for (i = name_size; i < header_size; i++) { 1014 if (getc(fp) == EOF) { 1015 goto file_error; 1016 } 1017 } 1018 1019 bootstrap = 0; 1020 if (flags & 0x0800) { 1021 charset = "utf-8"; 1022 } 1023 else if (!PyThreadState_GET()->interp->codecs_initialized) { 1024 /* During bootstrap, we may need to load the encodings 1025 package from a ZIP file. But the cp437 encoding is implemented 1026 in Python in the encodings package. 1027 1028 Break out of this dependency by assuming that the path to 1029 the encodings module is ASCII-only. */ 1030 charset = "ascii"; 1031 bootstrap = 1; 1032 } 1033 else { 1034 charset = "cp437"; 1035 } 1036 nameobj = PyUnicode_Decode(name, name_size, charset, NULL); 1037 if (nameobj == NULL) { 1038 if (bootstrap) { 1039 PyErr_Format(PyExc_NotImplementedError, 1040 "bootstrap issue: python%i%i.zip contains non-ASCII " 1041 "filenames without the unicode flag", 1042 PY_MAJOR_VERSION, PY_MINOR_VERSION); 1043 } 1044 goto error; 1045 } 1046 if (PyUnicode_READY(nameobj) == -1) { 1047 goto error; 1048 } 1049 path = PyUnicode_FromFormat("%U%c%U", archive, SEP, nameobj); 1050 if (path == NULL) { 1051 goto error; 1052 } 1053 t = Py_BuildValue("NHIIkHHI", path, compress, data_size, 1054 file_size, file_offset, time, date, crc); 1055 if (t == NULL) { 1056 goto error; 1057 } 1058 err = PyDict_SetItem(files, nameobj, t); 1059 Py_CLEAR(nameobj); 1060 Py_DECREF(t); 1061 if (err != 0) { 1062 goto error; 1063 } 1064 count++; 1065 } 1066 fclose(fp); 1067 if (Py_VerboseFlag) { 1068 PySys_FormatStderr("# zipimport: found %u names in %R\n", 1069 count, archive); 1070 } 1071 return files; 1072 1073eof_error: 1074 set_file_error(archive, !ferror(fp)); 1075 goto error; 1076 1077file_error: 1078 PyErr_Format(ZipImportError, "can't read Zip file: %R", archive); 1079 goto error; 1080 1081invalid_header: 1082 assert(errmsg != NULL); 1083 PyErr_Format(ZipImportError, "%s: %R", errmsg, archive); 1084 goto error; 1085 1086error: 1087 fclose(fp); 1088 Py_XDECREF(files); 1089 Py_XDECREF(nameobj); 1090 return NULL; 1091} 1092 1093/* Return the zlib.decompress function object, or NULL if zlib couldn't 1094 be imported. The function is cached when found, so subsequent calls 1095 don't import zlib again. */ 1096static PyObject * 1097get_decompress_func(void) 1098{ 1099 static int importing_zlib = 0; 1100 PyObject *zlib; 1101 PyObject *decompress; 1102 _Py_IDENTIFIER(decompress); 1103 1104 if (importing_zlib != 0) 1105 /* Someone has a zlib.py[co] in their Zip file; 1106 let's avoid a stack overflow. */ 1107 return NULL; 1108 importing_zlib = 1; 1109 zlib = PyImport_ImportModuleNoBlock("zlib"); 1110 importing_zlib = 0; 1111 if (zlib != NULL) { 1112 decompress = _PyObject_GetAttrId(zlib, 1113 &PyId_decompress); 1114 Py_DECREF(zlib); 1115 } 1116 else { 1117 PyErr_Clear(); 1118 decompress = NULL; 1119 } 1120 if (Py_VerboseFlag) 1121 PySys_WriteStderr("# zipimport: zlib %s\n", 1122 zlib != NULL ? "available": "UNAVAILABLE"); 1123 return decompress; 1124} 1125 1126/* Given a path to a Zip file and a toc_entry, return the (uncompressed) 1127 data as a new reference. */ 1128static PyObject * 1129get_data(PyObject *archive, PyObject *toc_entry) 1130{ 1131 PyObject *raw_data = NULL, *data, *decompress; 1132 char *buf; 1133 FILE *fp; 1134 PyObject *datapath; 1135 unsigned short compress, time, date; 1136 unsigned int crc; 1137 Py_ssize_t data_size, file_size, bytes_size; 1138 long file_offset, header_size; 1139 unsigned char buffer[30]; 1140 const char *errmsg = NULL; 1141 1142 if (!PyArg_ParseTuple(toc_entry, "OHnnlHHI", &datapath, &compress, 1143 &data_size, &file_size, &file_offset, &time, 1144 &date, &crc)) { 1145 return NULL; 1146 } 1147 if (data_size < 0) { 1148 PyErr_Format(ZipImportError, "negative data size"); 1149 return NULL; 1150 } 1151 1152 fp = _Py_fopen_obj(archive, "rb"); 1153 if (!fp) { 1154 return NULL; 1155 } 1156 /* Check to make sure the local file header is correct */ 1157 if (fseek(fp, file_offset, 0) == -1) { 1158 goto file_error; 1159 } 1160 if (fread(buffer, 1, 30, fp) != 30) { 1161 goto eof_error; 1162 } 1163 if (get_uint32(buffer) != 0x04034B50u) { 1164 /* Bad: Local File Header */ 1165 errmsg = "bad local file header"; 1166 goto invalid_header; 1167 } 1168 1169 header_size = (unsigned int)30 + 1170 get_uint16(buffer + 26) /* file name */ + 1171 get_uint16(buffer + 28) /* extra field */; 1172 if (file_offset > LONG_MAX - header_size) { 1173 errmsg = "bad local file header size"; 1174 goto invalid_header; 1175 } 1176 file_offset += header_size; /* Start of file data */ 1177 1178 if (data_size > LONG_MAX - 1) { 1179 fclose(fp); 1180 PyErr_NoMemory(); 1181 return NULL; 1182 } 1183 bytes_size = compress == 0 ? data_size : data_size + 1; 1184 if (bytes_size == 0) { 1185 bytes_size++; 1186 } 1187 raw_data = PyBytes_FromStringAndSize((char *)NULL, bytes_size); 1188 if (raw_data == NULL) { 1189 goto error; 1190 } 1191 buf = PyBytes_AsString(raw_data); 1192 1193 if (fseek(fp, file_offset, 0) == -1) { 1194 goto file_error; 1195 } 1196 if (fread(buf, 1, data_size, fp) != (size_t)data_size) { 1197 PyErr_SetString(PyExc_IOError, 1198 "zipimport: can't read data"); 1199 goto error; 1200 } 1201 1202 fclose(fp); 1203 fp = NULL; 1204 1205 if (compress != 0) { 1206 buf[data_size] = 'Z'; /* saw this in zipfile.py */ 1207 data_size++; 1208 } 1209 buf[data_size] = '\0'; 1210 1211 if (compress == 0) { /* data is not compressed */ 1212 data = PyBytes_FromStringAndSize(buf, data_size); 1213 Py_DECREF(raw_data); 1214 return data; 1215 } 1216 1217 /* Decompress with zlib */ 1218 decompress = get_decompress_func(); 1219 if (decompress == NULL) { 1220 PyErr_SetString(ZipImportError, 1221 "can't decompress data; " 1222 "zlib not available"); 1223 goto error; 1224 } 1225 data = PyObject_CallFunction(decompress, "Oi", raw_data, -15); 1226 Py_DECREF(decompress); 1227 Py_DECREF(raw_data); 1228 return data; 1229 1230eof_error: 1231 set_file_error(archive, !ferror(fp)); 1232 goto error; 1233 1234file_error: 1235 PyErr_Format(ZipImportError, "can't read Zip file: %R", archive); 1236 goto error; 1237 1238invalid_header: 1239 assert(errmsg != NULL); 1240 PyErr_Format(ZipImportError, "%s: %R", errmsg, archive); 1241 goto error; 1242 1243error: 1244 if (fp != NULL) { 1245 fclose(fp); 1246 } 1247 Py_XDECREF(raw_data); 1248 return NULL; 1249} 1250 1251/* Lenient date/time comparison function. The precision of the mtime 1252 in the archive is lower than the mtime stored in a .pyc: we 1253 must allow a difference of at most one second. */ 1254static int 1255eq_mtime(time_t t1, time_t t2) 1256{ 1257 time_t d = t1 - t2; 1258 if (d < 0) 1259 d = -d; 1260 /* dostime only stores even seconds, so be lenient */ 1261 return d <= 1; 1262} 1263 1264/* Given the contents of a .py[co] file in a buffer, unmarshal the data 1265 and return the code object. Return None if it the magic word doesn't 1266 match (we do this instead of raising an exception as we fall back 1267 to .py if available and we don't want to mask other errors). 1268 Returns a new reference. */ 1269static PyObject * 1270unmarshal_code(PyObject *pathname, PyObject *data, time_t mtime) 1271{ 1272 PyObject *code; 1273 unsigned char *buf = (unsigned char *)PyBytes_AsString(data); 1274 Py_ssize_t size = PyBytes_Size(data); 1275 1276 if (size < 12) { 1277 PyErr_SetString(ZipImportError, 1278 "bad pyc data"); 1279 return NULL; 1280 } 1281 1282 if (get_uint32(buf) != (unsigned int)PyImport_GetMagicNumber()) { 1283 if (Py_VerboseFlag) { 1284 PySys_FormatStderr("# %R has bad magic\n", 1285 pathname); 1286 } 1287 Py_INCREF(Py_None); 1288 return Py_None; /* signal caller to try alternative */ 1289 } 1290 1291 if (mtime != 0 && !eq_mtime(get_uint32(buf + 4), mtime)) { 1292 if (Py_VerboseFlag) { 1293 PySys_FormatStderr("# %R has bad mtime\n", 1294 pathname); 1295 } 1296 Py_INCREF(Py_None); 1297 return Py_None; /* signal caller to try alternative */ 1298 } 1299 1300 /* XXX the pyc's size field is ignored; timestamp collisions are probably 1301 unimportant with zip files. */ 1302 code = PyMarshal_ReadObjectFromString((char *)buf + 12, size - 12); 1303 if (code == NULL) { 1304 return NULL; 1305 } 1306 if (!PyCode_Check(code)) { 1307 Py_DECREF(code); 1308 PyErr_Format(PyExc_TypeError, 1309 "compiled module %R is not a code object", 1310 pathname); 1311 return NULL; 1312 } 1313 return code; 1314} 1315 1316/* Replace any occurrences of "\r\n?" in the input string with "\n". 1317 This converts DOS and Mac line endings to Unix line endings. 1318 Also append a trailing "\n" to be compatible with 1319 PyParser_SimpleParseFile(). Returns a new reference. */ 1320static PyObject * 1321normalize_line_endings(PyObject *source) 1322{ 1323 char *buf, *q, *p; 1324 PyObject *fixed_source; 1325 int len = 0; 1326 1327 p = PyBytes_AsString(source); 1328 if (p == NULL) { 1329 return PyBytes_FromStringAndSize("\n\0", 2); 1330 } 1331 1332 /* one char extra for trailing \n and one for terminating \0 */ 1333 buf = (char *)PyMem_Malloc(PyBytes_Size(source) + 2); 1334 if (buf == NULL) { 1335 PyErr_SetString(PyExc_MemoryError, 1336 "zipimport: no memory to allocate " 1337 "source buffer"); 1338 return NULL; 1339 } 1340 /* replace "\r\n?" by "\n" */ 1341 for (q = buf; *p != '\0'; p++) { 1342 if (*p == '\r') { 1343 *q++ = '\n'; 1344 if (*(p + 1) == '\n') 1345 p++; 1346 } 1347 else 1348 *q++ = *p; 1349 len++; 1350 } 1351 *q++ = '\n'; /* add trailing \n */ 1352 *q = '\0'; 1353 fixed_source = PyBytes_FromStringAndSize(buf, len + 2); 1354 PyMem_Free(buf); 1355 return fixed_source; 1356} 1357 1358/* Given a string buffer containing Python source code, compile it 1359 and return a code object as a new reference. */ 1360static PyObject * 1361compile_source(PyObject *pathname, PyObject *source) 1362{ 1363 PyObject *code, *fixed_source; 1364 1365 fixed_source = normalize_line_endings(source); 1366 if (fixed_source == NULL) { 1367 return NULL; 1368 } 1369 1370 code = Py_CompileStringObject(PyBytes_AsString(fixed_source), 1371 pathname, Py_file_input, NULL, -1); 1372 1373 Py_DECREF(fixed_source); 1374 return code; 1375} 1376 1377/* Convert the date/time values found in the Zip archive to a value 1378 that's compatible with the time stamp stored in .pyc files. */ 1379static time_t 1380parse_dostime(int dostime, int dosdate) 1381{ 1382 struct tm stm; 1383 1384 memset((void *) &stm, '\0', sizeof(stm)); 1385 1386 stm.tm_sec = (dostime & 0x1f) * 2; 1387 stm.tm_min = (dostime >> 5) & 0x3f; 1388 stm.tm_hour = (dostime >> 11) & 0x1f; 1389 stm.tm_mday = dosdate & 0x1f; 1390 stm.tm_mon = ((dosdate >> 5) & 0x0f) - 1; 1391 stm.tm_year = ((dosdate >> 9) & 0x7f) + 80; 1392 stm.tm_isdst = -1; /* wday/yday is ignored */ 1393 1394 return mktime(&stm); 1395} 1396 1397/* Given a path to a .pyc file in the archive, return the 1398 modification time of the matching .py file, or 0 if no source 1399 is available. */ 1400static time_t 1401get_mtime_of_source(ZipImporter *self, PyObject *path) 1402{ 1403 PyObject *toc_entry, *stripped; 1404 time_t mtime; 1405 1406 /* strip 'c' or 'o' from *.py[co] */ 1407 if (PyUnicode_READY(path) == -1) 1408 return (time_t)-1; 1409 stripped = PyUnicode_FromKindAndData(PyUnicode_KIND(path), 1410 PyUnicode_DATA(path), 1411 PyUnicode_GET_LENGTH(path) - 1); 1412 if (stripped == NULL) 1413 return (time_t)-1; 1414 1415 toc_entry = PyDict_GetItem(self->files, stripped); 1416 Py_DECREF(stripped); 1417 if (toc_entry != NULL && PyTuple_Check(toc_entry) && 1418 PyTuple_Size(toc_entry) == 8) { 1419 /* fetch the time stamp of the .py file for comparison 1420 with an embedded pyc time stamp */ 1421 int time, date; 1422 time = PyLong_AsLong(PyTuple_GetItem(toc_entry, 5)); 1423 date = PyLong_AsLong(PyTuple_GetItem(toc_entry, 6)); 1424 mtime = parse_dostime(time, date); 1425 } else 1426 mtime = 0; 1427 return mtime; 1428} 1429 1430/* Return the code object for the module named by 'fullname' from the 1431 Zip archive as a new reference. */ 1432static PyObject * 1433get_code_from_data(ZipImporter *self, int ispackage, int isbytecode, 1434 time_t mtime, PyObject *toc_entry) 1435{ 1436 PyObject *data, *modpath, *code; 1437 1438 data = get_data(self->archive, toc_entry); 1439 if (data == NULL) 1440 return NULL; 1441 1442 modpath = PyTuple_GetItem(toc_entry, 0); 1443 if (isbytecode) 1444 code = unmarshal_code(modpath, data, mtime); 1445 else 1446 code = compile_source(modpath, data); 1447 Py_DECREF(data); 1448 return code; 1449} 1450 1451/* Get the code object associated with the module specified by 1452 'fullname'. */ 1453static PyObject * 1454get_module_code(ZipImporter *self, PyObject *fullname, 1455 int *p_ispackage, PyObject **p_modpath) 1456{ 1457 PyObject *code = NULL, *toc_entry, *subname; 1458 PyObject *path, *fullpath = NULL; 1459 struct st_zip_searchorder *zso; 1460 1461 subname = get_subname(fullname); 1462 if (subname == NULL) 1463 return NULL; 1464 1465 path = make_filename(self->prefix, subname); 1466 Py_DECREF(subname); 1467 if (path == NULL) 1468 return NULL; 1469 1470 for (zso = zip_searchorder; *zso->suffix; zso++) { 1471 code = NULL; 1472 1473 fullpath = PyUnicode_FromFormat("%U%s", path, zso->suffix); 1474 if (fullpath == NULL) 1475 goto exit; 1476 1477 if (Py_VerboseFlag > 1) 1478 PySys_FormatStderr("# trying %U%c%U\n", 1479 self->archive, (int)SEP, fullpath); 1480 toc_entry = PyDict_GetItem(self->files, fullpath); 1481 if (toc_entry != NULL) { 1482 time_t mtime = 0; 1483 int ispackage = zso->type & IS_PACKAGE; 1484 int isbytecode = zso->type & IS_BYTECODE; 1485 1486 if (isbytecode) { 1487 mtime = get_mtime_of_source(self, fullpath); 1488 if (mtime == (time_t)-1 && PyErr_Occurred()) { 1489 goto exit; 1490 } 1491 } 1492 Py_CLEAR(fullpath); 1493 if (p_ispackage != NULL) 1494 *p_ispackage = ispackage; 1495 code = get_code_from_data(self, ispackage, 1496 isbytecode, mtime, 1497 toc_entry); 1498 if (code == Py_None) { 1499 /* bad magic number or non-matching mtime 1500 in byte code, try next */ 1501 Py_DECREF(code); 1502 continue; 1503 } 1504 if (code != NULL && p_modpath != NULL) { 1505 *p_modpath = PyTuple_GetItem(toc_entry, 0); 1506 Py_INCREF(*p_modpath); 1507 } 1508 goto exit; 1509 } 1510 else 1511 Py_CLEAR(fullpath); 1512 } 1513 PyErr_Format(ZipImportError, "can't find module %R", fullname); 1514exit: 1515 Py_DECREF(path); 1516 Py_XDECREF(fullpath); 1517 return code; 1518} 1519 1520 1521/* Module init */ 1522 1523PyDoc_STRVAR(zipimport_doc, 1524"zipimport provides support for importing Python modules from Zip archives.\n\ 1525\n\ 1526This module exports three objects:\n\ 1527- zipimporter: a class; its constructor takes a path to a Zip archive.\n\ 1528- ZipImportError: exception raised by zipimporter objects. It's a\n\ 1529 subclass of ImportError, so it can be caught as ImportError, too.\n\ 1530- _zip_directory_cache: a dict, mapping archive paths to zip directory\n\ 1531 info dicts, as used in zipimporter._files.\n\ 1532\n\ 1533It is usually not needed to use the zipimport module explicitly; it is\n\ 1534used by the builtin import mechanism for sys.path items that are paths\n\ 1535to Zip archives."); 1536 1537static struct PyModuleDef zipimportmodule = { 1538 PyModuleDef_HEAD_INIT, 1539 "zipimport", 1540 zipimport_doc, 1541 -1, 1542 NULL, 1543 NULL, 1544 NULL, 1545 NULL, 1546 NULL 1547}; 1548 1549PyMODINIT_FUNC 1550PyInit_zipimport(void) 1551{ 1552 PyObject *mod; 1553 1554 if (PyType_Ready(&ZipImporter_Type) < 0) 1555 return NULL; 1556 1557 /* Correct directory separator */ 1558 zip_searchorder[0].suffix[0] = SEP; 1559 zip_searchorder[1].suffix[0] = SEP; 1560 1561 mod = PyModule_Create(&zipimportmodule); 1562 if (mod == NULL) 1563 return NULL; 1564 1565 ZipImportError = PyErr_NewException("zipimport.ZipImportError", 1566 PyExc_ImportError, NULL); 1567 if (ZipImportError == NULL) 1568 return NULL; 1569 1570 Py_INCREF(ZipImportError); 1571 if (PyModule_AddObject(mod, "ZipImportError", 1572 ZipImportError) < 0) 1573 return NULL; 1574 1575 Py_INCREF(&ZipImporter_Type); 1576 if (PyModule_AddObject(mod, "zipimporter", 1577 (PyObject *)&ZipImporter_Type) < 0) 1578 return NULL; 1579 1580 zip_directory_cache = PyDict_New(); 1581 if (zip_directory_cache == NULL) 1582 return NULL; 1583 Py_INCREF(zip_directory_cache); 1584 if (PyModule_AddObject(mod, "_zip_directory_cache", 1585 zip_directory_cache) < 0) 1586 return NULL; 1587 return mod; 1588} 1589