SevenZipSharp icon indicating copy to clipboard operation
SevenZipSharp copied to clipboard

SevenZipExtractor.ExtractFileAsync(int, Stream) fails when created with leaveOpen == false

Open AlissaSabre opened this issue 2 years ago • 0 comments

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!

AlissaSabre avatar Apr 12 '23 09:04 AlissaSabre