Commits

Jason R. Coombs committed 9b938b4

Use zip files rather than tar files for source distributions of setuptools itself. Fixes #7 for users of Python 2.7.4 and later.

  • Participants
  • Parent commits 1fbec46

Comments (0)

Files changed (3)

   handled properly at runtime.  In 2.x it was possible to get away without
   including the declaration, but only at the cost of forcing namespace
   packages to be imported early, which 3.0 no longer does.
+* Issue #7: Setuptools itself is now distributed as a zipfile instead of a
+  tarball. This approach avoids the potential security vulnerabilities
+  presented by use of tar files. It also leverages the security features added
+  to ZipFile.extract in Python 2.7.4.
 
 ---
 2.3
 import shutil
 import sys
 import tempfile
-import tarfile
+import zipfile
 import optparse
 import subprocess
 import platform
     args = (sys.executable,) + args
     return subprocess.call(args) == 0
 
-def _install(tarball, install_args=()):
-    # extracting the tarball
+def _install(archive_filename, install_args=()):
+    # extracting the archive
     tmpdir = tempfile.mkdtemp()
     log.warn('Extracting in %s', tmpdir)
     old_wd = os.getcwd()
     try:
         os.chdir(tmpdir)
-        tar = tarfile.open(tarball)
-        tar.extractall()
-        tar.close()
+        with zipfile.ZipFile(archive_filename) as archive:
+            archive.extractall()
 
         # going in the directory
         subdir = os.path.join(tmpdir, os.listdir(tmpdir)[0])
         shutil.rmtree(tmpdir)
 
 
-def _build_egg(egg, tarball, to_dir):
-    # extracting the tarball
+def _build_egg(egg, archive_filename, to_dir):
+    # extracting the archive
     tmpdir = tempfile.mkdtemp()
     log.warn('Extracting in %s', tmpdir)
     old_wd = os.getcwd()
     try:
         os.chdir(tmpdir)
-        tar = tarfile.open(tarball)
-        tar.extractall()
-        tar.close()
+        with zipfile.ZipFile(archive_filename) as archive:
+            archive.extractall()
 
         # going in the directory
         subdir = os.path.join(tmpdir, os.listdir(tmpdir)[0])
     egg = os.path.join(to_dir, 'setuptools-%s-py%d.%d.egg'
                        % (version, sys.version_info[0], sys.version_info[1]))
     if not os.path.exists(egg):
-        tarball = download_setuptools(version, download_base,
+        archive = download_setuptools(version, download_base,
                                       to_dir, download_delay)
-        _build_egg(egg, tarball, to_dir)
+        _build_egg(egg, archive, to_dir)
     sys.path.insert(0, egg)
 
     # Remove previously-imported pkg_resources if present (see
     """
     # making sure we use the absolute path
     to_dir = os.path.abspath(to_dir)
-    tgz_name = "setuptools-%s.tar.gz" % version
-    url = download_base + tgz_name
-    saveto = os.path.join(to_dir, tgz_name)
+    zip_name = "setuptools-%s.zip" % version
+    url = download_base + zip_name
+    saveto = os.path.join(to_dir, zip_name)
     if not os.path.exists(saveto):  # Avoid repeated downloads
         log.warn("Downloading %s", url)
         downloader = downloader_factory()
 def main(version=DEFAULT_VERSION):
     """Install or upgrade setuptools and EasyInstall"""
     options = _parse_args()
-    tarball = download_setuptools(download_base=options.download_base,
+    archive = download_setuptools(download_base=options.download_base,
         downloader_factory=options.downloader_factory)
-    return _install(tarball, _build_install_args(options))
+    return _install(archive, _build_install_args(options))
 
 if __name__ == '__main__':
     sys.exit(main())
 upload-dir = docs/build/html
 
 [sdist]
-formats=gztar
+formats=zip
 
 [wheel]
 universal=1