From 5e977c044ae65ad32304a6e1f28480967bcd7ac2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 19 Jun 2024 00:02:06 -0700 Subject: [PATCH] Bump zipp from 3.18.2 to 3.19.2 (#2343) * Bump zipp from 3.18.2 to 3.19.2 Bumps [zipp](https://github.com/jaraco/zipp) from 3.18.2 to 3.19.2. - [Release notes](https://github.com/jaraco/zipp/releases) - [Changelog](https://github.com/jaraco/zipp/blob/main/NEWS.rst) - [Commits](https://github.com/jaraco/zipp/compare/v3.18.2...v3.19.2) --- updated-dependencies: - dependency-name: zipp dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] * Update zipp==3.19.2 --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: JonnyWong16 <9099342+JonnyWong16@users.noreply.github.com> [skip ci] --- lib/zipp/__init__.py | 76 +++++++++++++++++++++++++++++++++++++++++--- requirements.txt | 2 +- 2 files changed, 73 insertions(+), 5 deletions(-) diff --git a/lib/zipp/__init__.py b/lib/zipp/__init__.py index df3293aa..d65297b8 100644 --- a/lib/zipp/__init__.py +++ b/lib/zipp/__init__.py @@ -5,6 +5,7 @@ import itertools import contextlib import pathlib import re +import stat import sys from .compat.py310 import text_encoding @@ -85,7 +86,69 @@ class InitializedState: super().__init__(*args, **kwargs) -class CompleteDirs(InitializedState, zipfile.ZipFile): +class SanitizedNames: + """ + ZipFile mix-in to ensure names are sanitized. + """ + + def namelist(self): + return list(map(self._sanitize, super().namelist())) + + @staticmethod + def _sanitize(name): + r""" + Ensure a relative path with posix separators and no dot names. + + Modeled after + https://github.com/python/cpython/blob/bcc1be39cb1d04ad9fc0bd1b9193d3972835a57c/Lib/zipfile/__init__.py#L1799-L1813 + but provides consistent cross-platform behavior. + + >>> san = SanitizedNames._sanitize + >>> san('/foo/bar') + 'foo/bar' + >>> san('//foo.txt') + 'foo.txt' + >>> san('foo/.././bar.txt') + 'foo/bar.txt' + >>> san('foo../.bar.txt') + 'foo../.bar.txt' + >>> san('\\foo\\bar.txt') + 'foo/bar.txt' + >>> san('D:\\foo.txt') + 'D/foo.txt' + >>> san('\\\\server\\share\\file.txt') + 'server/share/file.txt' + >>> san('\\\\?\\GLOBALROOT\\Volume3') + '?/GLOBALROOT/Volume3' + >>> san('\\\\.\\PhysicalDrive1\\root') + 'PhysicalDrive1/root' + + Retain any trailing slash. + >>> san('abc/') + 'abc/' + + Raises a ValueError if the result is empty. + >>> san('../..') + Traceback (most recent call last): + ... + ValueError: Empty filename + """ + + def allowed(part): + return part and part not in {'..', '.'} + + # Remove the drive letter. + # Don't use ntpath.splitdrive, because that also strips UNC paths + bare = re.sub('^([A-Z]):', r'\1', name, flags=re.IGNORECASE) + clean = bare.replace('\\', '/') + parts = clean.split('/') + joined = '/'.join(filter(allowed, parts)) + if not joined: + raise ValueError("Empty filename") + return joined + '/' * name.endswith('/') + + +class CompleteDirs(InitializedState, SanitizedNames, zipfile.ZipFile): """ A ZipFile subclass that ensures that implied directories are always included in the namelist. @@ -188,7 +251,10 @@ def _extract_text_encoding(encoding=None, *args, **kwargs): class Path: """ - A pathlib-compatible interface for zip files. + A :class:`importlib.resources.abc.Traversable` interface for zip files. + + Implements many of the features users enjoy from + :class:`pathlib.Path`. Consider a zip file with this structure:: @@ -391,9 +457,11 @@ class Path: def is_symlink(self): """ - Return whether this path is a symlink. Always false (python/cpython#82102). + Return whether this path is a symlink. """ - return False + info = self.root.getinfo(self.at) + mode = info.external_attr >> 16 + return stat.S_ISLNK(mode) def glob(self, pattern): if not pattern: diff --git a/requirements.txt b/requirements.txt index a0c32ad9..7d8c9cb7 100644 --- a/requirements.txt +++ b/requirements.txt @@ -47,7 +47,7 @@ urllib3<2 webencodings==0.5.1 websocket-client==1.8.0 xmltodict==0.13.0 -zipp==3.18.2 +zipp==3.19.2 # configobj==5.1.0 # sgmllib3k==1.0.0