[Python-modules-commits] r31528 - in packages/python-pip/trunk/debian (3 files)

kitterman at users.alioth.debian.org kitterman at users.alioth.debian.org
Wed Dec 3 19:51:40 UTC 2014


    Date: Wednesday, December 3, 2014 @ 19:51:38
  Author: kitterman
Revision: 31528

* Team upload.
* Backport upstream fix to use non-predictable download directories
  - Fixes denial of service vector (CVE-2014-8991) (Closes: #725847)
  - Fixes retry failures (Closes: #769930)

Added:
  packages/python-pip/trunk/debian/patches/random-install-dir.patch
Modified:
  packages/python-pip/trunk/debian/changelog
  packages/python-pip/trunk/debian/patches/series

Modified: packages/python-pip/trunk/debian/changelog
===================================================================
--- packages/python-pip/trunk/debian/changelog	2014-12-02 17:27:55 UTC (rev 31527)
+++ packages/python-pip/trunk/debian/changelog	2014-12-03 19:51:38 UTC (rev 31528)
@@ -1,3 +1,12 @@
+python-pip (1.5.6-4) UNRELEASED; urgency=medium
+
+  * Team upload.
+  * Backport upstream fix to use non-predictable download directories
+    - Fixes denial of service vector (CVE-2014-8991) (Closes: #725847)
+    - Fixes retry failures (Closes: #769930)
+
+ -- Scott Kitterman <scott at kitterman.com>  Wed, 03 Dec 2014 13:46:31 -0500
+
 python-pip (1.5.6-3) unstable; urgency=medium
 
   * Team upload.

Added: packages/python-pip/trunk/debian/patches/random-install-dir.patch
===================================================================
--- packages/python-pip/trunk/debian/patches/random-install-dir.patch	                        (rev 0)
+++ packages/python-pip/trunk/debian/patches/random-install-dir.patch	2014-12-03 19:51:38 UTC (rev 31528)
@@ -0,0 +1,394 @@
+Description: Use randomized install directory
+ python-pip (1.5.6-4) UNRELEASED; urgency=medium
+ .
+   * Team upload.
+   * Backport upstream fix to use non-predictable download directories
+     - Fixes denial of service vector (CVE-2014-8991) (Closes: #725847)
+     - Fixes retry failures (Closes: #769930)
+Author: Donald Stufft <donald at stufft.io>
+Bug-Debian: http://bugs.debian.org/725847
+Bug-Debian: http://bugs.debian.org/769930
+Origin: https://github.com/pypa/pip/pull/2122
+Forwarded: not-needed
+Reviewed-By: Scott Kitterman <scott at kitterman.com>
+Last-Update: 2014-12-03
+
+--- python-pip-1.5.6.orig/pip/cmdoptions.py
++++ python-pip-1.5.6/pip/cmdoptions.py
+@@ -9,7 +9,7 @@ To be consistent, all options will follo
+ """
+ import copy
+ from optparse import OptionGroup, SUPPRESS_HELP, Option
+-from pip.locations import build_prefix, default_log_file
++from pip.locations import default_log_file
+ 
+ 
+ def make_option_group(group, parser):
+@@ -297,10 +297,8 @@ build_dir = OptionMaker(
+     '-b', '--build', '--build-dir', '--build-directory',
+     dest='build_dir',
+     metavar='dir',
+-    default=build_prefix,
+-    help='Directory to unpack packages into and build in. '
+-    'The default in a virtualenv is "<venv path>/build". '
+-    'The default for global installs is "<OS temp dir>/pip_build_<username>".')
++    help='Directory to unpack packages into and build in.',
++)
+ 
+ install_options = OptionMaker(
+     '--install-option',
+--- python-pip-1.5.6.orig/pip/commands/install.py
++++ python-pip-1.5.6/pip/commands/install.py
+@@ -10,6 +10,7 @@ from pip.basecommand import Command
+ from pip.index import PackageFinder
+ from pip.exceptions import InstallationError, CommandError, PreviousBuildDirError
+ from pip import cmdoptions
++from pip.util import BuildDirectory
+ 
+ 
+ class InstallCommand(Command):
+@@ -188,7 +189,7 @@ class InstallCommand(Command):
+         if (
+             options.no_install or
+             options.no_download or
+-            (options.build_dir != build_prefix) or
++            options.build_dir or
+             options.no_clean
+         ):
+             logger.deprecated('1.7', 'DEPRECATION: --no-install, --no-download, --build, '
+@@ -197,7 +198,16 @@ class InstallCommand(Command):
+         if options.download_dir:
+             options.no_install = True
+             options.ignore_installed = True
+-        options.build_dir = os.path.abspath(options.build_dir)
++
++        # If we have --no-install or --no-download and no --build we use the
++        # legacy static build dir
++        if (options.build_dir is None
++                and (options.no_install or options.no_download)):
++            options.build_dir = build_prefix
++
++        if options.build_dir:
++            options.build_dir = os.path.abspath(options.build_dir)
++
+         options.src_dir = os.path.abspath(options.src_dir)
+         install_options = options.install_options or []
+         if options.use_user_site:
+@@ -237,69 +247,71 @@ class InstallCommand(Command):
+ 
+         finder = self._build_package_finder(options, index_urls, session)
+ 
+-        requirement_set = RequirementSet(
+-            build_dir=options.build_dir,
+-            src_dir=options.src_dir,
+-            download_dir=options.download_dir,
+-            download_cache=options.download_cache,
+-            upgrade=options.upgrade,
+-            as_egg=options.as_egg,
+-            ignore_installed=options.ignore_installed,
+-            ignore_dependencies=options.ignore_dependencies,
+-            force_reinstall=options.force_reinstall,
+-            use_user_site=options.use_user_site,
+-            target_dir=temp_target_dir,
+-            session=session,
+-            pycompile=options.compile,
+-        )
+-        for name in args:
+-            requirement_set.add_requirement(
+-                InstallRequirement.from_line(name, None))
+-        for name in options.editables:
+-            requirement_set.add_requirement(
+-                InstallRequirement.from_editable(name, default_vcs=options.default_vcs))
+-        for filename in options.requirements:
+-            for req in parse_requirements(filename, finder=finder, options=options, session=session):
+-                requirement_set.add_requirement(req)
+-        if not requirement_set.has_requirements:
+-            opts = {'name': self.name}
+-            if options.find_links:
+-                msg = ('You must give at least one requirement to %(name)s '
+-                       '(maybe you meant "pip %(name)s %(links)s"?)' %
+-                       dict(opts, links=' '.join(options.find_links)))
+-            else:
+-                msg = ('You must give at least one requirement '
+-                       'to %(name)s (see "pip help %(name)s")' % opts)
+-            logger.warn(msg)
+-            return
+-
+-        try:
+-            if not options.no_download:
+-                requirement_set.prepare_files(finder, force_root_egg_info=self.bundle, bundle=self.bundle)
+-            else:
+-                requirement_set.locate_files()
+-
+-            if not options.no_install and not self.bundle:
+-                requirement_set.install(install_options, global_options, root=options.root_path)
+-                installed = ' '.join([req.name for req in
+-                                      requirement_set.successfully_installed])
+-                if installed:
+-                    logger.notify('Successfully installed %s' % installed)
+-            elif not self.bundle:
+-                downloaded = ' '.join([req.name for req in
+-                                       requirement_set.successfully_downloaded])
+-                if downloaded:
+-                    logger.notify('Successfully downloaded %s' % downloaded)
+-            elif self.bundle:
+-                requirement_set.create_bundle(self.bundle_filename)
+-                logger.notify('Created bundle in %s' % self.bundle_filename)
+-        except PreviousBuildDirError:
+-            options.no_clean = True
+-            raise
+-        finally:
+-            # Clean up
+-            if (not options.no_clean) and ((not options.no_install) or options.download_dir):
+-                requirement_set.cleanup_files(bundle=self.bundle)
++        build_delete = (not (options.no_clean or options.build_dir))
++        with BuildDirectory(options.build_dir, delete=build_delete) as build_dir:
++            requirement_set = RequirementSet(
++                build_dir=build_dir,
++                src_dir=options.src_dir,
++                download_dir=options.download_dir,
++                download_cache=options.download_cache,
++                upgrade=options.upgrade,
++                as_egg=options.as_egg,
++                ignore_installed=options.ignore_installed,
++                ignore_dependencies=options.ignore_dependencies,
++                force_reinstall=options.force_reinstall,
++                use_user_site=options.use_user_site,
++                target_dir=temp_target_dir,
++                session=session,
++                pycompile=options.compile,
++            )
++            for name in args:
++                requirement_set.add_requirement(
++                    InstallRequirement.from_line(name, None))
++            for name in options.editables:
++                requirement_set.add_requirement(
++                    InstallRequirement.from_editable(name, default_vcs=options.default_vcs))
++            for filename in options.requirements:
++                for req in parse_requirements(filename, finder=finder, options=options, session=session):
++                    requirement_set.add_requirement(req)
++            if not requirement_set.has_requirements:
++                opts = {'name': self.name}
++                if options.find_links:
++                    msg = ('You must give at least one requirement to %(name)s '
++                           '(maybe you meant "pip %(name)s %(links)s"?)' %
++                           dict(opts, links=' '.join(options.find_links)))
++                else:
++                    msg = ('You must give at least one requirement '
++                           'to %(name)s (see "pip help %(name)s")' % opts)
++                logger.warn(msg)
++                return
++
++            try:
++                if not options.no_download:
++                    requirement_set.prepare_files(finder, force_root_egg_info=self.bundle, bundle=self.bundle)
++                else:
++                    requirement_set.locate_files()
++
++                if not options.no_install and not self.bundle:
++                    requirement_set.install(install_options, global_options, root=options.root_path)
++                    installed = ' '.join([req.name for req in
++                                          requirement_set.successfully_installed])
++                    if installed:
++                        logger.notify('Successfully installed %s' % installed)
++                elif not self.bundle:
++                    downloaded = ' '.join([req.name for req in
++                                           requirement_set.successfully_downloaded])
++                    if downloaded:
++                        logger.notify('Successfully downloaded %s' % downloaded)
++                elif self.bundle:
++                    requirement_set.create_bundle(self.bundle_filename)
++                    logger.notify('Created bundle in %s' % self.bundle_filename)
++            except PreviousBuildDirError:
++                options.no_clean = True
++                raise
++            finally:
++                # Clean up
++                if (not options.no_clean) and ((not options.no_install) or options.download_dir):
++                    requirement_set.cleanup_files(bundle=self.bundle)
+ 
+         if options.target_dir:
+             if not os.path.exists(options.target_dir):
+--- python-pip-1.5.6.orig/pip/commands/wheel.py
++++ python-pip-1.5.6/pip/commands/wheel.py
+@@ -8,7 +8,7 @@ from pip.index import PackageFinder
+ from pip.log import logger
+ from pip.exceptions import CommandError, PreviousBuildDirError
+ from pip.req import InstallRequirement, RequirementSet, parse_requirements
+-from pip.util import normalize_path
++from pip.util import BuildDirectory, normalize_path
+ from pip.wheel import WheelBuilder
+ from pip import cmdoptions
+ 
+@@ -127,6 +127,9 @@ class WheelCommand(Command):
+                         "--extra-index-url is suggested.")
+             index_urls += options.mirrors
+ 
++        if options.build_dir:
++            options.build_dir = os.path.abspath(options.build_dir)
++
+         session = self._build_session(options)
+ 
+         finder = PackageFinder(find_links=options.find_links,
+@@ -141,59 +144,60 @@ class WheelCommand(Command):
+                                session=session,
+                             )
+ 
+-        options.build_dir = os.path.abspath(options.build_dir)
+-        requirement_set = RequirementSet(
+-            build_dir=options.build_dir,
+-            src_dir=None,
+-            download_dir=None,
+-            download_cache=options.download_cache,
+-            ignore_dependencies=options.ignore_dependencies,
+-            ignore_installed=True,
+-            session=session,
+-            wheel_download_dir=options.wheel_dir
+-        )
+-
+-        # make the wheelhouse
+-        if not os.path.exists(options.wheel_dir):
+-            os.makedirs(options.wheel_dir)
+-
+-        #parse args and/or requirements files
+-        for name in args:
+-            requirement_set.add_requirement(
+-                InstallRequirement.from_line(name, None))
+-
+-        for filename in options.requirements:
+-            for req in parse_requirements(
+-                filename,
+-                finder=finder,
+-                options=options,
+-                session=session):
+-                if req.editable:
+-                    logger.notify("ignoring %s" % req.url)
+-                    continue
+-                requirement_set.add_requirement(req)
+-
+-        #fail if no requirements
+-        if not requirement_set.has_requirements:
+-            opts = {'name': self.name}
+-            msg = ('You must give at least one requirement '
+-                   'to %(name)s (see "pip help %(name)s")' % opts)
+-            logger.error(msg)
+-            return
++        build_delete = (not (options.no_clean or options.build_dir))
++        with BuildDirectory(options.build_dir, delete=build_delete) as build_dir:
++            requirement_set = RequirementSet(
++                build_dir=build_dir,
++                src_dir=None,
++                download_dir=None,
++                download_cache=options.download_cache,
++                ignore_dependencies=options.ignore_dependencies,
++                ignore_installed=True,
++                session=session,
++                wheel_download_dir=options.wheel_dir
++            )
+ 
+-        try:
+-            #build wheels
+-            wb = WheelBuilder(
+-                requirement_set,
+-                finder,
+-                options.wheel_dir,
+-                build_options = options.build_options or [],
+-                global_options = options.global_options or []
+-                )
+-            wb.build()
+-        except PreviousBuildDirError:
+-            options.no_clean = True
+-            raise
+-        finally:
+-            if not options.no_clean:
+-                requirement_set.cleanup_files()
++            # make the wheelhouse
++            if not os.path.exists(options.wheel_dir):
++                os.makedirs(options.wheel_dir)
++
++            #parse args and/or requirements files
++            for name in args:
++                requirement_set.add_requirement(
++                    InstallRequirement.from_line(name, None))
++
++            for filename in options.requirements:
++                for req in parse_requirements(
++                    filename,
++                    finder=finder,
++                    options=options,
++                    session=session):
++                    if req.editable:
++                        logger.notify("ignoring %s" % req.url)
++                        continue
++                    requirement_set.add_requirement(req)
++
++            #fail if no requirements
++            if not requirement_set.has_requirements:
++                opts = {'name': self.name}
++                msg = ('You must give at least one requirement '
++                       'to %(name)s (see "pip help %(name)s")' % opts)
++                logger.error(msg)
++                return
++
++            try:
++                #build wheels
++                wb = WheelBuilder(
++                    requirement_set,
++                    finder,
++                    options.wheel_dir,
++                    build_options = options.build_options or [],
++                    global_options = options.global_options or []
++                    )
++                wb.build()
++            except PreviousBuildDirError:
++                options.no_clean = True
++                raise
++            finally:
++                if not options.no_clean:
++                    requirement_set.cleanup_files()
+--- python-pip-1.5.6.orig/pip/util.py
++++ python-pip-1.5.6/pip/util.py
+@@ -8,6 +8,7 @@ import zipfile
+ import tarfile
+ import subprocess
+ import textwrap
++import tempfile
+ 
+ from pip.exceptions import InstallationError, BadCommand, PipError
+ from pip.backwardcompat import(WindowsError, string_types, raw_input,
+@@ -718,3 +719,35 @@ def is_prerelease(vers):
+ 
+     parsed = version._normalized_key(normalized)
+     return any([any([y in set(["a", "b", "c", "rc", "dev"]) for y in x]) for x in parsed])
++
++
++class BuildDirectory(object):
++
++    def __init__(self, name=None, delete=None):
++        # If we were not given an explicit directory, and we were not given an
++        # explicit delete option, then we'll default to deleting.
++        if name is None and delete is None:
++            delete = True
++
++        if name is None:
++            name = tempfile.mkdtemp(prefix="pip-build-")
++            # If we were not given an explicit directory, and we were not given
++            # an explicit delete option, then we'll default to deleting.
++            if delete is None:
++                delete = True
++
++        self.name = name
++        self.delete = delete
++
++    def __repr__(self):
++        return "<{} {!r}>".format(self.__class__.__name__, self.name)
++
++    def __enter__(self):
++        return self.name
++
++    def __exit__(self, exc, value, tb):
++        self.cleanup()
++
++    def cleanup(self):
++        if self.delete:
++            rmtree(self.name)

Modified: packages/python-pip/trunk/debian/patches/series
===================================================================
--- packages/python-pip/trunk/debian/patches/series	2014-12-02 17:27:55 UTC (rev 31527)
+++ packages/python-pip/trunk/debian/patches/series	2014-12-03 19:51:38 UTC (rev 31528)
@@ -1,3 +1,4 @@
 de-vendorize.patch
 use-venv-wheels.patch
 better-error-message.patch
+random-install-dir.patch




More information about the Python-modules-commits mailing list