Issue #5068: Fixed the tarfile._BZ2Proxy.read() method that would loop
forever on incomplete input. That caused tarfile.open() to hang when used with mode 'r' or 'r:bz2' and a fileobj argument that contained no data or partial bzip2 compressed data. (backported from r70523)
This commit is contained in:
parent
f73bf85942
commit
7623294cb7
|
@ -594,12 +594,11 @@ class _BZ2Proxy(object):
|
||||||
b = [self.buf]
|
b = [self.buf]
|
||||||
x = len(self.buf)
|
x = len(self.buf)
|
||||||
while x < size:
|
while x < size:
|
||||||
try:
|
|
||||||
raw = self.fileobj.read(self.blocksize)
|
raw = self.fileobj.read(self.blocksize)
|
||||||
|
if not raw:
|
||||||
|
break
|
||||||
data = self.bz2obj.decompress(raw)
|
data = self.bz2obj.decompress(raw)
|
||||||
b.append(data)
|
b.append(data)
|
||||||
except EOFError:
|
|
||||||
break
|
|
||||||
x += len(data)
|
x += len(data)
|
||||||
self.buf = "".join(b)
|
self.buf = "".join(b)
|
||||||
|
|
||||||
|
|
|
@ -751,6 +751,29 @@ if bz2:
|
||||||
class ReadFileobjTestBzip2(ReadFileobjTest):
|
class ReadFileobjTestBzip2(ReadFileobjTest):
|
||||||
comp = "bz2"
|
comp = "bz2"
|
||||||
|
|
||||||
|
class PartialReadTestBzip2(unittest.TestCase):
|
||||||
|
# Issue5068: The _BZ2Proxy.read() method loops forever
|
||||||
|
# on an empty or partial bzipped file.
|
||||||
|
|
||||||
|
def _test_partial_input(self, mode):
|
||||||
|
class MyStringIO(StringIO.StringIO):
|
||||||
|
hit_eof = False
|
||||||
|
def read(self, n):
|
||||||
|
if self.hit_eof:
|
||||||
|
raise AssertionError("infinite loop detected in tarfile.open()")
|
||||||
|
self.hit_eof = self.pos == self.len
|
||||||
|
return StringIO.StringIO.read(self, n)
|
||||||
|
|
||||||
|
data = bz2.compress(tarfile.TarInfo("foo").tobuf())
|
||||||
|
for x in range(len(data) + 1):
|
||||||
|
tarfile.open(fileobj=MyStringIO(data[:x]), mode=mode)
|
||||||
|
|
||||||
|
def test_partial_input(self):
|
||||||
|
self._test_partial_input("r")
|
||||||
|
|
||||||
|
def test_partial_input_bz2(self):
|
||||||
|
self._test_partial_input("r:bz2")
|
||||||
|
|
||||||
# If importing gzip failed, discard the Gzip TestCases.
|
# If importing gzip failed, discard the Gzip TestCases.
|
||||||
if not gzip:
|
if not gzip:
|
||||||
del ReadTestGzip
|
del ReadTestGzip
|
||||||
|
@ -811,7 +834,7 @@ def test_main():
|
||||||
WriteTestBzip2, WriteStreamTestBzip2,
|
WriteTestBzip2, WriteStreamTestBzip2,
|
||||||
ReadDetectTestBzip2, ReadDetectFileobjTestBzip2,
|
ReadDetectTestBzip2, ReadDetectFileobjTestBzip2,
|
||||||
ReadAsteriskTestBzip2, ReadStreamAsteriskTestBzip2,
|
ReadAsteriskTestBzip2, ReadStreamAsteriskTestBzip2,
|
||||||
ReadFileobjTestBzip2
|
ReadFileobjTestBzip2, PartialReadTestBzip2
|
||||||
])
|
])
|
||||||
try:
|
try:
|
||||||
test_support.run_unittest(*tests)
|
test_support.run_unittest(*tests)
|
||||||
|
|
14
Misc/NEWS
14
Misc/NEWS
|
@ -4,6 +4,20 @@ Python News
|
||||||
|
|
||||||
(editors: check NEWS.help for information about editing NEWS using ReST.)
|
(editors: check NEWS.help for information about editing NEWS using ReST.)
|
||||||
|
|
||||||
|
What's New in Python 2.5.5?
|
||||||
|
===========================
|
||||||
|
|
||||||
|
*Release date: XX-XXX-20XX*
|
||||||
|
|
||||||
|
Library
|
||||||
|
-------
|
||||||
|
|
||||||
|
- Issue #5068: Fixed the tarfile._BZ2Proxy.read() method that would loop
|
||||||
|
forever on incomplete input. That caused tarfile.open() to hang when used
|
||||||
|
with mode 'r' or 'r:bz2' and a fileobj argument that contained no data or
|
||||||
|
partial bzip2 compressed data.
|
||||||
|
|
||||||
|
|
||||||
What's New in Python 2.5.4?
|
What's New in Python 2.5.4?
|
||||||
===========================
|
===========================
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue