summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSerhiy Storchaka <storchaka@gmail.com>2013-04-13 09:28:17 (GMT)
committerSerhiy Storchaka <storchaka@gmail.com>2013-04-13 09:28:17 (GMT)
commit6fa83f99af03cc84caccc19988c1e346958789cb (patch)
treeeac7f6ff8e977c5d31ec4c1241ea26141d68bada
parentb6cdae3db4ebcd34ba7039b2b1423f5ff4e235d6 (diff)
downloadcpython-6fa83f99af03cc84caccc19988c1e346958789cb.zip
cpython-6fa83f99af03cc84caccc19988c1e346958789cb.tar.gz
cpython-6fa83f99af03cc84caccc19988c1e346958789cb.tar.bz2
Issue #17656: Fix extraction of zip files with unicode member paths.
-rw-r--r--Lib/test/test_zipfile.py21
-rw-r--r--Lib/zipfile.py5
-rw-r--r--Misc/NEWS2
3 files changed, 26 insertions, 2 deletions
diff --git a/Lib/test/test_zipfile.py b/Lib/test/test_zipfile.py
index c26ca80..f960b6c 100644
--- a/Lib/test/test_zipfile.py
+++ b/Lib/test/test_zipfile.py
@@ -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'),
diff --git a/Lib/zipfile.py b/Lib/zipfile.py
index 9d1a984..6639317 100644
--- a/Lib/zipfile.py
+++ b/Lib/zipfile.py
@@ -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))
diff --git a/Misc/NEWS b/Misc/NEWS
index c4d9635..ee5393c 100644
--- 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.