From 6e0d7e0b281458965ec93adce9bd443a8f7efbe1 Mon Sep 17 00:00:00 2001 From: evilaliv3 Date: Mon, 22 Jun 2015 18:41:08 +0200 Subject: [PATCH] Fix encoding for UTF-8 filenames The issue addressed is https://github.com/SpiderOak/ZipStream/issues/6 --- zipstream.py | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/zipstream.py b/zipstream.py index a285897..9410fef 100644 --- a/zipstream.py +++ b/zipstream.py @@ -134,6 +134,15 @@ def __init__(self, filename="NoName", date_time=(1980,1,1,0,0,0)): # compress_size Size of the compressed file # file_size Size of the uncompressed file + def _encodeFilenameFlags(self): + if isinstance(self.filename, unicode): + try: + return self.filename.encode('ascii'), self.flag_bits + except UnicodeEncodeError: + return self.filename.encode('utf-8'), self.flag_bits | 0x800 + else: + return self.filename, self.flag_bits + def DataDescriptor(self): if self.compress_size > ZIP64_LIMIT or self.file_size > ZIP64_LIMIT: fmt = "<4slQQ" @@ -167,12 +176,14 @@ def FileHeader(self): self.extract_version = max(45, self.extract_version) self.create_version = max(45, self.extract_version) + filename, flag_bits = self._encodeFilenameFlags() + header = struct.pack(structFileHeader, stringFileHeader, - self.extract_version, self.reserved, self.flag_bits, + self.extract_version, self.reserved, flag_bits, self.compress_type, dostime, dosdate, CRC, compress_size, file_size, - len(self.filename), len(extra)) - return header + self.filename + extra + len(filename), len(extra)) + return header + filename + extra @@ -359,17 +370,19 @@ def archive_footer(self): extract_version = zinfo.extract_version create_version = zinfo.create_version + filename, flag_bits = zinfo._encodeFilenameFlags() + centdir = struct.pack(structCentralDir, stringCentralDir, create_version, zinfo.create_system, extract_version, zinfo.reserved, - zinfo.flag_bits, zinfo.compress_type, dostime, dosdate, + flag_bits, zinfo.compress_type, dostime, dosdate, zinfo.CRC, compress_size, file_size, - len(zinfo.filename), len(extra_data), len(zinfo.comment), + len(filename), len(extra_data), len(zinfo.comment), 0, zinfo.internal_attr, zinfo.external_attr, header_offset) data.append( self.update_data_ptr(centdir)) - data.append( self.update_data_ptr(zinfo.filename)) + data.append( self.update_data_ptr(filename)) data.append( self.update_data_ptr(extra_data)) data.append( self.update_data_ptr(zinfo.comment))