Merge pull request #1338 from adamhathcock/copilot/fix-writable-archive-disposeasync

Close writable entry streams during async archive disposal
This commit is contained in:
Adam Hathcock
2026-05-29 09:05:39 +01:00
committed by GitHub
4 changed files with 71 additions and 0 deletions

View File

@@ -122,6 +122,14 @@ public abstract partial class AbstractWritableArchive<TEntry, TVolume, TOptions>
.ConfigureAwait(false);
}
public override async ValueTask DisposeAsync()
{
await base.DisposeAsync().ConfigureAwait(false);
newEntries.Cast<Entry>().ForEach(x => x.Close());
removedEntries.Cast<Entry>().ForEach(x => x.Close());
modifiedEntries.Cast<Entry>().ForEach(x => x.Close());
}
protected abstract ValueTask SaveToAsync(
Stream stream,
TOptions options,

View File

@@ -221,4 +221,23 @@ public class GZipArchiveAsyncTests : ArchiveTests
Path.Combine(scratchPath2, "Tar.tar")
);
}
[Fact]
public async ValueTask GZip_Async_Dispose_Closes_New_Entry_Stream()
{
var entryStream = new TestStream(new MemoryStream(new byte[] { 1, 2, 3 }));
await using (var archive = await GZipArchive.CreateAsyncArchive())
{
await archive.AddEntryAsync(
"test.bin",
entryStream,
closeStream: true,
size: entryStream.Length
);
await archive.SaveToAsync(new MemoryStream(), new GZipWriterOptions());
}
Assert.True(entryStream.IsDisposed);
}
}

View File

@@ -179,6 +179,28 @@ public class TarArchiveAsyncTests : ArchiveTests
CompareArchivesByPath(unmodified, scratchPath);
}
[Fact]
public async ValueTask Tar_Async_Dispose_Closes_New_Entry_Stream()
{
var entryStream = new TestStream(new MemoryStream(Encoding.UTF8.GetBytes("test")));
await using (var archive = await TarArchive.CreateAsyncArchive())
{
await archive.AddEntryAsync(
"test.txt",
entryStream,
closeStream: true,
size: entryStream.Length
);
await archive.SaveToAsync(
new MemoryStream(),
new TarWriterOptions(CompressionType.None, true)
);
}
Assert.True(entryStream.IsDisposed);
}
[Fact]
public async ValueTask Tar_Random_Write_Add_Async()
{

View File

@@ -186,6 +186,28 @@ public class ZipArchiveAsyncTests : ArchiveTests
CompareArchivesByPath(unmodified, scratchPath);
}
[Fact]
public async ValueTask Zip_Async_Dispose_Closes_New_Entry_Stream()
{
var entryStream = new TestStream(new MemoryStream(Encoding.UTF8.GetBytes("test")));
await using (var archive = await ZipArchive.CreateAsyncArchive())
{
await archive.AddEntryAsync(
"test.txt",
entryStream,
closeStream: true,
size: entryStream.Length
);
await archive.SaveToAsync(
new MemoryStream(),
new ZipWriterOptions(CompressionType.Deflate)
);
}
Assert.True(entryStream.IsDisposed);
}
[Fact]
public async ValueTask Zip_Deflate_Entry_Stream_Async()
{