]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
Issue #17656: Fix extraction of zip files with unicode member paths.
authorSerhiy Storchaka <storchaka@gmail.com>
Sat, 13 Apr 2013 09:28:17 +0000 (12:28 +0300)
committerSerhiy Storchaka <storchaka@gmail.com>
Sat, 13 Apr 2013 09:28:17 +0000 (12:28 +0300)
Lib/test/test_zipfile.py
Lib/zipfile.py
Misc/NEWS

index c26ca80b0a9d1bc1d3985ad411ff4d6fd46dfa74..f960b6c7d4f6dae14cb2ae091b47506b9bd7937a 100644 (file)
@@ -18,7 +18,7 @@ from tempfile import TemporaryFile
 from random import randint, random
 from unittest import skipUnless
 
-from test.test_support import TESTFN, run_unittest, findfile, unlink
+from test.test_support import TESTFN, TESTFN_UNICODE, run_unittest, findfile, unlink
 
 TESTFN2 = TESTFN + "2"
 TESTFNDIR = TESTFN + "d"
@@ -424,6 +424,25 @@ class TestsWithSourceFile(unittest.TestCase):
         with open(filename, 'rb') as f:
             self.assertEqual(f.read(), content)
 
+    def test_extract_unicode_filenames(self):
+        fnames = [u'foo.txt', os.path.basename(TESTFN_UNICODE)]
+        content = 'Test for unicode filename'
+        with zipfile.ZipFile(TESTFN2, "w", zipfile.ZIP_STORED) as zipfp:
+            for fname in fnames:
+                zipfp.writestr(fname, content)
+
+        with zipfile.ZipFile(TESTFN2, "r") as zipfp:
+            for fname in fnames:
+                writtenfile = zipfp.extract(fname)
+
+                # make sure it was written to the right place
+                correctfile = os.path.join(os.getcwd(), fname)
+                correctfile = os.path.normpath(correctfile)
+                self.assertEqual(writtenfile, correctfile)
+
+                self.check_file(writtenfile, content)
+                os.remove(writtenfile)
+
     def test_extract_hackers_arcnames(self):
         hacknames = [
             ('../foo/bar', 'foo/bar'),
index 9d1a98479db6e2ffb2d6afca1b42eb3b74484bdb..6639317537bbf7d95c830553b6124dbf24849bb4 100644 (file)
@@ -1053,7 +1053,10 @@ class ZipFile(object):
         if os.path.sep == '\\':
             # filter illegal characters on Windows
             illegal = ':<>|"?*'
-            table = string.maketrans(illegal, '_' * len(illegal))
+            if isinstance(arcname, unicode):
+                table = {ord(c): ord('_') for c in illegal}
+            else:
+                table = string.maketrans(illegal, '_' * len(illegal))
             arcname = arcname.translate(table)
             # remove trailing dots
             arcname = (x.rstrip('.') for x in arcname.split(os.path.sep))
index c4d9635a8b30b92487b54d8ae378d148ebebe1df..ee5393c286779c82f25bee4fb4d350590041343f 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -22,6 +22,8 @@ Core and Builtins
 Library
 -------
 
+- Issue #17656: Fix extraction of zip files with unicode member paths.
+
 - Issue #13355: Raise ValueError on random.triangular call with invalid params.
   Initial patch by Yuriy Senko.