Skip to content

Commit 96df4ca

Browse files
authored
Merge PR #245, Attempt to read two end blocks when reading tararchive
* Attempt to read another block if EOA block found * Add test for #213 * Add disposable IO utils * Fixes #213
1 parent 6327312 commit 96df4ca

File tree

3 files changed

+149
-3
lines changed

3 files changed

+149
-3
lines changed

src/ICSharpCode.SharpZipLib/Tar/TarInputStream.cs

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -390,10 +390,21 @@ public TarEntry GetNextEntry()
390390

391391
byte[] headerBuf = tarBuffer.ReadBlock();
392392

393-
if (headerBuf == null) {
393+
if (headerBuf == null)
394+
{
395+
hasHitEOF = true;
396+
}
397+
else if (TarBuffer.IsEndOfArchiveBlock(headerBuf))
398+
{
394399
hasHitEOF = true;
395-
} else
396-
hasHitEOF |= TarBuffer.IsEndOfArchiveBlock(headerBuf);
400+
401+
// Read the second zero-filled block
402+
tarBuffer.ReadBlock();
403+
}
404+
else
405+
{
406+
hasHitEOF = false;
407+
}
397408

398409
if (hasHitEOF) {
399410
currentEntry = null;

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

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -665,6 +665,47 @@ public void InputStreamOwnership()
665665
Assert.IsFalse(memStream.IsDisposed, "Should not be disposed after parent owner close");
666666
}
667667

668+
[Test]
669+
[Category("Tar")]
670+
public void EndBlockHandling()
671+
{
672+
int dummySize = 70145;
673+
674+
long outCount, inCount;
675+
676+
using (var ms = new MemoryStream())
677+
{
678+
using (var tarOut = TarArchive.CreateOutputTarArchive(ms))
679+
using (var dummyFile = Utils.GetDummyFile(dummySize))
680+
{
681+
tarOut.IsStreamOwner = false;
682+
tarOut.WriteEntry(TarEntry.CreateEntryFromFile(dummyFile.Filename), false);
683+
}
684+
685+
outCount = ms.Position;
686+
ms.Seek(0, SeekOrigin.Begin);
687+
688+
using (var tarIn = TarArchive.CreateInputTarArchive(ms))
689+
using (var tempDir = new Utils.TempDir())
690+
{
691+
tarIn.IsStreamOwner = false;
692+
tarIn.ExtractContents(tempDir.Fullpath);
693+
694+
foreach (var file in Directory.GetFiles(tempDir.Fullpath, "*", SearchOption.AllDirectories))
695+
{
696+
Console.WriteLine($"Extracted \"{file}\"");
697+
}
698+
}
699+
700+
inCount = ms.Position;
701+
702+
Console.WriteLine($"Output count: {outCount}");
703+
Console.WriteLine($"Input count: {inCount}");
704+
705+
Assert.AreEqual(inCount, outCount, "Bytes read and bytes written should be equal");
706+
}
707+
}
708+
668709
[Test]
669710
[Category("Tar")]
670711
[Category("Performance")]

test/ICSharpCode.SharpZipLib.Tests/TestSupport/Utils.cs

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using System;
2+
using System.IO;
23
using NUnit.Framework;
34

45
namespace ICSharpCode.SharpZipLib.Tests.TestSupport
@@ -8,6 +9,7 @@ namespace ICSharpCode.SharpZipLib.Tests.TestSupport
89
/// </summary>
910
public static class Utils
1011
{
12+
static Random random = new Random();
1113

1214
static void Compare(byte[] a, byte[] b)
1315
{
@@ -25,5 +27,97 @@ static void Compare(byte[] a, byte[] b)
2527
}
2628
}
2729

30+
public static TempFile GetDummyFile(int size = -1)
31+
{
32+
var tempFile = new TempFile();
33+
if (size < 0)
34+
{
35+
File.WriteAllText(tempFile.Filename, DateTime.UtcNow.Ticks.ToString("x16"));
36+
}
37+
else if (size > 0)
38+
{
39+
var bytes = Array.CreateInstance(typeof(byte), size) as byte[];
40+
random.NextBytes(bytes);
41+
File.WriteAllBytes(tempFile.Filename, bytes);
42+
}
43+
return tempFile;
44+
}
45+
46+
public class TempFile : IDisposable
47+
{
48+
public string Filename { get; internal set; }
49+
50+
public TempFile()
51+
{
52+
Filename = Path.GetTempFileName();
53+
}
54+
55+
#region IDisposable Support
56+
private bool disposed = false; // To detect redundant calls
57+
58+
59+
protected virtual void Dispose(bool disposing)
60+
{
61+
if (!disposed)
62+
{
63+
if (disposing && File.Exists(Filename))
64+
{
65+
try
66+
{
67+
File.Delete(Filename);
68+
}
69+
catch { }
70+
}
71+
72+
disposed = true;
73+
}
74+
}
75+
76+
public void Dispose()
77+
=> Dispose(true);
78+
79+
#endregion
80+
81+
}
82+
83+
public class TempDir : IDisposable
84+
{
85+
public string Fullpath { get; internal set; }
86+
87+
public TempDir()
88+
{
89+
Fullpath = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());
90+
Directory.CreateDirectory(Fullpath);
91+
}
92+
93+
#region IDisposable Support
94+
private bool disposed = false; // To detect redundant calls
95+
96+
97+
protected virtual void Dispose(bool disposing)
98+
{
99+
if (!disposed)
100+
{
101+
if (disposing && Directory.Exists(Fullpath))
102+
{
103+
try
104+
{
105+
Directory.Delete(Fullpath, true);
106+
}
107+
catch { }
108+
}
109+
110+
disposed = true;
111+
}
112+
}
113+
114+
public void Dispose()
115+
=> Dispose(true);
116+
117+
#endregion
118+
119+
}
28120
}
121+
122+
29123
}

0 commit comments

Comments
 (0)