From af132529ea075cecc6c37f41d48be58d5d5483be Mon Sep 17 00:00:00 2001 From: eabdullin Date: Wed, 14 May 2025 18:02:33 +0000 Subject: [PATCH] import UBI python-pip-23.3.2-7.el10 --- .gitignore | 2 +- .python-pip.metadata | 1 - SOURCES/CVE-2018-18074.patch | 90 -- SOURCES/CVE-2018-20060.patch | 94 -- SOURCES/CVE-2019-11236.patch | 43 - SOURCES/CVE-2019-11324.patch | 26 - SOURCES/CVE-2021-3572.patch | 53 - ...given-prefix-from-wheel-RECORD-files.patch | 95 -- SOURCES/cve-2007-4559-tarfile.patch | 47 - SOURCES/dummy-certifi.patch | 15 - ...ng-when-running-with-root-privileges.patch | 44 - ...ctory-traversal-security-issue-tests.patch | 122 --- ...p-directory-traversal-security-issue.patch | 79 -- SOURCES/pip-nowarn-upgrade.patch | 36 - ...existing-dist-only-if-path-conflicts.patch | 97 -- SOURCES/skip_yanked_releases.patch | 91 -- SPECS/python-pip.spec | 688 ------------- cve-2007-4559-tarfile.patch | 85 ++ dummy-certifi.patch | 128 +++ no-version-warning.patch | 16 + nowarn-pip._internal.main.patch | 76 ++ python-pip.spec | 906 ++++++++++++++++++ ...existing-dist-only-if-path-conflicts.patch | 115 +++ sources | 1 + 24 files changed, 1328 insertions(+), 1622 deletions(-) delete mode 100644 .python-pip.metadata delete mode 100644 SOURCES/CVE-2018-18074.patch delete mode 100644 SOURCES/CVE-2018-20060.patch delete mode 100644 SOURCES/CVE-2019-11236.patch delete mode 100644 SOURCES/CVE-2019-11324.patch delete mode 100644 SOURCES/CVE-2021-3572.patch delete mode 100644 SOURCES/allow-stripping-given-prefix-from-wheel-RECORD-files.patch delete mode 100644 SOURCES/cve-2007-4559-tarfile.patch delete mode 100644 SOURCES/dummy-certifi.patch delete mode 100644 SOURCES/emit-a-warning-when-running-with-root-privileges.patch delete mode 100644 SOURCES/pip-directory-traversal-security-issue-tests.patch delete mode 100644 SOURCES/pip-directory-traversal-security-issue.patch delete mode 100644 SOURCES/pip-nowarn-upgrade.patch delete mode 100644 SOURCES/remove-existing-dist-only-if-path-conflicts.patch delete mode 100644 SOURCES/skip_yanked_releases.patch delete mode 100644 SPECS/python-pip.spec create mode 100644 cve-2007-4559-tarfile.patch create mode 100644 dummy-certifi.patch create mode 100644 no-version-warning.patch create mode 100644 nowarn-pip._internal.main.patch create mode 100644 python-pip.spec create mode 100644 remove-existing-dist-only-if-path-conflicts.patch create mode 100644 sources diff --git a/.gitignore b/.gitignore index a3caa7a..18ae4ff 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1 @@ -SOURCES/pip-9.0.3.tar.gz +pip-23.3.2.tar.gz diff --git a/.python-pip.metadata b/.python-pip.metadata deleted file mode 100644 index 3bc8f51..0000000 --- a/.python-pip.metadata +++ /dev/null @@ -1 +0,0 @@ -1f5f44d433ca599d40f8e46f440479b2c73802d8 SOURCES/pip-9.0.3.tar.gz diff --git a/SOURCES/CVE-2018-18074.patch b/SOURCES/CVE-2018-18074.patch deleted file mode 100644 index 21a9e7f..0000000 --- a/SOURCES/CVE-2018-18074.patch +++ /dev/null @@ -1,90 +0,0 @@ -From ffbfdb53681207b23bcf67dd76368ad6185ade24 Mon Sep 17 00:00:00 2001 -From: Lumir Balhar -Date: Thu, 16 Jan 2020 07:06:09 +0100 -Subject: [PATCH] Fix for CVE-2018-18074 - -This patch contains the fix for CVE-2018-18074 and -a subsequent regression fix combined in one. ---- - sessions.py | 36 +++++++++++++++++++++++++++++------- - utils.py | 1 + - 2 files changed, 30 insertions(+), 7 deletions(-) - -diff --git a/sessions.py b/sessions.py -index 6570e73..4038047 100644 ---- a/sessions.py -+++ b/sessions.py -@@ -29,7 +29,7 @@ from .adapters import HTTPAdapter - - from .utils import ( - requote_uri, get_environ_proxies, get_netrc_auth, should_bypass_proxies, -- get_auth_from_url, rewind_body -+ get_auth_from_url, rewind_body, DEFAULT_PORTS - ) - - from .status_codes import codes -@@ -116,6 +116,32 @@ class SessionRedirectMixin(object): - return to_native_string(location, 'utf8') - return None - -+ -+ def should_strip_auth(self, old_url, new_url): -+ """Decide whether Authorization header should be removed when redirecting""" -+ old_parsed = urlparse(old_url) -+ new_parsed = urlparse(new_url) -+ if old_parsed.hostname != new_parsed.hostname: -+ return True -+ # Special case: allow http -> https redirect when using the standard -+ # ports. This isn't specified by RFC 7235, but is kept to avoid -+ # breaking backwards compatibility with older versions of requests -+ # that allowed any redirects on the same host. -+ if (old_parsed.scheme == 'http' and old_parsed.port in (80, None) -+ and new_parsed.scheme == 'https' and new_parsed.port in (443, None)): -+ return False -+ -+ # Handle default port usage corresponding to scheme. -+ changed_port = old_parsed.port != new_parsed.port -+ changed_scheme = old_parsed.scheme != new_parsed.scheme -+ default_port = (DEFAULT_PORTS.get(old_parsed.scheme, None), None) -+ if (not changed_scheme and old_parsed.port in default_port -+ and new_parsed.port in default_port): -+ return False -+ -+ # Standard case: root URI must match -+ return changed_port or changed_scheme -+ - def resolve_redirects(self, resp, req, stream=False, timeout=None, - verify=True, cert=None, proxies=None, yield_requests=False, **adapter_kwargs): - """Receives a Response. Returns a generator of Responses or Requests.""" -@@ -232,14 +258,10 @@ class SessionRedirectMixin(object): - headers = prepared_request.headers - url = prepared_request.url - -- if 'Authorization' in headers: -+ if 'Authorization' in headers and self.should_strip_auth(response.request.url, url): - # If we get redirected to a new host, we should strip out any - # authentication headers. -- original_parsed = urlparse(response.request.url) -- redirect_parsed = urlparse(url) -- -- if (original_parsed.hostname != redirect_parsed.hostname): -- del headers['Authorization'] -+ del headers['Authorization'] - - # .netrc might have more auth for us on our new host. - new_auth = get_netrc_auth(url) if self.trust_env else None -diff --git a/utils.py b/utils.py -index 5c47de9..5695ab0 100644 ---- a/utils.py -+++ b/utils.py -@@ -38,6 +38,7 @@ NETRC_FILES = ('.netrc', '_netrc') - - DEFAULT_CA_BUNDLE_PATH = certs.where() - -+DEFAULT_PORTS = {'http': 80, 'https': 443} - - if platform.system() == 'Windows': - # provide a proxy_bypass version on Windows without DNS lookups --- -2.24.1 - diff --git a/SOURCES/CVE-2018-20060.patch b/SOURCES/CVE-2018-20060.patch deleted file mode 100644 index cc3b741..0000000 --- a/SOURCES/CVE-2018-20060.patch +++ /dev/null @@ -1,94 +0,0 @@ -From c734f873270cf9ca414832423f7aad98443c379f Mon Sep 17 00:00:00 2001 -From: Lumir Balhar -Date: Thu, 9 Jan 2020 11:26:24 +0100 -Subject: [PATCH] CVE-2018-20060 - ---- - poolmanager.py | 11 ++++++++++- - util/retry.py | 12 +++++++++++- - 2 files changed, 21 insertions(+), 2 deletions(-) - -diff --git a/poolmanager.py b/poolmanager.py -index 4ae9174..bfa5115 100644 ---- a/poolmanager.py -+++ b/poolmanager.py -@@ -312,8 +312,9 @@ class PoolManager(RequestMethods): - - kw['assert_same_host'] = False - kw['redirect'] = False -+ - if 'headers' not in kw: -- kw['headers'] = self.headers -+ kw['headers'] = self.headers.copy() - - if self.proxy is not None and u.scheme == "http": - response = conn.urlopen(method, url, **kw) -@@ -335,6 +336,14 @@ class PoolManager(RequestMethods): - if not isinstance(retries, Retry): - retries = Retry.from_int(retries, redirect=redirect) - -+ # Strip headers marked as unsafe to forward to the redirected location. -+ # Check remove_headers_on_redirect to avoid a potential network call within -+ # conn.is_same_host() which may use socket.gethostbyname() in the future. -+ if (retries.remove_headers_on_redirect -+ and not conn.is_same_host(redirect_location)): -+ for header in retries.remove_headers_on_redirect: -+ kw['headers'].pop(header, None) -+ - try: - retries = retries.increment(method, url, response=response, _pool=conn) - except MaxRetryError: -diff --git a/util/retry.py b/util/retry.py -index c603cb4..0b83963 100644 ---- a/util/retry.py -+++ b/util/retry.py -@@ -126,6 +126,11 @@ class Retry(object): - exhausted, to raise a MaxRetryError, or to return a response with a - response code in the 3xx range. - -+ :param iterable remove_headers_on_redirect: -+ Sequence of headers to remove from the request when a response -+ indicating a redirect is returned before firing off the redirected -+ request -+ - :param bool raise_on_status: Similar meaning to ``raise_on_redirect``: - whether we should raise an exception, or return a response, - if status falls in ``status_forcelist`` range and retries have -@@ -144,6 +149,8 @@ class Retry(object): - DEFAULT_METHOD_WHITELIST = frozenset([ - 'HEAD', 'GET', 'PUT', 'DELETE', 'OPTIONS', 'TRACE']) - -+ DEFAULT_REDIRECT_HEADERS_BLACKLIST = frozenset(['Authorization']) -+ - RETRY_AFTER_STATUS_CODES = frozenset([413, 429, 503]) - - #: Maximum backoff time. -@@ -152,7 +159,8 @@ class Retry(object): - def __init__(self, total=10, connect=None, read=None, redirect=None, status=None, - method_whitelist=DEFAULT_METHOD_WHITELIST, status_forcelist=None, - backoff_factor=0, raise_on_redirect=True, raise_on_status=True, -- history=None, respect_retry_after_header=True): -+ history=None, respect_retry_after_header=True, -+ remove_headers_on_redirect=DEFAULT_REDIRECT_HEADERS_BLACKLIST): - - self.total = total - self.connect = connect -@@ -171,6 +179,7 @@ class Retry(object): - self.raise_on_status = raise_on_status - self.history = history or tuple() - self.respect_retry_after_header = respect_retry_after_header -+ self.remove_headers_on_redirect = remove_headers_on_redirect - - def new(self, **kw): - params = dict( -@@ -182,6 +191,7 @@ class Retry(object): - raise_on_redirect=self.raise_on_redirect, - raise_on_status=self.raise_on_status, - history=self.history, -+ remove_headers_on_redirect=self.remove_headers_on_redirect, - ) - params.update(kw) - return type(self)(**params) --- -2.24.1 - diff --git a/SOURCES/CVE-2019-11236.patch b/SOURCES/CVE-2019-11236.patch deleted file mode 100644 index f8729d5..0000000 --- a/SOURCES/CVE-2019-11236.patch +++ /dev/null @@ -1,43 +0,0 @@ -From b40eb0f43daecc6e2e3ce47b0be49cf570d02adc Mon Sep 17 00:00:00 2001 -From: Lumir Balhar -Date: Thu, 9 Jan 2020 11:14:58 +0100 -Subject: [PATCH] CVE-2019-9740 - ---- - util/url.py | 7 +++++++ - 1 file changed, 7 insertions(+) - -diff --git a/util/url.py b/util/url.py -index 6b6f996..2784c85 100644 ---- a/util/url.py -+++ b/util/url.py -@@ -1,5 +1,6 @@ - from __future__ import absolute_import - from collections import namedtuple -+import re - - from ..exceptions import LocationParseError - -@@ -10,6 +11,8 @@ url_attrs = ['scheme', 'auth', 'host', 'port', 'path', 'query', 'fragment'] - # urllib3 infers URLs without a scheme (None) to be http. - NORMALIZABLE_SCHEMES = ('http', 'https', None) - -+_contains_disallowed_url_pchar_re = re.compile('[\x00-\x20\x7f]') -+from ..packages.six.moves.urllib.parse import quote - - class Url(namedtuple('Url', url_attrs)): - """ -@@ -155,6 +158,10 @@ def parse_url(url): - # Empty - return Url() - -+ # Prevent CVE-2019-9740. -+ # adapted from https://github.com/python/cpython/pull/12755 -+ url = _contains_disallowed_url_pchar_re.sub(lambda match: quote(match.group()), url) -+ - scheme = None - auth = None - host = None --- -2.24.1 - diff --git a/SOURCES/CVE-2019-11324.patch b/SOURCES/CVE-2019-11324.patch deleted file mode 100644 index b1016ab..0000000 --- a/SOURCES/CVE-2019-11324.patch +++ /dev/null @@ -1,26 +0,0 @@ -From 54e768a6dbe3cadeb456dea37bbeaf6e1e17e87c Mon Sep 17 00:00:00 2001 -From: Lumir Balhar -Date: Thu, 9 Jan 2020 10:47:27 +0100 -Subject: [PATCH] CVE-2019-11324 Certification mishandle when error should be - thrown - ---- - util/ssl_.py | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/util/ssl_.py b/util/ssl_.py -index 32fd9ed..f9f12ff 100644 ---- a/util/ssl_.py -+++ b/util/ssl_.py -@@ -319,7 +319,7 @@ def ssl_wrap_socket(sock, keyfile=None, certfile=None, cert_reqs=None, - if e.errno == errno.ENOENT: - raise SSLError(e) - raise -- elif getattr(context, 'load_default_certs', None) is not None: -+ elif ssl_context is None and hasattr(context, 'load_default_certs'): - # try to load OS default certs; works well on Windows (require Python3.4+) - context.load_default_certs() - --- -2.24.1 - diff --git a/SOURCES/CVE-2021-3572.patch b/SOURCES/CVE-2021-3572.patch deleted file mode 100644 index b1d0a62..0000000 --- a/SOURCES/CVE-2021-3572.patch +++ /dev/null @@ -1,53 +0,0 @@ -Backport of https://github.com/pypa/pip/pull/9827 with parts of -https://github.com/pypa/pip/pull/4690 to make it work with pip v9.0.1 -diff --git a/pip/vcs/git.py b/pip/vcs/git.py -index 2187dd8..d1502f8 100644 ---- a/pip/vcs/git.py -+++ b/pip/vcs/git.py -@@ -81,7 +81,7 @@ class Git(VersionControl): - and branches may need origin/ as a prefix. - Returns the SHA1 of the branch or tag if found. - """ -- revisions = self.get_short_refs(dest) -+ revisions = self.get_short_refs(dest, rev) - - origin_rev = 'origin/%s' % rev - if origin_rev in revisions: -@@ -171,12 +171,20 @@ class Git(VersionControl): - ['rev-parse', 'HEAD'], show_stdout=False, cwd=location) - return current_rev.strip() - -- def get_full_refs(self, location): -+ def get_full_refs(self, location, pattern=''): - """Yields tuples of (commit, ref) for branches and tags""" -- output = self.run_command(['show-ref'], -+ output = self.run_command(['show-ref', pattern], - show_stdout=False, cwd=location) -- for line in output.strip().splitlines(): -- commit, ref = line.split(' ', 1) -+ for line in output.split("\n"): -+ line = line.rstrip("\r") -+ if not line: -+ continue -+ try: -+ commit, ref = line.split(' ', 1) -+ except ValueError: -+ # Include the offending line to simplify troubleshooting if -+ # this error ever occurs. -+ raise ValueError(f'unexpected show-ref line: {line!r}') - yield commit.strip(), ref.strip() - - def is_ref_remote(self, ref): -@@ -200,10 +208,10 @@ class Git(VersionControl): - def get_refs(self, location): - return self.get_short_refs(location) - -- def get_short_refs(self, location): -+ def get_short_refs(self, location, pattern=''): - """Return map of named refs (branches or tags) to commit hashes.""" - rv = {} -- for commit, ref in self.get_full_refs(location): -+ for commit, ref in self.get_full_refs(location, pattern): - ref_name = None - if self.is_ref_remote(ref): - ref_name = ref[len('refs/remotes/'):] diff --git a/SOURCES/allow-stripping-given-prefix-from-wheel-RECORD-files.patch b/SOURCES/allow-stripping-given-prefix-from-wheel-RECORD-files.patch deleted file mode 100644 index d66b250..0000000 --- a/SOURCES/allow-stripping-given-prefix-from-wheel-RECORD-files.patch +++ /dev/null @@ -1,95 +0,0 @@ -diff -up pip-9.0.1/pip/commands/install.py.orig pip-9.0.1/pip/commands/install.py ---- pip-9.0.1/pip/commands/install.py.orig 2016-11-06 11:49:45.000000000 -0700 -+++ pip-9.0.1/pip/commands/install.py 2016-11-16 16:20:48.638906543 -0700 -@@ -151,6 +151,14 @@ class InstallCommand(RequirementCommand) - "directory.") - - cmd_opts.add_option( -+ '--strip-file-prefix', -+ dest='strip_file_prefix', -+ metavar='prefix', -+ default=None, -+ help="Strip given prefix from script paths in wheel RECORD." -+ ) -+ -+ cmd_opts.add_option( - '--prefix', - dest='prefix_path', - metavar='dir', -@@ -340,6 +348,7 @@ class InstallCommand(RequirementCommand) - global_options, - root=options.root_path, - prefix=options.prefix_path, -+ strip_file_prefix=options.strip_file_prefix, - ) - - possible_lib_locations = get_lib_location_guesses( -diff -up pip-9.0.1/pip/req/req_install.py.orig pip-9.0.1/pip/req/req_install.py ---- pip-9.0.1/pip/req/req_install.py.orig 2016-11-06 11:49:45.000000000 -0700 -+++ pip-9.0.1/pip/req/req_install.py 2016-11-16 16:19:24.848336960 -0700 -@@ -838,8 +838,7 @@ class InstallRequirement(object): - else: - return True - -- def install(self, install_options, global_options=[], root=None, -- prefix=None): -+ def install(self, install_options, global_options=[], root=None, prefix=None, strip_file_prefix=None): - if self.editable: - self.install_editable( - install_options, global_options, prefix=prefix) -@@ -848,7 +847,12 @@ class InstallRequirement(object): - version = pip.wheel.wheel_version(self.source_dir) - pip.wheel.check_compatibility(version, self.name) - -- self.move_wheel_files(self.source_dir, root=root, prefix=prefix) -+ self.move_wheel_files( -+ self.source_dir, -+ root=root, -+ prefix=prefix, -+ strip_file_prefix=strip_file_prefix -+ ) - self.install_succeeded = True - return - -@@ -1053,7 +1057,7 @@ class InstallRequirement(object): - def is_wheel(self): - return self.link and self.link.is_wheel - -- def move_wheel_files(self, wheeldir, root=None, prefix=None): -+ def move_wheel_files(self, wheeldir, root=None, prefix=None, strip_file_prefix=None): - move_wheel_files( - self.name, self.req, wheeldir, - user=self.use_user_site, -@@ -1062,6 +1066,7 @@ class InstallRequirement(object): - prefix=prefix, - pycompile=self.pycompile, - isolated=self.isolated, -+ strip_file_prefix=strip_file_prefix, - ) - - def get_dist(self): -diff -up pip-9.0.1/pip/wheel.py.orig pip-9.0.1/pip/wheel.py ---- pip-9.0.1/pip/wheel.py.orig 2016-11-06 11:49:45.000000000 -0700 -+++ pip-9.0.1/pip/wheel.py 2016-11-16 16:19:24.848336960 -0700 -@@ -238,7 +238,7 @@ def get_entrypoints(filename): - - - def move_wheel_files(name, req, wheeldir, user=False, home=None, root=None, -- pycompile=True, scheme=None, isolated=False, prefix=None): -+ pycompile=True, scheme=None, isolated=False, prefix=None, strip_file_prefix=None): - """Install a wheel""" - - if not scheme: -@@ -521,7 +521,11 @@ if __name__ == '__main__': - writer.writerow(row) - for f in generated: - h, l = rehash(f) -- writer.writerow((normpath(f, lib_dir), h, l)) -+ final_path = normpath(f, lib_dir) -+ if strip_file_prefix and final_path.startswith(strip_file_prefix): -+ final_path = os.path.join(os.sep, -+ os.path.relpath(final_path, strip_file_prefix)) -+ writer.writerow((final_path, h, l)) - for f in installed: - writer.writerow((installed[f], '', '')) - shutil.move(temp_record, record) diff --git a/SOURCES/cve-2007-4559-tarfile.patch b/SOURCES/cve-2007-4559-tarfile.patch deleted file mode 100644 index 5530e5e..0000000 --- a/SOURCES/cve-2007-4559-tarfile.patch +++ /dev/null @@ -1,47 +0,0 @@ -Minimal patch for pip - -diff -rU3 pip-22.3.1-orig/src/pip/_internal/utils/unpacking.py pip-22.3.1/src/pip/_internal/utils/unpacking.py ---- a/pip/utils/__init__.py 2022-11-05 16:25:43.000000000 +0100 -+++ b/pip/utils/__init__.py 2023-08-08 13:17:47.705613554 +0200 -@@ -559,6 +559,13 @@ - if leading: - fn = split_leading_dir(fn)[1] - path = os.path.join(location, fn) -+ -+ # Call the `data` filter for its side effect (raising exception) -+ try: -+ tarfile.data_filter(member.replace(name=fn), location) -+ except tarfile.LinkOutsideDestinationError: -+ pass -+ - if member.isdir(): - ensure_dir(path) - elif member.issym(): - - -Patch for vendored distlib from https://github.com/pypa/distlib/pull/201 - -diff --git a/distlib/util.py b/distlib/util.py -index e0622e4..4349d0b 100644 ---- a/pip/_vendor/distlib/util.py -+++ b/pip/_vendor/distlib/util.py -@@ -1249,6 +1249,19 @@ def check_path(path): - for tarinfo in archive.getmembers(): - if not isinstance(tarinfo.name, text_type): - tarinfo.name = tarinfo.name.decode('utf-8') -+ -+ # Limit extraction of dangerous items, if this Python -+ # allows it easily. If not, just trust the input. -+ # See: https://docs.python.org/3/library/tarfile.html#extraction-filters -+ def extraction_filter(member, path): -+ """Run tarfile.tar_fillter, but raise the expected ValueError""" -+ # This is only called if the current Python has tarfile filters -+ try: -+ return tarfile.tar_filter(member, path) -+ except tarfile.FilterError as exc: -+ raise ValueError(str(exc)) -+ archive.extraction_filter = extraction_filter -+ - archive.extractall(dest_dir) - - finally: diff --git a/SOURCES/dummy-certifi.patch b/SOURCES/dummy-certifi.patch deleted file mode 100644 index f6a9f35..0000000 --- a/SOURCES/dummy-certifi.patch +++ /dev/null @@ -1,15 +0,0 @@ -diff --git a/pip/_vendor/certifi/core.py b/pip/_vendor/certifi/core.py -index eab9d1d..9614a88 100644 ---- a/pip/_vendor/certifi/core.py -+++ b/pip/_vendor/certifi/core.py -@@ -19,9 +19,7 @@ class DeprecatedBundleWarning(DeprecationWarning): - - - def where(): -- f = os.path.dirname(__file__) -- -- return os.path.join(f, 'cacert.pem') -+ return '/etc/pki/tls/certs/ca-bundle.crt' - - - def old_where(): diff --git a/SOURCES/emit-a-warning-when-running-with-root-privileges.patch b/SOURCES/emit-a-warning-when-running-with-root-privileges.patch deleted file mode 100644 index 644fce9..0000000 --- a/SOURCES/emit-a-warning-when-running-with-root-privileges.patch +++ /dev/null @@ -1,44 +0,0 @@ -From 18a617e9e0f64b727938422d4f941dfddfbf5d00 Mon Sep 17 00:00:00 2001 -From: Tomas Orsava -Date: Tue, 14 Feb 2017 17:10:09 +0100 -Subject: [PATCH] Emit a warning when running with root privileges. - ---- - pip/commands/install.py | 14 ++++++++++++++ - 1 file changed, 14 insertions(+) - -diff --git a/pip/commands/install.py b/pip/commands/install.py -index 227c526..277a3d1 100644 ---- a/pip/commands/install.py -+++ b/pip/commands/install.py -@@ -6,6 +6,8 @@ import os - import tempfile - import shutil - import warnings -+import sys -+from os import path - try: - import wheel - except ImportError: -@@ -193,6 +195,18 @@ class InstallCommand(RequirementCommand): - cmdoptions.resolve_wheel_no_use_binary(options) - cmdoptions.check_install_build_global(options) - -+ def is_venv(): -+ return hasattr(sys, 'real_prefix') or \ -+ (hasattr(sys, 'base_prefix') and sys.base_prefix != sys.prefix) -+ -+ # Check whether we have root privileges and aren't in venv/virtualenv -+ if os.getuid() == 0 and not is_venv(): -+ logger.warning( -+ "WARNING: Running pip install with root privileges is " -+ "generally not a good idea. Try `%s install --user` instead." -+ % path.basename(sys.argv[0]) -+ ) -+ - if options.as_egg: - warnings.warn( - "--egg has been deprecated and will be removed in the future. " --- -2.11.0 - diff --git a/SOURCES/pip-directory-traversal-security-issue-tests.patch b/SOURCES/pip-directory-traversal-security-issue-tests.patch deleted file mode 100644 index 3f63467..0000000 --- a/SOURCES/pip-directory-traversal-security-issue-tests.patch +++ /dev/null @@ -1,122 +0,0 @@ -From 7917dbda14ef64a5e7fdea48383a266577484ac8 Mon Sep 17 00:00:00 2001 -From: Tomas Orsava -Date: Wed, 19 Aug 2020 12:51:16 +0200 -Subject: [PATCH 2/2] FIX #6413 pip install allow directory traversal - (tests) - ---- - tests/unit/test_download.py | 85 +++++++++++++++++++++++++++++++++++++ - 1 file changed, 85 insertions(+) - -diff --git a/tests/unit/test_download.py b/tests/unit/test_download.py -index ee4b11c..15f99ec 100644 ---- a/tests/unit/test_download.py -+++ b/tests/unit/test_download.py -@@ -1,5 +1,6 @@ - import hashlib - import os -+import sys - from io import BytesIO - from shutil import rmtree, copy - from tempfile import mkdtemp -@@ -13,6 +14,7 @@ import pip - from pip.exceptions import HashMismatch - from pip.download import ( - PipSession, SafeFileCache, path_to_url, unpack_http_url, url_to_path, -+ _download_http_url, parse_content_disposition, sanitize_content_filename, - unpack_file_url, - ) - from pip.index import Link -@@ -123,6 +125,89 @@ def test_unpack_http_url_bad_downloaded_checksum(mock_unpack_file): - rmtree(download_dir) - - -+@pytest.mark.parametrize("filename, expected", [ -+ ('dir/file', 'file'), -+ ('../file', 'file'), -+ ('../../file', 'file'), -+ ('../', ''), -+ ('../..', '..'), -+ ('/', ''), -+]) -+def test_sanitize_content_filename(filename, expected): -+ """ -+ Test inputs where the result is the same for Windows and non-Windows. -+ """ -+ assert sanitize_content_filename(filename) == expected -+ -+ -+@pytest.mark.parametrize("filename, win_expected, non_win_expected", [ -+ ('dir\\file', 'file', 'dir\\file'), -+ ('..\\file', 'file', '..\\file'), -+ ('..\\..\\file', 'file', '..\\..\\file'), -+ ('..\\', '', '..\\'), -+ ('..\\..', '..', '..\\..'), -+ ('\\', '', '\\'), -+]) -+def test_sanitize_content_filename__platform_dependent( -+ filename, -+ win_expected, -+ non_win_expected -+): -+ """ -+ Test inputs where the result is different for Windows and non-Windows. -+ """ -+ if sys.platform == 'win32': -+ expected = win_expected -+ else: -+ expected = non_win_expected -+ assert sanitize_content_filename(filename) == expected -+ -+ -+@pytest.mark.parametrize("content_disposition, default_filename, expected", [ -+ ('attachment;filename="../file"', 'df', 'file'), -+]) -+def test_parse_content_disposition( -+ content_disposition, -+ default_filename, -+ expected -+): -+ actual = parse_content_disposition(content_disposition, default_filename) -+ assert actual == expected -+ -+ -+def test_download_http_url__no_directory_traversal(tmpdir): -+ """ -+ Test that directory traversal doesn't happen on download when the -+ Content-Disposition header contains a filename with a ".." path part. -+ """ -+ mock_url = 'http://www.example.com/whatever.tgz' -+ contents = b'downloaded' -+ link = Link(mock_url) -+ -+ session = Mock() -+ resp = MockResponse(contents) -+ resp.url = mock_url -+ resp.headers = { -+ # Set the content-type to a random value to prevent -+ # mimetypes.guess_extension from guessing the extension. -+ 'content-type': 'random', -+ 'content-disposition': 'attachment;filename="../out_dir_file"' -+ } -+ session.get.return_value = resp -+ -+ download_dir = tmpdir.join('download') -+ os.mkdir(download_dir) -+ file_path, content_type = _download_http_url( -+ link, -+ session, -+ download_dir, -+ hashes=None, -+ ) -+ # The file should be downloaded to download_dir. -+ actual = os.listdir(download_dir) -+ assert actual == ['out_dir_file'] -+ -+ - @pytest.mark.skipif("sys.platform == 'win32'") - def test_path_to_url_unix(): - assert path_to_url('/tmp/file') == 'file:///tmp/file' --- -2.25.4 - diff --git a/SOURCES/pip-directory-traversal-security-issue.patch b/SOURCES/pip-directory-traversal-security-issue.patch deleted file mode 100644 index c6ef12d..0000000 --- a/SOURCES/pip-directory-traversal-security-issue.patch +++ /dev/null @@ -1,79 +0,0 @@ -From 8044d9f2fbcb09f09a62b26ac1d8a134976bb2ac Mon Sep 17 00:00:00 2001 -From: gzpan123 -Date: Wed, 17 Apr 2019 21:25:45 +0800 -Subject: [PATCH 1/2] FIX #6413 pip install allow directory traversal - ---- - news/6413.bugfix | 3 +++ - pip/download.py | 31 ++++++++++++++++++++++++++----- - 2 files changed, 29 insertions(+), 5 deletions(-) - create mode 100644 news/6413.bugfix - -diff --git a/news/6413.bugfix b/news/6413.bugfix -new file mode 100644 -index 0000000..68d0a72 ---- /dev/null -+++ b/news/6413.bugfix -@@ -0,0 +1,3 @@ -+Prevent ``pip install `` from permitting directory traversal if e.g. -+a malicious server sends a ``Content-Disposition`` header with a filename -+containing ``../`` or ``..\\``. -diff --git a/pip/download.py b/pip/download.py -index 039e55a..b3d169b 100644 ---- a/pip/download.py -+++ b/pip/download.py -@@ -54,7 +54,8 @@ __all__ = ['get_file_content', - 'is_url', 'url_to_path', 'path_to_url', - 'is_archive_file', 'unpack_vcs_link', - 'unpack_file_url', 'is_vcs_url', 'is_file_url', -- 'unpack_http_url', 'unpack_url'] -+ 'unpack_http_url', 'unpack_url', -+ 'parse_content_disposition', 'sanitize_content_filename'] - - - logger = logging.getLogger(__name__) -@@ -824,6 +825,29 @@ def unpack_url(link, location, download_dir=None, - write_delete_marker_file(location) - - -+def sanitize_content_filename(filename): -+ # type: (str) -> str -+ """ -+ Sanitize the "filename" value from a Content-Disposition header. -+ """ -+ return os.path.basename(filename) -+ -+ -+def parse_content_disposition(content_disposition, default_filename): -+ # type: (str, str) -> str -+ """ -+ Parse the "filename" value from a Content-Disposition header, and -+ return the default filename if the result is empty. -+ """ -+ _type, params = cgi.parse_header(content_disposition) -+ filename = params.get('filename') -+ if filename: -+ # We need to sanitize the filename to prevent directory traversal -+ # in case the filename contains ".." path parts. -+ filename = sanitize_content_filename(filename) -+ return filename or default_filename -+ -+ - def _download_http_url(link, session, temp_dir, hashes): - """Download link url into temp_dir using provided session""" - target_url = link.url.split('#', 1)[0] -@@ -864,10 +888,7 @@ def _download_http_url(link, session, temp_dir, hashes): - # Have a look at the Content-Disposition header for a better guess - content_disposition = resp.headers.get('content-disposition') - if content_disposition: -- type, params = cgi.parse_header(content_disposition) -- # We use ``or`` here because we don't want to use an "empty" value -- # from the filename param. -- filename = params.get('filename') or filename -+ filename = parse_content_disposition(content_disposition, filename) - ext = splitext(filename)[1] - if not ext: - ext = mimetypes.guess_extension(content_type) --- -2.25.4 - diff --git a/SOURCES/pip-nowarn-upgrade.patch b/SOURCES/pip-nowarn-upgrade.patch deleted file mode 100644 index 9e314a5..0000000 --- a/SOURCES/pip-nowarn-upgrade.patch +++ /dev/null @@ -1,36 +0,0 @@ -diff --git a/pip/utils/outdated.py b/pip/utils/outdated.py -index 2164cc3..c71539f 100644 ---- a/pip/utils/outdated.py -+++ b/pip/utils/outdated.py -@@ -92,6 +92,21 @@ def load_selfcheck_statefile(): - return GlobalSelfCheckState() - - -+def pip_installed_by_pip(): -+ """Checks whether pip was installed by pip -+ -+ This is used not to display the upgrade message when pip is in fact -+ installed by system package manager, such as dnf on Fedora. -+ """ -+ import pkg_resources -+ try: -+ dist = pkg_resources.get_distribution('pip') -+ return (dist.has_metadata('INSTALLER') and -+ 'pip' in dist.get_metadata_lines('INSTALLER')) -+ except pkg_resources.DistributionNotFound: -+ return False -+ -+ - def pip_version_check(session): - """Check for an update for pip. - -@@ -141,7 +156,8 @@ def pip_version_check(session): - - # Determine if our pypi_version is older - if (pip_version < remote_version and -- pip_version.base_version != remote_version.base_version): -+ pip_version.base_version != remote_version.base_version and -+ pip_installed_by_pip()): - # Advise "python -m pip" on Windows to avoid issues - # with overwriting pip.exe. - if WINDOWS: diff --git a/SOURCES/remove-existing-dist-only-if-path-conflicts.patch b/SOURCES/remove-existing-dist-only-if-path-conflicts.patch deleted file mode 100644 index 25ff598..0000000 --- a/SOURCES/remove-existing-dist-only-if-path-conflicts.patch +++ /dev/null @@ -1,97 +0,0 @@ -diff --git a/pip/req/req_install.py b/pip/req/req_install.py -index 6911fba..8524932 100644 ---- a/pip/req/req_install.py -+++ b/pip/req/req_install.py -@@ -34,7 +34,7 @@ from pip.locations import ( - ) - from pip.utils import ( - display_path, rmtree, ask_path_exists, backup_dir, is_installable_dir, -- dist_in_usersite, dist_in_site_packages, egg_link_path, -+ dist_in_usersite, dist_in_site_packages, dist_in_install_path, egg_link_path, - call_subprocess, read_text_file, FakeFile, _make_build_dir, ensure_dir, - get_installed_version, normalize_path, dist_is_local, - ) -@@ -1049,7 +1049,7 @@ class InstallRequirement(object): - "lack sys.path precedence to %s in %s" % - (existing_dist.project_name, existing_dist.location) - ) -- else: -+ elif dist_in_install_path(existing_dist): - self.conflicts_with = existing_dist - return True - -diff --git a/pip/req/req_set.py b/pip/req/req_set.py -index 76aec06..b93304a 100644 ---- a/pip/req/req_set.py -+++ b/pip/req/req_set.py -@@ -18,7 +18,8 @@ from pip.exceptions import (InstallationError, BestVersionAlreadyInstalled, - UnsupportedPythonVersion) - from pip.req.req_install import InstallRequirement - from pip.utils import ( -- display_path, dist_in_usersite, ensure_dir, normalize_path) -+ display_path, dist_in_usersite, dist_in_install_path, ensure_dir, -+ normalize_path) - from pip.utils.hashes import MissingHashes - from pip.utils.logging import indent_log - from pip.utils.packaging import check_dist_requires_python -@@ -437,10 +438,12 @@ class RequirementSet(object): - - if not best_installed: - # don't uninstall conflict if user install and -- # conflict is not user install -+ # conflict is not user install or conflict lives -+ # in a different path (/usr/lib vs /usr/local/lib/) - if not (self.use_user_site and not -- dist_in_usersite(req_to_install.satisfied_by)): -- req_to_install.conflicts_with = \ -+ dist_in_usersite(req_to_install.satisfied_by) or not -+ dist_in_install_path(req_to_install.satisfied_by)): -+ req_to_install.conflicts_with = \ - req_to_install.satisfied_by - req_to_install.satisfied_by = None - -@@ -644,10 +647,12 @@ class RequirementSet(object): - if req_to_install.satisfied_by: - if self.upgrade or self.ignore_installed: - # don't uninstall conflict if user install and -- # conflict is not user install -+ # conflict is not user install or conflict lives -+ # in a different path (/usr/lib vs /usr/local/lib/) - if not (self.use_user_site and not - dist_in_usersite( -- req_to_install.satisfied_by)): -+ req_to_install.satisfied_by) or not -+ dist_in_install_path(req_to_install.satisfied_by)): - req_to_install.conflicts_with = \ - req_to_install.satisfied_by - req_to_install.satisfied_by = None -diff --git a/pip/utils/__init__.py b/pip/utils/__init__.py -index 815bd33..0ed59f7 100644 ---- a/pip/utils/__init__.py -+++ b/pip/utils/__init__.py -@@ -22,7 +22,7 @@ from pip.exceptions import InstallationError - from pip.compat import console_to_str, expanduser, stdlib_pkgs - from pip.locations import ( - site_packages, user_site, running_under_virtualenv, virtualenv_no_global, -- write_delete_marker_file, -+ write_delete_marker_file, distutils_scheme, - ) - from pip._vendor import pkg_resources - from pip._vendor.six.moves import input -@@ -315,6 +315,16 @@ def dist_in_site_packages(dist): - ).startswith(normalize_path(site_packages)) - - -+def dist_in_install_path(dist): -+ """ -+ Return True if given Distribution is installed in -+ path matching distutils_scheme layout. -+ """ -+ norm_path = normalize_path(dist_location(dist)) -+ return norm_path.startswith(normalize_path( -+ distutils_scheme("")['purelib'].split('python')[0])) -+ -+ - def dist_is_editable(dist): - """Is distribution an editable install?""" - for path_item in sys.path: diff --git a/SOURCES/skip_yanked_releases.patch b/SOURCES/skip_yanked_releases.patch deleted file mode 100644 index ef3f8e5..0000000 --- a/SOURCES/skip_yanked_releases.patch +++ /dev/null @@ -1,91 +0,0 @@ -From b97ef609100fbdd5895dab48cdab578dfeba396c Mon Sep 17 00:00:00 2001 -From: Lumir Balhar -Date: Fri, 10 Sep 2021 13:38:40 +0200 -Subject: [PATCH 1/2] Implement handling of yanked_reason from the HTML anchor - ---- - pip/index.py | 10 ++++++++-- - 1 file changed, 8 insertions(+), 2 deletions(-) - -diff --git a/pip/index.py b/pip/index.py -index f653f6e6a..ced52ce5a 100644 ---- a/pip/index.py -+++ b/pip/index.py -@@ -865,7 +865,11 @@ class HTMLPage(object): - ) - pyrequire = anchor.get('data-requires-python') - pyrequire = unescape(pyrequire) if pyrequire else None -- yield Link(url, self, requires_python=pyrequire) -+ yanked_reason = anchor.get('data-yanked', default=None) -+ # Empty or valueless attribute are both parsed as empty string -+ if yanked_reason is not None: -+ yanked_reason = unescape(yanked_reason) -+ yield Link(url, self, requires_python=pyrequire, yanked_reason=yanked_reason) - - _clean_re = re.compile(r'[^a-z0-9$&+,/:;=?@.#%_\\|-]', re.I) - -@@ -879,7 +883,7 @@ class HTMLPage(object): - - class Link(object): - -- def __init__(self, url, comes_from=None, requires_python=None): -+ def __init__(self, url, comes_from=None, requires_python=None, yanked_reason=None): - """ - Object representing a parsed link from https://pypi.python.org/simple/* - -@@ -900,6 +904,8 @@ class Link(object): - self.url = url - self.comes_from = comes_from - self.requires_python = requires_python if requires_python else None -+ self.yanked_reason = yanked_reason -+ self.yanked = yanked_reason is not None - - def __str__(self): - if self.requires_python: --- -2.31.1 - -From d8dc6ee5d6809736dce43dc1e57d497f9ff91f26 Mon Sep 17 00:00:00 2001 -From: Lumir Balhar -Date: Fri, 10 Sep 2021 13:43:22 +0200 -Subject: [PATCH 2/2] Skip all yanked candidates if possible - ---- - pip/index.py | 21 +++++++++++++++++++++ - 1 file changed, 21 insertions(+) - -diff --git a/pip/index.py b/pip/index.py -index ced52ce5a..823bbaf7d 100644 ---- a/pip/index.py -+++ b/pip/index.py -@@ -489,6 +489,27 @@ class PackageFinder(object): - if applicable_candidates: - best_candidate = max(applicable_candidates, - key=self._candidate_sort_key) -+ # If we cannot find a non-yanked candidate, -+ # use the best one and print a warning about it. -+ # Otherwise, try to find another best candidate, ignoring -+ # all the yanked releases. -+ if getattr(best_candidate.location, "yanked", False): -+ nonyanked_candidates = [ -+ c for c in applicable_candidates -+ if not getattr(c.location, "yanked", False) -+ ] -+ -+ if set(nonyanked_candidates): -+ best_candidate = max(nonyanked_candidates, -+ key=self._candidate_sort_key) -+ else: -+ warning_message = ( -+ "WARNING: The candidate selected for download or install " -+ "is a yanked version: '{}' candidate (version {} at {})" -+ ).format(best_candidate.project, best_candidate.version, best_candidate.location) -+ if best_candidate.location.yanked_reason: -+ warning_message += "\nReason for being yanked: {}".format(best_candidate.location.yanked_reason) -+ logger.warning(warning_message) - else: - best_candidate = None - --- -2.31.1 - diff --git a/SPECS/python-pip.spec b/SPECS/python-pip.spec deleted file mode 100644 index f14ccf0..0000000 --- a/SPECS/python-pip.spec +++ /dev/null @@ -1,688 +0,0 @@ -%bcond_with bootstrap -%bcond_with tests - -%bcond_without doc - -%global srcname pip -%global python3_wheelname %{srcname}-%{version}-py2.py3-none-any.whl -%if %{without bootstrap} -%global python3_wheeldir %{_datadir}/python3-wheels -%endif - -%global bashcompdir %(b=$(pkg-config --variable=completionsdir bash-completion 2>/dev/null); echo ${b:-%{_sysconfdir}/bash_completion.d}) - -Name: python-%{srcname} -# When updating, update the bundled libraries versions bellow! -Version: 9.0.3 -Release: 24%{?dist} -Summary: A tool for installing and managing Python packages - -Group: Development/Libraries - -# We bundle a lot of libraries with pip, which itself is under MIT license. -# Here is the list of the libraries with corresponding licenses: - -# appdirs: MIT -# CacheControl: ASL 2.0 -# certifi: MPLv2.0 -# chardet: LGPLv2 -# colorama: BSD -# distlib: Python -# distro: ASL 2.0 -# html5lib: MIT -# idna: BSD -# ipaddress: Python -# lockfile: MIT -# packaging: ASL 2.0 or BSD -# progress: ISC -# pyparsing: MIT -# requests: ASL 2.0 -# retrying: ASL 2.0 -# urllib3: MIT -# six: MIT -# urllib3: MIT -# webencodings: BSD - -License: MIT and Python and ASL 2.0 and BSD and ISC and LGPLv2 and MPLv2.0 and (ASL 2.0 or BSD) -URL: http://www.pip-installer.org -Source0: https://files.pythonhosted.org/packages/source/p/%{srcname}/%{srcname}-%{version}.tar.gz - -BuildArch: noarch - -%if %{with tests} -BuildRequires: git -BuildRequires: bzr -%endif - -# to get tests: -# git clone https://github.com/pypa/pip && cd pip -# git checkout 9.0.1 && tar -czvf ../pip-9.0.1-tests.tar.gz tests/ -%if %{with tests} -Source1: pip-%{version}-tests.tar.gz -%endif - -# Patch until the following issue gets implemented upstream: -# https://github.com/pypa/pip/issues/1351 -Patch0: allow-stripping-given-prefix-from-wheel-RECORD-files.patch - -# Downstream only patch -# Emit a warning to the user if pip install is run with root privileges -# Issue upstream: https://github.com/pypa/pip/issues/4288 -Patch1: emit-a-warning-when-running-with-root-privileges.patch - -# Prevent removing of the system packages installed under /usr/lib -# when pip install -U is executed. -# https://bugzilla.redhat.com/show_bug.cgi?id=1626408 -# Author: Michal Cyprian -Patch2: remove-existing-dist-only-if-path-conflicts.patch - -# Do not show the "new version of pip" warning outside of venv -# Upstream issue: https://github.com/pypa/pip/issues/5346 -# Fedora bug: https://bugzilla.redhat.com/show_bug.cgi?id=1573755 -Patch3: pip-nowarn-upgrade.patch - -# Use the system level root certificate instead of the one bundled in certifi -# https://bugzilla.redhat.com/show_bug.cgi?id=1655255 -Patch4: dummy-certifi.patch - -# Patch for CVE in the bundled urllib3 -# CVE-2018-20060 Cross-host redirect does not remove Authorization header allow for credential exposure -# https://bugzilla.redhat.com/show_bug.cgi?id=CVE-2018-20060 -Patch5: CVE-2018-20060.patch - -# Patch for CVE in the bundled urllib3 -# CVE-2019-11236 CRLF injection due to not encoding the '\r\n' sequence leading to possible attack on internal service -# https://bugzilla.redhat.com/show_bug.cgi?id=CVE-2019-11236 -Patch6: CVE-2019-11236.patch - -# Patch for CVE in the bundled urllib3 -# CVE-2019-11324 Certification mishandle when error should be thrown -# https://bugzilla.redhat.com/show_bug.cgi?id=CVE-2019-11324 -Patch7: CVE-2019-11324.patch - -# Patch for CVE in the bundled requests -# CVE-2018-18074 Redirect from HTTPS to HTTP does not remove Authorization header -# This patch fixes both the CVE -# https://bugzilla.redhat.com/show_bug.cgi?id=1643829 -# and the subsequent regression -# https://github.com/psf/requests/pull/4851 -Patch8: CVE-2018-18074.patch - -# Patch for pip install allow directory traversal, leading to arbitrary file write -# - Upstream PR: https://github.com/pypa/pip/pull/6418/files -# - Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1868016 -# Patch9 fixes the issue -# Patch10 adds unit tests for the issue -Patch9: pip-directory-traversal-security-issue.patch -Patch10: pip-directory-traversal-security-issue-tests.patch - -# Patch for CVE-2021-3572 - pip incorrectly handled unicode separators in git references -# The patch is adjusted for older pip where it's necessary to also switch -# the way pip gets revisions from git -# Upstream PR: https://github.com/pypa/pip/pull/9827 -# Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1962856 -Patch11: CVE-2021-3572.patch - -# Downstream-only implementation of support of yanked releases -# PEP 592 - Adding "Yank" Support to the Simple API: -# https://www.python.org/dev/peps/pep-0592/ -# Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2000135 -Patch12: skip_yanked_releases.patch - -# CVE-2007-4559, PEP-721, PEP-706: Use tarfile.data_filter for extracting -# - Minimal downstream-only patch, to be replaced by upstream solution -# proposed in https://github.com/pypa/pip/pull/12214 -# - Patch for vendored distlib, accepted upstream: -# https://github.com/pypa/distlib/pull/201 -Patch13: cve-2007-4559-tarfile.patch - -%global _description \ -pip is a package management system used to install and manage software packages \ -written in Python. Many packages can be found in the Python Package Index \ -(PyPI). pip is a recursive acronym that can stand for either "Pip Installs \ -Packages" or "Pip Installs Python". - -%description %_description - - -%package -n platform-python-%{srcname} -Summary: A tool for installing and managing Python3 packages -Group: Development/Libraries -Conflicts: python%{python3_pkgversion}-pip < 9.0.3-5%{?dist} -Obsoletes: python%{python3_pkgversion}-pip < 9.0.3-6%{?dist} - -BuildRequires: python%{python3_pkgversion}-devel -BuildRequires: python%{python3_pkgversion}-setuptools -BuildRequires: bash-completion -%if %{with tests} -BuildRequires: python%{python3_pkgversion}-mock -BuildRequires: python%{python3_pkgversion}-pytest -BuildRequires: python%{python3_pkgversion}-pretend -BuildRequires: python%{python3_pkgversion}-freezegun -BuildRequires: python%{python3_pkgversion}-pytest-capturelog -BuildRequires: python%{python3_pkgversion}-scripttest -BuildRequires: python%{python3_pkgversion}-virtualenv -%endif -%if %{without bootstrap} -BuildRequires: python%{python3_pkgversion}-pip -BuildRequires: python%{python3_pkgversion}-wheel -%endif -Requires: platform-python-setuptools - -BuildRequires: ca-certificates -Requires: ca-certificates -# pip has to require explicit version of platform-python that provides -# filters in tarfile module (fix for CVE-2007-4559). -Requires: platform-python >= 3.6.8-55 - -# Virtual provides for the packages bundled by pip. -# See the python2 list above for instructions. -Provides: bundled(python3dist(appdirs)) = 1.4.0 -Provides: bundled(python3dist(cachecontrol)) = 0.11.7 -Provides: bundled(python3dist(colorama)) = 0.3.7 -Provides: bundled(python3dist(distlib)) = 0.2.4 -Provides: bundled(python3dist(distro)) = 1.0.1 -Provides: bundled(python3dist(html5lib)) = 1.0b10 -Provides: bundled(python3dist(ipaddress) = 1.0.17 -Provides: bundled(python3dist(lockfile)) = 0.12.2 -Provides: bundled(python3dist(packaging)) = 16.8 -Provides: bundled(python3dist(setuptools)) = 28.8.0 -Provides: bundled(python3dist(progress)) = 1.2 -Provides: bundled(python3dist(pyparsing)) = 2.1.10 -Provides: bundled(python3dist(requests)) = 2.11.1 -Provides: bundled(python3dist(retrying)) = 1.3.3 -Provides: bundled(python3dist(six)) = 1.10.0 -Provides: bundled(python3dist(webencodings)) = 0.5 - -# Bundled within the requests bundle -Provides: bundled(python3dist(chardet)) = 2.3.0 -Provides: bundled(python3dist(urllib3)) = 1.16 - -%description -n platform-python-%{srcname} %_description - - -%package -n python%{python3_pkgversion}-%{srcname} -Summary: A tool for installing and managing Python3 packages -Group: Development/Libraries - -Requires: platform-python-pip = %{version}-%{release} -Requires: python36 -%{?python_provide:%python_provide python%{python3_pkgversion}-%{srcname}} - -%description -n python%{python3_pkgversion}-%{srcname} %_description - - -%if %{with doc} -%package doc -Summary: A documentation for a tool for installing and managing Python packages - -BuildRequires: python%{python3_pkgversion}-sphinx - -%description doc -A documentation for a tool for installing and managing Python packages - -%endif - -%if %{without bootstrap} -%package -n python3-%{srcname}-wheel -Summary: The pip wheel -# Older Python does not provide tarfile filters (fix for CVE-2007-4559). -Conflicts: platform-python < 3.6.8-55 - -# Virtual provides for the packages bundled by pip. -# You can find the versions in pip/_vendor/vendor.txt file. -Provides: bundled(python3dist(appdirs)) = 1.4.0 -Provides: bundled(python3dist(cachecontrol)) = 0.11.7 -Provides: bundled(python3dist(colorama)) = 0.3.7 -Provides: bundled(python3dist(distlib)) = 0.2.4 -Provides: bundled(python3dist(distro)) = 1.0.1 -Provides: bundled(python3dist(html5lib)) = 1.0b10 -Provides: bundled(python3dist(ipaddress) = 1.0.17 -Provides: bundled(python3dist(lockfile)) = 0.12.2 -Provides: bundled(python3dist(packaging)) = 16.8 -Provides: bundled(python3dist(setuptools)) = 28.8.0 -Provides: bundled(python3dist(progress)) = 1.2 -Provides: bundled(python3dist(pyparsing)) = 2.1.10 -Provides: bundled(python3dist(requests)) = 2.11.1 -Provides: bundled(python3dist(retrying)) = 1.3.3 -Provides: bundled(python3dist(six)) = 1.10.0 -Provides: bundled(python3dist(webencodings)) = 0.5 - -# Bundled within the requests bundle -Provides: bundled(python3dist(chardet)) = 2.3.0 -Provides: bundled(python3dist(urllib3)) = 1.16 - -%description -n python3-%{srcname}-wheel -A Python wheel of pip to use with venv. -%endif - -%prep -%setup -q -n %{srcname}-%{version} - -%if %{with tests} -tar -xf %{SOURCE1} -%endif - -%patch0 -p1 -%patch1 -p1 -%patch2 -p1 -%patch3 -p1 -%patch4 -p1 - -# Patching of bundled libraries -pushd pip/_vendor/urllib3 -%patch5 -p1 -%patch6 -p1 -%patch7 -p1 -popd -pushd pip/_vendor/requests -%patch8 -p1 -popd -%patch9 -p1 -%if %{with tests} -%patch10 -p1 -%endif -%patch11 -p1 -%patch12 -p1 -%patch13 -p1 - -# this goes together with patch4 -rm pip/_vendor/certifi/*.pem -rm pip/_vendor/requests/*.pem -sed -i '/\.pem$/d' pip.egg-info/SOURCES.txt - -sed -i '1d' pip/__init__.py - -# Remove ordereddict as it is only required for python <= 2.6 -rm pip/_vendor/ordereddict.py - -# Remove windows executable binaries -rm -v pip/_vendor/distlib/*.exe -sed -i '/\.exe/d' setup.py - -# Backports for Python 2 -rm pip/_vendor/distlib/_backport/tarfile.py -rm pip/_vendor/distlib/_backport/shutil.py - -%build -%if %{without bootstrap} -%py3_build_wheel -%else -%py3_build -%endif - -%if %{with doc} -pushd docs -make html -make man -rm _build/html/.buildinfo -popd -%endif - - -%install -%if %{without bootstrap} -%py3_install_wheel %{python3_wheelname} -%else -%py3_install -%endif - -rm %{buildroot}%{_bindir}/pip - -%if %{with doc} -install -d %{buildroot}%{_mandir}/man1 -install -pm0644 docs/_build/man/*.1 %{buildroot}%{_mandir}/man1/pip3.1 -%endif # with doc - -mkdir -p %{buildroot}%{bashcompdir} -PYTHONPATH=%{buildroot}%{python3_sitelib} \ - %{buildroot}%{_bindir}/pip3 completion --bash \ - > %{buildroot}%{bashcompdir}/pip3 - -sed -i -e "s/^\\(complete.*\\) pip\$/\\1 pip3 pip-3 pip3.6 pip-3.6/" \ - -e s/_pip_completion/_pip3_completion/ \ - %{buildroot}%{bashcompdir}/pip3 - -# Provide symlinks to executables to comply with Fedora guidelines for Python -mv %{buildroot}%{_bindir}/pip3 %{buildroot}%{_bindir}/pip%{python3_version} -ln -s ./pip%{python3_version} %{buildroot}%{_bindir}/pip-%{python3_version} - -# Change shebang in /usr/bin/pip3.6 to /usr/bin/python3.6 -pathfix.py -i /usr/bin/python%{python3_version} -np %{buildroot}%{_bindir}/pip%{python3_version} - -# Make sure the INSTALLER is not pip, otherwise pip-nowarn-upgrade.patch -# (Patch3) won't work -echo rpm > %{buildroot}%{python3_sitelib}/pip-%{version}.dist-info/INSTALLER - -%if %{without bootstrap} -mkdir -p %{buildroot}%{python3_wheeldir} -install -p dist/%{python3_wheelname} -t %{buildroot}%{python3_wheeldir} -%endif - -%if %{with tests} -%check -py.test-%{python3_version} -m 'not network' -%endif - - -%files -n platform-python-%{srcname} -%license LICENSE.txt -%doc README.rst -%if %{with doc} -%{_mandir}/man1/pip3.* -%endif -%{python3_sitelib}/pip* - -%files -n python%{python3_pkgversion}-%{srcname} -%license LICENSE.txt -%doc README.rst -# The pip3 binary is created using alternatives -# defined in the python36 package -%{_bindir}/pip%{python3_version} -%{_bindir}/pip-%{python3_version} -%dir %{bashcompdir} -%{bashcompdir}/pip* - -%if %{with doc} -%files doc -%license LICENSE.txt -%doc README.rst -%doc docs/_build/html -%endif # with doc - -%if %{without bootstrap} -%files -n python3-%{srcname}-wheel -%license LICENSE.txt -# we own the dir for simplicity -%dir %{python3_wheeldir}/ -%{python3_wheeldir}/%{python3_wheelname} -%endif - -%changelog -* Wed Feb 14 2024 Lumír Balhar - 9.0.3-24 -- Require Python with tarfile filters -Resolves: RHEL-25446 - -* Tue Aug 08 2023 Petr Viktorin - 9.0.3-23 -- Use tarfile.data_filter for extracting (CVE-2007-4559, PEP-721, PEP-706) -Resolves: RHBZ#2218241 - -* Wed Oct 06 2021 Charalampos Stratakis - 9.0.3-22 -- Remove bundled windows executables -- Resolves: rhbz#2006788 - -* Tue Oct 05 2021 Lumír Balhar - 9.0.3-21 -- Support of yanked releases -Resolves: rhbz#2000135 - -* Mon Jun 07 2021 Lumír Balhar - 9.0.3-20 -- Fix for CVE-2021-3572 - pip incorrectly handled unicode separators in git references -Resolves: rhbz#1962856 - -* Fri Jan 08 2021 Lumír Balhar - 9.0.3-19 -- Fix bash completion files and simplify spec -Resolves: rhbz#1904478 - -* Wed Aug 19 2020 Tomas Orsava - 9.0.3-18 -- Patch for pip install allow directory traversal, leading to arbitrary file write -Resolves: rhbz#1868016 - -* Wed Mar 04 2020 Charalampos Stratakis - 9.0.3-17 -- Remove unused CA bundle from the bundled requests library -Resolves: rhbz#1775200 - -* Mon Jan 13 2020 Lumír Balhar - 9.0.3-16 -- Add four new patches for CVEs in bundled urllib3 and requests -CVE-2018-20060, CVE-2019-11236, CVE-2019-11324, CVE-2018-18074 -Resolves: rhbz#1649153 -Resolves: rhbz#1700824 -Resolves: rhbz#1702473 -Resolves: rhbz#1643829 - -* Thu Jun 06 2019 Charalampos Stratakis - 9.0.3-15 -- Create python-pip-wheel package with the wheel -Resolves: rhbz#1718031 - -* Wed Mar 13 2019 Lumír Balhar - 9.0.3-14 -- Move bash completion files from platform-python- to python3- subpackage -- resolves: rhbz#1664749 - -* Mon Dec 03 2018 Miro Hrončok - 9.0.3-13 -- Use the system level root certificate instead of the one bundled in certifi -- Resolves: rhbz#1655255 - -* Wed Nov 28 2018 Tomas Orsava - 9.0.3-12 -- Do not show the "new version of pip" warning outside of venv -- Resolves: rhbz#1656171 - -* Mon Nov 19 2018 Victor Stinner - 9.0.3-11 -- Prevent removing of the system packages installed under /usr/lib - when pip install -U is executed. Patch by Michal Cyprian. - Resolves: rhbz#1626408. - -* Fri Nov 16 2018 Tomas Orsava - 9.0.3-10 -- Bump the NVR so it's higher than previous builds of python3-pip that have - mistakenly gotten into the python27 module build when we were dealing with an - MBS filtering problem. See BZ#1650568. -- Resolves: rhbz#1638836 - -* Mon Nov 12 2018 Lumír Balhar - 9.0.3-6 -- python3-pip requires python36 and obsoletes previous version - where python3- and platform-python- were in one package -- Resolves: rhbz#1638836 - -* Mon Oct 22 2018 Tomas Orsava - 9.0.3-5 -- Split part of the python3-pip package into platform-python-pip -- python3-pip will only contain binaries in /usr/bin -- Resolves: rhbz#1638836 - -* Mon Aug 06 2018 Petr Viktorin - 9.0.3-4 -- Remove the python2 subpackage -- Remove unversioned executables (only *-3.6 should be provided) - -* Mon Aug 06 2018 Charalampos Stratakis - 9.0.3-3 -- Correct license information - -* Mon Jun 25 2018 Petr Viktorin - 9.0.3-2 -- Don't build the python2 subpackage - https://bugzilla.redhat.com/show_bug.cgi?id=1594335 - -* Thu Mar 29 2018 Charalampos Stratakis - 9.0.3-1 -- Update to 9.0.3 - -* Wed Feb 21 2018 Lumír Balhar - 9.0.1-16 -- Include built HTML documentation (in the new -doc subpackage) and man page - -* Fri Feb 09 2018 Fedora Release Engineering - 9.0.1-15 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_28_Mass_Rebuild - -* Mon Dec 04 2017 Charalampos Stratakis - 9.0.1-14 -- Reintroduce the ipaddress module in the python3 subpackage. - -* Mon Nov 20 2017 Charalampos Stratakis - 9.0.1-13 -- Add virtual provides for the bundled libraries. (rhbz#1096912) - -* Tue Aug 29 2017 Tomas Orsava - 9.0.1-12 -- Switch macros to bcond's and make Python 2 optional to facilitate building - the Python 2 and Python 3 modules - -* Thu Jul 27 2017 Fedora Release Engineering - 9.0.1-11 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Mass_Rebuild - -* Tue May 23 2017 Tomas Orsava - 9.0.1-10 -- Modernized package descriptions -Resolves: rhbz#1452568 - -* Tue Mar 21 2017 Tomas Orsava - 9.0.1-9 -- Fix typo in the sudo pip warning - -* Fri Mar 03 2017 Tomas Orsava - 9.0.1-8 -- Patch 1 update: No sudo pip warning in venv or virtualenv - -* Thu Feb 23 2017 Tomas Orsava - 9.0.1-7 -- Patch 1 update: Customize the warning with the proper version of the pip - command - -* Tue Feb 14 2017 Tomas Orsava - 9.0.1-6 -- Added patch 1: Emit a warning when running with root privileges - -* Sat Feb 11 2017 Fedora Release Engineering - 9.0.1-5 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_26_Mass_Rebuild - -* Mon Jan 02 2017 Tomas Orsava - 9.0.1-4 -- Provide symlinks to executables to comply with Fedora guidelines for Python -Resolves: rhbz#1406922 - -* Fri Dec 09 2016 Charalampos Stratakis - 9.0.1-3 -- Rebuild for Python 3.6 with wheel - -* Fri Dec 09 2016 Charalampos Stratakis - 9.0.1-2 -- Rebuild for Python 3.6 without wheel - -* Fri Nov 18 2016 Orion Poplawski - 9.0.1-1 -- Update to 9.0.1 - -* Fri Nov 18 2016 Orion Poplawski - 8.1.2-5 -- Enable EPEL Python 3 builds -- Use new python macros -- Cleanup spec - -* Fri Aug 05 2016 Tomas Orsava - 8.1.2-4 -- Updated the test sources - -* Fri Aug 05 2016 Tomas Orsava - 8.1.2-3 -- Moved python-pip into the python2-pip subpackage -- Added the python_provide macro - -* Tue Jul 19 2016 Fedora Release Engineering - 8.1.2-2 -- https://fedoraproject.org/wiki/Changes/Automatic_Provides_for_Python_RPM_Packages - -* Tue May 17 2016 Tomas Orsava - 8.1.2-1 -- Update to 8.1.2 -- Moved to a new PyPI URL format -- Updated the prefix-stripping patch because of upstream changes in pip/wheel.py - -* Mon Feb 22 2016 Slavek Kabrda - 8.0.2-1 -- Update to 8.0.2 - -* Thu Feb 04 2016 Fedora Release Engineering - 7.1.0-4 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_24_Mass_Rebuild - -* Wed Oct 14 2015 Robert Kuska - 7.1.0-3 -- Rebuilt for Python3.5 rebuild -- With wheel set to 1 - -* Tue Oct 13 2015 Robert Kuska - 7.1.0-2 -- Rebuilt for Python3.5 rebuild - -* Wed Jul 01 2015 Slavek Kabrda - 7.1.0-1 -- Update to 7.1.0 - -* Tue Jun 30 2015 Ville Skyttä - 7.0.3-3 -- Install bash completion -- Ship LICENSE.txt as %%license where available - -* Thu Jun 18 2015 Fedora Release Engineering - 7.0.3-2 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_23_Mass_Rebuild - -* Thu Jun 04 2015 Matej Stuchlik - 7.0.3-1 -- Update to 7.0.3 - -* Fri Mar 06 2015 Matej Stuchlik - 6.0.8-1 -- Update to 6.0.8 - -* Thu Dec 18 2014 Slavek Kabrda - 1.5.6-5 -- Only enable tests on Fedora. - -* Mon Dec 01 2014 Matej Stuchlik - 1.5.6-4 -- Add tests -- Add patch skipping tests requiring Internet access - -* Tue Nov 18 2014 Matej Stuchlik - 1.5.6-3 -- Added patch for local dos with predictable temp dictionary names - (http://seclists.org/oss-sec/2014/q4/655) - -* Sat Jun 07 2014 Fedora Release Engineering - 1.5.6-2 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_Mass_Rebuild - -* Sun May 25 2014 Matej Stuchlik - 1.5.6-1 -- Update to 1.5.6 - -* Fri Apr 25 2014 Matej Stuchlik - 1.5.4-4 -- Rebuild as wheel for Python 3.4 - -* Thu Apr 24 2014 Matej Stuchlik - 1.5.4-3 -- Disable build_wheel - -* Thu Apr 24 2014 Matej Stuchlik - 1.5.4-2 -- Rebuild as wheel for Python 3.4 - -* Mon Apr 07 2014 Matej Stuchlik - 1.5.4-1 -- Updated to 1.5.4 - -* Mon Oct 14 2013 Tim Flink - 1.4.1-1 -- Removed patch for CVE 2013-2099 as it has been included in the upstream 1.4.1 release -- Updated version to 1.4.1 - -* Sun Aug 04 2013 Fedora Release Engineering - 1.3.1-5 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_20_Mass_Rebuild - -* Tue Jul 16 2013 Toshio Kuratomi - 1.3.1-4 -- Fix for CVE 2013-2099 - -* Thu May 23 2013 Tim Flink - 1.3.1-3 -- undo python2 executable rename to python-pip. fixes #958377 -- fix summary to match upstream - -* Mon May 06 2013 Kevin Kofler - 1.3.1-2 -- Fix main package Summary, it's for Python 2, not 3 (#877401) - -* Fri Apr 26 2013 Jon Ciesla - 1.3.1-1 -- Update to 1.3.1, fix for CVE-2013-1888. - -* Thu Feb 14 2013 Fedora Release Engineering - 1.2.1-3 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_19_Mass_Rebuild - -* Tue Oct 09 2012 Tim Flink - 1.2.1-2 -- Fixing files for python3-pip - -* Thu Oct 04 2012 Tim Flink - 1.2.1-1 -- Update to upstream 1.2.1 -- Change binary from pip-python to python-pip (RHBZ#855495) -- Add alias from python-pip to pip-python, to be removed at a later date - -* Tue May 15 2012 Tim Flink - 1.1.0-1 -- Update to upstream 1.1.0 - -* Sat Jan 14 2012 Fedora Release Engineering - 1.0.2-2 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_17_Mass_Rebuild - -* Sat Oct 22 2011 Tim Flink - 1.0.2-1 -- update to 1.0.2 and added python3 subpackage - -* Wed Jun 22 2011 Tim Flink - 0.8.3-1 -- update to 0.8.3 and project home page - -* Tue Feb 08 2011 Fedora Release Engineering - 0.8.2-2 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_15_Mass_Rebuild - -* Mon Dec 20 2010 Luke Macken - 0.8.2-1 -- update to 0.8.2 of pip -* Mon Aug 30 2010 Peter Halliday - 0.8-1 -- update to 0.8 of pip -* Thu Jul 22 2010 David Malcolm - 0.7.2-5 -- Rebuilt for https://fedoraproject.org/wiki/Features/Python_2.7/MassRebuild - -* Wed Jul 7 2010 Peter Halliday - 0.7.2-1 -- update to 0.7.2 of pip -* Sun May 23 2010 Peter Halliday - 0.7.1-1 -- update to 0.7.1 of pip -* Fri Jan 1 2010 Peter Halliday - 0.6.1.4 -- fix dependency issue -* Fri Dec 18 2009 Peter Halliday - 0.6.1-2 -- fix spec file -* Thu Dec 17 2009 Peter Halliday - 0.6.1-1 -- upgrade to 0.6.1 of pip -* Mon Aug 31 2009 Peter Halliday - 0.4-1 -- Initial package - diff --git a/cve-2007-4559-tarfile.patch b/cve-2007-4559-tarfile.patch new file mode 100644 index 0000000..4b15642 --- /dev/null +++ b/cve-2007-4559-tarfile.patch @@ -0,0 +1,85 @@ +From 1819805f2019c731bcaefd6b12fd814790f88fcd Mon Sep 17 00:00:00 2001 +From: Lumir Balhar +Date: Tue, 19 Mar 2024 12:43:07 +0100 +Subject: [PATCH] cve-2007-4559-tarfile + +Minimal patch for pip +--- + src/pip/_internal/utils/unpacking.py | 7 +++++++ + src/pip/_vendor/distlib/util.py | 13 +++++++++++++ + tests/unit/test_utils_unpacking.py | 17 +++++++++++++++++ + 3 files changed, 37 insertions(+) + +diff --git a/src/pip/_internal/utils/unpacking.py b/src/pip/_internal/utils/unpacking.py +index 5f63f97..c31542f 100644 +--- a/src/pip/_internal/utils/unpacking.py ++++ b/src/pip/_internal/utils/unpacking.py +@@ -184,6 +184,13 @@ def untar_file(filename: str, location: str) -> None: + "outside target directory ({})" + ) + raise InstallationError(message.format(filename, path, location)) ++ ++ # Call the `data` filter for its side effect (raising exception) ++ try: ++ tarfile.data_filter(member.replace(name=fn), location) ++ except tarfile.LinkOutsideDestinationError: ++ pass ++ + if member.isdir(): + ensure_dir(path) + elif member.issym(): +diff --git a/src/pip/_vendor/distlib/util.py b/src/pip/_vendor/distlib/util.py +index 80bfc86..7e0941a 100644 +--- a/src/pip/_vendor/distlib/util.py ++++ b/src/pip/_vendor/distlib/util.py +@@ -1249,6 +1249,19 @@ def unarchive(archive_filename, dest_dir, format=None, check=True): + for tarinfo in archive.getmembers(): + if not isinstance(tarinfo.name, text_type): + tarinfo.name = tarinfo.name.decode('utf-8') ++ ++ # Limit extraction of dangerous items, if this Python ++ # allows it easily. If not, just trust the input. ++ # See: https://docs.python.org/3/library/tarfile.html#extraction-filters ++ def extraction_filter(member, path): ++ """Run tarfile.tar_fillter, but raise the expected ValueError""" ++ # This is only called if the current Python has tarfile filters ++ try: ++ return tarfile.tar_filter(member, path) ++ except tarfile.FilterError as exc: ++ raise ValueError(str(exc)) ++ archive.extraction_filter = extraction_filter ++ + archive.extractall(dest_dir) + + finally: +diff --git a/tests/unit/test_utils_unpacking.py b/tests/unit/test_utils_unpacking.py +index ccb7a30..05324ad 100644 +--- a/tests/unit/test_utils_unpacking.py ++++ b/tests/unit/test_utils_unpacking.py +@@ -171,6 +171,23 @@ class TestUnpackArchives: + test_tar = self.make_tar_file("test_tar.tar", files) + untar_file(test_tar, self.tempdir) + ++ def test_unpack_tar_filter(self) -> None: ++ """ ++ Test that the tarfile.data_filter is used to disallow dangerous ++ behaviour (PEP-721) ++ """ ++ test_tar = os.path.join(self.tempdir, "test_tar_filter.tar") ++ with tarfile.open(test_tar, "w") as mytar: ++ file_tarinfo = tarfile.TarInfo("bad-link") ++ file_tarinfo.type = tarfile.SYMTYPE ++ file_tarinfo.linkname = "../../../../pwn" ++ mytar.addfile(file_tarinfo, io.BytesIO(b"")) ++ with pytest.raises(InstallationError) as e: ++ untar_file(test_tar, self.tempdir) ++ ++ assert "is outside the destination" in str(e.value) ++ ++ + + def test_unpack_tar_unicode(tmpdir: Path) -> None: + test_tar = tmpdir / "test.tar" +-- +2.44.0 + diff --git a/dummy-certifi.patch b/dummy-certifi.patch new file mode 100644 index 0000000..8896ce8 --- /dev/null +++ b/dummy-certifi.patch @@ -0,0 +1,128 @@ +From 09c983fdeabe3fa0b90b73f32ddf84a61e498e09 Mon Sep 17 00:00:00 2001 +From: Karolina Surma +Date: Tue, 15 Nov 2022 09:22:46 +0100 +Subject: [PATCH] Dummy certifi patch + +--- + src/pip/_vendor/certifi/core.py | 105 ++------------------------------ + 1 file changed, 6 insertions(+), 99 deletions(-) + +diff --git a/src/pip/_vendor/certifi/core.py b/src/pip/_vendor/certifi/core.py +index c3e5466..eb297f7 100644 +--- a/src/pip/_vendor/certifi/core.py ++++ b/src/pip/_vendor/certifi/core.py +@@ -4,105 +4,12 @@ certifi.py + + This module returns the installation location of cacert.pem or its contents. + """ +-import sys + ++# The RPM-packaged certifi always uses the system certificates ++def where() -> str: ++ return '/etc/pki/tls/certs/ca-bundle.crt' + +-if sys.version_info >= (3, 11): ++def contents() -> str: ++ with open(where(), encoding='utf=8') as data: ++ return data.read() + +- from importlib.resources import as_file, files +- +- _CACERT_CTX = None +- _CACERT_PATH = None +- +- def where() -> str: +- # This is slightly terrible, but we want to delay extracting the file +- # in cases where we're inside of a zipimport situation until someone +- # actually calls where(), but we don't want to re-extract the file +- # on every call of where(), so we'll do it once then store it in a +- # global variable. +- global _CACERT_CTX +- global _CACERT_PATH +- if _CACERT_PATH is None: +- # This is slightly janky, the importlib.resources API wants you to +- # manage the cleanup of this file, so it doesn't actually return a +- # path, it returns a context manager that will give you the path +- # when you enter it and will do any cleanup when you leave it. In +- # the common case of not needing a temporary file, it will just +- # return the file system location and the __exit__() is a no-op. +- # +- # We also have to hold onto the actual context manager, because +- # it will do the cleanup whenever it gets garbage collected, so +- # we will also store that at the global level as well. +- _CACERT_CTX = as_file(files("pip._vendor.certifi").joinpath("cacert.pem")) +- _CACERT_PATH = str(_CACERT_CTX.__enter__()) +- +- return _CACERT_PATH +- +- def contents() -> str: +- return files("pip._vendor.certifi").joinpath("cacert.pem").read_text(encoding="ascii") +- +-elif sys.version_info >= (3, 7): +- +- from importlib.resources import path as get_path, read_text +- +- _CACERT_CTX = None +- _CACERT_PATH = None +- +- def where() -> str: +- # This is slightly terrible, but we want to delay extracting the +- # file in cases where we're inside of a zipimport situation until +- # someone actually calls where(), but we don't want to re-extract +- # the file on every call of where(), so we'll do it once then store +- # it in a global variable. +- global _CACERT_CTX +- global _CACERT_PATH +- if _CACERT_PATH is None: +- # This is slightly janky, the importlib.resources API wants you +- # to manage the cleanup of this file, so it doesn't actually +- # return a path, it returns a context manager that will give +- # you the path when you enter it and will do any cleanup when +- # you leave it. In the common case of not needing a temporary +- # file, it will just return the file system location and the +- # __exit__() is a no-op. +- # +- # We also have to hold onto the actual context manager, because +- # it will do the cleanup whenever it gets garbage collected, so +- # we will also store that at the global level as well. +- _CACERT_CTX = get_path("pip._vendor.certifi", "cacert.pem") +- _CACERT_PATH = str(_CACERT_CTX.__enter__()) +- +- return _CACERT_PATH +- +- def contents() -> str: +- return read_text("pip._vendor.certifi", "cacert.pem", encoding="ascii") +- +-else: +- import os +- import types +- from typing import Union +- +- Package = Union[types.ModuleType, str] +- Resource = Union[str, "os.PathLike"] +- +- # This fallback will work for Python versions prior to 3.7 that lack the +- # importlib.resources module but relies on the existing `where` function +- # so won't address issues with environments like PyOxidizer that don't set +- # __file__ on modules. +- def read_text( +- package: Package, +- resource: Resource, +- encoding: str = 'utf-8', +- errors: str = 'strict' +- ) -> str: +- with open(where(), encoding=encoding) as data: +- return data.read() +- +- # If we don't have importlib.resources, then we will just do the old logic +- # of assuming we're on the filesystem and munge the path directly. +- def where() -> str: +- f = os.path.dirname(__file__) +- +- return os.path.join(f, "cacert.pem") +- +- def contents() -> str: +- return read_text("pip._vendor.certifi", "cacert.pem", encoding="ascii") +-- +2.37.3 + diff --git a/no-version-warning.patch b/no-version-warning.patch new file mode 100644 index 0000000..6c34bec --- /dev/null +++ b/no-version-warning.patch @@ -0,0 +1,16 @@ +diff --git a/src/pip/_vendor/packaging/version.py b/src/pip/_vendor/packaging/version.py +index de9a09a..154e94d 100644 +--- a/src/pip/_vendor/packaging/version.py ++++ b/src/pip/_vendor/packaging/version.py +@@ -108,11 +108,6 @@ class LegacyVersion(_BaseVersion): + self._version = str(version) + self._key = _legacy_cmpkey(self._version) + +- warnings.warn( +- "Creating a LegacyVersion has been deprecated and will be " +- "removed in the next major release", +- DeprecationWarning, +- ) + + def __str__(self) -> str: + return self._version diff --git a/nowarn-pip._internal.main.patch b/nowarn-pip._internal.main.patch new file mode 100644 index 0000000..68f5971 --- /dev/null +++ b/nowarn-pip._internal.main.patch @@ -0,0 +1,76 @@ +From 8dd3793d1bab226cec9c5c49b01718a9634bc403 Mon Sep 17 00:00:00 2001 +From: Karolina Surma +Date: Mon, 10 May 2021 16:48:49 +0200 +Subject: [PATCH] Don't warn the user about pip._internal.main() entrypoint + +In Fedora, we use that in ensurepip and users cannot do anything about it, +this warning is juts moot. Also, the warning breaks CPython test suite. + +Co-Authored-By: =?UTF-8?q?Miro=20Hron=C4=8Dok?= +--- + src/pip/_internal/__init__.py | 2 +- + src/pip/_internal/utils/entrypoints.py | 19 ++++++++++--------- + tests/functional/test_cli.py | 3 ++- + 3 files changed, 13 insertions(+), 11 deletions(-) + +diff --git a/src/pip/_internal/__init__.py b/src/pip/_internal/__init__.py +index 6afb5c6..faf25af 100755 +--- a/src/pip/_internal/__init__.py ++++ b/src/pip/_internal/__init__.py +@@ -16,4 +16,4 @@ def main(args: (Optional[List[str]]) = None) -> int: + """ + from pip._internal.utils.entrypoints import _wrapper + +- return _wrapper(args) ++ return _wrapper(args, _nowarn=True) +diff --git a/src/pip/_internal/utils/entrypoints.py b/src/pip/_internal/utils/entrypoints.py +index f292c64..2e29a5e 100644 +--- a/src/pip/_internal/utils/entrypoints.py ++++ b/src/pip/_internal/utils/entrypoints.py +@@ -20,7 +20,7 @@ if WINDOWS: + ] + + +-def _wrapper(args: Optional[List[str]] = None) -> int: ++def _wrapper(args: Optional[List[str]] = None, _nowarn: bool = False) -> int: + """Central wrapper for all old entrypoints. + + Historically pip has had several entrypoints defined. Because of issues +@@ -32,14 +32,15 @@ def _wrapper(args: Optional[List[str]] = None) -> int: + directing them to an appropriate place for help, we now define all of + our old entrypoints as wrappers for the current one. + """ +- sys.stderr.write( +- "WARNING: pip is being invoked by an old script wrapper. This will " +- "fail in a future version of pip.\n" +- "Please see https://github.com/pypa/pip/issues/5599 for advice on " +- "fixing the underlying issue.\n" +- "To avoid this problem you can invoke Python with '-m pip' instead of " +- "running pip directly.\n" +- ) ++ if not _nowarn: ++ sys.stderr.write( ++ "WARNING: pip is being invoked by an old script wrapper. This will " ++ "fail in a future version of pip.\n" ++ "Please see https://github.com/pypa/pip/issues/5599 for advice on " ++ "fixing the underlying issue.\n" ++ "To avoid this problem you can invoke Python with '-m pip' instead of " ++ "running pip directly.\n" ++ ) + return main(args) + + +diff --git a/tests/functional/test_cli.py b/tests/functional/test_cli.py +index 3e85703..f86c392 100644 +--- a/tests/functional/test_cli.py ++++ b/tests/functional/test_cli.py +@@ -43,4 +43,5 @@ def test_entrypoints_work(entrypoint: str, script: PipTestEnvironment) -> None: + result = script.pip("-V") + result2 = script.run("fake_pip", "-V", allow_stderr_warning=True) + assert result.stdout == result2.stdout +- assert "old script wrapper" in result2.stderr ++ if entrypoint[0] != "fake_pip = pip._internal:main": ++ assert "old script wrapper" in result2.stderr +-- +2.35.3 + diff --git a/python-pip.spec b/python-pip.spec new file mode 100644 index 0000000..2347c00 --- /dev/null +++ b/python-pip.spec @@ -0,0 +1,906 @@ +## START: Set by rpmautospec +## (rpmautospec version 0.6.5) +## RPMAUTOSPEC: autorelease, autochangelog +%define autorelease(e:s:pb:n) %{?-p:0.}%{lua: + release_number = 7; + base_release_number = tonumber(rpm.expand("%{?-b*}%{!?-b:1}")); + print(release_number + base_release_number - 1); +}%{?-e:.%{-e*}}%{?-s:.%{-s*}}%{!?-n:%{?dist}} +## END: Set by rpmautospec + +# The original RHEL N+1 content set is defined by (build)dependencies +# of the packages in Fedora ELN. Hence we disable tests and documentation here +# to prevent pulling many unwanted packages in. +# We intentionally keep this enabled on EPEL. +%bcond tests %[%{defined fedora} || %{defined epel}] +%bcond doc %[%{defined fedora} || %{defined epel}] + +%global srcname pip +%global base_version 23.3.2 +%global upstream_version %{base_version}%{?prerel} +%global python_wheel_name %{srcname}-%{upstream_version}-py3-none-any.whl + +Name: python-%{srcname} +Version: %{base_version}%{?prerel:~%{prerel}} +Release: %autorelease +Summary: A tool for installing and managing Python packages + +# We bundle a lot of libraries with pip, which itself is under MIT license. +# Here is the list of the libraries with corresponding licenses: + +# appdirs: MIT +# certifi: MPL-2.0 +# chardet: LGPL-2.1-only +# colorama: BSD-3-Clause +# CacheControl: Apache-2.0 +# distlib: Python-2.0.1 +# distro: Apache-2.0 +# html5lib: MIT +# idna: BSD-3-Clause +# ipaddress: Python-2.0.1 +# msgpack: Apache-2.0 +# packaging: Apache-2.0 OR BSD-2-Clause +# progress: ISC +# pygments: BSD-2-Clause +# pyparsing: MIT +# pyproject-hooks: MIT +# requests: Apache-2.0 +# resolvelib: ISC +# rich: MIT +# setuptools: MIT +# six: MIT +# tenacity: Apache-2.0 +# truststore: MIT +# tomli: MIT +# typing-extensions: Python-2.0.1 +# urllib3: MIT +# webencodings: BSD-3-Clause + +License: MIT AND Python-2.0.1 AND Apache-2.0 AND BSD-2-Clause AND BSD-3-Clause AND ISC AND LGPL-2.1-only AND MPL-2.0 AND (Apache-2.0 OR BSD-2-Clause) +URL: https://pip.pypa.io/ +Source0: https://github.com/pypa/pip/archive/%{upstream_version}/%{srcname}-%{upstream_version}.tar.gz + +BuildArch: noarch + +%if %{with tests} +BuildRequires: /usr/bin/git +BuildRequires: /usr/bin/hg +BuildRequires: /usr/bin/bzr +BuildRequires: /usr/bin/svn +BuildRequires: python-setuptools-wheel +BuildRequires: python-wheel-wheel +%endif + +# Prevent removing of the system packages installed under /usr/lib +# when pip install -U is executed. +# https://bugzilla.redhat.com/show_bug.cgi?id=1550368#c24 +# Could be replaced with https://www.python.org/dev/peps/pep-0668/ +Patch: remove-existing-dist-only-if-path-conflicts.patch + +# Use the system level root certificate instead of the one bundled in certifi +# https://bugzilla.redhat.com/show_bug.cgi?id=1655253 +# The same patch is a part of the RPM-packaged python-certifi +Patch: dummy-certifi.patch + +# Don't warn the user about pip._internal.main() entrypoint +# In Fedora, we use that in ensurepip and users cannot do anything about it, +# this warning is juts moot. Also, the warning breaks CPython test suite. +Patch: nowarn-pip._internal.main.patch + +# Don't warn the user about packaging's LegacyVersion being deprecated. +# (This also breaks Python's test suite when warnings are treated as errors.) +# Upstream issue: https://github.com/pypa/packaging/issues/368 +Patch: no-version-warning.patch + +# CVE-2007-4559, PEP-721, PEP-706: Use tarfile.data_filter for extracting +# - Minimal downstream-only patch, to be replaced by upstream solution +# proposed in https://github.com/pypa/pip/pull/12214 +# - Test patch submitted upstream in the above pull request +# - Patch for vendored distlib, accepted upstream: +# https://github.com/pypa/distlib/pull/201 +Patch: cve-2007-4559-tarfile.patch + +%description +pip is a package management system used to install and manage software packages +written in Python. Many packages can be found in the Python Package Index +(PyPI). pip is a recursive acronym that can stand for either "Pip Installs +Packages" or "Pip Installs Python". + + + +# Virtual provides for the packages bundled by pip. +# You can generate it with: +# %%{_rpmconfigdir}/pythonbundles.py --namespace 'python%%{1}dist' src/pip/_vendor/vendor.txt +%global bundled() %{expand: +Provides: bundled(python%{1}dist(cachecontrol)) = 0.13.1 +Provides: bundled(python%{1}dist(certifi)) = 2023.7.22 +Provides: bundled(python%{1}dist(chardet)) = 5.1 +Provides: bundled(python%{1}dist(colorama)) = 0.4.6 +Provides: bundled(python%{1}dist(distlib)) = 0.3.6 +Provides: bundled(python%{1}dist(distro)) = 1.8 +Provides: bundled(python%{1}dist(idna)) = 3.4 +Provides: bundled(python%{1}dist(msgpack)) = 1.0.5 +Provides: bundled(python%{1}dist(packaging)) = 21.3 +Provides: bundled(python%{1}dist(platformdirs)) = 3.8.1 +Provides: bundled(python%{1}dist(pygments)) = 2.15.1 +Provides: bundled(python%{1}dist(pyparsing)) = 3.1 +Provides: bundled(python%{1}dist(pyproject-hooks)) = 1 +Provides: bundled(python%{1}dist(requests)) = 2.31 +Provides: bundled(python%{1}dist(resolvelib)) = 1.0.1 +Provides: bundled(python%{1}dist(rich)) = 13.4.2 +Provides: bundled(python%{1}dist(setuptools)) = 68 +Provides: bundled(python%{1}dist(six)) = 1.16 +Provides: bundled(python%{1}dist(tenacity)) = 8.2.2 +Provides: bundled(python%{1}dist(truststore)) = 0.8 +Provides: bundled(python%{1}dist(tomli)) = 2.0.1 +Provides: bundled(python%{1}dist(typing-extensions)) = 4.7.1 +Provides: bundled(python%{1}dist(urllib3)) = 1.26.17 +Provides: bundled(python%{1}dist(webencodings)) = 0.5.1 +} + +# Some manylinux1 wheels need libcrypt.so.1. +# Manylinux1, a common (as of 2019) platform tag for binary wheels, relies +# on a glibc version that included ancient crypto functions, which were +# moved to libxcrypt and then removed in: +# https://fedoraproject.org/wiki/Changes/FullyRemoveDeprecatedAndUnsafeFunctionsFromLibcrypt +# The manylinux1 standard assumed glibc would keep ABI compatibility, +# but that's only the case if libcrypt.so.1 (libxcrypt-compat) is around. +# This should be solved in the next manylinux standard (but it may be +# a long time until manylinux1 is phased out). +# See: https://github.com/pypa/manylinux/issues/305 +# Note that manylinux is only applicable to x86 (both 32 and 64 bits) +# As of Python 3.12, we no longer use this, +# see https://discuss.python.org/t/29455/ +# However, we keep it around for previous Python versions that use the wheel package. +%global crypt_compat_recommends() %{expand: +Recommends: (libcrypt.so.1()(64bit) if python%{1}(x86-64)) +Recommends: (libcrypt.so.1 if python%{1}(x86-32)) +} + + + +%package -n python%{python3_pkgversion}-%{srcname} +Summary: A tool for installing and managing Python3 packages + +BuildRequires: python%{python3_pkgversion}-devel +# python3 bootstrap: this is rebuilt before the final build of python3, which +# adds the dependency on python3-rpm-generators, so we require it manually +# Note that the package prefix is always python3-, even if we build for 3.X +# The minimal version is for bundled provides verification script +BuildRequires: python3-rpm-generators >= 11-8 +BuildRequires: python%{python3_pkgversion}-setuptools +BuildRequires: python%{python3_pkgversion}-wheel +BuildRequires: bash-completion +BuildRequires: ca-certificates +Requires: ca-certificates + +# Virtual provides for the packages bundled by pip: +%{bundled 3} + +Provides: pip = %{version}-%{release} +Conflicts: python-pip < %{version}-%{release} + +%description -n python%{python3_pkgversion}-%{srcname} +pip is a package management system used to install and manage software packages +written in Python. Many packages can be found in the Python Package Index +(PyPI). pip is a recursive acronym that can stand for either "Pip Installs +Packages" or "Pip Installs Python". + +%if %{with doc} +%package doc +Summary: A documentation for a tool for installing and managing Python packages + +BuildRequires: python%{python3_pkgversion}-sphinx +BuildRequires: python%{python3_pkgversion}-sphinx-inline-tabs +BuildRequires: python%{python3_pkgversion}-sphinx-copybutton +BuildRequires: python%{python3_pkgversion}-myst-parser + +%description doc +A documentation for a tool for installing and managing Python packages + +%endif + +%package -n %{python_wheel_pkg_prefix}-%{srcname}-wheel +Summary: The pip wheel +Requires: ca-certificates + +# Virtual provides for the packages bundled by pip: +%{bundled 3} + +# This is only relevant for Pythons that are older than 3.12 and don't use their own bundled wheels +# It is also only relevant when this wheel is shared across multiple Pythons +%if "%{python_wheel_pkg_prefix}" == "python" +%{crypt_compat_recommends 3.11} +%{crypt_compat_recommends 3.10} +%{crypt_compat_recommends 3.9} +%{crypt_compat_recommends 3.8} +%{crypt_compat_recommends 3.7} +%endif + +%description -n %{python_wheel_pkg_prefix}-%{srcname}-wheel +A Python wheel of pip to use with venv. + +%prep +%autosetup -p1 -n %{srcname}-%{upstream_version} + +# this goes together with patch4 +rm src/pip/_vendor/certifi/*.pem + +# Do not use furo as HTML theme in docs +# furo is not available in Fedora +sed -i '/html_theme = "furo"/d' docs/html/conf.py + +# towncrier extension for Sphinx is not yet available in Fedora +sed -i '/"sphinxcontrib.towncrier",/d' docs/html/conf.py + +# tests expect wheels in here +ln -s %{python_wheel_dir} tests/data/common_wheels + +# Remove windows executable binaries +rm -v src/pip/_vendor/distlib/*.exe +sed -i '/\.exe/d' setup.py + +# Remove RIGHT-TO-LEFT OVERRIDE from AUTHORS.txt +# https://github.com/pypa/pip/pull/12046 +%{python3} -c 'from pathlib import Path; p = Path("AUTHORS.txt"); p.write_text("".join(c for c in p.read_text() if c != "\u202e"))' + +# Remove unused test requirements +sed -Ei '/pytest-(cov|xdist|rerunfailures)/d' tests/requirements.txt + + +%if %{with tests} +%generate_buildrequires +# we only use this to generate test requires +# the "pyproject" part is explicitly disabled as it generates a requirement on pip +%pyproject_buildrequires -N tests/requirements.txt +%endif + + +%build +%py3_build_wheel + +%if %{with doc} +export PYTHONPATH=./src/ +# from tox.ini +sphinx-build-3 -b html docs/html docs/build/html +sphinx-build-3 -b man docs/man docs/build/man -c docs/html +rm -rf docs/build/html/{.doctrees,.buildinfo} +%endif + + +%install +# The following is similar to %%pyproject_install, but we don't have +# /usr/bin/pip yet, so we install using the wheel directly. +# (This is not standard wheel usage, but the pip wheel supports it -- see +# pip/__main__.py) +%{python3} dist/%{python_wheel_name}/pip install \ + --root %{buildroot} \ + --no-deps \ + --disable-pip-version-check \ + --progress-bar off \ + --verbose \ + --ignore-installed \ + --no-warn-script-location \ + --no-index \ + --no-cache-dir \ + --find-links dist \ + 'pip==%{upstream_version}' + +%if %{with doc} +pushd docs/build/man +install -d %{buildroot}%{_mandir}/man1 +for MAN in *1; do +install -pm0644 $MAN %{buildroot}%{_mandir}/man1/$MAN +for pip in "pip3" "pip-3" "pip%{python3_version}" "pip-%{python3_version}"; do +echo ".so $MAN" > %{buildroot}%{_mandir}/man1/${MAN/pip/$pip} +done +done +popd +%endif + +mkdir -p %{buildroot}%{bash_completions_dir} +PYTHONPATH=%{buildroot}%{python3_sitelib} \ + %{buildroot}%{_bindir}/pip completion --bash \ + > %{buildroot}%{bash_completions_dir}/pip3 + +# Make bash completion apply to all the 5 symlinks we install +sed -i -e "s/^\\(complete.*\\) pip\$/\\1 pip pip{,-}{3,%{python3_version}}/" \ + -e s/_pip_completion/_pip3_completion/ \ + %{buildroot}%{bash_completions_dir}/pip3 + + +# Provide symlinks to executables to comply with Fedora guidelines for Python +ln -s ./pip%{python3_version} %{buildroot}%{_bindir}/pip-%{python3_version} +ln -s ./pip-%{python3_version} %{buildroot}%{_bindir}/pip-3 + + +# Make sure the INSTALLER is not pip and remove RECORD +# %%pyproject macros do this for all packages +echo rpm > %{buildroot}%{python3_sitelib}/pip-%{upstream_version}.dist-info/INSTALLER +rm %{buildroot}%{python3_sitelib}/pip-%{upstream_version}.dist-info/RECORD + +mkdir -p %{buildroot}%{python_wheel_dir} +install -p dist/%{python_wheel_name} -t %{buildroot}%{python_wheel_dir} + + +%check +# Verify bundled provides are up to date +%{_rpmconfigdir}/pythonbundles.py src/pip/_vendor/vendor.txt --compare-with '%{bundled 3}' + +# Verify no unwanted files are present in the package +grep "exe$" %{pyproject_files} && exit 1 || true +grep "pem$" %{pyproject_files} && exit 1 || true + +# Verify we can at least run basic commands without crashing +%{py3_test_envvars} %{buildroot}%{_bindir}/pip --help +%{py3_test_envvars} %{buildroot}%{_bindir}/pip list +%{py3_test_envvars} %{buildroot}%{_bindir}/pip show pip + +%if %{with tests} +# Upstream tests +# bash completion tests only work from installed package +pytest_k='not completion' + +# --deselect'ed tests are not compatible with the latest virtualenv +# These files contain almost 500 tests so we should enable them back +# as soon as pip will be compatible upstream +# https://github.com/pypa/pip/pull/8441 +%pytest -m 'not network' -k "$(echo $pytest_k)" \ + --deselect tests/functional --deselect tests/lib/test_lib.py +%endif + + +%files -n python%{python3_pkgversion}-%{srcname} +%doc README.rst +%license %{python3_sitelib}/pip-%{upstream_version}.dist-info/LICENSE.txt +%if %{with doc} +%{_mandir}/man1/pip.* +%{_mandir}/man1/pip-*.* +%{_mandir}/man1/pip3.* +%{_mandir}/man1/pip3-*.* +%endif +%{_bindir}/pip +%{_bindir}/pip3 +%{_bindir}/pip-3 +%{_bindir}/pip%{python3_version} +%{_bindir}/pip-%{python3_version} +%{python3_sitelib}/pip* +%dir %{bash_completions_dir} +%{bash_completions_dir}/pip3 + +%if %{with doc} +%files doc +%license LICENSE.txt +%doc README.rst +%doc docs/build/html +%endif + +%files -n %{python_wheel_pkg_prefix}-%{srcname}-wheel +%license LICENSE.txt +# we own the dir for simplicity +%dir %{python_wheel_dir}/ +%{python_wheel_dir}/%{python_wheel_name} + +%changelog +## START: Generated by rpmautospec +* Tue Oct 29 2024 Troy Dawson - 23.3.2-7 +- Bump release for October 2024 mass rebuild: + +* Wed Sep 18 2024 Karolina Surma - 23.3.2-6 +- Verify no unwanted files are present in the package + +* Fri Sep 06 2024 Karolina Surma - 23.3.2-5 +- CI: Adjust tests for c10s + +* Fri Jul 26 2024 Karolina Surma - 23.3.2-4 +- Add gating.yaml + +* Mon Jun 24 2024 Troy Dawson - 23.3.2-3 +- Bump release for June 2024 mass rebuild + +* Tue May 07 2024 Charalampos Stratakis - 23.3.2-2 +- Use tarfile.data_filter for extracting (CVE-2007-4559, PEP-721, PEP-706) +- Require Python with tarfile filters +- Resolves: RHEL-25820 + +* Thu Jan 25 2024 Miro Hrončok - 23.3.2-1 +- Update to 23.3.2 + +* Mon Jan 22 2024 Miro Hrončok - 23.3.1-5 +- Switched to autogenerated BuildRequires for test dependencies, + which removed some that were no longer necessary + +* Mon Jan 22 2024 Fedora Release Engineering - 23.3.1-4 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild + +* Fri Jan 12 2024 Maxwell G - 23.3.1-3 +- Remove unused python3-mock dependency + +* Wed Jan 03 2024 Maxwell G - 23.3.1-2 +- Remove weak dependency on python3-setuptools + +* Thu Nov 16 2023 Petr Viktorin - 23.3.1-1 +- Update to 23.3.1 +Resolves: rhbz#2244306 + +* Fri Aug 04 2023 Miro Hrončok - 23.2.1-1 +- Update to 23.2.1 +Resolves: rhbz#2223082 + +* Fri Aug 04 2023 Miro Hrončok - 23.1.2-7 +- Actually run the tests and build the docs when building this package + +* Wed Jul 26 2023 Miro Hrončok - 23.1.2-6 +- Drop no-longer-needed custom changes to /usr/bin/pip* +- Stop Recommending libcrypt.so.1 on Python 3.12+ +Resolves: rhbz#2150373 + +* Tue Jul 25 2023 Python Maint - 23.1.2-5 +- Rebuilt for Python 3.12 + +* Fri Jul 21 2023 Fedora Release Engineering - 23.1.2-4 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_39_Mass_Rebuild + +* Thu Jul 20 2023 Python Maint - 23.1.2-3 +- Rebuilt for Python 3.12 + +* Tue Jun 13 2023 Python Maint - 23.1.2-2 +- Bootstrap for Python 3.12 + +* Fri May 19 2023 Miro Hrončok - 23.1.2-1 +- Update to 23.1.2 +Resolves: rhbz#2186979 + +* Mon Mar 27 2023 Karolina Surma - 23.0.1-2 +- Fix compatibility with Sphinx 6+ +Resolves: rhbz#2180479 + +* Mon Feb 20 2023 Tomáš Hrnčiar - 23.0.1-1 +- Update to 23.0.1 +Resolves: rhbz#2165760 + +* Fri Jan 20 2023 Fedora Release Engineering - 22.3.1-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_38_Mass_Rebuild + +* Mon Nov 14 2022 Karolina Surma - 22.3.1-1 +- Update to 22.3.1 +Resolves: rhbz#2135044 + +* Mon Sep 05 2022 Python Maint - 22.2.2-2 +- Fix crash when an empty dist-info/egg-info is present +Resolves: rhbz#2115001 +- No longer use the rpm_install prefix to determine RPM-installed packages +Related: rhbz#2026979 + +* Wed Aug 03 2022 Charalampos Stratakis - 22.2.2-1 +- Update to 22.2.2 +Resolves: rhbz#2109468 + +* Fri Jul 22 2022 Charalampos Stratakis - 22.2-1 +- Update to 22.2 +Resolves: rhbz#2109468 + +* Fri Jul 22 2022 Fedora Release Engineering - 22.0.4-5 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_37_Mass_Rebuild + +* Wed Jun 15 2022 Python Maint - 22.0.4-4 +- Rebuilt for Python 3.11 + +* Mon Jun 13 2022 Python Maint - 22.0.4-3 +- Bootstrap for Python 3.11 + +* Tue Apr 26 2022 Tomáš Hrnčiar - 22.0.4-2 +- Fallback to pep517 if setup.py is present and setuptools cannot be imported +- Fixes: rhbz#2020635 + +* Mon Mar 21 2022 Karolina Surma - 22.0.4-1 +- Update to 22.0.4 +Resolves: rhbz#2061262 + +* Wed Feb 16 2022 Lumír Balhar - 22.0.3-1 +- Update to 22.0.3 +Resolves: rhbz#2048243 + +* Fri Jan 21 2022 Fedora Release Engineering - 21.3.1-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_36_Mass_Rebuild + +* Mon Oct 25 2021 Miro Hrončok - 21.3.1-1 +- Update to 21.3.1 +- Resolves: rhbz#2016682 + +* Wed Oct 13 2021 Miro Hrončok - 21.3-1 +- Update to 21.3 +- Resolves: rhbz#2013026 +- Fix incomplete pip-updates in virtual environments + +* Wed Oct 06 2021 Charalampos Stratakis - 21.2.3-4 +- Remove bundled windows executables +- Resolves: rhbz#2005453 + +* Thu Sep 23 2021 Miro Hrončok - 21.2.3-3 +- Detect paths not to uninstall from via sysconfig's rpm_prefix install scheme + +* Mon Aug 16 2021 Miro Hrončok - 21.2.3-2 +- Fix broken uninstallation by a bogus downstream patch + +* Mon Aug 09 2021 Miro Hrončok - 21.2.3-1 +- Update to 21.2.3 +- Resolves: rhbz#1985635 + +* Fri Jul 23 2021 Fedora Release Engineering - 21.1.3-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_35_Mass_Rebuild + +* Tue Jun 29 2021 Lumír Balhar - 21.1.3-1 +- Update to 21.1.3 +Resolves: rhbz#1976449 + +* Mon Jun 07 2021 Karolina Surma - 21.1.2-1 +- Update to 21.1.2 +Resolves: rhbz#1963433 + +* Fri Jun 04 2021 Python Maint - 21.1.1-3 +- Rebuilt for Python 3.10 + +* Tue Jun 01 2021 Python Maint - 21.1.1-2 +- Bootstrap for Python 3.10 + +* Mon May 10 2021 Karolina Surma - 21.1.1-1 +- Update to 21.1.1 + +* Sat Mar 13 2021 Miro Hrončok - 21.0.1-2 +- python-pip-wheel: Remove bundled provides and libcrypt recommends for Python 2 + (The wheel is Python 3 only for a while) + +* Wed Feb 17 2021 Lumír Balhar - 21.0.1-1 +- Update to 21.0.1 +Resolves: rhbz#1922592 + +* Tue Jan 26 2021 Lumír Balhar - 21.0-1 +- Update to 21.0 (#1919530) + +* Thu Dec 17 2020 Petr Viktorin - 20.3.3-1 +- Update to 20.3.3 + +* Mon Nov 30 2020 Miro Hrončok - 20.3-1 +- Update to 20.3 +- Add support for PEP 600: Future manylinux Platform Tags +- New resolver +- Fixes: rhbz#1893470 + +* Mon Oct 19 2020 Lumír Balhar - 20.2.4-1 +- Update to 20.2.4 (#1889112) + +* Wed Aug 05 2020 Tomas Orsava - 20.2.2-1 +- Update to 20.2.2 (#1838553) + +* Wed Jul 29 2020 Fedora Release Engineering - 20.1.1-7 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_33_Mass_Rebuild + +* Fri Jul 10 2020 Lumír Balhar - 20.1.1-6 +- Do not emit a warning about root privileges when --root is used + +* Wed Jul 08 2020 Miro Hrončok - 20.1.1-5 +- Update bundled provides to match 20.1.1 + +* Tue Jun 16 2020 Lumír Balhar - 20.1.1-4 +- Deselect tests incompatible with the latest virtualenv + +* Sun May 24 2020 Miro Hrončok - 20.1.1-3 +- Rebuilt for Python 3.9 + +* Thu May 21 2020 Miro Hrončok - 20.1.1-2 +- Bootstrap for Python 3.9 + +* Wed May 20 2020 Tomas Hrnciar - 20.1.1-1 +- Update to 20.1.1 + +* Wed Apr 29 2020 Tomas Hrnciar - 20.1-1 +- Update to 20.1 + +* Mon Apr 27 2020 Tomas Hrnciar - 20.1~b1-1 +- Update to 20.1~b1 + +* Wed Apr 15 2020 Miro Hrončok - 20.0.2-4 +- Only recommend setuptools, don't require them + +* Fri Apr 10 2020 Miro Hrončok - 20.0.2-3 +- Allow setting $TMPDIR to $PWD/... during pip wheel (#1806625) + +* Tue Mar 10 2020 Miro Hrončok - 20.0.2-2 +- Don't warn the user about pip._internal.main() entrypoint to fix ensurepip + +* Mon Mar 02 2020 Miro Hrončok - 20.0.2-1 +- Update to 20.0.2 (#1793456) + +* Thu Jan 30 2020 Fedora Release Engineering - 19.3.1-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_32_Mass_Rebuild + +* Mon Nov 04 2019 Tomas Orsava - 19.3.1-1 +- Update to 19.3.1 (#1761508) +- Drop upstreamed patch that fixed expected output in test to not break with alpha/beta/rc Python versions + +* Wed Oct 30 2019 Miro Hrončok - 19.2.3-2 +- Make /usr/bin/pip(3) work with user-installed pip 19.3+ (#1767212) + +* Mon Sep 02 2019 Miro Hrončok - 19.2.3-1 +- Update to 19.2.3 (#1742230) +- Drop patch that should strip path prefixes from RECORD files, the paths are relative + +* Wed Aug 21 2019 Petr Viktorin - 19.1.1-8 +- Remove python2-pip +- Make pip bootstrap itself, rather than with an extra bootstrap RPM build + +* Sat Aug 17 2019 Miro Hrončok - 19.1.1-7 +- Rebuilt for Python 3.8 + +* Wed Aug 14 2019 Miro Hrončok - 19.1.1-6 +- Bootstrap for Python 3.8 + +* Wed Aug 14 2019 Miro Hrončok - 19.1.1-5 +- Bootstrap for Python 3.8 + +* Fri Jul 26 2019 Fedora Release Engineering - 19.1.1-4 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_31_Mass_Rebuild + +* Mon Jul 15 2019 Petr Viktorin - 19.1.1-3 +- Recommend libcrypt.so.1 for manylinux1 compatibility +- Make /usr/bin/pip Python 3 + +* Mon Jun 10 2019 Miro Hrončok - 19.1.1-2 +- Fix root warning when pip is invoked via python -m pip +- Remove a redundant second WARNING prefix form the abovementioned warning + +* Wed May 15 2019 Miro Hrončok - 19.1.1-1 +- Update to 19.1.1 (#1706995) + +* Thu Apr 25 2019 Miro Hrončok - 19.1-1 +- Update to 19.1 (#1702525) + +* Wed Mar 06 2019 Miro Hrončok - 19.0.3-1 +- Update to 19.0.3 (#1679277) + +* Wed Feb 13 2019 Miro Hrončok - 19.0.2-1 +- Update to 19.0.2 (#1668492) + +* Sat Feb 02 2019 Fedora Release Engineering - 18.1-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_30_Mass_Rebuild + +* Mon Dec 03 2018 Miro Hrončok - 18.1-2 +- Use the system level root certificate instead of the one bundled in certifi + +* Thu Nov 22 2018 Miro Hrončok - 18.1-1 +- Update to 18.1 (#1652089) + +* Tue Sep 18 2018 Victor Stinner - 18.0-4 +- Prevent removing of the system packages installed under /usr/lib + when pip install -U is executed. Original patch by Michal Cyprian. + Resolves: rhbz#1550368. + +* Wed Aug 08 2018 Miro Hrončok - 18.0-3 +- Create python-pip-wheel package with the wheel + +* Tue Jul 31 2018 Miro Hrončok - 18.0-2 +- Remove redundant "Unicode" from License + +* Mon Jul 23 2018 Marcel Plch - 18.0-7 +- Update to 18.0 + +* Sat Jul 14 2018 Fedora Release Engineering - 9.0.3-6 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_29_Mass_Rebuild + +* Mon Jun 18 2018 Miro Hrončok - 9.0.3-5 +- Rebuilt for Python 3.7 + +* Wed Jun 13 2018 Miro Hrončok - 9.0.3-4 +- Bootstrap for Python 3.7 + +* Wed Jun 13 2018 Miro Hrončok - 9.0.3-3 +- Bootstrap for Python 3.7 + +* Fri May 04 2018 Miro Hrončok - 9.0.3-2 +- Allow to import pip10's main from pip9's /usr/bin/pip +- Do not show the "new version of pip" warning outside of venv +Resolves: rhbz#1569488 +Resolves: rhbz#1571650 +Resolves: rhbz#1573755 + +* Thu Mar 29 2018 Charalampos Stratakis - 9.0.3-1 +- Update to 9.0.3 + +* Wed Feb 21 2018 Lumír Balhar - 9.0.1-16 +- Include built HTML documentation (in the new -doc subpackage) and man page + +* Fri Feb 09 2018 Fedora Release Engineering - 9.0.1-15 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_28_Mass_Rebuild + +* Mon Dec 04 2017 Charalampos Stratakis - 9.0.1-14 +- Reintroduce the ipaddress module in the python3 subpackage. + +* Mon Nov 20 2017 Charalampos Stratakis - 9.0.1-13 +- Add virtual provides for the bundled libraries. (rhbz#1096912) + +* Tue Aug 29 2017 Tomas Orsava - 9.0.1-12 +- Switch macros to bcond's and make Python 2 optional to facilitate building + the Python 2 and Python 3 modules + +* Thu Jul 27 2017 Fedora Release Engineering - 9.0.1-11 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Mass_Rebuild + +* Tue May 23 2017 Tomas Orsava - 9.0.1-10 +- Modernized package descriptions +Resolves: rhbz#1452568 + +* Tue Mar 21 2017 Tomas Orsava - 9.0.1-9 +- Fix typo in the sudo pip warning + +* Fri Mar 03 2017 Tomas Orsava - 9.0.1-8 +- Patch 1 update: No sudo pip warning in venv or virtualenv + +* Thu Feb 23 2017 Tomas Orsava - 9.0.1-7 +- Patch 1 update: Customize the warning with the proper version of the pip + command + +* Tue Feb 14 2017 Tomas Orsava - 9.0.1-6 +- Added patch 1: Emit a warning when running with root privileges + +* Sat Feb 11 2017 Fedora Release Engineering - 9.0.1-5 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_26_Mass_Rebuild + +* Mon Jan 02 2017 Tomas Orsava - 9.0.1-4 +- Provide symlinks to executables to comply with Fedora guidelines for Python +Resolves: rhbz#1406922 + +* Fri Dec 09 2016 Charalampos Stratakis - 9.0.1-3 +- Rebuild for Python 3.6 with wheel + +* Fri Dec 09 2016 Charalampos Stratakis - 9.0.1-2 +- Rebuild for Python 3.6 without wheel + +* Fri Nov 18 2016 Orion Poplawski - 9.0.1-1 +- Update to 9.0.1 + +* Fri Nov 18 2016 Orion Poplawski - 8.1.2-5 +- Enable EPEL Python 3 builds +- Use new python macros +- Cleanup spec + +* Fri Aug 05 2016 Tomas Orsava - 8.1.2-4 +- Updated the test sources + +* Fri Aug 05 2016 Tomas Orsava - 8.1.2-3 +- Moved python-pip into the python2-pip subpackage +- Added the python_provide macro + +* Tue Jul 19 2016 Fedora Release Engineering - 8.1.2-2 +- https://fedoraproject.org/wiki/Changes/Automatic_Provides_for_Python_RPM_Packages + +* Tue May 17 2016 Tomas Orsava - 8.1.2-1 +- Update to 8.1.2 +- Moved to a new PyPI URL format +- Updated the prefix-stripping patch because of upstream changes in pip/wheel.py + +* Mon Feb 22 2016 Slavek Kabrda - 8.0.2-1 +- Update to 8.0.2 + +* Thu Feb 04 2016 Fedora Release Engineering - 7.1.0-4 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_24_Mass_Rebuild + +* Wed Oct 14 2015 Robert Kuska - 7.1.0-3 +- Rebuilt for Python3.5 rebuild +- With wheel set to 1 + +* Tue Oct 13 2015 Robert Kuska - 7.1.0-2 +- Rebuilt for Python3.5 rebuild + +* Wed Jul 01 2015 Slavek Kabrda - 7.1.0-1 +- Update to 7.1.0 + +* Tue Jun 30 2015 Ville Skyttä - 7.0.3-3 +- Install bash completion +- Ship LICENSE.txt as %%license where available + +* Thu Jun 18 2015 Fedora Release Engineering - 7.0.3-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_23_Mass_Rebuild + +* Thu Jun 04 2015 Matej Stuchlik - 7.0.3-1 +- Update to 7.0.3 + +* Fri Mar 06 2015 Matej Stuchlik - 6.0.8-1 +- Update to 6.0.8 + +* Thu Dec 18 2014 Slavek Kabrda - 1.5.6-5 +- Only enable tests on Fedora. + +* Mon Dec 01 2014 Matej Stuchlik - 1.5.6-4 +- Add tests +- Add patch skipping tests requiring Internet access + +* Tue Nov 18 2014 Matej Stuchlik - 1.5.6-3 +- Added patch for local dos with predictable temp dictionary names + (http://seclists.org/oss-sec/2014/q4/655) + +* Sat Jun 07 2014 Fedora Release Engineering - 1.5.6-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_Mass_Rebuild + +* Sun May 25 2014 Matej Stuchlik - 1.5.6-1 +- Update to 1.5.6 + +* Fri Apr 25 2014 Matej Stuchlik - 1.5.4-4 +- Rebuild as wheel for Python 3.4 + +* Thu Apr 24 2014 Matej Stuchlik - 1.5.4-3 +- Disable build_wheel + +* Thu Apr 24 2014 Matej Stuchlik - 1.5.4-2 +- Rebuild as wheel for Python 3.4 + +* Mon Apr 07 2014 Matej Stuchlik - 1.5.4-1 +- Updated to 1.5.4 + +* Mon Oct 14 2013 Tim Flink - 1.4.1-1 +- Removed patch for CVE 2013-2099 as it has been included in the upstream 1.4.1 release +- Updated version to 1.4.1 + +* Sun Aug 04 2013 Fedora Release Engineering - 1.3.1-5 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_20_Mass_Rebuild + +* Tue Jul 16 2013 Toshio Kuratomi - 1.3.1-4 +- Fix for CVE 2013-2099 + +* Thu May 23 2013 Tim Flink - 1.3.1-3 +- undo python2 executable rename to python-pip. fixes #958377 +- fix summary to match upstream + +* Mon May 06 2013 Kevin Kofler - 1.3.1-2 +- Fix main package Summary, it's for Python 2, not 3 (#877401) + +* Fri Apr 26 2013 Jon Ciesla - 1.3.1-1 +- Update to 1.3.1, fix for CVE-2013-1888. + +* Thu Feb 14 2013 Fedora Release Engineering - 1.2.1-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_19_Mass_Rebuild + +* Tue Oct 09 2012 Tim Flink - 1.2.1-2 +- Fixing files for python3-pip + +* Thu Oct 04 2012 Tim Flink - 1.2.1-1 +- Update to upstream 1.2.1 +- Change binary from pip-python to python-pip (RHBZ#855495) +- Add alias from python-pip to pip-python, to be removed at a later date + +* Tue May 15 2012 Tim Flink - 1.1.0-1 +- Update to upstream 1.1.0 + +* Sat Jan 14 2012 Fedora Release Engineering - 1.0.2-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_17_Mass_Rebuild + +* Sat Oct 22 2011 Tim Flink - 1.0.2-1 +- update to 1.0.2 and added python3 subpackage + +* Wed Jun 22 2011 Tim Flink - 0.8.3-1 +- update to 0.8.3 and project home page + +* Tue Feb 08 2011 Fedora Release Engineering - 0.8.2-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_15_Mass_Rebuild + +* Mon Dec 20 2010 Luke Macken - 0.8.2-1 +- update to 0.8.2 of pip +* Mon Aug 30 2010 Peter Halliday - 0.8-1 +- update to 0.8 of pip +* Thu Jul 22 2010 David Malcolm - 0.7.2-5 +- Rebuilt for https://fedoraproject.org/wiki/Features/Python_2.7/MassRebuild + +* Wed Jul 7 2010 Peter Halliday - 0.7.2-1 +- update to 0.7.2 of pip +* Sun May 23 2010 Peter Halliday - 0.7.1-1 +- update to 0.7.1 of pip +* Fri Jan 1 2010 Peter Halliday - 0.6.1.4 +- fix dependency issue +* Fri Dec 18 2009 Peter Halliday - 0.6.1-2 +- fix spec file +* Thu Dec 17 2009 Peter Halliday - 0.6.1-1 +- upgrade to 0.6.1 of pip +* Mon Aug 31 2009 Peter Halliday - 0.4-1 +- Initial package + +## END: Generated by rpmautospec diff --git a/remove-existing-dist-only-if-path-conflicts.patch b/remove-existing-dist-only-if-path-conflicts.patch new file mode 100644 index 0000000..3a9ea25 --- /dev/null +++ b/remove-existing-dist-only-if-path-conflicts.patch @@ -0,0 +1,115 @@ +From 2c3f3a590ddfc151a456b44a5f96f0f603d178e9 Mon Sep 17 00:00:00 2001 +From: Lumir Balhar +Date: Wed, 16 Feb 2022 08:36:21 +0100 +Subject: [PATCH] Prevent removing of the system packages installed under + /usr/lib when pip install --upgrade is executed. +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Resolves: rhbz#1550368 + +Co-Authored-By: Michal Cyprian +Co-Authored-By: Victor Stinner +Co-Authored-By: Petr Viktorin +Co-Authored-By: Lumir Balhar +Co-Authored-By: Miro Hrončok +Co-Authored-By: Karolina Surma +--- + src/pip/_internal/metadata/base.py | 12 +++++++++++- + src/pip/_internal/req/req_install.py | 2 +- + src/pip/_internal/resolution/legacy/resolver.py | 4 +++- + src/pip/_internal/resolution/resolvelib/factory.py | 12 ++++++++++++ + 4 files changed, 27 insertions(+), 3 deletions(-) + +diff --git a/src/pip/_internal/metadata/base.py b/src/pip/_internal/metadata/base.py +index 151fd6d..f9109cd 100644 +--- a/src/pip/_internal/metadata/base.py ++++ b/src/pip/_internal/metadata/base.py +@@ -28,7 +28,7 @@ from pip._vendor.packaging.utils import NormalizedName + from pip._vendor.packaging.version import LegacyVersion, Version + + from pip._internal.exceptions import NoneMetadataError +-from pip._internal.locations import site_packages, user_site ++from pip._internal.locations import get_scheme, site_packages, user_site + from pip._internal.models.direct_url import ( + DIRECT_URL_METADATA_NAME, + DirectUrl, +@@ -560,6 +560,16 @@ class BaseDistribution(Protocol): + for extra in self._iter_egg_info_extras(): + metadata["Provides-Extra"] = extra + ++ @property ++ def in_install_path(self) -> bool: ++ """ ++ Return True if given Distribution is installed in ++ path matching distutils_scheme layout. ++ """ ++ norm_path = normalize_path(self.installed_location) ++ return norm_path.startswith(normalize_path( ++ get_scheme("").purelib.split('python')[0])) ++ + + class BaseEnvironment: + """An environment containing distributions to introspect.""" +diff --git a/src/pip/_internal/req/req_install.py b/src/pip/_internal/req/req_install.py +index a1e376c..ed7facf 100644 +--- a/src/pip/_internal/req/req_install.py ++++ b/src/pip/_internal/req/req_install.py +@@ -416,7 +416,7 @@ class InstallRequirement: + f"lack sys.path precedence to {existing_dist.raw_name} " + f"in {existing_dist.location}" + ) +- else: ++ elif existing_dist.in_install_path: + self.should_reinstall = True + else: + if self.editable: +diff --git a/src/pip/_internal/resolution/legacy/resolver.py b/src/pip/_internal/resolution/legacy/resolver.py +index fb49d41..040f2c1 100644 +--- a/src/pip/_internal/resolution/legacy/resolver.py ++++ b/src/pip/_internal/resolution/legacy/resolver.py +@@ -325,7 +325,9 @@ class Resolver(BaseResolver): + """ + # Don't uninstall the conflict if doing a user install and the + # conflict is not a user install. +- if not self.use_user_site or req.satisfied_by.in_usersite: ++ if ((not self.use_user_site ++ or req.satisfied_by.in_usersite) ++ and req.satisfied_by.in_install_path): + req.should_reinstall = True + req.satisfied_by = None + +diff --git a/src/pip/_internal/resolution/resolvelib/factory.py b/src/pip/_internal/resolution/resolvelib/factory.py +index a4c24b5..e7e2da9 100644 +--- a/src/pip/_internal/resolution/resolvelib/factory.py ++++ b/src/pip/_internal/resolution/resolvelib/factory.py +@@ -1,6 +1,8 @@ + import contextlib + import functools + import logging ++import sys ++import sysconfig + from typing import ( + TYPE_CHECKING, + Dict, +@@ -549,6 +551,16 @@ class Factory: + if dist is None: # Not installed, no uninstallation required. + return None + ++ # Prevent uninstalling packages from /usr ++ try: ++ if dist.installed_location in ( ++ sysconfig.get_path('purelib', scheme='posix_prefix', vars={'base': sys.base_prefix}), ++ sysconfig.get_path('platlib', scheme='posix_prefix', vars={'platbase': sys.base_prefix}), ++ ): ++ return None ++ except KeyError: # this Python doesn't have 'rpm_prefix' scheme yet ++ pass ++ + # We're installing into global site. The current installation must + # be uninstalled, no matter it's in global or user site, because the + # user site installation has precedence over global. +-- +2.35.3 + diff --git a/sources b/sources new file mode 100644 index 0000000..3ed3c55 --- /dev/null +++ b/sources @@ -0,0 +1 @@ +SHA512 (pip-23.3.2.tar.gz) = 976c6ab9959805f4d20d4bdedb4dabc95dd55f1ec78773f63f738599bbe44e766ad3a1394bee052a2c2386826d67686ad456726373345ba9e0d555fd251dff09