Skip to content
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

System.IO.Packaging.Open throws FileFormatException saying File contains corrupted data when the size of the package is more than 4GB and targeting .NET Framework #94899

Closed
SeenaAugusty opened this issue Nov 17, 2023 · 12 comments · Fixed by #102053
Labels
area-System.IO.Compression in-pr There is an active PR which will close this issue when it is merged
Milestone

Comments

@SeenaAugusty
Copy link

SeenaAugusty commented Nov 17, 2023

Description

Our DacFx code uses System.IO.Packaging for packing the schema and when it is packaged with more than 4GB, it throw FileFormat Exception saying File contains corrupted data when it is used in a console app targeting .NET Framework but the same package loads fine in .NET Core

File contains corrupted data.

Program Location:

at MS.Internal.IO.Zip.ZipIOLocalFileBlock.Validate(String fileName, ZipIOCentralDirectoryBlock centralDir, ZipIOCentralDirectoryFileHeader centralDirFileHeader)
at MS.Internal.IO.Zip.ZipIOLocalFileBlock.ParseRecord(BinaryReader reader, String fileName, Int64 position, ZipIOCentralDirectoryBlock centralDir, ZipIOCentralDirectoryFileHeader centralDirFileHeader)
at MS.Internal.IO.Zip.ZipIOLocalFileBlock.SeekableLoad(ZipIOBlockManager blockManager, String fileName)
at MS.Internal.IO.Zip.ZipIOBlockManager.LoadLocalFileBlock(String zipFileName)
at MS.Internal.IO.Zip.ZipArchive.GetFile(String zipFileName)
at MS.Internal.IO.Zip.ZipArchive.GetFiles()
at System.IO.Packaging.ZipPackage.ContentTypeHelper..ctor(ZipArchive zipArchive, IgnoredItemHelper ignoredItemHelper)
at System.IO.Packaging.ZipPackage..ctor(String path, FileMode mode, FileAccess access, FileShare share, Boolean streaming)
at System.IO.Packaging.Package.Open(String path, FileMode packageMode, FileAccess packageAccess, FileShare packageShare, Boolean streaming)
at Microsoft.Data.Tools.Schema.Sql.Build.SqlPackage.Artifact.InitializefromFile(FileInfo fileInfo, FileMode mode, FileAccess access)

Reproduction Steps

  1. Create a console app targeting .NET core and package a file of size greater than 4 or 6GB using System.IO.Packaging library
  2. Create another console app targeting .NET framework and try to open the package created in step 1 using System.IO.Packaging library, it would throw File Format Exception.

Expected behavior

It should open the package in the console app targeting .Net Framework

Actual behavior

It throws File Format exception saying File contains corrupted data when it works fine in the console app targeting .NET core

Regression?

No response

Known Workarounds

Open the package in the console app targeting .NET Core

Configuration

No response

Other information

It has been reported here in dotnet/wpf#2676 and because of this issue, we have an issue opened in DacFx microsoft/DacFx#363

@ghost ghost added the untriaged New issue has not been triaged by the area owner label Nov 17, 2023
@ghost
Copy link

ghost commented Nov 17, 2023

Tagging subscribers to this area: @dotnet/area-system-io-compression
See info in area-owners.md if you want to be subscribed.

Issue Details

Description

Our DacFx code uses System.IO.Packaging for packing the schema and when it is packaged with more than 4GB, it throw FileFormat Exception saying File contains corrupted data when it is used in a console app targeting .NET Framework but the same package loads fine in .NET Core

File contains corrupted data.

Program Location:

at MS.Internal.IO.Zip.ZipIOLocalFileBlock.Validate(String fileName, ZipIOCentralDirectoryBlock centralDir, ZipIOCentralDirectoryFileHeader centralDirFileHeader)
at MS.Internal.IO.Zip.ZipIOLocalFileBlock.ParseRecord(BinaryReader reader, String fileName, Int64 position, ZipIOCentralDirectoryBlock centralDir, ZipIOCentralDirectoryFileHeader centralDirFileHeader)
at MS.Internal.IO.Zip.ZipIOLocalFileBlock.SeekableLoad(ZipIOBlockManager blockManager, String fileName)
at MS.Internal.IO.Zip.ZipIOBlockManager.LoadLocalFileBlock(String zipFileName)
at MS.Internal.IO.Zip.ZipArchive.GetFile(String zipFileName)
at MS.Internal.IO.Zip.ZipArchive.GetFiles()
at System.IO.Packaging.ZipPackage.ContentTypeHelper..ctor(ZipArchive zipArchive, IgnoredItemHelper ignoredItemHelper)
at System.IO.Packaging.ZipPackage..ctor(String path, FileMode mode, FileAccess access, FileShare share, Boolean streaming)
at System.IO.Packaging.Package.Open(String path, FileMode packageMode, FileAccess packageAccess, FileShare packageShare, Boolean streaming)
at Microsoft.Data.Tools.Schema.Sql.Build.SqlPackage.Artifact.InitializefromFile(FileInfo fileInfo, FileMode mode, FileAccess access)

Reproduction Steps

  1. Create a console app targeting .NET core and package a file of size greater than 4 or 6GB using System.IO.Packaging library
  2. Create another console app targeting .NET framework and try to open the package created in step 1 using System.IO.Packaging library, it would throw File Format Exception.

Expected behavior

It should open the package in the console app targeting .Net Framework

Actual behavior

It throws File Format exception saying File contains corrupted data when it works fine in the console app targeting .NET core

Regression?

No response

Known Workarounds

Open the package in the console app targeting .NET Core

Configuration

No response

Other information

It has been reported here in dotnet/wpf#2676 and because of this issue, we have an issue opened in DacFx microsoft/DacFx#363

Author: SeenaAugusty
Assignees: -
Labels:

area-System.IO.Compression

Milestone: -

@zijchen
Copy link

zijchen commented Nov 17, 2023

We can repro this with version 5.0.0 but it's possible the issue was in prior versions too

@karakasa
Copy link
Contributor

karakasa commented Nov 19, 2023

Exception occurs due to the versionNeeded is different in the local header (20, Deflate) compared to that in central directory (45, ZIP64).

The underlying reason is that all small files after large files (>4GB) requires ZIP64 header because their LH offsets are >4GB. ZipArchiveEntry.WriteCentralDirectoryFileHeader() catches that so CD is correct, however LHs are unaware of the offset issue when created in ZipArchiveEntry.WriteCrcAndSizesInLocalHeader() so the version in LH is 20.

It's unclear in the PKWare spec whether the discrepancy is allowed, but the latest .NET doesn't validate that as the Framework used to do. 7-Zip set both ZIP64 flags in LH and CD for file offsetting >4GB.

If the discrepancy is allowed, the bug can only be fixed from the Framework side because the issue is within WindowsBase.dll.

If it's not allowed, the current ZIP LH writing impl in .NET is wrong. I would propose a fix as in #94970.

karakasa added a commit to karakasa/runtime that referenced this issue Nov 19, 2023
ZipArchiveEntry didn't set ZIP64 in local
headers for small files if their offset are
>4GB.
@ghost ghost added the in-pr There is an active PR which will close this issue when it is merged label Nov 19, 2023
@pwoosam
Copy link

pwoosam commented Nov 23, 2023

@karakasa, My understanding is that the central directory headers must match the local file headers.
Reference to APPNOTE-6.3.10.TXT on pkware.cachefly.net

The central directory header is intended to provide a quick lookup of all zip file metadata without needing to scan the entire file. It should contain identical data to the local file header. Mismatched headers may indicate corruption and is invalid.

As an example, multiple compression methods in the spec also specify the expectation that the compression method will match in both the central directory headers and local file headers.

image
image
image
image

@carlossanlop carlossanlop removed the untriaged New issue has not been triaged by the area owner label Dec 6, 2023
@carlossanlop carlossanlop added this to the 9.0.0 milestone Dec 6, 2023
@SeenaAugusty
Copy link
Author

@karakasa I was wondering if this fixed in net8?

@carlossanlop
Copy link
Member

@SeenaAugusty not yet but we will backport it to 8.0 once the fix is merged.

@llali
Copy link

llali commented Mar 22, 2024

@carlossanlop do you have any ETA on when this fix will be ported to 8.0? in which sdk version?

@carlossanlop
Copy link
Member

We need to merge the fix to main first, then we can backport it and have it included in the upcoming release at that point.

@ssreerama

This comment was marked as off-topic.

@pwoosam

This comment was marked as off-topic.

@llali

This comment was marked as off-topic.

@llali
Copy link

llali commented May 8, 2024

@carlossanlop any update on this bug?

carlossanlop pushed a commit to carlossanlop/runtime that referenced this issue May 9, 2024
ZipArchiveEntry didn't set ZIP64 in local
headers for small files if their offset are
>4GB.
carlossanlop pushed a commit to carlossanlop/runtime that referenced this issue May 9, 2024
ZipArchiveEntry didn't set ZIP64 in local
headers for small files if their offset are
>4GB.
carlossanlop pushed a commit to carlossanlop/runtime that referenced this issue May 29, 2024
ZipArchiveEntry didn't set ZIP64 in local
headers for small files if their offset are
>4GB.
@github-actions github-actions bot locked and limited conversation to collaborators Jul 1, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-System.IO.Compression in-pr There is an active PR which will close this issue when it is merged
Projects
None yet
7 participants