Perform more deserializer cleanup

This commit is contained in:
Matt Nadareski
2024-11-27 20:30:31 -05:00
parent 4a3741312e
commit 6b503a0733
9 changed files with 52 additions and 219 deletions

View File

@@ -19,9 +19,6 @@ namespace SabreTools.Serialization.Deserializers
if (data.Position < 0 || data.Position >= data.Length)
return null;
// Cache the current offset
int initialOffset = (int)data.Position;
// Create a new archive to fill
var archive = new Archive();
@@ -45,11 +42,7 @@ namespace SabreTools.Serialization.Deserializers
// Read all entries in turn
for (int i = 0; i < header.Files; i++)
{
var file = ParseFileEntry(data);
if (file == null)
return null;
files[i] = file;
files[i] = ParseFileEntry(data);
}
// Set the files
@@ -65,7 +58,7 @@ namespace SabreTools.Serialization.Deserializers
/// </summary>
/// <param name="data">Stream to parse</param>
/// <returns>Filled file entry on success, null on error</returns>
private static FileEntry? ParseFileEntry(Stream data)
private static FileEntry ParseFileEntry(Stream data)
{
var fileEntry = new FileEntry();

View File

@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Runtime.InteropServices;
using SabreTools.IO.Extensions;
using SabreTools.Models.CFB;
using static SabreTools.Models.CFB.Constants;
@@ -279,41 +280,24 @@ namespace SabreTools.Serialization.Deserializers
/// <returns>Filled sector full of directory entries on success, null on error</returns>
private static DirectoryEntry[]? ParseDirectoryEntries(Stream data, ushort sectorShift, ushort majorVersion)
{
const int directoryEntrySize = 64 + 2 + 1 + 1 + 4 + 4 + 4 + 16 + 4 + 8 + 8 + 4 + 8;
int directoryEntrySize = Marshal.SizeOf<DirectoryEntry>();
int sectorCount = (int)(Math.Pow(2, sectorShift) / directoryEntrySize);
var directoryEntries = new DirectoryEntry[sectorCount];
for (int i = 0; i < directoryEntries.Length; i++)
{
var directoryEntry = ParseDirectoryEntry(data, majorVersion);
var directoryEntry = data.ReadType<DirectoryEntry>();
if (directoryEntry == null)
return null;
// Handle version 3 entries
if (majorVersion == 3)
directoryEntry.StreamSize &= 0x0000FFFF;
directoryEntries[i] = directoryEntry;
}
return directoryEntries;
}
/// <summary>
/// Parse a Stream into a directory entry
/// </summary>
/// <param name="data">Stream to parse</param>
/// <param name="majorVersion">Major version from the header</param>
/// <returns>Filled directory entry on success, null on error</returns>
private static DirectoryEntry? ParseDirectoryEntry(Stream data, ushort majorVersion)
{
var directoryEntry = data.ReadType<DirectoryEntry>();
if (directoryEntry == null)
return null;
// Handle version 3 entries
if (majorVersion == 3)
directoryEntry.StreamSize &= 0x0000FFFF;
return directoryEntry;
}
}
}

View File

@@ -83,31 +83,14 @@ namespace SabreTools.Serialization.Deserializers
/// </summary>
private static HeaderV1? ParseHeaderV1(Stream data)
{
var header = new HeaderV1();
byte[] tagBytes = data.ReadBytes(8);
header.Tag = Encoding.ASCII.GetString(tagBytes);
if (header.Tag != Constants.SignatureString)
var header = data.ReadType<HeaderV1>();
if (header?.Tag != Constants.SignatureString)
return null;
header.Length = data.ReadUInt32BigEndian();
if (header.Length != Constants.HeaderV1Size)
return null;
header.Version = data.ReadUInt32BigEndian();
header.Flags = (Flags)data.ReadUInt32BigEndian();
header.Compression = (CompressionType)data.ReadUInt32BigEndian();
if (header.Compression > CompressionType.CHDCOMPRESSION_ZLIB)
return null;
header.HunkSize = data.ReadUInt32BigEndian();
header.TotalHunks = data.ReadUInt32BigEndian();
header.Cylinders = data.ReadUInt32BigEndian();
header.Heads = data.ReadUInt32BigEndian();
header.Sectors = data.ReadUInt32BigEndian();
header.MD5 = data.ReadBytes(16);
header.ParentMD5 = data.ReadBytes(16);
return header;
}
@@ -116,32 +99,14 @@ namespace SabreTools.Serialization.Deserializers
/// </summary>
private static HeaderV2? ParseHeaderV2(Stream data)
{
var header = new HeaderV2();
byte[] tagBytes = data.ReadBytes(8);
header.Tag = Encoding.ASCII.GetString(tagBytes);
if (header.Tag != Constants.SignatureString)
var header = data.ReadType<HeaderV2>();
if (header?.Tag != Constants.SignatureString)
return null;
header.Length = data.ReadUInt32BigEndian();
if (header.Length != Constants.HeaderV2Size)
return null;
header.Version = data.ReadUInt32BigEndian();
header.Flags = (Flags)data.ReadUInt32BigEndian();
header.Compression = (CompressionType)data.ReadUInt32BigEndian();
if (header.Compression > CompressionType.CHDCOMPRESSION_ZLIB)
return null;
header.HunkSize = data.ReadUInt32BigEndian();
header.TotalHunks = data.ReadUInt32BigEndian();
header.Cylinders = data.ReadUInt32BigEndian();
header.Heads = data.ReadUInt32BigEndian();
header.Sectors = data.ReadUInt32BigEndian();
header.MD5 = data.ReadBytes(16);
header.ParentMD5 = data.ReadBytes(16);
header.BytesPerSector = data.ReadUInt32BigEndian();
return header;
}
@@ -150,32 +115,14 @@ namespace SabreTools.Serialization.Deserializers
/// </summary>
private static HeaderV3? ParseHeaderV3(Stream data)
{
var header = new HeaderV3();
byte[] tagBytes = data.ReadBytes(8);
header.Tag = Encoding.ASCII.GetString(tagBytes);
if (header.Tag != Constants.SignatureString)
var header = data.ReadType<HeaderV3>();
if (header?.Tag != Constants.SignatureString)
return null;
header.Length = data.ReadUInt32BigEndian();
if (header.Length != Constants.HeaderV3Size)
return null;
header.Version = data.ReadUInt32BigEndian();
header.Flags = (Flags)data.ReadUInt32BigEndian();
header.Compression = (CompressionType)data.ReadUInt32BigEndian();
if (header.Compression > CompressionType.CHDCOMPRESSION_ZLIB_PLUS)
return null;
header.TotalHunks = data.ReadUInt32BigEndian();
header.LogicalBytes = data.ReadUInt64BigEndian();
header.MetaOffset = data.ReadUInt64BigEndian();
header.MD5 = data.ReadBytes(16);
header.ParentMD5 = data.ReadBytes(16);
header.HunkBytes = data.ReadUInt32BigEndian();
header.SHA1 = data.ReadBytes(20);
header.ParentSHA1 = data.ReadBytes(20);
return header;
}
@@ -184,31 +131,14 @@ namespace SabreTools.Serialization.Deserializers
/// </summary>
private static HeaderV4? ParseHeaderV4(Stream data)
{
var header = new HeaderV4();
byte[] tagBytes = data.ReadBytes(8);
header.Tag = Encoding.ASCII.GetString(tagBytes);
if (header.Tag != Constants.SignatureString)
var header = data.ReadType<HeaderV4>();
if (header?.Tag != Constants.SignatureString)
return null;
header.Length = data.ReadUInt32BigEndian();
if (header.Length != Constants.HeaderV4Size)
return null;
header.Version = data.ReadUInt32BigEndian();
header.Flags = (Flags)data.ReadUInt32BigEndian();
header.Compression = (CompressionType)data.ReadUInt32BigEndian();
if (header.Compression > CompressionType.CHDCOMPRESSION_AV)
return null;
header.TotalHunks = data.ReadUInt32BigEndian();
header.LogicalBytes = data.ReadUInt64BigEndian();
header.MetaOffset = data.ReadUInt64BigEndian();
header.HunkBytes = data.ReadUInt32BigEndian();
header.SHA1 = data.ReadBytes(20);
header.ParentSHA1 = data.ReadBytes(20);
header.RawSHA1 = data.ReadBytes(20);
return header;
}
@@ -217,33 +147,12 @@ namespace SabreTools.Serialization.Deserializers
/// </summary>
private static HeaderV5? ParseHeaderV5(Stream data)
{
var header = new HeaderV5();
byte[] tagBytes = data.ReadBytes(8);
header.Tag = Encoding.ASCII.GetString(tagBytes);
if (header.Tag != Constants.SignatureString)
var header = data.ReadType<HeaderV5>();
if (header?.Tag != Constants.SignatureString)
return null;
header.Length = data.ReadUInt32BigEndian();
if (header.Length != Constants.HeaderV5Size)
return null;
header.Version = data.ReadUInt32BigEndian();
header.Compressors = new CodecType[4];
for (int i = 0; i < header.Compressors.Length; i++)
{
header.Compressors[i] = (CodecType)data.ReadUInt32BigEndian();
}
header.LogicalBytes = data.ReadUInt64BigEndian();
header.MapOffset = data.ReadUInt64BigEndian();
header.MetaOffset = data.ReadUInt64BigEndian();
header.HunkBytes = data.ReadUInt32BigEndian();
header.UnitBytes = data.ReadUInt32BigEndian();
header.RawSHA1 = data.ReadBytes(20);
header.SHA1 = data.ReadBytes(20);
header.ParentSHA1 = data.ReadBytes(20);
return header;
}
}

View File

@@ -159,29 +159,23 @@ namespace SabreTools.Serialization.Deserializers
switch (certificate.SignatureType)
{
case SignatureType.RSA_4096_SHA1:
certificate.SignatureSize = 0x200;
certificate.PaddingSize = 0x3C;
break;
case SignatureType.RSA_2048_SHA1:
certificate.SignatureSize = 0x100;
certificate.PaddingSize = 0x3C;
break;
case SignatureType.ECDSA_SHA1:
certificate.SignatureSize = 0x3C;
certificate.PaddingSize = 0x40;
break;
case SignatureType.RSA_4096_SHA256:
certificate.SignatureSize = 0x200;
certificate.PaddingSize = 0x3C;
break;
case SignatureType.RSA_2048_SHA1:
case SignatureType.RSA_2048_SHA256:
certificate.SignatureSize = 0x100;
certificate.PaddingSize = 0x3C;
break;
case SignatureType.ECDSA_SHA1:
case SignatureType.ECDSA_SHA256:
certificate.SignatureSize = 0x3C;
certificate.PaddingSize = 0x40;
break;
default:
return null;
}
@@ -232,29 +226,23 @@ namespace SabreTools.Serialization.Deserializers
switch (ticket.SignatureType)
{
case SignatureType.RSA_4096_SHA1:
ticket.SignatureSize = 0x200;
ticket.PaddingSize = 0x3C;
break;
case SignatureType.RSA_2048_SHA1:
ticket.SignatureSize = 0x100;
ticket.PaddingSize = 0x3C;
break;
case SignatureType.ECDSA_SHA1:
ticket.SignatureSize = 0x3C;
ticket.PaddingSize = 0x40;
break;
case SignatureType.RSA_4096_SHA256:
ticket.SignatureSize = 0x200;
ticket.PaddingSize = 0x3C;
break;
case SignatureType.RSA_2048_SHA1:
case SignatureType.RSA_2048_SHA256:
ticket.SignatureSize = 0x100;
ticket.PaddingSize = 0x3C;
break;
case SignatureType.ECDSA_SHA1:
case SignatureType.ECDSA_SHA256:
ticket.SignatureSize = 0x3C;
ticket.PaddingSize = 0x40;
break;
default:
return null;
}
@@ -330,29 +318,23 @@ namespace SabreTools.Serialization.Deserializers
switch (titleMetadata.SignatureType)
{
case SignatureType.RSA_4096_SHA1:
titleMetadata.SignatureSize = 0x200;
titleMetadata.PaddingSize = 0x3C;
break;
case SignatureType.RSA_2048_SHA1:
titleMetadata.SignatureSize = 0x100;
titleMetadata.PaddingSize = 0x3C;
break;
case SignatureType.ECDSA_SHA1:
titleMetadata.SignatureSize = 0x3C;
titleMetadata.PaddingSize = 0x40;
break;
case SignatureType.RSA_4096_SHA256:
titleMetadata.SignatureSize = 0x200;
titleMetadata.PaddingSize = 0x3C;
break;
case SignatureType.RSA_2048_SHA1:
case SignatureType.RSA_2048_SHA256:
titleMetadata.SignatureSize = 0x100;
titleMetadata.PaddingSize = 0x3C;
break;
case SignatureType.ECDSA_SHA1:
case SignatureType.ECDSA_SHA256:
titleMetadata.SignatureSize = 0x3C;
titleMetadata.PaddingSize = 0x40;
break;
default:
return null;
}

View File

@@ -18,9 +18,6 @@ namespace SabreTools.Serialization.Deserializers
if (data.Position < 0 || data.Position >= data.Length)
return null;
// Cache the current offset
long initialOffset = data.Position;
// Create a new Half-Life Game Cache to fill
var file = new Models.GCF.File();
@@ -134,7 +131,7 @@ namespace SabreTools.Serialization.Deserializers
#endregion
// Cache the current offset
initialOffset = data.Position;
long initialOffset = data.Position;
#region Directory Header

View File

@@ -21,9 +21,6 @@ namespace SabreTools.Serialization.Deserializers
var ird = new Models.IRD.File();
ird.Magic = data.ReadBytes(4);
if (ird.Magic == null)
return null;
string magic = Encoding.ASCII.GetString(ird.Magic);
if (magic != "3IRD")
return null;
@@ -32,35 +29,20 @@ namespace SabreTools.Serialization.Deserializers
if (ird.Version < 6)
return null;
var titleId = data.ReadBytes(9);
if (titleId == null)
return null;
byte[] titleId = data.ReadBytes(9);
ird.TitleID = Encoding.ASCII.GetString(titleId);
ird.TitleLength = data.ReadByteValue();
var title = data.ReadBytes(ird.TitleLength);
if (title == null)
return null;
byte[] title = data.ReadBytes(ird.TitleLength);
ird.Title = Encoding.ASCII.GetString(title);
var systemVersion = data.ReadBytes(4);
if (systemVersion == null)
return null;
byte[] systemVersion = data.ReadBytes(4);
ird.SystemVersion = Encoding.ASCII.GetString(systemVersion);
var gameVersion = data.ReadBytes(5);
if (gameVersion == null)
return null;
byte[] gameVersion = data.ReadBytes(5);
ird.GameVersion = Encoding.ASCII.GetString(gameVersion);
var appVersion = data.ReadBytes(5);
if (appVersion == null)
return null;
byte[] appVersion = data.ReadBytes(5);
ird.AppVersion = Encoding.ASCII.GetString(appVersion);
if (ird.Version == 7)

View File

@@ -428,13 +428,13 @@ namespace SabreTools.Serialization.Deserializers
var entry = new ResidentNamesTableEntry();
entry.Length = data.ReadByteValue();
if (entry.Length > 0 && data.Position + entry.Length <= data.Length)
if (entry.Length > 0)
{
byte[] name = data.ReadBytes(entry.Length);
entry.Name = Encoding.ASCII.GetString(name).TrimEnd('\0');
}
entry.OrdinalNumber = data.ReadUInt16();
entry.OrdinalNumber = data.ReadUInt16();
return entry;
}
@@ -728,7 +728,7 @@ namespace SabreTools.Serialization.Deserializers
var entry = new ImportModuleNameTableEntry();
entry.Length = data.ReadByteValue();
if (entry.Length > 0 && data.Position + entry.Length <= data.Length)
if (entry.Length > 0)
{
byte[] name = data.ReadBytes(entry.Length);
entry.Name = Encoding.ASCII.GetString(name).TrimEnd('\0');
@@ -747,7 +747,7 @@ namespace SabreTools.Serialization.Deserializers
var entry = new ImportModuleProcedureNameTableEntry();
entry.Length = data.ReadByteValue();
if (entry.Length > 0 && data.Position + entry.Length <= data.Length)
if (entry.Length > 0)
{
byte[] name = data.ReadBytes(entry.Length);
entry.Name = Encoding.ASCII.GetString(name).TrimEnd('\0');
@@ -766,13 +766,13 @@ namespace SabreTools.Serialization.Deserializers
var entry = new NonResidentNamesTableEntry();
entry.Length = data.ReadByteValue();
if (entry.Length > 0 && data.Position + entry.Length <= data.Length)
if (entry.Length > 0)
{
byte[] name = data.ReadBytes(entry.Length);
entry.Name = Encoding.ASCII.GetString(name).TrimEnd('\0');
}
entry.OrdinalNumber = data.ReadUInt16();
entry.OrdinalNumber = data.ReadUInt16();
return entry;
}

View File

@@ -104,7 +104,8 @@ namespace SabreTools.Serialization.Deserializers
}
// Version 2 and 3
else if (archive.ArchiveHeader.FormatVersion == FormatVersion.Format2 || archive.ArchiveHeader.FormatVersion == FormatVersion.Format3)
else if (archive.ArchiveHeader.FormatVersion == FormatVersion.Format2
|| archive.ArchiveHeader.FormatVersion == FormatVersion.Format3)
{
// If we have a hash table
long hashTableOffset = ((uint)archive.ArchiveHeader.HashTablePositionHi << 23) | archive.ArchiveHeader.HashTablePosition;
@@ -195,7 +196,8 @@ namespace SabreTools.Serialization.Deserializers
}
// Version 2 and 3
else if (archive.ArchiveHeader.FormatVersion == FormatVersion.Format2 || archive.ArchiveHeader.FormatVersion == FormatVersion.Format3)
else if (archive.ArchiveHeader.FormatVersion == FormatVersion.Format2
|| archive.ArchiveHeader.FormatVersion == FormatVersion.Format3)
{
// If we have a block table
long blockTableOffset = ((uint)archive.ArchiveHeader.BlockTablePositionHi << 23) | archive.ArchiveHeader.BlockTablePosition;

View File

@@ -294,10 +294,11 @@ namespace SabreTools.Serialization.Deserializers
exeFSHeader.FileHeaders = new ExeFSFileHeader[10];
for (int i = 0; i < 10; i++)
{
var exeFsFileHeader = ParseExeFSFileHeader(data);
var exeFsFileHeader = data.ReadType<ExeFSFileHeader>();
if (exeFsFileHeader == null)
return null;
exeFsFileHeader.FileName = exeFsFileHeader.FileName?.TrimEnd('\0');
exeFSHeader.FileHeaders[i] = exeFsFileHeader;
}
exeFSHeader.Reserved = data.ReadBytes(0x20);
@@ -309,22 +310,5 @@ namespace SabreTools.Serialization.Deserializers
return exeFSHeader;
}
/// <summary>
/// Parse a Stream into an ExeFS file header
/// </summary>
/// <param name="data">Stream to parse</param>
/// <returns>Filled ExeFS file header on success, null on error</returns>
public static ExeFSFileHeader? ParseExeFSFileHeader(Stream data)
{
var exeFSFileHeader = new ExeFSFileHeader();
byte[] fileName = data.ReadBytes(8);
exeFSFileHeader.FileName = Encoding.ASCII.GetString(fileName).TrimEnd('\0');
exeFSFileHeader.FileOffset = data.ReadUInt32();
exeFSFileHeader.FileSize = data.ReadUInt32();
return exeFSFileHeader;
}
}
}