icsharpcode / SharpZipLib

#ziplib is a Zip, GZip, Tar and BZip2 library written entirely in C# for the .NET platform.
http://icsharpcode.github.io/SharpZipLib/
MIT License
3.7k stars 976 forks source link

Use CompressionMethod.Stored and flush the ZipOutputStream after each entity was added leads Zip corrupted in SharpZipLib 1.4.2 #834

Open zhuxb711 opened 1 year ago

zhuxb711 commented 1 year ago

Describe the bug

I found a bug that if I set CompressionMethod = CompressionMethod.Stored in the entry and flush the ZipOutputStream, the output zip is corrupted and only the first file exists in the zip file.

using (Stream NewZipStream = File.OpenWrite(Path.GetRandomFileName()))
using (ZipOutputStream ZipStream = new ZipOutputStream(NewZipStream , StringCodec.FromEncoding(Encoding.UTF8)))
{
    ZipStream.SetLevel(0);
    ZipStream.UseZip64 = UseZip64.Dynamic;
    ZipStream.IsStreamOwner = false;

    foreach (string FilePath in Directory.EnumerateFiles("<Your folder that has multiple files>"))
    {
          using (Stream FileStream = File.OpenRead(FilePath))
          {
              ZipEntry NewEntry = new ZipEntry(File.Name)
              {
                  DateTime = DateTime.Now,
                  CompressionMethod = CompressionMethod.Stored,
                  Size = FileStream.Length
              };

              await ZipStream.PutNextEntryAsync(NewEntry, CancelToken);
              await FileStream.CopyToAsync(ZipStream);
              await ZipStream.CloseEntryAsync(CancelToken);
          }

          await ZipStream.FlushAsync(CancelToken);
    }
}

Reproduction Code

No response

Steps to reproduce

  1. Use ZipOutputStream
  2. Set CompressionMethod to CompressionMethod.Stored on ZipEntry
  3. Add multiple files/folders into ZipOutputStream
  4. Flush the ZipOutputStream once each entity was added
  5. Found the zip file is corrupted

Expected behavior

Zip is not corrupted

Operating System

Windows

Framework Version

.NET 7

Tags

ZIP

Additional context

No response

SourceproStudio commented 1 year ago

这是来自QQ邮箱的假期自动回复邮件。   您好,我最近正在休假中,无法亲自回复您的邮件。我将在假期结束后,尽快给您回复。

piksel commented 1 year ago

only the first file exists in the zip file.

You are adding the same file many times, using the same name. Most archivers would probably only display that as a single file entry.

Could you upload the output file to ArchiveDiag and post the URL to the resulting analysis here?

zhuxb711 commented 1 year ago

@piksel Yes that just a sample, just let you know that I added multiple files

zhuxb711 commented 1 year ago

Sorry, further test shows that this issue related to FlushAsync() on ZipOutputStream, here is the demo. Make sure there are some files in your "~\Picures\Screenshot" folder

SharpZipLibTest.zip

zhuxb711 commented 1 year ago

In short, if CompressionMethod is not CompressionMethod.Stored or do not flush the ZipOutputStream after insert a new entry, this issue disappeared.

piksel commented 1 year ago

I tried to reproduce your issue but it works correctly: https://dotnetfiddle.net/IDUcxf

zhuxb711 commented 1 year ago

I have tested in two different PCs using the demo I provided before. And the result is the same, please try use the demo application instead: image

zhuxb711 commented 1 year ago

Demo application SharpZipLibTest.zip will try zip your Screenshots folder in 4 different ways, output zip file will be placed on your desktop. Test1.zip is corrupted and Test2.zip & Test3.zip Test4.zip are correct. Please check code of the demo application

zhuxb711 commented 1 year ago

@piksel Could you reproduce this issue using the demo application?