Skip to content

Commit 0b6e6fe

Browse files
committed
src: Fix NullReferenceException and static initialization issues in some cases due to mixing of static readonly and consts in some block types by setting Signature value to the fixed number 4, which will most likely never change.
1 parent 6afdb55 commit 0b6e6fe

File tree

3 files changed

+78
-64
lines changed

3 files changed

+78
-64
lines changed

src/libraries/System.IO.Compression/src/System/IO/Compression/ZipBlocks.FieldLengths.cs

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,9 @@ internal sealed partial class Zip64EndOfCentralDirectoryLocator
2727
{
2828
internal static class FieldLengths
2929
{
30-
public static readonly int Signature = SignatureConstantBytes.Length;
30+
// Must match the signature constant bytes length, but should stay a const int or sometimes
31+
// static initialization of FieldLengths and NullReferenceException occurs.
32+
public const int Signature = 4;
3133
public const int NumberOfDiskWithZip64EOCD = sizeof(uint);
3234
public const int OffsetOfZip64EOCD = sizeof(ulong);
3335
public const int TotalNumberOfDisks = sizeof(uint);
@@ -38,7 +40,9 @@ internal sealed partial class Zip64EndOfCentralDirectoryRecord
3840
{
3941
private static class FieldLengths
4042
{
41-
public static readonly int Signature = SignatureConstantBytes.Length;
43+
// Must match the signature constant bytes length, but should stay a const int or sometimes
44+
// static initialization of FieldLengths and NullReferenceException occurs.
45+
public const int Signature = 4;
4246
public const int SizeOfThisRecord = sizeof(ulong);
4347
public const int VersionMadeBy = sizeof(ushort);
4448
public const int VersionNeededToExtract = sizeof(ushort);
@@ -55,7 +59,9 @@ internal readonly partial struct ZipLocalFileHeader
5559
{
5660
internal static class FieldLengths
5761
{
58-
public static readonly int Signature = SignatureConstantBytes.Length;
62+
// Must match the signature constant bytes length, but should stay a const int or sometimes
63+
// static initialization of FieldLengths and NullReferenceException occurs.
64+
public const int Signature = 4;
5965
public const int VersionNeededToExtract = sizeof(ushort);
6066
public const int GeneralPurposeBitFlags = sizeof(ushort);
6167
public const int CompressionMethod = sizeof(ushort);
@@ -71,7 +77,9 @@ internal sealed partial class ZipDataDescriptor
7177
{
7278
internal static class FieldLengths
7379
{
74-
public static readonly int Signature = DataDescriptorSignatureConstantBytes.Length;
80+
// Must match the data descriptor signature constant bytes length, but should stay a const int or sometimes
81+
// static initialization of FieldLengths and NullReferenceException occurs.
82+
public const int Signature = 4;
7583
public const int Crc32 = sizeof(uint);
7684
public const int CompressedSize = sizeof(uint);
7785
public const int UncompressedSize = sizeof(uint);
@@ -82,7 +90,9 @@ internal sealed partial class Zip64DataDescriptor
8290
{
8391
internal static class FieldLengths
8492
{
85-
public static readonly int Signature = DataDescriptorSignatureConstantBytes.Length;
93+
// Must match the data descriptor signature constant bytes length, but should stay a const int or sometimes
94+
// static initialization of FieldLengths and NullReferenceException occurs.
95+
public const int Signature = 4;
8696
public const int Crc32 = sizeof(uint);
8797
public const int CompressedSize = sizeof(long);
8898
public const int UncompressedSize = sizeof(long);
@@ -94,7 +104,9 @@ internal sealed partial class ZipCentralDirectoryFileHeader
94104
{
95105
internal static class FieldLengths
96106
{
97-
public static readonly int Signature = SignatureConstantBytes.Length;
107+
// Must match the signature constant bytes length, but should stay a const int or sometimes
108+
// static initialization of FieldLengths and NullReferenceException occurs.
109+
public const int Signature = 4;
98110
public const int VersionMadeBySpecification = sizeof(byte);
99111
public const int VersionMadeByCompatibility = sizeof(byte);
100112
public const int VersionNeededToExtract = sizeof(ushort);
@@ -118,7 +130,9 @@ internal sealed partial class ZipEndOfCentralDirectoryBlock
118130
{
119131
internal static class FieldLengths
120132
{
121-
public static readonly int Signature = SignatureConstantBytes.Length;
133+
// Must match the signature constant bytes length, but should stay a const int or sometimes
134+
// static initialization of FieldLengths and NullReferenceException occurs.
135+
public const int Signature = 4;
122136
public const int NumberOfThisDisk = sizeof(ushort);
123137
public const int NumberOfTheDiskWithTheStartOfTheCentralDirectory = sizeof(ushort);
124138
public const int NumberOfEntriesInTheCentralDirectoryOnThisDisk = sizeof(ushort);

src/libraries/System.IO.Compression/src/System/IO/Compression/ZipBlocks.FieldLocations.cs

Lines changed: 53 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,9 @@ internal sealed partial class Zip64EndOfCentralDirectoryLocator
3131
private static class FieldLocations
3232
{
3333
public const int Signature = 0;
34-
public static readonly int NumberOfDiskWithZip64EOCD = Signature + FieldLengths.Signature;
35-
public static readonly int OffsetOfZip64EOCD = NumberOfDiskWithZip64EOCD + FieldLengths.NumberOfDiskWithZip64EOCD;
36-
public static readonly int TotalNumberOfDisks = OffsetOfZip64EOCD + FieldLengths.OffsetOfZip64EOCD;
34+
public const int NumberOfDiskWithZip64EOCD = Signature + FieldLengths.Signature;
35+
public const int OffsetOfZip64EOCD = NumberOfDiskWithZip64EOCD + FieldLengths.NumberOfDiskWithZip64EOCD;
36+
public const int TotalNumberOfDisks = OffsetOfZip64EOCD + FieldLengths.OffsetOfZip64EOCD;
3737
}
3838
}
3939

@@ -42,15 +42,15 @@ internal sealed partial class Zip64EndOfCentralDirectoryRecord
4242
private static class FieldLocations
4343
{
4444
public const int Signature = 0;
45-
public static readonly int SizeOfThisRecord = Signature + FieldLengths.Signature;
46-
public static readonly int VersionMadeBy = SizeOfThisRecord + FieldLengths.SizeOfThisRecord;
47-
public static readonly int VersionNeededToExtract = VersionMadeBy + FieldLengths.VersionMadeBy;
48-
public static readonly int NumberOfThisDisk = VersionNeededToExtract + FieldLengths.VersionNeededToExtract;
49-
public static readonly int NumberOfDiskWithStartOfCD = NumberOfThisDisk + FieldLengths.NumberOfThisDisk;
50-
public static readonly int NumberOfEntriesOnThisDisk = NumberOfDiskWithStartOfCD + FieldLengths.NumberOfDiskWithStartOfCD;
51-
public static readonly int NumberOfEntriesTotal = NumberOfEntriesOnThisDisk + FieldLengths.NumberOfEntriesOnThisDisk;
52-
public static readonly int SizeOfCentralDirectory = NumberOfEntriesTotal + FieldLengths.NumberOfEntriesTotal;
53-
public static readonly int OffsetOfCentralDirectory = SizeOfCentralDirectory + FieldLengths.SizeOfCentralDirectory;
45+
public const int SizeOfThisRecord = Signature + FieldLengths.Signature;
46+
public const int VersionMadeBy = SizeOfThisRecord + FieldLengths.SizeOfThisRecord;
47+
public const int VersionNeededToExtract = VersionMadeBy + FieldLengths.VersionMadeBy;
48+
public const int NumberOfThisDisk = VersionNeededToExtract + FieldLengths.VersionNeededToExtract;
49+
public const int NumberOfDiskWithStartOfCD = NumberOfThisDisk + FieldLengths.NumberOfThisDisk;
50+
public const int NumberOfEntriesOnThisDisk = NumberOfDiskWithStartOfCD + FieldLengths.NumberOfDiskWithStartOfCD;
51+
public const int NumberOfEntriesTotal = NumberOfEntriesOnThisDisk + FieldLengths.NumberOfEntriesOnThisDisk;
52+
public const int SizeOfCentralDirectory = NumberOfEntriesTotal + FieldLengths.NumberOfEntriesTotal;
53+
public const int OffsetOfCentralDirectory = SizeOfCentralDirectory + FieldLengths.SizeOfCentralDirectory;
5454
}
5555
}
5656

@@ -59,26 +59,26 @@ internal readonly partial struct ZipLocalFileHeader
5959
internal static class FieldLocations
6060
{
6161
public const int Signature = 0;
62-
public static readonly int VersionNeededToExtract = Signature + FieldLengths.Signature;
63-
public static readonly int GeneralPurposeBitFlags = VersionNeededToExtract + FieldLengths.VersionNeededToExtract;
64-
public static readonly int CompressionMethod = GeneralPurposeBitFlags + FieldLengths.GeneralPurposeBitFlags;
65-
public static readonly int LastModified = CompressionMethod + FieldLengths.CompressionMethod;
66-
public static readonly int Crc32 = LastModified + FieldLengths.LastModified;
67-
public static readonly int CompressedSize = Crc32 + FieldLengths.Crc32;
68-
public static readonly int UncompressedSize = CompressedSize + FieldLengths.CompressedSize;
69-
public static readonly int FilenameLength = UncompressedSize + FieldLengths.UncompressedSize;
70-
public static readonly int ExtraFieldLength = FilenameLength + FieldLengths.FilenameLength;
71-
public static readonly int DynamicData = ExtraFieldLength + FieldLengths.ExtraFieldLength;
62+
public const int VersionNeededToExtract = Signature + FieldLengths.Signature;
63+
public const int GeneralPurposeBitFlags = VersionNeededToExtract + FieldLengths.VersionNeededToExtract;
64+
public const int CompressionMethod = GeneralPurposeBitFlags + FieldLengths.GeneralPurposeBitFlags;
65+
public const int LastModified = CompressionMethod + FieldLengths.CompressionMethod;
66+
public const int Crc32 = LastModified + FieldLengths.LastModified;
67+
public const int CompressedSize = Crc32 + FieldLengths.Crc32;
68+
public const int UncompressedSize = CompressedSize + FieldLengths.CompressedSize;
69+
public const int FilenameLength = UncompressedSize + FieldLengths.UncompressedSize;
70+
public const int ExtraFieldLength = FilenameLength + FieldLengths.FilenameLength;
71+
public const int DynamicData = ExtraFieldLength + FieldLengths.ExtraFieldLength;
7272
}
7373

7474
internal sealed partial class ZipDataDescriptor
7575
{
7676
internal static class FieldLocations
7777
{
7878
public const int Signature = 0;
79-
public static readonly int Crc32 = Signature + FieldLengths.Signature;
80-
public static readonly int CompressedSize = Crc32 + FieldLengths.Crc32;
81-
public static readonly int UncompressedSize = CompressedSize + FieldLengths.CompressedSize;
79+
public const int Crc32 = Signature + FieldLengths.Signature;
80+
public const int CompressedSize = Crc32 + FieldLengths.Crc32;
81+
public const int UncompressedSize = CompressedSize + FieldLengths.CompressedSize;
8282
}
8383
}
8484

@@ -87,9 +87,9 @@ internal sealed partial class Zip64DataDescriptor
8787
internal static class FieldLocations
8888
{
8989
public const int Signature = 0;
90-
public static readonly int Crc32 = Signature + FieldLengths.Signature;
91-
public static readonly int CompressedSize = Crc32 + FieldLengths.Crc32;
92-
public static readonly int UncompressedSize = CompressedSize + FieldLengths.CompressedSize;
90+
public const int Crc32 = Signature + FieldLengths.Signature;
91+
public const int CompressedSize = Crc32 + FieldLengths.Crc32;
92+
public const int UncompressedSize = CompressedSize + FieldLengths.CompressedSize;
9393
}
9494
}
9595
}
@@ -99,23 +99,23 @@ internal sealed partial class ZipCentralDirectoryFileHeader
9999
internal static class FieldLocations
100100
{
101101
public const int Signature = 0;
102-
public static readonly int VersionMadeBySpecification = Signature + FieldLengths.Signature;
103-
public static readonly int VersionMadeByCompatibility = VersionMadeBySpecification + FieldLengths.VersionMadeBySpecification;
104-
public static readonly int VersionNeededToExtract = VersionMadeByCompatibility + FieldLengths.VersionMadeByCompatibility;
105-
public static readonly int GeneralPurposeBitFlags = VersionNeededToExtract + FieldLengths.VersionNeededToExtract;
106-
public static readonly int CompressionMethod = GeneralPurposeBitFlags + FieldLengths.GeneralPurposeBitFlags;
107-
public static readonly int LastModified = CompressionMethod + FieldLengths.CompressionMethod;
108-
public static readonly int Crc32 = LastModified + FieldLengths.LastModified;
109-
public static readonly int CompressedSize = Crc32 + FieldLengths.Crc32;
110-
public static readonly int UncompressedSize = CompressedSize + FieldLengths.CompressedSize;
111-
public static readonly int FilenameLength = UncompressedSize + FieldLengths.UncompressedSize;
112-
public static readonly int ExtraFieldLength = FilenameLength + FieldLengths.FilenameLength;
113-
public static readonly int FileCommentLength = ExtraFieldLength + FieldLengths.ExtraFieldLength;
114-
public static readonly int DiskNumberStart = FileCommentLength + FieldLengths.FileCommentLength;
115-
public static readonly int InternalFileAttributes = DiskNumberStart + FieldLengths.DiskNumberStart;
116-
public static readonly int ExternalFileAttributes = InternalFileAttributes + FieldLengths.InternalFileAttributes;
117-
public static readonly int RelativeOffsetOfLocalHeader = ExternalFileAttributes + FieldLengths.ExternalFileAttributes;
118-
public static readonly int DynamicData = RelativeOffsetOfLocalHeader + FieldLengths.RelativeOffsetOfLocalHeader;
102+
public const int VersionMadeBySpecification = Signature + FieldLengths.Signature;
103+
public const int VersionMadeByCompatibility = VersionMadeBySpecification + FieldLengths.VersionMadeBySpecification;
104+
public const int VersionNeededToExtract = VersionMadeByCompatibility + FieldLengths.VersionMadeByCompatibility;
105+
public const int GeneralPurposeBitFlags = VersionNeededToExtract + FieldLengths.VersionNeededToExtract;
106+
public const int CompressionMethod = GeneralPurposeBitFlags + FieldLengths.GeneralPurposeBitFlags;
107+
public const int LastModified = CompressionMethod + FieldLengths.CompressionMethod;
108+
public const int Crc32 = LastModified + FieldLengths.LastModified;
109+
public const int CompressedSize = Crc32 + FieldLengths.Crc32;
110+
public const int UncompressedSize = CompressedSize + FieldLengths.CompressedSize;
111+
public const int FilenameLength = UncompressedSize + FieldLengths.UncompressedSize;
112+
public const int ExtraFieldLength = FilenameLength + FieldLengths.FilenameLength;
113+
public const int FileCommentLength = ExtraFieldLength + FieldLengths.ExtraFieldLength;
114+
public const int DiskNumberStart = FileCommentLength + FieldLengths.FileCommentLength;
115+
public const int InternalFileAttributes = DiskNumberStart + FieldLengths.DiskNumberStart;
116+
public const int ExternalFileAttributes = InternalFileAttributes + FieldLengths.InternalFileAttributes;
117+
public const int RelativeOffsetOfLocalHeader = ExternalFileAttributes + FieldLengths.ExternalFileAttributes;
118+
public const int DynamicData = RelativeOffsetOfLocalHeader + FieldLengths.RelativeOffsetOfLocalHeader;
119119
}
120120
}
121121

@@ -124,14 +124,14 @@ internal sealed partial class ZipEndOfCentralDirectoryBlock
124124
private static class FieldLocations
125125
{
126126
public const int Signature = 0;
127-
public static readonly int NumberOfThisDisk = Signature + FieldLengths.Signature;
128-
public static readonly int NumberOfTheDiskWithTheStartOfTheCentralDirectory = NumberOfThisDisk + FieldLengths.NumberOfThisDisk;
129-
public static readonly int NumberOfEntriesInTheCentralDirectoryOnThisDisk = NumberOfTheDiskWithTheStartOfTheCentralDirectory + FieldLengths.NumberOfTheDiskWithTheStartOfTheCentralDirectory;
130-
public static readonly int NumberOfEntriesInTheCentralDirectory = NumberOfEntriesInTheCentralDirectoryOnThisDisk + FieldLengths.NumberOfEntriesInTheCentralDirectoryOnThisDisk;
131-
public static readonly int SizeOfCentralDirectory = NumberOfEntriesInTheCentralDirectory + FieldLengths.NumberOfEntriesInTheCentralDirectory;
132-
public static readonly int OffsetOfStartOfCentralDirectoryWithRespectToTheStartingDiskNumber = SizeOfCentralDirectory + FieldLengths.SizeOfCentralDirectory;
133-
public static readonly int ArchiveCommentLength = OffsetOfStartOfCentralDirectoryWithRespectToTheStartingDiskNumber + FieldLengths.OffsetOfStartOfCentralDirectoryWithRespectToTheStartingDiskNumber;
134-
public static readonly int DynamicData = ArchiveCommentLength + FieldLengths.ArchiveCommentLength;
127+
public const int NumberOfThisDisk = Signature + FieldLengths.Signature;
128+
public const int NumberOfTheDiskWithTheStartOfTheCentralDirectory = NumberOfThisDisk + FieldLengths.NumberOfThisDisk;
129+
public const int NumberOfEntriesInTheCentralDirectoryOnThisDisk = NumberOfTheDiskWithTheStartOfTheCentralDirectory + FieldLengths.NumberOfTheDiskWithTheStartOfTheCentralDirectory;
130+
public const int NumberOfEntriesInTheCentralDirectory = NumberOfEntriesInTheCentralDirectoryOnThisDisk + FieldLengths.NumberOfEntriesInTheCentralDirectoryOnThisDisk;
131+
public const int SizeOfCentralDirectory = NumberOfEntriesInTheCentralDirectory + FieldLengths.NumberOfEntriesInTheCentralDirectory;
132+
public const int OffsetOfStartOfCentralDirectoryWithRespectToTheStartingDiskNumber = SizeOfCentralDirectory + FieldLengths.SizeOfCentralDirectory;
133+
public const int ArchiveCommentLength = OffsetOfStartOfCentralDirectoryWithRespectToTheStartingDiskNumber + FieldLengths.OffsetOfStartOfCentralDirectoryWithRespectToTheStartingDiskNumber;
134+
public const int DynamicData = ArchiveCommentLength + FieldLengths.ArchiveCommentLength;
135135
}
136136
}
137137
}

src/libraries/System.IO.Compression/src/System/IO/Compression/ZipBlocks.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -409,8 +409,8 @@ internal sealed partial class Zip64EndOfCentralDirectoryLocator
409409
// ZIP files store values in little endian, so this is reversed.
410410
public static readonly byte[] SignatureConstantBytes = [0x50, 0x4B, 0x06, 0x07];
411411

412-
public static readonly int TotalSize = FieldLocations.TotalNumberOfDisks + FieldLengths.TotalNumberOfDisks;
413-
public static readonly int SizeOfBlockWithoutSignature = TotalSize - FieldLengths.Signature;
412+
public const int TotalSize = FieldLocations.TotalNumberOfDisks + FieldLengths.TotalNumberOfDisks;
413+
public const int SizeOfBlockWithoutSignature = TotalSize - FieldLengths.Signature;
414414

415415
public uint NumberOfDiskWithZip64EOCD;
416416
public ulong OffsetOfZip64EOCD;
@@ -850,9 +850,9 @@ internal sealed partial class ZipEndOfCentralDirectoryBlock
850850
public static readonly byte[] SignatureConstantBytes = [0x50, 0x4B, 0x05, 0x06];
851851

852852
// This also assumes a zero-length comment.
853-
public static readonly int TotalSize = FieldLocations.ArchiveCommentLength + FieldLengths.ArchiveCommentLength;
853+
public const int TotalSize = FieldLocations.ArchiveCommentLength + FieldLengths.ArchiveCommentLength;
854854
// These are the minimum possible size, assuming the zip file comments variable section is empty
855-
public static readonly int SizeOfBlockWithoutSignature = TotalSize - FieldLengths.Signature;
855+
public const int SizeOfBlockWithoutSignature = TotalSize - FieldLengths.Signature;
856856

857857
// The end of central directory can have a variable size zip file comment at the end, but its max length can be 64K
858858
// The Zip File Format Specification does not explicitly mention a max size for this field, but we are assuming this

0 commit comments

Comments
 (0)