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:
Lars Gustäbel 2009-03-22 20:09:33 +00:00
parent b364bfe2f4
commit 2020a59563
3 changed files with 34 additions and 5 deletions

View File

@ -662,12 +662,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:
data = self.bz2obj.decompress(raw)
b.append(data)
except EOFError:
break break
data = self.bz2obj.decompress(raw)
b.append(data)
x += len(data) x += len(data)
self.buf = "".join(b) self.buf = "".join(b)

View File

@ -1140,6 +1140,30 @@ class Bz2WriteTest(WriteTest):
class Bz2StreamWriteTest(StreamWriteTest): class Bz2StreamWriteTest(StreamWriteTest):
mode = "w|bz2" 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(): def test_main():
if not os.path.exists(TEMPDIR): if not os.path.exists(TEMPDIR):
os.mkdir(TEMPDIR) os.mkdir(TEMPDIR)
@ -1196,6 +1220,7 @@ def test_main():
Bz2StreamReadTest, Bz2StreamReadTest,
Bz2WriteTest, Bz2WriteTest,
Bz2StreamWriteTest, Bz2StreamWriteTest,
Bz2PartialReadTest,
] ]
try: try:

View File

@ -188,6 +188,11 @@ Core and Builtins
Library 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 - Issue #5536: urllib.urlretrieve makes sure to close the file it's writing to
even if an exception occurs. even if an exception occurs.