Skip to content

Commit 07659cf

Browse files
committed
gh-121639: Deduplicate reinitialization setup for ZipExtFile when seeking
1 parent e8c91d9 commit 07659cf

File tree

2 files changed

+31
-36
lines changed

2 files changed

+31
-36
lines changed

Lib/zipfile/__init__.py

Lines changed: 29 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -875,19 +875,12 @@ class ZipExtFile(io.BufferedIOBase):
875875

876876
def __init__(self, fileobj, mode, zipinfo, pwd=None,
877877
close_fileobj=False):
878+
self._zinfo = zipinfo
878879
self._fileobj = fileobj
879880
self._pwd = pwd
880881
self._close_fileobj = close_fileobj
881882

882883
self._compress_type = zipinfo.compress_type
883-
self._compress_left = zipinfo.compress_size
884-
self._left = zipinfo.file_size
885-
886-
self._decompressor = _get_decompressor(self._compress_type)
887-
888-
self._eof = False
889-
self._readbuffer = b''
890-
self._offset = 0
891884

892885
self.newlines = None
893886

@@ -896,34 +889,20 @@ def __init__(self, fileobj, mode, zipinfo, pwd=None,
896889

897890
if hasattr(zipinfo, 'CRC'):
898891
self._expected_crc = zipinfo.CRC
899-
self._running_crc = crc32(b'')
892+
self._orig_start_crc = crc32(b'')
900893
else:
901894
self._expected_crc = None
895+
self._orig_start_crc = None
902896

903897
self._seekable = False
904898
try:
905899
if fileobj.seekable():
906900
self._orig_compress_start = fileobj.tell()
907-
self._orig_compress_size = zipinfo.compress_size
908901
self._orig_file_size = zipinfo.file_size
909-
self._orig_start_crc = self._running_crc
910-
self._orig_crc = self._expected_crc
911902
self._seekable = True
912903
except AttributeError:
913904
pass
914-
915-
self._decrypter = None
916-
if pwd:
917-
if zipinfo.flag_bits & _MASK_USE_DATA_DESCRIPTOR:
918-
# compare against the file type from extended local headers
919-
check_byte = (zipinfo._raw_time >> 8) & 0xff
920-
else:
921-
# compare against the CRC otherwise
922-
check_byte = (zipinfo.CRC >> 24) & 0xff
923-
h = self._init_decrypter()
924-
if h != check_byte:
925-
raise RuntimeError("Bad password for file %r" % zipinfo.orig_filename)
926-
905+
self._init_read()
927906

928907
def _init_decrypter(self):
929908
self._decrypter = _ZipDecrypter(self._pwd)
@@ -934,7 +913,30 @@ def _init_decrypter(self):
934913
# and is used to check the correctness of the password.
935914
header = self._fileobj.read(12)
936915
self._compress_left -= 12
937-
return self._decrypter(header)[11]
916+
h = self._decrypter(header)[11]
917+
918+
if self._zinfo.flag_bits & _MASK_USE_DATA_DESCRIPTOR:
919+
# compare against the file type from extended local headers
920+
check_byte = (self._zinfo._raw_time >> 8) & 0xff
921+
else:
922+
# compare against the CRC otherwise
923+
check_byte = (self._zinfo.CRC >> 24) & 0xff
924+
if h != check_byte:
925+
raise RuntimeError("Bad password for file %r" % self._zinfo.orig_filename)
926+
return h
927+
928+
def _init_read(self):
929+
self._running_crc = self._orig_start_crc
930+
self._compress_left = self._zinfo.compress_size
931+
self._left = self._zinfo.file_size
932+
self._readbuffer = b''
933+
self._offset = 0
934+
self._eof = False
935+
if self._pwd:
936+
self._init_decrypter()
937+
else:
938+
self._decrypter = None
939+
self._decompressor = _get_decompressor(self._compress_type)
938940

939941
def __repr__(self):
940942
result = ['<%s.%s' % (self.__class__.__module__,
@@ -1174,17 +1176,8 @@ def seek(self, offset, whence=os.SEEK_SET):
11741176
elif read_offset < 0:
11751177
# Position is before the current position. Reset the ZipExtFile
11761178
self._fileobj.seek(self._orig_compress_start)
1177-
self._running_crc = self._orig_start_crc
1178-
self._expected_crc = self._orig_crc
1179-
self._compress_left = self._orig_compress_size
1180-
self._left = self._orig_file_size
1181-
self._readbuffer = b''
1182-
self._offset = 0
1183-
self._decompressor = _get_decompressor(self._compress_type)
1184-
self._eof = False
1179+
self._init_read()
11851180
read_offset = new_pos
1186-
if self._decrypter is not None:
1187-
self._init_decrypter()
11881181

11891182
while read_offset > 0:
11901183
read_len = min(self.MAX_SEEK_READ, read_offset)
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Add ``zipfile.ZipExtFile._init_read()`` to deduplicate read
2+
(re)initialization in ``seek()``.

0 commit comments

Comments
 (0)