Issue #28449: tarfile.open() with mode "r" or "r:" now tries to open a tar

file with compression before trying to open it without compression.  Otherwise
it had 50% chance failed with ignore_zeros=True.
This commit is contained in:
Serhiy Storchaka 2016-10-30 20:56:23 +02:00
commit 2f4453eff8
3 changed files with 14 additions and 3 deletions

View File

@ -1554,7 +1554,9 @@ class TarFile(object):
if mode in ("r", "r:*"): if mode in ("r", "r:*"):
# Find out which *open() is appropriate for opening the file. # Find out which *open() is appropriate for opening the file.
for comptype in cls.OPEN_METH: def not_compressed(comptype):
return cls.OPEN_METH[comptype] == 'taropen'
for comptype in sorted(cls.OPEN_METH, key=not_compressed):
func = getattr(cls, cls.OPEN_METH[comptype]) func = getattr(cls, cls.OPEN_METH[comptype])
if fileobj is not None: if fileobj is not None:
saved_pos = fileobj.tell() saved_pos = fileobj.tell()

View File

@ -3,6 +3,7 @@ import os
import io import io
from hashlib import md5 from hashlib import md5
from contextlib import contextmanager from contextlib import contextmanager
from random import Random
import unittest import unittest
import unittest.mock import unittest.mock
@ -349,12 +350,17 @@ class CommonReadTest(ReadTest):
def test_ignore_zeros(self): def test_ignore_zeros(self):
# Test TarFile's ignore_zeros option. # Test TarFile's ignore_zeros option.
# generate 512 pseudorandom bytes
data = Random(0).getrandbits(512*8).to_bytes(512, 'big')
for char in (b'\0', b'a'): for char in (b'\0', b'a'):
# Test if EOFHeaderError ('\0') and InvalidHeaderError ('a') # Test if EOFHeaderError ('\0') and InvalidHeaderError ('a')
# are ignored correctly. # are ignored correctly.
with self.open(tmpname, "w") as fobj: with self.open(tmpname, "w") as fobj:
fobj.write(char * 1024) fobj.write(char * 1024)
fobj.write(tarfile.TarInfo("foo").tobuf()) tarinfo = tarfile.TarInfo("foo")
tarinfo.size = len(data)
fobj.write(tarinfo.tobuf())
fobj.write(data)
tar = tarfile.open(tmpname, mode="r", ignore_zeros=True) tar = tarfile.open(tmpname, mode="r", ignore_zeros=True)
try: try:

View File

@ -27,10 +27,13 @@ Core and Builtins
- Issue #28471: Fix "Python memory allocator called without holding the GIL" - Issue #28471: Fix "Python memory allocator called without holding the GIL"
crash in socket.setblocking. crash in socket.setblocking.
Library Library
------- -------
- Issue #28449: tarfile.open() with mode "r" or "r:" now tries to open a tar
file with compression before trying to open it without compression. Otherwise
it had 50% chance failed with ignore_zeros=True.
- Issue #23262: The webbrowser module now supports Firefox 36+ and derived - Issue #23262: The webbrowser module now supports Firefox 36+ and derived
browsers. Based on patch by Oleg Broytman. browsers. Based on patch by Oleg Broytman.