adamhathcock / sharpcompress

SharpCompress is a fully managed C# library to deal with many compression types and formats.
MIT License
2.22k stars 476 forks source link

Inconsistent behavior on extracting 7zip with wrong password #811

Open idan-weiss opened 4 months ago

idan-weiss commented 4 months ago

Hi!

I'm trying to extract 7zip file with password. I found out that there is inconsistent behavior when I try to use a wrong password:

For a password protected 7zip file, this is the error I get when I use the password wrong:

SharpCompress.Compressors.LZMA.DataErrorException: Data Error
   at SharpCompress.Compressors.LZMA.Decoder.Code(Int32 dictionarySize, OutWindow outWindow, Decoder rangeDecoder)
   at SharpCompress.Compressors.LZMA.LzmaStream.Read(Byte[] buffer, Int32 offset, Int32 count)
   at SharpCompress.IO.ReadOnlySubStream.Read(Byte[] buffer, Int32 offset, Int32 count)
   at SharpCompress.Common.EntryStream.Read(Byte[] buffer, Int32 offset, Int32 count)
   at SharpCompress.Utility.ReadTransferBlock(Stream source, Byte[] array, Int32& count)
   at SharpCompress.Utility.TransferTo(Stream source, Stream destination, Entry entry, IReaderExtractionListener readerExtractionListener)
   at SharpCompress.Readers.AbstractReader`2.Write(Stream writeStream)
   at SharpCompress.Readers.AbstractReader`2.WriteEntryTo(Stream writableStream)

While this is the error I get when I use the password asdasd:

System.IndexOutOfRangeException: Index was outside the bounds of the array.
   at SharpCompress.Compressors.LZMA.LZ.OutWindow.GetByte(Int32 distance)
   at SharpCompress.Compressors.LZMA.Decoder.Code(Int32 dictionarySize, OutWindow outWindow, Decoder rangeDecoder)
   at SharpCompress.Compressors.LZMA.LzmaStream.Read(Byte[] buffer, Int32 offset, Int32 count)
   at SharpCompress.IO.ReadOnlySubStream.Read(Byte[] buffer, Int32 offset, Int32 count)
   at SharpCompress.Common.EntryStream.Read(Byte[] buffer, Int32 offset, Int32 count)
   at SharpCompress.Utility.Skip(Stream source)
   at SharpCompress.Common.EntryStream.SkipEntry()
   at SharpCompress.Common.EntryStream.Dispose(Boolean disposing)
   at System.IO.Stream.Close()
   at SharpCompress.Readers.AbstractReader`2.Write(Stream writeStream)
   at SharpCompress.Readers.AbstractReader`2.WriteEntryTo(Stream writableStream)

The described behavior happens when I use:

        var reader = archive.ExtractAllEntries();
        while (reader.MoveToNextEntry())

But when I use this instead, both cases throw the 1st exception:

            foreach (var entry in archive.Entries) {
            ... 
                    await using var entryMemoryStream = new MemoryStream();
                    await using var entryStream = entry.OpenEntryStream();
                    await entryStream.CopyToAsync(entryMemoryStream);
            ...

I have 2 issues with that: