Issue #9837: The read() method of ZipExtFile objects (as returned by

ZipFile.open()) could return more bytes than requested.
This commit is contained in:
Antoine Pitrou 2010-09-12 14:51:20 +00:00
parent 0b9489d21d
commit 6464d5ffdc
3 changed files with 32 additions and 6 deletions

View file

@ -939,6 +939,26 @@ class OtherTests(unittest.TestCase):
def test_read_with_bad_crc_deflated(self): def test_read_with_bad_crc_deflated(self):
self.check_read_with_bad_crc(zipfile.ZIP_DEFLATED) self.check_read_with_bad_crc(zipfile.ZIP_DEFLATED)
def check_read_return_size(self, compression):
# Issue #9837: ZipExtFile.read() shouldn't return more bytes
# than requested.
for test_size in (1, 4095, 4096, 4097, 16384):
file_size = test_size + 1
junk = b''.join(struct.pack('B', randint(0, 255))
for x in range(file_size))
with zipfile.ZipFile(io.BytesIO(), "w", compression) as zipf:
zipf.writestr('foo', junk)
with zipf.open('foo', 'r') as fp:
buf = fp.read(test_size)
self.assertEqual(len(buf), test_size)
def test_read_return_size_stored(self):
self.check_read_return_size(zipfile.ZIP_STORED)
@skipUnless(zlib, "requires zlib")
def test_read_return_size_deflated(self):
self.check_read_return_size(zipfile.ZIP_DEFLATED)
def tearDown(self): def tearDown(self):
unlink(TESTFN) unlink(TESTFN)
unlink(TESTFN2) unlink(TESTFN2)

View file

@ -564,17 +564,20 @@ class ZipExtFile(io.BufferedIOBase):
"""Read and return up to n bytes. """Read and return up to n bytes.
If the argument is omitted, None, or negative, data is read and returned until EOF is reached.. If the argument is omitted, None, or negative, data is read and returned until EOF is reached..
""" """
buf = b'' buf = b''
while n < 0 or n is None or n > len(buf): if n is None:
n = -1
while True:
if n < 0:
data = self.read1(n) data = self.read1(n)
elif n > len(buf):
data = self.read1(n - len(buf))
else:
return buf
if len(data) == 0: if len(data) == 0:
return buf return buf
buf += data buf += data
return buf
def _update_crc(self, newdata, eof): def _update_crc(self, newdata, eof):
# Update the CRC using the given data. # Update the CRC using the given data.
if self._expected_crc is None: if self._expected_crc is None:

View file

@ -32,6 +32,9 @@ Core and Builtins
Library Library
------- -------
- Issue #9837: The read() method of ZipExtFile objects (as returned by
ZipFile.open()) could return more bytes than requested.
- Issue #9826: OrderedDict.__repr__ can now handle self-referential - Issue #9826: OrderedDict.__repr__ can now handle self-referential
values: d['x'] = d. values: d['x'] = d.