2

We have code to upload a zip file, at the start of the process if the zip file contains __MACOSX folder in the zip it will strip these folders/files from the zip and pass the file bytes on.

The issue we're having is that further down the chain if we create a new ZipArchive using fileBytes we get the error:

Number of entries expected in End Of Central Directory does not correspond to number of entries in Central Directory.

This only happens when the zip doesn't contain any __MAXOSX folders to be removed. Commenting out the below code prevents this error ever occuring.

// Strip MacOSX folder if zip
var fileBytes = uploadController.FileBytes;
if (uploadController.FileName.EndsWith(".zip", StringComparison.CurrentCultureIgnoreCase))
{
    try
    {
        using (var data = new MemoryStream(fileBytes))
        {
            var changed = false;
            using (var archive = new ZipArchive(data, ZipArchiveMode.Update))
            {
                while (true)
                {
                    var osx = archive.Entries.FirstOrDefault(
                        c => c.FullName.StartsWith("__MACOSX/", StringComparison.CurrentCultureIgnoreCase)
                    );
                    if (osx == null) break;
                    osx.Delete();
                    changed = true;
                }
            }

            // Archive is updated once disposed
            if (changed)
            {
                fileBytes = data.ToArray();
            }
        }                    
    }
    catch (Exception e)
    {
        return new ObjectReturnMethodResult<UploadedFileV2>("Uploaded zip appears to be invalid." + e.Message);
    }
}

When running the above code on a zip that doesn't contain __MACOSX why might it create this error?

Tom Gullen
  • 61,249
  • 84
  • 283
  • 456
  • You need to rad the ZIP specification. There are many versions with optional requirements. The optional requirements allow vendors to implement the code differently. Since a zip file can be modified after it is created the specification allows for different implementation of deleting items. – jdweng Jun 22 '21 at 10:33
  • @jdweng the error is thrown if the above code is not executed (`changed=false`) – Tom Gullen Jun 22 '21 at 10:36

1 Answers1

0

Changing:

using (var data = new MemoryStream(fileBytes))

To:

using (var data = new MemoryStream(fileBytes.ToArray()))

Seems to fix this, although not sure why!

Tom Gullen
  • 61,249
  • 84
  • 283
  • 456