PKZIP model cleanup

This commit is contained in:
Matt Nadareski
2025-10-30 23:01:55 -04:00
parent 069dab7fba
commit a02d50e61d
20 changed files with 70 additions and 77 deletions

View File

@@ -4,7 +4,7 @@ namespace SabreTools.Data.Models.PKZIP
/// WinZip AES encryption data
/// </summary>
/// <remarks>Header ID = 0x9901</remarks>
/// <see href="https://github.com/adamhathcock/sharpcompress/blob/master/src/SharpCompress/Common/Zip/Headers/LocalEntryHeaderExtraFactory.cs"/>
/// <see href="https://github.com/adamhathcock/sharpcompress/blob/master/src/SharpCompress/Common/Zip/Headers/LocalEntryHeaderExtraFactory.cs"/>
public class AesEncryptionStructure : ExtensibleDataField
{
/// <summary>

View File

@@ -3,7 +3,7 @@ namespace SabreTools.Data.Models.PKZIP
/// <summary>
/// Central directory file header
/// </summary>
/// <see href="https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT"/>
/// <see href="https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT"/>
public class CentralDirectoryFileHeader
{
/// <summary>

View File

@@ -3,7 +3,7 @@ namespace SabreTools.Data.Models.PKZIP
/// <summary>
/// Data descriptor
/// </summary>
/// <see href="https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT"/>
/// <see href="https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT"/>
public class DataDescriptor
{
/// <summary>

View File

@@ -3,7 +3,7 @@ namespace SabreTools.Data.Models.PKZIP
/// <summary>
/// Data descriptor (ZIP64)
/// </summary>
/// <see href="https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT"/>
/// <see href="https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT"/>
public class DataDescriptor64
{
/// <summary>

View File

@@ -5,7 +5,7 @@ namespace SabreTools.Data.Models.PKZIP
/// <summary>
/// Zip64 end of central directory locator
/// </summary>
/// <see href="https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT"/>
/// <see href="https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT"/>
[StructLayout(LayoutKind.Sequential)]
public class EndOfCentralDirectoryLocator64
{

View File

@@ -3,7 +3,7 @@ namespace SabreTools.Data.Models.PKZIP
/// <summary>
/// End of central directory record
/// </summary>
/// <see href="https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT"/>
/// <see href="https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT"/>
public class EndOfCentralDirectoryRecord
{
/// <summary>

View File

@@ -1,7 +1,7 @@
using System;
/// <see href="https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT"/>
/// <see href="https://github.com/adamhathcock/sharpcompress/blob/master/src/SharpCompress/Common/Zip/Headers/LocalEntryHeaderExtraFactory.cs"/>
/// <see href="https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT"/>
/// <see href="https://github.com/adamhathcock/sharpcompress/blob/master/src/SharpCompress/Common/Zip/Headers/LocalEntryHeaderExtraFactory.cs"/>
namespace SabreTools.Data.Models.PKZIP
{
[Flags]
@@ -503,7 +503,7 @@ namespace SabreTools.Data.Models.PKZIP
NoCRC = 0b0000_0000_0000_1000,
/// <summary>
/// Reserved for use with method 8, for enhanced deflating.
/// Reserved for use with method 8, for enhanced deflating.
/// </summary>
EnhancedDeflateReserved = 0b0000_0000_0001_0000,
@@ -992,13 +992,13 @@ namespace SabreTools.Data.Models.PKZIP
Bit2 = 0b0000_0000_0000_0100,
/*
4.4.14.2 The 0x0002 bit of this field indicates, if set, that
a 4 byte variable record length control field precedes each
logical record indicating the length of the record. The
4.4.14.2 The 0x0002 bit of this field indicates, if set, that
a 4 byte variable record length control field precedes each
logical record indicating the length of the record. The
record length control field is stored in little-endian byte
order. This flag is independent of text control characters,
and if used in conjunction with text data, includes any
control characters in the total length of the record. This
order. This flag is independent of text control characters,
and if used in conjunction with text data, includes any
control characters in the total length of the record. This
value is provided for mainframe data transfer support.
*/
}

View File

@@ -4,7 +4,7 @@ namespace SabreTools.Data.Models.PKZIP
/// The unix modified time, last access time, and creation time, if set
/// </summary>
/// <remarks>Header ID = 0x5455</remarks>
/// <see href="https://github.com/adamhathcock/sharpcompress/blob/master/src/SharpCompress/Common/Zip/Headers/LocalEntryHeaderExtraFactory.cs"/>
/// <see href="https://github.com/adamhathcock/sharpcompress/blob/master/src/SharpCompress/Common/Zip/Headers/LocalEntryHeaderExtraFactory.cs"/>
public class ExtendedTimestampExtraField : ExtensibleDataField
{
/// <summary>
@@ -15,19 +15,19 @@ namespace SabreTools.Data.Models.PKZIP
/// <summary>
/// Last modified time
/// </summary>
/// <remarks>Only available when <see cref="RecordedTimeFlag.LastModified"/> is set</remarks>
/// <remarks>Only available when <see cref="RecordedTimeFlag.LastModified"/> is set</remarks>
public uint? LastModified { get; set; }
/// <summary>
/// Last accessed time
/// </summary>
/// <remarks>Only available when <see cref="RecordedTimeFlag.LastAccessed"/> is set</remarks>
/// <remarks>Only available when <see cref="RecordedTimeFlag.LastAccessed"/> is set</remarks>
public uint? LastAccessed { get; set; }
/// <summary>
/// Created on time
/// </summary>
/// <remarks>Only available when <see cref="RecordedTimeFlag.Created"/> is set</remarks>
/// <remarks>Only available when <see cref="RecordedTimeFlag.Created"/> is set</remarks>
public uint? CreatedOn { get; set; }
}
}

View File

@@ -6,7 +6,7 @@ namespace SabreTools.Data.Models.PKZIP
/// files, the following structure MUST be used for all
/// programs storing data in this field
/// </summary>
/// <see href="https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT"/>
/// <see href="https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT"/>
public abstract class ExtensibleDataField
{
/// <summary>

View File

@@ -3,20 +3,20 @@ namespace SabreTools.Data.Models.PKZIP
/// <summary>
/// Stores the UTF-8 version of the file comment as stored in the
/// central directory header. (Last Revision 20070912)
///
///
/// Currently Version is set to the number 1. If there is a need
/// to change this field, the version will be incremented. Changes
/// MAY NOT be backward compatible so this extra field SHOULD NOT be
/// used if the version is not recognized.
///
///
/// The ComCRC32 is the standard zip CRC32 checksum of the File Comment
/// field in the central directory header. This is used to verify that
/// the comment field has not changed since the Unicode Comment extra field
/// was created. This can happen if a utility changes the File Comment
/// field but does not update the UTF-8 Comment extra field. If the CRC
/// check fails, this Unicode Comment extra field SHOULD be ignored and
/// was created. This can happen if a utility changes the File Comment
/// field but does not update the UTF-8 Comment extra field. If the CRC
/// check fails, this Unicode Comment extra field SHOULD be ignored and
/// the File Comment field in the header SHOULD be used instead.
///
///
/// The UnicodeCom field is the UTF-8 version of the File Comment field
/// in the header. As UnicodeCom is defined to be UTF-8, no UTF-8 byte
/// order mark (BOM) is used. The length of this field is determined by
@@ -33,7 +33,7 @@ namespace SabreTools.Data.Models.PKZIP
/// Directory Header for a file.
/// </summary>
/// <remarks>Header ID = 0x6375</remarks>
/// <see href="https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT"/>
/// <see href="https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT"/>
public class InfoZIPUnicodeCommentExtraField : ExtensibleDataField
{
/// <summary>
@@ -49,6 +49,6 @@ namespace SabreTools.Data.Models.PKZIP
/// <summary>
/// UTF-8 version of the entry comment
/// </summary>
public string? UnicodeCom { get; set; }
public string UnicodeCom { get; set; }
}
}

View File

@@ -3,12 +3,12 @@ namespace SabreTools.Data.Models.PKZIP
/// <summary>
/// Stores the UTF-8 version of the file name field as stored in the
/// local header and central directory header. (Last Revision 20070912)
///
///
/// Currently Version is set to the number 1. If there is a need
/// to change this field, the version will be incremented. Changes
/// MAY NOT be backward compatible so this extra field SHOULD NOT be
/// used if the version is not recognized.
///
///
/// The NameCRC32 is the standard zip CRC32 checksum of the File Name
/// field in the header. This is used to verify that the header
/// File Name field has not changed since the Unicode Path extra field
@@ -16,7 +16,7 @@ namespace SabreTools.Data.Models.PKZIP
/// does not update the UTF-8 path extra field. If the CRC check fails,
/// this UTF-8 Path Extra Field SHOULD be ignored and the File Name field
/// in the header SHOULD be used instead.
///
///
/// The UnicodeName is the UTF-8 version of the contents of the File Name
/// field in the header. As UnicodeName is defined to be UTF-8, no UTF-8
/// byte order mark (BOM) is used. The length of this field is determined
@@ -33,7 +33,7 @@ namespace SabreTools.Data.Models.PKZIP
/// Directory Header for a file.
/// </summary>
/// <remarks>Header ID = 0x7075</remarks>
/// <see href="https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT"/>
/// <see href="https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT"/>
public class InfoZIPUnicodePathExtraField : ExtensibleDataField
{
/// <summary>
@@ -49,6 +49,6 @@ namespace SabreTools.Data.Models.PKZIP
/// <summary>
/// UTF-8 version of the entry File Name
/// </summary>
public string? UnicodeName { get; set; }
public string UnicodeName { get; set; }
}
}

View File

@@ -10,7 +10,7 @@ namespace SabreTools.Data.Models.PKZIP
/// <summary>
/// Local file header
/// </summary>
public LocalFileHeader? LocalFileHeader { get; set; }
public LocalFileHeader LocalFileHeader { get; set; }
/// <summary>
/// Encryption header

View File

@@ -3,8 +3,8 @@ namespace SabreTools.Data.Models.PKZIP
/// <summary>
/// PKZIP local file header
/// </summary>
/// <see href="https://petlibrary.tripod.com/ZIP.HTM"/>
/// <see href="https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT"/>
/// <see href="https://petlibrary.tripod.com/ZIP.HTM"/>
/// <see href="https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT"/>
public class LocalFileHeader
{
/// <summary>

View File

@@ -6,7 +6,7 @@ namespace SabreTools.Data.Models.PKZIP
/// and Ctime values MAY be used on any WIN32 system.)
/// </summary>
/// <remarks>Header ID = 0x000A</remarks>
/// <see href="https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT"/>
/// <see href="https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT"/>
public class NTFSExtraField : ExtensibleDataField
{
/// <summary>
@@ -17,6 +17,6 @@ namespace SabreTools.Data.Models.PKZIP
/// <summary>
/// NTFS attribute tags
/// </summary>
public TagSizeVar[]? TagSizeVars { get; set; }
public TagSizeVar[] TagSizeVars { get; set; }
}
}

View File

@@ -3,24 +3,24 @@ namespace SabreTools.Data.Models.PKZIP
/// <summary>
/// The following is the layout of the OpenVMS attributes
/// "extra" block.
///
///
/// OpenVMS Extra Field Rules:
///
///
/// - There will be one or more attributes present, which
/// will each be preceded by the above TagX & SizeX values.
/// These values are identical to the ATR$C_XXXX and ATR$S_XXXX
/// constants which are defined in ATR.H under OpenVMS C. Neither
/// of these values will ever be zero.
///
///
/// - No word alignment or padding is performed.
///
///
/// - A well-behaved PKZIP/OpenVMS program SHOULD NOT produce
/// more than one sub-block with the same TagX value. Also, there MUST
/// NOT be more than one "extra" block of type 0x000c in a particular
/// directory record.
/// </summary>
/// <remarks>Header ID = 0x000C</remarks>
/// <see href="https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT"/>
/// <see href="https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT"/>
public class OpenVMSExtraField : ExtensibleDataField
{
/// <summary>
@@ -31,6 +31,6 @@ namespace SabreTools.Data.Models.PKZIP
/// <summary>
/// OpenVMS attribute tags
/// </summary>
public TagSizeVar[]? TagSizeVars { get; set; }
public TagSizeVar[] TagSizeVars { get; set; }
}
}

View File

@@ -3,7 +3,7 @@ namespace SabreTools.Data.Models.PKZIP
/// <summary>
/// The following is the layout of the Patch Descriptor
/// "extra" block.
///
///
/// Patch support is provided by PKPatchMaker(tm) technology
/// and is covered under U.S. Patents and Patents Pending. The use or
/// implementation in a product of certain technological aspects set
@@ -14,7 +14,7 @@ namespace SabreTools.Data.Models.PKZIP
/// information.
/// </summary>
/// <remarks>Header ID = 0x000F</remarks>
/// <see href="https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT"/>
/// <see href="https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT"/>
public class PatchDescriptorExtraField : ExtensibleDataField
{
/// <summary>

View File

@@ -1,12 +1,12 @@
namespace SabreTools.Data.Models.PKZIP
{
/// <remarks>Header ID = 0x0018</remarks>
/// <see href="https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT"/>
/// <see href="https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT"/>
public class RecordManagementControls : ExtensibleDataField
{
/// <summary>
/// Record management control attribute tags
/// </summary>
public TagSizeVar[]? TagSizeVars { get; set; }
public TagSizeVar[] TagSizeVars { get; set; }
}
}

View File

@@ -1,24 +1,24 @@
namespace SabreTools.Data.Models.PKZIP
{
/// <summary>
/// The following is the layout of the zip64 extended
/// The following is the layout of the zip64 extended
/// information "extra" block. If one of the size or
/// offset fields in the Local or Central directory
/// record is too small to hold the required data,
/// a Zip64 extended information record is created.
/// The order of the fields in the zip64 extended
/// The order of the fields in the zip64 extended
/// information record is fixed, but the fields MUST
/// only appear if the corresponding Local or Central
/// directory record field is set to 0xFFFF or 0xFFFFFFFF.
///
///
/// This entry in the Local header MUST include BOTH original
/// and compressed file size fields. If encrypting the
/// and compressed file size fields. If encrypting the
/// central directory and bit 13 of the general purpose bit
/// flag is set indicating masking, the value stored in the
/// Local Header for the original file size will be zero.
/// </summary>
/// <remarks>Header ID = 0x0001</remarks>
/// <see href="https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT"/>
/// <see href="https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT"/>
public class Zip64ExtendedInformationExtraField : ExtensibleDataField
{
/// <summary>

View File

@@ -3,12 +3,12 @@ namespace SabreTools.Data.Models.PKZIP
/// <summary>
/// The following is the layout of a shortened variant of the
/// ZipIt extra block for Macintosh used only for directory
/// entries. This variant is used by ZipIt 1.3.5 and newer to
/// entries. This variant is used by ZipIt 1.3.5 and newer to
/// save some optional Mac-specific information about directories.
/// The local-header and central-header versions are identical.
/// </summary>
/// <remarks>Header ID = 0x2805</remarks>
/// <see href="https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT"/>
/// <see href="https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT"/>
public class ZipItMacintoshShortDirectoryExtraField : ExtensibleDataField
{
/// <summary>

View File

@@ -53,26 +53,19 @@ namespace SabreTools.Serialization.Wrappers
#region Local File Header
var localFileHeader = localFile.LocalFileHeader;
if (localFileHeader == null)
{
builder.AppendLine(" [Local File Header] [NULL]");
}
else
{
builder.AppendLine(localFileHeader.Signature, " [Local File Header] Signature");
builder.AppendLine(localFileHeader.Version, " [Local File Header] Version");
builder.AppendLine($" [Local File Header] Flags: {localFileHeader.Flags} (0x{localFileHeader.Flags:X})");
builder.AppendLine($" [Local File Header] Compression method: {localFileHeader.CompressionMethod} (0x{localFileHeader.CompressionMethod:X})");
builder.AppendLine(localFileHeader.LastModifedFileTime, " [Local File Header] Last modified file time"); // TODO: Parse from MS-DOS
builder.AppendLine(localFileHeader.LastModifiedFileDate, " [Local File Header] Last modified file date"); // TODO: Parse from MS-DOS
builder.AppendLine(localFileHeader.CRC32, " [Local File Header] CRC-32");
builder.AppendLine(localFileHeader.CompressedSize, " [Local File Header] Compressed size");
builder.AppendLine(localFileHeader.UncompressedSize, " [Local File Header] Uncompressed size");
builder.AppendLine(localFileHeader.FileNameLength, " [Local File Header] File name length");
builder.AppendLine(localFileHeader.ExtraFieldLength, " [Local File Header] Extra field length");
builder.AppendLine(localFileHeader.FileName, " [Local File Header] File name");
Print(builder, " [Local File Header] Extra Fields", localFileHeader.ExtraFields);
}
builder.AppendLine(localFileHeader.Signature, " [Local File Header] Signature");
builder.AppendLine(localFileHeader.Version, " [Local File Header] Version");
builder.AppendLine($" [Local File Header] Flags: {localFileHeader.Flags} (0x{localFileHeader.Flags:X})");
builder.AppendLine($" [Local File Header] Compression method: {localFileHeader.CompressionMethod} (0x{localFileHeader.CompressionMethod:X})");
builder.AppendLine(localFileHeader.LastModifedFileTime, " [Local File Header] Last modified file time"); // TODO: Parse from MS-DOS
builder.AppendLine(localFileHeader.LastModifiedFileDate, " [Local File Header] Last modified file date"); // TODO: Parse from MS-DOS
builder.AppendLine(localFileHeader.CRC32, " [Local File Header] CRC-32");
builder.AppendLine(localFileHeader.CompressedSize, " [Local File Header] Compressed size");
builder.AppendLine(localFileHeader.UncompressedSize, " [Local File Header] Uncompressed size");
builder.AppendLine(localFileHeader.FileNameLength, " [Local File Header] File name length");
builder.AppendLine(localFileHeader.ExtraFieldLength, " [Local File Header] Extra field length");
builder.AppendLine(localFileHeader.FileName, " [Local File Header] File name");
Print(builder, " [Local File Header] Extra Fields", localFileHeader.ExtraFields);
#endregion
@@ -485,11 +478,11 @@ namespace SabreTools.Serialization.Wrappers
builder.AppendLine(field.Data, " Data");
}
private static void Print(StringBuilder builder, TagSizeVar[]? tuples)
private static void Print(StringBuilder builder, TagSizeVar[] tuples)
{
builder.AppendLine(" Tag/Size/Var Tuples:");
builder.AppendLine(" -------------------------");
if (tuples == null)
if (tuples.Length == 0)
{
builder.AppendLine(" No tuples");
return;