annotate Lib/zipfile.py @ 87690:66c1c9f32567 default tip

Add use_weakref option to functools.lru_cache The use_weakref option makes lru_cache create weak references to the function arguments when creating the cache key, which prevents them from staying in the memory forever even after all other references to them are gone. This is a proof of concept for http://bugs.python.org/issue19859
author Radomir Dopieralski <devel@sheep.art.pl>
date Tue, 03 Dec 2013 16:02:48 +0100
parents 70bd6f7e013b
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
39442
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36609
diff changeset
1 """
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36609
diff changeset
2 Read and write ZIP files.
41812
50dafa22b8a4 Make test_zipfile pass.
Guido van Rossum <guido@python.org>
parents: 41760
diff changeset
3
50dafa22b8a4 Make test_zipfile pass.
Guido van Rossum <guido@python.org>
parents: 41760
diff changeset
4 XXX references to utf-8 need further investigation.
39442
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36609
diff changeset
5 """
58542
f41d353eb660 Merged revisions 77798 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58004
diff changeset
6 import io
60648
7b69e630d237 PEP 3147
Barry Warsaw <barry@python.org>
parents: 58822
diff changeset
7 import os
58542
f41d353eb660 Merged revisions 77798 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58004
diff changeset
8 import re
84155
f96eb1dc335f Issue #17177: Stop using imp in zipfile
Brett Cannon <brett@python.org>
parents: 84106
diff changeset
9 import importlib.util
60648
7b69e630d237 PEP 3147
Barry Warsaw <barry@python.org>
parents: 58822
diff changeset
10 import sys
7b69e630d237 PEP 3147
Barry Warsaw <barry@python.org>
parents: 58822
diff changeset
11 import time
7b69e630d237 PEP 3147
Barry Warsaw <barry@python.org>
parents: 58822
diff changeset
12 import stat
7b69e630d237 PEP 3147
Barry Warsaw <barry@python.org>
parents: 58822
diff changeset
13 import shutil
7b69e630d237 PEP 3147
Barry Warsaw <barry@python.org>
parents: 58822
diff changeset
14 import struct
7b69e630d237 PEP 3147
Barry Warsaw <barry@python.org>
parents: 58822
diff changeset
15 import binascii
7b69e630d237 PEP 3147
Barry Warsaw <barry@python.org>
parents: 58822
diff changeset
16
12197
7f18f979a93a Zip file handling module, by Jim Ahlstrom.
Guido van Rossum <guido@python.org>
parents:
diff changeset
17
7f18f979a93a Zip file handling module, by Jim Ahlstrom.
Guido van Rossum <guido@python.org>
parents:
diff changeset
18 try:
15874
4c01ee0a8073 Whitespace normalization. Top level of Lib now fixed-point for reindent.py!
Tim Peters <tim.peters@gmail.com>
parents: 14975
diff changeset
19 import zlib # We may need its compression method
45931
1657f0acca78 Merged revisions 61538-61540,61556,61559-61560,61563,61565,61571,61575-61576,61580-61582,61586,61591,61593,61595,61605-61606,61613-61616,61618,61621-61623,61625,61627,61631-61634 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 44810
diff changeset
20 crc32 = zlib.crc32
17377
5f68754eb3b6 Try an except: after an import into "except ImportError".
Guido van Rossum <guido@python.org>
parents: 17312
diff changeset
21 except ImportError:
12197
7f18f979a93a Zip file handling module, by Jim Ahlstrom.
Guido van Rossum <guido@python.org>
parents:
diff changeset
22 zlib = None
45931
1657f0acca78 Merged revisions 61538-61540,61556,61559-61560,61563,61565,61571,61575-61576,61580-61582,61586,61591,61593,61595,61605-61606,61613-61616,61618,61621-61623,61625,61627,61631-61634 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 44810
diff changeset
23 crc32 = binascii.crc32
12197
7f18f979a93a Zip file handling module, by Jim Ahlstrom.
Guido van Rossum <guido@python.org>
parents:
diff changeset
24
76682
028e8e0b03e8 Issue #14371: Support bzip2 in zipfile module.
Martin v. Löwis <martin@v.loewis.de>
parents: 76373
diff changeset
25 try:
028e8e0b03e8 Issue #14371: Support bzip2 in zipfile module.
Martin v. Löwis <martin@v.loewis.de>
parents: 76373
diff changeset
26 import bz2 # We may need its compression method
028e8e0b03e8 Issue #14371: Support bzip2 in zipfile module.
Martin v. Löwis <martin@v.loewis.de>
parents: 76373
diff changeset
27 except ImportError:
028e8e0b03e8 Issue #14371: Support bzip2 in zipfile module.
Martin v. Löwis <martin@v.loewis.de>
parents: 76373
diff changeset
28 bz2 = None
028e8e0b03e8 Issue #14371: Support bzip2 in zipfile module.
Martin v. Löwis <martin@v.loewis.de>
parents: 76373
diff changeset
29
76895
fccdcd83708a Issue #14366: Support lzma compression in zip files.
Martin v. Löwis <martin@v.loewis.de>
parents: 76694
diff changeset
30 try:
fccdcd83708a Issue #14366: Support lzma compression in zip files.
Martin v. Löwis <martin@v.loewis.de>
parents: 76694
diff changeset
31 import lzma # We may need its compression method
fccdcd83708a Issue #14366: Support lzma compression in zip files.
Martin v. Löwis <martin@v.loewis.de>
parents: 76694
diff changeset
32 except ImportError:
fccdcd83708a Issue #14366: Support lzma compression in zip files.
Martin v. Löwis <martin@v.loewis.de>
parents: 76694
diff changeset
33 lzma = None
fccdcd83708a Issue #14366: Support lzma compression in zip files.
Martin v. Löwis <martin@v.loewis.de>
parents: 76694
diff changeset
34
76682
028e8e0b03e8 Issue #14371: Support bzip2 in zipfile module.
Martin v. Löwis <martin@v.loewis.de>
parents: 76373
diff changeset
35 __all__ = ["BadZipFile", "BadZipfile", "error",
76895
fccdcd83708a Issue #14366: Support lzma compression in zip files.
Martin v. Löwis <martin@v.loewis.de>
parents: 76694
diff changeset
36 "ZIP_STORED", "ZIP_DEFLATED", "ZIP_BZIP2", "ZIP_LZMA",
65673
a281989a218b #7351: add more consistent exception name alias.
Georg Brandl <georg@python.org>
parents: 65290
diff changeset
37 "is_zipfile", "ZipInfo", "ZipFile", "PyZipFile", "LargeZipFile"]
16889
0feb63490093 final round of __all__ lists (I hope) - skipped urllib2 because Moshe may be
Skip Montanaro <skip@pobox.com>
parents: 16840
diff changeset
38
65673
a281989a218b #7351: add more consistent exception name alias.
Georg Brandl <georg@python.org>
parents: 65290
diff changeset
39 class BadZipFile(Exception):
12197
7f18f979a93a Zip file handling module, by Jim Ahlstrom.
Guido van Rossum <guido@python.org>
parents:
diff changeset
40 pass
39442
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36609
diff changeset
41
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36609
diff changeset
42
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36609
diff changeset
43 class LargeZipFile(Exception):
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36609
diff changeset
44 """
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36609
diff changeset
45 Raised when writing a zipfile, the zipfile requires ZIP64 extensions
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36609
diff changeset
46 and those extensions are disabled.
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36609
diff changeset
47 """
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36609
diff changeset
48
65673
a281989a218b #7351: add more consistent exception name alias.
Georg Brandl <georg@python.org>
parents: 65290
diff changeset
49 error = BadZipfile = BadZipFile # Pre-3.2 compatibility names
a281989a218b #7351: add more consistent exception name alias.
Georg Brandl <georg@python.org>
parents: 65290
diff changeset
50
12197
7f18f979a93a Zip file handling module, by Jim Ahlstrom.
Guido van Rossum <guido@python.org>
parents:
diff changeset
51
50825
1aad7d2e8945 Merged revisions 68661 via svnmerge from
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 50301
diff changeset
52 ZIP64_LIMIT = (1 << 31) - 1
48423
cdaac79a7237 Merged revisions 64688 via svnmerge from
Martin v. Löwis <martin@v.loewis.de>
parents: 47278
diff changeset
53 ZIP_FILECOUNT_LIMIT = 1 << 16
cdaac79a7237 Merged revisions 64688 via svnmerge from
Martin v. Löwis <martin@v.loewis.de>
parents: 47278
diff changeset
54 ZIP_MAX_COMMENT = (1 << 16) - 1
39442
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36609
diff changeset
55
12197
7f18f979a93a Zip file handling module, by Jim Ahlstrom.
Guido van Rossum <guido@python.org>
parents:
diff changeset
56 # constants for Zip file compression methods
7f18f979a93a Zip file handling module, by Jim Ahlstrom.
Guido van Rossum <guido@python.org>
parents:
diff changeset
57 ZIP_STORED = 0
7f18f979a93a Zip file handling module, by Jim Ahlstrom.
Guido van Rossum <guido@python.org>
parents:
diff changeset
58 ZIP_DEFLATED = 8
76682
028e8e0b03e8 Issue #14371: Support bzip2 in zipfile module.
Martin v. Löwis <martin@v.loewis.de>
parents: 76373
diff changeset
59 ZIP_BZIP2 = 12
76895
fccdcd83708a Issue #14366: Support lzma compression in zip files.
Martin v. Löwis <martin@v.loewis.de>
parents: 76694
diff changeset
60 ZIP_LZMA = 14
12197
7f18f979a93a Zip file handling module, by Jim Ahlstrom.
Guido van Rossum <guido@python.org>
parents:
diff changeset
61 # Other ZIP compression methods not supported
7f18f979a93a Zip file handling module, by Jim Ahlstrom.
Guido van Rossum <guido@python.org>
parents:
diff changeset
62
76682
028e8e0b03e8 Issue #14371: Support bzip2 in zipfile module.
Martin v. Löwis <martin@v.loewis.de>
parents: 76373
diff changeset
63 DEFAULT_VERSION = 20
028e8e0b03e8 Issue #14371: Support bzip2 in zipfile module.
Martin v. Löwis <martin@v.loewis.de>
parents: 76373
diff changeset
64 ZIP64_VERSION = 45
028e8e0b03e8 Issue #14371: Support bzip2 in zipfile module.
Martin v. Löwis <martin@v.loewis.de>
parents: 76373
diff changeset
65 BZIP2_VERSION = 46
76895
fccdcd83708a Issue #14366: Support lzma compression in zip files.
Martin v. Löwis <martin@v.loewis.de>
parents: 76694
diff changeset
66 LZMA_VERSION = 63
76694
66741dd4fabf Check extract_version when opening a zipfile.
Martin v. Löwis <martin@v.loewis.de>
parents: 76685
diff changeset
67 # we recognize (but not necessarily support) all features up to that version
76895
fccdcd83708a Issue #14366: Support lzma compression in zip files.
Martin v. Löwis <martin@v.loewis.de>
parents: 76694
diff changeset
68 MAX_EXTRACT_VERSION = 63
76682
028e8e0b03e8 Issue #14371: Support bzip2 in zipfile module.
Martin v. Löwis <martin@v.loewis.de>
parents: 76373
diff changeset
69
48423
cdaac79a7237 Merged revisions 64688 via svnmerge from
Martin v. Löwis <martin@v.loewis.de>
parents: 47278
diff changeset
70 # Below are some formats and associated data for reading/writing headers using
cdaac79a7237 Merged revisions 64688 via svnmerge from
Martin v. Löwis <martin@v.loewis.de>
parents: 47278
diff changeset
71 # the struct module. The names and structures of headers/records are those used
cdaac79a7237 Merged revisions 64688 via svnmerge from
Martin v. Löwis <martin@v.loewis.de>
parents: 47278
diff changeset
72 # in the PKWARE description of the ZIP file format:
cdaac79a7237 Merged revisions 64688 via svnmerge from
Martin v. Löwis <martin@v.loewis.de>
parents: 47278
diff changeset
73 # http://www.pkware.com/documents/casestudies/APPNOTE.TXT
cdaac79a7237 Merged revisions 64688 via svnmerge from
Martin v. Löwis <martin@v.loewis.de>
parents: 47278
diff changeset
74 # (URL valid as of January 2008)
cdaac79a7237 Merged revisions 64688 via svnmerge from
Martin v. Löwis <martin@v.loewis.de>
parents: 47278
diff changeset
75
cdaac79a7237 Merged revisions 64688 via svnmerge from
Martin v. Löwis <martin@v.loewis.de>
parents: 47278
diff changeset
76 # The "end of central directory" structure, magic number, size, and indices
cdaac79a7237 Merged revisions 64688 via svnmerge from
Martin v. Löwis <martin@v.loewis.de>
parents: 47278
diff changeset
77 # (section V.I in the format document)
48499
de0bf60f1245 Merged revisions 64722,64729,64753,64845-64846,64849,64871,64880-64882,64885,64888,64897,64900-64901,64915,64926-64929,64938-64941,64944,64961,64966,64973 via svnmerge from
Georg Brandl <georg@python.org>
parents: 48423
diff changeset
78 structEndArchive = b"<4s4H2LH"
de0bf60f1245 Merged revisions 64722,64729,64753,64845-64846,64849,64871,64880-64882,64885,64888,64897,64900-64901,64915,64926-64929,64938-64941,64944,64961,64966,64973 via svnmerge from
Georg Brandl <georg@python.org>
parents: 48423
diff changeset
79 stringEndArchive = b"PK\005\006"
de0bf60f1245 Merged revisions 64722,64729,64753,64845-64846,64849,64871,64880-64882,64885,64888,64897,64900-64901,64915,64926-64929,64938-64941,64944,64961,64966,64973 via svnmerge from
Georg Brandl <georg@python.org>
parents: 48423
diff changeset
80 sizeEndCentDir = struct.calcsize(structEndArchive)
48423
cdaac79a7237 Merged revisions 64688 via svnmerge from
Martin v. Löwis <martin@v.loewis.de>
parents: 47278
diff changeset
81
cdaac79a7237 Merged revisions 64688 via svnmerge from
Martin v. Löwis <martin@v.loewis.de>
parents: 47278
diff changeset
82 _ECD_SIGNATURE = 0
cdaac79a7237 Merged revisions 64688 via svnmerge from
Martin v. Löwis <martin@v.loewis.de>
parents: 47278
diff changeset
83 _ECD_DISK_NUMBER = 1
cdaac79a7237 Merged revisions 64688 via svnmerge from
Martin v. Löwis <martin@v.loewis.de>
parents: 47278
diff changeset
84 _ECD_DISK_START = 2
cdaac79a7237 Merged revisions 64688 via svnmerge from
Martin v. Löwis <martin@v.loewis.de>
parents: 47278
diff changeset
85 _ECD_ENTRIES_THIS_DISK = 3
cdaac79a7237 Merged revisions 64688 via svnmerge from
Martin v. Löwis <martin@v.loewis.de>
parents: 47278
diff changeset
86 _ECD_ENTRIES_TOTAL = 4
cdaac79a7237 Merged revisions 64688 via svnmerge from
Martin v. Löwis <martin@v.loewis.de>
parents: 47278
diff changeset
87 _ECD_SIZE = 5
cdaac79a7237 Merged revisions 64688 via svnmerge from
Martin v. Löwis <martin@v.loewis.de>
parents: 47278
diff changeset
88 _ECD_OFFSET = 6
cdaac79a7237 Merged revisions 64688 via svnmerge from
Martin v. Löwis <martin@v.loewis.de>
parents: 47278
diff changeset
89 _ECD_COMMENT_SIZE = 7
cdaac79a7237 Merged revisions 64688 via svnmerge from
Martin v. Löwis <martin@v.loewis.de>
parents: 47278
diff changeset
90 # These last two indices are not part of the structure as defined in the
cdaac79a7237 Merged revisions 64688 via svnmerge from
Martin v. Löwis <martin@v.loewis.de>
parents: 47278
diff changeset
91 # spec, but they are used internally by this module as a convenience
cdaac79a7237 Merged revisions 64688 via svnmerge from
Martin v. Löwis <martin@v.loewis.de>
parents: 47278
diff changeset
92 _ECD_COMMENT = 8
cdaac79a7237 Merged revisions 64688 via svnmerge from
Martin v. Löwis <martin@v.loewis.de>
parents: 47278
diff changeset
93 _ECD_LOCATION = 9
39442
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36609
diff changeset
94
48423
cdaac79a7237 Merged revisions 64688 via svnmerge from
Martin v. Löwis <martin@v.loewis.de>
parents: 47278
diff changeset
95 # The "central directory" structure, magic number, size, and indices
cdaac79a7237 Merged revisions 64688 via svnmerge from
Martin v. Löwis <martin@v.loewis.de>
parents: 47278
diff changeset
96 # of entries in the structure (section V.F in the format document)
cdaac79a7237 Merged revisions 64688 via svnmerge from
Martin v. Löwis <martin@v.loewis.de>
parents: 47278
diff changeset
97 structCentralDir = "<4s4B4HL2L5H2L"
48499
de0bf60f1245 Merged revisions 64722,64729,64753,64845-64846,64849,64871,64880-64882,64885,64888,64897,64900-64901,64915,64926-64929,64938-64941,64944,64961,64966,64973 via svnmerge from
Georg Brandl <georg@python.org>
parents: 48423
diff changeset
98 stringCentralDir = b"PK\001\002"
48423
cdaac79a7237 Merged revisions 64688 via svnmerge from
Martin v. Löwis <martin@v.loewis.de>
parents: 47278
diff changeset
99 sizeCentralDir = struct.calcsize(structCentralDir)
cdaac79a7237 Merged revisions 64688 via svnmerge from
Martin v. Löwis <martin@v.loewis.de>
parents: 47278
diff changeset
100
16840
950fc2261da4 Define lots of constants for indexes into the structures for the file
Fred Drake <fdrake@acm.org>
parents: 16826
diff changeset
101 # indexes of entries in the central directory structure
950fc2261da4 Define lots of constants for indexes into the structures for the file
Fred Drake <fdrake@acm.org>
parents: 16826
diff changeset
102 _CD_SIGNATURE = 0
950fc2261da4 Define lots of constants for indexes into the structures for the file
Fred Drake <fdrake@acm.org>
parents: 16826
diff changeset
103 _CD_CREATE_VERSION = 1
950fc2261da4 Define lots of constants for indexes into the structures for the file
Fred Drake <fdrake@acm.org>
parents: 16826
diff changeset
104 _CD_CREATE_SYSTEM = 2
950fc2261da4 Define lots of constants for indexes into the structures for the file
Fred Drake <fdrake@acm.org>
parents: 16826
diff changeset
105 _CD_EXTRACT_VERSION = 3
48423
cdaac79a7237 Merged revisions 64688 via svnmerge from
Martin v. Löwis <martin@v.loewis.de>
parents: 47278
diff changeset
106 _CD_EXTRACT_SYSTEM = 4
16840
950fc2261da4 Define lots of constants for indexes into the structures for the file
Fred Drake <fdrake@acm.org>
parents: 16826
diff changeset
107 _CD_FLAG_BITS = 5
950fc2261da4 Define lots of constants for indexes into the structures for the file
Fred Drake <fdrake@acm.org>
parents: 16826
diff changeset
108 _CD_COMPRESS_TYPE = 6
950fc2261da4 Define lots of constants for indexes into the structures for the file
Fred Drake <fdrake@acm.org>
parents: 16826
diff changeset
109 _CD_TIME = 7
950fc2261da4 Define lots of constants for indexes into the structures for the file
Fred Drake <fdrake@acm.org>
parents: 16826
diff changeset
110 _CD_DATE = 8
950fc2261da4 Define lots of constants for indexes into the structures for the file
Fred Drake <fdrake@acm.org>
parents: 16826
diff changeset
111 _CD_CRC = 9
950fc2261da4 Define lots of constants for indexes into the structures for the file
Fred Drake <fdrake@acm.org>
parents: 16826
diff changeset
112 _CD_COMPRESSED_SIZE = 10
950fc2261da4 Define lots of constants for indexes into the structures for the file
Fred Drake <fdrake@acm.org>
parents: 16826
diff changeset
113 _CD_UNCOMPRESSED_SIZE = 11
950fc2261da4 Define lots of constants for indexes into the structures for the file
Fred Drake <fdrake@acm.org>
parents: 16826
diff changeset
114 _CD_FILENAME_LENGTH = 12
950fc2261da4 Define lots of constants for indexes into the structures for the file
Fred Drake <fdrake@acm.org>
parents: 16826
diff changeset
115 _CD_EXTRA_FIELD_LENGTH = 13
950fc2261da4 Define lots of constants for indexes into the structures for the file
Fred Drake <fdrake@acm.org>
parents: 16826
diff changeset
116 _CD_COMMENT_LENGTH = 14
950fc2261da4 Define lots of constants for indexes into the structures for the file
Fred Drake <fdrake@acm.org>
parents: 16826
diff changeset
117 _CD_DISK_NUMBER_START = 15
950fc2261da4 Define lots of constants for indexes into the structures for the file
Fred Drake <fdrake@acm.org>
parents: 16826
diff changeset
118 _CD_INTERNAL_FILE_ATTRIBUTES = 16
950fc2261da4 Define lots of constants for indexes into the structures for the file
Fred Drake <fdrake@acm.org>
parents: 16826
diff changeset
119 _CD_EXTERNAL_FILE_ATTRIBUTES = 17
950fc2261da4 Define lots of constants for indexes into the structures for the file
Fred Drake <fdrake@acm.org>
parents: 16826
diff changeset
120 _CD_LOCAL_HEADER_OFFSET = 18
950fc2261da4 Define lots of constants for indexes into the structures for the file
Fred Drake <fdrake@acm.org>
parents: 16826
diff changeset
121
48423
cdaac79a7237 Merged revisions 64688 via svnmerge from
Martin v. Löwis <martin@v.loewis.de>
parents: 47278
diff changeset
122 # The "local file header" structure, magic number, size, and indices
cdaac79a7237 Merged revisions 64688 via svnmerge from
Martin v. Löwis <martin@v.loewis.de>
parents: 47278
diff changeset
123 # (section V.A in the format document)
cdaac79a7237 Merged revisions 64688 via svnmerge from
Martin v. Löwis <martin@v.loewis.de>
parents: 47278
diff changeset
124 structFileHeader = "<4s2B4HL2L2H"
48499
de0bf60f1245 Merged revisions 64722,64729,64753,64845-64846,64849,64871,64880-64882,64885,64888,64897,64900-64901,64915,64926-64929,64938-64941,64944,64961,64966,64973 via svnmerge from
Georg Brandl <georg@python.org>
parents: 48423
diff changeset
125 stringFileHeader = b"PK\003\004"
48423
cdaac79a7237 Merged revisions 64688 via svnmerge from
Martin v. Löwis <martin@v.loewis.de>
parents: 47278
diff changeset
126 sizeFileHeader = struct.calcsize(structFileHeader)
cdaac79a7237 Merged revisions 64688 via svnmerge from
Martin v. Löwis <martin@v.loewis.de>
parents: 47278
diff changeset
127
16840
950fc2261da4 Define lots of constants for indexes into the structures for the file
Fred Drake <fdrake@acm.org>
parents: 16826
diff changeset
128 _FH_SIGNATURE = 0
950fc2261da4 Define lots of constants for indexes into the structures for the file
Fred Drake <fdrake@acm.org>
parents: 16826
diff changeset
129 _FH_EXTRACT_VERSION = 1
48423
cdaac79a7237 Merged revisions 64688 via svnmerge from
Martin v. Löwis <martin@v.loewis.de>
parents: 47278
diff changeset
130 _FH_EXTRACT_SYSTEM = 2
16840
950fc2261da4 Define lots of constants for indexes into the structures for the file
Fred Drake <fdrake@acm.org>
parents: 16826
diff changeset
131 _FH_GENERAL_PURPOSE_FLAG_BITS = 3
950fc2261da4 Define lots of constants for indexes into the structures for the file
Fred Drake <fdrake@acm.org>
parents: 16826
diff changeset
132 _FH_COMPRESSION_METHOD = 4
950fc2261da4 Define lots of constants for indexes into the structures for the file
Fred Drake <fdrake@acm.org>
parents: 16826
diff changeset
133 _FH_LAST_MOD_TIME = 5
950fc2261da4 Define lots of constants for indexes into the structures for the file
Fred Drake <fdrake@acm.org>
parents: 16826
diff changeset
134 _FH_LAST_MOD_DATE = 6
950fc2261da4 Define lots of constants for indexes into the structures for the file
Fred Drake <fdrake@acm.org>
parents: 16826
diff changeset
135 _FH_CRC = 7
950fc2261da4 Define lots of constants for indexes into the structures for the file
Fred Drake <fdrake@acm.org>
parents: 16826
diff changeset
136 _FH_COMPRESSED_SIZE = 8
950fc2261da4 Define lots of constants for indexes into the structures for the file
Fred Drake <fdrake@acm.org>
parents: 16826
diff changeset
137 _FH_UNCOMPRESSED_SIZE = 9
950fc2261da4 Define lots of constants for indexes into the structures for the file
Fred Drake <fdrake@acm.org>
parents: 16826
diff changeset
138 _FH_FILENAME_LENGTH = 10
950fc2261da4 Define lots of constants for indexes into the structures for the file
Fred Drake <fdrake@acm.org>
parents: 16826
diff changeset
139 _FH_EXTRA_FIELD_LENGTH = 11
950fc2261da4 Define lots of constants for indexes into the structures for the file
Fred Drake <fdrake@acm.org>
parents: 16826
diff changeset
140
48423
cdaac79a7237 Merged revisions 64688 via svnmerge from
Martin v. Löwis <martin@v.loewis.de>
parents: 47278
diff changeset
141 # The "Zip64 end of central directory locator" structure, magic number, and size
48499
de0bf60f1245 Merged revisions 64722,64729,64753,64845-64846,64849,64871,64880-64882,64885,64888,64897,64900-64901,64915,64926-64929,64938-64941,64944,64961,64966,64973 via svnmerge from
Georg Brandl <georg@python.org>
parents: 48423
diff changeset
142 structEndArchive64Locator = "<4sLQL"
de0bf60f1245 Merged revisions 64722,64729,64753,64845-64846,64849,64871,64880-64882,64885,64888,64897,64900-64901,64915,64926-64929,64938-64941,64944,64961,64966,64973 via svnmerge from
Georg Brandl <georg@python.org>
parents: 48423
diff changeset
143 stringEndArchive64Locator = b"PK\x06\x07"
de0bf60f1245 Merged revisions 64722,64729,64753,64845-64846,64849,64871,64880-64882,64885,64888,64897,64900-64901,64915,64926-64929,64938-64941,64944,64961,64966,64973 via svnmerge from
Georg Brandl <georg@python.org>
parents: 48423
diff changeset
144 sizeEndCentDir64Locator = struct.calcsize(structEndArchive64Locator)
48423
cdaac79a7237 Merged revisions 64688 via svnmerge from
Martin v. Löwis <martin@v.loewis.de>
parents: 47278
diff changeset
145
cdaac79a7237 Merged revisions 64688 via svnmerge from
Martin v. Löwis <martin@v.loewis.de>
parents: 47278
diff changeset
146 # The "Zip64 end of central directory" record, magic number, size, and indices
cdaac79a7237 Merged revisions 64688 via svnmerge from
Martin v. Löwis <martin@v.loewis.de>
parents: 47278
diff changeset
147 # (section V.G in the format document)
48499
de0bf60f1245 Merged revisions 64722,64729,64753,64845-64846,64849,64871,64880-64882,64885,64888,64897,64900-64901,64915,64926-64929,64938-64941,64944,64961,64966,64973 via svnmerge from
Georg Brandl <georg@python.org>
parents: 48423
diff changeset
148 structEndArchive64 = "<4sQ2H2L4Q"
de0bf60f1245 Merged revisions 64722,64729,64753,64845-64846,64849,64871,64880-64882,64885,64888,64897,64900-64901,64915,64926-64929,64938-64941,64944,64961,64966,64973 via svnmerge from
Georg Brandl <georg@python.org>
parents: 48423
diff changeset
149 stringEndArchive64 = b"PK\x06\x06"
de0bf60f1245 Merged revisions 64722,64729,64753,64845-64846,64849,64871,64880-64882,64885,64888,64897,64900-64901,64915,64926-64929,64938-64941,64944,64961,64966,64973 via svnmerge from
Georg Brandl <georg@python.org>
parents: 48423
diff changeset
150 sizeEndCentDir64 = struct.calcsize(structEndArchive64)
48423
cdaac79a7237 Merged revisions 64688 via svnmerge from
Martin v. Löwis <martin@v.loewis.de>
parents: 47278
diff changeset
151
cdaac79a7237 Merged revisions 64688 via svnmerge from
Martin v. Löwis <martin@v.loewis.de>
parents: 47278
diff changeset
152 _CD64_SIGNATURE = 0
cdaac79a7237 Merged revisions 64688 via svnmerge from
Martin v. Löwis <martin@v.loewis.de>
parents: 47278
diff changeset
153 _CD64_DIRECTORY_RECSIZE = 1
cdaac79a7237 Merged revisions 64688 via svnmerge from
Martin v. Löwis <martin@v.loewis.de>
parents: 47278
diff changeset
154 _CD64_CREATE_VERSION = 2
cdaac79a7237 Merged revisions 64688 via svnmerge from
Martin v. Löwis <martin@v.loewis.de>
parents: 47278
diff changeset
155 _CD64_EXTRACT_VERSION = 3
cdaac79a7237 Merged revisions 64688 via svnmerge from
Martin v. Löwis <martin@v.loewis.de>
parents: 47278
diff changeset
156 _CD64_DISK_NUMBER = 4
cdaac79a7237 Merged revisions 64688 via svnmerge from
Martin v. Löwis <martin@v.loewis.de>
parents: 47278
diff changeset
157 _CD64_DISK_NUMBER_START = 5
cdaac79a7237 Merged revisions 64688 via svnmerge from
Martin v. Löwis <martin@v.loewis.de>
parents: 47278
diff changeset
158 _CD64_NUMBER_ENTRIES_THIS_DISK = 6
cdaac79a7237 Merged revisions 64688 via svnmerge from
Martin v. Löwis <martin@v.loewis.de>
parents: 47278
diff changeset
159 _CD64_NUMBER_ENTRIES_TOTAL = 7
cdaac79a7237 Merged revisions 64688 via svnmerge from
Martin v. Löwis <martin@v.loewis.de>
parents: 47278
diff changeset
160 _CD64_DIRECTORY_SIZE = 8
cdaac79a7237 Merged revisions 64688 via svnmerge from
Martin v. Löwis <martin@v.loewis.de>
parents: 47278
diff changeset
161 _CD64_OFFSET_START_CENTDIR = 9
cdaac79a7237 Merged revisions 64688 via svnmerge from
Martin v. Löwis <martin@v.loewis.de>
parents: 47278
diff changeset
162
50301
fec72c9b271d Merged revisions 67946 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 49037
diff changeset
163 def _check_zipfile(fp):
12197
7f18f979a93a Zip file handling module, by Jim Ahlstrom.
Guido van Rossum <guido@python.org>
parents:
diff changeset
164 try:
50301
fec72c9b271d Merged revisions 67946 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 49037
diff changeset
165 if _EndRecData(fp):
fec72c9b271d Merged revisions 67946 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 49037
diff changeset
166 return True # file has correct magic number
81039
7d69d04522e3 Replace IOError with OSError (#16715)
Andrew Svetlov <andrew.svetlov@gmail.com>
parents: 80502
diff changeset
167 except OSError:
12197
7f18f979a93a Zip file handling module, by Jim Ahlstrom.
Guido van Rossum <guido@python.org>
parents:
diff changeset
168 pass
22867
e2f2187c3d2c Partial introduction of bools where appropriate.
Guido van Rossum <guido@python.org>
parents: 21251
diff changeset
169 return False
12197
7f18f979a93a Zip file handling module, by Jim Ahlstrom.
Guido van Rossum <guido@python.org>
parents:
diff changeset
170
50301
fec72c9b271d Merged revisions 67946 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 49037
diff changeset
171 def is_zipfile(filename):
fec72c9b271d Merged revisions 67946 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 49037
diff changeset
172 """Quickly see if a file is a ZIP file by checking the magic number.
fec72c9b271d Merged revisions 67946 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 49037
diff changeset
173
fec72c9b271d Merged revisions 67946 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 49037
diff changeset
174 The filename argument may be a file or file-like object too.
fec72c9b271d Merged revisions 67946 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 49037
diff changeset
175 """
fec72c9b271d Merged revisions 67946 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 49037
diff changeset
176 result = False
fec72c9b271d Merged revisions 67946 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 49037
diff changeset
177 try:
fec72c9b271d Merged revisions 67946 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 49037
diff changeset
178 if hasattr(filename, "read"):
fec72c9b271d Merged revisions 67946 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 49037
diff changeset
179 result = _check_zipfile(fp=filename)
fec72c9b271d Merged revisions 67946 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 49037
diff changeset
180 else:
fec72c9b271d Merged revisions 67946 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 49037
diff changeset
181 with open(filename, "rb") as fp:
fec72c9b271d Merged revisions 67946 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 49037
diff changeset
182 result = _check_zipfile(fp)
81039
7d69d04522e3 Replace IOError with OSError (#16715)
Andrew Svetlov <andrew.svetlov@gmail.com>
parents: 80502
diff changeset
183 except OSError:
50301
fec72c9b271d Merged revisions 67946 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 49037
diff changeset
184 pass
fec72c9b271d Merged revisions 67946 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 49037
diff changeset
185 return result
fec72c9b271d Merged revisions 67946 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 49037
diff changeset
186
39442
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36609
diff changeset
187 def _EndRecData64(fpin, offset, endrec):
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36609
diff changeset
188 """
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36609
diff changeset
189 Read the ZIP64 end-of-archive records and use that to update endrec
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36609
diff changeset
190 """
66469
a372fc486281 Merged revisions 85450-85455,85460-85465 via svnmerge from
Georg Brandl <georg@python.org>
parents: 63936
diff changeset
191 try:
a372fc486281 Merged revisions 85450-85455,85460-85465 via svnmerge from
Georg Brandl <georg@python.org>
parents: 63936
diff changeset
192 fpin.seek(offset - sizeEndCentDir64Locator, 2)
81039
7d69d04522e3 Replace IOError with OSError (#16715)
Andrew Svetlov <andrew.svetlov@gmail.com>
parents: 80502
diff changeset
193 except OSError:
66469
a372fc486281 Merged revisions 85450-85455,85460-85465 via svnmerge from
Georg Brandl <georg@python.org>
parents: 63936
diff changeset
194 # If the seek fails, the file is not large enough to contain a ZIP64
a372fc486281 Merged revisions 85450-85455,85460-85465 via svnmerge from
Georg Brandl <georg@python.org>
parents: 63936
diff changeset
195 # end-of-archive record, so just return the end record we were given.
a372fc486281 Merged revisions 85450-85455,85460-85465 via svnmerge from
Georg Brandl <georg@python.org>
parents: 63936
diff changeset
196 return endrec
a372fc486281 Merged revisions 85450-85455,85460-85465 via svnmerge from
Georg Brandl <georg@python.org>
parents: 63936
diff changeset
197
48423
cdaac79a7237 Merged revisions 64688 via svnmerge from
Martin v. Löwis <martin@v.loewis.de>
parents: 47278
diff changeset
198 data = fpin.read(sizeEndCentDir64Locator)
81848
01147e468c8c Issue #4844: ZipFile now raises BadZipFile when opens a ZIP file with an
Serhiy Storchaka <storchaka@gmail.com>
parents: 81828
diff changeset
199 if len(data) != sizeEndCentDir64Locator:
01147e468c8c Issue #4844: ZipFile now raises BadZipFile when opens a ZIP file with an
Serhiy Storchaka <storchaka@gmail.com>
parents: 81828
diff changeset
200 return endrec
48499
de0bf60f1245 Merged revisions 64722,64729,64753,64845-64846,64849,64871,64880-64882,64885,64888,64897,64900-64901,64915,64926-64929,64938-64941,64944,64961,64966,64973 via svnmerge from
Georg Brandl <georg@python.org>
parents: 48423
diff changeset
201 sig, diskno, reloff, disks = struct.unpack(structEndArchive64Locator, data)
de0bf60f1245 Merged revisions 64722,64729,64753,64845-64846,64849,64871,64880-64882,64885,64888,64897,64900-64901,64915,64926-64929,64938-64941,64944,64961,64966,64973 via svnmerge from
Georg Brandl <georg@python.org>
parents: 48423
diff changeset
202 if sig != stringEndArchive64Locator:
39442
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36609
diff changeset
203 return endrec
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36609
diff changeset
204
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36609
diff changeset
205 if diskno != 0 or disks != 1:
65683
dc06aed9b984 Fix typo from r85874
Éric Araujo <merwok@netwok.org>
parents: 65673
diff changeset
206 raise BadZipFile("zipfiles that span multiple disks are not supported")
39442
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36609
diff changeset
207
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36609
diff changeset
208 # Assume no 'zip64 extensible data'
48423
cdaac79a7237 Merged revisions 64688 via svnmerge from
Martin v. Löwis <martin@v.loewis.de>
parents: 47278
diff changeset
209 fpin.seek(offset - sizeEndCentDir64Locator - sizeEndCentDir64, 2)
cdaac79a7237 Merged revisions 64688 via svnmerge from
Martin v. Löwis <martin@v.loewis.de>
parents: 47278
diff changeset
210 data = fpin.read(sizeEndCentDir64)
81848
01147e468c8c Issue #4844: ZipFile now raises BadZipFile when opens a ZIP file with an
Serhiy Storchaka <storchaka@gmail.com>
parents: 81828
diff changeset
211 if len(data) != sizeEndCentDir64:
01147e468c8c Issue #4844: ZipFile now raises BadZipFile when opens a ZIP file with an
Serhiy Storchaka <storchaka@gmail.com>
parents: 81828
diff changeset
212 return endrec
39442
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36609
diff changeset
213 sig, sz, create_version, read_version, disk_num, disk_dir, \
86536
34fb83421119 add a filterfunc to zip file.PyZipFile.writepy, issue 19274
Christian Tismer <tismer@stackless.com>
parents: 85814
diff changeset
214 dircount, dircount2, dirsize, diroffset = \
34fb83421119 add a filterfunc to zip file.PyZipFile.writepy, issue 19274
Christian Tismer <tismer@stackless.com>
parents: 85814
diff changeset
215 struct.unpack(structEndArchive64, data)
48499
de0bf60f1245 Merged revisions 64722,64729,64753,64845-64846,64849,64871,64880-64882,64885,64888,64897,64900-64901,64915,64926-64929,64938-64941,64944,64961,64966,64973 via svnmerge from
Georg Brandl <georg@python.org>
parents: 48423
diff changeset
216 if sig != stringEndArchive64:
39442
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36609
diff changeset
217 return endrec
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36609
diff changeset
218
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36609
diff changeset
219 # Update the original endrec using data from the ZIP64 record
49037
26bdd94a4293 Merged revisions 66240 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 48728
diff changeset
220 endrec[_ECD_SIGNATURE] = sig
48423
cdaac79a7237 Merged revisions 64688 via svnmerge from
Martin v. Löwis <martin@v.loewis.de>
parents: 47278
diff changeset
221 endrec[_ECD_DISK_NUMBER] = disk_num
cdaac79a7237 Merged revisions 64688 via svnmerge from
Martin v. Löwis <martin@v.loewis.de>
parents: 47278
diff changeset
222 endrec[_ECD_DISK_START] = disk_dir
cdaac79a7237 Merged revisions 64688 via svnmerge from
Martin v. Löwis <martin@v.loewis.de>
parents: 47278
diff changeset
223 endrec[_ECD_ENTRIES_THIS_DISK] = dircount
cdaac79a7237 Merged revisions 64688 via svnmerge from
Martin v. Löwis <martin@v.loewis.de>
parents: 47278
diff changeset
224 endrec[_ECD_ENTRIES_TOTAL] = dircount2
cdaac79a7237 Merged revisions 64688 via svnmerge from
Martin v. Löwis <martin@v.loewis.de>
parents: 47278
diff changeset
225 endrec[_ECD_SIZE] = dirsize
cdaac79a7237 Merged revisions 64688 via svnmerge from
Martin v. Löwis <martin@v.loewis.de>
parents: 47278
diff changeset
226 endrec[_ECD_OFFSET] = diroffset
39442
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36609
diff changeset
227 return endrec
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36609
diff changeset
228
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36609
diff changeset
229
25756
63225811498d Patch #611760: read archives with comments.
Martin v. Löwis <martin@v.loewis.de>
parents: 24756
diff changeset
230 def _EndRecData(fpin):
63225811498d Patch #611760: read archives with comments.
Martin v. Löwis <martin@v.loewis.de>
parents: 24756
diff changeset
231 """Return data from the "End of Central Directory" record, or None.
63225811498d Patch #611760: read archives with comments.
Martin v. Löwis <martin@v.loewis.de>
parents: 24756
diff changeset
232
63225811498d Patch #611760: read archives with comments.
Martin v. Löwis <martin@v.loewis.de>
parents: 24756
diff changeset
233 The data is a list of the nine items in the ZIP "End of central dir"
63225811498d Patch #611760: read archives with comments.
Martin v. Löwis <martin@v.loewis.de>
parents: 24756
diff changeset
234 record followed by a tenth item, the file seek offset of this record."""
48423
cdaac79a7237 Merged revisions 64688 via svnmerge from
Martin v. Löwis <martin@v.loewis.de>
parents: 47278
diff changeset
235
cdaac79a7237 Merged revisions 64688 via svnmerge from
Martin v. Löwis <martin@v.loewis.de>
parents: 47278
diff changeset
236 # Determine file size
cdaac79a7237 Merged revisions 64688 via svnmerge from
Martin v. Löwis <martin@v.loewis.de>
parents: 47278
diff changeset
237 fpin.seek(0, 2)
cdaac79a7237 Merged revisions 64688 via svnmerge from
Martin v. Löwis <martin@v.loewis.de>
parents: 47278
diff changeset
238 filesize = fpin.tell()
cdaac79a7237 Merged revisions 64688 via svnmerge from
Martin v. Löwis <martin@v.loewis.de>
parents: 47278
diff changeset
239
cdaac79a7237 Merged revisions 64688 via svnmerge from
Martin v. Löwis <martin@v.loewis.de>
parents: 47278
diff changeset
240 # Check to see if this is ZIP file with no archive comment (the
cdaac79a7237 Merged revisions 64688 via svnmerge from
Martin v. Löwis <martin@v.loewis.de>
parents: 47278
diff changeset
241 # "end of central directory" structure should be the last item in the
cdaac79a7237 Merged revisions 64688 via svnmerge from
Martin v. Löwis <martin@v.loewis.de>
parents: 47278
diff changeset
242 # file if this is the case).
58176
b3bb8b3e5e4e Merged revisions 74246 via svnmerge from
R. David Murray <rdmurray@bitdance.com>
parents: 56223
diff changeset
243 try:
b3bb8b3e5e4e Merged revisions 74246 via svnmerge from
R. David Murray <rdmurray@bitdance.com>
parents: 56223
diff changeset
244 fpin.seek(-sizeEndCentDir, 2)
81039
7d69d04522e3 Replace IOError with OSError (#16715)
Andrew Svetlov <andrew.svetlov@gmail.com>
parents: 80502
diff changeset
245 except OSError:
58176
b3bb8b3e5e4e Merged revisions 74246 via svnmerge from
R. David Murray <rdmurray@bitdance.com>
parents: 56223
diff changeset
246 return None
25756
63225811498d Patch #611760: read archives with comments.
Martin v. Löwis <martin@v.loewis.de>
parents: 24756
diff changeset
247 data = fpin.read()
81848
01147e468c8c Issue #4844: ZipFile now raises BadZipFile when opens a ZIP file with an
Serhiy Storchaka <storchaka@gmail.com>
parents: 81828
diff changeset
248 if (len(data) == sizeEndCentDir and
01147e468c8c Issue #4844: ZipFile now raises BadZipFile when opens a ZIP file with an
Serhiy Storchaka <storchaka@gmail.com>
parents: 81828
diff changeset
249 data[0:4] == stringEndArchive and
01147e468c8c Issue #4844: ZipFile now raises BadZipFile when opens a ZIP file with an
Serhiy Storchaka <storchaka@gmail.com>
parents: 81828
diff changeset
250 data[-2:] == b"\000\000"):
48423
cdaac79a7237 Merged revisions 64688 via svnmerge from
Martin v. Löwis <martin@v.loewis.de>
parents: 47278
diff changeset
251 # the signature is correct and there's no comment, unpack structure
48499
de0bf60f1245 Merged revisions 64722,64729,64753,64845-64846,64849,64871,64880-64882,64885,64888,64897,64900-64901,64915,64926-64929,64938-64941,64944,64961,64966,64973 via svnmerge from
Georg Brandl <georg@python.org>
parents: 48423
diff changeset
252 endrec = struct.unpack(structEndArchive, data)
48423
cdaac79a7237 Merged revisions 64688 via svnmerge from
Martin v. Löwis <martin@v.loewis.de>
parents: 47278
diff changeset
253 endrec=list(endrec)
cdaac79a7237 Merged revisions 64688 via svnmerge from
Martin v. Löwis <martin@v.loewis.de>
parents: 47278
diff changeset
254
cdaac79a7237 Merged revisions 64688 via svnmerge from
Martin v. Löwis <martin@v.loewis.de>
parents: 47278
diff changeset
255 # Append a blank comment and record start offset
cdaac79a7237 Merged revisions 64688 via svnmerge from
Martin v. Löwis <martin@v.loewis.de>
parents: 47278
diff changeset
256 endrec.append(b"")
cdaac79a7237 Merged revisions 64688 via svnmerge from
Martin v. Löwis <martin@v.loewis.de>
parents: 47278
diff changeset
257 endrec.append(filesize - sizeEndCentDir)
cdaac79a7237 Merged revisions 64688 via svnmerge from
Martin v. Löwis <martin@v.loewis.de>
parents: 47278
diff changeset
258
50847
4288546a4238 Merged revisions 68678 via svnmerge from
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 50825
diff changeset
259 # Try to read the "Zip64 end of central directory" structure
4288546a4238 Merged revisions 68678 via svnmerge from
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 50825
diff changeset
260 return _EndRecData64(fpin, -sizeEndCentDir, endrec)
48423
cdaac79a7237 Merged revisions 64688 via svnmerge from
Martin v. Löwis <martin@v.loewis.de>
parents: 47278
diff changeset
261
cdaac79a7237 Merged revisions 64688 via svnmerge from
Martin v. Löwis <martin@v.loewis.de>
parents: 47278
diff changeset
262 # Either this is not a ZIP file, or it is a ZIP file with an archive
cdaac79a7237 Merged revisions 64688 via svnmerge from
Martin v. Löwis <martin@v.loewis.de>
parents: 47278
diff changeset
263 # comment. Search the end of the file for the "end of central directory"
cdaac79a7237 Merged revisions 64688 via svnmerge from
Martin v. Löwis <martin@v.loewis.de>
parents: 47278
diff changeset
264 # record signature. The comment is the last item in the ZIP file and may be
cdaac79a7237 Merged revisions 64688 via svnmerge from
Martin v. Löwis <martin@v.loewis.de>
parents: 47278
diff changeset
265 # up to 64K long. It is assumed that the "end of central directory" magic
cdaac79a7237 Merged revisions 64688 via svnmerge from
Martin v. Löwis <martin@v.loewis.de>
parents: 47278
diff changeset
266 # number does not appear in the comment.
cdaac79a7237 Merged revisions 64688 via svnmerge from
Martin v. Löwis <martin@v.loewis.de>
parents: 47278
diff changeset
267 maxCommentStart = max(filesize - (1 << 16) - sizeEndCentDir, 0)
cdaac79a7237 Merged revisions 64688 via svnmerge from
Martin v. Löwis <martin@v.loewis.de>
parents: 47278
diff changeset
268 fpin.seek(maxCommentStart, 0)
25756
63225811498d Patch #611760: read archives with comments.
Martin v. Löwis <martin@v.loewis.de>
parents: 24756
diff changeset
269 data = fpin.read()
48499
de0bf60f1245 Merged revisions 64722,64729,64753,64845-64846,64849,64871,64880-64882,64885,64888,64897,64900-64901,64915,64926-64929,64938-64941,64944,64961,64966,64973 via svnmerge from
Georg Brandl <georg@python.org>
parents: 48423
diff changeset
270 start = data.rfind(stringEndArchive)
48423
cdaac79a7237 Merged revisions 64688 via svnmerge from
Martin v. Löwis <martin@v.loewis.de>
parents: 47278
diff changeset
271 if start >= 0:
cdaac79a7237 Merged revisions 64688 via svnmerge from
Martin v. Löwis <martin@v.loewis.de>
parents: 47278
diff changeset
272 # found the magic number; attempt to unpack and interpret
cdaac79a7237 Merged revisions 64688 via svnmerge from
Martin v. Löwis <martin@v.loewis.de>
parents: 47278
diff changeset
273 recData = data[start:start+sizeEndCentDir]
81848
01147e468c8c Issue #4844: ZipFile now raises BadZipFile when opens a ZIP file with an
Serhiy Storchaka <storchaka@gmail.com>
parents: 81828
diff changeset
274 if len(recData) != sizeEndCentDir:
01147e468c8c Issue #4844: ZipFile now raises BadZipFile when opens a ZIP file with an
Serhiy Storchaka <storchaka@gmail.com>
parents: 81828
diff changeset
275 # Zip file is corrupted.
01147e468c8c Issue #4844: ZipFile now raises BadZipFile when opens a ZIP file with an
Serhiy Storchaka <storchaka@gmail.com>
parents: 81828
diff changeset
276 return None
48499
de0bf60f1245 Merged revisions 64722,64729,64753,64845-64846,64849,64871,64880-64882,64885,64888,64897,64900-64901,64915,64926-64929,64938-64941,64944,64961,64966,64973 via svnmerge from
Georg Brandl <georg@python.org>
parents: 48423
diff changeset
277 endrec = list(struct.unpack(structEndArchive, recData))
70746
7530b141c20f #10694: zipfile now ignores garbage at the end of a zipfile.
R David Murray <rdmurray@bitdance.com>
parents: 70215
diff changeset
278 commentSize = endrec[_ECD_COMMENT_SIZE] #as claimed by the zip file
7530b141c20f #10694: zipfile now ignores garbage at the end of a zipfile.
R David Murray <rdmurray@bitdance.com>
parents: 70215
diff changeset
279 comment = data[start+sizeEndCentDir:start+sizeEndCentDir+commentSize]
7530b141c20f #10694: zipfile now ignores garbage at the end of a zipfile.
R David Murray <rdmurray@bitdance.com>
parents: 70215
diff changeset
280 endrec.append(comment)
7530b141c20f #10694: zipfile now ignores garbage at the end of a zipfile.
R David Murray <rdmurray@bitdance.com>
parents: 70215
diff changeset
281 endrec.append(maxCommentStart + start)
50847
4288546a4238 Merged revisions 68678 via svnmerge from
Amaury Forgeot d'Arc <amauryfa@gmail.com>
parents: 50825
diff changeset
282
70746
7530b141c20f #10694: zipfile now ignores garbage at the end of a zipfile.
R David Murray <rdmurray@bitdance.com>
parents: 70215
diff changeset
283 # Try to read the "Zip64 end of central directory" structure
7530b141c20f #10694: zipfile now ignores garbage at the end of a zipfile.
R David Murray <rdmurray@bitdance.com>
parents: 70215
diff changeset
284 return _EndRecData64(fpin, maxCommentStart + start - filesize,
7530b141c20f #10694: zipfile now ignores garbage at the end of a zipfile.
R David Murray <rdmurray@bitdance.com>
parents: 70215
diff changeset
285 endrec)
48423
cdaac79a7237 Merged revisions 64688 via svnmerge from
Martin v. Löwis <martin@v.loewis.de>
parents: 47278
diff changeset
286
cdaac79a7237 Merged revisions 64688 via svnmerge from
Martin v. Löwis <martin@v.loewis.de>
parents: 47278
diff changeset
287 # Unable to find a valid end of central directory structure
81848
01147e468c8c Issue #4844: ZipFile now raises BadZipFile when opens a ZIP file with an
Serhiy Storchaka <storchaka@gmail.com>
parents: 81828
diff changeset
288 return None
25756
63225811498d Patch #611760: read archives with comments.
Martin v. Löwis <martin@v.loewis.de>
parents: 24756
diff changeset
289
14975
27eab8032766 Delay import of py_compile until needed, since is is only used by the
Fred Drake <fdrake@acm.org>
parents: 14933
diff changeset
290
39442
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36609
diff changeset
291 class ZipInfo (object):
14975
27eab8032766 Delay import of py_compile until needed, since is is only used by the
Fred Drake <fdrake@acm.org>
parents: 14933
diff changeset
292 """Class with attributes describing each file in the ZIP archive."""
27eab8032766 Delay import of py_compile until needed, since is is only used by the
Fred Drake <fdrake@acm.org>
parents: 14933
diff changeset
293
39442
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36609
diff changeset
294 __slots__ = (
86536
34fb83421119 add a filterfunc to zip file.PyZipFile.writepy, issue 19274
Christian Tismer <tismer@stackless.com>
parents: 85814
diff changeset
295 'orig_filename',
34fb83421119 add a filterfunc to zip file.PyZipFile.writepy, issue 19274
Christian Tismer <tismer@stackless.com>
parents: 85814
diff changeset
296 'filename',
34fb83421119 add a filterfunc to zip file.PyZipFile.writepy, issue 19274
Christian Tismer <tismer@stackless.com>
parents: 85814
diff changeset
297 'date_time',
34fb83421119 add a filterfunc to zip file.PyZipFile.writepy, issue 19274
Christian Tismer <tismer@stackless.com>
parents: 85814
diff changeset
298 'compress_type',
34fb83421119 add a filterfunc to zip file.PyZipFile.writepy, issue 19274
Christian Tismer <tismer@stackless.com>
parents: 85814
diff changeset
299 'comment',
34fb83421119 add a filterfunc to zip file.PyZipFile.writepy, issue 19274
Christian Tismer <tismer@stackless.com>
parents: 85814
diff changeset
300 'extra',
34fb83421119 add a filterfunc to zip file.PyZipFile.writepy, issue 19274
Christian Tismer <tismer@stackless.com>
parents: 85814
diff changeset
301 'create_system',
34fb83421119 add a filterfunc to zip file.PyZipFile.writepy, issue 19274
Christian Tismer <tismer@stackless.com>
parents: 85814
diff changeset
302 'create_version',
34fb83421119 add a filterfunc to zip file.PyZipFile.writepy, issue 19274
Christian Tismer <tismer@stackless.com>
parents: 85814
diff changeset
303 'extract_version',
34fb83421119 add a filterfunc to zip file.PyZipFile.writepy, issue 19274
Christian Tismer <tismer@stackless.com>
parents: 85814
diff changeset
304 'reserved',
34fb83421119 add a filterfunc to zip file.PyZipFile.writepy, issue 19274
Christian Tismer <tismer@stackless.com>
parents: 85814
diff changeset
305 'flag_bits',
34fb83421119 add a filterfunc to zip file.PyZipFile.writepy, issue 19274
Christian Tismer <tismer@stackless.com>
parents: 85814
diff changeset
306 'volume',
34fb83421119 add a filterfunc to zip file.PyZipFile.writepy, issue 19274
Christian Tismer <tismer@stackless.com>
parents: 85814
diff changeset
307 'internal_attr',
34fb83421119 add a filterfunc to zip file.PyZipFile.writepy, issue 19274
Christian Tismer <tismer@stackless.com>
parents: 85814
diff changeset
308 'external_attr',
34fb83421119 add a filterfunc to zip file.PyZipFile.writepy, issue 19274
Christian Tismer <tismer@stackless.com>
parents: 85814
diff changeset
309 'header_offset',
34fb83421119 add a filterfunc to zip file.PyZipFile.writepy, issue 19274
Christian Tismer <tismer@stackless.com>
parents: 85814
diff changeset
310 'CRC',
34fb83421119 add a filterfunc to zip file.PyZipFile.writepy, issue 19274
Christian Tismer <tismer@stackless.com>
parents: 85814
diff changeset
311 'compress_size',
34fb83421119 add a filterfunc to zip file.PyZipFile.writepy, issue 19274
Christian Tismer <tismer@stackless.com>
parents: 85814
diff changeset
312 'file_size',
34fb83421119 add a filterfunc to zip file.PyZipFile.writepy, issue 19274
Christian Tismer <tismer@stackless.com>
parents: 85814
diff changeset
313 '_raw_time',
34fb83421119 add a filterfunc to zip file.PyZipFile.writepy, issue 19274
Christian Tismer <tismer@stackless.com>
parents: 85814
diff changeset
314 )
39442
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36609
diff changeset
315
12197
7f18f979a93a Zip file handling module, by Jim Ahlstrom.
Guido van Rossum <guido@python.org>
parents:
diff changeset
316 def __init__(self, filename="NoName", date_time=(1980,1,1,0,0,0)):
29523
87f30fcfad48 SF patch #755987 (Jim Ahlstrom):
Greg Ward <gward@python.net>
parents: 27250
diff changeset
317 self.orig_filename = filename # Original file name in archive
39442
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36609
diff changeset
318
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36609
diff changeset
319 # Terminate the file name at the first null byte. Null bytes in file
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36609
diff changeset
320 # names are used as tricks by viruses in archives.
29523
87f30fcfad48 SF patch #755987 (Jim Ahlstrom):
Greg Ward <gward@python.net>
parents: 27250
diff changeset
321 null_byte = filename.find(chr(0))
87f30fcfad48 SF patch #755987 (Jim Ahlstrom):
Greg Ward <gward@python.net>
parents: 27250
diff changeset
322 if null_byte >= 0:
87f30fcfad48 SF patch #755987 (Jim Ahlstrom):
Greg Ward <gward@python.net>
parents: 27250
diff changeset
323 filename = filename[0:null_byte]
39442
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36609
diff changeset
324 # This is used to ensure paths in generated ZIP files always use
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36609
diff changeset
325 # forward slashes as the directory separator, as required by the
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36609
diff changeset
326 # ZIP format specification.
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36609
diff changeset
327 if os.sep != "/" and os.sep in filename:
29523
87f30fcfad48 SF patch #755987 (Jim Ahlstrom):
Greg Ward <gward@python.net>
parents: 27250
diff changeset
328 filename = filename.replace(os.sep, "/")
39442
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36609
diff changeset
329
29523
87f30fcfad48 SF patch #755987 (Jim Ahlstrom):
Greg Ward <gward@python.net>
parents: 27250
diff changeset
330 self.filename = filename # Normalized file name
15874
4c01ee0a8073 Whitespace normalization. Top level of Lib now fixed-point for reindent.py!
Tim Peters <tim.peters@gmail.com>
parents: 14975
diff changeset
331 self.date_time = date_time # year, month, day, hour, min, sec
72992
12f3e86e9041 3.2 - Fix closes Issue6090 - Raise a ValueError, instead of failing with unrelated
Senthil Kumaran <senthil@uthcode.com>
parents: 70746
diff changeset
332
12f3e86e9041 3.2 - Fix closes Issue6090 - Raise a ValueError, instead of failing with unrelated
Senthil Kumaran <senthil@uthcode.com>
parents: 70746
diff changeset
333 if date_time[0] < 1980:
12f3e86e9041 3.2 - Fix closes Issue6090 - Raise a ValueError, instead of failing with unrelated
Senthil Kumaran <senthil@uthcode.com>
parents: 70746
diff changeset
334 raise ValueError('ZIP does not support timestamps before 1980')
12f3e86e9041 3.2 - Fix closes Issue6090 - Raise a ValueError, instead of failing with unrelated
Senthil Kumaran <senthil@uthcode.com>
parents: 70746
diff changeset
335
12197
7f18f979a93a Zip file handling module, by Jim Ahlstrom.
Guido van Rossum <guido@python.org>
parents:
diff changeset
336 # Standard values:
15874
4c01ee0a8073 Whitespace normalization. Top level of Lib now fixed-point for reindent.py!
Tim Peters <tim.peters@gmail.com>
parents: 14975
diff changeset
337 self.compress_type = ZIP_STORED # Type of compression for the file
41812
50dafa22b8a4 Make test_zipfile pass.
Guido van Rossum <guido@python.org>
parents: 41760
diff changeset
338 self.comment = b"" # Comment for each file
50dafa22b8a4 Make test_zipfile pass.
Guido van Rossum <guido@python.org>
parents: 41760
diff changeset
339 self.extra = b"" # ZIP extra data
36449
4ed30eaa0256 Patch #1412872: zipfile: use correct system type on unixy systems.
Martin v. Löwis <martin@v.loewis.de>
parents: 34594
diff changeset
340 if sys.platform == 'win32':
4ed30eaa0256 Patch #1412872: zipfile: use correct system type on unixy systems.
Martin v. Löwis <martin@v.loewis.de>
parents: 34594
diff changeset
341 self.create_system = 0 # System which created ZIP archive
4ed30eaa0256 Patch #1412872: zipfile: use correct system type on unixy systems.
Martin v. Löwis <martin@v.loewis.de>
parents: 34594
diff changeset
342 else:
4ed30eaa0256 Patch #1412872: zipfile: use correct system type on unixy systems.
Martin v. Löwis <martin@v.loewis.de>
parents: 34594
diff changeset
343 # Assume everything else is unix-y
4ed30eaa0256 Patch #1412872: zipfile: use correct system type on unixy systems.
Martin v. Löwis <martin@v.loewis.de>
parents: 34594
diff changeset
344 self.create_system = 3 # System which created ZIP archive
76682
028e8e0b03e8 Issue #14371: Support bzip2 in zipfile module.
Martin v. Löwis <martin@v.loewis.de>
parents: 76373
diff changeset
345 self.create_version = DEFAULT_VERSION # Version which created ZIP archive
028e8e0b03e8 Issue #14371: Support bzip2 in zipfile module.
Martin v. Löwis <martin@v.loewis.de>
parents: 76373
diff changeset
346 self.extract_version = DEFAULT_VERSION # Version needed to extract archive
15874
4c01ee0a8073 Whitespace normalization. Top level of Lib now fixed-point for reindent.py!
Tim Peters <tim.peters@gmail.com>
parents: 14975
diff changeset
347 self.reserved = 0 # Must be zero
4c01ee0a8073 Whitespace normalization. Top level of Lib now fixed-point for reindent.py!
Tim Peters <tim.peters@gmail.com>
parents: 14975
diff changeset
348 self.flag_bits = 0 # ZIP flag bits
4c01ee0a8073 Whitespace normalization. Top level of Lib now fixed-point for reindent.py!
Tim Peters <tim.peters@gmail.com>
parents: 14975
diff changeset
349 self.volume = 0 # Volume number of file header
4c01ee0a8073 Whitespace normalization. Top level of Lib now fixed-point for reindent.py!
Tim Peters <tim.peters@gmail.com>
parents: 14975
diff changeset
350 self.internal_attr = 0 # Internal attributes
4c01ee0a8073 Whitespace normalization. Top level of Lib now fixed-point for reindent.py!
Tim Peters <tim.peters@gmail.com>
parents: 14975
diff changeset
351 self.external_attr = 0 # External file attributes
12197
7f18f979a93a Zip file handling module, by Jim Ahlstrom.
Guido van Rossum <guido@python.org>
parents:
diff changeset
352 # Other attributes are set by class ZipFile:
15874
4c01ee0a8073 Whitespace normalization. Top level of Lib now fixed-point for reindent.py!
Tim Peters <tim.peters@gmail.com>
parents: 14975
diff changeset
353 # header_offset Byte offset to the file header
4c01ee0a8073 Whitespace normalization. Top level of Lib now fixed-point for reindent.py!
Tim Peters <tim.peters@gmail.com>
parents: 14975
diff changeset
354 # CRC CRC-32 of the uncompressed file
4c01ee0a8073 Whitespace normalization. Top level of Lib now fixed-point for reindent.py!
Tim Peters <tim.peters@gmail.com>
parents: 14975
diff changeset
355 # compress_size Size of the compressed file
4c01ee0a8073 Whitespace normalization. Top level of Lib now fixed-point for reindent.py!
Tim Peters <tim.peters@gmail.com>
parents: 14975
diff changeset
356 # file_size Size of the uncompressed file
12197
7f18f979a93a Zip file handling module, by Jim Ahlstrom.
Guido van Rossum <guido@python.org>
parents:
diff changeset
357
81502
b93848ca7760 Issue #9720: zipfile now writes correct local headers for files larger than 4 GiB.
Serhiy Storchaka <storchaka@gmail.com>
parents: 80500
diff changeset
358 def FileHeader(self, zip64=None):
14975
27eab8032766 Delay import of py_compile until needed, since is is only used by the
Fred Drake <fdrake@acm.org>
parents: 14933
diff changeset
359 """Return the per-file header as a string."""
12197
7f18f979a93a Zip file handling module, by Jim Ahlstrom.
Guido van Rossum <guido@python.org>
parents:
diff changeset
360 dt = self.date_time
7f18f979a93a Zip file handling module, by Jim Ahlstrom.
Guido van Rossum <guido@python.org>
parents:
diff changeset
361 dosdate = (dt[0] - 1980) << 9 | dt[1] << 5 | dt[2]
21251
45e1177424e1 SF bug #488514: -Qnew needs work
Tim Peters <tim.peters@gmail.com>
parents: 21098
diff changeset
362 dostime = dt[3] << 11 | dt[4] << 5 | (dt[5] // 2)
12197
7f18f979a93a Zip file handling module, by Jim Ahlstrom.
Guido van Rossum <guido@python.org>
parents:
diff changeset
363 if self.flag_bits & 0x08:
15874
4c01ee0a8073 Whitespace normalization. Top level of Lib now fixed-point for reindent.py!
Tim Peters <tim.peters@gmail.com>
parents: 14975
diff changeset
364 # Set these to zero because we write them after the file data
4c01ee0a8073 Whitespace normalization. Top level of Lib now fixed-point for reindent.py!
Tim Peters <tim.peters@gmail.com>
parents: 14975
diff changeset
365 CRC = compress_size = file_size = 0
12197
7f18f979a93a Zip file handling module, by Jim Ahlstrom.
Guido van Rossum <guido@python.org>
parents:
diff changeset
366 else:
15874
4c01ee0a8073 Whitespace normalization. Top level of Lib now fixed-point for reindent.py!
Tim Peters <tim.peters@gmail.com>
parents: 14975
diff changeset
367 CRC = self.CRC
4c01ee0a8073 Whitespace normalization. Top level of Lib now fixed-point for reindent.py!
Tim Peters <tim.peters@gmail.com>
parents: 14975
diff changeset
368 compress_size = self.compress_size
4c01ee0a8073 Whitespace normalization. Top level of Lib now fixed-point for reindent.py!
Tim Peters <tim.peters@gmail.com>
parents: 14975
diff changeset
369 file_size = self.file_size
39442
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36609
diff changeset
370
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36609
diff changeset
371 extra = self.extra
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36609
diff changeset
372
76682
028e8e0b03e8 Issue #14371: Support bzip2 in zipfile module.
Martin v. Löwis <martin@v.loewis.de>
parents: 76373
diff changeset
373 min_version = 0
81502
b93848ca7760 Issue #9720: zipfile now writes correct local headers for files larger than 4 GiB.
Serhiy Storchaka <storchaka@gmail.com>
parents: 80500
diff changeset
374 if zip64 is None:
b93848ca7760 Issue #9720: zipfile now writes correct local headers for files larger than 4 GiB.
Serhiy Storchaka <storchaka@gmail.com>
parents: 80500
diff changeset
375 zip64 = file_size > ZIP64_LIMIT or compress_size > ZIP64_LIMIT
b93848ca7760 Issue #9720: zipfile now writes correct local headers for files larger than 4 GiB.
Serhiy Storchaka <storchaka@gmail.com>
parents: 80500
diff changeset
376 if zip64:
45931
1657f0acca78 Merged revisions 61538-61540,61556,61559-61560,61563,61565,61571,61575-61576,61580-61582,61586,61591,61593,61595,61605-61606,61613-61616,61618,61621-61623,61625,61627,61631-61634 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 44810
diff changeset
377 fmt = '<HHQQ'
39442
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36609
diff changeset
378 extra = extra + struct.pack(fmt,
86536
34fb83421119 add a filterfunc to zip file.PyZipFile.writepy, issue 19274
Christian Tismer <tismer@stackless.com>
parents: 85814
diff changeset
379 1, struct.calcsize(fmt)-4, file_size, compress_size)
81502
b93848ca7760 Issue #9720: zipfile now writes correct local headers for files larger than 4 GiB.
Serhiy Storchaka <storchaka@gmail.com>
parents: 80500
diff changeset
380 if file_size > ZIP64_LIMIT or compress_size > ZIP64_LIMIT:
b93848ca7760 Issue #9720: zipfile now writes correct local headers for files larger than 4 GiB.
Serhiy Storchaka <storchaka@gmail.com>
parents: 80500
diff changeset
381 if not zip64:
b93848ca7760 Issue #9720: zipfile now writes correct local headers for files larger than 4 GiB.
Serhiy Storchaka <storchaka@gmail.com>
parents: 80500
diff changeset
382 raise LargeZipFile("Filesize would require ZIP64 extensions")
b93848ca7760 Issue #9720: zipfile now writes correct local headers for files larger than 4 GiB.
Serhiy Storchaka <storchaka@gmail.com>
parents: 80500
diff changeset
383 # File is larger than what fits into a 4 byte integer,
b93848ca7760 Issue #9720: zipfile now writes correct local headers for files larger than 4 GiB.
Serhiy Storchaka <storchaka@gmail.com>
parents: 80500
diff changeset
384 # fall back to the ZIP64 extension
48423
cdaac79a7237 Merged revisions 64688 via svnmerge from
Martin v. Löwis <martin@v.loewis.de>
parents: 47278
diff changeset
385 file_size = 0xffffffff
cdaac79a7237 Merged revisions 64688 via svnmerge from
Martin v. Löwis <martin@v.loewis.de>
parents: 47278
diff changeset
386 compress_size = 0xffffffff
76682
028e8e0b03e8 Issue #14371: Support bzip2 in zipfile module.
Martin v. Löwis <martin@v.loewis.de>
parents: 76373
diff changeset
387 min_version = ZIP64_VERSION
39442
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36609
diff changeset
388
76682
028e8e0b03e8 Issue #14371: Support bzip2 in zipfile module.
Martin v. Löwis <martin@v.loewis.de>
parents: 76373
diff changeset
389 if self.compress_type == ZIP_BZIP2:
028e8e0b03e8 Issue #14371: Support bzip2 in zipfile module.
Martin v. Löwis <martin@v.loewis.de>
parents: 76373
diff changeset
390 min_version = max(BZIP2_VERSION, min_version)
76895
fccdcd83708a Issue #14366: Support lzma compression in zip files.
Martin v. Löwis <martin@v.loewis.de>
parents: 76694
diff changeset
391 elif self.compress_type == ZIP_LZMA:
fccdcd83708a Issue #14366: Support lzma compression in zip files.
Martin v. Löwis <martin@v.loewis.de>
parents: 76694
diff changeset
392 min_version = max(LZMA_VERSION, min_version)
76682
028e8e0b03e8 Issue #14371: Support bzip2 in zipfile module.
Martin v. Löwis <martin@v.loewis.de>
parents: 76373
diff changeset
393
028e8e0b03e8 Issue #14371: Support bzip2 in zipfile module.
Martin v. Löwis <martin@v.loewis.de>
parents: 76373
diff changeset
394 self.extract_version = max(min_version, self.extract_version)
028e8e0b03e8 Issue #14371: Support bzip2 in zipfile module.
Martin v. Löwis <martin@v.loewis.de>
parents: 76373
diff changeset
395 self.create_version = max(min_version, self.create_version)
46672
15f1d232eae9 Merged revisions 62724 via svnmerge from
Martin v. Löwis <martin@v.loewis.de>
parents: 45941
diff changeset
396 filename, flag_bits = self._encodeFilenameFlags()
48499
de0bf60f1245 Merged revisions 64722,64729,64753,64845-64846,64849,64871,64880-64882,64885,64888,64897,64900-64901,64915,64926-64929,64938-64941,64944,64961,64966,64973 via svnmerge from
Georg Brandl <georg@python.org>
parents: 48423
diff changeset
397 header = struct.pack(structFileHeader, stringFileHeader,
86536
34fb83421119 add a filterfunc to zip file.PyZipFile.writepy, issue 19274
Christian Tismer <tismer@stackless.com>
parents: 85814
diff changeset
398 self.extract_version, self.reserved, flag_bits,
34fb83421119 add a filterfunc to zip file.PyZipFile.writepy, issue 19274
Christian Tismer <tismer@stackless.com>
parents: 85814
diff changeset
399 self.compress_type, dostime, dosdate, CRC,
34fb83421119 add a filterfunc to zip file.PyZipFile.writepy, issue 19274
Christian Tismer <tismer@stackless.com>
parents: 85814
diff changeset
400 compress_size, file_size,
34fb83421119 add a filterfunc to zip file.PyZipFile.writepy, issue 19274
Christian Tismer <tismer@stackless.com>
parents: 85814
diff changeset
401 len(filename), len(extra))
46672
15f1d232eae9 Merged revisions 62724 via svnmerge from
Martin v. Löwis <martin@v.loewis.de>
parents: 45941
diff changeset
402 return header + filename + extra
15f1d232eae9 Merged revisions 62724 via svnmerge from
Martin v. Löwis <martin@v.loewis.de>
parents: 45941
diff changeset
403
15f1d232eae9 Merged revisions 62724 via svnmerge from
Martin v. Löwis <martin@v.loewis.de>
parents: 45941
diff changeset
404 def _encodeFilenameFlags(self):
15f1d232eae9 Merged revisions 62724 via svnmerge from
Martin v. Löwis <martin@v.loewis.de>
parents: 45941
diff changeset
405 try:
15f1d232eae9 Merged revisions 62724 via svnmerge from
Martin v. Löwis <martin@v.loewis.de>
parents: 45941
diff changeset
406 return self.filename.encode('ascii'), self.flag_bits
15f1d232eae9 Merged revisions 62724 via svnmerge from
Martin v. Löwis <martin@v.loewis.de>
parents: 45941
diff changeset
407 except UnicodeEncodeError:
15f1d232eae9 Merged revisions 62724 via svnmerge from
Martin v. Löwis <martin@v.loewis.de>
parents: 45941
diff changeset
408 return self.filename.encode('utf-8'), self.flag_bits | 0x800
39442
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36609
diff changeset
409
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36609
diff changeset
410 def _decodeExtra(self):
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36609
diff changeset
411 # Try to decode the extra field.
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36609
diff changeset
412 extra = self.extra
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36609
diff changeset
413 unpack = struct.unpack
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36609
diff changeset
414 while extra:
45931
1657f0acca78 Merged revisions 61538-61540,61556,61559-61560,61563,61565,61571,61575-61576,61580-61582,61586,61591,61593,61595,61605-61606,61613-61616,61618,61621-61623,61625,61627,61631-61634 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 44810
diff changeset
415 tp, ln = unpack('<HH', extra[:4])
39442
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36609
diff changeset
416 if tp == 1:
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36609
diff changeset
417 if ln >= 24:
45931
1657f0acca78 Merged revisions 61538-61540,61556,61559-61560,61563,61565,61571,61575-61576,61580-61582,61586,61591,61593,61595,61605-61606,61613-61616,61618,61621-61623,61625,61627,61631-61634 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 44810
diff changeset
418 counts = unpack('<QQQ', extra[4:28])
39442
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36609
diff changeset
419 elif ln == 16:
45931
1657f0acca78 Merged revisions 61538-61540,61556,61559-61560,61563,61565,61571,61575-61576,61580-61582,61586,61591,61593,61595,61605-61606,61613-61616,61618,61621-61623,61625,61627,61631-61634 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 44810
diff changeset
420 counts = unpack('<QQ', extra[4:20])
39442
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36609
diff changeset
421 elif ln == 8:
45931
1657f0acca78 Merged revisions 61538-61540,61556,61559-61560,61563,61565,61571,61575-61576,61580-61582,61586,61591,61593,61595,61605-61606,61613-61616,61618,61621-61623,61625,61627,61631-61634 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 44810
diff changeset
422 counts = unpack('<Q', extra[4:12])
39442
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36609
diff changeset
423 elif ln == 0:
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36609
diff changeset
424 counts = ()
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36609
diff changeset
425 else:
43020
907a45df1295 Raise statement normalization in Lib/.
Collin Winter <collinw@gmail.com>
parents: 43005
diff changeset
426 raise RuntimeError("Corrupt extra field %s"%(ln,))
39442
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36609
diff changeset
427
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36609
diff changeset
428 idx = 0
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36609
diff changeset
429
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36609
diff changeset
430 # ZIP64 extension (large files and/or large archives)
45931
1657f0acca78 Merged revisions 61538-61540,61556,61559-61560,61563,61565,61571,61575-61576,61580-61582,61586,61591,61593,61595,61605-61606,61613-61616,61618,61621-61623,61625,61627,61631-61634 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 44810
diff changeset
431 if self.file_size in (0xffffffffffffffff, 0xffffffff):
39442
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36609
diff changeset
432 self.file_size = counts[idx]
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36609
diff changeset
433 idx += 1
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36609
diff changeset
434
48423
cdaac79a7237 Merged revisions 64688 via svnmerge from
Martin v. Löwis <martin@v.loewis.de>
parents: 47278
diff changeset
435 if self.compress_size == 0xFFFFFFFF:
39442
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36609
diff changeset
436 self.compress_size = counts[idx]
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36609
diff changeset
437 idx += 1
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36609
diff changeset
438
48423
cdaac79a7237 Merged revisions 64688 via svnmerge from
Martin v. Löwis <martin@v.loewis.de>
parents: 47278
diff changeset
439 if self.header_offset == 0xffffffff:
39442
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36609
diff changeset
440 old = self.header_offset
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36609
diff changeset
441 self.header_offset = counts[idx]
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36609
diff changeset
442 idx+=1
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36609
diff changeset
443
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36609
diff changeset
444 extra = extra[ln+4:]
12197
7f18f979a93a Zip file handling module, by Jim Ahlstrom.
Guido van Rossum <guido@python.org>
parents:
diff changeset
445
7f18f979a93a Zip file handling module, by Jim Ahlstrom.
Guido van Rossum <guido@python.org>
parents:
diff changeset
446
40893
32c4897b5d46 Merged revisions 53623-53858 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 40775
diff changeset
447 class _ZipDecrypter:
32c4897b5d46 Merged revisions 53623-53858 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 40775
diff changeset
448 """Class to handle decryption of files stored within a ZIP archive.
32c4897b5d46 Merged revisions 53623-53858 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 40775
diff changeset
449
32c4897b5d46 Merged revisions 53623-53858 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 40775
diff changeset
450 ZIP supports a password-based form of encryption. Even though known
32c4897b5d46 Merged revisions 53623-53858 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 40775
diff changeset
451 plaintext attacks have been found against it, it is still useful
44810
fa6cee14dcba Merged revisions 60094-60123 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 44699
diff changeset
452 to be able to get data out of such a file.
40893
32c4897b5d46 Merged revisions 53623-53858 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 40775
diff changeset
453
32c4897b5d46 Merged revisions 53623-53858 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 40775
diff changeset
454 Usage:
32c4897b5d46 Merged revisions 53623-53858 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 40775
diff changeset
455 zd = _ZipDecrypter(mypwd)
32c4897b5d46 Merged revisions 53623-53858 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 40775
diff changeset
456 plain_char = zd(cypher_char)
32c4897b5d46 Merged revisions 53623-53858 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 40775
diff changeset
457 plain_text = map(zd, cypher_text)
32c4897b5d46 Merged revisions 53623-53858 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 40775
diff changeset
458 """
32c4897b5d46 Merged revisions 53623-53858 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 40775
diff changeset
459
32c4897b5d46 Merged revisions 53623-53858 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 40775
diff changeset
460 def _GenerateCRCTable():
32c4897b5d46 Merged revisions 53623-53858 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 40775
diff changeset
461 """Generate a CRC-32 table.
32c4897b5d46 Merged revisions 53623-53858 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 40775
diff changeset
462
32c4897b5d46 Merged revisions 53623-53858 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 40775
diff changeset
463 ZIP encryption uses the CRC32 one-byte primitive for scrambling some
32c4897b5d46 Merged revisions 53623-53858 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 40775
diff changeset
464 internal keys. We noticed that a direct implementation is faster than
32c4897b5d46 Merged revisions 53623-53858 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 40775
diff changeset
465 relying on binascii.crc32().
32c4897b5d46 Merged revisions 53623-53858 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 40775
diff changeset
466 """
32c4897b5d46 Merged revisions 53623-53858 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 40775
diff changeset
467 poly = 0xedb88320
32c4897b5d46 Merged revisions 53623-53858 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 40775
diff changeset
468 table = [0] * 256
32c4897b5d46 Merged revisions 53623-53858 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 40775
diff changeset
469 for i in range(256):
32c4897b5d46 Merged revisions 53623-53858 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 40775
diff changeset
470 crc = i
32c4897b5d46 Merged revisions 53623-53858 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 40775
diff changeset
471 for j in range(8):
32c4897b5d46 Merged revisions 53623-53858 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 40775
diff changeset
472 if crc & 1:
32c4897b5d46 Merged revisions 53623-53858 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 40775
diff changeset
473 crc = ((crc >> 1) & 0x7FFFFFFF) ^ poly
32c4897b5d46 Merged revisions 53623-53858 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 40775
diff changeset
474 else:
32c4897b5d46 Merged revisions 53623-53858 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 40775
diff changeset
475 crc = ((crc >> 1) & 0x7FFFFFFF)
32c4897b5d46 Merged revisions 53623-53858 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 40775
diff changeset
476 table[i] = crc
32c4897b5d46 Merged revisions 53623-53858 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 40775
diff changeset
477 return table
32c4897b5d46 Merged revisions 53623-53858 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 40775
diff changeset
478 crctable = _GenerateCRCTable()
32c4897b5d46 Merged revisions 53623-53858 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 40775
diff changeset
479
32c4897b5d46 Merged revisions 53623-53858 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 40775
diff changeset
480 def _crc32(self, ch, crc):
32c4897b5d46 Merged revisions 53623-53858 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 40775
diff changeset
481 """Compute the CRC32 primitive on one byte."""
41812
50dafa22b8a4 Make test_zipfile pass.
Guido van Rossum <guido@python.org>
parents: 41760
diff changeset
482 return ((crc >> 8) & 0xffffff) ^ self.crctable[(crc ^ ch) & 0xff]
40893
32c4897b5d46 Merged revisions 53623-53858 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 40775
diff changeset
483
32c4897b5d46 Merged revisions 53623-53858 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 40775
diff changeset
484 def __init__(self, pwd):
32c4897b5d46 Merged revisions 53623-53858 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 40775
diff changeset
485 self.key0 = 305419896
32c4897b5d46 Merged revisions 53623-53858 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 40775
diff changeset
486 self.key1 = 591751049
32c4897b5d46 Merged revisions 53623-53858 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 40775
diff changeset
487 self.key2 = 878082192
32c4897b5d46 Merged revisions 53623-53858 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 40775
diff changeset
488 for p in pwd:
32c4897b5d46 Merged revisions 53623-53858 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 40775
diff changeset
489 self._UpdateKeys(p)
32c4897b5d46 Merged revisions 53623-53858 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 40775
diff changeset
490
32c4897b5d46 Merged revisions 53623-53858 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 40775
diff changeset
491 def _UpdateKeys(self, c):
32c4897b5d46 Merged revisions 53623-53858 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 40775
diff changeset
492 self.key0 = self._crc32(c, self.key0)
32c4897b5d46 Merged revisions 53623-53858 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 40775
diff changeset
493 self.key1 = (self.key1 + (self.key0 & 255)) & 4294967295
32c4897b5d46 Merged revisions 53623-53858 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 40775
diff changeset
494 self.key1 = (self.key1 * 134775813 + 1) & 4294967295
41812
50dafa22b8a4 Make test_zipfile pass.
Guido van Rossum <guido@python.org>
parents: 41760
diff changeset
495 self.key2 = self._crc32((self.key1 >> 24) & 255, self.key2)
40893
32c4897b5d46 Merged revisions 53623-53858 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 40775
diff changeset
496
32c4897b5d46 Merged revisions 53623-53858 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 40775
diff changeset
497 def __call__(self, c):
32c4897b5d46 Merged revisions 53623-53858 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 40775
diff changeset
498 """Decrypt a single character."""
41812
50dafa22b8a4 Make test_zipfile pass.
Guido van Rossum <guido@python.org>
parents: 41760
diff changeset
499 assert isinstance(c, int)
40893
32c4897b5d46 Merged revisions 53623-53858 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 40775
diff changeset
500 k = self.key2 | 2
32c4897b5d46 Merged revisions 53623-53858 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 40775
diff changeset
501 c = c ^ (((k * (k^1)) >> 8) & 255)
32c4897b5d46 Merged revisions 53623-53858 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 40775
diff changeset
502 self._UpdateKeys(c)
32c4897b5d46 Merged revisions 53623-53858 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 40775
diff changeset
503 return c
32c4897b5d46 Merged revisions 53623-53858 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 40775
diff changeset
504
80500
b193a5dc7a58 #14313: zipfile now raises NotImplementedError when the compression type is unknown.
Ezio Melotti <ezio.melotti@gmail.com>
parents: 80482
diff changeset
505
76895
fccdcd83708a Issue #14366: Support lzma compression in zip files.
Martin v. Löwis <martin@v.loewis.de>
parents: 76694
diff changeset
506 class LZMACompressor:
fccdcd83708a Issue #14366: Support lzma compression in zip files.
Martin v. Löwis <martin@v.loewis.de>
parents: 76694
diff changeset
507
fccdcd83708a Issue #14366: Support lzma compression in zip files.
Martin v. Löwis <martin@v.loewis.de>
parents: 76694
diff changeset
508 def __init__(self):
fccdcd83708a Issue #14366: Support lzma compression in zip files.
Martin v. Löwis <martin@v.loewis.de>
parents: 76694
diff changeset
509 self._comp = None
fccdcd83708a Issue #14366: Support lzma compression in zip files.
Martin v. Löwis <martin@v.loewis.de>
parents: 76694
diff changeset
510
fccdcd83708a Issue #14366: Support lzma compression in zip files.
Martin v. Löwis <martin@v.loewis.de>
parents: 76694
diff changeset
511 def _init(self):
77557
0f470b91b710 Make lzma.{encode,decode}_filter_properties private.
Nadeem Vawda <nadeem.vawda@gmail.com>
parents: 76895
diff changeset
512 props = lzma._encode_filter_properties({'id': lzma.FILTER_LZMA1})
76895
fccdcd83708a Issue #14366: Support lzma compression in zip files.
Martin v. Löwis <martin@v.loewis.de>
parents: 76694
diff changeset
513 self._comp = lzma.LZMACompressor(lzma.FORMAT_RAW, filters=[
86536
34fb83421119 add a filterfunc to zip file.PyZipFile.writepy, issue 19274
Christian Tismer <tismer@stackless.com>
parents: 85814
diff changeset
514 lzma._decode_filter_properties(lzma.FILTER_LZMA1, props)
76895
fccdcd83708a Issue #14366: Support lzma compression in zip files.
Martin v. Löwis <martin@v.loewis.de>
parents: 76694
diff changeset
515 ])
fccdcd83708a Issue #14366: Support lzma compression in zip files.
Martin v. Löwis <martin@v.loewis.de>
parents: 76694
diff changeset
516 return struct.pack('<BBH', 9, 4, len(props)) + props
fccdcd83708a Issue #14366: Support lzma compression in zip files.
Martin v. Löwis <martin@v.loewis.de>
parents: 76694
diff changeset
517
fccdcd83708a Issue #14366: Support lzma compression in zip files.
Martin v. Löwis <martin@v.loewis.de>
parents: 76694
diff changeset
518 def compress(self, data):
fccdcd83708a Issue #14366: Support lzma compression in zip files.
Martin v. Löwis <martin@v.loewis.de>
parents: 76694
diff changeset
519 if self._comp is None:
fccdcd83708a Issue #14366: Support lzma compression in zip files.
Martin v. Löwis <martin@v.loewis.de>
parents: 76694
diff changeset
520 return self._init() + self._comp.compress(data)
fccdcd83708a Issue #14366: Support lzma compression in zip files.
Martin v. Löwis <martin@v.loewis.de>
parents: 76694
diff changeset
521 return self._comp.compress(data)
fccdcd83708a Issue #14366: Support lzma compression in zip files.
Martin v. Löwis <martin@v.loewis.de>
parents: 76694
diff changeset
522
fccdcd83708a Issue #14366: Support lzma compression in zip files.
Martin v. Löwis <martin@v.loewis.de>
parents: 76694
diff changeset
523 def flush(self):
fccdcd83708a Issue #14366: Support lzma compression in zip files.
Martin v. Löwis <martin@v.loewis.de>
parents: 76694
diff changeset
524 if self._comp is None:
fccdcd83708a Issue #14366: Support lzma compression in zip files.
Martin v. Löwis <martin@v.loewis.de>
parents: 76694
diff changeset
525 return self._init() + self._comp.flush()
fccdcd83708a Issue #14366: Support lzma compression in zip files.
Martin v. Löwis <martin@v.loewis.de>
parents: 76694
diff changeset
526 return self._comp.flush()
fccdcd83708a Issue #14366: Support lzma compression in zip files.
Martin v. Löwis <martin@v.loewis.de>
parents: 76694
diff changeset
527
fccdcd83708a Issue #14366: Support lzma compression in zip files.
Martin v. Löwis <martin@v.loewis.de>
parents: 76694
diff changeset
528
fccdcd83708a Issue #14366: Support lzma compression in zip files.
Martin v. Löwis <martin@v.loewis.de>
parents: 76694
diff changeset
529 class LZMADecompressor:
fccdcd83708a Issue #14366: Support lzma compression in zip files.
Martin v. Löwis <martin@v.loewis.de>
parents: 76694
diff changeset
530
fccdcd83708a Issue #14366: Support lzma compression in zip files.
Martin v. Löwis <martin@v.loewis.de>
parents: 76694
diff changeset
531 def __init__(self):
fccdcd83708a Issue #14366: Support lzma compression in zip files.
Martin v. Löwis <martin@v.loewis.de>
parents: 76694
diff changeset
532 self._decomp = None
fccdcd83708a Issue #14366: Support lzma compression in zip files.
Martin v. Löwis <martin@v.loewis.de>
parents: 76694
diff changeset
533 self._unconsumed = b''
fccdcd83708a Issue #14366: Support lzma compression in zip files.
Martin v. Löwis <martin@v.loewis.de>
parents: 76694
diff changeset
534 self.eof = False
fccdcd83708a Issue #14366: Support lzma compression in zip files.
Martin v. Löwis <martin@v.loewis.de>
parents: 76694
diff changeset
535
fccdcd83708a Issue #14366: Support lzma compression in zip files.
Martin v. Löwis <martin@v.loewis.de>
parents: 76694
diff changeset
536 def decompress(self, data):
fccdcd83708a Issue #14366: Support lzma compression in zip files.
Martin v. Löwis <martin@v.loewis.de>
parents: 76694
diff changeset
537 if self._decomp is None:
fccdcd83708a Issue #14366: Support lzma compression in zip files.
Martin v. Löwis <martin@v.loewis.de>
parents: 76694
diff changeset
538 self._unconsumed += data
fccdcd83708a Issue #14366: Support lzma compression in zip files.
Martin v. Löwis <martin@v.loewis.de>
parents: 76694
diff changeset
539 if len(self._unconsumed) <= 4:
fccdcd83708a Issue #14366: Support lzma compression in zip files.
Martin v. Löwis <martin@v.loewis.de>
parents: 76694
diff changeset
540 return b''
fccdcd83708a Issue #14366: Support lzma compression in zip files.
Martin v. Löwis <martin@v.loewis.de>
parents: 76694
diff changeset
541 psize, = struct.unpack('<H', self._unconsumed[2:4])
fccdcd83708a Issue #14366: Support lzma compression in zip files.
Martin v. Löwis <martin@v.loewis.de>
parents: 76694
diff changeset
542 if len(self._unconsumed) <= 4 + psize:
fccdcd83708a Issue #14366: Support lzma compression in zip files.
Martin v. Löwis <martin@v.loewis.de>
parents: 76694
diff changeset
543 return b''
fccdcd83708a Issue #14366: Support lzma compression in zip files.
Martin v. Löwis <martin@v.loewis.de>
parents: 76694
diff changeset
544
fccdcd83708a Issue #14366: Support lzma compression in zip files.
Martin v. Löwis <martin@v.loewis.de>
parents: 76694
diff changeset
545 self._decomp = lzma.LZMADecompressor(lzma.FORMAT_RAW, filters=[
86536
34fb83421119 add a filterfunc to zip file.PyZipFile.writepy, issue 19274
Christian Tismer <tismer@stackless.com>
parents: 85814
diff changeset
546 lzma._decode_filter_properties(lzma.FILTER_LZMA1,
34fb83421119 add a filterfunc to zip file.PyZipFile.writepy, issue 19274
Christian Tismer <tismer@stackless.com>
parents: 85814
diff changeset
547 self._unconsumed[4:4 + psize])
76895
fccdcd83708a Issue #14366: Support lzma compression in zip files.
Martin v. Löwis <martin@v.loewis.de>
parents: 76694
diff changeset
548 ])
fccdcd83708a Issue #14366: Support lzma compression in zip files.
Martin v. Löwis <martin@v.loewis.de>
parents: 76694
diff changeset
549 data = self._unconsumed[4 + psize:]
fccdcd83708a Issue #14366: Support lzma compression in zip files.
Martin v. Löwis <martin@v.loewis.de>
parents: 76694
diff changeset
550 del self._unconsumed
fccdcd83708a Issue #14366: Support lzma compression in zip files.
Martin v. Löwis <martin@v.loewis.de>
parents: 76694
diff changeset
551
fccdcd83708a Issue #14366: Support lzma compression in zip files.
Martin v. Löwis <martin@v.loewis.de>
parents: 76694
diff changeset
552 result = self._decomp.decompress(data)
fccdcd83708a Issue #14366: Support lzma compression in zip files.
Martin v. Löwis <martin@v.loewis.de>
parents: 76694
diff changeset
553 self.eof = self._decomp.eof
fccdcd83708a Issue #14366: Support lzma compression in zip files.
Martin v. Löwis <martin@v.loewis.de>
parents: 76694
diff changeset
554 return result
fccdcd83708a Issue #14366: Support lzma compression in zip files.
Martin v. Löwis <martin@v.loewis.de>
parents: 76694
diff changeset
555
fccdcd83708a Issue #14366: Support lzma compression in zip files.
Martin v. Löwis <martin@v.loewis.de>
parents: 76694
diff changeset
556
80500
b193a5dc7a58 #14313: zipfile now raises NotImplementedError when the compression type is unknown.
Ezio Melotti <ezio.melotti@gmail.com>
parents: 80482
diff changeset
557 compressor_names = {
b193a5dc7a58 #14313: zipfile now raises NotImplementedError when the compression type is unknown.
Ezio Melotti <ezio.melotti@gmail.com>
parents: 80482
diff changeset
558 0: 'store',
b193a5dc7a58 #14313: zipfile now raises NotImplementedError when the compression type is unknown.
Ezio Melotti <ezio.melotti@gmail.com>
parents: 80482
diff changeset
559 1: 'shrink',
b193a5dc7a58 #14313: zipfile now raises NotImplementedError when the compression type is unknown.
Ezio Melotti <ezio.melotti@gmail.com>
parents: 80482
diff changeset
560 2: 'reduce',
b193a5dc7a58 #14313: zipfile now raises NotImplementedError when the compression type is unknown.
Ezio Melotti <ezio.melotti@gmail.com>
parents: 80482
diff changeset
561 3: 'reduce',
b193a5dc7a58 #14313: zipfile now raises NotImplementedError when the compression type is unknown.
Ezio Melotti <ezio.melotti@gmail.com>
parents: 80482
diff changeset
562 4: 'reduce',
b193a5dc7a58 #14313: zipfile now raises NotImplementedError when the compression type is unknown.
Ezio Melotti <ezio.melotti@gmail.com>
parents: 80482
diff changeset
563 5: 'reduce',
b193a5dc7a58 #14313: zipfile now raises NotImplementedError when the compression type is unknown.
Ezio Melotti <ezio.melotti@gmail.com>
parents: 80482
diff changeset
564 6: 'implode',
b193a5dc7a58 #14313: zipfile now raises NotImplementedError when the compression type is unknown.
Ezio Melotti <ezio.melotti@gmail.com>
parents: 80482
diff changeset
565 7: 'tokenize',
b193a5dc7a58 #14313: zipfile now raises NotImplementedError when the compression type is unknown.
Ezio Melotti <ezio.melotti@gmail.com>
parents: 80482
diff changeset
566 8: 'deflate',
b193a5dc7a58 #14313: zipfile now raises NotImplementedError when the compression type is unknown.
Ezio Melotti <ezio.melotti@gmail.com>
parents: 80482
diff changeset
567 9: 'deflate64',
b193a5dc7a58 #14313: zipfile now raises NotImplementedError when the compression type is unknown.
Ezio Melotti <ezio.melotti@gmail.com>
parents: 80482
diff changeset
568 10: 'implode',
b193a5dc7a58 #14313: zipfile now raises NotImplementedError when the compression type is unknown.
Ezio Melotti <ezio.melotti@gmail.com>
parents: 80482
diff changeset
569 12: 'bzip2',
b193a5dc7a58 #14313: zipfile now raises NotImplementedError when the compression type is unknown.
Ezio Melotti <ezio.melotti@gmail.com>
parents: 80482
diff changeset
570 14: 'lzma',
b193a5dc7a58 #14313: zipfile now raises NotImplementedError when the compression type is unknown.
Ezio Melotti <ezio.melotti@gmail.com>
parents: 80482
diff changeset
571 18: 'terse',
b193a5dc7a58 #14313: zipfile now raises NotImplementedError when the compression type is unknown.
Ezio Melotti <ezio.melotti@gmail.com>
parents: 80482
diff changeset
572 19: 'lz77',
b193a5dc7a58 #14313: zipfile now raises NotImplementedError when the compression type is unknown.
Ezio Melotti <ezio.melotti@gmail.com>
parents: 80482
diff changeset
573 97: 'wavpack',
b193a5dc7a58 #14313: zipfile now raises NotImplementedError when the compression type is unknown.
Ezio Melotti <ezio.melotti@gmail.com>
parents: 80482
diff changeset
574 98: 'ppmd',
b193a5dc7a58 #14313: zipfile now raises NotImplementedError when the compression type is unknown.
Ezio Melotti <ezio.melotti@gmail.com>
parents: 80482
diff changeset
575 }
b193a5dc7a58 #14313: zipfile now raises NotImplementedError when the compression type is unknown.
Ezio Melotti <ezio.melotti@gmail.com>
parents: 80482
diff changeset
576
76682
028e8e0b03e8 Issue #14371: Support bzip2 in zipfile module.
Martin v. Löwis <martin@v.loewis.de>
parents: 76373
diff changeset
577 def _check_compression(compression):
028e8e0b03e8 Issue #14371: Support bzip2 in zipfile module.
Martin v. Löwis <martin@v.loewis.de>
parents: 76373
diff changeset
578 if compression == ZIP_STORED:
028e8e0b03e8 Issue #14371: Support bzip2 in zipfile module.
Martin v. Löwis <martin@v.loewis.de>
parents: 76373
diff changeset
579 pass
028e8e0b03e8 Issue #14371: Support bzip2 in zipfile module.
Martin v. Löwis <martin@v.loewis.de>
parents: 76373
diff changeset
580 elif compression == ZIP_DEFLATED:
028e8e0b03e8 Issue #14371: Support bzip2 in zipfile module.
Martin v. Löwis <martin@v.loewis.de>
parents: 76373
diff changeset
581 if not zlib:
028e8e0b03e8 Issue #14371: Support bzip2 in zipfile module.
Martin v. Löwis <martin@v.loewis.de>
parents: 76373
diff changeset
582 raise RuntimeError(
86536
34fb83421119 add a filterfunc to zip file.PyZipFile.writepy, issue 19274
Christian Tismer <tismer@stackless.com>
parents: 85814
diff changeset
583 "Compression requires the (missing) zlib module")
76682
028e8e0b03e8 Issue #14371: Support bzip2 in zipfile module.
Martin v. Löwis <martin@v.loewis.de>
parents: 76373
diff changeset
584 elif compression == ZIP_BZIP2:
028e8e0b03e8 Issue #14371: Support bzip2 in zipfile module.
Martin v. Löwis <martin@v.loewis.de>
parents: 76373
diff changeset
585 if not bz2:
028e8e0b03e8 Issue #14371: Support bzip2 in zipfile module.
Martin v. Löwis <martin@v.loewis.de>
parents: 76373
diff changeset
586 raise RuntimeError(
86536
34fb83421119 add a filterfunc to zip file.PyZipFile.writepy, issue 19274
Christian Tismer <tismer@stackless.com>
parents: 85814
diff changeset
587 "Compression requires the (missing) bz2 module")
76895
fccdcd83708a Issue #14366: Support lzma compression in zip files.
Martin v. Löwis <martin@v.loewis.de>
parents: 76694
diff changeset
588 elif compression == ZIP_LZMA:
fccdcd83708a Issue #14366: Support lzma compression in zip files.
Martin v. Löwis <martin@v.loewis.de>
parents: 76694
diff changeset
589 if not lzma:
fccdcd83708a Issue #14366: Support lzma compression in zip files.
Martin v. Löwis <martin@v.loewis.de>
parents: 76694
diff changeset
590 raise RuntimeError(
86536
34fb83421119 add a filterfunc to zip file.PyZipFile.writepy, issue 19274
Christian Tismer <tismer@stackless.com>
parents: 85814
diff changeset
591 "Compression requires the (missing) lzma module")
76682
028e8e0b03e8 Issue #14371: Support bzip2 in zipfile module.
Martin v. Löwis <martin@v.loewis.de>
parents: 76373
diff changeset
592 else:
028e8e0b03e8 Issue #14371: Support bzip2 in zipfile module.
Martin v. Löwis <martin@v.loewis.de>
parents: 76373
diff changeset
593 raise RuntimeError("That compression method is not supported")
028e8e0b03e8 Issue #14371: Support bzip2 in zipfile module.
Martin v. Löwis <martin@v.loewis.de>
parents: 76373
diff changeset
594
028e8e0b03e8 Issue #14371: Support bzip2 in zipfile module.
Martin v. Löwis <martin@v.loewis.de>
parents: 76373
diff changeset
595
028e8e0b03e8 Issue #14371: Support bzip2 in zipfile module.
Martin v. Löwis <martin@v.loewis.de>
parents: 76373
diff changeset
596 def _get_compressor(compress_type):
028e8e0b03e8 Issue #14371: Support bzip2 in zipfile module.
Martin v. Löwis <martin@v.loewis.de>
parents: 76373
diff changeset
597 if compress_type == ZIP_DEFLATED:
028e8e0b03e8 Issue #14371: Support bzip2 in zipfile module.
Martin v. Löwis <martin@v.loewis.de>
parents: 76373
diff changeset
598 return zlib.compressobj(zlib.Z_DEFAULT_COMPRESSION,
86536
34fb83421119 add a filterfunc to zip file.PyZipFile.writepy, issue 19274
Christian Tismer <tismer@stackless.com>
parents: 85814
diff changeset
599 zlib.DEFLATED, -15)
76682
028e8e0b03e8 Issue #14371: Support bzip2 in zipfile module.
Martin v. Löwis <martin@v.loewis.de>
parents: 76373
diff changeset
600 elif compress_type == ZIP_BZIP2:
028e8e0b03e8 Issue #14371: Support bzip2 in zipfile module.
Martin v. Löwis <martin@v.loewis.de>
parents: 76373
diff changeset
601 return bz2.BZ2Compressor()
76895
fccdcd83708a Issue #14366: Support lzma compression in zip files.
Martin v. Löwis <martin@v.loewis.de>
parents: 76694
diff changeset
602 elif compress_type == ZIP_LZMA:
fccdcd83708a Issue #14366: Support lzma compression in zip files.
Martin v. Löwis <martin@v.loewis.de>
parents: 76694
diff changeset
603 return LZMACompressor()
76682
028e8e0b03e8 Issue #14371: Support bzip2 in zipfile module.
Martin v. Löwis <martin@v.loewis.de>
parents: 76373
diff changeset
604 else:
028e8e0b03e8 Issue #14371: Support bzip2 in zipfile module.
Martin v. Löwis <martin@v.loewis.de>
parents: 76373
diff changeset
605 return None
028e8e0b03e8 Issue #14371: Support bzip2 in zipfile module.
Martin v. Löwis <martin@v.loewis.de>
parents: 76373
diff changeset
606
028e8e0b03e8 Issue #14371: Support bzip2 in zipfile module.
Martin v. Löwis <martin@v.loewis.de>
parents: 76373
diff changeset
607
028e8e0b03e8 Issue #14371: Support bzip2 in zipfile module.
Martin v. Löwis <martin@v.loewis.de>
parents: 76373
diff changeset
608 def _get_decompressor(compress_type):
76683
596b0eaeece8 Detect unsupported compression types.
Martin v. Löwis <martin@v.loewis.de>
parents: 76682
diff changeset
609 if compress_type == ZIP_STORED:
596b0eaeece8 Detect unsupported compression types.
Martin v. Löwis <martin@v.loewis.de>
parents: 76682
diff changeset
610 return None
596b0eaeece8 Detect unsupported compression types.
Martin v. Löwis <martin@v.loewis.de>
parents: 76682
diff changeset
611 elif compress_type == ZIP_DEFLATED:
76682
028e8e0b03e8 Issue #14371: Support bzip2 in zipfile module.
Martin v. Löwis <martin@v.loewis.de>
parents: 76373
diff changeset
612 return zlib.decompressobj(-15)
028e8e0b03e8 Issue #14371: Support bzip2 in zipfile module.
Martin v. Löwis <martin@v.loewis.de>
parents: 76373
diff changeset
613 elif compress_type == ZIP_BZIP2:
028e8e0b03e8 Issue #14371: Support bzip2 in zipfile module.
Martin v. Löwis <martin@v.loewis.de>
parents: 76373
diff changeset
614 return bz2.BZ2Decompressor()
76895
fccdcd83708a Issue #14366: Support lzma compression in zip files.
Martin v. Löwis <martin@v.loewis.de>
parents: 76694
diff changeset
615 elif compress_type == ZIP_LZMA:
fccdcd83708a Issue #14366: Support lzma compression in zip files.
Martin v. Löwis <martin@v.loewis.de>
parents: 76694
diff changeset
616 return LZMADecompressor()
76682
028e8e0b03e8 Issue #14371: Support bzip2 in zipfile module.
Martin v. Löwis <martin@v.loewis.de>
parents: 76373
diff changeset
617 else:
76895
fccdcd83708a Issue #14366: Support lzma compression in zip files.
Martin v. Löwis <martin@v.loewis.de>
parents: 76694
diff changeset
618 descr = compressor_names.get(compress_type)
76683
596b0eaeece8 Detect unsupported compression types.
Martin v. Löwis <martin@v.loewis.de>
parents: 76682
diff changeset
619 if descr:
596b0eaeece8 Detect unsupported compression types.
Martin v. Löwis <martin@v.loewis.de>
parents: 76682
diff changeset
620 raise NotImplementedError("compression type %d (%s)" % (compress_type, descr))
596b0eaeece8 Detect unsupported compression types.
Martin v. Löwis <martin@v.loewis.de>
parents: 76682
diff changeset
621 else:
596b0eaeece8 Detect unsupported compression types.
Martin v. Löwis <martin@v.loewis.de>
parents: 76682
diff changeset
622 raise NotImplementedError("compression type %d" % (compress_type,))
76682
028e8e0b03e8 Issue #14371: Support bzip2 in zipfile module.
Martin v. Löwis <martin@v.loewis.de>
parents: 76373
diff changeset
623
80500
b193a5dc7a58 #14313: zipfile now raises NotImplementedError when the compression type is unknown.
Ezio Melotti <ezio.melotti@gmail.com>
parents: 80482
diff changeset
624
58542
f41d353eb660 Merged revisions 77798 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58004
diff changeset
625 class ZipExtFile(io.BufferedIOBase):
41554
06145fbc7ab9 Merged revisions 53952-54987 via svnmerge from
Guido van Rossum <guido@python.org>
parents: 41452
diff changeset
626 """File-like object for reading an archive member.
06145fbc7ab9 Merged revisions 53952-54987 via svnmerge from
Guido van Rossum <guido@python.org>
parents: 41452
diff changeset
627 Is returned by ZipFile.open().
06145fbc7ab9 Merged revisions 53952-54987 via svnmerge from
Guido van Rossum <guido@python.org>
parents: 41452
diff changeset
628 """
06145fbc7ab9 Merged revisions 53952-54987 via svnmerge from
Guido van Rossum <guido@python.org>
parents: 41452
diff changeset
629
58542
f41d353eb660 Merged revisions 77798 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58004
diff changeset
630 # Max size supported by decompressor.
f41d353eb660 Merged revisions 77798 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58004
diff changeset
631 MAX_N = 1 << 31 - 1
f41d353eb660 Merged revisions 77798 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58004
diff changeset
632
f41d353eb660 Merged revisions 77798 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58004
diff changeset
633 # Read from compressed files in 4k blocks.
f41d353eb660 Merged revisions 77798 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58004
diff changeset
634 MIN_READ_SIZE = 4096
f41d353eb660 Merged revisions 77798 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58004
diff changeset
635
f41d353eb660 Merged revisions 77798 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58004
diff changeset
636 # Search for universal newlines or line chunks.
f41d353eb660 Merged revisions 77798 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58004
diff changeset
637 PATTERN = re.compile(br'^(?P<chunk>[^\r\n]+)|(?P<newline>\n|\r\n?)')
f41d353eb660 Merged revisions 77798 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58004
diff changeset
638
66408
2c370065c1b4 Issue #9846: ZipExtFile provides no mechanism for closing the underlying file object
Łukasz Langa <lukasz@langa.pl>
parents: 65830
diff changeset
639 def __init__(self, fileobj, mode, zipinfo, decrypter=None,
2c370065c1b4 Issue #9846: ZipExtFile provides no mechanism for closing the underlying file object
Łukasz Langa <lukasz@langa.pl>
parents: 65830
diff changeset
640 close_fileobj=False):
58542
f41d353eb660 Merged revisions 77798 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58004
diff changeset
641 self._fileobj = fileobj
f41d353eb660 Merged revisions 77798 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58004
diff changeset
642 self._decrypter = decrypter
66408
2c370065c1b4 Issue #9846: ZipExtFile provides no mechanism for closing the underlying file object
Łukasz Langa <lukasz@langa.pl>
parents: 65830
diff changeset
643 self._close_fileobj = close_fileobj
41554
06145fbc7ab9 Merged revisions 53952-54987 via svnmerge from
Guido van Rossum <guido@python.org>
parents: 41452
diff changeset
644
58552
245f36282113 Merged revisions 77809 via svnmerge from
Ezio Melotti <ezio.melotti@gmail.com>
parents: 58542
diff changeset
645 self._compress_type = zipinfo.compress_type
245f36282113 Merged revisions 77809 via svnmerge from
Ezio Melotti <ezio.melotti@gmail.com>
parents: 58542
diff changeset
646 self._compress_left = zipinfo.compress_size
76682
028e8e0b03e8 Issue #14371: Support bzip2 in zipfile module.
Martin v. Löwis <martin@v.loewis.de>
parents: 76373
diff changeset
647 self._left = zipinfo.file_size
58552
245f36282113 Merged revisions 77809 via svnmerge from
Ezio Melotti <ezio.melotti@gmail.com>
parents: 58542
diff changeset
648
76682
028e8e0b03e8 Issue #14371: Support bzip2 in zipfile module.
Martin v. Löwis <martin@v.loewis.de>
parents: 76373
diff changeset
649 self._decompressor = _get_decompressor(self._compress_type)
41554
06145fbc7ab9 Merged revisions 53952-54987 via svnmerge from
Guido van Rossum <guido@python.org>
parents: 41452
diff changeset
650
76682
028e8e0b03e8 Issue #14371: Support bzip2 in zipfile module.
Martin v. Löwis <martin@v.loewis.de>
parents: 76373
diff changeset
651 self._eof = False
58542
f41d353eb660 Merged revisions 77798 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58004
diff changeset
652 self._readbuffer = b''
f41d353eb660 Merged revisions 77798 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58004
diff changeset
653 self._offset = 0
f41d353eb660 Merged revisions 77798 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58004
diff changeset
654
f41d353eb660 Merged revisions 77798 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58004
diff changeset
655 self._universal = 'U' in mode
f41d353eb660 Merged revisions 77798 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58004
diff changeset
656 self.newlines = None
41554
06145fbc7ab9 Merged revisions 53952-54987 via svnmerge from
Guido van Rossum <guido@python.org>
parents: 41452
diff changeset
657
58542
f41d353eb660 Merged revisions 77798 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58004
diff changeset
658 # Adjust read size for encrypted files since the first 12 bytes
f41d353eb660 Merged revisions 77798 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58004
diff changeset
659 # are for the encryption/password information.
f41d353eb660 Merged revisions 77798 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58004
diff changeset
660 if self._decrypter is not None:
f41d353eb660 Merged revisions 77798 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58004
diff changeset
661 self._compress_left -= 12
f41d353eb660 Merged revisions 77798 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58004
diff changeset
662
f41d353eb660 Merged revisions 77798 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58004
diff changeset
663 self.mode = mode
41554
06145fbc7ab9 Merged revisions 53952-54987 via svnmerge from
Guido van Rossum <guido@python.org>
parents: 41452
diff changeset
664 self.name = zipinfo.filename
06145fbc7ab9 Merged revisions 53952-54987 via svnmerge from
Guido van Rossum <guido@python.org>
parents: 41452
diff changeset
665
63936
68c48f8aa555 Merged revisions 83959-83960 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58176
diff changeset
666 if hasattr(zipinfo, 'CRC'):
68c48f8aa555 Merged revisions 83959-83960 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58176
diff changeset
667 self._expected_crc = zipinfo.CRC
68c48f8aa555 Merged revisions 83959-83960 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58176
diff changeset
668 self._running_crc = crc32(b'') & 0xffffffff
68c48f8aa555 Merged revisions 83959-83960 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58176
diff changeset
669 else:
68c48f8aa555 Merged revisions 83959-83960 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58176
diff changeset
670 self._expected_crc = None
68c48f8aa555 Merged revisions 83959-83960 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58176
diff changeset
671
58542
f41d353eb660 Merged revisions 77798 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58004
diff changeset
672 def readline(self, limit=-1):
f41d353eb660 Merged revisions 77798 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58004
diff changeset
673 """Read and return a line from the stream.
41554
06145fbc7ab9 Merged revisions 53952-54987 via svnmerge from
Guido van Rossum <guido@python.org>
parents: 41452
diff changeset
674
58542
f41d353eb660 Merged revisions 77798 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58004
diff changeset
675 If limit is specified, at most limit bytes will be read.
41554
06145fbc7ab9 Merged revisions 53952-54987 via svnmerge from
Guido van Rossum <guido@python.org>
parents: 41452
diff changeset
676 """
06145fbc7ab9 Merged revisions 53952-54987 via svnmerge from
Guido van Rossum <guido@python.org>
parents: 41452
diff changeset
677
58542
f41d353eb660 Merged revisions 77798 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58004
diff changeset
678 if not self._universal and limit < 0:
f41d353eb660 Merged revisions 77798 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58004
diff changeset
679 # Shortcut common case - newline found in buffer.
f41d353eb660 Merged revisions 77798 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58004
diff changeset
680 i = self._readbuffer.find(b'\n', self._offset) + 1
f41d353eb660 Merged revisions 77798 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58004
diff changeset
681 if i > 0:
f41d353eb660 Merged revisions 77798 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58004
diff changeset
682 line = self._readbuffer[self._offset: i]
f41d353eb660 Merged revisions 77798 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58004
diff changeset
683 self._offset = i
f41d353eb660 Merged revisions 77798 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58004
diff changeset
684 return line
41554
06145fbc7ab9 Merged revisions 53952-54987 via svnmerge from
Guido van Rossum <guido@python.org>
parents: 41452
diff changeset
685
58542
f41d353eb660 Merged revisions 77798 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58004
diff changeset
686 if not self._universal:
f41d353eb660 Merged revisions 77798 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58004
diff changeset
687 return io.BufferedIOBase.readline(self, limit)
41554
06145fbc7ab9 Merged revisions 53952-54987 via svnmerge from
Guido van Rossum <guido@python.org>
parents: 41452
diff changeset
688
58542
f41d353eb660 Merged revisions 77798 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58004
diff changeset
689 line = b''
f41d353eb660 Merged revisions 77798 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58004
diff changeset
690 while limit < 0 or len(line) < limit:
f41d353eb660 Merged revisions 77798 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58004
diff changeset
691 readahead = self.peek(2)
f41d353eb660 Merged revisions 77798 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58004
diff changeset
692 if readahead == b'':
f41d353eb660 Merged revisions 77798 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58004
diff changeset
693 return line
41554
06145fbc7ab9 Merged revisions 53952-54987 via svnmerge from
Guido van Rossum <guido@python.org>
parents: 41452
diff changeset
694
58542
f41d353eb660 Merged revisions 77798 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58004
diff changeset
695 #
f41d353eb660 Merged revisions 77798 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58004
diff changeset
696 # Search for universal newlines or line chunks.
f41d353eb660 Merged revisions 77798 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58004
diff changeset
697 #
f41d353eb660 Merged revisions 77798 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58004
diff changeset
698 # The pattern returns either a line chunk or a newline, but not
f41d353eb660 Merged revisions 77798 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58004
diff changeset
699 # both. Combined with peek(2), we are assured that the sequence
f41d353eb660 Merged revisions 77798 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58004
diff changeset
700 # '\r\n' is always retrieved completely and never split into
f41d353eb660 Merged revisions 77798 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58004
diff changeset
701 # separate newlines - '\r', '\n' due to coincidental readaheads.
f41d353eb660 Merged revisions 77798 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58004
diff changeset
702 #
f41d353eb660 Merged revisions 77798 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58004
diff changeset
703 match = self.PATTERN.search(readahead)
f41d353eb660 Merged revisions 77798 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58004
diff changeset
704 newline = match.group('newline')
f41d353eb660 Merged revisions 77798 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58004
diff changeset
705 if newline is not None:
f41d353eb660 Merged revisions 77798 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58004
diff changeset
706 if self.newlines is None:
f41d353eb660 Merged revisions 77798 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58004
diff changeset
707 self.newlines = []
f41d353eb660 Merged revisions 77798 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58004
diff changeset
708 if newline not in self.newlines:
f41d353eb660 Merged revisions 77798 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58004
diff changeset
709 self.newlines.append(newline)
f41d353eb660 Merged revisions 77798 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58004
diff changeset
710 self._offset += len(newline)
f41d353eb660 Merged revisions 77798 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58004
diff changeset
711 return line + b'\n'
41554
06145fbc7ab9 Merged revisions 53952-54987 via svnmerge from
Guido van Rossum <guido@python.org>
parents: 41452
diff changeset
712
58542
f41d353eb660 Merged revisions 77798 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58004
diff changeset
713 chunk = match.group('chunk')
f41d353eb660 Merged revisions 77798 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58004
diff changeset
714 if limit >= 0:
f41d353eb660 Merged revisions 77798 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58004
diff changeset
715 chunk = chunk[: limit - len(line)]
41554
06145fbc7ab9 Merged revisions 53952-54987 via svnmerge from
Guido van Rossum <guido@python.org>
parents: 41452
diff changeset
716
58542
f41d353eb660 Merged revisions 77798 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58004
diff changeset
717 self._offset += len(chunk)
f41d353eb660 Merged revisions 77798 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58004
diff changeset
718 line += chunk
f41d353eb660 Merged revisions 77798 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58004
diff changeset
719
f41d353eb660 Merged revisions 77798 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58004
diff changeset
720 return line
41554
06145fbc7ab9 Merged revisions 53952-54987 via svnmerge from
Guido van Rossum <guido@python.org>
parents: 41452
diff changeset
721
58542
f41d353eb660 Merged revisions 77798 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58004
diff changeset
722 def peek(self, n=1):
f41d353eb660 Merged revisions 77798 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58004
diff changeset
723 """Returns buffered bytes without advancing the position."""
f41d353eb660 Merged revisions 77798 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58004
diff changeset
724 if n > len(self._readbuffer) - self._offset:
f41d353eb660 Merged revisions 77798 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58004
diff changeset
725 chunk = self.read(n)
76682
028e8e0b03e8 Issue #14371: Support bzip2 in zipfile module.
Martin v. Löwis <martin@v.loewis.de>
parents: 76373
diff changeset
726 if len(chunk) > self._offset:
028e8e0b03e8 Issue #14371: Support bzip2 in zipfile module.
Martin v. Löwis <martin@v.loewis.de>
parents: 76373
diff changeset
727 self._readbuffer = chunk + self._readbuffer[self._offset:]
028e8e0b03e8 Issue #14371: Support bzip2 in zipfile module.
Martin v. Löwis <martin@v.loewis.de>
parents: 76373
diff changeset
728 self._offset = 0
028e8e0b03e8 Issue #14371: Support bzip2 in zipfile module.
Martin v. Löwis <martin@v.loewis.de>
parents: 76373
diff changeset
729 else:
028e8e0b03e8 Issue #14371: Support bzip2 in zipfile module.
Martin v. Löwis <martin@v.loewis.de>
parents: 76373
diff changeset
730 self._offset -= len(chunk)
41554
06145fbc7ab9 Merged revisions 53952-54987 via svnmerge from
Guido van Rossum <guido@python.org>
parents: 41452
diff changeset
731
58542
f41d353eb660 Merged revisions 77798 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58004
diff changeset
732 # Return up to 512 bytes to reduce allocation overhead for tight loops.
f41d353eb660 Merged revisions 77798 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58004
diff changeset
733 return self._readbuffer[self._offset: self._offset + 512]
41554
06145fbc7ab9 Merged revisions 53952-54987 via svnmerge from
Guido van Rossum <guido@python.org>
parents: 41452
diff changeset
734
58542
f41d353eb660 Merged revisions 77798 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58004
diff changeset
735 def readable(self):
f41d353eb660 Merged revisions 77798 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58004
diff changeset
736 return True
41554
06145fbc7ab9 Merged revisions 53952-54987 via svnmerge from
Guido van Rossum <guido@python.org>
parents: 41452
diff changeset
737
58542
f41d353eb660 Merged revisions 77798 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58004
diff changeset
738 def read(self, n=-1):
f41d353eb660 Merged revisions 77798 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58004
diff changeset
739 """Read and return up to n bytes.
f41d353eb660 Merged revisions 77798 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58004
diff changeset
740 If the argument is omitted, None, or negative, data is read and returned until EOF is reached..
41554
06145fbc7ab9 Merged revisions 53952-54987 via svnmerge from
Guido van Rossum <guido@python.org>
parents: 41452
diff changeset
741 """
76682
028e8e0b03e8 Issue #14371: Support bzip2 in zipfile module.
Martin v. Löwis <martin@v.loewis.de>
parents: 76373
diff changeset
742 if n is None or n < 0:
028e8e0b03e8 Issue #14371: Support bzip2 in zipfile module.
Martin v. Löwis <martin@v.loewis.de>
parents: 76373
diff changeset
743 buf = self._readbuffer[self._offset:]
028e8e0b03e8 Issue #14371: Support bzip2 in zipfile module.
Martin v. Löwis <martin@v.loewis.de>
parents: 76373
diff changeset
744 self._readbuffer = b''
028e8e0b03e8 Issue #14371: Support bzip2 in zipfile module.
Martin v. Löwis <martin@v.loewis.de>
parents: 76373
diff changeset
745 self._offset = 0
028e8e0b03e8 Issue #14371: Support bzip2 in zipfile module.
Martin v. Löwis <martin@v.loewis.de>
parents: 76373
diff changeset
746 while not self._eof:
028e8e0b03e8 Issue #14371: Support bzip2 in zipfile module.
Martin v. Löwis <martin@v.loewis.de>
parents: 76373
diff changeset
747 buf += self._read1(self.MAX_N)
028e8e0b03e8 Issue #14371: Support bzip2 in zipfile module.
Martin v. Löwis <martin@v.loewis.de>
parents: 76373
diff changeset
748 return buf
028e8e0b03e8 Issue #14371: Support bzip2 in zipfile module.
Martin v. Löwis <martin@v.loewis.de>
parents: 76373
diff changeset
749
77631
0e8285321659 On behalf of Nadeem Vawda: issue #10376: micro-optimize reading from a Zipfile.
Antoine Pitrou <solipsis@pitrou.net>
parents: 77557
diff changeset
750 end = n + self._offset
0e8285321659 On behalf of Nadeem Vawda: issue #10376: micro-optimize reading from a Zipfile.
Antoine Pitrou <solipsis@pitrou.net>
parents: 77557
diff changeset
751 if end < len(self._readbuffer):
0e8285321659 On behalf of Nadeem Vawda: issue #10376: micro-optimize reading from a Zipfile.
Antoine Pitrou <solipsis@pitrou.net>
parents: 77557
diff changeset
752 buf = self._readbuffer[self._offset:end]
0e8285321659 On behalf of Nadeem Vawda: issue #10376: micro-optimize reading from a Zipfile.
Antoine Pitrou <solipsis@pitrou.net>
parents: 77557
diff changeset
753 self._offset = end
76682
028e8e0b03e8 Issue #14371: Support bzip2 in zipfile module.
Martin v. Löwis <martin@v.loewis.de>
parents: 76373
diff changeset
754 return buf
028e8e0b03e8 Issue #14371: Support bzip2 in zipfile module.
Martin v. Löwis <martin@v.loewis.de>
parents: 76373
diff changeset
755
77631
0e8285321659 On behalf of Nadeem Vawda: issue #10376: micro-optimize reading from a Zipfile.
Antoine Pitrou <solipsis@pitrou.net>
parents: 77557
diff changeset
756 n = end - len(self._readbuffer)
76682
028e8e0b03e8 Issue #14371: Support bzip2 in zipfile module.
Martin v. Löwis <martin@v.loewis.de>
parents: 76373
diff changeset
757 buf = self._readbuffer[self._offset:]
028e8e0b03e8 Issue #14371: Support bzip2 in zipfile module.
Martin v. Löwis <martin@v.loewis.de>
parents: 76373
diff changeset
758 self._readbuffer = b''
028e8e0b03e8 Issue #14371: Support bzip2 in zipfile module.
Martin v. Löwis <martin@v.loewis.de>
parents: 76373
diff changeset
759 self._offset = 0
028e8e0b03e8 Issue #14371: Support bzip2 in zipfile module.
Martin v. Löwis <martin@v.loewis.de>
parents: 76373
diff changeset
760 while n > 0 and not self._eof:
028e8e0b03e8 Issue #14371: Support bzip2 in zipfile module.
Martin v. Löwis <martin@v.loewis.de>
parents: 76373
diff changeset
761 data = self._read1(n)
028e8e0b03e8 Issue #14371: Support bzip2 in zipfile module.
Martin v. Löwis <martin@v.loewis.de>
parents: 76373
diff changeset
762 if n < len(data):
028e8e0b03e8 Issue #14371: Support bzip2 in zipfile module.
Martin v. Löwis <martin@v.loewis.de>
parents: 76373
diff changeset
763 self._readbuffer = data
028e8e0b03e8 Issue #14371: Support bzip2 in zipfile module.
Martin v. Löwis <martin@v.loewis.de>
parents: 76373
diff changeset
764 self._offset = n
028e8e0b03e8 Issue #14371: Support bzip2 in zipfile module.
Martin v. Löwis <martin@v.loewis.de>
parents: 76373
diff changeset
765 buf += data[:n]
028e8e0b03e8 Issue #14371: Support bzip2 in zipfile module.
Martin v. Löwis <martin@v.loewis.de>
parents: 76373
diff changeset
766 break
58542
f41d353eb660 Merged revisions 77798 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58004
diff changeset
767 buf += data
76682
028e8e0b03e8 Issue #14371: Support bzip2 in zipfile module.
Martin v. Löwis <martin@v.loewis.de>
parents: 76373
diff changeset
768 n -= len(data)
028e8e0b03e8 Issue #14371: Support bzip2 in zipfile module.
Martin v. Löwis <martin@v.loewis.de>
parents: 76373
diff changeset
769 return buf
41554
06145fbc7ab9 Merged revisions 53952-54987 via svnmerge from
Guido van Rossum <guido@python.org>
parents: 41452
diff changeset
770
76682
028e8e0b03e8 Issue #14371: Support bzip2 in zipfile module.
Martin v. Löwis <martin@v.loewis.de>
parents: 76373
diff changeset
771 def _update_crc(self, newdata):
63936
68c48f8aa555 Merged revisions 83959-83960 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58176
diff changeset
772 # Update the CRC using the given data.
68c48f8aa555 Merged revisions 83959-83960 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58176
diff changeset
773 if self._expected_crc is None:
68c48f8aa555 Merged revisions 83959-83960 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58176
diff changeset
774 # No need to compute the CRC if we don't have a reference value
68c48f8aa555 Merged revisions 83959-83960 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58176
diff changeset
775 return
68c48f8aa555 Merged revisions 83959-83960 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58176
diff changeset
776 self._running_crc = crc32(newdata, self._running_crc) & 0xffffffff
68c48f8aa555 Merged revisions 83959-83960 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58176
diff changeset
777 # Check the CRC if we're at the end of the file
76682
028e8e0b03e8 Issue #14371: Support bzip2 in zipfile module.
Martin v. Löwis <martin@v.loewis.de>
parents: 76373
diff changeset
778 if self._eof and self._running_crc != self._expected_crc:
65673
a281989a218b #7351: add more consistent exception name alias.
Georg Brandl <georg@python.org>
parents: 65290
diff changeset
779 raise BadZipFile("Bad CRC-32 for file %r" % self.name)
63936
68c48f8aa555 Merged revisions 83959-83960 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58176
diff changeset
780
58542
f41d353eb660 Merged revisions 77798 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58004
diff changeset
781 def read1(self, n):
f41d353eb660 Merged revisions 77798 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58004
diff changeset
782 """Read up to n bytes with at most one read() system call."""
41554
06145fbc7ab9 Merged revisions 53952-54987 via svnmerge from
Guido van Rossum <guido@python.org>
parents: 41452
diff changeset
783
76682
028e8e0b03e8 Issue #14371: Support bzip2 in zipfile module.
Martin v. Löwis <martin@v.loewis.de>
parents: 76373
diff changeset
784 if n is None or n < 0:
028e8e0b03e8 Issue #14371: Support bzip2 in zipfile module.
Martin v. Löwis <martin@v.loewis.de>
parents: 76373
diff changeset
785 buf = self._readbuffer[self._offset:]
028e8e0b03e8 Issue #14371: Support bzip2 in zipfile module.
Martin v. Löwis <martin@v.loewis.de>
parents: 76373
diff changeset
786 self._readbuffer = b''
028e8e0b03e8 Issue #14371: Support bzip2 in zipfile module.
Martin v. Löwis <martin@v.loewis.de>
parents: 76373
diff changeset
787 self._offset = 0
85813
460b0ccbab7f Issue #19053: ZipExtFile.read1() with non-zero argument no more returns empty
Serhiy Storchaka <storchaka@gmail.com>
parents: 81961
diff changeset
788 while not self._eof:
460b0ccbab7f Issue #19053: ZipExtFile.read1() with non-zero argument no more returns empty
Serhiy Storchaka <storchaka@gmail.com>
parents: 81961
diff changeset
789 data = self._read1(self.MAX_N)
460b0ccbab7f Issue #19053: ZipExtFile.read1() with non-zero argument no more returns empty
Serhiy Storchaka <storchaka@gmail.com>
parents: 81961
diff changeset
790 if data:
460b0ccbab7f Issue #19053: ZipExtFile.read1() with non-zero argument no more returns empty
Serhiy Storchaka <storchaka@gmail.com>
parents: 81961
diff changeset
791 buf += data
460b0ccbab7f Issue #19053: ZipExtFile.read1() with non-zero argument no more returns empty
Serhiy Storchaka <storchaka@gmail.com>
parents: 81961
diff changeset
792 break
76682
028e8e0b03e8 Issue #14371: Support bzip2 in zipfile module.
Martin v. Löwis <martin@v.loewis.de>
parents: 76373
diff changeset
793 return buf
028e8e0b03e8 Issue #14371: Support bzip2 in zipfile module.
Martin v. Löwis <martin@v.loewis.de>
parents: 76373
diff changeset
794
77631
0e8285321659 On behalf of Nadeem Vawda: issue #10376: micro-optimize reading from a Zipfile.
Antoine Pitrou <solipsis@pitrou.net>
parents: 77557
diff changeset
795 end = n + self._offset
0e8285321659 On behalf of Nadeem Vawda: issue #10376: micro-optimize reading from a Zipfile.
Antoine Pitrou <solipsis@pitrou.net>
parents: 77557
diff changeset
796 if end < len(self._readbuffer):
0e8285321659 On behalf of Nadeem Vawda: issue #10376: micro-optimize reading from a Zipfile.
Antoine Pitrou <solipsis@pitrou.net>
parents: 77557
diff changeset
797 buf = self._readbuffer[self._offset:end]
0e8285321659 On behalf of Nadeem Vawda: issue #10376: micro-optimize reading from a Zipfile.
Antoine Pitrou <solipsis@pitrou.net>
parents: 77557
diff changeset
798 self._offset = end
76682
028e8e0b03e8 Issue #14371: Support bzip2 in zipfile module.
Martin v. Löwis <martin@v.loewis.de>
parents: 76373
diff changeset
799 return buf
41554
06145fbc7ab9 Merged revisions 53952-54987 via svnmerge from
Guido van Rossum <guido@python.org>
parents: 41452
diff changeset
800
77631
0e8285321659 On behalf of Nadeem Vawda: issue #10376: micro-optimize reading from a Zipfile.
Antoine Pitrou <solipsis@pitrou.net>
parents: 77557
diff changeset
801 n = end - len(self._readbuffer)
76682
028e8e0b03e8 Issue #14371: Support bzip2 in zipfile module.
Martin v. Löwis <martin@v.loewis.de>
parents: 76373
diff changeset
802 buf = self._readbuffer[self._offset:]
028e8e0b03e8 Issue #14371: Support bzip2 in zipfile module.
Martin v. Löwis <martin@v.loewis.de>
parents: 76373
diff changeset
803 self._readbuffer = b''
028e8e0b03e8 Issue #14371: Support bzip2 in zipfile module.
Martin v. Löwis <martin@v.loewis.de>
parents: 76373
diff changeset
804 self._offset = 0
028e8e0b03e8 Issue #14371: Support bzip2 in zipfile module.
Martin v. Löwis <martin@v.loewis.de>
parents: 76373
diff changeset
805 if n > 0:
85813
460b0ccbab7f Issue #19053: ZipExtFile.read1() with non-zero argument no more returns empty
Serhiy Storchaka <storchaka@gmail.com>
parents: 81961
diff changeset
806 while not self._eof:
460b0ccbab7f Issue #19053: ZipExtFile.read1() with non-zero argument no more returns empty
Serhiy Storchaka <storchaka@gmail.com>
parents: 81961
diff changeset
807 data = self._read1(n)
460b0ccbab7f Issue #19053: ZipExtFile.read1() with non-zero argument no more returns empty
Serhiy Storchaka <storchaka@gmail.com>
parents: 81961
diff changeset
808 if n < len(data):
460b0ccbab7f Issue #19053: ZipExtFile.read1() with non-zero argument no more returns empty
Serhiy Storchaka <storchaka@gmail.com>
parents: 81961
diff changeset
809 self._readbuffer = data
460b0ccbab7f Issue #19053: ZipExtFile.read1() with non-zero argument no more returns empty
Serhiy Storchaka <storchaka@gmail.com>
parents: 81961
diff changeset
810 self._offset = n
460b0ccbab7f Issue #19053: ZipExtFile.read1() with non-zero argument no more returns empty
Serhiy Storchaka <storchaka@gmail.com>
parents: 81961
diff changeset
811 buf += data[:n]
460b0ccbab7f Issue #19053: ZipExtFile.read1() with non-zero argument no more returns empty
Serhiy Storchaka <storchaka@gmail.com>
parents: 81961
diff changeset
812 break
460b0ccbab7f Issue #19053: ZipExtFile.read1() with non-zero argument no more returns empty
Serhiy Storchaka <storchaka@gmail.com>
parents: 81961
diff changeset
813 if data:
460b0ccbab7f Issue #19053: ZipExtFile.read1() with non-zero argument no more returns empty
Serhiy Storchaka <storchaka@gmail.com>
parents: 81961
diff changeset
814 buf += data
460b0ccbab7f Issue #19053: ZipExtFile.read1() with non-zero argument no more returns empty
Serhiy Storchaka <storchaka@gmail.com>
parents: 81961
diff changeset
815 break
76682
028e8e0b03e8 Issue #14371: Support bzip2 in zipfile module.
Martin v. Löwis <martin@v.loewis.de>
parents: 76373
diff changeset
816 return buf
028e8e0b03e8 Issue #14371: Support bzip2 in zipfile module.
Martin v. Löwis <martin@v.loewis.de>
parents: 76373
diff changeset
817
028e8e0b03e8 Issue #14371: Support bzip2 in zipfile module.
Martin v. Löwis <martin@v.loewis.de>
parents: 76373
diff changeset
818 def _read1(self, n):
028e8e0b03e8 Issue #14371: Support bzip2 in zipfile module.
Martin v. Löwis <martin@v.loewis.de>
parents: 76373
diff changeset
819 # Read up to n compressed bytes with at most one read() system call,
028e8e0b03e8 Issue #14371: Support bzip2 in zipfile module.
Martin v. Löwis <martin@v.loewis.de>
parents: 76373
diff changeset
820 # decrypt and decompress them.
028e8e0b03e8 Issue #14371: Support bzip2 in zipfile module.
Martin v. Löwis <martin@v.loewis.de>
parents: 76373
diff changeset
821 if self._eof or n <= 0:
028e8e0b03e8 Issue #14371: Support bzip2 in zipfile module.
Martin v. Löwis <martin@v.loewis.de>
parents: 76373
diff changeset
822 return b''
41554
06145fbc7ab9 Merged revisions 53952-54987 via svnmerge from
Guido van Rossum <guido@python.org>
parents: 41452
diff changeset
823
58542
f41d353eb660 Merged revisions 77798 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58004
diff changeset
824 # Read from file.
76682
028e8e0b03e8 Issue #14371: Support bzip2 in zipfile module.
Martin v. Löwis <martin@v.loewis.de>
parents: 76373
diff changeset
825 if self._compress_type == ZIP_DEFLATED:
028e8e0b03e8 Issue #14371: Support bzip2 in zipfile module.
Martin v. Löwis <martin@v.loewis.de>
parents: 76373
diff changeset
826 ## Handle unconsumed data.
028e8e0b03e8 Issue #14371: Support bzip2 in zipfile module.
Martin v. Löwis <martin@v.loewis.de>
parents: 76373
diff changeset
827 data = self._decompressor.unconsumed_tail
028e8e0b03e8 Issue #14371: Support bzip2 in zipfile module.
Martin v. Löwis <martin@v.loewis.de>
parents: 76373
diff changeset
828 if n > len(data):
028e8e0b03e8 Issue #14371: Support bzip2 in zipfile module.
Martin v. Löwis <martin@v.loewis.de>
parents: 76373
diff changeset
829 data += self._read2(n - len(data))
028e8e0b03e8 Issue #14371: Support bzip2 in zipfile module.
Martin v. Löwis <martin@v.loewis.de>
parents: 76373
diff changeset
830 else:
028e8e0b03e8 Issue #14371: Support bzip2 in zipfile module.
Martin v. Löwis <martin@v.loewis.de>
parents: 76373
diff changeset
831 data = self._read2(n)
41554
06145fbc7ab9 Merged revisions 53952-54987 via svnmerge from
Guido van Rossum <guido@python.org>
parents: 41452
diff changeset
832
76682
028e8e0b03e8 Issue #14371: Support bzip2 in zipfile module.
Martin v. Löwis <martin@v.loewis.de>
parents: 76373
diff changeset
833 if self._compress_type == ZIP_STORED:
028e8e0b03e8 Issue #14371: Support bzip2 in zipfile module.
Martin v. Löwis <martin@v.loewis.de>
parents: 76373
diff changeset
834 self._eof = self._compress_left <= 0
028e8e0b03e8 Issue #14371: Support bzip2 in zipfile module.
Martin v. Löwis <martin@v.loewis.de>
parents: 76373
diff changeset
835 elif self._compress_type == ZIP_DEFLATED:
028e8e0b03e8 Issue #14371: Support bzip2 in zipfile module.
Martin v. Löwis <martin@v.loewis.de>
parents: 76373
diff changeset
836 n = max(n, self.MIN_READ_SIZE)
028e8e0b03e8 Issue #14371: Support bzip2 in zipfile module.
Martin v. Löwis <martin@v.loewis.de>
parents: 76373
diff changeset
837 data = self._decompressor.decompress(data, n)
028e8e0b03e8 Issue #14371: Support bzip2 in zipfile module.
Martin v. Löwis <martin@v.loewis.de>
parents: 76373
diff changeset
838 self._eof = (self._decompressor.eof or
86536
34fb83421119 add a filterfunc to zip file.PyZipFile.writepy, issue 19274
Christian Tismer <tismer@stackless.com>
parents: 85814
diff changeset
839 self._compress_left <= 0 and
34fb83421119 add a filterfunc to zip file.PyZipFile.writepy, issue 19274
Christian Tismer <tismer@stackless.com>
parents: 85814
diff changeset
840 not self._decompressor.unconsumed_tail)
76682
028e8e0b03e8 Issue #14371: Support bzip2 in zipfile module.
Martin v. Löwis <martin@v.loewis.de>
parents: 76373
diff changeset
841 if self._eof:
028e8e0b03e8 Issue #14371: Support bzip2 in zipfile module.
Martin v. Löwis <martin@v.loewis.de>
parents: 76373
diff changeset
842 data += self._decompressor.flush()
028e8e0b03e8 Issue #14371: Support bzip2 in zipfile module.
Martin v. Löwis <martin@v.loewis.de>
parents: 76373
diff changeset
843 else:
028e8e0b03e8 Issue #14371: Support bzip2 in zipfile module.
Martin v. Löwis <martin@v.loewis.de>
parents: 76373
diff changeset
844 data = self._decompressor.decompress(data)
028e8e0b03e8 Issue #14371: Support bzip2 in zipfile module.
Martin v. Löwis <martin@v.loewis.de>
parents: 76373
diff changeset
845 self._eof = self._decompressor.eof or self._compress_left <= 0
41554
06145fbc7ab9 Merged revisions 53952-54987 via svnmerge from
Guido van Rossum <guido@python.org>
parents: 41452
diff changeset
846
76682
028e8e0b03e8 Issue #14371: Support bzip2 in zipfile module.
Martin v. Löwis <martin@v.loewis.de>
parents: 76373
diff changeset
847 data = data[:self._left]
028e8e0b03e8 Issue #14371: Support bzip2 in zipfile module.
Martin v. Löwis <martin@v.loewis.de>
parents: 76373
diff changeset
848 self._left -= len(data)
028e8e0b03e8 Issue #14371: Support bzip2 in zipfile module.
Martin v. Löwis <martin@v.loewis.de>
parents: 76373
diff changeset
849 if self._left <= 0:
028e8e0b03e8 Issue #14371: Support bzip2 in zipfile module.
Martin v. Löwis <martin@v.loewis.de>
parents: 76373
diff changeset
850 self._eof = True
028e8e0b03e8 Issue #14371: Support bzip2 in zipfile module.
Martin v. Löwis <martin@v.loewis.de>
parents: 76373
diff changeset
851 self._update_crc(data)
028e8e0b03e8 Issue #14371: Support bzip2 in zipfile module.
Martin v. Löwis <martin@v.loewis.de>
parents: 76373
diff changeset
852 return data
41554
06145fbc7ab9 Merged revisions 53952-54987 via svnmerge from
Guido van Rossum <guido@python.org>
parents: 41452
diff changeset
853
76682
028e8e0b03e8 Issue #14371: Support bzip2 in zipfile module.
Martin v. Löwis <martin@v.loewis.de>
parents: 76373
diff changeset
854 def _read2(self, n):
028e8e0b03e8 Issue #14371: Support bzip2 in zipfile module.
Martin v. Löwis <martin@v.loewis.de>
parents: 76373
diff changeset
855 if self._compress_left <= 0:
028e8e0b03e8 Issue #14371: Support bzip2 in zipfile module.
Martin v. Löwis <martin@v.loewis.de>
parents: 76373
diff changeset
856 return b''
41554
06145fbc7ab9 Merged revisions 53952-54987 via svnmerge from
Guido van Rossum <guido@python.org>
parents: 41452
diff changeset
857
76682
028e8e0b03e8 Issue #14371: Support bzip2 in zipfile module.
Martin v. Löwis <martin@v.loewis.de>
parents: 76373
diff changeset
858 n = max(n, self.MIN_READ_SIZE)
028e8e0b03e8 Issue #14371: Support bzip2 in zipfile module.
Martin v. Löwis <martin@v.loewis.de>
parents: 76373
diff changeset
859 n = min(n, self._compress_left)
028e8e0b03e8 Issue #14371: Support bzip2 in zipfile module.
Martin v. Löwis <martin@v.loewis.de>
parents: 76373
diff changeset
860
028e8e0b03e8 Issue #14371: Support bzip2 in zipfile module.
Martin v. Löwis <martin@v.loewis.de>
parents: 76373
diff changeset
861 data = self._fileobj.read(n)
028e8e0b03e8 Issue #14371: Support bzip2 in zipfile module.
Martin v. Löwis <martin@v.loewis.de>
parents: 76373
diff changeset
862 self._compress_left -= len(data)
028e8e0b03e8 Issue #14371: Support bzip2 in zipfile module.
Martin v. Löwis <martin@v.loewis.de>
parents: 76373
diff changeset
863
028e8e0b03e8 Issue #14371: Support bzip2 in zipfile module.
Martin v. Löwis <martin@v.loewis.de>
parents: 76373
diff changeset
864 if self._decrypter is not None:
028e8e0b03e8 Issue #14371: Support bzip2 in zipfile module.
Martin v. Löwis <martin@v.loewis.de>
parents: 76373
diff changeset
865 data = bytes(map(self._decrypter, data))
41812
50dafa22b8a4 Make test_zipfile pass.
Guido van Rossum <guido@python.org>
parents: 41760
diff changeset
866 return data
41554
06145fbc7ab9 Merged revisions 53952-54987 via svnmerge from
Guido van Rossum <guido@python.org>
parents: 41452
diff changeset
867
66408
2c370065c1b4 Issue #9846: ZipExtFile provides no mechanism for closing the underlying file object
Łukasz Langa <lukasz@langa.pl>
parents: 65830
diff changeset
868 def close(self):
2c370065c1b4 Issue #9846: ZipExtFile provides no mechanism for closing the underlying file object
Łukasz Langa <lukasz@langa.pl>
parents: 65830
diff changeset
869 try:
2c370065c1b4 Issue #9846: ZipExtFile provides no mechanism for closing the underlying file object
Łukasz Langa <lukasz@langa.pl>
parents: 65830
diff changeset
870 if self._close_fileobj:
2c370065c1b4 Issue #9846: ZipExtFile provides no mechanism for closing the underlying file object
Łukasz Langa <lukasz@langa.pl>
parents: 65830
diff changeset
871 self._fileobj.close()
2c370065c1b4 Issue #9846: ZipExtFile provides no mechanism for closing the underlying file object
Łukasz Langa <lukasz@langa.pl>
parents: 65830
diff changeset
872 finally:
2c370065c1b4 Issue #9846: ZipExtFile provides no mechanism for closing the underlying file object
Łukasz Langa <lukasz@langa.pl>
parents: 65830
diff changeset
873 super().close()
41554
06145fbc7ab9 Merged revisions 53952-54987 via svnmerge from
Guido van Rossum <guido@python.org>
parents: 41452
diff changeset
874
06145fbc7ab9 Merged revisions 53952-54987 via svnmerge from
Guido van Rossum <guido@python.org>
parents: 41452
diff changeset
875
12197
7f18f979a93a Zip file handling module, by Jim Ahlstrom.
Guido van Rossum <guido@python.org>
parents:
diff changeset
876 class ZipFile:
17245
0377f927cafa Whitespace normalization.
Tim Peters <tim.peters@gmail.com>
parents: 17224
diff changeset
877 """ Class with methods to open, read, write, close, list zip files.
0377f927cafa Whitespace normalization.
Tim Peters <tim.peters@gmail.com>
parents: 17224
diff changeset
878
87417
271cc3660445 Issue #17201: ZIP64 extensions now are enabled by default.
Serhiy Storchaka <storchaka@gmail.com>
parents: 86555
diff changeset
879 z = ZipFile(file, mode="r", compression=ZIP_STORED, allowZip64=True)
17245
0377f927cafa Whitespace normalization.
Tim Peters <tim.peters@gmail.com>
parents: 17224
diff changeset
880
17224
f9395f7627c4 Itamar Shtull-Trauring <itamar@maxnm.com>:
Fred Drake <fdrake@acm.org>
parents: 16889
diff changeset
881 file: Either the path to the file, or a file-like object.
f9395f7627c4 Itamar Shtull-Trauring <itamar@maxnm.com>:
Fred Drake <fdrake@acm.org>
parents: 16889
diff changeset
882 If it is a path, the file will be opened and closed by ZipFile.
f9395f7627c4 Itamar Shtull-Trauring <itamar@maxnm.com>:
Fred Drake <fdrake@acm.org>
parents: 16889
diff changeset
883 mode: The mode can be either read "r", write "w" or append "a".
76895
fccdcd83708a Issue #14366: Support lzma compression in zip files.
Martin v. Löwis <martin@v.loewis.de>
parents: 76694
diff changeset
884 compression: ZIP_STORED (no compression), ZIP_DEFLATED (requires zlib),
fccdcd83708a Issue #14366: Support lzma compression in zip files.
Martin v. Löwis <martin@v.loewis.de>
parents: 76694
diff changeset
885 ZIP_BZIP2 (requires bz2) or ZIP_LZMA (requires lzma).
39442
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36609
diff changeset
886 allowZip64: if True ZipFile will create files with ZIP64 extensions when
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36609
diff changeset
887 needed, otherwise it will raise an exception when this would
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36609
diff changeset
888 be necessary.
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36609
diff changeset
889
17224
f9395f7627c4 Itamar Shtull-Trauring <itamar@maxnm.com>:
Fred Drake <fdrake@acm.org>
parents: 16889
diff changeset
890 """
14975
27eab8032766 Delay import of py_compile until needed, since is is only used by the
Fred Drake <fdrake@acm.org>
parents: 14933
diff changeset
891
16826
a95693491eca Fix SF tracker bug #403871: AttributeError in ZipFile.__del__() when
Fred Drake <fdrake@acm.org>
parents: 15874
diff changeset
892 fp = None # Set here since __del__ checks it
81961
3febccf2a756 Refactor recently added bugfix into more testable code by using a
Gregory P. Smith <greg@krypto.org>
parents: 81939
diff changeset
893 _windows_illegal_name_trans_table = None
16826
a95693491eca Fix SF tracker bug #403871: AttributeError in ZipFile.__del__() when
Fred Drake <fdrake@acm.org>
parents: 15874
diff changeset
894
87417
271cc3660445 Issue #17201: ZIP64 extensions now are enabled by default.
Serhiy Storchaka <storchaka@gmail.com>
parents: 86555
diff changeset
895 def __init__(self, file, mode="r", compression=ZIP_STORED, allowZip64=True):
14975
27eab8032766 Delay import of py_compile until needed, since is is only used by the
Fred Drake <fdrake@acm.org>
parents: 14933
diff changeset
896 """Open the ZIP file with mode read "r", write "w" or append "a"."""
42309
bd6acfdb47d2 Merged revisions 56301-56442 via svnmerge from
Guido van Rossum <guido@python.org>
parents: 42142
diff changeset
897 if mode not in ("r", "w", "a"):
bd6acfdb47d2 Merged revisions 56301-56442 via svnmerge from
Guido van Rossum <guido@python.org>
parents: 42142
diff changeset
898 raise RuntimeError('ZipFile() requires mode "r", "w", or "a"')
bd6acfdb47d2 Merged revisions 56301-56442 via svnmerge from
Guido van Rossum <guido@python.org>
parents: 42142
diff changeset
899
76682
028e8e0b03e8 Issue #14371: Support bzip2 in zipfile module.
Martin v. Löwis <martin@v.loewis.de>
parents: 76373
diff changeset
900 _check_compression(compression)
42309
bd6acfdb47d2 Merged revisions 56301-56442 via svnmerge from
Guido van Rossum <guido@python.org>
parents: 42142
diff changeset
901
bd6acfdb47d2 Merged revisions 56301-56442 via svnmerge from
Guido van Rossum <guido@python.org>
parents: 42142
diff changeset
902 self._allowZip64 = allowZip64
bd6acfdb47d2 Merged revisions 56301-56442 via svnmerge from
Guido van Rossum <guido@python.org>
parents: 42142
diff changeset
903 self._didModify = False
15874
4c01ee0a8073 Whitespace normalization. Top level of Lib now fixed-point for reindent.py!
Tim Peters <tim.peters@gmail.com>
parents: 14975
diff changeset
904 self.debug = 0 # Level of printing: 0 through 3
4c01ee0a8073 Whitespace normalization. Top level of Lib now fixed-point for reindent.py!
Tim Peters <tim.peters@gmail.com>
parents: 14975
diff changeset
905 self.NameToInfo = {} # Find file info given name
4c01ee0a8073 Whitespace normalization. Top level of Lib now fixed-point for reindent.py!
Tim Peters <tim.peters@gmail.com>
parents: 14975
diff changeset
906 self.filelist = [] # List of ZipInfo instances for archive
4c01ee0a8073 Whitespace normalization. Top level of Lib now fixed-point for reindent.py!
Tim Peters <tim.peters@gmail.com>
parents: 14975
diff changeset
907 self.compression = compression # Method of compression
34594
32b89606f0cd Remove dependency on order of mode flags
Raymond Hettinger <python@rcn.com>
parents: 33914
diff changeset
908 self.mode = key = mode.replace('b', '')[0]
40893
32c4897b5d46 Merged revisions 53623-53858 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 40775
diff changeset
909 self.pwd = None
76270
4186f20d9fa4 #14399: zipfile now correctly handles comments added to empty zipfiles.
R David Murray <rdmurray@bitdance.com>
parents: 72992
diff changeset
910 self._comment = b''
17245
0377f927cafa Whitespace normalization.
Tim Peters <tim.peters@gmail.com>
parents: 17224
diff changeset
911
17224
f9395f7627c4 Itamar Shtull-Trauring <itamar@maxnm.com>:
Fred Drake <fdrake@acm.org>
parents: 16889
diff changeset
912 # Check if we were passed a file-like object
43577
ace45b361e87 Patch# 1258 by Christian Heimes: kill basestring.
Guido van Rossum <guido@python.org>
parents: 43020
diff changeset
913 if isinstance(file, str):
41812
50dafa22b8a4 Make test_zipfile pass.
Guido van Rossum <guido@python.org>
parents: 41760
diff changeset
914 # No, it's a filename
17224
f9395f7627c4 Itamar Shtull-Trauring <itamar@maxnm.com>:
Fred Drake <fdrake@acm.org>
parents: 16889
diff changeset
915 self._filePassed = 0
f9395f7627c4 Itamar Shtull-Trauring <itamar@maxnm.com>:
Fred Drake <fdrake@acm.org>
parents: 16889
diff changeset
916 self.filename = file
f9395f7627c4 Itamar Shtull-Trauring <itamar@maxnm.com>:
Fred Drake <fdrake@acm.org>
parents: 16889
diff changeset
917 modeDict = {'r' : 'rb', 'w': 'wb', 'a' : 'r+b'}
40893
32c4897b5d46 Merged revisions 53623-53858 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 40775
diff changeset
918 try:
41812
50dafa22b8a4 Make test_zipfile pass.
Guido van Rossum <guido@python.org>
parents: 41760
diff changeset
919 self.fp = io.open(file, modeDict[mode])
81039
7d69d04522e3 Replace IOError with OSError (#16715)
Andrew Svetlov <andrew.svetlov@gmail.com>
parents: 80502
diff changeset
920 except OSError:
40893
32c4897b5d46 Merged revisions 53623-53858 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 40775
diff changeset
921 if mode == 'a':
32c4897b5d46 Merged revisions 53623-53858 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 40775
diff changeset
922 mode = key = 'w'
41812
50dafa22b8a4 Make test_zipfile pass.
Guido van Rossum <guido@python.org>
parents: 41760
diff changeset
923 self.fp = io.open(file, modeDict[mode])
40893
32c4897b5d46 Merged revisions 53623-53858 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 40775
diff changeset
924 else:
32c4897b5d46 Merged revisions 53623-53858 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 40775
diff changeset
925 raise
17224
f9395f7627c4 Itamar Shtull-Trauring <itamar@maxnm.com>:
Fred Drake <fdrake@acm.org>
parents: 16889
diff changeset
926 else:
f9395f7627c4 Itamar Shtull-Trauring <itamar@maxnm.com>:
Fred Drake <fdrake@acm.org>
parents: 16889
diff changeset
927 self._filePassed = 1
f9395f7627c4 Itamar Shtull-Trauring <itamar@maxnm.com>:
Fred Drake <fdrake@acm.org>
parents: 16889
diff changeset
928 self.fp = file
f9395f7627c4 Itamar Shtull-Trauring <itamar@maxnm.com>:
Fred Drake <fdrake@acm.org>
parents: 16889
diff changeset
929 self.filename = getattr(file, 'name', None)
17245
0377f927cafa Whitespace normalization.
Tim Peters <tim.peters@gmail.com>
parents: 17224
diff changeset
930
80482
d51d95c9ea81 Issue #16408: Fix file descriptors not being closed in error conditions in the zipfile module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76270
diff changeset
931 try:
d51d95c9ea81 Issue #16408: Fix file descriptors not being closed in error conditions in the zipfile module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76270
diff changeset
932 if key == 'r':
25756
63225811498d Patch #611760: read archives with comments.
Martin v. Löwis <martin@v.loewis.de>
parents: 24756
diff changeset
933 self._RealGetContents()
80482
d51d95c9ea81 Issue #16408: Fix file descriptors not being closed in error conditions in the zipfile module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76270
diff changeset
934 elif key == 'w':
66469
a372fc486281 Merged revisions 85450-85455,85460-85465 via svnmerge from
Georg Brandl <georg@python.org>
parents: 63936
diff changeset
935 # set the modified flag so central directory gets written
a372fc486281 Merged revisions 85450-85455,85460-85465 via svnmerge from
Georg Brandl <georg@python.org>
parents: 63936
diff changeset
936 # even if no files are added to the archive
a372fc486281 Merged revisions 85450-85455,85460-85465 via svnmerge from
Georg Brandl <georg@python.org>
parents: 63936
diff changeset
937 self._didModify = True
80482
d51d95c9ea81 Issue #16408: Fix file descriptors not being closed in error conditions in the zipfile module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76270
diff changeset
938 elif key == 'a':
d51d95c9ea81 Issue #16408: Fix file descriptors not being closed in error conditions in the zipfile module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76270
diff changeset
939 try:
d51d95c9ea81 Issue #16408: Fix file descriptors not being closed in error conditions in the zipfile module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76270
diff changeset
940 # See if file is a zip file
d51d95c9ea81 Issue #16408: Fix file descriptors not being closed in error conditions in the zipfile module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76270
diff changeset
941 self._RealGetContents()
d51d95c9ea81 Issue #16408: Fix file descriptors not being closed in error conditions in the zipfile module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76270
diff changeset
942 # seek to start of directory and overwrite
d51d95c9ea81 Issue #16408: Fix file descriptors not being closed in error conditions in the zipfile module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76270
diff changeset
943 self.fp.seek(self.start_dir, 0)
d51d95c9ea81 Issue #16408: Fix file descriptors not being closed in error conditions in the zipfile module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76270
diff changeset
944 except BadZipFile:
d51d95c9ea81 Issue #16408: Fix file descriptors not being closed in error conditions in the zipfile module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76270
diff changeset
945 # file is not a zip file, just append
d51d95c9ea81 Issue #16408: Fix file descriptors not being closed in error conditions in the zipfile module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76270
diff changeset
946 self.fp.seek(0, 2)
d51d95c9ea81 Issue #16408: Fix file descriptors not being closed in error conditions in the zipfile module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76270
diff changeset
947
d51d95c9ea81 Issue #16408: Fix file descriptors not being closed in error conditions in the zipfile module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76270
diff changeset
948 # set the modified flag so central directory gets written
d51d95c9ea81 Issue #16408: Fix file descriptors not being closed in error conditions in the zipfile module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76270
diff changeset
949 # even if no files are added to the archive
d51d95c9ea81 Issue #16408: Fix file descriptors not being closed in error conditions in the zipfile module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76270
diff changeset
950 self._didModify = True
d51d95c9ea81 Issue #16408: Fix file descriptors not being closed in error conditions in the zipfile module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76270
diff changeset
951 else:
d51d95c9ea81 Issue #16408: Fix file descriptors not being closed in error conditions in the zipfile module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76270
diff changeset
952 raise RuntimeError('Mode must be "r", "w" or "a"')
d51d95c9ea81 Issue #16408: Fix file descriptors not being closed in error conditions in the zipfile module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76270
diff changeset
953 except:
d51d95c9ea81 Issue #16408: Fix file descriptors not being closed in error conditions in the zipfile module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76270
diff changeset
954 fp = self.fp
d51d95c9ea81 Issue #16408: Fix file descriptors not being closed in error conditions in the zipfile module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76270
diff changeset
955 self.fp = None
17312
7635f8838c68 Sf bug [ #412214 ] ZipFile constructor leaves files open.
Tim Peters <tim.peters@gmail.com>
parents: 17245
diff changeset
956 if not self._filePassed:
80482
d51d95c9ea81 Issue #16408: Fix file descriptors not being closed in error conditions in the zipfile module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76270
diff changeset
957 fp.close()
d51d95c9ea81 Issue #16408: Fix file descriptors not being closed in error conditions in the zipfile module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76270
diff changeset
958 raise
12197
7f18f979a93a Zip file handling module, by Jim Ahlstrom.
Guido van Rossum <guido@python.org>
parents:
diff changeset
959
58004
6248b7fdec0d Merged revisions 77136 via svnmerge from
Ezio Melotti <ezio.melotti@gmail.com>
parents: 56222
diff changeset
960 def __enter__(self):
6248b7fdec0d Merged revisions 77136 via svnmerge from
Ezio Melotti <ezio.melotti@gmail.com>
parents: 56222
diff changeset
961 return self
6248b7fdec0d Merged revisions 77136 via svnmerge from
Ezio Melotti <ezio.melotti@gmail.com>
parents: 56222
diff changeset
962
6248b7fdec0d Merged revisions 77136 via svnmerge from
Ezio Melotti <ezio.melotti@gmail.com>
parents: 56222
diff changeset
963 def __exit__(self, type, value, traceback):
6248b7fdec0d Merged revisions 77136 via svnmerge from
Ezio Melotti <ezio.melotti@gmail.com>
parents: 56222
diff changeset
964 self.close()
6248b7fdec0d Merged revisions 77136 via svnmerge from
Ezio Melotti <ezio.melotti@gmail.com>
parents: 56222
diff changeset
965
17312
7635f8838c68 Sf bug [ #412214 ] ZipFile constructor leaves files open.
Tim Peters <tim.peters@gmail.com>
parents: 17245
diff changeset
966 def _RealGetContents(self):
14975
27eab8032766 Delay import of py_compile until needed, since is is only used by the
Fred Drake <fdrake@acm.org>
parents: 14933
diff changeset
967 """Read in the table of contents for the ZIP file."""
12197
7f18f979a93a Zip file handling module, by Jim Ahlstrom.
Guido van Rossum <guido@python.org>
parents:
diff changeset
968 fp = self.fp
66469
a372fc486281 Merged revisions 85450-85455,85460-85465 via svnmerge from
Georg Brandl <georg@python.org>
parents: 63936
diff changeset
969 try:
a372fc486281 Merged revisions 85450-85455,85460-85465 via svnmerge from
Georg Brandl <georg@python.org>
parents: 63936
diff changeset
970 endrec = _EndRecData(fp)
81039
7d69d04522e3 Replace IOError with OSError (#16715)
Andrew Svetlov <andrew.svetlov@gmail.com>
parents: 80502
diff changeset
971 except OSError:
65673
a281989a218b #7351: add more consistent exception name alias.
Georg Brandl <georg@python.org>
parents: 65290
diff changeset
972 raise BadZipFile("File is not a zip file")
25756
63225811498d Patch #611760: read archives with comments.
Martin v. Löwis <martin@v.loewis.de>
parents: 24756
diff changeset
973 if not endrec:
65673
a281989a218b #7351: add more consistent exception name alias.
Georg Brandl <georg@python.org>
parents: 65290
diff changeset
974 raise BadZipFile("File is not a zip file")
12197
7f18f979a93a Zip file handling module, by Jim Ahlstrom.
Guido van Rossum <guido@python.org>
parents:
diff changeset
975 if self.debug > 1:
40775
4cdf21a0dbbc Fix most trivially-findable print statements.
Guido van Rossum <guido@python.org>
parents: 40644
diff changeset
976 print(endrec)
48423
cdaac79a7237 Merged revisions 64688 via svnmerge from
Martin v. Löwis <martin@v.loewis.de>
parents: 47278
diff changeset
977 size_cd = endrec[_ECD_SIZE] # bytes in central directory
cdaac79a7237 Merged revisions 64688 via svnmerge from
Martin v. Löwis <martin@v.loewis.de>
parents: 47278
diff changeset
978 offset_cd = endrec[_ECD_OFFSET] # offset of central directory
76270
4186f20d9fa4 #14399: zipfile now correctly handles comments added to empty zipfiles.
R David Murray <rdmurray@bitdance.com>
parents: 72992
diff changeset
979 self._comment = endrec[_ECD_COMMENT] # archive comment
48423
cdaac79a7237 Merged revisions 64688 via svnmerge from
Martin v. Löwis <martin@v.loewis.de>
parents: 47278
diff changeset
980
12197
7f18f979a93a Zip file handling module, by Jim Ahlstrom.
Guido van Rossum <guido@python.org>
parents:
diff changeset
981 # "concat" is zero, unless zip was concatenated to another file
48423
cdaac79a7237 Merged revisions 64688 via svnmerge from
Martin v. Löwis <martin@v.loewis.de>
parents: 47278
diff changeset
982 concat = endrec[_ECD_LOCATION] - size_cd - offset_cd
49037
26bdd94a4293 Merged revisions 66240 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 48728
diff changeset
983 if endrec[_ECD_SIGNATURE] == stringEndArchive64:
26bdd94a4293 Merged revisions 66240 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 48728
diff changeset
984 # If Zip64 extension structures are present, account for them
48423
cdaac79a7237 Merged revisions 64688 via svnmerge from
Martin v. Löwis <martin@v.loewis.de>
parents: 47278
diff changeset
985 concat -= (sizeEndCentDir64 + sizeEndCentDir64Locator)
cdaac79a7237 Merged revisions 64688 via svnmerge from
Martin v. Löwis <martin@v.loewis.de>
parents: 47278
diff changeset
986
12197
7f18f979a93a Zip file handling module, by Jim Ahlstrom.
Guido van Rossum <guido@python.org>
parents:
diff changeset
987 if self.debug > 2:
48423
cdaac79a7237 Merged revisions 64688 via svnmerge from
Martin v. Löwis <martin@v.loewis.de>
parents: 47278
diff changeset
988 inferred = concat + offset_cd
cdaac79a7237 Merged revisions 64688 via svnmerge from
Martin v. Löwis <martin@v.loewis.de>
parents: 47278
diff changeset
989 print("given, inferred, offset", offset_cd, inferred, concat)
12197
7f18f979a93a Zip file handling module, by Jim Ahlstrom.
Guido van Rossum <guido@python.org>
parents:
diff changeset
990 # self.start_dir: Position of start of central directory
7f18f979a93a Zip file handling module, by Jim Ahlstrom.
Guido van Rossum <guido@python.org>
parents:
diff changeset
991 self.start_dir = offset_cd + concat
7f18f979a93a Zip file handling module, by Jim Ahlstrom.
Guido van Rossum <guido@python.org>
parents:
diff changeset
992 fp.seek(self.start_dir, 0)
39442
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36609
diff changeset
993 data = fp.read(size_cd)
41812
50dafa22b8a4 Make test_zipfile pass.
Guido van Rossum <guido@python.org>
parents: 41760
diff changeset
994 fp = io.BytesIO(data)
12197
7f18f979a93a Zip file handling module, by Jim Ahlstrom.
Guido van Rossum <guido@python.org>
parents:
diff changeset
995 total = 0
7f18f979a93a Zip file handling module, by Jim Ahlstrom.
Guido van Rossum <guido@python.org>
parents:
diff changeset
996 while total < size_cd:
48423
cdaac79a7237 Merged revisions 64688 via svnmerge from
Martin v. Löwis <martin@v.loewis.de>
parents: 47278
diff changeset
997 centdir = fp.read(sizeCentralDir)
81848
01147e468c8c Issue #4844: ZipFile now raises BadZipFile when opens a ZIP file with an
Serhiy Storchaka <storchaka@gmail.com>
parents: 81828
diff changeset
998 if len(centdir) != sizeCentralDir:
01147e468c8c Issue #4844: ZipFile now raises BadZipFile when opens a ZIP file with an
Serhiy Storchaka <storchaka@gmail.com>
parents: 81828
diff changeset
999 raise BadZipFile("Truncated central directory")
01147e468c8c Issue #4844: ZipFile now raises BadZipFile when opens a ZIP file with an
Serhiy Storchaka <storchaka@gmail.com>
parents: 81828
diff changeset
1000 centdir = struct.unpack(structCentralDir, centdir)
01147e468c8c Issue #4844: ZipFile now raises BadZipFile when opens a ZIP file with an
Serhiy Storchaka <storchaka@gmail.com>
parents: 81828
diff changeset
1001 if centdir[_CD_SIGNATURE] != stringCentralDir:
65673
a281989a218b #7351: add more consistent exception name alias.
Georg Brandl <georg@python.org>
parents: 65290
diff changeset
1002 raise BadZipFile("Bad magic number for central directory")
12197
7f18f979a93a Zip file handling module, by Jim Ahlstrom.
Guido van Rossum <guido@python.org>
parents:
diff changeset
1003 if self.debug > 2:
40775
4cdf21a0dbbc Fix most trivially-findable print statements.
Guido van Rossum <guido@python.org>
parents: 40644
diff changeset
1004 print(centdir)
16840
950fc2261da4 Define lots of constants for indexes into the structures for the file
Fred Drake <fdrake@acm.org>
parents: 16826
diff changeset
1005 filename = fp.read(centdir[_CD_FILENAME_LENGTH])
46672
15f1d232eae9 Merged revisions 62724 via svnmerge from
Martin v. Löwis <martin@v.loewis.de>
parents: 45941
diff changeset
1006 flags = centdir[5]
15f1d232eae9 Merged revisions 62724 via svnmerge from
Martin v. Löwis <martin@v.loewis.de>
parents: 45941
diff changeset
1007 if flags & 0x800:
15f1d232eae9 Merged revisions 62724 via svnmerge from
Martin v. Löwis <martin@v.loewis.de>
parents: 45941
diff changeset
1008 # UTF-8 file names extension
15f1d232eae9 Merged revisions 62724 via svnmerge from
Martin v. Löwis <martin@v.loewis.de>
parents: 45941
diff changeset
1009 filename = filename.decode('utf-8')
15f1d232eae9 Merged revisions 62724 via svnmerge from
Martin v. Löwis <martin@v.loewis.de>
parents: 45941
diff changeset
1010 else:
15f1d232eae9 Merged revisions 62724 via svnmerge from
Martin v. Löwis <martin@v.loewis.de>
parents: 45941
diff changeset
1011 # Historical ZIP filename encoding
15f1d232eae9 Merged revisions 62724 via svnmerge from
Martin v. Löwis <martin@v.loewis.de>
parents: 45941
diff changeset
1012 filename = filename.decode('cp437')
12197
7f18f979a93a Zip file handling module, by Jim Ahlstrom.
Guido van Rossum <guido@python.org>
parents:
diff changeset
1013 # Create ZipInfo instance to store file information
46672
15f1d232eae9 Merged revisions 62724 via svnmerge from
Martin v. Löwis <martin@v.loewis.de>
parents: 45941
diff changeset
1014 x = ZipInfo(filename)
16840
950fc2261da4 Define lots of constants for indexes into the structures for the file
Fred Drake <fdrake@acm.org>
parents: 16826
diff changeset
1015 x.extra = fp.read(centdir[_CD_EXTRA_FIELD_LENGTH])
950fc2261da4 Define lots of constants for indexes into the structures for the file
Fred Drake <fdrake@acm.org>
parents: 16826
diff changeset
1016 x.comment = fp.read(centdir[_CD_COMMENT_LENGTH])
39442
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36609
diff changeset
1017 x.header_offset = centdir[_CD_LOCAL_HEADER_OFFSET]
12197
7f18f979a93a Zip file handling module, by Jim Ahlstrom.
Guido van Rossum <guido@python.org>
parents:
diff changeset
1018 (x.create_version, x.create_system, x.extract_version, x.reserved,
86536
34fb83421119 add a filterfunc to zip file.PyZipFile.writepy, issue 19274
Christian Tismer <tismer@stackless.com>
parents: 85814
diff changeset
1019 x.flag_bits, x.compress_type, t, d,
34fb83421119 add a filterfunc to zip file.PyZipFile.writepy, issue 19274
Christian Tismer <tismer@stackless.com>
parents: 85814
diff changeset
1020 x.CRC, x.compress_size, x.file_size) = centdir[1:12]
76694
66741dd4fabf Check extract_version when opening a zipfile.
Martin v. Löwis <martin@v.loewis.de>
parents: 76685
diff changeset
1021 if x.extract_version > MAX_EXTRACT_VERSION:
66741dd4fabf Check extract_version when opening a zipfile.
Martin v. Löwis <martin@v.loewis.de>
parents: 76685
diff changeset
1022 raise NotImplementedError("zip file version %.1f" %
66741dd4fabf Check extract_version when opening a zipfile.
Martin v. Löwis <martin@v.loewis.de>
parents: 76685
diff changeset
1023 (x.extract_version / 10))
12197
7f18f979a93a Zip file handling module, by Jim Ahlstrom.
Guido van Rossum <guido@python.org>
parents:
diff changeset
1024 x.volume, x.internal_attr, x.external_attr = centdir[15:18]
7f18f979a93a Zip file handling module, by Jim Ahlstrom.
Guido van Rossum <guido@python.org>
parents:
diff changeset
1025 # Convert date/time code to (year, month, day, hour, min, sec)
44810
fa6cee14dcba Merged revisions 60094-60123 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 44699
diff changeset
1026 x._raw_time = t
12197
7f18f979a93a Zip file handling module, by Jim Ahlstrom.
Guido van Rossum <guido@python.org>
parents:
diff changeset
1027 x.date_time = ( (d>>9)+1980, (d>>5)&0xF, d&0x1F,
86536
34fb83421119 add a filterfunc to zip file.PyZipFile.writepy, issue 19274
Christian Tismer <tismer@stackless.com>
parents: 85814
diff changeset
1028 t>>11, (t>>5)&0x3F, (t&0x1F) * 2 )
39442
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36609
diff changeset
1029
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36609
diff changeset
1030 x._decodeExtra()
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36609
diff changeset
1031 x.header_offset = x.header_offset + concat
12197
7f18f979a93a Zip file handling module, by Jim Ahlstrom.
Guido van Rossum <guido@python.org>
parents:
diff changeset
1032 self.filelist.append(x)
7f18f979a93a Zip file handling module, by Jim Ahlstrom.
Guido van Rossum <guido@python.org>
parents:
diff changeset
1033 self.NameToInfo[x.filename] = x
48423
cdaac79a7237 Merged revisions 64688 via svnmerge from
Martin v. Löwis <martin@v.loewis.de>
parents: 47278
diff changeset
1034
cdaac79a7237 Merged revisions 64688 via svnmerge from
Martin v. Löwis <martin@v.loewis.de>
parents: 47278
diff changeset
1035 # update total bytes read from central directory
cdaac79a7237 Merged revisions 64688 via svnmerge from
Martin v. Löwis <martin@v.loewis.de>
parents: 47278
diff changeset
1036 total = (total + sizeCentralDir + centdir[_CD_FILENAME_LENGTH]
cdaac79a7237 Merged revisions 64688 via svnmerge from
Martin v. Löwis <martin@v.loewis.de>
parents: 47278
diff changeset
1037 + centdir[_CD_EXTRA_FIELD_LENGTH]
cdaac79a7237 Merged revisions 64688 via svnmerge from
Martin v. Löwis <martin@v.loewis.de>
parents: 47278
diff changeset
1038 + centdir[_CD_COMMENT_LENGTH])
cdaac79a7237 Merged revisions 64688 via svnmerge from
Martin v. Löwis <martin@v.loewis.de>
parents: 47278
diff changeset
1039
12197
7f18f979a93a Zip file handling module, by Jim Ahlstrom.
Guido van Rossum <guido@python.org>
parents:
diff changeset
1040 if self.debug > 2:
40775
4cdf21a0dbbc Fix most trivially-findable print statements.
Guido van Rossum <guido@python.org>
parents: 40644
diff changeset
1041 print("total", total)
39442
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36609
diff changeset
1042
12197
7f18f979a93a Zip file handling module, by Jim Ahlstrom.
Guido van Rossum <guido@python.org>
parents:
diff changeset
1043
7f18f979a93a Zip file handling module, by Jim Ahlstrom.
Guido van Rossum <guido@python.org>
parents:
diff changeset
1044 def namelist(self):
14975
27eab8032766 Delay import of py_compile until needed, since is is only used by the
Fred Drake <fdrake@acm.org>
parents: 14933
diff changeset
1045 """Return a list of file names in the archive."""
76373
cac63f6ad252 #14603: use a listcomp in ZipFile.namelist.
Ezio Melotti <ezio.melotti@gmail.com>
parents: 76270
diff changeset
1046 return [data.filename for data in self.filelist]
12197
7f18f979a93a Zip file handling module, by Jim Ahlstrom.
Guido van Rossum <guido@python.org>
parents:
diff changeset
1047
7f18f979a93a Zip file handling module, by Jim Ahlstrom.
Guido van Rossum <guido@python.org>
parents:
diff changeset
1048 def infolist(self):
14975
27eab8032766 Delay import of py_compile until needed, since is is only used by the
Fred Drake <fdrake@acm.org>
parents: 14933
diff changeset
1049 """Return a list of class ZipInfo instances for files in the
27eab8032766 Delay import of py_compile until needed, since is is only used by the
Fred Drake <fdrake@acm.org>
parents: 14933
diff changeset
1050 archive."""
12197
7f18f979a93a Zip file handling module, by Jim Ahlstrom.
Guido van Rossum <guido@python.org>
parents:
diff changeset
1051 return self.filelist
7f18f979a93a Zip file handling module, by Jim Ahlstrom.
Guido van Rossum <guido@python.org>
parents:
diff changeset
1052
41812
50dafa22b8a4 Make test_zipfile pass.
Guido van Rossum <guido@python.org>
parents: 41760
diff changeset
1053 def printdir(self, file=None):
14975
27eab8032766 Delay import of py_compile until needed, since is is only used by the
Fred Drake <fdrake@acm.org>
parents: 14933
diff changeset
1054 """Print a table of contents for the zip file."""
41812
50dafa22b8a4 Make test_zipfile pass.
Guido van Rossum <guido@python.org>
parents: 41760
diff changeset
1055 print("%-46s %19s %12s" % ("File Name", "Modified ", "Size"),
50dafa22b8a4 Make test_zipfile pass.
Guido van Rossum <guido@python.org>
parents: 41760
diff changeset
1056 file=file)
12197
7f18f979a93a Zip file handling module, by Jim Ahlstrom.
Guido van Rossum <guido@python.org>
parents:
diff changeset
1057 for zinfo in self.filelist:
44699
6f049ca55e06 Merged revisions 59952-59984 via svnmerge from
Guido van Rossum <guido@python.org>
parents: 44587
diff changeset
1058 date = "%d-%02d-%02d %02d:%02d:%02d" % zinfo.date_time[:6]
41812
50dafa22b8a4 Make test_zipfile pass.
Guido van Rossum <guido@python.org>
parents: 41760
diff changeset
1059 print("%-46s %s %12d" % (zinfo.filename, date, zinfo.file_size),
50dafa22b8a4 Make test_zipfile pass.
Guido van Rossum <guido@python.org>
parents: 41760
diff changeset
1060 file=file)
12197
7f18f979a93a Zip file handling module, by Jim Ahlstrom.
Guido van Rossum <guido@python.org>
parents:
diff changeset
1061
7f18f979a93a Zip file handling module, by Jim Ahlstrom.
Guido van Rossum <guido@python.org>
parents:
diff changeset
1062 def testzip(self):
14975
27eab8032766 Delay import of py_compile until needed, since is is only used by the
Fred Drake <fdrake@acm.org>
parents: 14933
diff changeset
1063 """Read all the files and check the CRC."""
48728
06891aec41de Merged revisions 65659,65693,65700,65702,65706-65707,65761 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 48572
diff changeset
1064 chunk_size = 2 ** 20
12197
7f18f979a93a Zip file handling module, by Jim Ahlstrom.
Guido van Rossum <guido@python.org>
parents:
diff changeset
1065 for zinfo in self.filelist:
7f18f979a93a Zip file handling module, by Jim Ahlstrom.
Guido van Rossum <guido@python.org>
parents:
diff changeset
1066 try:
48728
06891aec41de Merged revisions 65659,65693,65700,65702,65706-65707,65761 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 48572
diff changeset
1067 # Read by chunks, to avoid an OverflowError or a
06891aec41de Merged revisions 65659,65693,65700,65702,65706-65707,65761 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 48572
diff changeset
1068 # MemoryError with very large embedded files.
80482
d51d95c9ea81 Issue #16408: Fix file descriptors not being closed in error conditions in the zipfile module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76270
diff changeset
1069 with self.open(zinfo.filename, "r") as f:
d51d95c9ea81 Issue #16408: Fix file descriptors not being closed in error conditions in the zipfile module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76270
diff changeset
1070 while f.read(chunk_size): # Check CRC-32
d51d95c9ea81 Issue #16408: Fix file descriptors not being closed in error conditions in the zipfile module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76270
diff changeset
1071 pass
65673
a281989a218b #7351: add more consistent exception name alias.
Georg Brandl <georg@python.org>
parents: 65290
diff changeset
1072 except BadZipFile:
12197
7f18f979a93a Zip file handling module, by Jim Ahlstrom.
Guido van Rossum <guido@python.org>
parents:
diff changeset
1073 return zinfo.filename
7f18f979a93a Zip file handling module, by Jim Ahlstrom.
Guido van Rossum <guido@python.org>
parents:
diff changeset
1074
7f18f979a93a Zip file handling module, by Jim Ahlstrom.
Guido van Rossum <guido@python.org>
parents:
diff changeset
1075 def getinfo(self, name):
14975
27eab8032766 Delay import of py_compile until needed, since is is only used by the
Fred Drake <fdrake@acm.org>
parents: 14933
diff changeset
1076 """Return the instance of ZipInfo given 'name'."""
42309
bd6acfdb47d2 Merged revisions 56301-56442 via svnmerge from
Guido van Rossum <guido@python.org>
parents: 42142
diff changeset
1077 info = self.NameToInfo.get(name)
bd6acfdb47d2 Merged revisions 56301-56442 via svnmerge from
Guido van Rossum <guido@python.org>
parents: 42142
diff changeset
1078 if info is None:
bd6acfdb47d2 Merged revisions 56301-56442 via svnmerge from
Guido van Rossum <guido@python.org>
parents: 42142
diff changeset
1079 raise KeyError(
bd6acfdb47d2 Merged revisions 56301-56442 via svnmerge from
Guido van Rossum <guido@python.org>
parents: 42142
diff changeset
1080 'There is no item named %r in the archive' % name)
bd6acfdb47d2 Merged revisions 56301-56442 via svnmerge from
Guido van Rossum <guido@python.org>
parents: 42142
diff changeset
1081
bd6acfdb47d2 Merged revisions 56301-56442 via svnmerge from
Guido van Rossum <guido@python.org>
parents: 42142
diff changeset
1082 return info
12197
7f18f979a93a Zip file handling module, by Jim Ahlstrom.
Guido van Rossum <guido@python.org>
parents:
diff changeset
1083
40893
32c4897b5d46 Merged revisions 53623-53858 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 40775
diff changeset
1084 def setpassword(self, pwd):
32c4897b5d46 Merged revisions 53623-53858 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 40775
diff changeset
1085 """Set default password for encrypted files."""
67077
561ea640188b Merged revisions 87430 via svnmerge from
R. David Murray <rdmurray@bitdance.com>
parents: 66469
diff changeset
1086 if pwd and not isinstance(pwd, bytes):
561ea640188b Merged revisions 87430 via svnmerge from
R. David Murray <rdmurray@bitdance.com>
parents: 66469
diff changeset
1087 raise TypeError("pwd: expected bytes, got %s" % type(pwd))
561ea640188b Merged revisions 87430 via svnmerge from
R. David Murray <rdmurray@bitdance.com>
parents: 66469
diff changeset
1088 if pwd:
561ea640188b Merged revisions 87430 via svnmerge from
R. David Murray <rdmurray@bitdance.com>
parents: 66469
diff changeset
1089 self.pwd = pwd
561ea640188b Merged revisions 87430 via svnmerge from
R. David Murray <rdmurray@bitdance.com>
parents: 66469
diff changeset
1090 else:
561ea640188b Merged revisions 87430 via svnmerge from
R. David Murray <rdmurray@bitdance.com>
parents: 66469
diff changeset
1091 self.pwd = None
40893
32c4897b5d46 Merged revisions 53623-53858 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 40775
diff changeset
1092
76270
4186f20d9fa4 #14399: zipfile now correctly handles comments added to empty zipfiles.
R David Murray <rdmurray@bitdance.com>
parents: 72992
diff changeset
1093 @property
4186f20d9fa4 #14399: zipfile now correctly handles comments added to empty zipfiles.
R David Murray <rdmurray@bitdance.com>
parents: 72992
diff changeset
1094 def comment(self):
4186f20d9fa4 #14399: zipfile now correctly handles comments added to empty zipfiles.
R David Murray <rdmurray@bitdance.com>
parents: 72992
diff changeset
1095 """The comment text associated with the ZIP file."""
4186f20d9fa4 #14399: zipfile now correctly handles comments added to empty zipfiles.
R David Murray <rdmurray@bitdance.com>
parents: 72992
diff changeset
1096 return self._comment
4186f20d9fa4 #14399: zipfile now correctly handles comments added to empty zipfiles.
R David Murray <rdmurray@bitdance.com>
parents: 72992
diff changeset
1097
4186f20d9fa4 #14399: zipfile now correctly handles comments added to empty zipfiles.
R David Murray <rdmurray@bitdance.com>
parents: 72992
diff changeset
1098 @comment.setter
4186f20d9fa4 #14399: zipfile now correctly handles comments added to empty zipfiles.
R David Murray <rdmurray@bitdance.com>
parents: 72992
diff changeset
1099 def comment(self, comment):
4186f20d9fa4 #14399: zipfile now correctly handles comments added to empty zipfiles.
R David Murray <rdmurray@bitdance.com>
parents: 72992
diff changeset
1100 if not isinstance(comment, bytes):
4186f20d9fa4 #14399: zipfile now correctly handles comments added to empty zipfiles.
R David Murray <rdmurray@bitdance.com>
parents: 72992
diff changeset
1101 raise TypeError("comment: expected bytes, got %s" % type(comment))
4186f20d9fa4 #14399: zipfile now correctly handles comments added to empty zipfiles.
R David Murray <rdmurray@bitdance.com>
parents: 72992
diff changeset
1102 # check for valid comment length
4186f20d9fa4 #14399: zipfile now correctly handles comments added to empty zipfiles.
R David Murray <rdmurray@bitdance.com>
parents: 72992
diff changeset
1103 if len(comment) >= ZIP_MAX_COMMENT:
4186f20d9fa4 #14399: zipfile now correctly handles comments added to empty zipfiles.
R David Murray <rdmurray@bitdance.com>
parents: 72992
diff changeset
1104 if self.debug:
4186f20d9fa4 #14399: zipfile now correctly handles comments added to empty zipfiles.
R David Murray <rdmurray@bitdance.com>
parents: 72992
diff changeset
1105 print('Archive comment is too long; truncating to %d bytes'
86536
34fb83421119 add a filterfunc to zip file.PyZipFile.writepy, issue 19274
Christian Tismer <tismer@stackless.com>
parents: 85814
diff changeset
1106 % ZIP_MAX_COMMENT)
76270
4186f20d9fa4 #14399: zipfile now correctly handles comments added to empty zipfiles.
R David Murray <rdmurray@bitdance.com>
parents: 72992
diff changeset
1107 comment = comment[:ZIP_MAX_COMMENT]
4186f20d9fa4 #14399: zipfile now correctly handles comments added to empty zipfiles.
R David Murray <rdmurray@bitdance.com>
parents: 72992
diff changeset
1108 self._comment = comment
4186f20d9fa4 #14399: zipfile now correctly handles comments added to empty zipfiles.
R David Murray <rdmurray@bitdance.com>
parents: 72992
diff changeset
1109 self._didModify = True
4186f20d9fa4 #14399: zipfile now correctly handles comments added to empty zipfiles.
R David Murray <rdmurray@bitdance.com>
parents: 72992
diff changeset
1110
40893
32c4897b5d46 Merged revisions 53623-53858 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 40775
diff changeset
1111 def read(self, name, pwd=None):
14975
27eab8032766 Delay import of py_compile until needed, since is is only used by the
Fred Drake <fdrake@acm.org>
parents: 14933
diff changeset
1112 """Return file bytes (as a string) for name."""
65830
719ebcb934f3 start banging on zipfile's file leakiness
Benjamin Peterson <benjamin@python.org>
parents: 65683
diff changeset
1113 with self.open(name, "r", pwd) as fp:
719ebcb934f3 start banging on zipfile's file leakiness
Benjamin Peterson <benjamin@python.org>
parents: 65683
diff changeset
1114 return fp.read()
41554
06145fbc7ab9 Merged revisions 53952-54987 via svnmerge from
Guido van Rossum <guido@python.org>
parents: 41452
diff changeset
1115
06145fbc7ab9 Merged revisions 53952-54987 via svnmerge from
Guido van Rossum <guido@python.org>
parents: 41452
diff changeset
1116 def open(self, name, mode="r", pwd=None):
06145fbc7ab9 Merged revisions 53952-54987 via svnmerge from
Guido van Rossum <guido@python.org>
parents: 41452
diff changeset
1117 """Return file-like object for 'name'."""
06145fbc7ab9 Merged revisions 53952-54987 via svnmerge from
Guido van Rossum <guido@python.org>
parents: 41452
diff changeset
1118 if mode not in ("r", "U", "rU"):
43020
907a45df1295 Raise statement normalization in Lib/.
Collin Winter <collinw@gmail.com>
parents: 43005
diff changeset
1119 raise RuntimeError('open() requires mode "r", "U", or "rU"')
87448
70bd6f7e013b Issue #15204: Deprecated the 'U' mode in file-like objects.
Serhiy Storchaka <storchaka@gmail.com>
parents: 87417
diff changeset
1120 if 'U' in mode:
70bd6f7e013b Issue #15204: Deprecated the 'U' mode in file-like objects.
Serhiy Storchaka <storchaka@gmail.com>
parents: 87417
diff changeset
1121 import warnings
70bd6f7e013b Issue #15204: Deprecated the 'U' mode in file-like objects.
Serhiy Storchaka <storchaka@gmail.com>
parents: 87417
diff changeset
1122 warnings.warn("'U' mode is deprecated",
70bd6f7e013b Issue #15204: Deprecated the 'U' mode in file-like objects.
Serhiy Storchaka <storchaka@gmail.com>
parents: 87417
diff changeset
1123 DeprecationWarning, 2)
67077
561ea640188b Merged revisions 87430 via svnmerge from
R. David Murray <rdmurray@bitdance.com>
parents: 66469
diff changeset
1124 if pwd and not isinstance(pwd, bytes):
561ea640188b Merged revisions 87430 via svnmerge from
R. David Murray <rdmurray@bitdance.com>
parents: 66469
diff changeset
1125 raise TypeError("pwd: expected bytes, got %s" % type(pwd))
12197
7f18f979a93a Zip file handling module, by Jim Ahlstrom.
Guido van Rossum <guido@python.org>
parents:
diff changeset
1126 if not self.fp:
43020
907a45df1295 Raise statement normalization in Lib/.
Collin Winter <collinw@gmail.com>
parents: 43005
diff changeset
1127 raise RuntimeError(
86536
34fb83421119 add a filterfunc to zip file.PyZipFile.writepy, issue 19274
Christian Tismer <tismer@stackless.com>
parents: 85814
diff changeset
1128 "Attempt to read ZIP archive that was already closed")
41554
06145fbc7ab9 Merged revisions 53952-54987 via svnmerge from
Guido van Rossum <guido@python.org>
parents: 41452
diff changeset
1129
06145fbc7ab9 Merged revisions 53952-54987 via svnmerge from
Guido van Rossum <guido@python.org>
parents: 41452
diff changeset
1130 # Only open a new file for instances where we were not
06145fbc7ab9 Merged revisions 53952-54987 via svnmerge from
Guido van Rossum <guido@python.org>
parents: 41452
diff changeset
1131 # given a file object in the constructor
06145fbc7ab9 Merged revisions 53952-54987 via svnmerge from
Guido van Rossum <guido@python.org>
parents: 41452
diff changeset
1132 if self._filePassed:
06145fbc7ab9 Merged revisions 53952-54987 via svnmerge from
Guido van Rossum <guido@python.org>
parents: 41452
diff changeset
1133 zef_file = self.fp
06145fbc7ab9 Merged revisions 53952-54987 via svnmerge from
Guido van Rossum <guido@python.org>
parents: 41452
diff changeset
1134 else:
41812
50dafa22b8a4 Make test_zipfile pass.
Guido van Rossum <guido@python.org>
parents: 41760
diff changeset
1135 zef_file = io.open(self.filename, 'rb')
41554
06145fbc7ab9 Merged revisions 53952-54987 via svnmerge from
Guido van Rossum <guido@python.org>
parents: 41452
diff changeset
1136
80482
d51d95c9ea81 Issue #16408: Fix file descriptors not being closed in error conditions in the zipfile module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76270
diff changeset
1137 try:
d51d95c9ea81 Issue #16408: Fix file descriptors not being closed in error conditions in the zipfile module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76270
diff changeset
1138 # Make sure we have an info object
d51d95c9ea81 Issue #16408: Fix file descriptors not being closed in error conditions in the zipfile module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76270
diff changeset
1139 if isinstance(name, ZipInfo):
d51d95c9ea81 Issue #16408: Fix file descriptors not being closed in error conditions in the zipfile module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76270
diff changeset
1140 # 'name' is already an info object
d51d95c9ea81 Issue #16408: Fix file descriptors not being closed in error conditions in the zipfile module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76270
diff changeset
1141 zinfo = name
d51d95c9ea81 Issue #16408: Fix file descriptors not being closed in error conditions in the zipfile module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76270
diff changeset
1142 else:
d51d95c9ea81 Issue #16408: Fix file descriptors not being closed in error conditions in the zipfile module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76270
diff changeset
1143 # Get info object for name
66409
260ff379115c zipfile: remove remaining ResourceWarnings
Łukasz Langa <lukasz@langa.pl>
parents: 66408
diff changeset
1144 zinfo = self.getinfo(name)
80482
d51d95c9ea81 Issue #16408: Fix file descriptors not being closed in error conditions in the zipfile module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76270
diff changeset
1145 zef_file.seek(zinfo.header_offset, 0)
d51d95c9ea81 Issue #16408: Fix file descriptors not being closed in error conditions in the zipfile module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76270
diff changeset
1146
d51d95c9ea81 Issue #16408: Fix file descriptors not being closed in error conditions in the zipfile module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76270
diff changeset
1147 # Skip the file header:
d51d95c9ea81 Issue #16408: Fix file descriptors not being closed in error conditions in the zipfile module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76270
diff changeset
1148 fheader = zef_file.read(sizeFileHeader)
81848
01147e468c8c Issue #4844: ZipFile now raises BadZipFile when opens a ZIP file with an
Serhiy Storchaka <storchaka@gmail.com>
parents: 81828
diff changeset
1149 if len(fheader) != sizeFileHeader:
01147e468c8c Issue #4844: ZipFile now raises BadZipFile when opens a ZIP file with an
Serhiy Storchaka <storchaka@gmail.com>
parents: 81828
diff changeset
1150 raise BadZipFile("Truncated file header")
01147e468c8c Issue #4844: ZipFile now raises BadZipFile when opens a ZIP file with an
Serhiy Storchaka <storchaka@gmail.com>
parents: 81828
diff changeset
1151 fheader = struct.unpack(structFileHeader, fheader)
01147e468c8c Issue #4844: ZipFile now raises BadZipFile when opens a ZIP file with an
Serhiy Storchaka <storchaka@gmail.com>
parents: 81828
diff changeset
1152 if fheader[_FH_SIGNATURE] != stringFileHeader:
80482
d51d95c9ea81 Issue #16408: Fix file descriptors not being closed in error conditions in the zipfile module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76270
diff changeset
1153 raise BadZipFile("Bad magic number for file header")
d51d95c9ea81 Issue #16408: Fix file descriptors not being closed in error conditions in the zipfile module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76270
diff changeset
1154
d51d95c9ea81 Issue #16408: Fix file descriptors not being closed in error conditions in the zipfile module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76270
diff changeset
1155 fname = zef_file.read(fheader[_FH_FILENAME_LENGTH])
d51d95c9ea81 Issue #16408: Fix file descriptors not being closed in error conditions in the zipfile module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76270
diff changeset
1156 if fheader[_FH_EXTRA_FIELD_LENGTH]:
d51d95c9ea81 Issue #16408: Fix file descriptors not being closed in error conditions in the zipfile module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76270
diff changeset
1157 zef_file.read(fheader[_FH_EXTRA_FIELD_LENGTH])
d51d95c9ea81 Issue #16408: Fix file descriptors not being closed in error conditions in the zipfile module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76270
diff changeset
1158
80483
27cb1a3d57c8 Issue #16408: Fix file descriptors not being closed in error conditions in the zipfile module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 77631 80482
diff changeset
1159 if zinfo.flag_bits & 0x20:
27cb1a3d57c8 Issue #16408: Fix file descriptors not being closed in error conditions in the zipfile module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 77631 80482
diff changeset
1160 # Zip 2.7: compressed patched data
27cb1a3d57c8 Issue #16408: Fix file descriptors not being closed in error conditions in the zipfile module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 77631 80482
diff changeset
1161 raise NotImplementedError("compressed patched data (flag bit 5)")
27cb1a3d57c8 Issue #16408: Fix file descriptors not being closed in error conditions in the zipfile module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 77631 80482
diff changeset
1162
27cb1a3d57c8 Issue #16408: Fix file descriptors not being closed in error conditions in the zipfile module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 77631 80482
diff changeset
1163 if zinfo.flag_bits & 0x40:
27cb1a3d57c8 Issue #16408: Fix file descriptors not being closed in error conditions in the zipfile module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 77631 80482
diff changeset
1164 # strong encryption
27cb1a3d57c8 Issue #16408: Fix file descriptors not being closed in error conditions in the zipfile module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 77631 80482
diff changeset
1165 raise NotImplementedError("strong encryption (flag bit 6)")
27cb1a3d57c8 Issue #16408: Fix file descriptors not being closed in error conditions in the zipfile module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 77631 80482
diff changeset
1166
80482
d51d95c9ea81 Issue #16408: Fix file descriptors not being closed in error conditions in the zipfile module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76270
diff changeset
1167 if zinfo.flag_bits & 0x800:
d51d95c9ea81 Issue #16408: Fix file descriptors not being closed in error conditions in the zipfile module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76270
diff changeset
1168 # UTF-8 filename
d51d95c9ea81 Issue #16408: Fix file descriptors not being closed in error conditions in the zipfile module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76270
diff changeset
1169 fname_str = fname.decode("utf-8")
d51d95c9ea81 Issue #16408: Fix file descriptors not being closed in error conditions in the zipfile module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76270
diff changeset
1170 else:
d51d95c9ea81 Issue #16408: Fix file descriptors not being closed in error conditions in the zipfile module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76270
diff changeset
1171 fname_str = fname.decode("cp437")
d51d95c9ea81 Issue #16408: Fix file descriptors not being closed in error conditions in the zipfile module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76270
diff changeset
1172
d51d95c9ea81 Issue #16408: Fix file descriptors not being closed in error conditions in the zipfile module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76270
diff changeset
1173 if fname_str != zinfo.orig_filename:
d51d95c9ea81 Issue #16408: Fix file descriptors not being closed in error conditions in the zipfile module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76270
diff changeset
1174 raise BadZipFile(
d51d95c9ea81 Issue #16408: Fix file descriptors not being closed in error conditions in the zipfile module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76270
diff changeset
1175 'File name in directory %r and header %r differ.'
d51d95c9ea81 Issue #16408: Fix file descriptors not being closed in error conditions in the zipfile module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76270
diff changeset
1176 % (zinfo.orig_filename, fname))
39442
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36609
diff changeset
1177
80482
d51d95c9ea81 Issue #16408: Fix file descriptors not being closed in error conditions in the zipfile module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76270
diff changeset
1178 # check for encrypted flag & handle password
d51d95c9ea81 Issue #16408: Fix file descriptors not being closed in error conditions in the zipfile module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76270
diff changeset
1179 is_encrypted = zinfo.flag_bits & 0x1
d51d95c9ea81 Issue #16408: Fix file descriptors not being closed in error conditions in the zipfile module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76270
diff changeset
1180 zd = None
d51d95c9ea81 Issue #16408: Fix file descriptors not being closed in error conditions in the zipfile module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76270
diff changeset
1181 if is_encrypted:
d51d95c9ea81 Issue #16408: Fix file descriptors not being closed in error conditions in the zipfile module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76270
diff changeset
1182 if not pwd:
d51d95c9ea81 Issue #16408: Fix file descriptors not being closed in error conditions in the zipfile module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76270
diff changeset
1183 pwd = self.pwd
d51d95c9ea81 Issue #16408: Fix file descriptors not being closed in error conditions in the zipfile module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76270
diff changeset
1184 if not pwd:
d51d95c9ea81 Issue #16408: Fix file descriptors not being closed in error conditions in the zipfile module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76270
diff changeset
1185 raise RuntimeError("File %s is encrypted, password "
d51d95c9ea81 Issue #16408: Fix file descriptors not being closed in error conditions in the zipfile module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76270
diff changeset
1186 "required for extraction" % name)
39442
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36609
diff changeset
1187
80482
d51d95c9ea81 Issue #16408: Fix file descriptors not being closed in error conditions in the zipfile module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76270
diff changeset
1188 zd = _ZipDecrypter(pwd)
d51d95c9ea81 Issue #16408: Fix file descriptors not being closed in error conditions in the zipfile module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76270
diff changeset
1189 # The first 12 bytes in the cypher stream is an encryption header
d51d95c9ea81 Issue #16408: Fix file descriptors not being closed in error conditions in the zipfile module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76270
diff changeset
1190 # used to strengthen the algorithm. The first 11 bytes are
d51d95c9ea81 Issue #16408: Fix file descriptors not being closed in error conditions in the zipfile module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76270
diff changeset
1191 # completely random, while the 12th contains the MSB of the CRC,
d51d95c9ea81 Issue #16408: Fix file descriptors not being closed in error conditions in the zipfile module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76270
diff changeset
1192 # or the MSB of the file time depending on the header type
d51d95c9ea81 Issue #16408: Fix file descriptors not being closed in error conditions in the zipfile module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76270
diff changeset
1193 # and is used to check the correctness of the password.
d51d95c9ea81 Issue #16408: Fix file descriptors not being closed in error conditions in the zipfile module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76270
diff changeset
1194 header = zef_file.read(12)
d51d95c9ea81 Issue #16408: Fix file descriptors not being closed in error conditions in the zipfile module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76270
diff changeset
1195 h = list(map(zd, header[0:12]))
d51d95c9ea81 Issue #16408: Fix file descriptors not being closed in error conditions in the zipfile module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76270
diff changeset
1196 if zinfo.flag_bits & 0x8:
d51d95c9ea81 Issue #16408: Fix file descriptors not being closed in error conditions in the zipfile module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76270
diff changeset
1197 # compare against the file type from extended local headers
d51d95c9ea81 Issue #16408: Fix file descriptors not being closed in error conditions in the zipfile module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76270
diff changeset
1198 check_byte = (zinfo._raw_time >> 8) & 0xff
d51d95c9ea81 Issue #16408: Fix file descriptors not being closed in error conditions in the zipfile module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76270
diff changeset
1199 else:
d51d95c9ea81 Issue #16408: Fix file descriptors not being closed in error conditions in the zipfile module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76270
diff changeset
1200 # compare against the CRC otherwise
d51d95c9ea81 Issue #16408: Fix file descriptors not being closed in error conditions in the zipfile module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76270
diff changeset
1201 check_byte = (zinfo.CRC >> 24) & 0xff
d51d95c9ea81 Issue #16408: Fix file descriptors not being closed in error conditions in the zipfile module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76270
diff changeset
1202 if h[11] != check_byte:
d51d95c9ea81 Issue #16408: Fix file descriptors not being closed in error conditions in the zipfile module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76270
diff changeset
1203 raise RuntimeError("Bad password for file", name)
39442
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36609
diff changeset
1204
80482
d51d95c9ea81 Issue #16408: Fix file descriptors not being closed in error conditions in the zipfile module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76270
diff changeset
1205 return ZipExtFile(zef_file, mode, zinfo, zd,
d51d95c9ea81 Issue #16408: Fix file descriptors not being closed in error conditions in the zipfile module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76270
diff changeset
1206 close_fileobj=not self._filePassed)
d51d95c9ea81 Issue #16408: Fix file descriptors not being closed in error conditions in the zipfile module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76270
diff changeset
1207 except:
66409
260ff379115c zipfile: remove remaining ResourceWarnings
Łukasz Langa <lukasz@langa.pl>
parents: 66408
diff changeset
1208 if not self._filePassed:
260ff379115c zipfile: remove remaining ResourceWarnings
Łukasz Langa <lukasz@langa.pl>
parents: 66408
diff changeset
1209 zef_file.close()
80482
d51d95c9ea81 Issue #16408: Fix file descriptors not being closed in error conditions in the zipfile module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76270
diff changeset
1210 raise
12197
7f18f979a93a Zip file handling module, by Jim Ahlstrom.
Guido van Rossum <guido@python.org>
parents:
diff changeset
1211
44587
fb5a6330f71b Merged revisions 59822-59841 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 44160
diff changeset
1212 def extract(self, member, path=None, pwd=None):
fb5a6330f71b Merged revisions 59822-59841 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 44160
diff changeset
1213 """Extract a member from the archive to the current working directory,
fb5a6330f71b Merged revisions 59822-59841 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 44160
diff changeset
1214 using its full name. Its file information is extracted as accurately
fb5a6330f71b Merged revisions 59822-59841 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 44160
diff changeset
1215 as possible. `member' may be a filename or a ZipInfo object. You can
fb5a6330f71b Merged revisions 59822-59841 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 44160
diff changeset
1216 specify a different directory using `path'.
fb5a6330f71b Merged revisions 59822-59841 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 44160
diff changeset
1217 """
fb5a6330f71b Merged revisions 59822-59841 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 44160
diff changeset
1218 if not isinstance(member, ZipInfo):
fb5a6330f71b Merged revisions 59822-59841 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 44160
diff changeset
1219 member = self.getinfo(member)
fb5a6330f71b Merged revisions 59822-59841 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 44160
diff changeset
1220
fb5a6330f71b Merged revisions 59822-59841 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 44160
diff changeset
1221 if path is None:
fb5a6330f71b Merged revisions 59822-59841 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 44160
diff changeset
1222 path = os.getcwd()
fb5a6330f71b Merged revisions 59822-59841 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 44160
diff changeset
1223
fb5a6330f71b Merged revisions 59822-59841 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 44160
diff changeset
1224 return self._extract_member(member, path, pwd)
fb5a6330f71b Merged revisions 59822-59841 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 44160
diff changeset
1225
fb5a6330f71b Merged revisions 59822-59841 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 44160
diff changeset
1226 def extractall(self, path=None, members=None, pwd=None):
fb5a6330f71b Merged revisions 59822-59841 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 44160
diff changeset
1227 """Extract all members from the archive to the current working
fb5a6330f71b Merged revisions 59822-59841 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 44160
diff changeset
1228 directory. `path' specifies a different directory to extract to.
fb5a6330f71b Merged revisions 59822-59841 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 44160
diff changeset
1229 `members' is optional and must be a subset of the list returned
fb5a6330f71b Merged revisions 59822-59841 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 44160
diff changeset
1230 by namelist().
fb5a6330f71b Merged revisions 59822-59841 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 44160
diff changeset
1231 """
fb5a6330f71b Merged revisions 59822-59841 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 44160
diff changeset
1232 if members is None:
fb5a6330f71b Merged revisions 59822-59841 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 44160
diff changeset
1233 members = self.namelist()
fb5a6330f71b Merged revisions 59822-59841 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 44160
diff changeset
1234
fb5a6330f71b Merged revisions 59822-59841 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 44160
diff changeset
1235 for zipinfo in members:
fb5a6330f71b Merged revisions 59822-59841 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 44160
diff changeset
1236 self.extract(zipinfo, path, pwd)
fb5a6330f71b Merged revisions 59822-59841 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 44160
diff changeset
1237
81961
3febccf2a756 Refactor recently added bugfix into more testable code by using a
Gregory P. Smith <greg@krypto.org>
parents: 81939
diff changeset
1238 @classmethod
3febccf2a756 Refactor recently added bugfix into more testable code by using a
Gregory P. Smith <greg@krypto.org>
parents: 81939
diff changeset
1239 def _sanitize_windows_name(cls, arcname, pathsep):
3febccf2a756 Refactor recently added bugfix into more testable code by using a
Gregory P. Smith <greg@krypto.org>
parents: 81939
diff changeset
1240 """Replace bad characters and remove trailing dots from parts."""
3febccf2a756 Refactor recently added bugfix into more testable code by using a
Gregory P. Smith <greg@krypto.org>
parents: 81939
diff changeset
1241 table = cls._windows_illegal_name_trans_table
3febccf2a756 Refactor recently added bugfix into more testable code by using a
Gregory P. Smith <greg@krypto.org>
parents: 81939
diff changeset
1242 if not table:
3febccf2a756 Refactor recently added bugfix into more testable code by using a
Gregory P. Smith <greg@krypto.org>
parents: 81939
diff changeset
1243 illegal = ':<>|"?*'
3febccf2a756 Refactor recently added bugfix into more testable code by using a
Gregory P. Smith <greg@krypto.org>
parents: 81939
diff changeset
1244 table = str.maketrans(illegal, '_' * len(illegal))
3febccf2a756 Refactor recently added bugfix into more testable code by using a
Gregory P. Smith <greg@krypto.org>
parents: 81939
diff changeset
1245 cls._windows_illegal_name_trans_table = table
3febccf2a756 Refactor recently added bugfix into more testable code by using a
Gregory P. Smith <greg@krypto.org>
parents: 81939
diff changeset
1246 arcname = arcname.translate(table)
3febccf2a756 Refactor recently added bugfix into more testable code by using a
Gregory P. Smith <greg@krypto.org>
parents: 81939
diff changeset
1247 # remove trailing dots
3febccf2a756 Refactor recently added bugfix into more testable code by using a
Gregory P. Smith <greg@krypto.org>
parents: 81939
diff changeset
1248 arcname = (x.rstrip('.') for x in arcname.split(pathsep))
3febccf2a756 Refactor recently added bugfix into more testable code by using a
Gregory P. Smith <greg@krypto.org>
parents: 81939
diff changeset
1249 # rejoin, removing empty parts.
3febccf2a756 Refactor recently added bugfix into more testable code by using a
Gregory P. Smith <greg@krypto.org>
parents: 81939
diff changeset
1250 arcname = pathsep.join(x for x in arcname if x)
3febccf2a756 Refactor recently added bugfix into more testable code by using a
Gregory P. Smith <greg@krypto.org>
parents: 81939
diff changeset
1251 return arcname
3febccf2a756 Refactor recently added bugfix into more testable code by using a
Gregory P. Smith <greg@krypto.org>
parents: 81939
diff changeset
1252
44587
fb5a6330f71b Merged revisions 59822-59841 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 44160
diff changeset
1253 def _extract_member(self, member, targetpath, pwd):
fb5a6330f71b Merged revisions 59822-59841 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 44160
diff changeset
1254 """Extract the ZipInfo object 'member' to a physical
fb5a6330f71b Merged revisions 59822-59841 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 44160
diff changeset
1255 file on the path targetpath.
fb5a6330f71b Merged revisions 59822-59841 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 44160
diff changeset
1256 """
fb5a6330f71b Merged revisions 59822-59841 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 44160
diff changeset
1257 # build the destination pathname, replacing
fb5a6330f71b Merged revisions 59822-59841 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 44160
diff changeset
1258 # forward slashes to platform specific separators.
81871
0c5fa35c9f12 Fixes Issue #6972: The zipfile module no longer overwrites files outside of
Gregory P. Smith <greg@krypto.org>
parents: 81848
diff changeset
1259 arcname = member.filename.replace('/', os.path.sep)
44587
fb5a6330f71b Merged revisions 59822-59841 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 44160
diff changeset
1260
81871
0c5fa35c9f12 Fixes Issue #6972: The zipfile module no longer overwrites files outside of
Gregory P. Smith <greg@krypto.org>
parents: 81848
diff changeset
1261 if os.path.altsep:
0c5fa35c9f12 Fixes Issue #6972: The zipfile module no longer overwrites files outside of
Gregory P. Smith <greg@krypto.org>
parents: 81848
diff changeset
1262 arcname = arcname.replace(os.path.altsep, os.path.sep)
0c5fa35c9f12 Fixes Issue #6972: The zipfile module no longer overwrites files outside of
Gregory P. Smith <greg@krypto.org>
parents: 81848
diff changeset
1263 # interpret absolute pathname as relative, remove drive letter or
0c5fa35c9f12 Fixes Issue #6972: The zipfile module no longer overwrites files outside of
Gregory P. Smith <greg@krypto.org>
parents: 81848
diff changeset
1264 # UNC path, redundant separators, "." and ".." components.
0c5fa35c9f12 Fixes Issue #6972: The zipfile module no longer overwrites files outside of
Gregory P. Smith <greg@krypto.org>
parents: 81848
diff changeset
1265 arcname = os.path.splitdrive(arcname)[1]
81961
3febccf2a756 Refactor recently added bugfix into more testable code by using a
Gregory P. Smith <greg@krypto.org>
parents: 81939
diff changeset
1266 invalid_path_parts = ('', os.path.curdir, os.path.pardir)
81871
0c5fa35c9f12 Fixes Issue #6972: The zipfile module no longer overwrites files outside of
Gregory P. Smith <greg@krypto.org>
parents: 81848
diff changeset
1267 arcname = os.path.sep.join(x for x in arcname.split(os.path.sep)
81961
3febccf2a756 Refactor recently added bugfix into more testable code by using a
Gregory P. Smith <greg@krypto.org>
parents: 81939
diff changeset
1268 if x not in invalid_path_parts)
81871
0c5fa35c9f12 Fixes Issue #6972: The zipfile module no longer overwrites files outside of
Gregory P. Smith <greg@krypto.org>
parents: 81848
diff changeset
1269 if os.path.sep == '\\':
81938
434b50c7bbed Fix the test for issue #6972.
Serhiy Storchaka <storchaka@gmail.com>
parents: 81871
diff changeset
1270 # filter illegal characters on Windows
81961
3febccf2a756 Refactor recently added bugfix into more testable code by using a
Gregory P. Smith <greg@krypto.org>
parents: 81939
diff changeset
1271 arcname = self._sanitize_windows_name(arcname, os.path.sep)
44587
fb5a6330f71b Merged revisions 59822-59841 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 44160
diff changeset
1272
81871
0c5fa35c9f12 Fixes Issue #6972: The zipfile module no longer overwrites files outside of
Gregory P. Smith <greg@krypto.org>
parents: 81848
diff changeset
1273 targetpath = os.path.join(targetpath, arcname)
44587
fb5a6330f71b Merged revisions 59822-59841 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 44160
diff changeset
1274 targetpath = os.path.normpath(targetpath)
fb5a6330f71b Merged revisions 59822-59841 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 44160
diff changeset
1275
fb5a6330f71b Merged revisions 59822-59841 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 44160
diff changeset
1276 # Create all upper directories if necessary.
fb5a6330f71b Merged revisions 59822-59841 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 44160
diff changeset
1277 upperdirs = os.path.dirname(targetpath)
fb5a6330f71b Merged revisions 59822-59841 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 44160
diff changeset
1278 if upperdirs and not os.path.exists(upperdirs):
fb5a6330f71b Merged revisions 59822-59841 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 44160
diff changeset
1279 os.makedirs(upperdirs)
fb5a6330f71b Merged revisions 59822-59841 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 44160
diff changeset
1280
51001
cef0fcc91559 Merged revisions 68885 via svnmerge from
Martin v. Löwis <martin@v.loewis.de>
parents: 50847
diff changeset
1281 if member.filename[-1] == '/':
54313
538f4e774c18 Merged revisions 72893 via svnmerge from
Martin v. Löwis <martin@v.loewis.de>
parents: 53753
diff changeset
1282 if not os.path.isdir(targetpath):
538f4e774c18 Merged revisions 72893 via svnmerge from
Martin v. Löwis <martin@v.loewis.de>
parents: 53753
diff changeset
1283 os.mkdir(targetpath)
51001
cef0fcc91559 Merged revisions 68885 via svnmerge from
Martin v. Löwis <martin@v.loewis.de>
parents: 50847
diff changeset
1284 return targetpath
cef0fcc91559 Merged revisions 68885 via svnmerge from
Martin v. Löwis <martin@v.loewis.de>
parents: 50847
diff changeset
1285
80482
d51d95c9ea81 Issue #16408: Fix file descriptors not being closed in error conditions in the zipfile module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76270
diff changeset
1286 with self.open(member, pwd=pwd) as source, \
d51d95c9ea81 Issue #16408: Fix file descriptors not being closed in error conditions in the zipfile module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76270
diff changeset
1287 open(targetpath, "wb") as target:
d51d95c9ea81 Issue #16408: Fix file descriptors not being closed in error conditions in the zipfile module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76270
diff changeset
1288 shutil.copyfileobj(source, target)
44587
fb5a6330f71b Merged revisions 59822-59841 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 44160
diff changeset
1289
fb5a6330f71b Merged revisions 59822-59841 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 44160
diff changeset
1290 return targetpath
fb5a6330f71b Merged revisions 59822-59841 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 44160
diff changeset
1291
12197
7f18f979a93a Zip file handling module, by Jim Ahlstrom.
Guido van Rossum <guido@python.org>
parents:
diff changeset
1292 def _writecheck(self, zinfo):
14975
27eab8032766 Delay import of py_compile until needed, since is is only used by the
Fred Drake <fdrake@acm.org>
parents: 14933
diff changeset
1293 """Check for errors before writing a file to the archive."""
23620
a1de0bab5475 SF 563203. Replaced 'has_key()' with 'in'.
Raymond Hettinger <python@rcn.com>
parents: 22867
diff changeset
1294 if zinfo.filename in self.NameToInfo:
15874
4c01ee0a8073 Whitespace normalization. Top level of Lib now fixed-point for reindent.py!
Tim Peters <tim.peters@gmail.com>
parents: 14975
diff changeset
1295 if self.debug: # Warning for duplicate names
40775
4cdf21a0dbbc Fix most trivially-findable print statements.
Guido van Rossum <guido@python.org>
parents: 40644
diff changeset
1296 print("Duplicate name:", zinfo.filename)
12197
7f18f979a93a Zip file handling module, by Jim Ahlstrom.
Guido van Rossum <guido@python.org>
parents:
diff changeset
1297 if self.mode not in ("w", "a"):
43020
907a45df1295 Raise statement normalization in Lib/.
Collin Winter <collinw@gmail.com>
parents: 43005
diff changeset
1298 raise RuntimeError('write() requires mode "w" or "a"')
12197
7f18f979a93a Zip file handling module, by Jim Ahlstrom.
Guido van Rossum <guido@python.org>
parents:
diff changeset
1299 if not self.fp:
43020
907a45df1295 Raise statement normalization in Lib/.
Collin Winter <collinw@gmail.com>
parents: 43005
diff changeset
1300 raise RuntimeError(
86536
34fb83421119 add a filterfunc to zip file.PyZipFile.writepy, issue 19274
Christian Tismer <tismer@stackless.com>
parents: 85814
diff changeset
1301 "Attempt to write ZIP archive that was already closed")
76682
028e8e0b03e8 Issue #14371: Support bzip2 in zipfile module.
Martin v. Löwis <martin@v.loewis.de>
parents: 76373
diff changeset
1302 _check_compression(zinfo.compress_type)
39442
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36609
diff changeset
1303 if zinfo.file_size > ZIP64_LIMIT:
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36609
diff changeset
1304 if not self._allowZip64:
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36609
diff changeset
1305 raise LargeZipFile("Filesize would require ZIP64 extensions")
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36609
diff changeset
1306 if zinfo.header_offset > ZIP64_LIMIT:
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36609
diff changeset
1307 if not self._allowZip64:
43020
907a45df1295 Raise statement normalization in Lib/.
Collin Winter <collinw@gmail.com>
parents: 43005
diff changeset
1308 raise LargeZipFile(
86536
34fb83421119 add a filterfunc to zip file.PyZipFile.writepy, issue 19274
Christian Tismer <tismer@stackless.com>
parents: 85814
diff changeset
1309 "Zipfile size would require ZIP64 extensions")
12197
7f18f979a93a Zip file handling module, by Jim Ahlstrom.
Guido van Rossum <guido@python.org>
parents:
diff changeset
1310
7f18f979a93a Zip file handling module, by Jim Ahlstrom.
Guido van Rossum <guido@python.org>
parents:
diff changeset
1311 def write(self, filename, arcname=None, compress_type=None):
14975
27eab8032766 Delay import of py_compile until needed, since is is only used by the
Fred Drake <fdrake@acm.org>
parents: 14933
diff changeset
1312 """Put the bytes from filename into the archive under the name
27eab8032766 Delay import of py_compile until needed, since is is only used by the
Fred Drake <fdrake@acm.org>
parents: 14933
diff changeset
1313 arcname."""
42309
bd6acfdb47d2 Merged revisions 56301-56442 via svnmerge from
Guido van Rossum <guido@python.org>
parents: 42142
diff changeset
1314 if not self.fp:
bd6acfdb47d2 Merged revisions 56301-56442 via svnmerge from
Guido van Rossum <guido@python.org>
parents: 42142
diff changeset
1315 raise RuntimeError(
86536
34fb83421119 add a filterfunc to zip file.PyZipFile.writepy, issue 19274
Christian Tismer <tismer@stackless.com>
parents: 85814
diff changeset
1316 "Attempt to write to ZIP archive that was already closed")
42309
bd6acfdb47d2 Merged revisions 56301-56442 via svnmerge from
Guido van Rossum <guido@python.org>
parents: 42142
diff changeset
1317
12197
7f18f979a93a Zip file handling module, by Jim Ahlstrom.
Guido van Rossum <guido@python.org>
parents:
diff changeset
1318 st = os.stat(filename)
51001
cef0fcc91559 Merged revisions 68885 via svnmerge from
Martin v. Löwis <martin@v.loewis.de>
parents: 50847
diff changeset
1319 isdir = stat.S_ISDIR(st.st_mode)
23625
65cf478950ff Replaced obsolete stat module constants with equivalent attributes
Raymond Hettinger <python@rcn.com>
parents: 23620
diff changeset
1320 mtime = time.localtime(st.st_mtime)
12197
7f18f979a93a Zip file handling module, by Jim Ahlstrom.
Guido van Rossum <guido@python.org>
parents:
diff changeset
1321 date_time = mtime[0:6]
7f18f979a93a Zip file handling module, by Jim Ahlstrom.
Guido van Rossum <guido@python.org>
parents:
diff changeset
1322 # Create ZipInfo instance to store file information
7f18f979a93a Zip file handling module, by Jim Ahlstrom.
Guido van Rossum <guido@python.org>
parents:
diff changeset
1323 if arcname is None:
36609
46ec948cbde8 Bug #1413790: zipfile now sanitizes absolute archive names that are
Georg Brandl <georg@python.org>
parents: 36449
diff changeset
1324 arcname = filename
46ec948cbde8 Bug #1413790: zipfile now sanitizes absolute archive names that are
Georg Brandl <georg@python.org>
parents: 36449
diff changeset
1325 arcname = os.path.normpath(os.path.splitdrive(arcname)[1])
46ec948cbde8 Bug #1413790: zipfile now sanitizes absolute archive names that are
Georg Brandl <georg@python.org>
parents: 36449
diff changeset
1326 while arcname[0] in (os.sep, os.altsep):
46ec948cbde8 Bug #1413790: zipfile now sanitizes absolute archive names that are
Georg Brandl <georg@python.org>
parents: 36449
diff changeset
1327 arcname = arcname[1:]
51001
cef0fcc91559 Merged revisions 68885 via svnmerge from
Martin v. Löwis <martin@v.loewis.de>
parents: 50847
diff changeset
1328 if isdir:
cef0fcc91559 Merged revisions 68885 via svnmerge from
Martin v. Löwis <martin@v.loewis.de>
parents: 50847
diff changeset
1329 arcname += '/'
36609
46ec948cbde8 Bug #1413790: zipfile now sanitizes absolute archive names that are
Georg Brandl <georg@python.org>
parents: 36449
diff changeset
1330 zinfo = ZipInfo(arcname, date_time)
40644
1c26505c1de6 Rip out 'long' and 'L'-suffixed integer literals.
Guido van Rossum <guido@python.org>
parents: 40587
diff changeset
1331 zinfo.external_attr = (st[0] & 0xFFFF) << 16 # Unix attributes
12197
7f18f979a93a Zip file handling module, by Jim Ahlstrom.
Guido van Rossum <guido@python.org>
parents:
diff changeset
1332 if compress_type is None:
15874
4c01ee0a8073 Whitespace normalization. Top level of Lib now fixed-point for reindent.py!
Tim Peters <tim.peters@gmail.com>
parents: 14975
diff changeset
1333 zinfo.compress_type = self.compression
12197
7f18f979a93a Zip file handling module, by Jim Ahlstrom.
Guido van Rossum <guido@python.org>
parents:
diff changeset
1334 else:
15874
4c01ee0a8073 Whitespace normalization. Top level of Lib now fixed-point for reindent.py!
Tim Peters <tim.peters@gmail.com>
parents: 14975
diff changeset
1335 zinfo.compress_type = compress_type
39442
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36609
diff changeset
1336
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36609
diff changeset
1337 zinfo.file_size = st.st_size
19737
56c549a253a6 [ #458701 ] Patch to zipfile.py for Java
Finn Bock <bckfnn@worldonline.dk>
parents: 18746
diff changeset
1338 zinfo.flag_bits = 0x00
15874
4c01ee0a8073 Whitespace normalization. Top level of Lib now fixed-point for reindent.py!
Tim Peters <tim.peters@gmail.com>
parents: 14975
diff changeset
1339 zinfo.header_offset = self.fp.tell() # Start of header bytes
76895
fccdcd83708a Issue #14366: Support lzma compression in zip files.
Martin v. Löwis <martin@v.loewis.de>
parents: 76694
diff changeset
1340 if zinfo.compress_type == ZIP_LZMA:
fccdcd83708a Issue #14366: Support lzma compression in zip files.
Martin v. Löwis <martin@v.loewis.de>
parents: 76694
diff changeset
1341 # Compressed data includes an end-of-stream (EOS) marker
fccdcd83708a Issue #14366: Support lzma compression in zip files.
Martin v. Löwis <martin@v.loewis.de>
parents: 76694
diff changeset
1342 zinfo.flag_bits |= 0x02
39442
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36609
diff changeset
1343
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36609
diff changeset
1344 self._writecheck(zinfo)
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36609
diff changeset
1345 self._didModify = True
51001
cef0fcc91559 Merged revisions 68885 via svnmerge from
Martin v. Löwis <martin@v.loewis.de>
parents: 50847
diff changeset
1346
cef0fcc91559 Merged revisions 68885 via svnmerge from
Martin v. Löwis <martin@v.loewis.de>
parents: 50847
diff changeset
1347 if isdir:
cef0fcc91559 Merged revisions 68885 via svnmerge from
Martin v. Löwis <martin@v.loewis.de>
parents: 50847
diff changeset
1348 zinfo.file_size = 0
cef0fcc91559 Merged revisions 68885 via svnmerge from
Martin v. Löwis <martin@v.loewis.de>
parents: 50847
diff changeset
1349 zinfo.compress_size = 0
cef0fcc91559 Merged revisions 68885 via svnmerge from
Martin v. Löwis <martin@v.loewis.de>
parents: 50847
diff changeset
1350 zinfo.CRC = 0
cef0fcc91559 Merged revisions 68885 via svnmerge from
Martin v. Löwis <martin@v.loewis.de>
parents: 50847
diff changeset
1351 self.filelist.append(zinfo)
cef0fcc91559 Merged revisions 68885 via svnmerge from
Martin v. Löwis <martin@v.loewis.de>
parents: 50847
diff changeset
1352 self.NameToInfo[zinfo.filename] = zinfo
81502
b93848ca7760 Issue #9720: zipfile now writes correct local headers for files larger than 4 GiB.
Serhiy Storchaka <storchaka@gmail.com>
parents: 80500
diff changeset
1353 self.fp.write(zinfo.FileHeader(False))
51001
cef0fcc91559 Merged revisions 68885 via svnmerge from
Martin v. Löwis <martin@v.loewis.de>
parents: 50847
diff changeset
1354 return
cef0fcc91559 Merged revisions 68885 via svnmerge from
Martin v. Löwis <martin@v.loewis.de>
parents: 50847
diff changeset
1355
76682
028e8e0b03e8 Issue #14371: Support bzip2 in zipfile module.
Martin v. Löwis <martin@v.loewis.de>
parents: 76373
diff changeset
1356 cmpr = _get_compressor(zinfo.compress_type)
54501
ced380b40004 Merged revisions 72506,72525-72526,72551,72558,72616,72654-72655,72689,72745,72750,72802,72812,72822,72824,72826-72827,72833,72876,72890,72923,72946,73026,73042,73045,73047,73065,73068-73069 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 54313
diff changeset
1357 with open(filename, "rb") as fp:
ced380b40004 Merged revisions 72506,72525-72526,72551,72558,72616,72654-72655,72689,72745,72750,72802,72812,72822,72824,72826-72827,72833,72876,72890,72923,72946,73026,73042,73045,73047,73065,73068-73069 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 54313
diff changeset
1358 # Must overwrite CRC and sizes with correct data later
ced380b40004 Merged revisions 72506,72525-72526,72551,72558,72616,72654-72655,72689,72745,72750,72802,72812,72822,72824,72826-72827,72833,72876,72890,72923,72946,73026,73042,73045,73047,73065,73068-73069 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 54313
diff changeset
1359 zinfo.CRC = CRC = 0
ced380b40004 Merged revisions 72506,72525-72526,72551,72558,72616,72654-72655,72689,72745,72750,72802,72812,72822,72824,72826-72827,72833,72876,72890,72923,72946,73026,73042,73045,73047,73065,73068-73069 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 54313
diff changeset
1360 zinfo.compress_size = compress_size = 0
81502
b93848ca7760 Issue #9720: zipfile now writes correct local headers for files larger than 4 GiB.
Serhiy Storchaka <storchaka@gmail.com>
parents: 80500
diff changeset
1361 # Compressed size can be larger than uncompressed size
b93848ca7760 Issue #9720: zipfile now writes correct local headers for files larger than 4 GiB.
Serhiy Storchaka <storchaka@gmail.com>
parents: 80500
diff changeset
1362 zip64 = self._allowZip64 and \
86536
34fb83421119 add a filterfunc to zip file.PyZipFile.writepy, issue 19274
Christian Tismer <tismer@stackless.com>
parents: 85814
diff changeset
1363 zinfo.file_size * 1.05 > ZIP64_LIMIT
81502
b93848ca7760 Issue #9720: zipfile now writes correct local headers for files larger than 4 GiB.
Serhiy Storchaka <storchaka@gmail.com>
parents: 80500
diff changeset
1364 self.fp.write(zinfo.FileHeader(zip64))
b93848ca7760 Issue #9720: zipfile now writes correct local headers for files larger than 4 GiB.
Serhiy Storchaka <storchaka@gmail.com>
parents: 80500
diff changeset
1365 file_size = 0
54501
ced380b40004 Merged revisions 72506,72525-72526,72551,72558,72616,72654-72655,72689,72745,72750,72802,72812,72822,72824,72826-72827,72833,72876,72890,72923,72946,73026,73042,73045,73047,73065,73068-73069 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 54313
diff changeset
1366 while 1:
ced380b40004 Merged revisions 72506,72525-72526,72551,72558,72616,72654-72655,72689,72745,72750,72802,72812,72822,72824,72826-72827,72833,72876,72890,72923,72946,73026,73042,73045,73047,73065,73068-73069 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 54313
diff changeset
1367 buf = fp.read(1024 * 8)
ced380b40004 Merged revisions 72506,72525-72526,72551,72558,72616,72654-72655,72689,72745,72750,72802,72812,72822,72824,72826-72827,72833,72876,72890,72923,72946,73026,73042,73045,73047,73065,73068-73069 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 54313
diff changeset
1368 if not buf:
ced380b40004 Merged revisions 72506,72525-72526,72551,72558,72616,72654-72655,72689,72745,72750,72802,72812,72822,72824,72826-72827,72833,72876,72890,72923,72946,73026,73042,73045,73047,73065,73068-73069 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 54313
diff changeset
1369 break
ced380b40004 Merged revisions 72506,72525-72526,72551,72558,72616,72654-72655,72689,72745,72750,72802,72812,72822,72824,72826-72827,72833,72876,72890,72923,72946,73026,73042,73045,73047,73065,73068-73069 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 54313
diff changeset
1370 file_size = file_size + len(buf)
ced380b40004 Merged revisions 72506,72525-72526,72551,72558,72616,72654-72655,72689,72745,72750,72802,72812,72822,72824,72826-72827,72833,72876,72890,72923,72946,73026,73042,73045,73047,73065,73068-73069 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 54313
diff changeset
1371 CRC = crc32(buf, CRC) & 0xffffffff
ced380b40004 Merged revisions 72506,72525-72526,72551,72558,72616,72654-72655,72689,72745,72750,72802,72812,72822,72824,72826-72827,72833,72876,72890,72923,72946,73026,73042,73045,73047,73065,73068-73069 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 54313
diff changeset
1372 if cmpr:
ced380b40004 Merged revisions 72506,72525-72526,72551,72558,72616,72654-72655,72689,72745,72750,72802,72812,72822,72824,72826-72827,72833,72876,72890,72923,72946,73026,73042,73045,73047,73065,73068-73069 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 54313
diff changeset
1373 buf = cmpr.compress(buf)
ced380b40004 Merged revisions 72506,72525-72526,72551,72558,72616,72654-72655,72689,72745,72750,72802,72812,72822,72824,72826-72827,72833,72876,72890,72923,72946,73026,73042,73045,73047,73065,73068-73069 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 54313
diff changeset
1374 compress_size = compress_size + len(buf)
ced380b40004 Merged revisions 72506,72525-72526,72551,72558,72616,72654-72655,72689,72745,72750,72802,72812,72822,72824,72826-72827,72833,72876,72890,72923,72946,73026,73042,73045,73047,73065,73068-73069 via svnmerge from
Benjamin Peterson <benjamin@python.org>
parents: 54313
diff changeset
1375 self.fp.write(buf)
12197
7f18f979a93a Zip file handling module, by Jim Ahlstrom.
Guido van Rossum <guido@python.org>
parents:
diff changeset
1376 if cmpr:
7f18f979a93a Zip file handling module, by Jim Ahlstrom.
Guido van Rossum <guido@python.org>
parents:
diff changeset
1377 buf = cmpr.flush()
7f18f979a93a Zip file handling module, by Jim Ahlstrom.
Guido van Rossum <guido@python.org>
parents:
diff changeset
1378 compress_size = compress_size + len(buf)
7f18f979a93a Zip file handling module, by Jim Ahlstrom.
Guido van Rossum <guido@python.org>
parents:
diff changeset
1379 self.fp.write(buf)
7f18f979a93a Zip file handling module, by Jim Ahlstrom.
Guido van Rossum <guido@python.org>
parents:
diff changeset
1380 zinfo.compress_size = compress_size
7f18f979a93a Zip file handling module, by Jim Ahlstrom.
Guido van Rossum <guido@python.org>
parents:
diff changeset
1381 else:
7f18f979a93a Zip file handling module, by Jim Ahlstrom.
Guido van Rossum <guido@python.org>
parents:
diff changeset
1382 zinfo.compress_size = file_size
7f18f979a93a Zip file handling module, by Jim Ahlstrom.
Guido van Rossum <guido@python.org>
parents:
diff changeset
1383 zinfo.CRC = CRC
7f18f979a93a Zip file handling module, by Jim Ahlstrom.
Guido van Rossum <guido@python.org>
parents:
diff changeset
1384 zinfo.file_size = file_size
81502
b93848ca7760 Issue #9720: zipfile now writes correct local headers for files larger than 4 GiB.
Serhiy Storchaka <storchaka@gmail.com>
parents: 80500
diff changeset
1385 if not zip64 and self._allowZip64:
b93848ca7760 Issue #9720: zipfile now writes correct local headers for files larger than 4 GiB.
Serhiy Storchaka <storchaka@gmail.com>
parents: 80500
diff changeset
1386 if file_size > ZIP64_LIMIT:
b93848ca7760 Issue #9720: zipfile now writes correct local headers for files larger than 4 GiB.
Serhiy Storchaka <storchaka@gmail.com>
parents: 80500
diff changeset
1387 raise RuntimeError('File size has increased during compressing')
b93848ca7760 Issue #9720: zipfile now writes correct local headers for files larger than 4 GiB.
Serhiy Storchaka <storchaka@gmail.com>
parents: 80500
diff changeset
1388 if compress_size > ZIP64_LIMIT:
b93848ca7760 Issue #9720: zipfile now writes correct local headers for files larger than 4 GiB.
Serhiy Storchaka <storchaka@gmail.com>
parents: 80500
diff changeset
1389 raise RuntimeError('Compressed size larger than uncompressed size')
b93848ca7760 Issue #9720: zipfile now writes correct local headers for files larger than 4 GiB.
Serhiy Storchaka <storchaka@gmail.com>
parents: 80500
diff changeset
1390 # Seek backwards and write file header (which will now include
b93848ca7760 Issue #9720: zipfile now writes correct local headers for files larger than 4 GiB.
Serhiy Storchaka <storchaka@gmail.com>
parents: 80500
diff changeset
1391 # correct CRC and file sizes)
19953
0f9df563b65d Whitespace normalization.
Tim Peters <tim.peters@gmail.com>
parents: 19737
diff changeset
1392 position = self.fp.tell() # Preserve current position in file
81502
b93848ca7760 Issue #9720: zipfile now writes correct local headers for files larger than 4 GiB.
Serhiy Storchaka <storchaka@gmail.com>
parents: 80500
diff changeset
1393 self.fp.seek(zinfo.header_offset, 0)
b93848ca7760 Issue #9720: zipfile now writes correct local headers for files larger than 4 GiB.
Serhiy Storchaka <storchaka@gmail.com>
parents: 80500
diff changeset
1394 self.fp.write(zinfo.FileHeader(zip64))
19737
56c549a253a6 [ #458701 ] Patch to zipfile.py for Java
Finn Bock <bckfnn@worldonline.dk>
parents: 18746
diff changeset
1395 self.fp.seek(position, 0)
12197
7f18f979a93a Zip file handling module, by Jim Ahlstrom.
Guido van Rossum <guido@python.org>
parents:
diff changeset
1396 self.filelist.append(zinfo)
7f18f979a93a Zip file handling module, by Jim Ahlstrom.
Guido van Rossum <guido@python.org>
parents:
diff changeset
1397 self.NameToInfo[zinfo.filename] = zinfo
7f18f979a93a Zip file handling module, by Jim Ahlstrom.
Guido van Rossum <guido@python.org>
parents:
diff changeset
1398
58822
faca97c5f038 Merged revisions 78097 via svnmerge from
Ronald Oussoren <ronaldoussoren@mac.com>
parents: 58552
diff changeset
1399 def writestr(self, zinfo_or_arcname, data, compress_type=None):
42900
19196cce1431 Changes preparing for stricter enforcement of bytes vs. str.
Guido van Rossum <guido@python.org>
parents: 42314
diff changeset
1400 """Write a file into the archive. The contents is 'data', which
19196cce1431 Changes preparing for stricter enforcement of bytes vs. str.
Guido van Rossum <guido@python.org>
parents: 42314
diff changeset
1401 may be either a 'str' or a 'bytes' instance; if it is a 'str',
19196cce1431 Changes preparing for stricter enforcement of bytes vs. str.
Guido van Rossum <guido@python.org>
parents: 42314
diff changeset
1402 it is encoded as UTF-8 first.
19196cce1431 Changes preparing for stricter enforcement of bytes vs. str.
Guido van Rossum <guido@python.org>
parents: 42314
diff changeset
1403 'zinfo_or_arcname' is either a ZipInfo instance or
26611
8771993c9aac Patch #651621, approved by MvL.
Just van Rossum <just@letterror.com>
parents: 25756
diff changeset
1404 the name of the file in the archive."""
42900
19196cce1431 Changes preparing for stricter enforcement of bytes vs. str.
Guido van Rossum <guido@python.org>
parents: 42314
diff changeset
1405 if isinstance(data, str):
19196cce1431 Changes preparing for stricter enforcement of bytes vs. str.
Guido van Rossum <guido@python.org>
parents: 42314
diff changeset
1406 data = data.encode("utf-8")
26611
8771993c9aac Patch #651621, approved by MvL.
Just van Rossum <just@letterror.com>
parents: 25756
diff changeset
1407 if not isinstance(zinfo_or_arcname, ZipInfo):
8771993c9aac Patch #651621, approved by MvL.
Just van Rossum <just@letterror.com>
parents: 25756
diff changeset
1408 zinfo = ZipInfo(filename=zinfo_or_arcname,
44699
6f049ca55e06 Merged revisions 59952-59984 via svnmerge from
Guido van Rossum <guido@python.org>
parents: 44587
diff changeset
1409 date_time=time.localtime(time.time())[:6])
26611
8771993c9aac Patch #651621, approved by MvL.
Just van Rossum <just@letterror.com>
parents: 25756
diff changeset
1410 zinfo.compress_type = self.compression
48572
55640151e0fc Merged revisions 65235 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 48499
diff changeset
1411 zinfo.external_attr = 0o600 << 16
26611
8771993c9aac Patch #651621, approved by MvL.
Just van Rossum <just@letterror.com>
parents: 25756
diff changeset
1412 else:
8771993c9aac Patch #651621, approved by MvL.
Just van Rossum <just@letterror.com>
parents: 25756
diff changeset
1413 zinfo = zinfo_or_arcname
42309
bd6acfdb47d2 Merged revisions 56301-56442 via svnmerge from
Guido van Rossum <guido@python.org>
parents: 42142
diff changeset
1414
bd6acfdb47d2 Merged revisions 56301-56442 via svnmerge from
Guido van Rossum <guido@python.org>
parents: 42142
diff changeset
1415 if not self.fp:
bd6acfdb47d2 Merged revisions 56301-56442 via svnmerge from
Guido van Rossum <guido@python.org>
parents: 42142
diff changeset
1416 raise RuntimeError(
86536
34fb83421119 add a filterfunc to zip file.PyZipFile.writepy, issue 19274
Christian Tismer <tismer@stackless.com>
parents: 85814
diff changeset
1417 "Attempt to write to ZIP archive that was already closed")
42309
bd6acfdb47d2 Merged revisions 56301-56442 via svnmerge from
Guido van Rossum <guido@python.org>
parents: 42142
diff changeset
1418
42900
19196cce1431 Changes preparing for stricter enforcement of bytes vs. str.
Guido van Rossum <guido@python.org>
parents: 42314
diff changeset
1419 zinfo.file_size = len(data) # Uncompressed size
19196cce1431 Changes preparing for stricter enforcement of bytes vs. str.
Guido van Rossum <guido@python.org>
parents: 42314
diff changeset
1420 zinfo.header_offset = self.fp.tell() # Start of header data
58822
faca97c5f038 Merged revisions 78097 via svnmerge from
Ronald Oussoren <ronaldoussoren@mac.com>
parents: 58552
diff changeset
1421 if compress_type is not None:
faca97c5f038 Merged revisions 78097 via svnmerge from
Ronald Oussoren <ronaldoussoren@mac.com>
parents: 58552
diff changeset
1422 zinfo.compress_type = compress_type
76895
fccdcd83708a Issue #14366: Support lzma compression in zip files.
Martin v. Löwis <martin@v.loewis.de>
parents: 76694
diff changeset
1423 if zinfo.compress_type == ZIP_LZMA:
fccdcd83708a Issue #14366: Support lzma compression in zip files.
Martin v. Löwis <martin@v.loewis.de>
parents: 76694
diff changeset
1424 # Compressed data includes an end-of-stream (EOS) marker
fccdcd83708a Issue #14366: Support lzma compression in zip files.
Martin v. Löwis <martin@v.loewis.de>
parents: 76694
diff changeset
1425 zinfo.flag_bits |= 0x02
58822
faca97c5f038 Merged revisions 78097 via svnmerge from
Ronald Oussoren <ronaldoussoren@mac.com>
parents: 58552
diff changeset
1426
12197
7f18f979a93a Zip file handling module, by Jim Ahlstrom.
Guido van Rossum <guido@python.org>
parents:
diff changeset
1427 self._writecheck(zinfo)
39442
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36609
diff changeset
1428 self._didModify = True
45931
1657f0acca78 Merged revisions 61538-61540,61556,61559-61560,61563,61565,61571,61575-61576,61580-61582,61586,61591,61593,61595,61605-61606,61613-61616,61618,61621-61623,61625,61627,61631-61634 via svnmerge from
Christian Heimes <christian@cheimes.de>
parents: 44810
diff changeset
1429 zinfo.CRC = crc32(data) & 0xffffffff # CRC-32 checksum
76682
028e8e0b03e8 Issue #14371: Support bzip2 in zipfile module.
Martin v. Löwis <martin@v.loewis.de>
parents: 76373
diff changeset
1430 co = _get_compressor(zinfo.compress_type)
028e8e0b03e8 Issue #14371: Support bzip2 in zipfile module.
Martin v. Löwis <martin@v.loewis.de>
parents: 76373
diff changeset
1431 if co:
42900
19196cce1431 Changes preparing for stricter enforcement of bytes vs. str.
Guido van Rossum <guido@python.org>
parents: 42314
diff changeset
1432 data = co.compress(data) + co.flush()
19196cce1431 Changes preparing for stricter enforcement of bytes vs. str.
Guido van Rossum <guido@python.org>
parents: 42314
diff changeset
1433 zinfo.compress_size = len(data) # Compressed size
12197
7f18f979a93a Zip file handling module, by Jim Ahlstrom.
Guido van Rossum <guido@python.org>
parents:
diff changeset
1434 else:
7f18f979a93a Zip file handling module, by Jim Ahlstrom.
Guido van Rossum <guido@python.org>
parents:
diff changeset
1435 zinfo.compress_size = zinfo.file_size
81502
b93848ca7760 Issue #9720: zipfile now writes correct local headers for files larger than 4 GiB.
Serhiy Storchaka <storchaka@gmail.com>
parents: 80500
diff changeset
1436 zip64 = zinfo.file_size > ZIP64_LIMIT or \
86536
34fb83421119 add a filterfunc to zip file.PyZipFile.writepy, issue 19274
Christian Tismer <tismer@stackless.com>
parents: 85814
diff changeset
1437 zinfo.compress_size > ZIP64_LIMIT
81502
b93848ca7760 Issue #9720: zipfile now writes correct local headers for files larger than 4 GiB.
Serhiy Storchaka <storchaka@gmail.com>
parents: 80500
diff changeset
1438 if zip64 and not self._allowZip64:
b93848ca7760 Issue #9720: zipfile now writes correct local headers for files larger than 4 GiB.
Serhiy Storchaka <storchaka@gmail.com>
parents: 80500
diff changeset
1439 raise LargeZipFile("Filesize would require ZIP64 extensions")
b93848ca7760 Issue #9720: zipfile now writes correct local headers for files larger than 4 GiB.
Serhiy Storchaka <storchaka@gmail.com>
parents: 80500
diff changeset
1440 self.fp.write(zinfo.FileHeader(zip64))
42900
19196cce1431 Changes preparing for stricter enforcement of bytes vs. str.
Guido van Rossum <guido@python.org>
parents: 42314
diff changeset
1441 self.fp.write(data)
12197
7f18f979a93a Zip file handling module, by Jim Ahlstrom.
Guido van Rossum <guido@python.org>
parents:
diff changeset
1442 if zinfo.flag_bits & 0x08:
15874
4c01ee0a8073 Whitespace normalization. Top level of Lib now fixed-point for reindent.py!
Tim Peters <tim.peters@gmail.com>
parents: 14975
diff changeset
1443 # Write CRC and file sizes after the file data
81502
b93848ca7760 Issue #9720: zipfile now writes correct local headers for files larger than 4 GiB.
Serhiy Storchaka <storchaka@gmail.com>
parents: 80500
diff changeset
1444 fmt = '<LQQ' if zip64 else '<LLL'
b93848ca7760 Issue #9720: zipfile now writes correct local headers for files larger than 4 GiB.
Serhiy Storchaka <storchaka@gmail.com>
parents: 80500
diff changeset
1445 self.fp.write(struct.pack(fmt, zinfo.CRC, zinfo.compress_size,
86536
34fb83421119 add a filterfunc to zip file.PyZipFile.writepy, issue 19274
Christian Tismer <tismer@stackless.com>
parents: 85814
diff changeset
1446 zinfo.file_size))
81502
b93848ca7760 Issue #9720: zipfile now writes correct local headers for files larger than 4 GiB.
Serhiy Storchaka <storchaka@gmail.com>
parents: 80500
diff changeset
1447 self.fp.flush()
12197
7f18f979a93a Zip file handling module, by Jim Ahlstrom.
Guido van Rossum <guido@python.org>
parents:
diff changeset
1448 self.filelist.append(zinfo)
7f18f979a93a Zip file handling module, by Jim Ahlstrom.
Guido van Rossum <guido@python.org>
parents:
diff changeset
1449 self.NameToInfo[zinfo.filename] = zinfo
7f18f979a93a Zip file handling module, by Jim Ahlstrom.
Guido van Rossum <guido@python.org>
parents:
diff changeset
1450
7f18f979a93a Zip file handling module, by Jim Ahlstrom.
Guido van Rossum <guido@python.org>
parents:
diff changeset
1451 def __del__(self):
14975
27eab8032766 Delay import of py_compile until needed, since is is only used by the
Fred Drake <fdrake@acm.org>
parents: 14933
diff changeset
1452 """Call the "close()" method in case the user forgot."""
21098
82d8413636e7 SF bug 486480: zipfile __del__ is broken
Tim Peters <tim.peters@gmail.com>
parents: 20020
diff changeset
1453 self.close()
12197
7f18f979a93a Zip file handling module, by Jim Ahlstrom.
Guido van Rossum <guido@python.org>
parents:
diff changeset
1454
7f18f979a93a Zip file handling module, by Jim Ahlstrom.
Guido van Rossum <guido@python.org>
parents:
diff changeset
1455 def close(self):
14975
27eab8032766 Delay import of py_compile until needed, since is is only used by the
Fred Drake <fdrake@acm.org>
parents: 14933
diff changeset
1456 """Close the file, and for mode "w" and "a" write the ending
27eab8032766 Delay import of py_compile until needed, since is is only used by the
Fred Drake <fdrake@acm.org>
parents: 14933
diff changeset
1457 records."""
21098
82d8413636e7 SF bug 486480: zipfile __del__ is broken
Tim Peters <tim.peters@gmail.com>
parents: 20020
diff changeset
1458 if self.fp is None:
82d8413636e7 SF bug 486480: zipfile __del__ is broken
Tim Peters <tim.peters@gmail.com>
parents: 20020
diff changeset
1459 return
39442
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36609
diff changeset
1460
80482
d51d95c9ea81 Issue #16408: Fix file descriptors not being closed in error conditions in the zipfile module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76270
diff changeset
1461 try:
d51d95c9ea81 Issue #16408: Fix file descriptors not being closed in error conditions in the zipfile module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76270
diff changeset
1462 if self.mode in ("w", "a") and self._didModify: # write ending records
d51d95c9ea81 Issue #16408: Fix file descriptors not being closed in error conditions in the zipfile module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76270
diff changeset
1463 count = 0
d51d95c9ea81 Issue #16408: Fix file descriptors not being closed in error conditions in the zipfile module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76270
diff changeset
1464 pos1 = self.fp.tell()
d51d95c9ea81 Issue #16408: Fix file descriptors not being closed in error conditions in the zipfile module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76270
diff changeset
1465 for zinfo in self.filelist: # write central directory
d51d95c9ea81 Issue #16408: Fix file descriptors not being closed in error conditions in the zipfile module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76270
diff changeset
1466 count = count + 1
d51d95c9ea81 Issue #16408: Fix file descriptors not being closed in error conditions in the zipfile module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76270
diff changeset
1467 dt = zinfo.date_time
d51d95c9ea81 Issue #16408: Fix file descriptors not being closed in error conditions in the zipfile module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76270
diff changeset
1468 dosdate = (dt[0] - 1980) << 9 | dt[1] << 5 | dt[2]
d51d95c9ea81 Issue #16408: Fix file descriptors not being closed in error conditions in the zipfile module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76270
diff changeset
1469 dostime = dt[3] << 11 | dt[4] << 5 | (dt[5] // 2)
d51d95c9ea81 Issue #16408: Fix file descriptors not being closed in error conditions in the zipfile module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76270
diff changeset
1470 extra = []
d51d95c9ea81 Issue #16408: Fix file descriptors not being closed in error conditions in the zipfile module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76270
diff changeset
1471 if zinfo.file_size > ZIP64_LIMIT \
86536
34fb83421119 add a filterfunc to zip file.PyZipFile.writepy, issue 19274
Christian Tismer <tismer@stackless.com>
parents: 85814
diff changeset
1472 or zinfo.compress_size > ZIP64_LIMIT:
80482
d51d95c9ea81 Issue #16408: Fix file descriptors not being closed in error conditions in the zipfile module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76270
diff changeset
1473 extra.append(zinfo.file_size)
d51d95c9ea81 Issue #16408: Fix file descriptors not being closed in error conditions in the zipfile module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76270
diff changeset
1474 extra.append(zinfo.compress_size)
d51d95c9ea81 Issue #16408: Fix file descriptors not being closed in error conditions in the zipfile module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76270
diff changeset
1475 file_size = 0xffffffff
d51d95c9ea81 Issue #16408: Fix file descriptors not being closed in error conditions in the zipfile module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76270
diff changeset
1476 compress_size = 0xffffffff
d51d95c9ea81 Issue #16408: Fix file descriptors not being closed in error conditions in the zipfile module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76270
diff changeset
1477 else:
d51d95c9ea81 Issue #16408: Fix file descriptors not being closed in error conditions in the zipfile module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76270
diff changeset
1478 file_size = zinfo.file_size
d51d95c9ea81 Issue #16408: Fix file descriptors not being closed in error conditions in the zipfile module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76270
diff changeset
1479 compress_size = zinfo.compress_size
39442
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36609
diff changeset
1480
80482
d51d95c9ea81 Issue #16408: Fix file descriptors not being closed in error conditions in the zipfile module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76270
diff changeset
1481 if zinfo.header_offset > ZIP64_LIMIT:
d51d95c9ea81 Issue #16408: Fix file descriptors not being closed in error conditions in the zipfile module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76270
diff changeset
1482 extra.append(zinfo.header_offset)
d51d95c9ea81 Issue #16408: Fix file descriptors not being closed in error conditions in the zipfile module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76270
diff changeset
1483 header_offset = 0xffffffff
d51d95c9ea81 Issue #16408: Fix file descriptors not being closed in error conditions in the zipfile module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76270
diff changeset
1484 else:
d51d95c9ea81 Issue #16408: Fix file descriptors not being closed in error conditions in the zipfile module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76270
diff changeset
1485 header_offset = zinfo.header_offset
39442
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36609
diff changeset
1486
80482
d51d95c9ea81 Issue #16408: Fix file descriptors not being closed in error conditions in the zipfile module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76270
diff changeset
1487 extra_data = zinfo.extra
80483
27cb1a3d57c8 Issue #16408: Fix file descriptors not being closed in error conditions in the zipfile module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 77631 80482
diff changeset
1488 min_version = 0
80482
d51d95c9ea81 Issue #16408: Fix file descriptors not being closed in error conditions in the zipfile module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76270
diff changeset
1489 if extra:
d51d95c9ea81 Issue #16408: Fix file descriptors not being closed in error conditions in the zipfile module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76270
diff changeset
1490 # Append a ZIP64 field to the extra's
d51d95c9ea81 Issue #16408: Fix file descriptors not being closed in error conditions in the zipfile module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76270
diff changeset
1491 extra_data = struct.pack(
86536
34fb83421119 add a filterfunc to zip file.PyZipFile.writepy, issue 19274
Christian Tismer <tismer@stackless.com>
parents: 85814
diff changeset
1492 '<HH' + 'Q'*len(extra),
34fb83421119 add a filterfunc to zip file.PyZipFile.writepy, issue 19274
Christian Tismer <tismer@stackless.com>
parents: 85814
diff changeset
1493 1, 8*len(extra), *extra) + extra_data
39442
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36609
diff changeset
1494
80483
27cb1a3d57c8 Issue #16408: Fix file descriptors not being closed in error conditions in the zipfile module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 77631 80482
diff changeset
1495 min_version = ZIP64_VERSION
39442
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36609
diff changeset
1496
80483
27cb1a3d57c8 Issue #16408: Fix file descriptors not being closed in error conditions in the zipfile module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 77631 80482
diff changeset
1497 if zinfo.compress_type == ZIP_BZIP2:
27cb1a3d57c8 Issue #16408: Fix file descriptors not being closed in error conditions in the zipfile module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 77631 80482
diff changeset
1498 min_version = max(BZIP2_VERSION, min_version)
27cb1a3d57c8 Issue #16408: Fix file descriptors not being closed in error conditions in the zipfile module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 77631 80482
diff changeset
1499 elif zinfo.compress_type == ZIP_LZMA:
27cb1a3d57c8 Issue #16408: Fix file descriptors not being closed in error conditions in the zipfile module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 77631 80482
diff changeset
1500 min_version = max(LZMA_VERSION, min_version)
76682
028e8e0b03e8 Issue #14371: Support bzip2 in zipfile module.
Martin v. Löwis <martin@v.loewis.de>
parents: 76373
diff changeset
1501
80483
27cb1a3d57c8 Issue #16408: Fix file descriptors not being closed in error conditions in the zipfile module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 77631 80482
diff changeset
1502 extract_version = max(min_version, zinfo.extract_version)
27cb1a3d57c8 Issue #16408: Fix file descriptors not being closed in error conditions in the zipfile module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 77631 80482
diff changeset
1503 create_version = max(min_version, zinfo.create_version)
80482
d51d95c9ea81 Issue #16408: Fix file descriptors not being closed in error conditions in the zipfile module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76270
diff changeset
1504 try:
d51d95c9ea81 Issue #16408: Fix file descriptors not being closed in error conditions in the zipfile module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76270
diff changeset
1505 filename, flag_bits = zinfo._encodeFilenameFlags()
d51d95c9ea81 Issue #16408: Fix file descriptors not being closed in error conditions in the zipfile module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76270
diff changeset
1506 centdir = struct.pack(structCentralDir,
86536
34fb83421119 add a filterfunc to zip file.PyZipFile.writepy, issue 19274
Christian Tismer <tismer@stackless.com>
parents: 85814
diff changeset
1507 stringCentralDir, create_version,
34fb83421119 add a filterfunc to zip file.PyZipFile.writepy, issue 19274
Christian Tismer <tismer@stackless.com>
parents: 85814
diff changeset
1508 zinfo.create_system, extract_version, zinfo.reserved,
34fb83421119 add a filterfunc to zip file.PyZipFile.writepy, issue 19274
Christian Tismer <tismer@stackless.com>
parents: 85814
diff changeset
1509 flag_bits, zinfo.compress_type, dostime, dosdate,
34fb83421119 add a filterfunc to zip file.PyZipFile.writepy, issue 19274
Christian Tismer <tismer@stackless.com>
parents: 85814
diff changeset
1510 zinfo.CRC, compress_size, file_size,
34fb83421119 add a filterfunc to zip file.PyZipFile.writepy, issue 19274
Christian Tismer <tismer@stackless.com>
parents: 85814
diff changeset
1511 len(filename), len(extra_data), len(zinfo.comment),
34fb83421119 add a filterfunc to zip file.PyZipFile.writepy, issue 19274
Christian Tismer <tismer@stackless.com>
parents: 85814
diff changeset
1512 0, zinfo.internal_attr, zinfo.external_attr,
34fb83421119 add a filterfunc to zip file.PyZipFile.writepy, issue 19274
Christian Tismer <tismer@stackless.com>
parents: 85814
diff changeset
1513 header_offset)
80482
d51d95c9ea81 Issue #16408: Fix file descriptors not being closed in error conditions in the zipfile module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76270
diff changeset
1514 except DeprecationWarning:
d51d95c9ea81 Issue #16408: Fix file descriptors not being closed in error conditions in the zipfile module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76270
diff changeset
1515 print((structCentralDir, stringCentralDir, create_version,
86536
34fb83421119 add a filterfunc to zip file.PyZipFile.writepy, issue 19274
Christian Tismer <tismer@stackless.com>
parents: 85814
diff changeset
1516 zinfo.create_system, extract_version, zinfo.reserved,
34fb83421119 add a filterfunc to zip file.PyZipFile.writepy, issue 19274
Christian Tismer <tismer@stackless.com>
parents: 85814
diff changeset
1517 zinfo.flag_bits, zinfo.compress_type, dostime, dosdate,
34fb83421119 add a filterfunc to zip file.PyZipFile.writepy, issue 19274
Christian Tismer <tismer@stackless.com>
parents: 85814
diff changeset
1518 zinfo.CRC, compress_size, file_size,
34fb83421119 add a filterfunc to zip file.PyZipFile.writepy, issue 19274
Christian Tismer <tismer@stackless.com>
parents: 85814
diff changeset
1519 len(zinfo.filename), len(extra_data), len(zinfo.comment),
34fb83421119 add a filterfunc to zip file.PyZipFile.writepy, issue 19274
Christian Tismer <tismer@stackless.com>
parents: 85814
diff changeset
1520 0, zinfo.internal_attr, zinfo.external_attr,
34fb83421119 add a filterfunc to zip file.PyZipFile.writepy, issue 19274
Christian Tismer <tismer@stackless.com>
parents: 85814
diff changeset
1521 header_offset), file=sys.stderr)
80482
d51d95c9ea81 Issue #16408: Fix file descriptors not being closed in error conditions in the zipfile module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76270
diff changeset
1522 raise
d51d95c9ea81 Issue #16408: Fix file descriptors not being closed in error conditions in the zipfile module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76270
diff changeset
1523 self.fp.write(centdir)
d51d95c9ea81 Issue #16408: Fix file descriptors not being closed in error conditions in the zipfile module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76270
diff changeset
1524 self.fp.write(filename)
d51d95c9ea81 Issue #16408: Fix file descriptors not being closed in error conditions in the zipfile module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76270
diff changeset
1525 self.fp.write(extra_data)
d51d95c9ea81 Issue #16408: Fix file descriptors not being closed in error conditions in the zipfile module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76270
diff changeset
1526 self.fp.write(zinfo.comment)
39442
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36609
diff changeset
1527
80482
d51d95c9ea81 Issue #16408: Fix file descriptors not being closed in error conditions in the zipfile module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76270
diff changeset
1528 pos2 = self.fp.tell()
d51d95c9ea81 Issue #16408: Fix file descriptors not being closed in error conditions in the zipfile module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76270
diff changeset
1529 # Write end-of-zip-archive record
d51d95c9ea81 Issue #16408: Fix file descriptors not being closed in error conditions in the zipfile module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76270
diff changeset
1530 centDirCount = count
d51d95c9ea81 Issue #16408: Fix file descriptors not being closed in error conditions in the zipfile module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76270
diff changeset
1531 centDirSize = pos2 - pos1
d51d95c9ea81 Issue #16408: Fix file descriptors not being closed in error conditions in the zipfile module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76270
diff changeset
1532 centDirOffset = pos1
d51d95c9ea81 Issue #16408: Fix file descriptors not being closed in error conditions in the zipfile module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76270
diff changeset
1533 if (centDirCount >= ZIP_FILECOUNT_LIMIT or
d51d95c9ea81 Issue #16408: Fix file descriptors not being closed in error conditions in the zipfile module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76270
diff changeset
1534 centDirOffset > ZIP64_LIMIT or
d51d95c9ea81 Issue #16408: Fix file descriptors not being closed in error conditions in the zipfile module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76270
diff changeset
1535 centDirSize > ZIP64_LIMIT):
d51d95c9ea81 Issue #16408: Fix file descriptors not being closed in error conditions in the zipfile module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76270
diff changeset
1536 # Need to write the ZIP64 end-of-archive records
d51d95c9ea81 Issue #16408: Fix file descriptors not being closed in error conditions in the zipfile module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76270
diff changeset
1537 zip64endrec = struct.pack(
86536
34fb83421119 add a filterfunc to zip file.PyZipFile.writepy, issue 19274
Christian Tismer <tismer@stackless.com>
parents: 85814
diff changeset
1538 structEndArchive64, stringEndArchive64,
34fb83421119 add a filterfunc to zip file.PyZipFile.writepy, issue 19274
Christian Tismer <tismer@stackless.com>
parents: 85814
diff changeset
1539 44, 45, 45, 0, 0, centDirCount, centDirCount,
34fb83421119 add a filterfunc to zip file.PyZipFile.writepy, issue 19274
Christian Tismer <tismer@stackless.com>
parents: 85814
diff changeset
1540 centDirSize, centDirOffset)
80482
d51d95c9ea81 Issue #16408: Fix file descriptors not being closed in error conditions in the zipfile module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76270
diff changeset
1541 self.fp.write(zip64endrec)
39442
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36609
diff changeset
1542
80482
d51d95c9ea81 Issue #16408: Fix file descriptors not being closed in error conditions in the zipfile module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76270
diff changeset
1543 zip64locrec = struct.pack(
86536
34fb83421119 add a filterfunc to zip file.PyZipFile.writepy, issue 19274
Christian Tismer <tismer@stackless.com>
parents: 85814
diff changeset
1544 structEndArchive64Locator,
34fb83421119 add a filterfunc to zip file.PyZipFile.writepy, issue 19274
Christian Tismer <tismer@stackless.com>
parents: 85814
diff changeset
1545 stringEndArchive64Locator, 0, pos2, 1)
80482
d51d95c9ea81 Issue #16408: Fix file descriptors not being closed in error conditions in the zipfile module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76270
diff changeset
1546 self.fp.write(zip64locrec)
d51d95c9ea81 Issue #16408: Fix file descriptors not being closed in error conditions in the zipfile module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76270
diff changeset
1547 centDirCount = min(centDirCount, 0xFFFF)
d51d95c9ea81 Issue #16408: Fix file descriptors not being closed in error conditions in the zipfile module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76270
diff changeset
1548 centDirSize = min(centDirSize, 0xFFFFFFFF)
d51d95c9ea81 Issue #16408: Fix file descriptors not being closed in error conditions in the zipfile module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76270
diff changeset
1549 centDirOffset = min(centDirOffset, 0xFFFFFFFF)
39442
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36609
diff changeset
1550
80482
d51d95c9ea81 Issue #16408: Fix file descriptors not being closed in error conditions in the zipfile module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76270
diff changeset
1551 endrec = struct.pack(structEndArchive, stringEndArchive,
86536
34fb83421119 add a filterfunc to zip file.PyZipFile.writepy, issue 19274
Christian Tismer <tismer@stackless.com>
parents: 85814
diff changeset
1552 0, 0, centDirCount, centDirCount,
34fb83421119 add a filterfunc to zip file.PyZipFile.writepy, issue 19274
Christian Tismer <tismer@stackless.com>
parents: 85814
diff changeset
1553 centDirSize, centDirOffset, len(self._comment))
80482
d51d95c9ea81 Issue #16408: Fix file descriptors not being closed in error conditions in the zipfile module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76270
diff changeset
1554 self.fp.write(endrec)
d51d95c9ea81 Issue #16408: Fix file descriptors not being closed in error conditions in the zipfile module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76270
diff changeset
1555 self.fp.write(self._comment)
d51d95c9ea81 Issue #16408: Fix file descriptors not being closed in error conditions in the zipfile module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76270
diff changeset
1556 self.fp.flush()
d51d95c9ea81 Issue #16408: Fix file descriptors not being closed in error conditions in the zipfile module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76270
diff changeset
1557 finally:
d51d95c9ea81 Issue #16408: Fix file descriptors not being closed in error conditions in the zipfile module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76270
diff changeset
1558 fp = self.fp
d51d95c9ea81 Issue #16408: Fix file descriptors not being closed in error conditions in the zipfile module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76270
diff changeset
1559 self.fp = None
d51d95c9ea81 Issue #16408: Fix file descriptors not being closed in error conditions in the zipfile module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76270
diff changeset
1560 if not self._filePassed:
d51d95c9ea81 Issue #16408: Fix file descriptors not being closed in error conditions in the zipfile module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76270
diff changeset
1561 fp.close()
12197
7f18f979a93a Zip file handling module, by Jim Ahlstrom.
Guido van Rossum <guido@python.org>
parents:
diff changeset
1562
7f18f979a93a Zip file handling module, by Jim Ahlstrom.
Guido van Rossum <guido@python.org>
parents:
diff changeset
1563
7f18f979a93a Zip file handling module, by Jim Ahlstrom.
Guido van Rossum <guido@python.org>
parents:
diff changeset
1564 class PyZipFile(ZipFile):
14975
27eab8032766 Delay import of py_compile until needed, since is is only used by the
Fred Drake <fdrake@acm.org>
parents: 14933
diff changeset
1565 """Class to create ZIP archives with Python library files and packages."""
27eab8032766 Delay import of py_compile until needed, since is is only used by the
Fred Drake <fdrake@acm.org>
parents: 14933
diff changeset
1566
66685
713c6b6ca5ce Add an "optimize" parameter to compile() to control the optimization level, and provide an interface to it in py_compile, compileall and PyZipFile.
Georg Brandl <georg@python.org>
parents: 66409
diff changeset
1567 def __init__(self, file, mode="r", compression=ZIP_STORED,
87417
271cc3660445 Issue #17201: ZIP64 extensions now are enabled by default.
Serhiy Storchaka <storchaka@gmail.com>
parents: 86555
diff changeset
1568 allowZip64=True, optimize=-1):
66685
713c6b6ca5ce Add an "optimize" parameter to compile() to control the optimization level, and provide an interface to it in py_compile, compileall and PyZipFile.
Georg Brandl <georg@python.org>
parents: 66409
diff changeset
1569 ZipFile.__init__(self, file, mode=mode, compression=compression,
713c6b6ca5ce Add an "optimize" parameter to compile() to control the optimization level, and provide an interface to it in py_compile, compileall and PyZipFile.
Georg Brandl <georg@python.org>
parents: 66409
diff changeset
1570 allowZip64=allowZip64)
713c6b6ca5ce Add an "optimize" parameter to compile() to control the optimization level, and provide an interface to it in py_compile, compileall and PyZipFile.
Georg Brandl <georg@python.org>
parents: 66409
diff changeset
1571 self._optimize = optimize
713c6b6ca5ce Add an "optimize" parameter to compile() to control the optimization level, and provide an interface to it in py_compile, compileall and PyZipFile.
Georg Brandl <georg@python.org>
parents: 66409
diff changeset
1572
86536
34fb83421119 add a filterfunc to zip file.PyZipFile.writepy, issue 19274
Christian Tismer <tismer@stackless.com>
parents: 85814
diff changeset
1573 def writepy(self, pathname, basename="", filterfunc=None):
12197
7f18f979a93a Zip file handling module, by Jim Ahlstrom.
Guido van Rossum <guido@python.org>
parents:
diff changeset
1574 """Add all files from "pathname" to the ZIP archive.
7f18f979a93a Zip file handling module, by Jim Ahlstrom.
Guido van Rossum <guido@python.org>
parents:
diff changeset
1575
14975
27eab8032766 Delay import of py_compile until needed, since is is only used by the
Fred Drake <fdrake@acm.org>
parents: 14933
diff changeset
1576 If pathname is a package directory, search the directory and
27eab8032766 Delay import of py_compile until needed, since is is only used by the
Fred Drake <fdrake@acm.org>
parents: 14933
diff changeset
1577 all package subdirectories recursively for all *.py and enter
27eab8032766 Delay import of py_compile until needed, since is is only used by the
Fred Drake <fdrake@acm.org>
parents: 14933
diff changeset
1578 the modules into the archive. If pathname is a plain
27eab8032766 Delay import of py_compile until needed, since is is only used by the
Fred Drake <fdrake@acm.org>
parents: 14933
diff changeset
1579 directory, listdir *.py and enter all modules. Else, pathname
27eab8032766 Delay import of py_compile until needed, since is is only used by the
Fred Drake <fdrake@acm.org>
parents: 14933
diff changeset
1580 must be a Python *.py file and the module will be put into the
27eab8032766 Delay import of py_compile until needed, since is is only used by the
Fred Drake <fdrake@acm.org>
parents: 14933
diff changeset
1581 archive. Added modules are always module.pyo or module.pyc.
27eab8032766 Delay import of py_compile until needed, since is is only used by the
Fred Drake <fdrake@acm.org>
parents: 14933
diff changeset
1582 This method will compile the module.py into module.pyc if
27eab8032766 Delay import of py_compile until needed, since is is only used by the
Fred Drake <fdrake@acm.org>
parents: 14933
diff changeset
1583 necessary.
86536
34fb83421119 add a filterfunc to zip file.PyZipFile.writepy, issue 19274
Christian Tismer <tismer@stackless.com>
parents: 85814
diff changeset
1584 If filterfunc(pathname) is given, it is called with every argument.
34fb83421119 add a filterfunc to zip file.PyZipFile.writepy, issue 19274
Christian Tismer <tismer@stackless.com>
parents: 85814
diff changeset
1585 When it is False, the file or directory is skipped.
14975
27eab8032766 Delay import of py_compile until needed, since is is only used by the
Fred Drake <fdrake@acm.org>
parents: 14933
diff changeset
1586 """
86536
34fb83421119 add a filterfunc to zip file.PyZipFile.writepy, issue 19274
Christian Tismer <tismer@stackless.com>
parents: 85814
diff changeset
1587 if filterfunc and not filterfunc(pathname):
34fb83421119 add a filterfunc to zip file.PyZipFile.writepy, issue 19274
Christian Tismer <tismer@stackless.com>
parents: 85814
diff changeset
1588 if self.debug:
86555
4f1121ae1cb5 add filtering of individual files to PyZipFile
Christian Tismer <tismer@stackless.com>
parents: 86536
diff changeset
1589 label = 'path' if os.path.isdir(pathname) else 'file'
4f1121ae1cb5 add filtering of individual files to PyZipFile
Christian Tismer <tismer@stackless.com>
parents: 86536
diff changeset
1590 print('%s "%s" skipped by filterfunc' % (label, pathname))
86536
34fb83421119 add a filterfunc to zip file.PyZipFile.writepy, issue 19274
Christian Tismer <tismer@stackless.com>
parents: 85814
diff changeset
1591 return
12197
7f18f979a93a Zip file handling module, by Jim Ahlstrom.
Guido van Rossum <guido@python.org>
parents:
diff changeset
1592 dir, name = os.path.split(pathname)
7f18f979a93a Zip file handling module, by Jim Ahlstrom.
Guido van Rossum <guido@python.org>
parents:
diff changeset
1593 if os.path.isdir(pathname):
7f18f979a93a Zip file handling module, by Jim Ahlstrom.
Guido van Rossum <guido@python.org>
parents:
diff changeset
1594 initname = os.path.join(pathname, "__init__.py")
7f18f979a93a Zip file handling module, by Jim Ahlstrom.
Guido van Rossum <guido@python.org>
parents:
diff changeset
1595 if os.path.isfile(initname):
7f18f979a93a Zip file handling module, by Jim Ahlstrom.
Guido van Rossum <guido@python.org>
parents:
diff changeset
1596 # This is a package directory, add it
7f18f979a93a Zip file handling module, by Jim Ahlstrom.
Guido van Rossum <guido@python.org>
parents:
diff changeset
1597 if basename:
7f18f979a93a Zip file handling module, by Jim Ahlstrom.
Guido van Rossum <guido@python.org>
parents:
diff changeset
1598 basename = "%s/%s" % (basename, name)
7f18f979a93a Zip file handling module, by Jim Ahlstrom.
Guido van Rossum <guido@python.org>
parents:
diff changeset
1599 else:
7f18f979a93a Zip file handling module, by Jim Ahlstrom.
Guido van Rossum <guido@python.org>
parents:
diff changeset
1600 basename = name
7f18f979a93a Zip file handling module, by Jim Ahlstrom.
Guido van Rossum <guido@python.org>
parents:
diff changeset
1601 if self.debug:
40775
4cdf21a0dbbc Fix most trivially-findable print statements.
Guido van Rossum <guido@python.org>
parents: 40644
diff changeset
1602 print("Adding package in", pathname, "as", basename)
12197
7f18f979a93a Zip file handling module, by Jim Ahlstrom.
Guido van Rossum <guido@python.org>
parents:
diff changeset
1603 fname, arcname = self._get_codename(initname[0:-3], basename)
7f18f979a93a Zip file handling module, by Jim Ahlstrom.
Guido van Rossum <guido@python.org>
parents:
diff changeset
1604 if self.debug:
40775
4cdf21a0dbbc Fix most trivially-findable print statements.
Guido van Rossum <guido@python.org>
parents: 40644
diff changeset
1605 print("Adding", arcname)
12197
7f18f979a93a Zip file handling module, by Jim Ahlstrom.
Guido van Rossum <guido@python.org>
parents:
diff changeset
1606 self.write(fname, arcname)
7f18f979a93a Zip file handling module, by Jim Ahlstrom.
Guido van Rossum <guido@python.org>
parents:
diff changeset
1607 dirlist = os.listdir(pathname)
7f18f979a93a Zip file handling module, by Jim Ahlstrom.
Guido van Rossum <guido@python.org>
parents:
diff changeset
1608 dirlist.remove("__init__.py")
7f18f979a93a Zip file handling module, by Jim Ahlstrom.
Guido van Rossum <guido@python.org>
parents:
diff changeset
1609 # Add all *.py files and package subdirectories
7f18f979a93a Zip file handling module, by Jim Ahlstrom.
Guido van Rossum <guido@python.org>
parents:
diff changeset
1610 for filename in dirlist:
7f18f979a93a Zip file handling module, by Jim Ahlstrom.
Guido van Rossum <guido@python.org>
parents:
diff changeset
1611 path = os.path.join(pathname, filename)
7f18f979a93a Zip file handling module, by Jim Ahlstrom.
Guido van Rossum <guido@python.org>
parents:
diff changeset
1612 root, ext = os.path.splitext(filename)
7f18f979a93a Zip file handling module, by Jim Ahlstrom.
Guido van Rossum <guido@python.org>
parents:
diff changeset
1613 if os.path.isdir(path):
7f18f979a93a Zip file handling module, by Jim Ahlstrom.
Guido van Rossum <guido@python.org>
parents:
diff changeset
1614 if os.path.isfile(os.path.join(path, "__init__.py")):
7f18f979a93a Zip file handling module, by Jim Ahlstrom.
Guido van Rossum <guido@python.org>
parents:
diff changeset
1615 # This is a package directory, add it
86536
34fb83421119 add a filterfunc to zip file.PyZipFile.writepy, issue 19274
Christian Tismer <tismer@stackless.com>
parents: 85814
diff changeset
1616 self.writepy(path, basename,
34fb83421119 add a filterfunc to zip file.PyZipFile.writepy, issue 19274
Christian Tismer <tismer@stackless.com>
parents: 85814
diff changeset
1617 filterfunc=filterfunc) # Recursive call
12197
7f18f979a93a Zip file handling module, by Jim Ahlstrom.
Guido van Rossum <guido@python.org>
parents:
diff changeset
1618 elif ext == ".py":
86555
4f1121ae1cb5 add filtering of individual files to PyZipFile
Christian Tismer <tismer@stackless.com>
parents: 86536
diff changeset
1619 if filterfunc and not filterfunc(path):
4f1121ae1cb5 add filtering of individual files to PyZipFile
Christian Tismer <tismer@stackless.com>
parents: 86536
diff changeset
1620 if self.debug:
4f1121ae1cb5 add filtering of individual files to PyZipFile
Christian Tismer <tismer@stackless.com>
parents: 86536
diff changeset
1621 print('file "%s" skipped by filterfunc' % path)
4f1121ae1cb5 add filtering of individual files to PyZipFile
Christian Tismer <tismer@stackless.com>
parents: 86536
diff changeset
1622 continue
12197
7f18f979a93a Zip file handling module, by Jim Ahlstrom.
Guido van Rossum <guido@python.org>
parents:
diff changeset
1623 fname, arcname = self._get_codename(path[0:-3],
86536
34fb83421119 add a filterfunc to zip file.PyZipFile.writepy, issue 19274
Christian Tismer <tismer@stackless.com>
parents: 85814
diff changeset
1624 basename)
12197
7f18f979a93a Zip file handling module, by Jim Ahlstrom.
Guido van Rossum <guido@python.org>
parents:
diff changeset
1625 if self.debug:
40775
4cdf21a0dbbc Fix most trivially-findable print statements.
Guido van Rossum <guido@python.org>
parents: 40644
diff changeset
1626 print("Adding", arcname)
12197
7f18f979a93a Zip file handling module, by Jim Ahlstrom.
Guido van Rossum <guido@python.org>
parents:
diff changeset
1627 self.write(fname, arcname)
7f18f979a93a Zip file handling module, by Jim Ahlstrom.
Guido van Rossum <guido@python.org>
parents:
diff changeset
1628 else:
7f18f979a93a Zip file handling module, by Jim Ahlstrom.
Guido van Rossum <guido@python.org>
parents:
diff changeset
1629 # This is NOT a package directory, add its files at top level
7f18f979a93a Zip file handling module, by Jim Ahlstrom.
Guido van Rossum <guido@python.org>
parents:
diff changeset
1630 if self.debug:
40775
4cdf21a0dbbc Fix most trivially-findable print statements.
Guido van Rossum <guido@python.org>
parents: 40644
diff changeset
1631 print("Adding files from directory", pathname)
12197
7f18f979a93a Zip file handling module, by Jim Ahlstrom.
Guido van Rossum <guido@python.org>
parents:
diff changeset
1632 for filename in os.listdir(pathname):
7f18f979a93a Zip file handling module, by Jim Ahlstrom.
Guido van Rossum <guido@python.org>
parents:
diff changeset
1633 path = os.path.join(pathname, filename)
7f18f979a93a Zip file handling module, by Jim Ahlstrom.
Guido van Rossum <guido@python.org>
parents:
diff changeset
1634 root, ext = os.path.splitext(filename)
7f18f979a93a Zip file handling module, by Jim Ahlstrom.
Guido van Rossum <guido@python.org>
parents:
diff changeset
1635 if ext == ".py":
86555
4f1121ae1cb5 add filtering of individual files to PyZipFile
Christian Tismer <tismer@stackless.com>
parents: 86536
diff changeset
1636 if filterfunc and not filterfunc(path):
4f1121ae1cb5 add filtering of individual files to PyZipFile
Christian Tismer <tismer@stackless.com>
parents: 86536
diff changeset
1637 if self.debug:
4f1121ae1cb5 add filtering of individual files to PyZipFile
Christian Tismer <tismer@stackless.com>
parents: 86536
diff changeset
1638 print('file "%s" skipped by filterfunc' % path)
4f1121ae1cb5 add filtering of individual files to PyZipFile
Christian Tismer <tismer@stackless.com>
parents: 86536
diff changeset
1639 continue
12197
7f18f979a93a Zip file handling module, by Jim Ahlstrom.
Guido van Rossum <guido@python.org>
parents:
diff changeset
1640 fname, arcname = self._get_codename(path[0:-3],
86536
34fb83421119 add a filterfunc to zip file.PyZipFile.writepy, issue 19274
Christian Tismer <tismer@stackless.com>
parents: 85814
diff changeset
1641 basename)
12197
7f18f979a93a Zip file handling module, by Jim Ahlstrom.
Guido van Rossum <guido@python.org>
parents:
diff changeset
1642 if self.debug:
40775
4cdf21a0dbbc Fix most trivially-findable print statements.
Guido van Rossum <guido@python.org>
parents: 40644
diff changeset
1643 print("Adding", arcname)
12197
7f18f979a93a Zip file handling module, by Jim Ahlstrom.
Guido van Rossum <guido@python.org>
parents:
diff changeset
1644 self.write(fname, arcname)
7f18f979a93a Zip file handling module, by Jim Ahlstrom.
Guido van Rossum <guido@python.org>
parents:
diff changeset
1645 else:
7f18f979a93a Zip file handling module, by Jim Ahlstrom.
Guido van Rossum <guido@python.org>
parents:
diff changeset
1646 if pathname[-3:] != ".py":
43020
907a45df1295 Raise statement normalization in Lib/.
Collin Winter <collinw@gmail.com>
parents: 43005
diff changeset
1647 raise RuntimeError(
86536
34fb83421119 add a filterfunc to zip file.PyZipFile.writepy, issue 19274
Christian Tismer <tismer@stackless.com>
parents: 85814
diff changeset
1648 'Files added with writepy() must end with ".py"')
12197
7f18f979a93a Zip file handling module, by Jim Ahlstrom.
Guido van Rossum <guido@python.org>
parents:
diff changeset
1649 fname, arcname = self._get_codename(pathname[0:-3], basename)
7f18f979a93a Zip file handling module, by Jim Ahlstrom.
Guido van Rossum <guido@python.org>
parents:
diff changeset
1650 if self.debug:
40775
4cdf21a0dbbc Fix most trivially-findable print statements.
Guido van Rossum <guido@python.org>
parents: 40644
diff changeset
1651 print("Adding file", arcname)
12197
7f18f979a93a Zip file handling module, by Jim Ahlstrom.
Guido van Rossum <guido@python.org>
parents:
diff changeset
1652 self.write(fname, arcname)
7f18f979a93a Zip file handling module, by Jim Ahlstrom.
Guido van Rossum <guido@python.org>
parents:
diff changeset
1653
7f18f979a93a Zip file handling module, by Jim Ahlstrom.
Guido van Rossum <guido@python.org>
parents:
diff changeset
1654 def _get_codename(self, pathname, basename):
7f18f979a93a Zip file handling module, by Jim Ahlstrom.
Guido van Rossum <guido@python.org>
parents:
diff changeset
1655 """Return (filename, archivename) for the path.
7f18f979a93a Zip file handling module, by Jim Ahlstrom.
Guido van Rossum <guido@python.org>
parents:
diff changeset
1656
14975
27eab8032766 Delay import of py_compile until needed, since is is only used by the
Fred Drake <fdrake@acm.org>
parents: 14933
diff changeset
1657 Given a module name path, return the correct file path and
27eab8032766 Delay import of py_compile until needed, since is is only used by the
Fred Drake <fdrake@acm.org>
parents: 14933
diff changeset
1658 archive name, compiling if necessary. For example, given
27eab8032766 Delay import of py_compile until needed, since is is only used by the
Fred Drake <fdrake@acm.org>
parents: 14933
diff changeset
1659 /python/lib/string, return (/python/lib/string.pyc, string).
27eab8032766 Delay import of py_compile until needed, since is is only used by the
Fred Drake <fdrake@acm.org>
parents: 14933
diff changeset
1660 """
66685
713c6b6ca5ce Add an "optimize" parameter to compile() to control the optimization level, and provide an interface to it in py_compile, compileall and PyZipFile.
Georg Brandl <georg@python.org>
parents: 66409
diff changeset
1661 def _compile(file, optimize=-1):
713c6b6ca5ce Add an "optimize" parameter to compile() to control the optimization level, and provide an interface to it in py_compile, compileall and PyZipFile.
Georg Brandl <georg@python.org>
parents: 66409
diff changeset
1662 import py_compile
713c6b6ca5ce Add an "optimize" parameter to compile() to control the optimization level, and provide an interface to it in py_compile, compileall and PyZipFile.
Georg Brandl <georg@python.org>
parents: 66409
diff changeset
1663 if self.debug:
713c6b6ca5ce Add an "optimize" parameter to compile() to control the optimization level, and provide an interface to it in py_compile, compileall and PyZipFile.
Georg Brandl <georg@python.org>
parents: 66409
diff changeset
1664 print("Compiling", file)
713c6b6ca5ce Add an "optimize" parameter to compile() to control the optimization level, and provide an interface to it in py_compile, compileall and PyZipFile.
Georg Brandl <georg@python.org>
parents: 66409
diff changeset
1665 try:
713c6b6ca5ce Add an "optimize" parameter to compile() to control the optimization level, and provide an interface to it in py_compile, compileall and PyZipFile.
Georg Brandl <georg@python.org>
parents: 66409
diff changeset
1666 py_compile.compile(file, doraise=True, optimize=optimize)
81828
3a1ac42435f9 Issue #12004: Fix an internal error in PyZipFile when writing an invalid
Serhiy Storchaka <storchaka@gmail.com>
parents: 81502
diff changeset
1667 except py_compile.PyCompileError as err:
66685
713c6b6ca5ce Add an "optimize" parameter to compile() to control the optimization level, and provide an interface to it in py_compile, compileall and PyZipFile.
Georg Brandl <georg@python.org>
parents: 66409
diff changeset
1668 print(err.msg)
713c6b6ca5ce Add an "optimize" parameter to compile() to control the optimization level, and provide an interface to it in py_compile, compileall and PyZipFile.
Georg Brandl <georg@python.org>
parents: 66409
diff changeset
1669 return False
713c6b6ca5ce Add an "optimize" parameter to compile() to control the optimization level, and provide an interface to it in py_compile, compileall and PyZipFile.
Georg Brandl <georg@python.org>
parents: 66409
diff changeset
1670 return True
713c6b6ca5ce Add an "optimize" parameter to compile() to control the optimization level, and provide an interface to it in py_compile, compileall and PyZipFile.
Georg Brandl <georg@python.org>
parents: 66409
diff changeset
1671
12197
7f18f979a93a Zip file handling module, by Jim Ahlstrom.
Guido van Rossum <guido@python.org>
parents:
diff changeset
1672 file_py = pathname + ".py"
7f18f979a93a Zip file handling module, by Jim Ahlstrom.
Guido van Rossum <guido@python.org>
parents:
diff changeset
1673 file_pyc = pathname + ".pyc"
7f18f979a93a Zip file handling module, by Jim Ahlstrom.
Guido van Rossum <guido@python.org>
parents:
diff changeset
1674 file_pyo = pathname + ".pyo"
84155
f96eb1dc335f Issue #17177: Stop using imp in zipfile
Brett Cannon <brett@python.org>
parents: 84106
diff changeset
1675 pycache_pyc = importlib.util.cache_from_source(file_py, True)
f96eb1dc335f Issue #17177: Stop using imp in zipfile
Brett Cannon <brett@python.org>
parents: 84106
diff changeset
1676 pycache_pyo = importlib.util.cache_from_source(file_py, False)
66685
713c6b6ca5ce Add an "optimize" parameter to compile() to control the optimization level, and provide an interface to it in py_compile, compileall and PyZipFile.
Georg Brandl <georg@python.org>
parents: 66409
diff changeset
1677 if self._optimize == -1:
713c6b6ca5ce Add an "optimize" parameter to compile() to control the optimization level, and provide an interface to it in py_compile, compileall and PyZipFile.
Georg Brandl <georg@python.org>
parents: 66409
diff changeset
1678 # legacy mode: use whatever file is present
713c6b6ca5ce Add an "optimize" parameter to compile() to control the optimization level, and provide an interface to it in py_compile, compileall and PyZipFile.
Georg Brandl <georg@python.org>
parents: 66409
diff changeset
1679 if (os.path.isfile(file_pyo) and
713c6b6ca5ce Add an "optimize" parameter to compile() to control the optimization level, and provide an interface to it in py_compile, compileall and PyZipFile.
Georg Brandl <georg@python.org>
parents: 66409
diff changeset
1680 os.stat(file_pyo).st_mtime >= os.stat(file_py).st_mtime):
713c6b6ca5ce Add an "optimize" parameter to compile() to control the optimization level, and provide an interface to it in py_compile, compileall and PyZipFile.
Georg Brandl <georg@python.org>
parents: 66409
diff changeset
1681 # Use .pyo file.
713c6b6ca5ce Add an "optimize" parameter to compile() to control the optimization level, and provide an interface to it in py_compile, compileall and PyZipFile.
Georg Brandl <georg@python.org>
parents: 66409
diff changeset
1682 arcname = fname = file_pyo
713c6b6ca5ce Add an "optimize" parameter to compile() to control the optimization level, and provide an interface to it in py_compile, compileall and PyZipFile.
Georg Brandl <georg@python.org>
parents: 66409
diff changeset
1683 elif (os.path.isfile(file_pyc) and
713c6b6ca5ce Add an "optimize" parameter to compile() to control the optimization level, and provide an interface to it in py_compile, compileall and PyZipFile.
Georg Brandl <georg@python.org>
parents: 66409
diff changeset
1684 os.stat(file_pyc).st_mtime >= os.stat(file_py).st_mtime):
713c6b6ca5ce Add an "optimize" parameter to compile() to control the optimization level, and provide an interface to it in py_compile, compileall and PyZipFile.
Georg Brandl <georg@python.org>
parents: 66409
diff changeset
1685 # Use .pyc file.
713c6b6ca5ce Add an "optimize" parameter to compile() to control the optimization level, and provide an interface to it in py_compile, compileall and PyZipFile.
Georg Brandl <georg@python.org>
parents: 66409
diff changeset
1686 arcname = fname = file_pyc
713c6b6ca5ce Add an "optimize" parameter to compile() to control the optimization level, and provide an interface to it in py_compile, compileall and PyZipFile.
Georg Brandl <georg@python.org>
parents: 66409
diff changeset
1687 elif (os.path.isfile(pycache_pyc) and
713c6b6ca5ce Add an "optimize" parameter to compile() to control the optimization level, and provide an interface to it in py_compile, compileall and PyZipFile.
Georg Brandl <georg@python.org>
parents: 66409
diff changeset
1688 os.stat(pycache_pyc).st_mtime >= os.stat(file_py).st_mtime):
713c6b6ca5ce Add an "optimize" parameter to compile() to control the optimization level, and provide an interface to it in py_compile, compileall and PyZipFile.
Georg Brandl <georg@python.org>
parents: 66409
diff changeset
1689 # Use the __pycache__/*.pyc file, but write it to the legacy pyc
713c6b6ca5ce Add an "optimize" parameter to compile() to control the optimization level, and provide an interface to it in py_compile, compileall and PyZipFile.
Georg Brandl <georg@python.org>
parents: 66409
diff changeset
1690 # file name in the archive.
713c6b6ca5ce Add an "optimize" parameter to compile() to control the optimization level, and provide an interface to it in py_compile, compileall and PyZipFile.
Georg Brandl <georg@python.org>
parents: 66409
diff changeset
1691 fname = pycache_pyc
713c6b6ca5ce Add an "optimize" parameter to compile() to control the optimization level, and provide an interface to it in py_compile, compileall and PyZipFile.
Georg Brandl <georg@python.org>
parents: 66409
diff changeset
1692 arcname = file_pyc
713c6b6ca5ce Add an "optimize" parameter to compile() to control the optimization level, and provide an interface to it in py_compile, compileall and PyZipFile.
Georg Brandl <georg@python.org>
parents: 66409
diff changeset
1693 elif (os.path.isfile(pycache_pyo) and
713c6b6ca5ce Add an "optimize" parameter to compile() to control the optimization level, and provide an interface to it in py_compile, compileall and PyZipFile.
Georg Brandl <georg@python.org>
parents: 66409
diff changeset
1694 os.stat(pycache_pyo).st_mtime >= os.stat(file_py).st_mtime):
713c6b6ca5ce Add an "optimize" parameter to compile() to control the optimization level, and provide an interface to it in py_compile, compileall and PyZipFile.
Georg Brandl <georg@python.org>
parents: 66409
diff changeset
1695 # Use the __pycache__/*.pyo file, but write it to the legacy pyo
713c6b6ca5ce Add an "optimize" parameter to compile() to control the optimization level, and provide an interface to it in py_compile, compileall and PyZipFile.
Georg Brandl <georg@python.org>
parents: 66409
diff changeset
1696 # file name in the archive.
713c6b6ca5ce Add an "optimize" parameter to compile() to control the optimization level, and provide an interface to it in py_compile, compileall and PyZipFile.
Georg Brandl <georg@python.org>
parents: 66409
diff changeset
1697 fname = pycache_pyo
713c6b6ca5ce Add an "optimize" parameter to compile() to control the optimization level, and provide an interface to it in py_compile, compileall and PyZipFile.
Georg Brandl <georg@python.org>
parents: 66409
diff changeset
1698 arcname = file_pyo
713c6b6ca5ce Add an "optimize" parameter to compile() to control the optimization level, and provide an interface to it in py_compile, compileall and PyZipFile.
Georg Brandl <georg@python.org>
parents: 66409
diff changeset
1699 else:
713c6b6ca5ce Add an "optimize" parameter to compile() to control the optimization level, and provide an interface to it in py_compile, compileall and PyZipFile.
Georg Brandl <georg@python.org>
parents: 66409
diff changeset
1700 # Compile py into PEP 3147 pyc file.
713c6b6ca5ce Add an "optimize" parameter to compile() to control the optimization level, and provide an interface to it in py_compile, compileall and PyZipFile.
Georg Brandl <georg@python.org>
parents: 66409
diff changeset
1701 if _compile(file_py):
713c6b6ca5ce Add an "optimize" parameter to compile() to control the optimization level, and provide an interface to it in py_compile, compileall and PyZipFile.
Georg Brandl <georg@python.org>
parents: 66409
diff changeset
1702 fname = (pycache_pyc if __debug__ else pycache_pyo)
713c6b6ca5ce Add an "optimize" parameter to compile() to control the optimization level, and provide an interface to it in py_compile, compileall and PyZipFile.
Georg Brandl <georg@python.org>
parents: 66409
diff changeset
1703 arcname = (file_pyc if __debug__ else file_pyo)
713c6b6ca5ce Add an "optimize" parameter to compile() to control the optimization level, and provide an interface to it in py_compile, compileall and PyZipFile.
Georg Brandl <georg@python.org>
parents: 66409
diff changeset
1704 else:
713c6b6ca5ce Add an "optimize" parameter to compile() to control the optimization level, and provide an interface to it in py_compile, compileall and PyZipFile.
Georg Brandl <georg@python.org>
parents: 66409
diff changeset
1705 fname = arcname = file_py
12197
7f18f979a93a Zip file handling module, by Jim Ahlstrom.
Guido van Rossum <guido@python.org>
parents:
diff changeset
1706 else:
66685
713c6b6ca5ce Add an "optimize" parameter to compile() to control the optimization level, and provide an interface to it in py_compile, compileall and PyZipFile.
Georg Brandl <georg@python.org>
parents: 66409
diff changeset
1707 # new mode: use given optimization level
713c6b6ca5ce Add an "optimize" parameter to compile() to control the optimization level, and provide an interface to it in py_compile, compileall and PyZipFile.
Georg Brandl <georg@python.org>
parents: 66409
diff changeset
1708 if self._optimize == 0:
713c6b6ca5ce Add an "optimize" parameter to compile() to control the optimization level, and provide an interface to it in py_compile, compileall and PyZipFile.
Georg Brandl <georg@python.org>
parents: 66409
diff changeset
1709 fname = pycache_pyc
713c6b6ca5ce Add an "optimize" parameter to compile() to control the optimization level, and provide an interface to it in py_compile, compileall and PyZipFile.
Georg Brandl <georg@python.org>
parents: 66409
diff changeset
1710 arcname = file_pyc
60648
7b69e630d237 PEP 3147
Barry Warsaw <barry@python.org>
parents: 58822
diff changeset
1711 else:
66685
713c6b6ca5ce Add an "optimize" parameter to compile() to control the optimization level, and provide an interface to it in py_compile, compileall and PyZipFile.
Georg Brandl <georg@python.org>
parents: 66409
diff changeset
1712 fname = pycache_pyo
713c6b6ca5ce Add an "optimize" parameter to compile() to control the optimization level, and provide an interface to it in py_compile, compileall and PyZipFile.
Georg Brandl <georg@python.org>
parents: 66409
diff changeset
1713 arcname = file_pyo
713c6b6ca5ce Add an "optimize" parameter to compile() to control the optimization level, and provide an interface to it in py_compile, compileall and PyZipFile.
Georg Brandl <georg@python.org>
parents: 66409
diff changeset
1714 if not (os.path.isfile(fname) and
713c6b6ca5ce Add an "optimize" parameter to compile() to control the optimization level, and provide an interface to it in py_compile, compileall and PyZipFile.
Georg Brandl <georg@python.org>
parents: 66409
diff changeset
1715 os.stat(fname).st_mtime >= os.stat(file_py).st_mtime):
713c6b6ca5ce Add an "optimize" parameter to compile() to control the optimization level, and provide an interface to it in py_compile, compileall and PyZipFile.
Georg Brandl <georg@python.org>
parents: 66409
diff changeset
1716 if not _compile(file_py, optimize=self._optimize):
713c6b6ca5ce Add an "optimize" parameter to compile() to control the optimization level, and provide an interface to it in py_compile, compileall and PyZipFile.
Georg Brandl <georg@python.org>
parents: 66409
diff changeset
1717 fname = arcname = file_py
60648
7b69e630d237 PEP 3147
Barry Warsaw <barry@python.org>
parents: 58822
diff changeset
1718 archivename = os.path.split(arcname)[1]
12197
7f18f979a93a Zip file handling module, by Jim Ahlstrom.
Guido van Rossum <guido@python.org>
parents:
diff changeset
1719 if basename:
7f18f979a93a Zip file handling module, by Jim Ahlstrom.
Guido van Rossum <guido@python.org>
parents:
diff changeset
1720 archivename = "%s/%s" % (basename, archivename)
7f18f979a93a Zip file handling module, by Jim Ahlstrom.
Guido van Rossum <guido@python.org>
parents:
diff changeset
1721 return (fname, archivename)
39442
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36609
diff changeset
1722
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36609
diff changeset
1723
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36609
diff changeset
1724 def main(args = None):
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36609
diff changeset
1725 import textwrap
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36609
diff changeset
1726 USAGE=textwrap.dedent("""\
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36609
diff changeset
1727 Usage:
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36609
diff changeset
1728 zipfile.py -l zipfile.zip # Show listing of a zipfile
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36609
diff changeset
1729 zipfile.py -t zipfile.zip # Test if a zipfile is valid
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36609
diff changeset
1730 zipfile.py -e zipfile.zip target # Extract zipfile into target dir
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36609
diff changeset
1731 zipfile.py -c zipfile.zip src ... # Create zipfile from sources
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36609
diff changeset
1732 """)
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36609
diff changeset
1733 if args is None:
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36609
diff changeset
1734 args = sys.argv[1:]
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36609
diff changeset
1735
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36609
diff changeset
1736 if not args or args[0] not in ('-l', '-c', '-e', '-t'):
40775
4cdf21a0dbbc Fix most trivially-findable print statements.
Guido van Rossum <guido@python.org>
parents: 40644
diff changeset
1737 print(USAGE)
39442
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36609
diff changeset
1738 sys.exit(1)
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36609
diff changeset
1739
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36609
diff changeset
1740 if args[0] == '-l':
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36609
diff changeset
1741 if len(args) != 2:
40775
4cdf21a0dbbc Fix most trivially-findable print statements.
Guido van Rossum <guido@python.org>
parents: 40644
diff changeset
1742 print(USAGE)
39442
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36609
diff changeset
1743 sys.exit(1)
80482
d51d95c9ea81 Issue #16408: Fix file descriptors not being closed in error conditions in the zipfile module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76270
diff changeset
1744 with ZipFile(args[1], 'r') as zf:
d51d95c9ea81 Issue #16408: Fix file descriptors not being closed in error conditions in the zipfile module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76270
diff changeset
1745 zf.printdir()
39442
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36609
diff changeset
1746
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36609
diff changeset
1747 elif args[0] == '-t':
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36609
diff changeset
1748 if len(args) != 2:
40775
4cdf21a0dbbc Fix most trivially-findable print statements.
Guido van Rossum <guido@python.org>
parents: 40644
diff changeset
1749 print(USAGE)
39442
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36609
diff changeset
1750 sys.exit(1)
80482
d51d95c9ea81 Issue #16408: Fix file descriptors not being closed in error conditions in the zipfile module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76270
diff changeset
1751 with ZipFile(args[1], 'r') as zf:
d51d95c9ea81 Issue #16408: Fix file descriptors not being closed in error conditions in the zipfile module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76270
diff changeset
1752 badfile = zf.testzip()
63936
68c48f8aa555 Merged revisions 83959-83960 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58176
diff changeset
1753 if badfile:
68c48f8aa555 Merged revisions 83959-83960 via svnmerge from
Antoine Pitrou <solipsis@pitrou.net>
parents: 58176
diff changeset
1754 print("The following enclosed file is corrupted: {!r}".format(badfile))
40775
4cdf21a0dbbc Fix most trivially-findable print statements.
Guido van Rossum <guido@python.org>
parents: 40644
diff changeset
1755 print("Done testing")
39442
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36609
diff changeset
1756
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36609
diff changeset
1757 elif args[0] == '-e':
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36609
diff changeset
1758 if len(args) != 3:
40775
4cdf21a0dbbc Fix most trivially-findable print statements.
Guido van Rossum <guido@python.org>
parents: 40644
diff changeset
1759 print(USAGE)
39442
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36609
diff changeset
1760 sys.exit(1)
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36609
diff changeset
1761
80482
d51d95c9ea81 Issue #16408: Fix file descriptors not being closed in error conditions in the zipfile module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76270
diff changeset
1762 with ZipFile(args[1], 'r') as zf:
d51d95c9ea81 Issue #16408: Fix file descriptors not being closed in error conditions in the zipfile module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76270
diff changeset
1763 out = args[2]
d51d95c9ea81 Issue #16408: Fix file descriptors not being closed in error conditions in the zipfile module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76270
diff changeset
1764 for path in zf.namelist():
d51d95c9ea81 Issue #16408: Fix file descriptors not being closed in error conditions in the zipfile module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76270
diff changeset
1765 if path.startswith('./'):
d51d95c9ea81 Issue #16408: Fix file descriptors not being closed in error conditions in the zipfile module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76270
diff changeset
1766 tgt = os.path.join(out, path[2:])
d51d95c9ea81 Issue #16408: Fix file descriptors not being closed in error conditions in the zipfile module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76270
diff changeset
1767 else:
d51d95c9ea81 Issue #16408: Fix file descriptors not being closed in error conditions in the zipfile module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76270
diff changeset
1768 tgt = os.path.join(out, path)
39442
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36609
diff changeset
1769
80482
d51d95c9ea81 Issue #16408: Fix file descriptors not being closed in error conditions in the zipfile module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76270
diff changeset
1770 tgtdir = os.path.dirname(tgt)
d51d95c9ea81 Issue #16408: Fix file descriptors not being closed in error conditions in the zipfile module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76270
diff changeset
1771 if not os.path.exists(tgtdir):
d51d95c9ea81 Issue #16408: Fix file descriptors not being closed in error conditions in the zipfile module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76270
diff changeset
1772 os.makedirs(tgtdir)
d51d95c9ea81 Issue #16408: Fix file descriptors not being closed in error conditions in the zipfile module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76270
diff changeset
1773 with open(tgt, 'wb') as fp:
d51d95c9ea81 Issue #16408: Fix file descriptors not being closed in error conditions in the zipfile module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76270
diff changeset
1774 fp.write(zf.read(path))
39442
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36609
diff changeset
1775
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36609
diff changeset
1776 elif args[0] == '-c':
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36609
diff changeset
1777 if len(args) < 3:
40775
4cdf21a0dbbc Fix most trivially-findable print statements.
Guido van Rossum <guido@python.org>
parents: 40644
diff changeset
1778 print(USAGE)
39442
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36609
diff changeset
1779 sys.exit(1)
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36609
diff changeset
1780
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36609
diff changeset
1781 def addToZip(zf, path, zippath):
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36609
diff changeset
1782 if os.path.isfile(path):
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36609
diff changeset
1783 zf.write(path, zippath, ZIP_DEFLATED)
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36609
diff changeset
1784 elif os.path.isdir(path):
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36609
diff changeset
1785 for nm in os.listdir(path):
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36609
diff changeset
1786 addToZip(zf,
86536
34fb83421119 add a filterfunc to zip file.PyZipFile.writepy, issue 19274
Christian Tismer <tismer@stackless.com>
parents: 85814
diff changeset
1787 os.path.join(path, nm), os.path.join(zippath, nm))
39442
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36609
diff changeset
1788 # else: ignore
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36609
diff changeset
1789
87417
271cc3660445 Issue #17201: ZIP64 extensions now are enabled by default.
Serhiy Storchaka <storchaka@gmail.com>
parents: 86555
diff changeset
1790 with ZipFile(args[1], 'w') as zf:
80482
d51d95c9ea81 Issue #16408: Fix file descriptors not being closed in error conditions in the zipfile module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76270
diff changeset
1791 for src in args[2:]:
d51d95c9ea81 Issue #16408: Fix file descriptors not being closed in error conditions in the zipfile module.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76270
diff changeset
1792 addToZip(zf, src, os.path.basename(src))
39442
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36609
diff changeset
1793
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36609
diff changeset
1794 if __name__ == "__main__":
654c380cf8b9 Merged revisions 46753-51188 via svnmerge from
Thomas Wouters <thomas@python.org>
parents: 36609
diff changeset
1795 main()