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

TestArchive doesn't handle invalid offsets correctly #856

Open adamkadzban opened 8 months ago

adamkadzban commented 8 months ago

Describe the bug

Entry header offsets are not checked for validity before trying to seek to them in the stream. Invalid offsets (i.e. <0) cause InvalidArgumentExceptions to be thrown from inside System.IO code, which are not caught in the existing ZipException handlers. They bubble up and cause the entire archive to fail validation with a cryptic "The parameter is incorrect - {filename}" message.

Reproduction Code

using ICSharpCode.SharpZipLib.Zip;

namespace TestArchive
{
    internal class Program
    {
        static void Main(string[] args)
        {
            string zipPath = @"C:\temp\test.zip";
            using var stream = System.IO.File.OpenRead(zipPath);
            using var zip = new ZipFile(stream);
            bool isValid = zip.TestArchive(false, TestStrategy.FindAllErrors, ZipTestResultHandler); 
            if (!isValid)
            {
                throw new ArgumentException("Zip file is invalid!");
            }
        }

        static void ZipTestResultHandler(TestStatus status, string message)
        {
            if (status.Entry != null && !status.EntryValid && !string.IsNullOrEmpty(message))
            {
                Console.WriteLine(status.Entry.ZipFileIndex + ": " + status.Entry.Name);
                Console.WriteLine(message);
            }
        }
    }
}

Steps to reproduce

  1. Get a zip file with an entry whose Offset is negative (this is generally an invalid state and I don't know how to create one like this)
  2. Call TestArchive() and pass in a ZipTestResultHandler to get the test results

Expected behavior

I expect each individual entry with an invalid offset/header to be reported on (assuming TestStrategy.FindAllErrors is specified)

Operating System

Windows

Framework Version

Other

Tags

ZIP

Additional context

entry.Offset not being checked for > 0: https://github.com/icsharpcode/SharpZipLib/blob/master/src/ICSharpCode.SharpZipLib/Zip/ZipFile.cs#L1184

Where the InvalidArgumentException from deep in System.IO gets caught outside the while loop (additional entries are not tested): https://github.com/icsharpcode/SharpZipLib/blob/master/src/ICSharpCode.SharpZipLib/Zip/ZipFile.cs#L1144

SourceproStudio commented 8 months ago

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

adamkadzban commented 8 months ago

I have a proposed/local fix for this, let me know if you want me to open up a Pull Request.