1
0
Fork 0
mirror of https://github.com/ansible-collections/community.general.git synced 2024-09-14 20:13:21 +02:00

Python2.4's zipfile library cannot handle zip 64bit extensions which are needed for > 64K files (#3754)

Fallback to unzip if zipfile fails and hope that unzip can deal with it
(sites have an easier time upgrading the unzip utility than all of
python).

https://bugs.python.org/issue3997

Fixes #3560
This commit is contained in:
Toshio Kuratomi 2016-05-26 16:40:50 -07:00 committed by Matt Clay
parent 20d9c0c484
commit 286a46e8b4

View file

@ -123,7 +123,7 @@ import grp
import datetime import datetime
import time import time
import binascii import binascii
from zipfile import ZipFile from zipfile import ZipFile, BadZipfile
import tarfile import tarfile
import subprocess import subprocess
@ -174,17 +174,41 @@ class ZipArchive(object):
# mode += 2**(9+j) # mode += 2**(9+j)
return ( mode & ~umask ) return ( mode & ~umask )
def _legacy_file_list(self, force_refresh=False):
unzip_bin = self.module.get_bin_path('unzip')
if not unzip_bin:
raise UnarchiveError('Python Zipfile cannot read %s and unzip not found' % self.src)
rc, out, err = self.module.run_command([unzip_bin, '-v', self.src])
if rc:
raise UnarchiveError('Neither python zipfile nor unzip can read %s' % self.src)
for line in out.splitlines()[3:-2]:
fields = line.split(None, 7)
self._files_in_archive.append(fields[7])
self._infodict[fields[7]] = long(fields[6])
def _crc32(self, path): def _crc32(self, path):
if self._infodict: if self._infodict:
return self._infodict[path] return self._infodict[path]
archive = ZipFile(self.src)
try: try:
for item in archive.infolist(): archive = ZipFile(self.src)
self._infodict[item.filename] = long(item.CRC) except BadZipfile:
except: e = get_exception()
archive.close() if e.args[0].lower().startswith('bad magic number'):
raise UnarchiveError('Unable to list files in the archive') # Python2.4 can't handle zipfiles with > 64K files. Try using
# /usr/bin/unzip instead
self._legacy_file_list()
else:
raise
else:
try:
for item in archive.infolist():
self._infodict[item.filename] = long(item.CRC)
except:
archive.close()
raise UnarchiveError('Unable to list files in the archive')
return self._infodict[path] return self._infodict[path]
@ -194,16 +218,26 @@ class ZipArchive(object):
return self._files_in_archive return self._files_in_archive
self._files_in_archive = [] self._files_in_archive = []
archive = ZipFile(self.src)
try: try:
for member in archive.namelist(): archive = ZipFile(self.src)
if member not in self.excludes: except BadZipfile:
self._files_in_archive.append(member) e = get_exception()
except: if e.args[0].lower().startswith('bad magic number'):
archive.close() # Python2.4 can't handle zipfiles with > 64K files. Try using
raise UnarchiveError('Unable to list files in the archive') # /usr/bin/unzip instead
self._legacy_file_list(force_refresh)
else:
raise
else:
try:
for member in archive.namelist():
if member not in self.excludes:
self._files_in_archive.append(member)
except:
archive.close()
raise UnarchiveError('Unable to list files in the archive')
archive.close() archive.close()
return self._files_in_archive return self._files_in_archive
def is_unarchived(self): def is_unarchived(self):