Skip to content

Package.Open ZIP regression or unmitigatable breaking change on .NET 9 #123419

@idigra

Description

@idigra

Description

When trying to bump from .NET 8 to .NET 10, we encounter exception when trying to dispose a package created by Package.Open on compressed data that was previously saved in customers' storage. See repro steps for one such example.
The issue might be related to .NET 9 breaking change dotnet/docs#40299 (reference to PR too - #98278 ). An indication for that is that when trying to zero one of the general purpose flag bits (as the commented out line in the repro steps demonstrates) the exception is mitigated. However, this breaking change doc doesn't cover our case:

  • The doc describes a breaking change in the code level, not when using a data that previously worked properly.
  • The doc mentions that This breaking change was introduced to restore the existing .NET Framework behaviour, however when trying to test it with .NET Framework the issue is not reproducing (tried .NET Framework 4.6.2 and .NET Framework 4.8).

This issue currently blocks our way forward to .NET 9 or 10, as this will break on users' data.

Reproduction Steps

Build and run following code in .NET 9:

byte[] compressed = new byte[]
{
			80,75,3,4,20,0,6,0,8,0,0,0,33,0,42,221,170,64,210,0,0,0,55,1,0,0,19,0,8,2,91,67,111,110,116,101,110,116,95,84,121,112,101,115,93,46,120,109,108,32,162,4,2,40,160,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,108,143,189,78,196,48,16,132,123,36,222,193,218,254,178,129,2,33,148,228,10,126,74,184,226,120,128,149,179,201,89,216,107,203,94,80,238,237,113,46,84,64,185,63,51,223,76,183,95,130,55,95,156,139,139,210,195,77,211,130,97,177,113,116,50,247,240,126,124,217,221,131,41,74,50,146,143,194,61,156,185,192,126,184,190,234,142,231,196,197,84,181,148,30,78,170,233,1,177,216,19,7,42,77,76,44,245,50,197,28,72,235,152,103,76,100,63,104,102,188,109,219,59,180,81,148,69,119,186,122,192,208,61,241,68,159,94,205,243,82,215,91,146,0,230,113,251,90,65,61,40,47,138,201,147,19,192,127,5,149,247,75,66,41,121,103,73,107,51,92,175,85,247,86,155,102,55,178,57,80,214,87,10,213,24,43,102,114,51,30,182,128,205,95,159,11,250,199,0,47,181,135,111,0,0,0,255,255,3,0,80,75,3,4,20,0,2,0,8,0,0,0,33,0,10,177,174,11,172,0,0,0,247,0,0,0,18,0,0,0,67,111,110,102,105,103,47,80,97,99,107,97,103,101,46,120,109,108,132,143,189,14,130,48,28,196,119,19,223,129,116,167,31,160,11,41,101,112,149,196,132,104,92,27,104,164,17,254,53,180,88,222,205,193,71,242,21,132,40,234,230,120,119,191,228,238,30,183,59,207,134,182,9,174,170,179,218,64,138,24,166,40,176,78,66,37,27,3,42,69,96,80,38,150,11,190,147,229,89,158,84,48,210,96,147,193,86,41,170,157,187,36,132,120,239,177,143,177,233,78,36,162,148,145,99,190,45,202,90,181,18,125,96,253,31,14,53,76,181,165,66,130,31,94,107,68,132,25,91,227,104,21,99,202,201,108,242,92,195,23,136,198,193,83,250,99,242,77,223,184,190,83,66,65,184,47,56,153,37,39,239,15,226,9,0,0,255,255,3,0,80,75,3,4,20,0,2,0,8,0,0,0,33,0,98,124,210,234,150,0,0,0,177,2,0,0,19,0,0,0,70,111,114,109,117,108,97,115,47,83,101,99,116,105,111,110,49,46,109,42,78,77,46,201,204,207,83,8,134,208,134,214,92,92,197,25,137,69,169,41,10,129,165,169,69,149,62,249,137,41,169,41,33,249,33,137,73,57,169,10,182,10,57,169,37,188,92,10,64,16,156,95,90,148,12,18,81,82,226,229,202,204,67,22,196,103,132,75,98,73,162,111,126,74,106,14,101,102,5,100,150,229,151,80,193,77,8,115,208,28,134,110,30,208,56,194,166,57,231,231,229,65,130,209,63,47,167,146,50,151,161,154,69,13,215,129,253,234,12,148,40,161,66,152,129,205,161,196,85,225,153,37,25,249,165,37,8,111,18,235,40,0,0,0,0,255,255,3,0,80,75,1,2,45,0,20,0,6,0,8,0,0,0,33,0,42,221,170,64,210,0,0,0,55,1,0,0,19,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,91,67,111,110,116,101,110,116,95,84,121,112,101,115,93,46,120,109,108,80,75,1,2,45,0,20,0,2,0,8,0,0,0,33,0,10,177,174,11,172,0,0,0,247,0,0,0,18,0,0,0,0,0,0,0,0,0,0,0,0,0,11,3,0,0,67,111,110,102,105,103,47,80,97,99,107,97,103,101,46,120,109,108,80,75,1,2,45,0,20,0,2,0,8,0,0,0,33,0,98,124,210,234,150,0,0,0,177,2,0,0,19,0,0,0,0,0,0,0,0,0,0,0,0,0,231,3,0,0,70,111,114,109,117,108,97,115,47,83,101,99,116,105,111,110,49,46,109,80,75,5,6,0,0,0,0,3,0,3,0,194,0,0,0,174,4,0,0,0,0
};
// compressed[1206] = 2;

MemoryStream stream = new MemoryStream(compressed);
Package package = Package.Open(stream, FileMode.OpenOrCreate, FileAccess.ReadWrite);
IDisposable disposable = package;
disposable.Dispose();

Expected behavior

Dispose should not throw and package should be created equivalently to how it works in .NET Framework.

Actual behavior

Observe System.NotSupportedException with description Memory stream is not expandable. and a stack trace:

System.Private.CoreLib.dll!System.IO.MemoryStream.Capacity.set(int value)	Unknown
System.Private.CoreLib.dll!System.IO.MemoryStream.EnsureCapacity(int value)	Unknown
System.Private.CoreLib.dll!System.IO.MemoryStream.Write(byte[] buffer, int offset, int count)	Unknown
System.IO.Compression.dll!System.IO.Compression.ZipArchiveEntry.WriteCentralDirectoryFileHeader()	Unknown
System.IO.Compression.dll!System.IO.Compression.ZipArchive.WriteFile()	Unknown
System.IO.Compression.dll!System.IO.Compression.ZipArchive.Dispose(bool disposing)	Unknown
System.IO.Compression.dll!System.IO.Compression.ZipArchive.Dispose()	Unknown
System.IO.Packaging.dll!System.IO.Packaging.ZipPackage.Dispose(bool disposing)	Unknown
System.IO.Packaging.dll!System.IO.Packaging.Package.System.IDisposable.Dispose()	Unknown
Tries.dll!Program.Main(string[] args) Line 16	C#

Uncommenting the line that zeroes one general purpose flag bit mitigating the exception.

Regression?

Works properly on .NET 8, and on .NET Framework 4.6.2 and .NET Framework 4.8.

Known Workarounds

No stable workaround is known to us.

Configuration

  • .NET 9.
  • Win 11.
  • x64.
  • Yet, only .NET 9 and above.

Other information

Metadata

Metadata

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions