summaryrefslogtreecommitdiffstats
path: root/Lib/zipfile.py
diff options
context:
space:
mode:
authorGregory P. Smith <greg@krypto.org>2013-02-01 19:31:31 (GMT)
committerGregory P. Smith <greg@krypto.org>2013-02-01 19:31:31 (GMT)
commit193e1be72d2f9bb45e054b38dd9ed1090c45f3bf (patch)
treeed26dbea67939a7a01ea3ee20190285d97fb7645 /Lib/zipfile.py
parent0ecd30b4af4f5bd3c9e884a608e0a256ffe8f5fa (diff)
parentb47acbf46abd425f69dcc03e9b4f0c7f7c321ac2 (diff)
downloadcpython-193e1be72d2f9bb45e054b38dd9ed1090c45f3bf.zip
cpython-193e1be72d2f9bb45e054b38dd9ed1090c45f3bf.tar.gz
cpython-193e1be72d2f9bb45e054b38dd9ed1090c45f3bf.tar.bz2
Fixes Issue #6972: The zipfile module no longer overwrites files outside of
its destination path when extracting malicious zip files.
Diffstat (limited to 'Lib/zipfile.py')
-rw-r--r--Lib/zipfile.py27
1 files changed, 16 insertions, 11 deletions
diff --git a/Lib/zipfile.py b/Lib/zipfile.py
index 235b811..f5c3f17 100644
--- a/Lib/zipfile.py
+++ b/Lib/zipfile.py
@@ -1229,17 +1229,22 @@ class ZipFile:
"""
# build the destination pathname, replacing
# forward slashes to platform specific separators.
- # Strip trailing path separator, unless it represents the root.
- if (targetpath[-1:] in (os.path.sep, os.path.altsep)
- and len(os.path.splitdrive(targetpath)[1]) > 1):
- targetpath = targetpath[:-1]
-
- # don't include leading "/" from file name if present
- if member.filename[0] == '/':
- targetpath = os.path.join(targetpath, member.filename[1:])
- else:
- targetpath = os.path.join(targetpath, member.filename)
-
+ arcname = member.filename.replace('/', os.path.sep)
+
+ if os.path.altsep:
+ arcname = arcname.replace(os.path.altsep, os.path.sep)
+ # interpret absolute pathname as relative, remove drive letter or
+ # UNC path, redundant separators, "." and ".." components.
+ arcname = os.path.splitdrive(arcname)[1]
+ arcname = os.path.sep.join(x for x in arcname.split(os.path.sep)
+ if x not in ('', os.path.curdir, os.path.pardir))
+ # filter illegal characters on Windows
+ if os.path.sep == '\\':
+ illegal = ':<>|"?*'
+ table = str.maketrans(illegal, '_' * len(illegal))
+ arcname = arcname.translate(table)
+
+ targetpath = os.path.join(targetpath, arcname)
targetpath = os.path.normpath(targetpath)
# Create all upper directories if necessary.