Skip to content

Commit 44c08b8

Browse files
authored
Change ZipBlocks structs to classes (#113453)
* Change ZipBlocks structs to classes. Update the places where they're used and adjust their nullability rules.
1 parent 2218335 commit 44c08b8

File tree

5 files changed

+117
-109
lines changed

5 files changed

+117
-109
lines changed

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

+4-9
Original file line numberDiff line numberDiff line change
@@ -530,14 +530,10 @@ private void ReadCentralDirectory()
530530
while (continueReadingCentralDirectory
531531
&& currPosition + ZipCentralDirectoryFileHeader.BlockConstantSectionSize < sizedFileBuffer.Length)
532532
{
533-
ZipCentralDirectoryFileHeader currentHeader = default;
534-
535-
continueReadingCentralDirectory = continueReadingCentralDirectory &&
536-
ZipCentralDirectoryFileHeader.TryReadBlock(sizedFileBuffer.Slice(currPosition), _archiveStream,
537-
saveExtraFieldsAndComments, out bytesConsumed, out currentHeader);
538-
539-
if (!continueReadingCentralDirectory)
533+
if (!ZipCentralDirectoryFileHeader.TryReadBlock(sizedFileBuffer.Slice(currPosition), _archiveStream,
534+
saveExtraFieldsAndComments, out bytesConsumed, out ZipCentralDirectoryFileHeader? currentHeader))
540535
{
536+
continueReadingCentralDirectory = false;
541537
break;
542538
}
543539

@@ -662,8 +658,7 @@ private void TryReadZip64EndOfCentralDirectory(ZipEndOfCentralDirectoryBlock eoc
662658
Zip64EndOfCentralDirectoryLocator.FieldLengths.Signature))
663659
{
664660
// use locator to get to Zip64-EOCD
665-
Zip64EndOfCentralDirectoryLocator locator;
666-
bool zip64eocdLocatorProper = Zip64EndOfCentralDirectoryLocator.TryReadBlock(_archiveStream, out locator);
661+
bool zip64eocdLocatorProper = Zip64EndOfCentralDirectoryLocator.TryReadBlock(_archiveStream, out Zip64EndOfCentralDirectoryLocator locator);
667662
Debug.Assert(zip64eocdLocatorProper); // we just found this using the signature finder, so it should be okay
668663

669664
if (locator.OffsetOfZip64EOCD > long.MaxValue)

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

+37-28
Original file line numberDiff line numberDiff line change
@@ -491,24 +491,24 @@ internal void WriteCentralDirectoryFileHeader(bool forceWrite)
491491
Debug.Assert(_fileComment.Length <= ushort.MaxValue);
492492

493493
// decide if we need the Zip64 extra field:
494-
Zip64ExtraField zip64ExtraField = default;
494+
Zip64ExtraField? zip64ExtraField = null;
495495
uint compressedSizeTruncated, uncompressedSizeTruncated, offsetOfLocalHeaderTruncated;
496496

497-
bool zip64Needed = false;
498-
499497
if (AreSizesTooLarge
500498
#if DEBUG_FORCE_ZIP64
501499
|| _archive._forceZip64
502500
#endif
503501
)
504502
{
505-
zip64Needed = true;
506503
compressedSizeTruncated = ZipHelper.Mask32Bit;
507504
uncompressedSizeTruncated = ZipHelper.Mask32Bit;
508505

509506
// If we have one of the sizes, the other must go in there as speced for LH, but not necessarily for CH, but we do it anyways
510-
zip64ExtraField.CompressedSize = _compressedSize;
511-
zip64ExtraField.UncompressedSize = _uncompressedSize;
507+
zip64ExtraField = new()
508+
{
509+
CompressedSize = _compressedSize,
510+
UncompressedSize = _uncompressedSize
511+
};
512512
}
513513
else
514514
{
@@ -523,27 +523,32 @@ internal void WriteCentralDirectoryFileHeader(bool forceWrite)
523523
#endif
524524
)
525525
{
526-
zip64Needed = true;
527526
offsetOfLocalHeaderTruncated = ZipHelper.Mask32Bit;
528527

529528
// If we have one of the sizes, the other must go in there as speced for LH, but not necessarily for CH, but we do it anyways
530-
zip64ExtraField.LocalHeaderOffset = _offsetOfLocalHeader;
529+
zip64ExtraField = new()
530+
{
531+
LocalHeaderOffset = _offsetOfLocalHeader
532+
};
531533
}
532534
else
533535
{
534536
offsetOfLocalHeaderTruncated = (uint)_offsetOfLocalHeader;
535537
}
536538

537-
if (zip64Needed)
539+
if (zip64ExtraField != null)
540+
{
538541
VersionToExtractAtLeast(ZipVersionNeededValues.Zip64);
542+
}
543+
539544

540545
// determine if we can fit zip64 extra field and original extra fields all in
541-
int bigExtraFieldLength = (zip64Needed ? zip64ExtraField.TotalSize : 0)
546+
int bigExtraFieldLength = (zip64ExtraField != null ? zip64ExtraField.TotalSize : 0)
542547
+ (_cdUnknownExtraFields != null ? ZipGenericExtraField.TotalSize(_cdUnknownExtraFields) : 0);
543548
ushort extraFieldLength;
544549
if (bigExtraFieldLength > ushort.MaxValue)
545550
{
546-
extraFieldLength = (ushort)(zip64Needed ? zip64ExtraField.TotalSize : 0);
551+
extraFieldLength = (ushort)(zip64ExtraField != null ? zip64ExtraField.TotalSize : 0);
547552
_cdUnknownExtraFields = null;
548553
}
549554
else
@@ -555,7 +560,7 @@ internal void WriteCentralDirectoryFileHeader(bool forceWrite)
555560
{
556561
long centralDirectoryHeaderLength = ZipCentralDirectoryFileHeader.FieldLocations.DynamicData
557562
+ _storedEntryNameBytes.Length
558-
+ (zip64Needed ? zip64ExtraField.TotalSize : 0)
563+
+ (zip64ExtraField != null ? zip64ExtraField.TotalSize : 0)
559564
+ (_cdUnknownExtraFields != null ? ZipGenericExtraField.TotalSize(_cdUnknownExtraFields) : 0)
560565
+ _fileComment.Length;
561566

@@ -604,14 +609,18 @@ internal void WriteCentralDirectoryFileHeader(bool forceWrite)
604609
_archive.ArchiveStream.Write(cdStaticHeader);
605610
_archive.ArchiveStream.Write(_storedEntryNameBytes);
606611

607-
// write extra fields
608-
if (zip64Needed)
609-
zip64ExtraField.WriteBlock(_archive.ArchiveStream);
612+
// write extra fields, and only write zip64ExtraField if we decided we need it (it's not null)
613+
zip64ExtraField?.WriteBlock(_archive.ArchiveStream);
614+
610615
if (_cdUnknownExtraFields != null)
616+
{
611617
ZipGenericExtraField.WriteAllBlocks(_cdUnknownExtraFields, _archive.ArchiveStream);
618+
}
612619

613620
if (_fileComment.Length > 0)
621+
{
614622
_archive.ArchiveStream.Write(_fileComment);
623+
}
615624
}
616625
}
617626

@@ -908,8 +917,7 @@ private bool WriteLocalFileHeader(bool isEmptyFile, bool forceWrite)
908917
Debug.Assert(_storedEntryNameBytes.Length <= ushort.MaxValue);
909918

910919
// decide if we need the Zip64 extra field:
911-
Zip64ExtraField zip64ExtraField = default;
912-
bool zip64Used = false;
920+
Zip64ExtraField? zip64ExtraField = null;
913921
uint compressedSizeTruncated, uncompressedSizeTruncated;
914922

915923
// save offset
@@ -932,7 +940,6 @@ private bool WriteLocalFileHeader(bool isEmptyFile, bool forceWrite)
932940
if (_archive.Mode == ZipArchiveMode.Create && _archive.ArchiveStream.CanSeek == false)
933941
{
934942
_generalPurposeBitFlag |= BitFlagValues.DataDescriptor;
935-
zip64Used = false;
936943
compressedSizeTruncated = 0;
937944
uncompressedSizeTruncated = 0;
938945
// the crc should not have been set if we are in create mode, but clear it just to be sure
@@ -948,19 +955,20 @@ private bool WriteLocalFileHeader(bool isEmptyFile, bool forceWrite)
948955
#endif
949956
)
950957
{
951-
zip64Used = true;
952958
compressedSizeTruncated = ZipHelper.Mask32Bit;
953959
uncompressedSizeTruncated = ZipHelper.Mask32Bit;
954960

955961
// prepare Zip64 extra field object. If we have one of the sizes, the other must go in there
956-
zip64ExtraField.CompressedSize = _compressedSize;
957-
zip64ExtraField.UncompressedSize = _uncompressedSize;
962+
zip64ExtraField = new()
963+
{
964+
CompressedSize = _compressedSize,
965+
UncompressedSize = _uncompressedSize,
966+
};
958967

959968
VersionToExtractAtLeast(ZipVersionNeededValues.Zip64);
960969
}
961970
else
962971
{
963-
zip64Used = false;
964972
compressedSizeTruncated = (uint)_compressedSize;
965973
uncompressedSizeTruncated = (uint)_uncompressedSize;
966974
}
@@ -971,12 +979,12 @@ private bool WriteLocalFileHeader(bool isEmptyFile, bool forceWrite)
971979
_offsetOfLocalHeader = _archive.ArchiveStream.Position;
972980

973981
// calculate extra field. if zip64 stuff + original extraField aren't going to fit, dump the original extraField, because this is more important
974-
int bigExtraFieldLength = (zip64Used ? zip64ExtraField.TotalSize : 0)
982+
int bigExtraFieldLength = (zip64ExtraField != null ? zip64ExtraField.TotalSize : 0)
975983
+ (_lhUnknownExtraFields != null ? ZipGenericExtraField.TotalSize(_lhUnknownExtraFields) : 0);
976984
ushort extraFieldLength;
977985
if (bigExtraFieldLength > ushort.MaxValue)
978986
{
979-
extraFieldLength = (ushort)(zip64Used ? zip64ExtraField.TotalSize : 0);
987+
extraFieldLength = (ushort)(zip64ExtraField != null ? zip64ExtraField.TotalSize : 0);
980988
_lhUnknownExtraFields = null;
981989
}
982990
else
@@ -990,7 +998,7 @@ private bool WriteLocalFileHeader(bool isEmptyFile, bool forceWrite)
990998
{
991999
_archive.ArchiveStream.Seek(ZipLocalFileHeader.SizeOfLocalHeader + _storedEntryNameBytes.Length, SeekOrigin.Current);
9921000

993-
if (zip64Used)
1001+
if (zip64ExtraField != null)
9941002
{
9951003
_archive.ArchiveStream.Seek(zip64ExtraField.TotalSize, SeekOrigin.Current);
9961004
}
@@ -1018,13 +1026,14 @@ private bool WriteLocalFileHeader(bool isEmptyFile, bool forceWrite)
10181026

10191027
_archive.ArchiveStream.Write(_storedEntryNameBytes);
10201028

1021-
if (zip64Used)
1022-
zip64ExtraField.WriteBlock(_archive.ArchiveStream);
1029+
// Only when handling zip64
1030+
zip64ExtraField?.WriteBlock(_archive.ArchiveStream);
1031+
10231032
if (_lhUnknownExtraFields != null)
10241033
ZipGenericExtraField.WriteAllBlocks(_lhUnknownExtraFields, _archive.ArchiveStream);
10251034
}
10261035

1027-
return zip64Used;
1036+
return zip64ExtraField != null;
10281037
}
10291038

10301039
private void WriteLocalFileHeaderAndDataIfNeeded(bool forceWrite)

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

+8-8
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
namespace System.IO.Compression
55
{
6-
internal partial struct ZipGenericExtraField
6+
internal sealed partial class ZipGenericExtraField
77
{
88
private static class FieldLengths
99
{
@@ -12,7 +12,7 @@ private static class FieldLengths
1212
}
1313
}
1414

15-
internal partial struct Zip64ExtraField
15+
internal sealed partial class Zip64ExtraField
1616
{
1717
internal static class FieldLengths
1818
{
@@ -23,7 +23,7 @@ internal static class FieldLengths
2323
}
2424
}
2525

26-
internal partial struct Zip64EndOfCentralDirectoryLocator
26+
internal sealed partial class Zip64EndOfCentralDirectoryLocator
2727
{
2828
internal static class FieldLengths
2929
{
@@ -34,7 +34,7 @@ internal static class FieldLengths
3434
}
3535
}
3636

37-
internal partial struct Zip64EndOfCentralDirectoryRecord
37+
internal sealed partial class Zip64EndOfCentralDirectoryRecord
3838
{
3939
private static class FieldLengths
4040
{
@@ -67,7 +67,7 @@ internal static class FieldLengths
6767
public const int ExtraFieldLength = sizeof(ushort);
6868
}
6969

70-
internal readonly partial struct ZipDataDescriptor
70+
internal sealed partial class ZipDataDescriptor
7171
{
7272
internal static class FieldLengths
7373
{
@@ -78,7 +78,7 @@ internal static class FieldLengths
7878
}
7979
}
8080

81-
internal readonly partial struct Zip64DataDescriptor
81+
internal sealed partial class Zip64DataDescriptor
8282
{
8383
internal static class FieldLengths
8484
{
@@ -90,7 +90,7 @@ internal static class FieldLengths
9090
}
9191
}
9292

93-
internal partial struct ZipCentralDirectoryFileHeader
93+
internal sealed partial class ZipCentralDirectoryFileHeader
9494
{
9595
internal static class FieldLengths
9696
{
@@ -114,7 +114,7 @@ internal static class FieldLengths
114114
}
115115
}
116116

117-
internal partial struct ZipEndOfCentralDirectoryBlock
117+
internal sealed partial class ZipEndOfCentralDirectoryBlock
118118
{
119119
internal static class FieldLengths
120120
{

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

+8-8
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
namespace System.IO.Compression
55
{
6-
internal partial struct ZipGenericExtraField
6+
internal sealed partial class ZipGenericExtraField
77
{
88
internal static class FieldLocations
99
{
@@ -13,7 +13,7 @@ internal static class FieldLocations
1313
}
1414
}
1515

16-
internal partial struct Zip64ExtraField
16+
internal sealed partial class Zip64ExtraField
1717
{
1818
internal static class FieldLocations
1919
{
@@ -26,7 +26,7 @@ internal static class FieldLocations
2626
}
2727
}
2828

29-
internal partial struct Zip64EndOfCentralDirectoryLocator
29+
internal sealed partial class Zip64EndOfCentralDirectoryLocator
3030
{
3131
private static class FieldLocations
3232
{
@@ -37,7 +37,7 @@ private static class FieldLocations
3737
}
3838
}
3939

40-
internal partial struct Zip64EndOfCentralDirectoryRecord
40+
internal sealed partial class Zip64EndOfCentralDirectoryRecord
4141
{
4242
private static class FieldLocations
4343
{
@@ -71,7 +71,7 @@ internal static class FieldLocations
7171
public static readonly int DynamicData = ExtraFieldLength + FieldLengths.ExtraFieldLength;
7272
}
7373

74-
internal readonly partial struct ZipDataDescriptor
74+
internal sealed partial class ZipDataDescriptor
7575
{
7676
internal static class FieldLocations
7777
{
@@ -82,7 +82,7 @@ internal static class FieldLocations
8282
}
8383
}
8484

85-
internal readonly partial struct Zip64DataDescriptor
85+
internal sealed partial class Zip64DataDescriptor
8686
{
8787
internal static class FieldLocations
8888
{
@@ -94,7 +94,7 @@ internal static class FieldLocations
9494
}
9595
}
9696

97-
internal partial struct ZipCentralDirectoryFileHeader
97+
internal sealed partial class ZipCentralDirectoryFileHeader
9898
{
9999
internal static class FieldLocations
100100
{
@@ -119,7 +119,7 @@ internal static class FieldLocations
119119
}
120120
}
121121

122-
internal partial struct ZipEndOfCentralDirectoryBlock
122+
internal sealed partial class ZipEndOfCentralDirectoryBlock
123123
{
124124
private static class FieldLocations
125125
{

0 commit comments

Comments
 (0)