Skip to content

Commit 556d5ad

Browse files
authored
bpo-44129: Add descriptive global variables for general purpose bit flags (GH-26118)
Replace hex flag masks with named global variables to improve readability. eg. if flags & 0x800 becomes: if flags & _MASK_UTF_FILENAME
1 parent a79e2b6 commit 556d5ad

File tree

2 files changed

+39
-13
lines changed

2 files changed

+39
-13
lines changed

Lib/test/test_zipfile.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1545,7 +1545,7 @@ def test_writestr_extended_local_header_issue1202(self):
15451545
with zipfile.ZipFile(TESTFN2, 'w') as orig_zip:
15461546
for data in 'abcdefghijklmnop':
15471547
zinfo = zipfile.ZipInfo(data)
1548-
zinfo.flag_bits |= 0x08 # Include an extended local header.
1548+
zinfo.flag_bits |= zipfile._MASK_USE_DATA_DESCRIPTOR # Include an extended local header.
15491549
orig_zip.writestr(zinfo, data)
15501550

15511551
def test_close(self):

Lib/zipfile.py

Lines changed: 38 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,32 @@ class LargeZipFile(Exception):
123123
_CD_EXTERNAL_FILE_ATTRIBUTES = 17
124124
_CD_LOCAL_HEADER_OFFSET = 18
125125

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+
126152
# The "local file header" structure, magic number, size, and indices
127153
# (section V.A in the format document)
128154
structFileHeader = "<4s2B4HL2L2H"
@@ -411,7 +437,7 @@ def FileHeader(self, zip64=None):
411437
dt = self.date_time
412438
dosdate = (dt[0] - 1980) << 9 | dt[1] << 5 | dt[2]
413439
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:
415441
# Set these to zero because we write them after the file data
416442
CRC = compress_size = file_size = 0
417443
else:
@@ -456,7 +482,7 @@ def _encodeFilenameFlags(self):
456482
try:
457483
return self.filename.encode('ascii'), self.flag_bits
458484
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
460486

461487
def _decodeExtra(self):
462488
# Try to decode the extra field.
@@ -825,7 +851,7 @@ def __init__(self, fileobj, mode, zipinfo, pwd=None,
825851

826852
self._decrypter = None
827853
if pwd:
828-
if zipinfo.flag_bits & 0x8:
854+
if zipinfo.flag_bits & _MASK_USE_DATA_DESCRIPTOR:
829855
# compare against the file type from extended local headers
830856
check_byte = (zipinfo._raw_time >> 8) & 0xff
831857
else:
@@ -1147,7 +1173,7 @@ def close(self):
11471173
self._zinfo.file_size = self._file_size
11481174

11491175
# Write updated header info
1150-
if self._zinfo.flag_bits & 0x08:
1176+
if self._zinfo.flag_bits & _MASK_USE_DATA_DESCRIPTOR:
11511177
# Write CRC and file sizes after the file data
11521178
fmt = '<LLQQ' if self._zip64 else '<LLLL'
11531179
self._fileobj.write(struct.pack(fmt, _DD_SIGNATURE, self._zinfo.CRC,
@@ -1355,7 +1381,7 @@ def _RealGetContents(self):
13551381
print(centdir)
13561382
filename = fp.read(centdir[_CD_FILENAME_LENGTH])
13571383
flags = centdir[5]
1358-
if flags & 0x800:
1384+
if flags & _MASK_UTF_FILENAME:
13591385
# UTF-8 file names extension
13601386
filename = filename.decode('utf-8')
13611387
else:
@@ -1527,15 +1553,15 @@ def open(self, name, mode="r", pwd=None, *, force_zip64=False):
15271553
if fheader[_FH_EXTRA_FIELD_LENGTH]:
15281554
zef_file.read(fheader[_FH_EXTRA_FIELD_LENGTH])
15291555

1530-
if zinfo.flag_bits & 0x20:
1556+
if zinfo.flag_bits & _MASK_COMPRESSED_PATCH:
15311557
# Zip 2.7: compressed patched data
15321558
raise NotImplementedError("compressed patched data (flag bit 5)")
15331559

1534-
if zinfo.flag_bits & 0x40:
1560+
if zinfo.flag_bits & _MASK_STRONG_ENCRYPTION:
15351561
# strong encryption
15361562
raise NotImplementedError("strong encryption (flag bit 6)")
15371563

1538-
if fheader[_FH_GENERAL_PURPOSE_FLAG_BITS] & 0x800:
1564+
if fheader[_FH_GENERAL_PURPOSE_FLAG_BITS] & _MASK_UTF_FILENAME:
15391565
# UTF-8 filename
15401566
fname_str = fname.decode("utf-8")
15411567
else:
@@ -1547,7 +1573,7 @@ def open(self, name, mode="r", pwd=None, *, force_zip64=False):
15471573
% (zinfo.orig_filename, fname))
15481574

15491575
# check for encrypted flag & handle password
1550-
is_encrypted = zinfo.flag_bits & 0x1
1576+
is_encrypted = zinfo.flag_bits & _MASK_ENCRYPTED
15511577
if is_encrypted:
15521578
if not pwd:
15531579
pwd = self.pwd
@@ -1580,9 +1606,9 @@ def _open_to_write(self, zinfo, force_zip64=False):
15801606
zinfo.flag_bits = 0x00
15811607
if zinfo.compress_type == ZIP_LZMA:
15821608
# Compressed data includes an end-of-stream (EOS) marker
1583-
zinfo.flag_bits |= 0x02
1609+
zinfo.flag_bits |= _MASK_COMPRESS_OPTION_1
15841610
if not self._seekable:
1585-
zinfo.flag_bits |= 0x08
1611+
zinfo.flag_bits |= _MASK_USE_DATA_DESCRIPTOR
15861612

15871613
if not zinfo.external_attr:
15881614
zinfo.external_attr = 0o600 << 16 # permissions: ?rw-------
@@ -1749,7 +1775,7 @@ def write(self, filename, arcname=None,
17491775
zinfo.header_offset = self.fp.tell() # Start of header bytes
17501776
if zinfo.compress_type == ZIP_LZMA:
17511777
# Compressed data includes an end-of-stream (EOS) marker
1752-
zinfo.flag_bits |= 0x02
1778+
zinfo.flag_bits |= _MASK_COMPRESS_OPTION_1
17531779

17541780
self._writecheck(zinfo)
17551781
self._didModify = True

0 commit comments

Comments
 (0)