Skip to content

Commit d5a8c37

Browse files
authored
Merge pull request #1154 from adamhathcock/adam/1151-release
Adam/1151 release cherry pick
2 parents 97879f1 + 21ce9a3 commit d5a8c37

4 files changed

Lines changed: 136 additions & 5 deletions

File tree

src/SharpCompress/Common/EntryStream.cs

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -79,11 +79,25 @@ protected override void Dispose(bool disposing)
7979
{
8080
if (ss.BaseStream() is SharpCompress.Compressors.Deflate.DeflateStream deflateStream)
8181
{
82-
deflateStream.Flush(); //Deflate over reads. Knock it back
82+
try
83+
{
84+
deflateStream.Flush(); //Deflate over reads. Knock it back
85+
}
86+
catch (NotSupportedException)
87+
{
88+
// Ignore: underlying stream does not support required operations for Flush
89+
}
8390
}
8491
else if (ss.BaseStream() is SharpCompress.Compressors.LZMA.LzmaStream lzmaStream)
8592
{
86-
lzmaStream.Flush(); //Lzma over reads. Knock it back
93+
try
94+
{
95+
lzmaStream.Flush(); //Lzma over reads. Knock it back
96+
}
97+
catch (NotSupportedException)
98+
{
99+
// Ignore: underlying stream does not support required operations for Flush
100+
}
87101
}
88102
}
89103
#if DEBUG_STREAMS
@@ -111,11 +125,25 @@ public override async ValueTask DisposeAsync()
111125
{
112126
if (ss.BaseStream() is SharpCompress.Compressors.Deflate.DeflateStream deflateStream)
113127
{
114-
await deflateStream.FlushAsync().ConfigureAwait(false);
128+
try
129+
{
130+
await deflateStream.FlushAsync().ConfigureAwait(false);
131+
}
132+
catch (NotSupportedException)
133+
{
134+
// Ignore: underlying stream does not support required operations for Flush
135+
}
115136
}
116137
else if (ss.BaseStream() is SharpCompress.Compressors.LZMA.LzmaStream lzmaStream)
117138
{
118-
await lzmaStream.FlushAsync().ConfigureAwait(false);
139+
try
140+
{
141+
await lzmaStream.FlushAsync().ConfigureAwait(false);
142+
}
143+
catch (NotSupportedException)
144+
{
145+
// Ignore: underlying stream does not support required operations for Flush
146+
}
119147
}
120148
}
121149
#if DEBUG_STREAMS

tests/SharpCompress.Test/SharpCompress.Test.csproj

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@
99
<PropertyGroup Condition="'$(Configuration)|$(TargetFramework)|$(Platform)'=='Debug|net10.0|AnyCPU'">
1010
<DefineConstants>$(DefineConstants);DEBUG_STREAMS</DefineConstants>
1111
</PropertyGroup>
12+
<PropertyGroup Condition=" '$(TargetFramework)' == 'net48' ">
13+
<DefineConstants>$(DefineConstants);LEGACY_DOTNET</DefineConstants>
14+
</PropertyGroup>
1215
<PropertyGroup Condition="$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Windows)))">
1316
<DefineConstants>$(DefineConstants);WINDOWS</DefineConstants>
1417
</PropertyGroup>
@@ -25,7 +28,7 @@
2528
<PackageReference Include="xunit" />
2629
<PackageReference Include="Microsoft.NETFramework.ReferenceAssemblies" PrivateAssets="All" />
2730
</ItemGroup>
28-
<ItemGroup Condition=" '$(VersionlessImplicitFrameworkDefine)' != 'NETFRAMEWORK' ">
31+
<ItemGroup Condition="$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Linux)))">
2932
<PackageReference Include="Mono.Posix.NETStandard" />
3033
</ItemGroup>
3134
</Project>

tests/SharpCompress.Test/Zip/ZipReaderAsyncTests.cs

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -251,4 +251,58 @@ await reader.WriteEntryToDirectoryAsync(
251251
}
252252
Assert.Equal(8, count);
253253
}
254+
255+
[Fact]
256+
public async ValueTask EntryStream_Dispose_DoesNotThrow_OnNonSeekableStream_Deflate_Async()
257+
{
258+
// Since version 0.41.0: EntryStream.DisposeAsync() should not throw NotSupportedException
259+
// when FlushAsync() fails on non-seekable streams (Deflate compression)
260+
var path = Path.Combine(TEST_ARCHIVES_PATH, "Zip.deflate.dd.zip");
261+
using Stream stream = new ForwardOnlyStream(File.OpenRead(path));
262+
using var reader = ReaderFactory.Open(stream);
263+
264+
// This should not throw, even if internal FlushAsync() fails
265+
while (await reader.MoveToNextEntryAsync())
266+
{
267+
if (!reader.Entry.IsDirectory)
268+
{
269+
#if LEGACY_DOTNET
270+
using var entryStream = await reader.OpenEntryStreamAsync();
271+
#else
272+
await using var entryStream = await reader.OpenEntryStreamAsync();
273+
#endif
274+
// Read some data
275+
var buffer = new byte[1024];
276+
await entryStream.ReadAsync(buffer, 0, buffer.Length);
277+
// DisposeAsync should not throw NotSupportedException
278+
}
279+
}
280+
}
281+
282+
[Fact]
283+
public async ValueTask EntryStream_Dispose_DoesNotThrow_OnNonSeekableStream_LZMA_Async()
284+
{
285+
// Since version 0.41.0: EntryStream.DisposeAsync() should not throw NotSupportedException
286+
// when FlushAsync() fails on non-seekable streams (LZMA compression)
287+
var path = Path.Combine(TEST_ARCHIVES_PATH, "Zip.lzma.dd.zip");
288+
using Stream stream = new ForwardOnlyStream(File.OpenRead(path));
289+
using var reader = ReaderFactory.Open(stream);
290+
291+
// This should not throw, even if internal FlushAsync() fails
292+
while (await reader.MoveToNextEntryAsync())
293+
{
294+
if (!reader.Entry.IsDirectory)
295+
{
296+
#if LEGACY_DOTNET
297+
using var entryStream = await reader.OpenEntryStreamAsync();
298+
#else
299+
await using var entryStream = await reader.OpenEntryStreamAsync();
300+
#endif
301+
// Read some data
302+
var buffer = new byte[1024];
303+
await entryStream.ReadAsync(buffer, 0, buffer.Length);
304+
// DisposeAsync should not throw NotSupportedException
305+
}
306+
}
307+
}
254308
}

tests/SharpCompress.Test/Zip/ZipReaderTests.cs

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -436,4 +436,50 @@ public void ZipReader_Returns_Same_Entries_As_ZipArchive()
436436
Assert.Equal(archiveKeys.OrderBy(k => k), readerKeys.OrderBy(k => k));
437437
}
438438
}
439+
440+
[Fact]
441+
public void EntryStream_Dispose_DoesNotThrow_OnNonSeekableStream_Deflate()
442+
{
443+
// Since version 0.41.0: EntryStream.Dispose() should not throw NotSupportedException
444+
// when Flush() fails on non-seekable streams (Deflate compression)
445+
var path = Path.Combine(TEST_ARCHIVES_PATH, "Zip.deflate.dd.zip");
446+
using Stream stream = new ForwardOnlyStream(File.OpenRead(path));
447+
using var reader = ReaderFactory.Open(stream);
448+
449+
// This should not throw, even if internal Flush() fails
450+
while (reader.MoveToNextEntry())
451+
{
452+
if (!reader.Entry.IsDirectory)
453+
{
454+
using var entryStream = reader.OpenEntryStream();
455+
// Read some data
456+
var buffer = new byte[1024];
457+
entryStream.Read(buffer, 0, buffer.Length);
458+
// Dispose should not throw NotSupportedException
459+
}
460+
}
461+
}
462+
463+
[Fact]
464+
public void EntryStream_Dispose_DoesNotThrow_OnNonSeekableStream_LZMA()
465+
{
466+
// Since version 0.41.0: EntryStream.Dispose() should not throw NotSupportedException
467+
// when Flush() fails on non-seekable streams (LZMA compression)
468+
var path = Path.Combine(TEST_ARCHIVES_PATH, "Zip.lzma.dd.zip");
469+
using Stream stream = new ForwardOnlyStream(File.OpenRead(path));
470+
using var reader = ReaderFactory.Open(stream);
471+
472+
// This should not throw, even if internal Flush() fails
473+
while (reader.MoveToNextEntry())
474+
{
475+
if (!reader.Entry.IsDirectory)
476+
{
477+
using var entryStream = reader.OpenEntryStream();
478+
// Read some data
479+
var buffer = new byte[1024];
480+
entryStream.Read(buffer, 0, buffer.Length);
481+
// Dispose should not throw NotSupportedException
482+
}
483+
}
484+
}
439485
}

0 commit comments

Comments
 (0)