Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commite0264a6

Browse files
authored
[3.10]gh-122905: Sanitize names in zipfile.Path. (GH-122906) (#123160)
[3.10] [3.11]gh-122905: Sanitize names in zipfile.Path. (GH-122906) (GH-122925)*gh-122905: Sanitize names in zipfile.Path. (GH-122906)Ported from zipp 3.19.1; refjaraco/zippGH-119.(cherry picked from commit9cd0326)* [3.11]gh-122905: Sanitize names in zipfile.Path. (GH-122906)Ported from zipp 3.19.1; refjaraco/zippGH-119.(cherry picked from commit9cd0326)(cherry picked from commit795f259)
1 parent31302f5 commite0264a6

File tree

3 files changed

+78
-1
lines changed

3 files changed

+78
-1
lines changed

‎Lib/test/test_zipfile.py‎

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3280,6 +3280,23 @@ def test_extract_orig_with_implied_dirs(self, alpharep):
32803280
zipfile.Path(zf)
32813281
zf.extractall(source_path.parent)
32823282

3283+
deftest_malformed_paths(self):
3284+
"""
3285+
Path should handle malformed paths.
3286+
"""
3287+
data=io.BytesIO()
3288+
zf=zipfile.ZipFile(data,"w")
3289+
zf.writestr("/one-slash.txt",b"content")
3290+
zf.writestr("//two-slash.txt",b"content")
3291+
zf.writestr("../parent.txt",b"content")
3292+
zf.filename=''
3293+
root=zipfile.Path(zf)
3294+
assertlist(map(str,root.iterdir()))== [
3295+
'one-slash.txt',
3296+
'two-slash.txt',
3297+
'parent.txt',
3298+
]
3299+
32833300

32843301
classStripExtraTests(unittest.TestCase):
32853302
# Note: all of the "z" characters are technically invalid, but up

‎Lib/zipfile.py‎

Lines changed: 60 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
importitertools
1010
importos
1111
importposixpath
12+
importre
1213
importshutil
1314
importstat
1415
importstruct
@@ -2182,7 +2183,65 @@ def _difference(minuend, subtrahend):
21822183
returnitertools.filterfalse(set(subtrahend).__contains__,minuend)
21832184

21842185

2185-
classCompleteDirs(ZipFile):
2186+
classSanitizedNames:
2187+
"""
2188+
ZipFile mix-in to ensure names are sanitized.
2189+
"""
2190+
2191+
defnamelist(self):
2192+
returnlist(map(self._sanitize,super().namelist()))
2193+
2194+
@staticmethod
2195+
def_sanitize(name):
2196+
r"""
2197+
Ensure a relative path with posix separators and no dot names.
2198+
Modeled after
2199+
https://github.com/python/cpython/blob/bcc1be39cb1d04ad9fc0bd1b9193d3972835a57c/Lib/zipfile/__init__.py#L1799-L1813
2200+
but provides consistent cross-platform behavior.
2201+
>>> san = SanitizedNames._sanitize
2202+
>>> san('/foo/bar')
2203+
'foo/bar'
2204+
>>> san('//foo.txt')
2205+
'foo.txt'
2206+
>>> san('foo/.././bar.txt')
2207+
'foo/bar.txt'
2208+
>>> san('foo../.bar.txt')
2209+
'foo../.bar.txt'
2210+
>>> san('\\foo\\bar.txt')
2211+
'foo/bar.txt'
2212+
>>> san('D:\\foo.txt')
2213+
'D/foo.txt'
2214+
>>> san('\\\\server\\share\\file.txt')
2215+
'server/share/file.txt'
2216+
>>> san('\\\\?\\GLOBALROOT\\Volume3')
2217+
'?/GLOBALROOT/Volume3'
2218+
>>> san('\\\\.\\PhysicalDrive1\\root')
2219+
'PhysicalDrive1/root'
2220+
Retain any trailing slash.
2221+
>>> san('abc/')
2222+
'abc/'
2223+
Raises a ValueError if the result is empty.
2224+
>>> san('../..')
2225+
Traceback (most recent call last):
2226+
...
2227+
ValueError: Empty filename
2228+
"""
2229+
2230+
defallowed(part):
2231+
returnpartandpartnotin {'..','.'}
2232+
2233+
# Remove the drive letter.
2234+
# Don't use ntpath.splitdrive, because that also strips UNC paths
2235+
bare=re.sub('^([A-Z]):',r'\1',name,flags=re.IGNORECASE)
2236+
clean=bare.replace('\\','/')
2237+
parts=clean.split('/')
2238+
joined='/'.join(filter(allowed,parts))
2239+
ifnotjoined:
2240+
raiseValueError("Empty filename")
2241+
returnjoined+'/'*name.endswith('/')
2242+
2243+
2244+
classCompleteDirs(SanitizedNames,ZipFile):
21862245
"""
21872246
A ZipFile subclass that ensures that implied directories
21882247
are always included in the namelist.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
:class:`zipfile.Path` objects now sanitize names from the zipfile.

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp