diff --git a/src/ICSharpCode.SharpZipLib/Tar/TarArchive.cs b/src/ICSharpCode.SharpZipLib/Tar/TarArchive.cs
index 878649017..852b241ea 100644
--- a/src/ICSharpCode.SharpZipLib/Tar/TarArchive.cs
+++ b/src/ICSharpCode.SharpZipLib/Tar/TarArchive.cs
@@ -855,14 +855,34 @@ private void WriteEntryCore(TarEntry sourceEntry, bool recurse)
string newName = null;
+ // need to have a test if the root path is set to a child directory of the working directory
+ var currentDirectory = Directory.GetCurrentDirectory()
+ .ToTarArchivePath();
+
if (!String.IsNullOrEmpty(rootPath))
{
+ // hack: fix this
+
if (entry.Name.StartsWith(rootPath, StringComparison.OrdinalIgnoreCase))
{
newName = entry.Name.Substring(rootPath.Length + 1);
}
+ // root path is set, is root path under the current directory?
+ else if (entry.Name.StartsWith(currentDirectory + "/" + RootPath, StringComparison.OrdinalIgnoreCase))
+ {
+ newName = entry.Name.Substring(rootPath.Length + 2 + currentDirectory.Length);
+ }
+ }
+ else
+ {
+
+ if (entry.Name.StartsWith(currentDirectory, StringComparison.OrdinalIgnoreCase))
+ {
+ newName = entry.Name.Substring(currentDirectory.Length);
+ }
}
+
if (pathPrefix != null)
{
newName = (newName == null) ? pathPrefix + "/" + entry.Name : pathPrefix + "/" + newName;
diff --git a/src/ICSharpCode.SharpZipLib/Tar/TarEntry.cs b/src/ICSharpCode.SharpZipLib/Tar/TarEntry.cs
index 82c813367..e59165afe 100644
--- a/src/ICSharpCode.SharpZipLib/Tar/TarEntry.cs
+++ b/src/ICSharpCode.SharpZipLib/Tar/TarEntry.cs
@@ -348,11 +348,17 @@ public void GetFileTarHeader(TarHeader header, string file)
// bugfix from torhovl from #D forum:
string name = file;
+ // not sure if I understand this comment, unsure if this needs to move
// 23-Jan-2004 GnuTar allows device names in path where the name is not local to the current directory
- if (name.IndexOf(Directory.GetCurrentDirectory(), StringComparison.Ordinal) == 0)
- {
- name = name.Substring(Directory.GetCurrentDirectory().Length);
- }
+
+ // the functional difference here is that TarEntry has changed
+ // is this something that we are concerned about?
+
+ // TODO: this has moved
+ //if (name.IndexOf(Directory.GetCurrentDirectory(), StringComparison.Ordinal) == 0)
+ //{
+ // name = name.Substring(Directory.GetCurrentDirectory().Length);
+ //}
/*
if (Path.DirectorySeparatorChar == '\\')
diff --git a/test/ICSharpCode.SharpZipLib.Tests/Tar/TarTests.cs b/test/ICSharpCode.SharpZipLib.Tests/Tar/TarTests.cs
index c6a35ff08..261aef1d7 100644
--- a/test/ICSharpCode.SharpZipLib.Tests/Tar/TarTests.cs
+++ b/test/ICSharpCode.SharpZipLib.Tests/Tar/TarTests.cs
@@ -8,6 +8,7 @@
using System.Threading;
using System.Threading.Tasks;
using NUnit.Framework.Internal;
+using System.Linq;
namespace ICSharpCode.SharpZipLib.Tests.Tar
{
@@ -916,5 +917,179 @@ public void RootPathIsRespected()
}
}
}
+
+ ///
+ /// This tests ensure that the property is respected, even if the
+ /// path is under the current working directory.
+ ///
+ [Test]
+ [Category("Tar")]
+ public void RootPathUnderWorkDirRespected()
+ {
+ // If a user specifies that the RootDir is a path under the working directory
+ // the RootDir properly must correctly trim away the root path
+ // this must not alter existing behavior
+ using (var workDir = new TempDir())
+ using (var tarFileName = new TempFile())
+ using (var extractDirectory = new TempDir())
+ {
+ // the files created must be under the current working dir
+ Environment.CurrentDirectory = workDir.FullName;
+
+ // create a temp dir and file under this path
+ var expectDir = Path.Combine(workDir.FullName, "temp"); // TODO: improve quality of this
+ Directory.CreateDirectory(expectDir);
+ var fileName = Path.Combine(expectDir, "testFile.txt");
+ File.WriteAllText(fileName, "test123");
+
+ // extract files under the given path
+ using (var tarFile = File.Open(tarFileName.FullName, FileMode.Create))
+ {
+ using (var tarOutputStream = TarArchive.CreateOutputTarArchive(tarFile))
+ {
+ tarOutputStream.RootPath = Path.Combine(Environment.CurrentDirectory, "temp");
+ var entry = TarEntry.CreateEntryFromFile(fileName);
+ tarOutputStream.WriteEntry(entry, true);
+ }
+ }
+
+ using (var file = File.OpenRead(tarFileName.FullName))
+ {
+ using (var archive = TarArchive.CreateInputTarArchive(file, Encoding.UTF8))
+ {
+ archive.ExtractContents(extractDirectory.FullName);
+ }
+ }
+
+ // the resulting files must be the same as the expectation dir, should no longer have the "temp" prefix
+ var expectationDirectory = new DirectoryInfo(expectDir);
+ var expectedFile = expectationDirectory.GetFiles("", SearchOption.AllDirectories)
+ .First();
+
+ // the archive should contain the entry "testFile.txt", not "temp/testFile.txt", because
+ // the root dir is configured to "{CurrentDirectory}/tmp/"
+ FileAssert.DoesNotExist(Path.Combine(extractDirectory.FullName, "temp", "testFile.txt"));
+ FileAssert.Exists(Path.Combine(extractDirectory.FullName, "testFile.txt"));
+
+ FileAssert.AreEqual(fileName, Path.Combine(extractDirectory.FullName, "testFile.txt"));
+ }
+ }
+
+ ///
+ /// This tests ensure that the property is respected, even if the
+ /// path is under the current working directory.
+ ///
+ [Test]
+ [Category("Tar")]
+ public void RootPathUnderWorkDirRespectedExistingBehavior()
+ {
+ // If a user specifies that the RootDir is a path under the working directory
+ // the RootDir properly must correctly trim away the root path
+ // this must not alter existing behavior
+ using (var workDir = new TempDir())
+ using (var tarFileName = new TempFile())
+ using (var extractDirectory = new TempDir())
+ {
+ // the files created must be under the current working dir
+ Environment.CurrentDirectory = workDir.FullName;
+
+ // create a temp dir and file under this path
+ var expectDir = Path.Combine(workDir.FullName, "temp"); // TODO: improve quality of this
+ Directory.CreateDirectory(expectDir);
+ var fileName = Path.Combine(expectDir, "testFile.txt");
+ File.WriteAllText(fileName, "test123");
+
+ // extract files under the given path
+ using (var tarFile = File.Open(tarFileName.FullName, FileMode.Create))
+ {
+ using (var tarOutputStream = TarArchive.CreateOutputTarArchive(tarFile))
+ {
+ // when root path is NOT included, maintain the existing behavior
+ // tarOutputStream.RootPath = Path.Combine(Environment.CurrentDirectory, "temp");
+ var entry = TarEntry.CreateEntryFromFile(fileName);
+ tarOutputStream.WriteEntry(entry, true);
+ }
+ }
+
+ using (var file = File.OpenRead(tarFileName.FullName))
+ {
+ using (var archive = TarArchive.CreateInputTarArchive(file, Encoding.UTF8))
+ {
+ archive.ExtractContents(extractDirectory.FullName);
+ }
+ }
+
+ // the resulting files must be the same as the expectation dir, should no longer have the "temp" prefix
+ var expectationDirectory = new DirectoryInfo(expectDir);
+ var expectedFile = expectationDirectory.GetFiles("", SearchOption.AllDirectories)
+ .First();
+
+ // the archive should contain the entry "testFile.txt", not "temp/testFile.txt", because
+ // the root dir is configured to "{CurrentDirectory}/tmp/"
+ FileAssert.Exists(Path.Combine(extractDirectory.FullName, "temp", "testFile.txt"));
+ FileAssert.DoesNotExist(Path.Combine(extractDirectory.FullName, "testFile.txt"));
+
+ FileAssert.AreEqual(fileName, Path.Combine(extractDirectory.FullName, "temp", "testFile.txt"));
+ }
+ }
+
+ ///
+ /// This tests ensure that the property is respected, even if the
+ /// path is under the current working directory.
+ ///
+ [Test]
+ [Category("Tar")]
+ public void RootPathUnderWorkDirRespectedExistingBehaviorRootPathIsRelative()
+ {
+ // If a user specifies that the RootDir is a path under the working directory
+ // the RootDir properly must correctly trim away the root path
+ // this must not alter existing behavior
+ using (var workDir = new TempDir())
+ using (var tarFileName = new TempFile())
+ using (var extractDirectory = new TempDir())
+ {
+ // the files created must be under the current working dir
+ Environment.CurrentDirectory = workDir.FullName;
+
+ // create a temp dir and file under this path
+ var expectDir = Path.Combine(workDir.FullName, "temp"); // TODO: improve quality of this
+ Directory.CreateDirectory(expectDir);
+ var fileName = Path.Combine(expectDir, "testFile.txt");
+ File.WriteAllText(fileName, "test123");
+
+ // extract files under the given path
+ using (var tarFile = File.Open(tarFileName.FullName, FileMode.Create))
+ {
+ using (var tarOutputStream = TarArchive.CreateOutputTarArchive(tarFile))
+ {
+ // when root path is NOT included, maintain the existing behavior
+ // tarOutputStream.RootPath = Path.Combine(Environment.CurrentDirectory, "temp");
+ tarOutputStream.RootPath = "temp";
+ var entry = TarEntry.CreateEntryFromFile(fileName);
+ tarOutputStream.WriteEntry(entry, true);
+ }
+ }
+
+ using (var file = File.OpenRead(tarFileName.FullName))
+ {
+ using (var archive = TarArchive.CreateInputTarArchive(file, Encoding.UTF8))
+ {
+ archive.ExtractContents(extractDirectory.FullName);
+ }
+ }
+
+ // the resulting files must be the same as the expectation dir, should no longer have the "temp" prefix
+ var expectationDirectory = new DirectoryInfo(expectDir);
+ var expectedFile = expectationDirectory.GetFiles("", SearchOption.AllDirectories)
+ .First();
+
+ // the archive should contain the entry "testFile.txt", not "temp/testFile.txt", because
+ // the root dir is configured to "{CurrentDirectory}/tmp/"
+ FileAssert.DoesNotExist(Path.Combine(extractDirectory.FullName, "temp", "testFile.txt"));
+ FileAssert.Exists(Path.Combine(extractDirectory.FullName, "testFile.txt"));
+
+ FileAssert.AreEqual(fileName, Path.Combine(extractDirectory.FullName, "temp", "testFile.txt"));
+ }
+ }
}
}