@@ -123,6 +123,32 @@ class LargeZipFile(Exception):
123
123
_CD_EXTERNAL_FILE_ATTRIBUTES = 17
124
124
_CD_LOCAL_HEADER_OFFSET = 18
125
125
126
+ # General purpose bit flags
127
+ # Zip Appnote: 4.4.4 general purpose bit flag: (2 bytes)
128
+ _MASK_ENCRYPTED = 1 << 0
129
+ # Bits 1 and 2 have different meanings depending on the compression used.
130
+ _MASK_COMPRESS_OPTION_1 = 1 << 1
131
+ # _MASK_COMPRESS_OPTION_2 = 1 << 2
132
+ # _MASK_USE_DATA_DESCRIPTOR: If set, crc-32, compressed size and uncompressed
133
+ # size are zero in the local header and the real values are written in the data
134
+ # descriptor immediately following the compressed data.
135
+ _MASK_USE_DATA_DESCRIPTOR = 1 << 3
136
+ # Bit 4: Reserved for use with compression method 8, for enhanced deflating.
137
+ # _MASK_RESERVED_BIT_4 = 1 << 4
138
+ _MASK_COMPRESSED_PATCH = 1 << 5
139
+ _MASK_STRONG_ENCRYPTION = 1 << 6
140
+ # _MASK_UNUSED_BIT_7 = 1 << 7
141
+ # _MASK_UNUSED_BIT_8 = 1 << 8
142
+ # _MASK_UNUSED_BIT_9 = 1 << 9
143
+ # _MASK_UNUSED_BIT_10 = 1 << 10
144
+ _MASK_UTF_FILENAME = 1 << 11
145
+ # Bit 12: Reserved by PKWARE for enhanced compression.
146
+ # _MASK_RESERVED_BIT_12 = 1 << 12
147
+ # _MASK_ENCRYPTED_CENTRAL_DIR = 1 << 13
148
+ # Bit 14, 15: Reserved by PKWARE
149
+ # _MASK_RESERVED_BIT_14 = 1 << 14
150
+ # _MASK_RESERVED_BIT_15 = 1 << 15
151
+
126
152
# The "local file header" structure, magic number, size, and indices
127
153
# (section V.A in the format document)
128
154
structFileHeader = "<4s2B4HL2L2H"
@@ -411,7 +437,7 @@ def FileHeader(self, zip64=None):
411
437
dt = self .date_time
412
438
dosdate = (dt [0 ] - 1980 ) << 9 | dt [1 ] << 5 | dt [2 ]
413
439
dostime = dt [3 ] << 11 | dt [4 ] << 5 | (dt [5 ] // 2 )
414
- if self .flag_bits & 0x08 :
440
+ if self .flag_bits & _MASK_USE_DATA_DESCRIPTOR :
415
441
# Set these to zero because we write them after the file data
416
442
CRC = compress_size = file_size = 0
417
443
else :
@@ -456,7 +482,7 @@ def _encodeFilenameFlags(self):
456
482
try :
457
483
return self .filename .encode ('ascii' ), self .flag_bits
458
484
except UnicodeEncodeError :
459
- return self .filename .encode ('utf-8' ), self .flag_bits | 0x800
485
+ return self .filename .encode ('utf-8' ), self .flag_bits | _MASK_UTF_FILENAME
460
486
461
487
def _decodeExtra (self ):
462
488
# Try to decode the extra field.
@@ -825,7 +851,7 @@ def __init__(self, fileobj, mode, zipinfo, pwd=None,
825
851
826
852
self ._decrypter = None
827
853
if pwd :
828
- if zipinfo .flag_bits & 0x8 :
854
+ if zipinfo .flag_bits & _MASK_USE_DATA_DESCRIPTOR :
829
855
# compare against the file type from extended local headers
830
856
check_byte = (zipinfo ._raw_time >> 8 ) & 0xff
831
857
else :
@@ -1147,7 +1173,7 @@ def close(self):
1147
1173
self ._zinfo .file_size = self ._file_size
1148
1174
1149
1175
# Write updated header info
1150
- if self ._zinfo .flag_bits & 0x08 :
1176
+ if self ._zinfo .flag_bits & _MASK_USE_DATA_DESCRIPTOR :
1151
1177
# Write CRC and file sizes after the file data
1152
1178
fmt = '<LLQQ' if self ._zip64 else '<LLLL'
1153
1179
self ._fileobj .write (struct .pack (fmt , _DD_SIGNATURE , self ._zinfo .CRC ,
@@ -1355,7 +1381,7 @@ def _RealGetContents(self):
1355
1381
print (centdir )
1356
1382
filename = fp .read (centdir [_CD_FILENAME_LENGTH ])
1357
1383
flags = centdir [5 ]
1358
- if flags & 0x800 :
1384
+ if flags & _MASK_UTF_FILENAME :
1359
1385
# UTF-8 file names extension
1360
1386
filename = filename .decode ('utf-8' )
1361
1387
else :
@@ -1527,15 +1553,15 @@ def open(self, name, mode="r", pwd=None, *, force_zip64=False):
1527
1553
if fheader [_FH_EXTRA_FIELD_LENGTH ]:
1528
1554
zef_file .read (fheader [_FH_EXTRA_FIELD_LENGTH ])
1529
1555
1530
- if zinfo .flag_bits & 0x20 :
1556
+ if zinfo .flag_bits & _MASK_COMPRESSED_PATCH :
1531
1557
# Zip 2.7: compressed patched data
1532
1558
raise NotImplementedError ("compressed patched data (flag bit 5)" )
1533
1559
1534
- if zinfo .flag_bits & 0x40 :
1560
+ if zinfo .flag_bits & _MASK_STRONG_ENCRYPTION :
1535
1561
# strong encryption
1536
1562
raise NotImplementedError ("strong encryption (flag bit 6)" )
1537
1563
1538
- if fheader [_FH_GENERAL_PURPOSE_FLAG_BITS ] & 0x800 :
1564
+ if fheader [_FH_GENERAL_PURPOSE_FLAG_BITS ] & _MASK_UTF_FILENAME :
1539
1565
# UTF-8 filename
1540
1566
fname_str = fname .decode ("utf-8" )
1541
1567
else :
@@ -1547,7 +1573,7 @@ def open(self, name, mode="r", pwd=None, *, force_zip64=False):
1547
1573
% (zinfo .orig_filename , fname ))
1548
1574
1549
1575
# check for encrypted flag & handle password
1550
- is_encrypted = zinfo .flag_bits & 0x1
1576
+ is_encrypted = zinfo .flag_bits & _MASK_ENCRYPTED
1551
1577
if is_encrypted :
1552
1578
if not pwd :
1553
1579
pwd = self .pwd
@@ -1580,9 +1606,9 @@ def _open_to_write(self, zinfo, force_zip64=False):
1580
1606
zinfo .flag_bits = 0x00
1581
1607
if zinfo .compress_type == ZIP_LZMA :
1582
1608
# Compressed data includes an end-of-stream (EOS) marker
1583
- zinfo .flag_bits |= 0x02
1609
+ zinfo .flag_bits |= _MASK_COMPRESS_OPTION_1
1584
1610
if not self ._seekable :
1585
- zinfo .flag_bits |= 0x08
1611
+ zinfo .flag_bits |= _MASK_USE_DATA_DESCRIPTOR
1586
1612
1587
1613
if not zinfo .external_attr :
1588
1614
zinfo .external_attr = 0o600 << 16 # permissions: ?rw-------
@@ -1749,7 +1775,7 @@ def write(self, filename, arcname=None,
1749
1775
zinfo .header_offset = self .fp .tell () # Start of header bytes
1750
1776
if zinfo .compress_type == ZIP_LZMA :
1751
1777
# Compressed data includes an end-of-stream (EOS) marker
1752
- zinfo .flag_bits |= 0x02
1778
+ zinfo .flag_bits |= _MASK_COMPRESS_OPTION_1
1753
1779
1754
1780
self ._writecheck (zinfo )
1755
1781
self ._didModify = True
0 commit comments