[Pkg-bazaar-commits] ./bzr-builddeb/trunk r202: * Normalise filenames from the tarballs when extracting to import a

James Westby jw+debian at jameswestby.net
Thu May 15 13:29:36 UTC 2008


------------------------------------------------------------
revno: 202
committer: James Westby <jw+debian at jameswestby.net>
branch nick: trunk
timestamp: Fri 2008-01-25 12:22:42 +0000
message:
  * Normalise filenames from the tarballs when extracting to import a
    dsc to avoid errors on strange tarballs.
modified:
  debian/changelog
  import_dsc.py
  tests/test_import_dsc.py
-------------- next part --------------
=== modified file 'debian/changelog'
--- a/debian/changelog	2008-01-25 11:17:14 +0000
+++ b/debian/changelog	2008-01-25 12:22:42 +0000
@@ -15,8 +15,8 @@
   * Fix the import diff code to not deadlock on large diffs. Thanks to
     Jamie Wilkinson. (Closes: #451248)
   * Exclude more files/directories than just .bzr when importing.
-  * Be more careful in excluding the root entry when extracting a tarball
-    from import of a package.
+  * Normalise filenames from the tarballs when extracting to import a
+    dsc to avoid errors on strange tarballs.
 
  -- James Westby <jw+debian at jameswestby.net>  Fri, 25 Jan 2008 11:16:09 +0000
 

=== modified file 'import_dsc.py'
--- a/import_dsc.py	2008-01-25 11:17:14 +0000
+++ b/import_dsc.py	2008-01-25 12:22:42 +0000
@@ -36,6 +36,7 @@
 
 from bzrlib import (bzrdir,
                     generate_ids,
+                    osutils,
                     urlutils,
                     )
 from bzrlib.config import ConfigObj
@@ -113,7 +114,7 @@
             # type 'g' is a header
             continue
         relative_path = member.name
-        relative_path = relative_path.rstrip('/')
+        relative_path = osutils.normpath(relative_path)
         if prefix is not None:
             relative_path = relative_path[len(prefix)+1:]
         if relative_path == '' or relative_path == '.':

=== modified file 'tests/test_import_dsc.py'
--- a/tests/test_import_dsc.py	2008-01-25 11:17:14 +0000
+++ b/tests/test_import_dsc.py	2008-01-25 12:22:42 +0000
@@ -1068,5 +1068,92 @@
     DscImporter([self.native_dsc_1]).import_dsc(self.target)
     self.failUnlessExists(self.target)
 
+  def test_import_extra_slash(self):
+    tar = tarfile.open(self.native_1, 'w:gz')
+    try:
+      tar.addfile(_TarInfo('root//'))
+      tar.addfile(_TarInfo('root//README'))
+      tar.addfile(_TarInfo('root//NEWS'))
+    finally:
+      tar.close()
+    self.make_dsc(self.native_dsc_1, '0.1', self.native_1)
+    DscImporter([self.native_dsc_1]).import_dsc(self.target)
+    self.failUnlessExists(self.target)
+
+class _TarInfo(tarfile.TarInfo):
+    """Subclass TarInfo to stop it normalising its path. Sorry Mum."""
+
+    def tobuf(self, posix=False):
+        """Return a tar header as a string of 512 byte blocks.
+        """
+        buf = ""
+        type = self.type
+        prefix = ""
+
+        if self.name.endswith("/"):
+            type = tarfile.DIRTYPE
+
+        name = self.name
+
+        if type == tarfile.DIRTYPE:
+            # directories should end with '/'
+            name += "/"
+
+        linkname = self.linkname
+        if linkname:
+            # if linkname is empty we end up with a '.'
+            linkname = normpath(linkname)
+
+        if posix:
+            if self.size > tarfile.MAXSIZE_MEMBER:
+                raise ValueError("file is too large (>= 8 GB)")
+
+            if len(self.linkname) > tarfile.LENGTH_LINK:
+                raise ValueError("linkname is too long (>%d)" % (LENGTH_LINK))
+
+            if len(name) > tarfile.LENGTH_NAME:
+                prefix = name[:tarfile.LENGTH_PREFIX + 1]
+                while prefix and prefix[-1] != "/":
+                    prefix = prefix[:-1]
+
+                name = name[len(prefix):]
+                prefix = prefix[:-1]
+
+                if not prefix or len(name) > tarfile.LENGTH_NAME:
+                    raise ValueError("name is too long")
+
+        else:
+            if len(self.linkname) > tarfile.LENGTH_LINK:
+                buf += self._create_gnulong(self.linkname,
+                                            tarfile.GNUTYPE_LONGLINK)
+
+            if len(name) > tarfile.LENGTH_NAME:
+                buf += self._create_gnulong(name, tarfile.GNUTYPE_LONGNAME)
+
+        parts = [
+            tarfile.stn(name, 100),
+            tarfile.itn(self.mode & 07777, 8, posix),
+            tarfile.itn(self.uid, 8, posix),
+            tarfile.itn(self.gid, 8, posix),
+            tarfile.itn(self.size, 12, posix),
+            tarfile.itn(self.mtime, 12, posix),
+            "        ", # checksum field
+            type,
+            tarfile.stn(self.linkname, 100),
+            tarfile.stn(tarfile.MAGIC, 6),
+            tarfile.stn(tarfile.VERSION, 2),
+            tarfile.stn(self.uname, 32),
+            tarfile.stn(self.gname, 32),
+            tarfile.itn(self.devmajor, 8, posix),
+            tarfile.itn(self.devminor, 8, posix),
+            tarfile.stn(prefix, 155)
+        ]
+
+        buf += "".join(parts).ljust(tarfile.BLOCKSIZE, tarfile.NUL)
+        chksum = tarfile.calc_chksums(buf[-tarfile.BLOCKSIZE:])[0]
+        buf = buf[:-364] + "%06o\0" % chksum + buf[-357:]
+        self.buf = buf
+        return buf
+
 # vim: sw=2 sts=2 ts=2 
 



More information about the Pkg-bazaar-commits mailing list