Skip to content

Commit 75d1cf8

Browse files
authored
fix(tar): clear rest of buffer when eof is reached (#789)
1 parent 6c96ce2 commit 75d1cf8

File tree

3 files changed

+42
-4
lines changed

3 files changed

+42
-4
lines changed

src/ICSharpCode.SharpZipLib/Tar/TarBuffer.cs

+5
Original file line numberDiff line numberDiff line change
@@ -402,6 +402,11 @@ private async ValueTask<bool> ReadRecordAsync(CancellationToken ct, bool isAsync
402402
//
403403
if (numBytes <= 0)
404404
{
405+
// Fill the rest of the buffer with 0 to clear any left over data in the shared buffer
406+
for (; offset < RecordSize; offset++)
407+
{
408+
recordBuffer[offset] = 0;
409+
}
405410
break;
406411
}
407412

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

+24
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
using System;
2+
using System.Buffers;
23
using System.IO;
34
using System.Text;
45
using System.Threading;
56
using System.Threading.Tasks;
67
using ICSharpCode.SharpZipLib.Tar;
8+
using ICSharpCode.SharpZipLib.Tests.TestSupport;
79
using NUnit.Framework;
810

911
namespace ICSharpCode.SharpZipLib.Tests.Tar
@@ -87,5 +89,27 @@ public async Task TestReadAsync()
8789
Assert.AreEqual(975, read3);
8890
Assert.AreEqual(entryBytes.AsSpan(1025, 975).ToArray(), buffer.AsSpan().Slice(0, 975).ToArray());
8991
}
92+
93+
[Test]
94+
public void ReadEmptyStreamWhenArrayPoolIsDirty()
95+
{
96+
// Rent an array with the same size as the tar buffer from the array pool
97+
var buffer = ArrayPool<byte>.Shared.Rent(TarBuffer.DefaultRecordSize);
98+
99+
// Fill the array with anything but 0
100+
Utils.FillArray(buffer, 0x8b);
101+
102+
// Return the now dirty buffer to the array pool
103+
ArrayPool<byte>.Shared.Return(buffer);
104+
105+
Assert.DoesNotThrow(() =>
106+
{
107+
using var emptyStream = new MemoryStream(Array.Empty<byte>());
108+
using var tarInputStream = new TarInputStream(emptyStream, Encoding.UTF8);
109+
while (tarInputStream.GetNextEntry() is { } tarEntry)
110+
{
111+
}
112+
}, "reading from an empty input stream should not cause an error");
113+
}
90114
}
91115
}

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

+13-4
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,15 @@ public static void PatchFirstEntrySize(Stream stream, int newSize)
133133
stream.Write(sizeBytes, 0, 4);
134134
}
135135
}
136+
137+
public static void FillArray(byte[] buffer, byte value)
138+
{
139+
#if NET6_0_OR_GREATER
140+
Array.Fill(buffer, value);
141+
#else
142+
for(var i = 0; i < buffer.Length; i++) buffer[i] = value;
143+
#endif
144+
}
136145
}
137146

138147
public class TestTraceListener : TraceListener
@@ -185,7 +194,7 @@ internal TempFile(string dirPath = null, string filename = null)
185194
_fileInfo = new FileInfo(Path.Combine(dirPath, filename));
186195
}
187196

188-
#region IDisposable Support
197+
#region IDisposable Support
189198

190199
private bool _disposed; // To detect redundant calls
191200

@@ -213,7 +222,7 @@ public void Dispose()
213222
GC.SuppressFinalize(this);
214223
}
215224

216-
#endregion IDisposable Support
225+
#endregion IDisposable Support
217226
}
218227

219228

@@ -245,7 +254,7 @@ public TempFile CreateDummyFile(string name, int size = 16, int seed = Utils.Def
245254

246255
public TempFile GetFile(string fileName) => new TempFile(FullPath, fileName);
247256

248-
#region IDisposable Support
257+
#region IDisposable Support
249258

250259
private bool _disposed; // To detect redundant calls
251260

@@ -272,6 +281,6 @@ public void Dispose()
272281
GC.SuppressFinalize(this);
273282
}
274283

275-
#endregion IDisposable Support
284+
#endregion IDisposable Support
276285
}
277286
}

0 commit comments

Comments
 (0)