SevenZipExtractor.ExtractFileAsync(int, Stream) fails when created with leaveOpen == false #191
Description
Hi. A bug is found in SevenZipExtractor
. I hope this issue filing helps the library more stable.
Issue description
When I create an instance of SevenZipExtractor
using the constructor SevenZipExtractor(Stream, bool)
with its leaveOpen
argument set to false, its ExtractFileAsync(int, Stream)
method doesn't work; it causes an ArgumentException
whose Message
reads The specified stream can not seek or read.
, although the source archiveStream passed to the constructor is seekable and readable.
If I call the constructor with leaveOpen
set to true, the same ExtractFileAsync
works fine.
I tested the issue for several .7z
, .zip
, and .rar
files and observed the same behavior.
Environment details
- Windows 10 Pro (x64) 21H2
- Visual Studio 2017, C# 7.3, .NET Framwork 4.7.2 ("Prefer 32-bit" turned off)
- Squid-Box.SevenZipSharp v1.6.1.23 (nuget)
- 7-Zip 22.01 (2022-07-15) for Windows (x64)
Reproduction code fragment
using (var outputStream = new MemoryStream())
using (var archiveStream = File.OpenRead("test.7z"))
using (var extractor = new SevenZipExtractor(archiveStream: archiveStream, leaveOpen: false))
{
await extractor.ExtractFileAsync(0, outputStream);
}
See the attachment file for the full reproduction code as well as the project files and the sample 7z file:
TestSevenZipSharp.zip
Observed output
Unhandled Exception: System.AggregateException: One or more errors occurred. ---> System.ArgumentException: The specified stream can not seek or read.
Parameter name: stream
at SevenZip.SevenZipExtractor.ValidateStream(Stream stream) in D:\a\SevenZipSharp\SevenZipSharp\SevenZip\SevenZipExtractor.cs:line 754
at SevenZip.SevenZipExtractor.Init(Stream stream) in D:\a\SevenZipSharp\SevenZipSharp\SevenZip\SevenZipExtractor.cs:line 109
at SevenZip.SevenZipExtractor.RecreateInstanceIfNeeded() in D:\a\SevenZipSharp\SevenZipSharp\SevenZip\SevenZipExtractorAsynchronous.cs:line 42
at SevenZip.SevenZipExtractor.ExtractFile(Int32 index, Stream stream) in D:\a\SevenZipSharp\SevenZipSharp\SevenZip\SevenZipExtractor.cs:line 1076
at System.Threading.Tasks.Task.Execute()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at SevenZip.SevenZipExtractor.<ExtractFileAsync>d__114.MoveNext() in D:\a\SevenZipSharp\SevenZipSharp\SevenZip\SevenZipExtractorAsynchronous.cs:line 182
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.GetResult()
at TestSevenZipSharp.Program.<MainAsync>d__1.MoveNext() in C:\Repos\TestSevenZipSharp\TestSevenZipSharp\Program.cs:line 29
--- End of inner exception stack trace ---
at System.Threading.Tasks.Task.ThrowIfExceptional(Boolean includeTaskCanceledExceptions)
at System.Threading.Tasks.Task.Wait(Int32 millisecondsTimeout, CancellationToken cancellationToken)
at System.Threading.Tasks.Task.Wait()
at TestSevenZipSharp.Program.Main(String[] args) in C:\Repos\TestSevenZipSharp\TestSevenZipSharp\Program.cs:line 20
Thanks!