Better error message when trying to unzip file with reserved filenames on windows

This commit is contained in:
Kovid Goyal 2019-12-18 08:49:23 +05:30
parent 72efa745c7
commit ab81c2f309
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C

View File

@ -33,6 +33,20 @@ LocalHeader = namedtuple('LocalHeader',
'filename extra') 'filename extra')
if hasattr(sys, 'getwindowsversion'):
windows_reserved_filenames = (
'CON', 'PRN', 'AUX', 'CLOCK$', 'NUL' 'COM0', 'COM1', 'COM2', 'COM3',
'COM4', 'COM5', 'COM6', 'COM7', 'COM8', 'COM9' 'LPT0', 'LPT1', 'LPT2',
'LPT3', 'LPT4', 'LPT5', 'LPT6', 'LPT7', 'LPT8', 'LPT9')
def is_reserved_filename(x):
base = x.partition('.')[0].upper()
return base in windows_reserved_filenames
else:
def is_reserved_filename(x):
return False
def decode_arcname(name): def decode_arcname(name):
if isinstance(name, bytes): if isinstance(name, bytes):
from calibre.ebooks.chardet import detect from calibre.ebooks.chardet import detect
@ -207,11 +221,18 @@ def _extractall(f, path=None, file_info=None):
if not os.path.exists(bdir): if not os.path.exists(bdir):
os.makedirs(bdir) os.makedirs(bdir)
dest = os.path.join(path, *parts) dest = os.path.join(path, *parts)
with open(dest, 'wb') as o: try:
df = open(dest, 'wb')
except EnvironmentError:
if is_reserved_filename(os.path.basename(dest)):
raise ValueError('This ZIP file contains a file with a reserved filename'
' that cannot be processed on Windows: {}'.format(os.path.basename(dest)))
raise
with df:
if header.compression_method == ZIP_STORED: if header.compression_method == ZIP_STORED:
copy_stored_file(f, header.compressed_size, o) copy_stored_file(f, header.compressed_size, df)
else: else:
copy_compressed_file(f, header.compressed_size, o) copy_compressed_file(f, header.compressed_size, df)
else: else:
f.seek(f.tell()+seekval) f.seek(f.tell()+seekval)