-
Notifications
You must be signed in to change notification settings - Fork 4.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
"A local file header is corrupt" error occurs while unpacking the ZIP archive #49580
Comments
I couldn't figure out the best area label to add to this issue. If you have write-permissions please help me learn by adding exactly one area label. |
Is it possible to share a zip that repros? Although it may be some time before we can take a look, perhaps you are comfortable debugging further. |
Here you are: test.zip |
It seems that the problem remains I'm trying to solve this problem using the following method, Most are normal, but occasionally the following occurs :
The problem could not be reproduced locally windows os ! I'll try to get further information, |
Thanks for the info. @maikebing it might be interesting if you could break under a debugger and see what return code we're getting from where. I assume you are using x64? To set expectations, it might be a while before we look at this on our side. Breaking in in a debugger at the point the exception is thrown might suggest whether it's .NET code or zlib. We are using the latest zlib (https://github.com/madler/zlib/releases/tag/v1.2.11) -- they haven't updated for a couple years. If there is some other tool (such as the platform 'unzip' command perhaps) that is zlib based it would be interesting to know whether that repros the problem. |
And here are reproduction steps. Issue49580.csproj <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFrameworks>net48;net5.0</TargetFrameworks>
<LangVersion>9.0</LangVersion>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="System.IO.Compression" Version="4.3.0" />
</ItemGroup>
</Project> Program.cs using System;
using System.IO;
using System.IO.Compression;
using System.Runtime.InteropServices;
// Demonstrates issue described on https://github.com/dotnet/runtime/issues/49580
try
{
// Produced with `xxd -i test.zip` with file from https://github.com/dotnet/runtime/files/6135119/test.zip
var zipData = new byte[]
{
0x50, 0x4b, 0x03, 0x04, 0x2d, 0x00, 0x00, 0x08, 0x08, 0x00, 0x17, 0x9b, 0x6d, 0x52, 0x0c, 0x7e, 0x7f, 0xd8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0x08, 0x00, 0x38, 0x00, 0x66, 0x69, 0x6c, 0x65, 0x2e, 0x74, 0x78, 0x74, 0x01, 0x00, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x18, 0x00, 0xa8, 0xb1,
0xf6, 0x61, 0x25, 0x18, 0xd7, 0x01, 0xa8, 0xb1, 0xf6, 0x61, 0x25, 0x18, 0xd7, 0x01, 0xa8, 0xb1, 0xf6, 0x61, 0x25, 0x18, 0xd7, 0x01, 0x2b, 0x49,
0x2d, 0x2e, 0x01, 0x00, 0x50, 0x4b, 0x01, 0x02, 0x2d, 0x00, 0x2d, 0x00, 0x00, 0x08, 0x08, 0x00, 0x17, 0x9b, 0x6d, 0x52, 0x0c, 0x7e, 0x7f, 0xd8,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x08, 0x00, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x66, 0x69, 0x6c, 0x65, 0x2e, 0x74, 0x78, 0x74, 0x01, 0x00, 0x1c, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x20, 0x00, 0x00, 0x00,
0x00, 0x00, 0x01, 0x00, 0x18, 0x00, 0xa8, 0xb1, 0xf6, 0x61, 0x25, 0x18, 0xd7, 0x01, 0xa8, 0xb1, 0xf6, 0x61, 0x25, 0x18, 0xd7, 0x01, 0xa8, 0xb1,
0xf6, 0x61, 0x25, 0x18, 0xd7, 0x01, 0x50, 0x4b, 0x06, 0x06, 0x2c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x2d, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7a, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x4b, 0x06, 0x07, 0x00, 0x00, 0x00, 0x00, 0xde, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x50, 0x4b, 0x05, 0x06, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x7a, 0x00,
0x00, 0x00, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00
};
Console.WriteLine($"Extracting test.zip on {RuntimeInformation.OSDescription.Trim()} ({RuntimeInformation.FrameworkDescription})");
using var archive = new ZipArchive(new MemoryStream(zipData));
foreach (var entry in archive.Entries)
{
Console.WriteLine($"{entry} (CompressedLength: {entry.CompressedLength} -- Length: {entry.Length})");
using var _ = entry.Open(); // throws System.IO.InvalidDataException (A local file header is corrupt)
}
return 0;
}
catch (Exception exception)
{
Console.Error.WriteLine(exception);
return 1;
} Result on .NET Framework 4.8 (
Result on .NET 5 (
|
if (OffsetOfCompressedData + _compressedSize > _archive.ArchiveStream.Length)
{
message = SR.LocalFileHeaderCorrupt;
return false;
} (long)94 + (long)4294967295 > (long)320.
|
4294967295 is 0xFFFFFFFF => -1
|
Please fix; this bug also manifests in powershell's Expand-Archive as "Unable to remove file" (or similar) errors. |
For the record, here's an example on how this issue can manifest in real life:
|
please fix this |
OK, apologies for not looking into this earlier, especially given the excellent description and ideal repro above.
So as noted, compressed and uncompressed size are both 0xFFFFFFFF. file name is 0x0008, extra field length is 0x0044. 'disk number start' and 'external file attributes' are both 0x0. the spec says that if they are 0xFFFF / 0xFFFFFFFF respectively, they are in the extra field; it doesn't say that if they aren't those values that they aren't in the extra field:
But the Zip64 extended field section seems completely explicit that they ONLY appear if they were 0xFFFF / 0xFFFFFFFF. Our code follows this, and identifies the unexpected length as a corruption. 4.5.3
What do other implementations do? The old WPF implementation mentioned in the past issue seems to make the same check and SharpCompress apparently does too. However Python apparently skips the specified length, whether or not it uses the fields: My guess is that Python and the others' implementations are most battle-tested and we should trust the length. |
For this zip, 7zip shows a warning "Characteristics: Extra_ERROR Zip64_ERROR NTFS : UTF8". From looking at https://sourceforge.net/p/sevenzip/discussion/45797/thread/13e7d575/#83a1, this can occur when 7zip sees that the zip64 extended field has sections present that were not all 0xFF in the 32 bit fields. Evidently it still moves past those unexpected fields as it will read the archive successfully. |
Description
In the process of working with a large number of .zip archives from various sources, I ran into a problem when unpacking some of them.
Configuration
Regression?
No, there is a similar problem in .NET 4.7.2
Other information
ZipArchiveEntry.cs :: IsOpenable
ZipBlocks.cs :: TryReadBlock
ZipBlocks.cs :: TryGetZip64BlockFromGenericExtraField
Here is the ZipInfo result for the given archive.
The archive is alive and correctly opened by all current archivers.
A similar problem was mentioned earlier, but it was related to large files:
#1094
The text was updated successfully, but these errors were encountered: