diff --git a/src/ICSharpCode.SharpZipLib/Zip/ZipOutputStream.cs b/src/ICSharpCode.SharpZipLib/Zip/ZipOutputStream.cs index 36349c886..3f77fbe80 100644 --- a/src/ICSharpCode.SharpZipLib/Zip/ZipOutputStream.cs +++ b/src/ICSharpCode.SharpZipLib/Zip/ZipOutputStream.cs @@ -521,9 +521,10 @@ internal void PutNextEntry(Stream stream, ZipEntry entry, long streamOffset = 0, public async Task PutNextEntryAsync(ZipEntry entry, CancellationToken ct = default) { if (curEntry != null) await CloseEntryAsync(ct); + var position = CanPatchEntries ? baseOutputStream_.Position : -1; await baseOutputStream_.WriteProcToStreamAsync(s => { - PutNextEntry(s, entry, baseOutputStream_.Position); + PutNextEntry(s, entry, position); }, ct); if (!entry.IsCrypted) return; diff --git a/test/ICSharpCode.SharpZipLib.Tests/TestSupport/Streams.cs b/test/ICSharpCode.SharpZipLib.Tests/TestSupport/Streams.cs index 3f5ae552a..f6b0fff3e 100644 --- a/test/ICSharpCode.SharpZipLib.Tests/TestSupport/Streams.cs +++ b/test/ICSharpCode.SharpZipLib.Tests/TestSupport/Streams.cs @@ -177,13 +177,15 @@ public class MemoryStreamWithoutSeek : TrackedMemoryStream /// /// /// true if the stream is open. - public override bool CanSeek + public override bool CanSeek => false; + + /// + public override long Position { - get - { - return false; - } + get => throw new NotSupportedException("Getting position is not supported"); + set => throw new NotSupportedException("Setting position is not supported"); } + } /// diff --git a/test/ICSharpCode.SharpZipLib.Tests/Zip/StreamHandling.cs b/test/ICSharpCode.SharpZipLib.Tests/Zip/StreamHandling.cs index 2f1e866fd..d96d32713 100644 --- a/test/ICSharpCode.SharpZipLib.Tests/Zip/StreamHandling.cs +++ b/test/ICSharpCode.SharpZipLib.Tests/Zip/StreamHandling.cs @@ -111,11 +111,10 @@ public void ReadAndWriteZip64NonSeekable() outStream.Close(); } - Assert.That(msw.ToArray(), Does.PassTestArchive()); - - msw.Position = 0; + var msBytes = msw.ToArray(); + Assert.That(msBytes, Does.PassTestArchive()); - using (var zis = new ZipInputStream(msw)) + using (var zis = new ZipInputStream(new MemoryStream(msBytes))) { while (zis.GetNextEntry() != null) { diff --git a/test/ICSharpCode.SharpZipLib.Tests/Zip/ZipStreamAsyncTests.cs b/test/ICSharpCode.SharpZipLib.Tests/Zip/ZipStreamAsyncTests.cs index 5eb33c063..9a8aeac14 100644 --- a/test/ICSharpCode.SharpZipLib.Tests/Zip/ZipStreamAsyncTests.cs +++ b/test/ICSharpCode.SharpZipLib.Tests/Zip/ZipStreamAsyncTests.cs @@ -97,5 +97,26 @@ public async Task WriteZipStreamWithZipCryptoAsync() ZipTesting.AssertValidZip(ms, password, false); } + [Test] + [Category("Zip")] + [Category("Async")] + public async Task WriteReadOnlyZipStreamAsync () + { + using var ms = new MemoryStreamWithoutSeek(); + + using(var outStream = new ZipOutputStream(ms) { IsStreamOwner = false }) + { + await outStream.PutNextEntryAsync(new ZipEntry("FirstFile")); + await Utils.WriteDummyDataAsync(outStream, 12); + + await outStream.PutNextEntryAsync(new ZipEntry("SecondFile")); + await Utils.WriteDummyDataAsync(outStream, 12); + + await outStream.FinishAsync(CancellationToken.None); + } + + ZipTesting.AssertValidZip(new MemoryStream(ms.ToArray())); + } + } }