diff options
author | Martin v. Löwis <martin@v.loewis.de> | 2008-05-05 17:44:38 (GMT) |
---|---|---|
committer | Martin v. Löwis <martin@v.loewis.de> | 2008-05-05 17:44:38 (GMT) |
commit | 8570f6a402abc77646b491762fb61a1fa968f432 (patch) | |
tree | bd06ccdc9801866f4a0f4ccdbcb7ccb580ee7ffb | |
parent | 43653bbdab49e677862ea2fae94d202e0d86058a (diff) | |
download | cpython-8570f6a402abc77646b491762fb61a1fa968f432.zip cpython-8570f6a402abc77646b491762fb61a1fa968f432.tar.gz cpython-8570f6a402abc77646b491762fb61a1fa968f432.tar.bz2 |
Merged revisions 62724 via svnmerge from
svn+ssh://pythondev@svn.python.org/python/trunk
........
r62724 | martin.v.loewis | 2008-05-05 19:16:58 +0200 (Mo, 05 Mai 2008) | 2 lines
Issue #1734346: Support Unicode file names for zipfiles.
........
-rw-r--r-- | Lib/test/test_zipfile.py | 8 | ||||
-rw-r--r-- | Lib/zipfile.py | 29 |
2 files changed, 30 insertions, 7 deletions
diff --git a/Lib/test/test_zipfile.py b/Lib/test/test_zipfile.py index c4f8f79..c69892b 100644 --- a/Lib/test/test_zipfile.py +++ b/Lib/test/test_zipfile.py @@ -541,6 +541,14 @@ class PyZipFileTests(unittest.TestCase): class OtherTests(unittest.TestCase): + def testUnicodeFilenames(self): + zf = zipfile.ZipFile(TESTFN, "w") + zf.writestr("foo.txt", "Test for unicode filename") + zf.writestr("fo\xf6.txt", "Test for unicode filename") + zf.close() + zf = zipfile.ZipFile(TESTFN, "w") + + def testCreateNonExistentFileForAppend(self): if os.path.exists(TESTFN): os.unlink(TESTFN) diff --git a/Lib/zipfile.py b/Lib/zipfile.py index 2672d0a..73b62af 100644 --- a/Lib/zipfile.py +++ b/Lib/zipfile.py @@ -257,12 +257,19 @@ class ZipInfo (object): 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.encode("utf-8") + extra + len(filename), len(extra)) + return header + filename + extra + + def _encodeFilenameFlags(self): + try: + return self.filename.encode('ascii'), self.flag_bits + except UnicodeEncodeError: + return self.filename.encode('utf-8'), self.flag_bits | 0x800 def _decodeExtra(self): # Try to decode the extra field. @@ -681,8 +688,15 @@ class ZipFile: if self.debug > 2: print(centdir) filename = fp.read(centdir[_CD_FILENAME_LENGTH]) + flags = centdir[5] + if flags & 0x800: + # UTF-8 file names extension + filename = filename.decode('utf-8') + else: + # Historical ZIP filename encoding + filename = filename.decode('cp437') # Create ZipInfo instance to store file information - x = ZipInfo(filename.decode("utf-8")) + x = ZipInfo(filename) x.extra = fp.read(centdir[_CD_EXTRA_FIELD_LENGTH]) x.comment = fp.read(centdir[_CD_COMMENT_LENGTH]) total = (total + centdir[_CD_FILENAME_LENGTH] @@ -1067,16 +1081,17 @@ class ZipFile: 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) self.fp.write(centdir) - self.fp.write(zinfo.filename.encode("utf-8")) + self.fp.write(filename) self.fp.write(extra_data) self.fp.write(zinfo.comment) |