Skip to content

Data Descriptor Lost UncompressedSize #147

Description

@daroubing

Steps to reproduce

1.Use ZipFile open android apk file
2.Do some Update
3.Data descriptor UncompressedSize is wrong
4.ZipFile.TestArchive(true) is return false

Expected behavior

It is equal ZipEntry's Size

Actual behavior

It is 0x504B0304

Version of SharpZipLib

0.85, 0.86

Obtained from (place an x between the brackets for all that apply)

  • [-] Compiled from source
    • branch: master
    • commit: _______
  • [ .] Downloaded DLL from GitHub
  • Downloaded DLL from SourceForge
  • Downloaded DLL from _______
  • DLL included as part of
  • Package installed using:
    • NuGet
    • MyGet
    • Chocolatey
      screenshot_20161017_043451

Activity

  1. Numpsy commented on Jun 7, 2020

    @Numpsy
    Contributor

    example of a unit test that looks to hit the issue (or something very similar at least):

    [Test]
    [Category("Zip")]
    public void TestDescriptorUpdate()
    {
        MemoryStream msw = new MemoryStreamWithoutSeek();
        using (ZipOutputStream outStream = new ZipOutputStream(msw))
        {
            outStream.UseZip64 = UseZip64.Off;
            outStream.IsStreamOwner = false;
            outStream.PutNextEntry(new ZipEntry("StripedMarlin"));
            outStream.WriteByte(89);
    
            outStream.PutNextEntry(new ZipEntry("StripedMarlin2"));
            outStream.WriteByte(91);
        }
    
        var zipData = msw.ToArray();
        Assert.IsTrue(ZipTesting.TestArchive(zipData));
    
        using (var memoryStream = new MemoryStream(zipData))
        {
            using (var zipFile = new ZipFile(memoryStream, leaveOpen: true))
            {
                zipFile.BeginUpdate();
                zipFile.Delete("StripedMarlin");
                zipFile.CommitUpdate();
            }
    
            memoryStream.Position = 0;
    
            using (var zipFile = new ZipFile(memoryStream, leaveOpen: true))
            {
                Assert.That(zipFile.TestArchive(true), Is.True);
            }
        }
    }

    i tried debugging the zipfile update, and i'm wondering if there is an issue in the GetDescriptorSize function in ZipFile:

    private int GetDescriptorSize(ZipUpdate update)
    {
        int result = 0;
        if ((update.Entry.Flags & (int)GeneralBitFlags.Descriptor) != 0)
        {
            result = ZipConstants.DataDescriptorSize - 4;
            if (update.Entry.LocalHeaderRequiresZip64)
            {
                result = ZipConstants.Zip64DataDescriptorSize - 4;
            }
        }
        return result;
    }

    Where I don't know what those -4s are for?

    The test passes if those are removed, so i'm not sure if the issue isn't just that it's slicing the end off the descriptor when doing the update?
    (though i'm not sure if there should really be a descriptor there after the update at all, given that the size fields for the entry are known at this point)

  2. Numpsy commented on Jun 7, 2020

    @Numpsy
    Contributor

    Actually, posted that and then saw the

    image

    comment in CopyEntryDirect, which sounds a tad suspicious given that GetDescriptorSize takes 4 bytes off the size.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions