summaryrefslogtreecommitdiff
path: root/Lib/zipfile.py
diff options
context:
space:
mode:
authorGregory P. Smith <greg@krypto.org>2013-02-03 00:36:32 -0800
committerGregory P. Smith <greg@krypto.org>2013-02-03 00:36:32 -0800
commit09aa752067863ecf749010b315227f41e25571a5 (patch)
tree90f5dd649fbaa8429abc3bd4bb9303b05d7bcc84 /Lib/zipfile.py
parent6d29628d6bb083f63b94efeba6103522681bc872 (diff)
downloadcpython-git-09aa752067863ecf749010b315227f41e25571a5.tar.gz
Refactor recently added bugfix into more testable code by using a
method for windows file name sanitization. Splits the unittest up into several based on platform.
Diffstat (limited to 'Lib/zipfile.py')
-rw-r--r--Lib/zipfile.py26
1 files changed, 19 insertions, 7 deletions
diff --git a/Lib/zipfile.py b/Lib/zipfile.py
index 8b355d6acd..3448c61795 100644
--- a/Lib/zipfile.py
+++ b/Lib/zipfile.py
@@ -883,6 +883,7 @@ class ZipFile:
"""
fp = None # Set here since __del__ checks it
+ _windows_illegal_name_trans_table = None
def __init__(self, file, mode="r", compression=ZIP_STORED, allowZip64=False):
"""Open the ZIP file with mode read "r", write "w" or append "a"."""
@@ -1223,6 +1224,21 @@ class ZipFile:
for zipinfo in members:
self.extract(zipinfo, path, pwd)
+ @classmethod
+ def _sanitize_windows_name(cls, arcname, pathsep):
+ """Replace bad characters and remove trailing dots from parts."""
+ table = cls._windows_illegal_name_trans_table
+ if not table:
+ illegal = ':<>|"?*'
+ table = str.maketrans(illegal, '_' * len(illegal))
+ cls._windows_illegal_name_trans_table = table
+ arcname = arcname.translate(table)
+ # remove trailing dots
+ arcname = (x.rstrip('.') for x in arcname.split(pathsep))
+ # rejoin, removing empty parts.
+ arcname = pathsep.join(x for x in arcname if x)
+ return arcname
+
def _extract_member(self, member, targetpath, pwd):
"""Extract the ZipInfo object 'member' to a physical
file on the path targetpath.
@@ -1236,16 +1252,12 @@ class ZipFile:
# interpret absolute pathname as relative, remove drive letter or
# UNC path, redundant separators, "." and ".." components.
arcname = os.path.splitdrive(arcname)[1]
+ invalid_path_parts = ('', os.path.curdir, os.path.pardir)
arcname = os.path.sep.join(x for x in arcname.split(os.path.sep)
- if x not in ('', os.path.curdir, os.path.pardir))
+ if x not in invalid_path_parts)
if os.path.sep == '\\':
# filter illegal characters on Windows
- illegal = ':<>|"?*'
- table = str.maketrans(illegal, '_' * len(illegal))
- arcname = arcname.translate(table)
- # remove trailing dots
- arcname = (x.rstrip('.') for x in arcname.split(os.path.sep))
- arcname = os.path.sep.join(x for x in arcname if x)
+ arcname = self._sanitize_windows_name(arcname, os.path.sep)
targetpath = os.path.join(targetpath, arcname)
targetpath = os.path.normpath(targetpath)