Merged revisions 84737 via svnmerge from

svn+ssh://pythondev@svn.python.org/python/branches/py3k

........
  r84737 | antoine.pitrou | 2010-09-12 16:51:20 +0200 (dim., 12 sept. 2010) | 4 lines

  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:56:27 +00:00
parent 2039753a9a
commit e4195e8825
3 changed files with 32 additions and 6 deletions

View file

@ -929,6 +929,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

@ -565,17 +565,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 = '' buf = ''
while n < 0 or n is None or n > len(buf): if n is None:
data = self.read1(n) n = -1
while True:
if n < 0:
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

@ -43,6 +43,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 #9825: removed __del__ from the definition of collections.OrderedDict. - Issue #9825: removed __del__ from the definition of collections.OrderedDict.
This prevents user-created self-referencing ordered dictionaries from This prevents user-created self-referencing ordered dictionaries from
becoming permanently uncollectable GC garbage. The downside is that becoming permanently uncollectable GC garbage. The downside is that