Skip to content

Commit cf007d5

Browse files
author
Simon Ensslen
committed
- Use string extension method for path cleanup to make it equal wihtout code duplication
- Add unit test that tests the compression and extraction
1 parent bb5c546 commit cf007d5

File tree

4 files changed

+90
-18
lines changed

4 files changed

+90
-18
lines changed

src/ICSharpCode.SharpZipLib/Tar/TarArchive.cs

+1-7
Original file line numberDiff line numberDiff line change
@@ -356,13 +356,7 @@ public string RootPath
356356
{
357357
throw new ObjectDisposedException("TarArchive");
358358
}
359-
// Convert to forward slashes for matching. Trim trailing / for correct final path
360-
rootPath = value.Replace('\\', '/').TrimEnd('/');
361-
// Fix rooted paths on linux
362-
while (rootPath.StartsWith("/", StringComparison.Ordinal))
363-
{
364-
rootPath = rootPath.Substring(1);
365-
}
359+
rootPath = value.ClearTarPath().TrimEnd('/');
366360
}
367361
}
368362

src/ICSharpCode.SharpZipLib/Tar/TarEntry.cs

+1-6
Original file line numberDiff line numberDiff line change
@@ -418,15 +418,10 @@ public void GetFileTarHeader(TarHeader header, string file)
418418
}
419419
*/
420420

421-
name = name.Replace(Path.DirectorySeparatorChar, '/');
422-
423421
// No absolute pathnames
424422
// Windows (and Posix?) paths can start with UNC style "\\NetworkDrive\",
425423
// so we loop on starting /'s.
426-
while (name.StartsWith("/", StringComparison.Ordinal))
427-
{
428-
name = name.Substring(1);
429-
}
424+
name = name.ClearTarPath();
430425

431426
header.LinkName = String.Empty;
432427
header.Name = name;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
using System.IO;
2+
3+
namespace ICSharpCode.SharpZipLib.Tar
4+
{
5+
internal static class TarStringExtension
6+
{
7+
public static string ClearTarPath(this string s)
8+
{
9+
if (Path.GetPathRoot(s) != null)
10+
{
11+
s = s.Substring(Path.GetPathRoot(s).Length);
12+
}
13+
return s.Replace(Path.DirectorySeparatorChar, '/');
14+
}
15+
}
16+
}

test/ICSharpCode.SharpZipLib.Tests/Tar/TarTests.cs

+72-5
Original file line numberDiff line numberDiff line change
@@ -859,7 +859,7 @@ public void ParseHeaderWithEncoding(int length, string encodingName)
859859
reparseHeader.ParseBuffer(headerbytes, enc);
860860
Assert.AreEqual(name, reparseHeader.Name);
861861
// top 100 bytes are name field in tar header
862-
for (int i = 0;i < encodedName.Length;i++)
862+
for (int i = 0; i < encodedName.Length; i++)
863863
{
864864
Assert.AreEqual(encodedName[i], headerbytes[i]);
865865
}
@@ -878,17 +878,17 @@ public void StreamWithJapaneseName(int length, string encodingName)
878878
var entryName = new string((char)0x3042, length);
879879
var data = new byte[32];
880880
var encoding = Encoding.GetEncoding(encodingName);
881-
using(var memoryStream = new MemoryStream())
881+
using (var memoryStream = new MemoryStream())
882882
{
883-
using(var tarOutput = new TarOutputStream(memoryStream, encoding))
883+
using (var tarOutput = new TarOutputStream(memoryStream, encoding))
884884
{
885885
var entry = TarEntry.CreateTarEntry(entryName);
886886
entry.Size = 32;
887887
tarOutput.PutNextEntry(entry);
888888
tarOutput.Write(data, 0, data.Length);
889889
}
890-
using(var memInput = new MemoryStream(memoryStream.ToArray()))
891-
using(var inputStream = new TarInputStream(memInput, encoding))
890+
using (var memInput = new MemoryStream(memoryStream.ToArray()))
891+
using (var inputStream = new TarInputStream(memInput, encoding))
892892
{
893893
var buf = new byte[64];
894894
var entry = inputStream.GetNextEntry();
@@ -899,5 +899,72 @@ public void StreamWithJapaneseName(int length, string encodingName)
899899
File.WriteAllBytes(Path.Combine(Path.GetTempPath(), $"jpnametest_{length}_{encodingName}.tar"), memoryStream.ToArray());
900900
}
901901
}
902+
[Test]
903+
[Category("Tar")]
904+
public void rootPathIsRespected()
905+
{
906+
// create dummy folder structure
907+
var tempDirectory = Path.Combine(Path.GetTempPath(), "sharpziplib_tar_test_folder");
908+
CreateAndClearDirectory(tempDirectory);
909+
using (var dummyfile = File.Create("dummyfile"))
910+
{
911+
using (var randomStream = new ChaosStream())
912+
{
913+
randomStream.CopyTo(dummyfile);
914+
}
915+
}
916+
917+
var tarFileName = Path.Combine(Path.GetTempPath(), "sharpziplib_tar_test_folder_archive.tar");
918+
919+
using (var tarFile = File.Open(tarFileName, FileMode.Create))
920+
{
921+
using (var tarOutputStream = TarArchive.CreateOutputTarArchive(tarFile))
922+
{
923+
tarOutputStream.RootPath = tempDirectory;
924+
var entry = TarEntry.CreateEntryFromFile(tempDirectory);
925+
tarOutputStream.WriteEntry(entry, true);
926+
}
927+
}
928+
929+
var extractDirectory = Path.Combine(Path.GetTempPath(), "sharpziplib_tar_extract_folder");
930+
CreateAndClearDirectory(extractDirectory);
931+
using (var file = File.OpenRead(tarFileName))
932+
{
933+
using (var archive = TarArchive.CreateInputTarArchive(file, Encoding.UTF8))
934+
{
935+
archive.ExtractContents(extractDirectory);
936+
}
937+
}
938+
939+
var expectationDirectory = new DirectoryInfo(tempDirectory);
940+
foreach (var checkFile in expectationDirectory.GetFiles("", SearchOption.AllDirectories))
941+
{
942+
var relativePath = expectationDirectory.FullName.Substring(expectationDirectory.FullName.Length);
943+
FileAssert.Exists(Path.Combine(extractDirectory, relativePath));
944+
FileAssert.AreEqual(checkFile.FullName, Path.Combine(extractDirectory, relativePath));
945+
}
946+
}
947+
948+
private void CreateAndClearDirectory(string path)
949+
{
950+
if (Directory.Exists(path))
951+
{
952+
Directory.Delete(path);
953+
}
954+
Directory.CreateDirectory(path);
955+
}
956+
957+
public class ChaosStream : MemoryStream
958+
{
959+
private readonly int length = new Random().Next() % 5000 + 200;
960+
961+
// Create constructors as needed to match desired MemoryStream construction
962+
963+
public override int Read(byte[] buffer, int offset, int count)
964+
{
965+
int readCount = Math.Max(0, Math.Min(length - offset, count));
966+
return base.Read(buffer, offset, readCount);
967+
}
968+
}
902969
}
903970
}

0 commit comments

Comments
 (0)