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.
This commit is contained in:
parent
b364bfe2f4
commit
2020a59563
|
@ -662,12 +662,11 @@ class _BZ2Proxy(object):
|
|||
b = [self.buf]
|
||||
x = len(self.buf)
|
||||
while x < size:
|
||||
try:
|
||||
raw = self.fileobj.read(self.blocksize)
|
||||
if not raw:
|
||||
break
|
||||
data = self.bz2obj.decompress(raw)
|
||||
b.append(data)
|
||||
except EOFError:
|
||||
break
|
||||
x += len(data)
|
||||
self.buf = "".join(b)
|
||||
|
||||
|
|
|
@ -1140,6 +1140,30 @@ class Bz2WriteTest(WriteTest):
|
|||
class Bz2StreamWriteTest(StreamWriteTest):
|
||||
mode = "w|bz2"
|
||||
|
||||
class Bz2PartialReadTest(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")
|
||||
|
||||
|
||||
def test_main():
|
||||
if not os.path.exists(TEMPDIR):
|
||||
os.mkdir(TEMPDIR)
|
||||
|
@ -1196,6 +1220,7 @@ def test_main():
|
|||
Bz2StreamReadTest,
|
||||
Bz2WriteTest,
|
||||
Bz2StreamWriteTest,
|
||||
Bz2PartialReadTest,
|
||||
]
|
||||
|
||||
try:
|
||||
|
|
|
@ -188,6 +188,11 @@ Core and Builtins
|
|||
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.
|
||||
|
||||
- Issue #5536: urllib.urlretrieve makes sure to close the file it's writing to
|
||||
even if an exception occurs.
|
||||
|
||||
|
|
Loading…
Reference in New Issue