|
32 | 32 | lzma = None |
33 | 33 |
|
34 | 34 | from backports import zstd |
| 35 | +from backports.zstd._compat import os_path_splitroot |
35 | 36 |
|
36 | 37 | __all__ = ["BadZipFile", "BadZipfile", "error", |
37 | 38 | "ZIP_STORED", "ZIP_DEFLATED", "ZIP_BZIP2", "ZIP_LZMA", |
@@ -1405,6 +1406,7 @@ class ZipFile: |
1405 | 1406 |
|
1406 | 1407 | fp = None # Set here since __del__ checks it |
1407 | 1408 | _windows_illegal_name_trans_table = None |
| 1409 | + _ignore_invalid_names = False |
1408 | 1410 |
|
1409 | 1411 | def __init__(self, file, mode="r", compression=ZIP_STORED, allowZip64=True, |
1410 | 1412 | compresslevel=None, *, strict_timestamps=True, metadata_encoding=None): |
@@ -1890,21 +1892,31 @@ def _extract_member(self, member, targetpath, pwd): |
1890 | 1892 |
|
1891 | 1893 | # build the destination pathname, replacing |
1892 | 1894 | # forward slashes to platform specific separators. |
1893 | | - arcname = member.filename.replace('/', os.path.sep) |
1894 | | - |
1895 | | - if os.path.altsep: |
| 1895 | + arcname = member.filename |
| 1896 | + if os.path.sep != '/': |
| 1897 | + arcname = arcname.replace('/', os.path.sep) |
| 1898 | + if os.path.altsep and os.path.altsep != '/': |
1896 | 1899 | arcname = arcname.replace(os.path.altsep, os.path.sep) |
1897 | 1900 | # interpret absolute pathname as relative, remove drive letter or |
1898 | 1901 | # UNC path, redundant separators, "." and ".." components. |
1899 | | - arcname = os.path.splitdrive(arcname)[1] |
| 1902 | + drive, root, arcname = os_path_splitroot(arcname) |
| 1903 | + if self._ignore_invalid_names and (drive or root): |
| 1904 | + return None |
| 1905 | + if self._ignore_invalid_names and os.path.pardir in arcname.split(os.path.sep): |
| 1906 | + return None |
1900 | 1907 | invalid_path_parts = ('', os.path.curdir, os.path.pardir) |
1901 | 1908 | arcname = os.path.sep.join(x for x in arcname.split(os.path.sep) |
1902 | 1909 | if x not in invalid_path_parts) |
1903 | 1910 | if os.path.sep == '\\': |
1904 | 1911 | # filter illegal characters on Windows |
1905 | | - arcname = self._sanitize_windows_name(arcname, os.path.sep) |
| 1912 | + arcname2 = self._sanitize_windows_name(arcname, os.path.sep) |
| 1913 | + if self._ignore_invalid_names and arcname2 != arcname: |
| 1914 | + return None |
| 1915 | + arcname = arcname2 |
1906 | 1916 |
|
1907 | 1917 | if not arcname and not member.is_dir(): |
| 1918 | + if self._ignore_invalid_names: |
| 1919 | + return None |
1908 | 1920 | raise ValueError("Empty filename.") |
1909 | 1921 |
|
1910 | 1922 | targetpath = os.path.join(targetpath, arcname) |
|
0 commit comments