From 6d25e9b92048dbb864aaba42ab839479ccd1cddd Mon Sep 17 00:00:00 2001 From: Thomas Leonard Date: Fri, 11 Jun 2010 13:36:26 +0100 Subject: [PATCH] Fixed handling of 'extract' attribute in unpack_archive_over MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Reported by Anders F Björklund. Also, stopped the unittests from running the tests in the abstract base class. --- tests/testunpack.py | 10 +++++++--- zeroinstall/zerostore/unpack.py | 18 +++++++++++++----- 2 files changed, 20 insertions(+), 8 deletions(-) diff --git a/tests/testunpack.py b/tests/testunpack.py index 2a57382..f774815 100755 --- a/tests/testunpack.py +++ b/tests/testunpack.py @@ -18,7 +18,7 @@ def skipIf(condition, reason): return underlying return wrapped -class AbstractTestUnpack(BaseTest): +class AbstractTestUnpack(): def setUp(self): BaseTest.setUp(self) @@ -57,6 +57,10 @@ class AbstractTestUnpack(BaseTest): unpack.unpack_archive('ftp://foo/file.tgz', file('HelloWorld.tgz'), self.tmpdir, extract = 'HelloWorld') self.assert_manifest('sha1=3ce644dc725f1d21cfcf02562c76f375944b266a') + def testExtractOver(self): + unpack.unpack_archive_over('ftp://foo/file.tgz', file('HelloWorld.tgz'), self.tmpdir, extract = 'HelloWorld') + self.assert_manifest('sha1=491678c37f77fadafbaae66b13d48d237773a68f') + def testExtractZip(self): unpack.unpack_archive('ftp://foo/file.zip', file('HelloWorld.zip'), self.tmpdir, extract = 'HelloWorld') self.assert_manifest('sha1=3ce644dc725f1d21cfcf02562c76f375944b266a') @@ -139,13 +143,13 @@ class AbstractTestUnpack(BaseTest): full_mode = os.stat(full).st_mode self.assertEquals(0444, full_mode & 0666) # Must be r-?r-?r-? -class TestUnpackPython(AbstractTestUnpack): +class TestUnpackPython(BaseTest, AbstractTestUnpack): def setUp(self): AbstractTestUnpack.setUp(self) unpack._tar_version = 'Solaris tar' assert not unpack._gnu_tar() -class TestUnpackGNU(AbstractTestUnpack): +class TestUnpackGNU(BaseTest, AbstractTestUnpack): def setUp(self): AbstractTestUnpack.setUp(self) unpack._tar_version = None diff --git a/zeroinstall/zerostore/unpack.py b/zeroinstall/zerostore/unpack.py index d6d5593..7467220 100644 --- a/zeroinstall/zerostore/unpack.py +++ b/zeroinstall/zerostore/unpack.py @@ -138,16 +138,24 @@ def unpack_archive_over(url, data, destdir, extract = None, type = None, start_o then move things over, checking that we're not following symlinks at each stage. Use this when you want to unpack an unarchive into a directory which already has stuff in it. + @note: Since 0.49, the leading "extract" component is removed (unlike unpack_archive). @since: 0.28""" import stat tmpdir = mkdtemp(dir = destdir) + assert extract is None or os.sep not in extract, extract try: mtimes = [] unpack_archive(url, data, tmpdir, extract, type, start_offset) - stem_len = len(tmpdir) - for root, dirs, files in os.walk(tmpdir): + if extract is None: + srcdir = tmpdir + else: + srcdir = os.path.join(tmpdir, extract) + assert not os.path.islink(srcdir) + + stem_len = len(srcdir) + for root, dirs, files in os.walk(srcdir): relative_root = root[stem_len + 1:] or '.' target_root = os.path.join(destdir, relative_root) try: @@ -162,15 +170,15 @@ def unpack_archive_over(url, data, destdir, extract = None, type = None, start_o raise SafeException(_('Attempt to unpack dir over symlink "%s"!') % relative_root) elif not stat.S_ISDIR(info.st_mode): raise SafeException(_('Attempt to unpack dir over non-directory "%s"!') % relative_root) - mtimes.append((relative_root, os.lstat(os.path.join(tmpdir, root)).st_mtime)) + mtimes.append((relative_root, os.lstat(os.path.join(srcdir, root)).st_mtime)) for s in dirs: # Symlinks are counted as directories - src = os.path.join(tmpdir, relative_root, s) + src = os.path.join(srcdir, relative_root, s) if os.path.islink(src): files.append(s) for f in files: - src = os.path.join(tmpdir, relative_root, f) + src = os.path.join(srcdir, relative_root, f) dest = os.path.join(destdir, relative_root, f) if os.path.islink(dest): raise SafeException(_('Attempt to unpack file over symlink "%s"!') % -- 2.11.4.GIT