Commit 108a7a31 authored by Serhiy Storchaka's avatar Serhiy Storchaka

Issue #17656: Fix extraction of zip files with unicode member paths.

parent 4ac42666
...@@ -18,7 +18,7 @@ from tempfile import TemporaryFile ...@@ -18,7 +18,7 @@ from tempfile import TemporaryFile
from random import randint, random from random import randint, random
from unittest import skipUnless 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" TESTFN2 = TESTFN + "2"
TESTFNDIR = TESTFN + "d" TESTFNDIR = TESTFN + "d"
...@@ -424,6 +424,25 @@ class TestsWithSourceFile(unittest.TestCase): ...@@ -424,6 +424,25 @@ class TestsWithSourceFile(unittest.TestCase):
with open(filename, 'rb') as f: with open(filename, 'rb') as f:
self.assertEqual(f.read(), content) 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): def test_extract_hackers_arcnames(self):
hacknames = [ hacknames = [
('../foo/bar', 'foo/bar'), ('../foo/bar', 'foo/bar'),
......
...@@ -1053,7 +1053,10 @@ class ZipFile(object): ...@@ -1053,7 +1053,10 @@ class ZipFile(object):
if os.path.sep == '\\': if os.path.sep == '\\':
# filter illegal characters on Windows # filter illegal characters on Windows
illegal = ':<>|"?*' 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) arcname = arcname.translate(table)
# remove trailing dots # remove trailing dots
arcname = (x.rstrip('.') for x in arcname.split(os.path.sep)) arcname = (x.rstrip('.') for x in arcname.split(os.path.sep))
......
...@@ -22,6 +22,8 @@ Core and Builtins ...@@ -22,6 +22,8 @@ Core and Builtins
Library Library
------- -------
- Issue #17656: Fix extraction of zip files with unicode member paths.
- Issue #13355: Raise ValueError on random.triangular call with invalid params. - Issue #13355: Raise ValueError on random.triangular call with invalid params.
Initial patch by Yuriy Senko. Initial patch by Yuriy Senko.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment