diff --git a/SabreTools.Serialization/Deserializers/BFPK.cs b/SabreTools.Serialization/Deserializers/BFPK.cs
index 8151353c..432484d6 100644
--- a/SabreTools.Serialization/Deserializers/BFPK.cs
+++ b/SabreTools.Serialization/Deserializers/BFPK.cs
@@ -17,6 +17,9 @@ namespace SabreTools.Serialization.Deserializers
try
{
+ // Cache the current offset
+ long initialOffset = data.Position;
+
// Create a new archive to fill
var archive = new Archive();
@@ -40,7 +43,7 @@ namespace SabreTools.Serialization.Deserializers
// Read all entries in turn
for (int i = 0; i < header.Files; i++)
{
- files[i] = ParseFileEntry(data);
+ files[i] = ParseFileEntry(data, initialOffset);
}
// Set the files
@@ -62,7 +65,7 @@ namespace SabreTools.Serialization.Deserializers
///
/// Stream to parse
/// Filled FileEntry on success, null on error
- public static FileEntry ParseFileEntry(Stream data)
+ public static FileEntry ParseFileEntry(Stream data, long initialOffset)
{
var fileEntry = new FileEntry();
@@ -78,7 +81,7 @@ namespace SabreTools.Serialization.Deserializers
if (fileEntry.Offset > 0)
{
long currentOffset = data.Position;
- data.Seek(fileEntry.Offset, SeekOrigin.Begin);
+ data.Seek(initialOffset + fileEntry.Offset, SeekOrigin.Begin);
fileEntry.CompressedSize = data.ReadInt32LittleEndian();
data.Seek(currentOffset, SeekOrigin.Begin);
}
diff --git a/SabreTools.Serialization/Deserializers/BSP.cs b/SabreTools.Serialization/Deserializers/BSP.cs
index fd9938b9..894f62f4 100644
--- a/SabreTools.Serialization/Deserializers/BSP.cs
+++ b/SabreTools.Serialization/Deserializers/BSP.cs
@@ -19,6 +19,9 @@ namespace SabreTools.Serialization.Deserializers
try
{
+ // Cache the current offset
+ long initialOffset = data.Position;
+
// Create a new Half-Life Level to fill
var file = new BspFile();
@@ -46,7 +49,7 @@ namespace SabreTools.Serialization.Deserializers
continue;
// Seek to the lump offset
- data.Seek(lumpEntry.Offset, SeekOrigin.Begin);
+ data.Seek(initialOffset + lumpEntry.Offset, SeekOrigin.Begin);
// Read according to the lump type
switch ((LumpType)l)
diff --git a/SabreTools.Serialization/Deserializers/CFB.cs b/SabreTools.Serialization/Deserializers/CFB.cs
index e28a0761..4357c314 100644
--- a/SabreTools.Serialization/Deserializers/CFB.cs
+++ b/SabreTools.Serialization/Deserializers/CFB.cs
@@ -19,6 +19,9 @@ namespace SabreTools.Serialization.Deserializers
try
{
+ // Cache the current offset
+ long initialOffset = data.Position;
+
// Create a new binary to fill
var binary = new Binary();
@@ -62,8 +65,9 @@ namespace SabreTools.Serialization.Deserializers
break;
// Get the new next sector information
- long sectorOffset = (long)((long)(currentSector + 1) * Math.Pow(2, fileHeader.SectorShift));
- if (sectorOffset < 0 || sectorOffset >= data.Length)
+ long sectorOffset = initialOffset
+ + (long)((long)(currentSector + 1) * Math.Pow(2, fileHeader.SectorShift));
+ if (sectorOffset < initialOffset || sectorOffset >= data.Length)
return null;
// Seek to the next sector
@@ -105,8 +109,9 @@ namespace SabreTools.Serialization.Deserializers
break;
// Get the new next sector information
- long sectorOffset = (long)((long)(currentSector + 1) * Math.Pow(2, fileHeader.SectorShift));
- if (sectorOffset < 0 || sectorOffset >= data.Length)
+ long sectorOffset = initialOffset
+ + (long)((long)(currentSector + 1) * Math.Pow(2, fileHeader.SectorShift));
+ if (sectorOffset < initialOffset || sectorOffset >= data.Length)
return null;
// Seek to the next sector
@@ -140,8 +145,9 @@ namespace SabreTools.Serialization.Deserializers
break;
// Get the new next sector information
- long sectorOffset = (long)((long)(currentSector + 1) * Math.Pow(2, fileHeader.SectorShift));
- if (sectorOffset < 0 || sectorOffset >= data.Length)
+ long sectorOffset = initialOffset
+ + (long)((long)(currentSector + 1) * Math.Pow(2, fileHeader.SectorShift));
+ if (sectorOffset < initialOffset || sectorOffset >= data.Length)
return null;
// Seek to the next sector
@@ -194,8 +200,9 @@ namespace SabreTools.Serialization.Deserializers
break;
// Get the new next sector information
- long sectorOffset = (long)((long)(currentSector + 1) * Math.Pow(2, fileHeader.SectorShift));
- if (sectorOffset < 0 || sectorOffset >= data.Length)
+ long sectorOffset = initialOffset
+ + (long)((long)(currentSector + 1) * Math.Pow(2, fileHeader.SectorShift));
+ if (sectorOffset < initialOffset || sectorOffset >= data.Length)
return null;
// Seek to the next sector
diff --git a/SabreTools.Serialization/Deserializers/CHD.cs b/SabreTools.Serialization/Deserializers/CHD.cs
index aee85e85..2db3d876 100644
--- a/SabreTools.Serialization/Deserializers/CHD.cs
+++ b/SabreTools.Serialization/Deserializers/CHD.cs
@@ -18,8 +18,11 @@ namespace SabreTools.Serialization.Deserializers
try
{
+ // Cache the current offset
+ long initialOffset = data.Position;
+
// Determine the header version
- uint version = GetVersion(data);
+ uint version = GetVersion(data, initialOffset);
// Read and return the current CHD
switch (version)
@@ -98,7 +101,7 @@ namespace SabreTools.Serialization.Deserializers
/// Get the matching CHD version, if possible
///
/// Matching version, 0 if none
- private static uint GetVersion(Stream data)
+ private static uint GetVersion(Stream data, long initialOffset)
{
// Read the header values
byte[] tagBytes = data.ReadBytes(8);
@@ -107,7 +110,7 @@ namespace SabreTools.Serialization.Deserializers
uint version = data.ReadUInt32BigEndian();
// Seek back to start
- data.SeekIfPossible();
+ data.SeekIfPossible(initialOffset);
// Check the signature
if (!string.Equals(tag, Constants.SignatureString, StringComparison.Ordinal))
diff --git a/SabreTools.Serialization/Deserializers/GCF.cs b/SabreTools.Serialization/Deserializers/GCF.cs
index 4c43d320..6a1edb11 100644
--- a/SabreTools.Serialization/Deserializers/GCF.cs
+++ b/SabreTools.Serialization/Deserializers/GCF.cs
@@ -16,6 +16,9 @@ namespace SabreTools.Serialization.Deserializers
try
{
+ // Cache the current offset
+ long initialOffset = data.Position;
+
// Create a new Half-Life Game Cache to fill
var file = new Models.GCF.File();
@@ -100,7 +103,7 @@ namespace SabreTools.Serialization.Deserializers
#endregion
// Cache the current offset
- long initialOffset = data.Position;
+ long afterMapPosition = data.Position;
#region Directory Header
@@ -213,7 +216,7 @@ namespace SabreTools.Serialization.Deserializers
#endregion
// Seek to end of directory section, just in case
- data.Seek(initialOffset + file.DirectoryHeader.DirectorySize, SeekOrigin.Begin);
+ data.Seek(afterMapPosition + file.DirectoryHeader.DirectorySize, SeekOrigin.Begin);
#region Directory Map Header
@@ -301,7 +304,7 @@ namespace SabreTools.Serialization.Deserializers
#endregion
// Seek to end of checksum section, just in case
- data.Seek(initialOffset + checksumHeader.ChecksumSize, SeekOrigin.Begin);
+ data.Seek(afterMapPosition + checksumHeader.ChecksumSize, SeekOrigin.Begin);
#region Data Block Header
diff --git a/SabreTools.Serialization/Deserializers/InstallShieldArchiveV3.cs b/SabreTools.Serialization/Deserializers/InstallShieldArchiveV3.cs
index 86f01eac..15c54c37 100644
--- a/SabreTools.Serialization/Deserializers/InstallShieldArchiveV3.cs
+++ b/SabreTools.Serialization/Deserializers/InstallShieldArchiveV3.cs
@@ -16,6 +16,9 @@ namespace SabreTools.Serialization.Deserializers
try
{
+ // Cache the current offset
+ long initialOffset = data.Position;
+
// Create a new archive to fill
var archive = new Archive();
@@ -25,7 +28,7 @@ namespace SabreTools.Serialization.Deserializers
var header = ParseHeader(data);
if (header.Signature1 != Constants.HeaderSignature)
return null;
- if (header.TocAddress >= data.Length)
+ if (initialOffset + header.TocAddress >= data.Length)
return null;
// Set the archive header
@@ -36,8 +39,8 @@ namespace SabreTools.Serialization.Deserializers
#region Directories
// Get the directories offset
- uint directoriesOffset = header.TocAddress;
- if (directoriesOffset < 0 || directoriesOffset >= data.Length)
+ long directoriesOffset = initialOffset + header.TocAddress;
+ if (directoriesOffset < initialOffset || directoriesOffset >= data.Length)
return null;
// Seek to the directories
diff --git a/SabreTools.Serialization/Deserializers/InstallShieldCabinet.cs b/SabreTools.Serialization/Deserializers/InstallShieldCabinet.cs
index 9dcfaaf9..c8d99fb7 100644
--- a/SabreTools.Serialization/Deserializers/InstallShieldCabinet.cs
+++ b/SabreTools.Serialization/Deserializers/InstallShieldCabinet.cs
@@ -20,6 +20,9 @@ namespace SabreTools.Serialization.Deserializers
try
{
+ // Cache the current offset
+ long initialOffset = data.Position;
+
// Create a new cabinet to fill
var cabinet = new Cabinet();
@@ -48,8 +51,8 @@ namespace SabreTools.Serialization.Deserializers
#region Descriptor
// Get the descriptor offset
- uint descriptorOffset = commonHeader.DescriptorOffset;
- if (descriptorOffset < 0 || descriptorOffset >= data.Length)
+ long descriptorOffset = initialOffset + commonHeader.DescriptorOffset;
+ if (descriptorOffset < initialOffset || descriptorOffset >= data.Length)
return null;
// Seek to the descriptor
@@ -63,8 +66,8 @@ namespace SabreTools.Serialization.Deserializers
#region File Descriptor Offsets
// Get the file table offset
- uint fileTableOffset = commonHeader.DescriptorOffset + cabinet.Descriptor.FileTableOffset;
- if (fileTableOffset < 0 || fileTableOffset >= data.Length)
+ long fileTableOffset = descriptorOffset + cabinet.Descriptor.FileTableOffset;
+ if (fileTableOffset < initialOffset || fileTableOffset >= data.Length)
return null;
// Seek to the file table
@@ -93,12 +96,12 @@ namespace SabreTools.Serialization.Deserializers
for (int i = 0; i < cabinet.Descriptor.DirectoryCount; i++)
{
// Get the directory descriptor offset
- uint offset = descriptorOffset
+ long offset = descriptorOffset
+ cabinet.Descriptor.FileTableOffset
+ cabinet.FileDescriptorOffsets[i];
// If we have an invalid offset
- if (offset < 0 || offset >= data.Length)
+ if (offset < initialOffset || offset >= data.Length)
continue;
// Seek to the file descriptor offset
@@ -119,7 +122,7 @@ namespace SabreTools.Serialization.Deserializers
for (int i = 0; i < cabinet.Descriptor.FileCount; i++)
{
// Get the file descriptor offset
- uint offset;
+ long offset;
if (majorVersion <= 5)
{
offset = descriptorOffset
@@ -135,7 +138,7 @@ namespace SabreTools.Serialization.Deserializers
}
// If we have an invalid offset
- if (offset < 0 || offset >= data.Length)
+ if (offset < initialOffset || offset >= data.Length)
continue;
// Seek to the file descriptor offset
@@ -156,13 +159,13 @@ namespace SabreTools.Serialization.Deserializers
for (int i = 0; i < (cabinet.Descriptor.FileGroupOffsets?.Length ?? 0); i++)
{
// Get the file group offset
- uint offset = cabinet.Descriptor.FileGroupOffsets![i];
+ long offset = cabinet.Descriptor.FileGroupOffsets![i];
if (offset == 0)
continue;
// Adjust the file group offset
- offset += commonHeader.DescriptorOffset;
- if (offset < 0 || offset >= data.Length)
+ offset += descriptorOffset;
+ if (offset < initialOffset || offset >= data.Length)
continue;
// Seek to the file group offset
@@ -173,11 +176,11 @@ namespace SabreTools.Serialization.Deserializers
cabinet.FileGroupOffsets[offset] = offsetList;
// If we have a nonzero next offset
- uint nextOffset = offsetList.NextOffset;
+ long nextOffset = offsetList.NextOffset;
while (nextOffset != 0)
{
// Get the next offset to read
- uint internalOffset = nextOffset + commonHeader.DescriptorOffset;
+ long internalOffset = descriptorOffset + nextOffset;
// Seek to the file group offset
data.Seek(internalOffset, SeekOrigin.Begin);
@@ -218,7 +221,7 @@ namespace SabreTools.Serialization.Deserializers
}
/// Seek to the file group
- data.Seek(list.DescriptorOffset + descriptorOffset, SeekOrigin.Begin);
+ data.Seek(descriptorOffset + list.DescriptorOffset, SeekOrigin.Begin);
// Add the file group
cabinet.FileGroups[fileGroupId++] = ParseFileGroup(data, majorVersion, descriptorOffset);
@@ -233,13 +236,13 @@ namespace SabreTools.Serialization.Deserializers
for (int i = 0; i < (cabinet.Descriptor.ComponentOffsets?.Length ?? 0); i++)
{
// Get the component offset
- uint offset = cabinet.Descriptor.ComponentOffsets![i];
+ long offset = cabinet.Descriptor.ComponentOffsets![i];
if (offset == 0)
continue;
// Adjust the component offset
- offset += commonHeader.DescriptorOffset;
- if (offset < 0 || offset >= data.Length)
+ offset += descriptorOffset;
+ if (offset < initialOffset || offset >= data.Length)
continue;
// Seek to the component offset
@@ -250,11 +253,11 @@ namespace SabreTools.Serialization.Deserializers
cabinet.ComponentOffsets[cabinet.Descriptor.ComponentOffsets[i]] = offsetList;
// If we have a nonzero next offset
- uint nextOffset = offsetList.NextOffset;
+ long nextOffset = offsetList.NextOffset;
while (nextOffset != 0)
{
// Get the next offset to read
- uint internalOffset = nextOffset + commonHeader.DescriptorOffset;
+ long internalOffset = descriptorOffset + nextOffset;
// Seek to the file group offset
data.Seek(internalOffset, SeekOrigin.Begin);
@@ -295,7 +298,7 @@ namespace SabreTools.Serialization.Deserializers
}
// Seek to the component
- data.Seek(list.DescriptorOffset + descriptorOffset, SeekOrigin.Begin);
+ data.Seek(descriptorOffset + list.DescriptorOffset, SeekOrigin.Begin);
// Add the component
cabinet.Components[componentId++] = ParseComponent(data, majorVersion, descriptorOffset);
@@ -340,7 +343,7 @@ namespace SabreTools.Serialization.Deserializers
/// Major version of the cabinet
/// Offset of the cabinet descriptor
/// Filled Component on success, null on error
- public static Component ParseComponent(Stream data, int majorVersion, uint descriptorOffset)
+ public static Component ParseComponent(Stream data, int majorVersion, long descriptorOffset)
{
var obj = new Component();
@@ -384,7 +387,7 @@ namespace SabreTools.Serialization.Deserializers
if (obj.IdentifierOffset != 0)
{
// Seek to the identifier
- data.Seek(obj.IdentifierOffset + descriptorOffset, SeekOrigin.Begin);
+ data.Seek(descriptorOffset + obj.IdentifierOffset, SeekOrigin.Begin);
// Read the string
if (majorVersion >= 17)
@@ -397,7 +400,7 @@ namespace SabreTools.Serialization.Deserializers
if (obj.DisplayNameOffset != 0)
{
// Seek to the name
- data.Seek(obj.DisplayNameOffset + descriptorOffset, SeekOrigin.Begin);
+ data.Seek(descriptorOffset + obj.DisplayNameOffset, SeekOrigin.Begin);
// Read the string
if (majorVersion >= 17)
@@ -410,7 +413,7 @@ namespace SabreTools.Serialization.Deserializers
if (obj.NameOffset != 0)
{
// Seek to the name
- data.Seek(obj.NameOffset + descriptorOffset, SeekOrigin.Begin);
+ data.Seek(descriptorOffset + obj.NameOffset, SeekOrigin.Begin);
// Read the string
if (majorVersion >= 17)
@@ -423,7 +426,7 @@ namespace SabreTools.Serialization.Deserializers
if (obj.CLSIDOffset != 0)
{
// Seek to the CLSID
- data.Seek(obj.CLSIDOffset + descriptorOffset, SeekOrigin.Begin);
+ data.Seek(descriptorOffset + obj.CLSIDOffset, SeekOrigin.Begin);
// Read the GUID
obj.CLSID = data.ReadGuid();
@@ -433,7 +436,7 @@ namespace SabreTools.Serialization.Deserializers
if (obj.FileGroupCount != 0 && obj.FileGroupNamesOffset != 0)
{
// Seek to the file group table offset
- data.Seek(obj.FileGroupNamesOffset + descriptorOffset, SeekOrigin.Begin);
+ data.Seek(descriptorOffset + obj.FileGroupNamesOffset, SeekOrigin.Begin);
// Read the file group names table
obj.FileGroupNames = new string[obj.FileGroupCount];
@@ -446,7 +449,7 @@ namespace SabreTools.Serialization.Deserializers
long preNameOffset = data.Position;
// Seek to the name offset
- data.Seek(nameOffset + descriptorOffset, SeekOrigin.Begin);
+ data.Seek(descriptorOffset + nameOffset, SeekOrigin.Begin);
if (majorVersion >= 17)
obj.FileGroupNames[j] = data.ReadNullTerminatedUnicodeString() ?? string.Empty;
@@ -530,7 +533,7 @@ namespace SabreTools.Serialization.Deserializers
/// Major version of the cabinet
/// Offset of the cabinet descriptor
/// Filled FileDescriptor on success, null on error
- public static FileDescriptor ParseFileDescriptor(Stream data, int majorVersion, uint descriptorOffset)
+ public static FileDescriptor ParseFileDescriptor(Stream data, int majorVersion, long descriptorOffset)
{
var obj = new FileDescriptor();
@@ -573,7 +576,7 @@ namespace SabreTools.Serialization.Deserializers
if (obj.NameOffset != 0)
{
// Seek to the name
- data.Seek(obj.NameOffset + descriptorOffset, SeekOrigin.Begin);
+ data.Seek(descriptorOffset + obj.NameOffset, SeekOrigin.Begin);
// Read the string
if (majorVersion >= 17)
@@ -595,7 +598,7 @@ namespace SabreTools.Serialization.Deserializers
/// Major version of the cabinet
/// Offset of the cabinet descriptor
/// Filled FileGroup on success, null on error
- public static FileGroup ParseFileGroup(Stream data, int majorVersion, uint descriptorOffset)
+ public static FileGroup ParseFileGroup(Stream data, int majorVersion, long descriptorOffset)
{
var obj = new FileGroup();
@@ -631,7 +634,7 @@ namespace SabreTools.Serialization.Deserializers
if (obj.NameOffset != 0)
{
// Seek to the name
- data.Seek(obj.NameOffset + descriptorOffset, SeekOrigin.Begin);
+ data.Seek(descriptorOffset + obj.NameOffset, SeekOrigin.Begin);
// Read the string
if (majorVersion >= 17)
@@ -653,7 +656,7 @@ namespace SabreTools.Serialization.Deserializers
/// Major version of the cabinet
/// Offset of the cabinet descriptor
/// Filled OffsetList on success, null on error
- public static OffsetList ParseOffsetList(Stream data, int majorVersion, uint descriptorOffset)
+ public static OffsetList ParseOffsetList(Stream data, int majorVersion, long descriptorOffset)
{
var obj = new OffsetList();
@@ -665,7 +668,7 @@ namespace SabreTools.Serialization.Deserializers
long currentOffset = data.Position;
// Seek to the name offset
- data.Seek(obj.NameOffset + descriptorOffset, SeekOrigin.Begin);
+ data.Seek(descriptorOffset + obj.NameOffset, SeekOrigin.Begin);
// Read the string
if (majorVersion >= 17)
diff --git a/SabreTools.Serialization/Deserializers/LinearExecutable.cs b/SabreTools.Serialization/Deserializers/LinearExecutable.cs
index d5a019a1..e9a47460 100644
--- a/SabreTools.Serialization/Deserializers/LinearExecutable.cs
+++ b/SabreTools.Serialization/Deserializers/LinearExecutable.cs
@@ -19,7 +19,7 @@ namespace SabreTools.Serialization.Deserializers
try
{
// Cache the current offset
- int initialOffset = (int)data.Position;
+ long initialOffset = data.Position;
// Create a new executable to fill
var executable = new Executable();
@@ -52,8 +52,10 @@ namespace SabreTools.Serialization.Deserializers
#region Object Table
// Get the object table offset
- long offset = informationBlock.ObjectTableOffset + stub.Header.NewExeHeaderAddr;
- if (offset > stub.Header.NewExeHeaderAddr && offset < data.Length)
+ long offset = initialOffset
+ + stub.Header.NewExeHeaderAddr
+ + informationBlock.ObjectTableOffset;
+ if (offset > initialOffset + stub.Header.NewExeHeaderAddr && offset < data.Length)
{
// Seek to the object table
data.Seek(offset, SeekOrigin.Begin);
@@ -73,8 +75,10 @@ namespace SabreTools.Serialization.Deserializers
#region Object Page Map
// Get the object page map offset
- offset = informationBlock.ObjectPageMapOffset + stub.Header.NewExeHeaderAddr;
- if (offset > stub.Header.NewExeHeaderAddr && offset < data.Length)
+ offset = initialOffset
+ + stub.Header.NewExeHeaderAddr
+ + informationBlock.ObjectPageMapOffset;
+ if (offset > initialOffset + stub.Header.NewExeHeaderAddr && offset < data.Length)
{
// Seek to the object page map
data.Seek(offset, SeekOrigin.Begin);
@@ -93,8 +97,10 @@ namespace SabreTools.Serialization.Deserializers
#region Object Iterate Data Map
- offset = informationBlock.ObjectIterateDataMapOffset + stub.Header.NewExeHeaderAddr;
- if (offset > stub.Header.NewExeHeaderAddr && offset < data.Length)
+ offset = initialOffset
+ + stub.Header.NewExeHeaderAddr
+ + informationBlock.ObjectIterateDataMapOffset;
+ if (offset > initialOffset + stub.Header.NewExeHeaderAddr && offset < data.Length)
{
// Seek to the object page map
data.Seek(offset, SeekOrigin.Begin);
@@ -109,8 +115,10 @@ namespace SabreTools.Serialization.Deserializers
#region Resource Table
// Get the resource table offset
- offset = informationBlock.ResourceTableOffset + stub.Header.NewExeHeaderAddr;
- if (offset > stub.Header.NewExeHeaderAddr && offset < data.Length)
+ offset = initialOffset
+ + stub.Header.NewExeHeaderAddr
+ + informationBlock.ResourceTableOffset;
+ if (offset > initialOffset + stub.Header.NewExeHeaderAddr && offset < data.Length)
{
// Seek to the resource table
data.Seek(offset, SeekOrigin.Begin);
@@ -130,8 +138,10 @@ namespace SabreTools.Serialization.Deserializers
#region Resident Names Table
// Get the resident names table offset
- offset = informationBlock.ResidentNamesTableOffset + stub.Header.NewExeHeaderAddr;
- if (offset > stub.Header.NewExeHeaderAddr && offset < data.Length)
+ offset = initialOffset
+ + stub.Header.NewExeHeaderAddr
+ + informationBlock.ResidentNamesTableOffset;
+ if (offset > initialOffset + stub.Header.NewExeHeaderAddr && offset < data.Length)
{
// Seek to the resident names table
data.Seek(offset, SeekOrigin.Begin);
@@ -159,8 +169,10 @@ namespace SabreTools.Serialization.Deserializers
#region Entry Table
// Get the entry table offset
- offset = informationBlock.EntryTableOffset + stub.Header.NewExeHeaderAddr;
- if (offset > stub.Header.NewExeHeaderAddr && offset < data.Length)
+ offset = initialOffset
+ + stub.Header.NewExeHeaderAddr
+ + informationBlock.EntryTableOffset;
+ if (offset > initialOffset + stub.Header.NewExeHeaderAddr && offset < data.Length)
{
// Seek to the entry table
data.Seek(offset, SeekOrigin.Begin);
@@ -189,8 +201,10 @@ namespace SabreTools.Serialization.Deserializers
#region Module Format Directives Table
// Get the module format directives table offset
- offset = informationBlock.ModuleDirectivesTableOffset + stub.Header.NewExeHeaderAddr;
- if (offset > stub.Header.NewExeHeaderAddr && offset < data.Length)
+ offset = initialOffset
+ + stub.Header.NewExeHeaderAddr
+ + informationBlock.ModuleDirectivesTableOffset;
+ if (offset > initialOffset + stub.Header.NewExeHeaderAddr && offset < data.Length)
{
// Seek to the module format directives table
data.Seek(offset, SeekOrigin.Begin);
@@ -218,8 +232,10 @@ namespace SabreTools.Serialization.Deserializers
#region Fix-up Page Table
// Get the fix-up page table offset
- offset = informationBlock.FixupPageTableOffset + stub.Header.NewExeHeaderAddr;
- if (offset > stub.Header.NewExeHeaderAddr && offset < data.Length)
+ offset = initialOffset
+ + stub.Header.NewExeHeaderAddr
+ + informationBlock.FixupPageTableOffset;
+ if (offset > initialOffset + stub.Header.NewExeHeaderAddr && offset < data.Length)
{
// Seek to the fix-up page table
data.Seek(offset, SeekOrigin.Begin);
@@ -239,8 +255,10 @@ namespace SabreTools.Serialization.Deserializers
#region Fix-up Record Table
// Get the fix-up record table offset
- offset = informationBlock.FixupRecordTableOffset + stub.Header.NewExeHeaderAddr;
- if (offset > stub.Header.NewExeHeaderAddr && offset < data.Length)
+ offset = initialOffset
+ + stub.Header.NewExeHeaderAddr
+ + informationBlock.FixupRecordTableOffset;
+ if (offset > initialOffset + stub.Header.NewExeHeaderAddr && offset < data.Length)
{
// Seek to the fix-up record table
data.Seek(offset, SeekOrigin.Begin);
@@ -264,8 +282,10 @@ namespace SabreTools.Serialization.Deserializers
#region Imported Module Name Table
// Get the imported module name table offset
- offset = informationBlock.ImportedModulesNameTableOffset + stub.Header.NewExeHeaderAddr;
- if (offset > stub.Header.NewExeHeaderAddr && offset < data.Length)
+ offset = initialOffset
+ + stub.Header.NewExeHeaderAddr
+ + informationBlock.ImportedModulesNameTableOffset;
+ if (offset > initialOffset + stub.Header.NewExeHeaderAddr && offset < data.Length)
{
// Seek to the imported module name table
data.Seek(offset, SeekOrigin.Begin);
@@ -285,8 +305,10 @@ namespace SabreTools.Serialization.Deserializers
#region Imported Module Procedure Name Table
// Get the imported module procedure name table offset
- offset = informationBlock.ImportProcedureNameTableOffset + stub.Header.NewExeHeaderAddr;
- if (offset > stub.Header.NewExeHeaderAddr && offset < data.Length)
+ offset = initialOffset
+ + stub.Header.NewExeHeaderAddr
+ + informationBlock.ImportProcedureNameTableOffset;
+ if (offset > initialOffset + stub.Header.NewExeHeaderAddr && offset < data.Length)
{
// Seek to the imported module procedure name table
data.Seek(offset, SeekOrigin.Begin);
@@ -315,8 +337,10 @@ namespace SabreTools.Serialization.Deserializers
#region Per-Page Checksum Table
// Get the per-page checksum table offset
- offset = informationBlock.PerPageChecksumTableOffset + stub.Header.NewExeHeaderAddr;
- if (offset > stub.Header.NewExeHeaderAddr && offset < data.Length)
+ offset = initialOffset
+ + stub.Header.NewExeHeaderAddr
+ + informationBlock.PerPageChecksumTableOffset;
+ if (offset > initialOffset + stub.Header.NewExeHeaderAddr && offset < data.Length)
{
// Seek to the per-page checksum name table
data.Seek(offset, SeekOrigin.Begin);
@@ -336,8 +360,10 @@ namespace SabreTools.Serialization.Deserializers
#region Non-Resident Names Table
// Get the non-resident names table offset
- offset = informationBlock.NonResidentNamesTableOffset + stub.Header.NewExeHeaderAddr;
- if (offset > stub.Header.NewExeHeaderAddr && offset < data.Length)
+ offset = initialOffset
+ + stub.Header.NewExeHeaderAddr
+ + informationBlock.NonResidentNamesTableOffset;
+ if (offset > initialOffset + stub.Header.NewExeHeaderAddr && offset < data.Length)
{
// Seek to the non-resident names table
data.Seek(offset, SeekOrigin.Begin);
@@ -365,8 +391,10 @@ namespace SabreTools.Serialization.Deserializers
#region Debug Information
// Get the debug information offset
- offset = informationBlock.DebugInformationOffset + stub.Header.NewExeHeaderAddr;
- if (offset > stub.Header.NewExeHeaderAddr && offset < data.Length)
+ offset = initialOffset
+ + stub.Header.NewExeHeaderAddr
+ + informationBlock.DebugInformationOffset;
+ if (offset > initialOffset + stub.Header.NewExeHeaderAddr && offset < data.Length)
{
// Seek to the debug information
data.Seek(offset, SeekOrigin.Begin);
diff --git a/SabreTools.Serialization/Deserializers/MSDOS.cs b/SabreTools.Serialization/Deserializers/MSDOS.cs
index 46001a5a..b026a24a 100644
--- a/SabreTools.Serialization/Deserializers/MSDOS.cs
+++ b/SabreTools.Serialization/Deserializers/MSDOS.cs
@@ -18,7 +18,7 @@ namespace SabreTools.Serialization.Deserializers
try
{
// Cache the current offset
- int initialOffset = (int)data.Position;
+ long initialOffset = data.Position;
// Create a new executable to fill
var executable = new Executable();
@@ -38,7 +38,7 @@ namespace SabreTools.Serialization.Deserializers
#region Relocation Table
// If the offset for the relocation table doesn't exist
- int tableAddress = initialOffset + executableHeader.RelocationTableAddr;
+ long tableAddress = initialOffset + executableHeader.RelocationTableAddr;
if (tableAddress >= data.Length)
return executable;
diff --git a/SabreTools.Serialization/Deserializers/MicrosoftCabinet.cs b/SabreTools.Serialization/Deserializers/MicrosoftCabinet.cs
index 04685a15..22420c43 100644
--- a/SabreTools.Serialization/Deserializers/MicrosoftCabinet.cs
+++ b/SabreTools.Serialization/Deserializers/MicrosoftCabinet.cs
@@ -19,7 +19,7 @@ namespace SabreTools.Serialization.Deserializers
try
{
// Cache the current offset
- int initialOffset = (int)data.Position;
+ long initialOffset = data.Position;
// Create a new cabinet to fill
var cabinet = new Cabinet();
@@ -57,7 +57,7 @@ namespace SabreTools.Serialization.Deserializers
#region Files
// Get the files offset
- int filesOffset = (int)cabinetHeader.FilesOffset + initialOffset;
+ long filesOffset = initialOffset + cabinetHeader.FilesOffset;
if (filesOffset > data.Length)
return null;
diff --git a/SabreTools.Serialization/Deserializers/MoPaQ.cs b/SabreTools.Serialization/Deserializers/MoPaQ.cs
index 535333a9..9445133a 100644
--- a/SabreTools.Serialization/Deserializers/MoPaQ.cs
+++ b/SabreTools.Serialization/Deserializers/MoPaQ.cs
@@ -19,6 +19,9 @@ namespace SabreTools.Serialization.Deserializers
try
{
+ // Cache the current offset
+ long initialOffset = data.Position;
+
// Create a new archive to fill
var archive = new Archive();
@@ -29,9 +32,6 @@ namespace SabreTools.Serialization.Deserializers
data.Seek(-4, SeekOrigin.Current);
if (possibleSignature == UserDataSignatureUInt32)
{
- // Save the current position for offset correction
- long basePtr = data.Position;
-
// Deserialize the user data, returning null if invalid
var userData = ParseUserData(data);
if (userData?.Signature != UserDataSignatureString)
@@ -41,7 +41,7 @@ namespace SabreTools.Serialization.Deserializers
archive.UserData = userData;
// Set the starting position according to the header offset
- data.Seek(basePtr + (int)archive.UserData.HeaderOffset, SeekOrigin.Begin);
+ data.Seek(initialOffset + archive.UserData.HeaderOffset, SeekOrigin.Begin);
}
#endregion
@@ -76,8 +76,8 @@ namespace SabreTools.Serialization.Deserializers
if (archive.ArchiveHeader.FormatVersion == FormatVersion.Format1)
{
// If we have a hash table
- long hashTableOffset = archive.ArchiveHeader.HashTablePosition;
- if (hashTableOffset != 0)
+ long hashTableOffset = initialOffset + archive.ArchiveHeader.HashTablePosition;
+ if (hashTableOffset > initialOffset)
{
// Seek to the offset
data.Seek(hashTableOffset, SeekOrigin.Begin);
@@ -103,8 +103,8 @@ namespace SabreTools.Serialization.Deserializers
|| archive.ArchiveHeader.FormatVersion == FormatVersion.Format3)
{
// If we have a hash table
- long hashTableOffset = ((uint)archive.ArchiveHeader.HashTablePositionHi << 23) | archive.ArchiveHeader.HashTablePosition;
- if (hashTableOffset != 0)
+ long hashTableOffset = initialOffset + (((uint)archive.ArchiveHeader.HashTablePositionHi << 23) | archive.ArchiveHeader.HashTablePosition);
+ if (hashTableOffset > initialOffset)
{
// Seek to the offset
data.Seek(hashTableOffset, SeekOrigin.Begin);
@@ -129,8 +129,8 @@ namespace SabreTools.Serialization.Deserializers
else if (archive.ArchiveHeader.FormatVersion == FormatVersion.Format4)
{
// If we have a hash table
- long hashTableOffset = ((uint)archive.ArchiveHeader.HashTablePositionHi << 23) | archive.ArchiveHeader.HashTablePosition;
- if (hashTableOffset != 0)
+ long hashTableOffset = initialOffset + (((uint)archive.ArchiveHeader.HashTablePositionHi << 23) | archive.ArchiveHeader.HashTablePosition);
+ if (hashTableOffset > initialOffset)
{
// Seek to the offset
data.Seek(hashTableOffset, SeekOrigin.Begin);
@@ -159,8 +159,8 @@ namespace SabreTools.Serialization.Deserializers
if (archive.ArchiveHeader.FormatVersion == FormatVersion.Format1)
{
// If we have a block table
- long blockTableOffset = archive.ArchiveHeader.BlockTablePosition;
- if (blockTableOffset != 0)
+ long blockTableOffset = initialOffset + archive.ArchiveHeader.BlockTablePosition;
+ if (blockTableOffset > initialOffset)
{
// Seek to the offset
data.Seek(blockTableOffset, SeekOrigin.Begin);
@@ -186,8 +186,8 @@ namespace SabreTools.Serialization.Deserializers
|| archive.ArchiveHeader.FormatVersion == FormatVersion.Format3)
{
// If we have a block table
- long blockTableOffset = ((uint)archive.ArchiveHeader.BlockTablePositionHi << 23) | archive.ArchiveHeader.BlockTablePosition;
- if (blockTableOffset != 0)
+ long blockTableOffset = initialOffset + (((uint)archive.ArchiveHeader.BlockTablePositionHi << 23) | archive.ArchiveHeader.BlockTablePosition);
+ if (blockTableOffset > initialOffset)
{
// Seek to the offset
data.Seek(blockTableOffset, SeekOrigin.Begin);
@@ -212,8 +212,8 @@ namespace SabreTools.Serialization.Deserializers
else if (archive.ArchiveHeader.FormatVersion == FormatVersion.Format4)
{
// If we have a block table
- long blockTableOffset = ((uint)archive.ArchiveHeader.BlockTablePositionHi << 23) | archive.ArchiveHeader.BlockTablePosition;
- if (blockTableOffset != 0)
+ long blockTableOffset = initialOffset + (((uint)archive.ArchiveHeader.BlockTablePositionHi << 23) | archive.ArchiveHeader.BlockTablePosition);
+ if (blockTableOffset > initialOffset)
{
// Seek to the offset
data.Seek(blockTableOffset, SeekOrigin.Begin);
@@ -242,8 +242,8 @@ namespace SabreTools.Serialization.Deserializers
if (archive.ArchiveHeader.FormatVersion >= FormatVersion.Format2)
{
// If we have a hi-block table
- long hiBlockTableOffset = (long)archive.ArchiveHeader.HiBlockTablePosition;
- if (hiBlockTableOffset != 0)
+ long hiBlockTableOffset = initialOffset + (long)archive.ArchiveHeader.HiBlockTablePosition;
+ if (hiBlockTableOffset > initialOffset)
{
// Seek to the offset
data.Seek(hiBlockTableOffset, SeekOrigin.Begin);
@@ -269,8 +269,8 @@ namespace SabreTools.Serialization.Deserializers
if (archive.ArchiveHeader.FormatVersion >= FormatVersion.Format3)
{
// If we have a BET table
- long betTableOffset = (long)archive.ArchiveHeader.BetTablePosition;
- if (betTableOffset != 0)
+ long betTableOffset = initialOffset + (long)archive.ArchiveHeader.BetTablePosition;
+ if (betTableOffset > initialOffset)
{
// Seek to the offset
data.Seek(betTableOffset, SeekOrigin.Begin);
@@ -292,8 +292,8 @@ namespace SabreTools.Serialization.Deserializers
if (archive.ArchiveHeader.FormatVersion >= FormatVersion.Format3)
{
// If we have a HET table
- long hetTableOffset = (long)archive.ArchiveHeader.HetTablePosition;
- if (hetTableOffset != 0)
+ long hetTableOffset = initialOffset + (long)archive.ArchiveHeader.HetTablePosition;
+ if (hetTableOffset > initialOffset)
{
// Seek to the offset
data.Seek(hetTableOffset, SeekOrigin.Begin);
diff --git a/SabreTools.Serialization/Deserializers/N3DS.cs b/SabreTools.Serialization/Deserializers/N3DS.cs
index 6943c449..3926657a 100644
--- a/SabreTools.Serialization/Deserializers/N3DS.cs
+++ b/SabreTools.Serialization/Deserializers/N3DS.cs
@@ -18,6 +18,9 @@ namespace SabreTools.Serialization.Deserializers
try
{
+ // Cache the current offset
+ long initialOffset = data.Position;
+
// Create a new cart image to fill
var cart = new Cart();
@@ -64,9 +67,9 @@ namespace SabreTools.Serialization.Deserializers
for (int i = 0; i < 8; i++)
{
// Find the offset to the partition
- long partitionOffset = cart.Header.PartitionsTable?[i]?.Offset ?? 0;
+ long partitionOffset = initialOffset + cart.Header.PartitionsTable?[i]?.Offset ?? 0;
partitionOffset *= mediaUnitSize;
- if (partitionOffset == 0)
+ if (partitionOffset <= initialOffset)
continue;
// Seek to the start of the partition
diff --git a/SabreTools.Serialization/Deserializers/NCF.cs b/SabreTools.Serialization/Deserializers/NCF.cs
index e63c83e2..ff67a165 100644
--- a/SabreTools.Serialization/Deserializers/NCF.cs
+++ b/SabreTools.Serialization/Deserializers/NCF.cs
@@ -17,6 +17,9 @@ namespace SabreTools.Serialization.Deserializers
try
{
+ // Cache the current offset
+ long initialOffset = data.Position;
+
// Create a new Half-Life No Cache to fill
var file = new Models.NCF.File();
@@ -37,7 +40,7 @@ namespace SabreTools.Serialization.Deserializers
#endregion
// Cache the current offset
- long initialOffset = data.Position;
+ long afterHeaderPosition = data.Position;
#region Directory Header
@@ -148,7 +151,7 @@ namespace SabreTools.Serialization.Deserializers
#endregion
// Seek to end of directory section, just in case
- data.Seek(initialOffset + directoryHeader.DirectorySize, SeekOrigin.Begin);
+ data.Seek(afterHeaderPosition + directoryHeader.DirectorySize, SeekOrigin.Begin);
#region Unknown Header
@@ -233,7 +236,7 @@ namespace SabreTools.Serialization.Deserializers
#endregion
// Seek to end of checksum section, just in case
- data.Seek(initialOffset + checksumHeader.ChecksumSize, SeekOrigin.Begin);
+ data.Seek(afterHeaderPosition + checksumHeader.ChecksumSize, SeekOrigin.Begin);
return file;
}
diff --git a/SabreTools.Serialization/Deserializers/NewExecutable.cs b/SabreTools.Serialization/Deserializers/NewExecutable.cs
index 20f639e1..28dbe005 100644
--- a/SabreTools.Serialization/Deserializers/NewExecutable.cs
+++ b/SabreTools.Serialization/Deserializers/NewExecutable.cs
@@ -20,7 +20,7 @@ namespace SabreTools.Serialization.Deserializers
try
{
// Cache the current offset
- int initialOffset = (int)data.Position;
+ long initialOffset = data.Position;
// Create a new executable to fill
var executable = new Executable();
@@ -53,9 +53,7 @@ namespace SabreTools.Serialization.Deserializers
#region Segment Table
// If the offset for the segment table doesn't exist
- int tableAddress = initialOffset
- + (int)stub.Header.NewExeHeaderAddr
- + header.SegmentTableOffset;
+ long tableAddress = initialOffset + stub.Header.NewExeHeaderAddr + header.SegmentTableOffset;
if (tableAddress >= data.Length)
return executable;
@@ -74,9 +72,7 @@ namespace SabreTools.Serialization.Deserializers
#region Resource Table
// If the offset for the segment table doesn't exist
- tableAddress = initialOffset
- + (int)stub.Header.NewExeHeaderAddr
- + header.ResourceTableOffset;
+ tableAddress = initialOffset + stub.Header.NewExeHeaderAddr + header.ResourceTableOffset;
if (tableAddress >= data.Length)
return executable;
@@ -91,12 +87,8 @@ namespace SabreTools.Serialization.Deserializers
#region Resident-Name Table
// If the offset for the resident-name table doesn't exist
- tableAddress = initialOffset
- + (int)stub.Header.NewExeHeaderAddr
- + header.ResidentNameTableOffset;
- int endOffset = initialOffset
- + (int)stub.Header.NewExeHeaderAddr
- + header.ModuleReferenceTableOffset;
+ tableAddress = initialOffset + stub.Header.NewExeHeaderAddr + header.ResidentNameTableOffset;
+ long endOffset = initialOffset + stub.Header.NewExeHeaderAddr + header.ModuleReferenceTableOffset;
if (tableAddress >= data.Length)
return executable;
@@ -111,9 +103,7 @@ namespace SabreTools.Serialization.Deserializers
#region Module-Reference Table
// If the offset for the module-reference table doesn't exist
- tableAddress = initialOffset
- + (int)stub.Header.NewExeHeaderAddr
- + header.ModuleReferenceTableOffset;
+ tableAddress = initialOffset + stub.Header.NewExeHeaderAddr + header.ModuleReferenceTableOffset;
if (tableAddress >= data.Length)
return executable;
@@ -132,12 +122,8 @@ namespace SabreTools.Serialization.Deserializers
#region Imported-Name Table
// If the offset for the imported-name table doesn't exist
- tableAddress = initialOffset
- + (int)stub.Header.NewExeHeaderAddr
- + header.ImportedNamesTableOffset;
- endOffset = initialOffset
- + (int)stub.Header.NewExeHeaderAddr
- + header.EntryTableOffset;
+ tableAddress = initialOffset + stub.Header.NewExeHeaderAddr + header.ImportedNamesTableOffset;
+ endOffset = initialOffset + stub.Header.NewExeHeaderAddr + header.EntryTableOffset;
if (tableAddress >= data.Length)
return executable;
@@ -152,13 +138,8 @@ namespace SabreTools.Serialization.Deserializers
#region Entry Table
// If the offset for the imported-name table doesn't exist
- tableAddress = initialOffset
- + (int)stub.Header.NewExeHeaderAddr
- + header.EntryTableOffset;
- endOffset = initialOffset
- + (int)stub.Header.NewExeHeaderAddr
- + header.EntryTableOffset
- + header.EntryTableSize;
+ tableAddress = initialOffset + stub.Header.NewExeHeaderAddr + header.EntryTableOffset;
+ endOffset = initialOffset + stub.Header.NewExeHeaderAddr + + header.EntryTableOffset + header.EntryTableSize;
if (tableAddress >= data.Length)
return executable;
@@ -173,11 +154,8 @@ namespace SabreTools.Serialization.Deserializers
#region Nonresident-Name Table
// If the offset for the nonresident-name table doesn't exist
- tableAddress = initialOffset
- + (int)header.NonResidentNamesTableOffset;
- endOffset = initialOffset
- + (int)header.NonResidentNamesTableOffset
- + header.NonResidentNameTableSize;
+ tableAddress = initialOffset + header.NonResidentNamesTableOffset;
+ endOffset = initialOffset + header.NonResidentNamesTableOffset + header.NonResidentNameTableSize;
if (tableAddress >= data.Length)
return executable;
@@ -204,7 +182,7 @@ namespace SabreTools.Serialization.Deserializers
/// Stream to parse
/// First address not part of the entry table
/// Filled entry table on success, null on error
- public static EntryTableBundle[] ParseEntryTable(Stream data, int endOffset)
+ public static EntryTableBundle[] ParseEntryTable(Stream data, long endOffset)
{
var entryTable = new List();
@@ -287,7 +265,7 @@ namespace SabreTools.Serialization.Deserializers
/// Stream to parse
/// First address not part of the imported-name table
/// Filled imported-name table on success, null on error
- public static Dictionary ParseImportedNameTable(Stream data, int endOffset)
+ public static Dictionary ParseImportedNameTable(Stream data, long endOffset)
{
var importedNameTable = new Dictionary();
@@ -381,7 +359,7 @@ namespace SabreTools.Serialization.Deserializers
/// Stream to parse
/// First address not part of the nonresident-name table
/// Filled nonresident-name table on success, null on error
- public static NonResidentNameTableEntry[] ParseNonResidentNameTable(Stream data, int endOffset)
+ public static NonResidentNameTableEntry[] ParseNonResidentNameTable(Stream data, long endOffset)
{
var residentNameTable = new List();
@@ -482,7 +460,7 @@ namespace SabreTools.Serialization.Deserializers
/// Stream to parse
/// First address not part of the resident-name table
/// Filled resident-name table on success, null on error
- public static ResidentNameTableEntry[] ParseResidentNameTable(Stream data, int endOffset)
+ public static ResidentNameTableEntry[] ParseResidentNameTable(Stream data, long endOffset)
{
var residentNameTable = new List();
diff --git a/SabreTools.Serialization/Deserializers/Nitro.cs b/SabreTools.Serialization/Deserializers/Nitro.cs
index 767802f5..839c35cd 100644
--- a/SabreTools.Serialization/Deserializers/Nitro.cs
+++ b/SabreTools.Serialization/Deserializers/Nitro.cs
@@ -17,6 +17,9 @@ namespace SabreTools.Serialization.Deserializers
try
{
+ // Cache the current offset
+ long initialOffset = data.Position;
+
// Create a new cart image to fill
var cart = new Cart();
@@ -38,7 +41,7 @@ namespace SabreTools.Serialization.Deserializers
#region Secure Area
// Try to get the secure area offset
- long secureAreaOffset = 0x4000;
+ long secureAreaOffset = initialOffset + 0x4000;
if (secureAreaOffset > data.Length)
return null;
@@ -53,8 +56,8 @@ namespace SabreTools.Serialization.Deserializers
#region Name Table
// Try to get the name table offset
- long nameTableOffset = cart.CommonHeader.FileNameTableOffset;
- if (nameTableOffset < 0 || nameTableOffset > data.Length)
+ long nameTableOffset = initialOffset + cart.CommonHeader.FileNameTableOffset;
+ if (nameTableOffset < initialOffset || nameTableOffset > data.Length)
return null;
// Seek to the name table
@@ -68,8 +71,8 @@ namespace SabreTools.Serialization.Deserializers
#region File Allocation Table
// Try to get the file allocation table offset
- long fileAllocationTableOffset = cart.CommonHeader.FileAllocationTableOffset;
- if (fileAllocationTableOffset < 0 || fileAllocationTableOffset > data.Length)
+ long fileAllocationTableOffset = initialOffset + cart.CommonHeader.FileAllocationTableOffset;
+ if (fileAllocationTableOffset < initialOffset || fileAllocationTableOffset > data.Length)
return null;
// Seek to the file allocation table
diff --git a/SabreTools.Serialization/Deserializers/PAK.cs b/SabreTools.Serialization/Deserializers/PAK.cs
index 69bc078b..2cf3a19e 100644
--- a/SabreTools.Serialization/Deserializers/PAK.cs
+++ b/SabreTools.Serialization/Deserializers/PAK.cs
@@ -17,6 +17,9 @@ namespace SabreTools.Serialization.Deserializers
try
{
+ // Cache the current offset
+ long initialOffset = data.Position;
+
// Create a new Half-Life Package to fill
var file = new Models.PAK.File();
@@ -35,8 +38,8 @@ namespace SabreTools.Serialization.Deserializers
#region Directory Items
// Get the directory items offset
- uint directoryItemsOffset = header.DirectoryOffset;
- if (directoryItemsOffset < 0 || directoryItemsOffset >= data.Length)
+ long directoryItemsOffset = initialOffset + header.DirectoryOffset;
+ if (directoryItemsOffset < initialOffset || directoryItemsOffset >= data.Length)
return null;
// Seek to the directory items
diff --git a/SabreTools.Serialization/Deserializers/PFF.cs b/SabreTools.Serialization/Deserializers/PFF.cs
index c2fa6eff..6d845597 100644
--- a/SabreTools.Serialization/Deserializers/PFF.cs
+++ b/SabreTools.Serialization/Deserializers/PFF.cs
@@ -17,6 +17,9 @@ namespace SabreTools.Serialization.Deserializers
try
{
+ // Cache the current offset
+ long initialOffset = data.Position;
+
// Create a new archive to fill
var archive = new Archive();
@@ -60,8 +63,8 @@ namespace SabreTools.Serialization.Deserializers
#region Segments
// Get the segments
- long offset = header.FileListOffset;
- if (offset < 0 || offset >= data.Length)
+ long offset = initialOffset + header.FileListOffset;
+ if (offset < initialOffset || offset >= data.Length)
return null;
// Seek to the segments
@@ -81,8 +84,8 @@ namespace SabreTools.Serialization.Deserializers
#region Footer
// Get the footer offset
- offset = header.FileListOffset + (header.FileSegmentSize * header.NumberOfFiles);
- if (offset < 0 || offset >= data.Length)
+ offset = initialOffset + header.FileListOffset + (header.FileSegmentSize * header.NumberOfFiles);
+ if (offset < initialOffset || offset >= data.Length)
return null;
// Seek to the footer
diff --git a/SabreTools.Serialization/Deserializers/PKZIP.cs b/SabreTools.Serialization/Deserializers/PKZIP.cs
index 2b971ce0..57fa4c88 100644
--- a/SabreTools.Serialization/Deserializers/PKZIP.cs
+++ b/SabreTools.Serialization/Deserializers/PKZIP.cs
@@ -23,13 +23,16 @@ namespace SabreTools.Serialization.Deserializers
try
{
+ // Cache the current offset
+ long initialOffset = data.Position;
+
var archive = new Archive();
#region End of Central Directory Record
// Find the end of central directory record
long eocdrOffset = SearchForEndOfCentralDirectoryRecord(data);
- if (eocdrOffset < 0 || eocdrOffset >= data.Length)
+ if (eocdrOffset < initialOffset || eocdrOffset >= data.Length)
return null;
// Seek to the end of central directory record
@@ -63,7 +66,7 @@ namespace SabreTools.Serialization.Deserializers
// Find the ZIP64 end of central directory locator
long eocdlOffset = SearchForZIP64EndOfCentralDirectoryLocator(data);
- if (eocdlOffset < 0 || eocdlOffset >= data.Length)
+ if (eocdlOffset < initialOffset || eocdlOffset >= data.Length)
return null;
// Seek to the ZIP64 end of central directory locator
@@ -78,11 +81,11 @@ namespace SabreTools.Serialization.Deserializers
archive.ZIP64EndOfCentralDirectoryLocator = eocdl64;
// Try to get the ZIP64 end of central directory record offset
- if ((long)eocdl64.CentralDirectoryOffset < 0 || (long)eocdl64.CentralDirectoryOffset >= data.Length)
+ if ((long)eocdl64.CentralDirectoryOffset < 0 || initialOffset + (long)eocdl64.CentralDirectoryOffset >= data.Length)
return null;
// Seek to the ZIP64 end of central directory record
- data.Seek((long)eocdl64.CentralDirectoryOffset, SeekOrigin.Begin);
+ data.Seek(initialOffset + (long)eocdl64.CentralDirectoryOffset, SeekOrigin.Begin);
// Read the ZIP64 end of central directory record
var eocdr64 = ParseEndOfCentralDirectoryRecord64(data);
@@ -101,12 +104,12 @@ namespace SabreTools.Serialization.Deserializers
long cdrOffset, cdrSize;
if (zip64 && archive.ZIP64EndOfCentralDirectoryRecord != null)
{
- cdrOffset = (long)archive.ZIP64EndOfCentralDirectoryRecord.CentralDirectoryOffset;
+ cdrOffset = initialOffset + (long)archive.ZIP64EndOfCentralDirectoryRecord.CentralDirectoryOffset;
cdrSize = (long)archive.ZIP64EndOfCentralDirectoryRecord.CentralDirectorySize;
}
else if (archive.EndOfCentralDirectoryRecord != null)
{
- cdrOffset = archive.EndOfCentralDirectoryRecord.CentralDirectoryOffset;
+ cdrOffset = initialOffset + archive.EndOfCentralDirectoryRecord.CentralDirectoryOffset;
cdrSize = archive.EndOfCentralDirectoryRecord.CentralDirectorySize;
}
else
@@ -115,7 +118,7 @@ namespace SabreTools.Serialization.Deserializers
}
// Try to get the central directory record offset
- if (cdrOffset < 0 || cdrOffset >= data.Length)
+ if (cdrOffset < initialOffset || cdrOffset >= data.Length)
return null;
// Seek to the first central directory record
@@ -188,11 +191,11 @@ namespace SabreTools.Serialization.Deserializers
headerOffset = BitConverter.ToInt64(extraData, 4);
}
- if (headerOffset < 0 || headerOffset >= data.Length)
+ if (headerOffset < 0 || initialOffset + headerOffset >= data.Length)
return null;
// Seek to the local file header
- data.Seek(headerOffset, SeekOrigin.Begin);
+ data.Seek(initialOffset + headerOffset, SeekOrigin.Begin);
// Try to parse the local header
var localFileHeader = ParseLocalFileHeader(data);
@@ -212,7 +215,7 @@ namespace SabreTools.Serialization.Deserializers
// Only read the encryption header if necessary
#if NET20 || NET35
- if ((header.Flags & GeneralPurposeBitFlags.FileEncrypted) != 0)
+ if ((header.Flags & GeneralPurposeBitFlags.FileEncrypted) != 0)
#else
if (header.Flags.HasFlag(GeneralPurposeBitFlags.FileEncrypted))
#endif
@@ -241,7 +244,7 @@ namespace SabreTools.Serialization.Deserializers
// Only read the data descriptor if necessary
#if NET20 || NET35
- if ((header.Flags & GeneralPurposeBitFlags.NoCRC) != 0)
+ if ((header.Flags & GeneralPurposeBitFlags.NoCRC) != 0)
#else
if (header.Flags.HasFlag(GeneralPurposeBitFlags.NoCRC))
#endif
diff --git a/SabreTools.Serialization/Deserializers/PlayJAudio.cs b/SabreTools.Serialization/Deserializers/PlayJAudio.cs
index d34b98ac..7df645dc 100644
--- a/SabreTools.Serialization/Deserializers/PlayJAudio.cs
+++ b/SabreTools.Serialization/Deserializers/PlayJAudio.cs
@@ -8,20 +8,8 @@ namespace SabreTools.Serialization.Deserializers
{
public class PlayJAudio : BaseBinaryDeserializer
{
- ///
- public static AudioFile? DeserializeStream(Stream? data, long adjust = 0)
- {
- var deserializer = new PlayJAudio();
- return deserializer.Deserialize(data, adjust);
- }
-
///
public override AudioFile? Deserialize(Stream? data)
- => Deserialize(data, 0);
-
- ///
- /// Offset to adjust all seeking by
- public AudioFile? Deserialize(Stream? data, long adjust)
{
// If the data is invalid
if (data == null || !data.CanRead)
@@ -29,6 +17,9 @@ namespace SabreTools.Serialization.Deserializers
try
{
+ // Cache the current offset
+ long initialOffset = data.Position;
+
// Create a new audio file to fill
var audioFile = new AudioFile();
@@ -54,8 +45,8 @@ namespace SabreTools.Serialization.Deserializers
if (unknownOffset1 > 0)
{
// Get the unknown block 1 offset
- long offset = unknownOffset1 + adjust;
- if (offset < 0 || offset >= data.Length)
+ long offset = initialOffset + unknownOffset1;
+ if (offset < initialOffset || offset >= data.Length)
return null;
// Seek to the unknown block 1
@@ -86,8 +77,8 @@ namespace SabreTools.Serialization.Deserializers
if (unknownOffset2 != null && unknownOffset2 > 0)
{
// Get the unknown value 2 offset
- long offset = unknownOffset2.Value + adjust;
- if (offset < 0 || offset >= data.Length)
+ long offset = initialOffset + unknownOffset2.Value;
+ if (offset < initialOffset || offset >= data.Length)
return null;
// Seek to the unknown value 2
@@ -108,8 +99,8 @@ namespace SabreTools.Serialization.Deserializers
if (unknownOffset3 != null && unknownOffset3 > 0)
{
// Get the unknown block 3 offset
- long offset = unknownOffset3.Value + adjust;
- if (offset < 0 || offset >= data.Length)
+ long offset = initialOffset + unknownOffset3.Value;
+ if (offset < initialOffset || offset >= data.Length)
return null;
// Seek to the unknown block 3
diff --git a/SabreTools.Serialization/Deserializers/PlayJPlaylist.cs b/SabreTools.Serialization/Deserializers/PlayJPlaylist.cs
index 9102ee35..ebc393e5 100644
--- a/SabreTools.Serialization/Deserializers/PlayJPlaylist.cs
+++ b/SabreTools.Serialization/Deserializers/PlayJPlaylist.cs
@@ -38,8 +38,7 @@ namespace SabreTools.Serialization.Deserializers
// Try to parse the audio files
for (int i = 0; i < playlist.AudioFiles.Length; i++)
{
- long currentOffset = data.Position;
- var entryHeader = PlayJAudio.DeserializeStream(data, currentOffset);
+ var entryHeader = PlayJAudio.DeserializeStream(data);
if (entryHeader == null)
continue;
diff --git a/SabreTools.Serialization/Deserializers/PortableExecutable.cs b/SabreTools.Serialization/Deserializers/PortableExecutable.cs
index 906511dc..21cf94df 100644
--- a/SabreTools.Serialization/Deserializers/PortableExecutable.cs
+++ b/SabreTools.Serialization/Deserializers/PortableExecutable.cs
@@ -90,7 +90,7 @@ namespace SabreTools.Serialization.Deserializers
// TODO: Validate that this is correct with an "old" PE
long symbolTableAddress = initialOffset + coffFileHeader.PointerToSymbolTable;
- if (symbolTableAddress != 0 && symbolTableAddress < data.Length)
+ if (symbolTableAddress > initialOffset && symbolTableAddress < data.Length)
{
// Seek to the COFF symbol table
data.Seek(symbolTableAddress, SeekOrigin.Begin);
@@ -112,13 +112,13 @@ namespace SabreTools.Serialization.Deserializers
{
long exportTableAddress = initialOffset
+ optionalHeader.ExportTable.VirtualAddress.ConvertVirtualAddress(executable.SectionTable);
- if (exportTableAddress != 0 && exportTableAddress < data.Length)
+ if (exportTableAddress > initialOffset && exportTableAddress < data.Length)
{
// Seek to the export table
data.Seek(exportTableAddress, SeekOrigin.Begin);
// Set the export table
- executable.ExportTable = ParseExportTable(data, executable.SectionTable);
+ executable.ExportTable = ParseExportTable(data, initialOffset, executable.SectionTable);
}
}
@@ -131,13 +131,13 @@ namespace SabreTools.Serialization.Deserializers
{
long importTableAddress = initialOffset
+ optionalHeader.ImportTable.VirtualAddress.ConvertVirtualAddress(executable.SectionTable);
- if (importTableAddress != 0 && importTableAddress < data.Length)
+ if (importTableAddress > initialOffset && importTableAddress < data.Length)
{
// Seek to the import table
data.Seek(importTableAddress, SeekOrigin.Begin);
// Set the import table
- executable.ImportTable = ParseImportTable(data, optionalHeader.Magic, executable.SectionTable);
+ executable.ImportTable = ParseImportTable(data, initialOffset, optionalHeader.Magic, executable.SectionTable);
}
}
@@ -150,7 +150,7 @@ namespace SabreTools.Serialization.Deserializers
{
long resourceTableAddress = initialOffset
+ optionalHeader.ResourceTable.VirtualAddress.ConvertVirtualAddress(executable.SectionTable);
- if (resourceTableAddress != 0 && resourceTableAddress < data.Length)
+ if (resourceTableAddress > initialOffset && resourceTableAddress < data.Length)
{
// Seek to the resource directory table
data.Seek(resourceTableAddress, SeekOrigin.Begin);
@@ -170,7 +170,7 @@ namespace SabreTools.Serialization.Deserializers
{
long certificateTableAddress = initialOffset
+ optionalHeader.CertificateTable.VirtualAddress.ConvertVirtualAddress(executable.SectionTable);
- if (certificateTableAddress != 0 && certificateTableAddress < data.Length)
+ if (certificateTableAddress > initialOffset && certificateTableAddress < data.Length)
{
// Seek to the attribute certificate table
data.Seek(certificateTableAddress, SeekOrigin.Begin);
@@ -190,7 +190,7 @@ namespace SabreTools.Serialization.Deserializers
{
long baseRelocationTableAddress = initialOffset
+ optionalHeader.BaseRelocationTable.VirtualAddress.ConvertVirtualAddress(executable.SectionTable);
- if (baseRelocationTableAddress != 0 && baseRelocationTableAddress < data.Length)
+ if (baseRelocationTableAddress > initialOffset && baseRelocationTableAddress < data.Length)
{
// Seek to the base relocation table
data.Seek(baseRelocationTableAddress, SeekOrigin.Begin);
@@ -210,7 +210,7 @@ namespace SabreTools.Serialization.Deserializers
{
long debugTableAddress = initialOffset
+ optionalHeader.Debug.VirtualAddress.ConvertVirtualAddress(executable.SectionTable);
- if (debugTableAddress != 0 && debugTableAddress < data.Length)
+ if (debugTableAddress > initialOffset && debugTableAddress < data.Length)
{
// Seek to the debug table
data.Seek(debugTableAddress, SeekOrigin.Begin);
@@ -236,7 +236,7 @@ namespace SabreTools.Serialization.Deserializers
{
long delayLoadDirectoryTableAddress = initialOffset
+ optionalHeader.DelayImportDescriptor.VirtualAddress.ConvertVirtualAddress(executable.SectionTable);
- if (delayLoadDirectoryTableAddress != 0 && delayLoadDirectoryTableAddress < data.Length)
+ if (delayLoadDirectoryTableAddress > initialOffset && delayLoadDirectoryTableAddress < data.Length)
{
// Seek to the delay-load directory table
data.Seek(delayLoadDirectoryTableAddress, SeekOrigin.Begin);
@@ -664,9 +664,10 @@ namespace SabreTools.Serialization.Deserializers
/// Parse a Stream into a ExportTable
///
/// Stream to parse
+ /// Initial offset to use in address comparisons
/// Section table to use for virtual address translation
/// Filled ExportTable on success, null on error
- public static ExportTable ParseExportTable(Stream data, SectionHeader[] sections)
+ public static ExportTable ParseExportTable(Stream data, long initialOffset, SectionHeader[] sections)
{
var exportTable = new ExportTable();
@@ -689,7 +690,8 @@ namespace SabreTools.Serialization.Deserializers
// Name
if (exportDirectoryTable.NameRVA.ConvertVirtualAddress(sections) != 0)
{
- uint nameAddress = exportDirectoryTable.NameRVA.ConvertVirtualAddress(sections);
+ long nameAddress = initialOffset
+ + exportDirectoryTable.NameRVA.ConvertVirtualAddress(sections);
data.Seek(nameAddress, SeekOrigin.Begin);
string? name = data.ReadNullTerminatedAnsiString();
@@ -699,7 +701,8 @@ namespace SabreTools.Serialization.Deserializers
// Address table
if (exportDirectoryTable.AddressTableEntries != 0 && exportDirectoryTable.ExportAddressTableRVA.ConvertVirtualAddress(sections) != 0)
{
- uint exportAddressTableAddress = exportDirectoryTable.ExportAddressTableRVA.ConvertVirtualAddress(sections);
+ long exportAddressTableAddress = initialOffset
+ + exportDirectoryTable.ExportAddressTableRVA.ConvertVirtualAddress(sections);
data.Seek(exportAddressTableAddress, SeekOrigin.Begin);
var exportAddressTable = new ExportAddressTableEntry[exportDirectoryTable.AddressTableEntries];
@@ -715,7 +718,8 @@ namespace SabreTools.Serialization.Deserializers
// Name pointer table
if (exportDirectoryTable.NumberOfNamePointers != 0 && exportDirectoryTable.NamePointerRVA.ConvertVirtualAddress(sections) != 0)
{
- uint namePointerTableAddress = exportDirectoryTable.NamePointerRVA.ConvertVirtualAddress(sections);
+ long namePointerTableAddress = initialOffset
+ + exportDirectoryTable.NamePointerRVA.ConvertVirtualAddress(sections);
data.Seek(namePointerTableAddress, SeekOrigin.Begin);
var namePointerTable = new ExportNamePointerTable();
@@ -733,7 +737,8 @@ namespace SabreTools.Serialization.Deserializers
// Ordinal table
if (exportDirectoryTable.NumberOfNamePointers != 0 && exportDirectoryTable.OrdinalTableRVA.ConvertVirtualAddress(sections) != 0)
{
- uint ordinalTableAddress = exportDirectoryTable.OrdinalTableRVA.ConvertVirtualAddress(sections);
+ long ordinalTableAddress = initialOffset
+ + exportDirectoryTable.OrdinalTableRVA.ConvertVirtualAddress(sections);
data.Seek(ordinalTableAddress, SeekOrigin.Begin);
var exportOrdinalTable = new ExportOrdinalTable();
@@ -756,7 +761,8 @@ namespace SabreTools.Serialization.Deserializers
exportNameTable.Strings = new string[exportDirectoryTable.NumberOfNamePointers];
for (int i = 0; i < exportDirectoryTable.NumberOfNamePointers; i++)
{
- uint nameAddress = exportTable.NamePointerTable.Pointers[i].ConvertVirtualAddress(sections); ;
+ long nameAddress = initialOffset
+ + exportTable.NamePointerTable.Pointers[i].ConvertVirtualAddress(sections); ;
data.Seek(nameAddress, SeekOrigin.Begin);
string? str = data.ReadNullTerminatedAnsiString();
@@ -806,10 +812,11 @@ namespace SabreTools.Serialization.Deserializers
/// Parse a Stream into a import table
///
/// Stream to parse
+ /// Initial offset to use in address comparisons
/// Optional header magic number indicating PE32 or PE32+
/// Section table to use for virtual address translation
/// Filled import table on success, null on error
- public static ImportTable ParseImportTable(Stream data, OptionalHeaderMagicNumber magic, SectionHeader[] sections)
+ public static ImportTable ParseImportTable(Stream data, long initialOffset, OptionalHeaderMagicNumber magic, SectionHeader[] sections)
{
var importTable = new ImportTable();
@@ -843,7 +850,8 @@ namespace SabreTools.Serialization.Deserializers
if (importDirectoryTableEntry.NameRVA.ConvertVirtualAddress(sections) == 0)
continue;
- uint nameAddress = importDirectoryTableEntry.NameRVA.ConvertVirtualAddress(sections);
+ long nameAddress = initialOffset
+ + importDirectoryTableEntry.NameRVA.ConvertVirtualAddress(sections);
data.Seek(nameAddress, SeekOrigin.Begin);
string? name = data.ReadNullTerminatedAnsiString();
@@ -862,7 +870,8 @@ namespace SabreTools.Serialization.Deserializers
if (importDirectoryTableEntry.ImportLookupTableRVA.ConvertVirtualAddress(sections) == 0)
continue;
- uint tableAddress = importDirectoryTableEntry.ImportLookupTableRVA.ConvertVirtualAddress(sections);
+ long tableAddress = initialOffset
+ + importDirectoryTableEntry.ImportLookupTableRVA.ConvertVirtualAddress(sections);
data.Seek(tableAddress, SeekOrigin.Begin);
var entryLookupTable = new List();
@@ -916,7 +925,8 @@ namespace SabreTools.Serialization.Deserializers
if (importDirectoryTableEntry.ImportAddressTableRVA.ConvertVirtualAddress(sections) == 0)
continue;
- uint tableAddress = importDirectoryTableEntry.ImportAddressTableRVA.ConvertVirtualAddress(sections);
+ long tableAddress = initialOffset
+ + importDirectoryTableEntry.ImportAddressTableRVA.ConvertVirtualAddress(sections);
data.Seek(tableAddress, SeekOrigin.Begin);
var addressLookupTable = new List();
@@ -1017,7 +1027,8 @@ namespace SabreTools.Serialization.Deserializers
hintNameTableEntryAddresses.Sort();
for (int i = 0; i < hintNameTableEntryAddresses.Count; i++)
{
- int hintNameTableEntryAddress = hintNameTableEntryAddresses[i];
+ long hintNameTableEntryAddress = initialOffset
+ + hintNameTableEntryAddresses[i];
data.Seek(hintNameTableEntryAddress, SeekOrigin.Begin);
var hintNameTableEntry = ParseHintNameTableEntry(data);
@@ -1199,7 +1210,7 @@ namespace SabreTools.Serialization.Deserializers
if (entry.NameOffset > 0)
{
long currentOffset = data.Position;
- offset = entry.NameOffset + (uint)initialOffset;
+ long nameOffset = initialOffset + entry.NameOffset;
data.Seek(offset, SeekOrigin.Begin);
var resourceDirectoryString = new ResourceDirectoryString();
@@ -1224,7 +1235,7 @@ namespace SabreTools.Serialization.Deserializers
if (entry.DataEntryOffset > 0)
{
- uint offset = entry.DataEntryOffset + (uint)initialOffset;
+ long offset = initialOffset + entry.DataEntryOffset;
data.Seek(offset, SeekOrigin.Begin);
var resourceDataEntry = new ResourceDataEntry();
@@ -1234,7 +1245,7 @@ namespace SabreTools.Serialization.Deserializers
resourceDataEntry.Reserved = data.ReadUInt32LittleEndian();
// Read the data from the offset
- offset = resourceDataEntry.DataRVA.ConvertVirtualAddress(sections);
+ offset = initialOffset + resourceDataEntry.DataRVA.ConvertVirtualAddress(sections);
if (offset > 0 && resourceDataEntry.Size > 0 && offset + (int)resourceDataEntry.Size < data.Length)
{
data.Seek(offset, SeekOrigin.Begin);
@@ -1245,7 +1256,7 @@ namespace SabreTools.Serialization.Deserializers
}
else if (entry.SubdirectoryOffset > 0)
{
- uint offset = entry.SubdirectoryOffset + (uint)initialOffset;
+ long offset = initialOffset + entry.SubdirectoryOffset;
data.Seek(offset, SeekOrigin.Begin);
entry.Subdirectory = ParseResourceDirectoryTable(data, initialOffset, sections);
diff --git a/SabreTools.Serialization/Deserializers/SGA.cs b/SabreTools.Serialization/Deserializers/SGA.cs
index e40a3d4e..626f4607 100644
--- a/SabreTools.Serialization/Deserializers/SGA.cs
+++ b/SabreTools.Serialization/Deserializers/SGA.cs
@@ -18,6 +18,9 @@ namespace SabreTools.Serialization.Deserializers
try
{
+ // Cache the current offset
+ long initialOffset = data.Position;
+
// Create a new SGA to fill
var archive = new Archive();
@@ -158,11 +161,10 @@ namespace SabreTools.Serialization.Deserializers
#region Sections
// Get and adjust the sections offset
- long sectionOffset = directoryHeader.SectionOffset;
- sectionOffset += currentOffset;
+ long sectionOffset = currentOffset + directoryHeader.SectionOffset;
// Validate the offset
- if (sectionOffset < 0 || sectionOffset >= data.Length)
+ if (sectionOffset < currentOffset || sectionOffset >= data.Length)
return null;
// Seek to the sections
@@ -182,11 +184,10 @@ namespace SabreTools.Serialization.Deserializers
#region Folders
// Get and adjust the folders offset
- long folderOffset = directoryHeader.FolderOffset;
- folderOffset += currentOffset;
+ long folderOffset = currentOffset + directoryHeader.FolderOffset;
// Validate the offset
- if (folderOffset < 0 || folderOffset >= data.Length)
+ if (folderOffset < currentOffset || folderOffset >= data.Length)
return null;
// Seek to the folders
@@ -206,11 +207,10 @@ namespace SabreTools.Serialization.Deserializers
#region Files
// Get and adjust the files offset
- long fileOffset = directoryHeader.FileOffset;
- fileOffset += currentOffset;
+ long fileOffset = currentOffset + directoryHeader.FileOffset;
// Validate the offset
- if (fileOffset < 0 || fileOffset >= data.Length)
+ if (fileOffset < currentOffset || fileOffset >= data.Length)
return null;
// Seek to the files
@@ -233,11 +233,10 @@ namespace SabreTools.Serialization.Deserializers
#region String Table
// Get and adjust the string table offset
- long stringTableOffset = directoryHeader.StringTableOffset;
- stringTableOffset += currentOffset;
+ long stringTableOffset = currentOffset + directoryHeader.StringTableOffset;
// Validate the offset
- if (stringTableOffset < 0 || stringTableOffset >= data.Length)
+ if (stringTableOffset < currentOffset || stringTableOffset >= data.Length)
return null;
// Seek to the string table
@@ -311,11 +310,10 @@ namespace SabreTools.Serialization.Deserializers
#region Sections
// Get and adjust the sections offset
- long sectionOffset = directoryHeader.SectionOffset;
- sectionOffset += currentOffset;
+ long sectionOffset = currentOffset + directoryHeader.SectionOffset;
// Validate the offset
- if (sectionOffset < 0 || sectionOffset >= data.Length)
+ if (sectionOffset < currentOffset || sectionOffset >= data.Length)
return null;
// Seek to the sections
@@ -335,11 +333,10 @@ namespace SabreTools.Serialization.Deserializers
#region Folders
// Get and adjust the folders offset
- long folderOffset = directoryHeader.FolderOffset;
- folderOffset += currentOffset;
+ long folderOffset = currentOffset + directoryHeader.FolderOffset;
// Validate the offset
- if (folderOffset < 0 || folderOffset >= data.Length)
+ if (folderOffset < currentOffset || folderOffset >= data.Length)
return null;
// Seek to the folders
@@ -359,11 +356,10 @@ namespace SabreTools.Serialization.Deserializers
#region Files
// Get and adjust the files offset
- long fileOffset = directoryHeader.FileOffset;
- fileOffset += currentOffset;
+ long fileOffset = currentOffset + directoryHeader.FileOffset;
// Validate the offset
- if (fileOffset < 0 || fileOffset >= data.Length)
+ if (fileOffset < currentOffset || fileOffset >= data.Length)
return null;
// Seek to the files
@@ -383,11 +379,10 @@ namespace SabreTools.Serialization.Deserializers
#region String Table
// Get and adjust the string table offset
- long stringTableOffset = directoryHeader.StringTableOffset;
- stringTableOffset += currentOffset;
+ long stringTableOffset = currentOffset + directoryHeader.StringTableOffset;
// Validate the offset
- if (stringTableOffset < 0 || stringTableOffset >= data.Length)
+ if (stringTableOffset < currentOffset || stringTableOffset >= data.Length)
return null;
// Seek to the string table
@@ -461,11 +456,10 @@ namespace SabreTools.Serialization.Deserializers
#region Sections
// Get and adjust the sections offset
- long sectionOffset = directoryHeader.SectionOffset;
- sectionOffset += currentOffset;
+ long sectionOffset = currentOffset + directoryHeader.SectionOffset;
// Validate the offset
- if (sectionOffset < 0 || sectionOffset >= data.Length)
+ if (sectionOffset < currentOffset || sectionOffset >= data.Length)
return null;
// Seek to the sections
@@ -485,11 +479,10 @@ namespace SabreTools.Serialization.Deserializers
#region Folders
// Get and adjust the folders offset
- long folderOffset = directoryHeader.FolderOffset;
- folderOffset += currentOffset;
+ long folderOffset = currentOffset + directoryHeader.FolderOffset;
// Validate the offset
- if (folderOffset < 0 || folderOffset >= data.Length)
+ if (folderOffset < currentOffset || folderOffset >= data.Length)
return null;
// Seek to the folders
@@ -509,11 +502,10 @@ namespace SabreTools.Serialization.Deserializers
#region Files
// Get and adjust the files offset
- long fileOffset = directoryHeader.FileOffset;
- fileOffset += currentOffset;
+ long fileOffset = currentOffset + directoryHeader.FileOffset;
// Validate the offset
- if (fileOffset < 0 || fileOffset >= data.Length)
+ if (fileOffset < currentOffset || fileOffset >= data.Length)
return null;
// Seek to the files
@@ -533,11 +525,10 @@ namespace SabreTools.Serialization.Deserializers
#region String Table
// Get and adjust the string table offset
- long stringTableOffset = directoryHeader.StringTableOffset;
- stringTableOffset += currentOffset;
+ long stringTableOffset = currentOffset + directoryHeader.StringTableOffset;
// Validate the offset
- if (stringTableOffset < 0 || stringTableOffset >= data.Length)
+ if (stringTableOffset < currentOffset || stringTableOffset >= data.Length)
return null;
// Seek to the string table
@@ -611,11 +602,10 @@ namespace SabreTools.Serialization.Deserializers
#region Sections
// Get and adjust the sections offset
- long sectionOffset = directoryHeader.SectionOffset;
- sectionOffset += currentOffset;
+ long sectionOffset = currentOffset + directoryHeader.SectionOffset;
// Validate the offset
- if (sectionOffset < 0 || sectionOffset >= data.Length)
+ if (sectionOffset < currentOffset || sectionOffset >= data.Length)
return null;
// Seek to the sections
@@ -635,11 +625,10 @@ namespace SabreTools.Serialization.Deserializers
#region Folders
// Get and adjust the folders offset
- long folderOffset = directoryHeader.FolderOffset;
- folderOffset += currentOffset;
+ long folderOffset = currentOffset + directoryHeader.FolderOffset;
// Validate the offset
- if (folderOffset < 0 || folderOffset >= data.Length)
+ if (folderOffset < currentOffset || folderOffset >= data.Length)
return null;
// Seek to the folders
@@ -659,11 +648,10 @@ namespace SabreTools.Serialization.Deserializers
#region Files
// Get and adjust the files offset
- long fileOffset = directoryHeader.FileOffset;
- fileOffset += currentOffset;
+ long fileOffset = currentOffset + directoryHeader.FileOffset;
// Validate the offset
- if (fileOffset < 0 || fileOffset >= data.Length)
+ if (fileOffset < currentOffset || fileOffset >= data.Length)
return null;
// Seek to the files
@@ -683,11 +671,10 @@ namespace SabreTools.Serialization.Deserializers
#region String Table
// Get and adjust the string table offset
- long stringTableOffset = directoryHeader.StringTableOffset;
- stringTableOffset += currentOffset;
+ long stringTableOffset = currentOffset + directoryHeader.StringTableOffset;
// Validate the offset
- if (stringTableOffset < 0 || stringTableOffset >= data.Length)
+ if (stringTableOffset < currentOffset || stringTableOffset >= data.Length)
return null;
// Seek to the string table
diff --git a/SabreTools.Serialization/Deserializers/VBSP.cs b/SabreTools.Serialization/Deserializers/VBSP.cs
index dafe101e..be00dbc7 100644
--- a/SabreTools.Serialization/Deserializers/VBSP.cs
+++ b/SabreTools.Serialization/Deserializers/VBSP.cs
@@ -20,6 +20,9 @@ namespace SabreTools.Serialization.Deserializers
try
{
+ // Cache the current offset
+ long initialOffset = data.Position;
+
// Create a new Half-Life 2 Level to fill
var file = new VbspFile();
@@ -51,7 +54,7 @@ namespace SabreTools.Serialization.Deserializers
continue;
// Seek to the lump offset
- data.Seek(lumpEntry.Offset, SeekOrigin.Begin);
+ data.Seek(initialOffset + lumpEntry.Offset, SeekOrigin.Begin);
// Read according to the lump type
switch ((LumpType)l)
diff --git a/SabreTools.Serialization/Deserializers/VPK.cs b/SabreTools.Serialization/Deserializers/VPK.cs
index 05d2eecc..0275a230 100644
--- a/SabreTools.Serialization/Deserializers/VPK.cs
+++ b/SabreTools.Serialization/Deserializers/VPK.cs
@@ -17,6 +17,9 @@ namespace SabreTools.Serialization.Deserializers
try
{
+ // Cache the current offset
+ long initialOffset = data.Position;
+
// Create a new Valve Package to fill
var file = new Models.VPK.File();
@@ -45,7 +48,7 @@ namespace SabreTools.Serialization.Deserializers
#region Directory Items
// Set the directory items
- file.DirectoryItems = ParseDirectoryItemTree(data);
+ file.DirectoryItems = ParseDirectoryItemTree(data, initialOffset);
#endregion
@@ -60,10 +63,10 @@ namespace SabreTools.Serialization.Deserializers
var archiveHashes = new List();
// Cache the current offset
- long initialOffset = data.Position;
+ long afterHeaderOffset = data.Position;
// Try to parse the directory items
- while (data.Position < initialOffset + file.ExtendedHeader.ArchiveMD5SectionSize)
+ while (data.Position < afterHeaderOffset + file.ExtendedHeader.ArchiveMD5SectionSize)
{
var archiveHash = ParseArchiveHash(data);
archiveHashes.Add(archiveHash);
@@ -123,8 +126,9 @@ namespace SabreTools.Serialization.Deserializers
/// Parse a Stream into a Valve Package directory item
///
/// Stream to parse
+ /// Initial offset to use in address comparisons
/// Filled Valve Package directory item on success, null on error
- public static DirectoryItem ParseDirectoryItem(Stream data, string extension, string path, string name)
+ public static DirectoryItem ParseDirectoryItem(Stream data, long initialOffset, string extension, string path, string name)
{
var obj = new DirectoryItem();
@@ -141,7 +145,7 @@ namespace SabreTools.Serialization.Deserializers
&& obj.DirectoryEntry.EntryLength > 0
&& data.Position + obj.DirectoryEntry.EntryLength <= data.Length)
{
- preloadDataPointer = obj.DirectoryEntry.EntryOffset;
+ preloadDataPointer = initialOffset + obj.DirectoryEntry.EntryOffset;
preloadDataLength = (int)obj.DirectoryEntry.EntryLength;
}
else if (obj.DirectoryEntry.PreloadBytes > 0)
@@ -152,12 +156,12 @@ namespace SabreTools.Serialization.Deserializers
// If we had a valid preload data pointer
byte[]? preloadData = null;
- if (preloadDataPointer >= 0
+ if (preloadDataPointer >= initialOffset
&& preloadDataLength > 0
&& data.Position + preloadDataLength <= data.Length)
{
// Cache the current offset
- long initialOffset = data.Position;
+ long currentOffset = data.Position;
// Seek to the preload data offset
data.Seek(preloadDataPointer, SeekOrigin.Begin);
@@ -166,7 +170,7 @@ namespace SabreTools.Serialization.Deserializers
preloadData = data.ReadBytes(preloadDataLength);
// Seek back to the original offset
- data.Seek(initialOffset, SeekOrigin.Begin);
+ data.Seek(currentOffset, SeekOrigin.Begin);
}
// Set the preload data
@@ -179,8 +183,9 @@ namespace SabreTools.Serialization.Deserializers
/// Parse a Stream into a Valve Package directory item tree
///
/// Stream to parse
+ /// Initial offset to use in address comparisons
/// Filled Valve Package directory item tree on success, null on error
- public static DirectoryItem[] ParseDirectoryItemTree(Stream data)
+ public static DirectoryItem[] ParseDirectoryItemTree(Stream data, long initialOffset)
{
// Create the directory items list
var directoryItems = new List();
@@ -225,7 +230,7 @@ namespace SabreTools.Serialization.Deserializers
}
// Get the directory item
- var directoryItem = ParseDirectoryItem(data, extensionString!, pathString!, nameString!);
+ var directoryItem = ParseDirectoryItem(data, initialOffset, extensionString!, pathString!, nameString!);
// Add the directory item
directoryItems.Add(directoryItem);
diff --git a/SabreTools.Serialization/Deserializers/WAD3.cs b/SabreTools.Serialization/Deserializers/WAD3.cs
index e8b8cc7b..f755bb30 100644
--- a/SabreTools.Serialization/Deserializers/WAD3.cs
+++ b/SabreTools.Serialization/Deserializers/WAD3.cs
@@ -17,6 +17,9 @@ namespace SabreTools.Serialization.Deserializers
try
{
+ // Cache the current offset
+ long initialOffset = data.Position;
+
// Create a new Half-Life Texture Package to fill
var file = new Models.WAD3.File();
@@ -35,8 +38,8 @@ namespace SabreTools.Serialization.Deserializers
#region Directory Entries
// Get the directory offset
- uint dirOffset = header.DirOffset;
- if (dirOffset < 0 || dirOffset >= data.Length)
+ long dirOffset = initialOffset + header.DirOffset;
+ if (dirOffset < initialOffset || dirOffset >= data.Length)
return null;
// Seek to the lump offset
@@ -66,8 +69,8 @@ namespace SabreTools.Serialization.Deserializers
continue;
// Get the file entry offset
- uint fileEntryOffset = dirEntry.Offset;
- if (fileEntryOffset < 0 || fileEntryOffset >= data.Length)
+ long fileEntryOffset = initialOffset + dirEntry.Offset;
+ if (fileEntryOffset < initialOffset || fileEntryOffset >= data.Length)
continue;
// Seek to the file entry offset
diff --git a/SabreTools.Serialization/Deserializers/XZP.cs b/SabreTools.Serialization/Deserializers/XZP.cs
index cb475b8f..a8237634 100644
--- a/SabreTools.Serialization/Deserializers/XZP.cs
+++ b/SabreTools.Serialization/Deserializers/XZP.cs
@@ -17,6 +17,9 @@ namespace SabreTools.Serialization.Deserializers
try
{
+ // Cache the current offset
+ long initialOffset = data.Position;
+
// Create a new XBox Package File to fill
var file = new Models.XZP.File();
@@ -84,8 +87,8 @@ namespace SabreTools.Serialization.Deserializers
if (header.DirectoryItemCount > 0)
{
// Get the directory item offset
- uint directoryItemOffset = header.DirectoryItemOffset;
- if (directoryItemOffset < 0 || directoryItemOffset >= data.Length)
+ long directoryItemOffset = initialOffset + header.DirectoryItemOffset;
+ if (directoryItemOffset < initialOffset || directoryItemOffset >= data.Length)
return null;
// Seek to the directory items
@@ -97,7 +100,7 @@ namespace SabreTools.Serialization.Deserializers
// Try to parse the directory items
for (int i = 0; i < file.DirectoryItems.Length; i++)
{
- file.DirectoryItems[i] = ParseDirectoryItem(data);
+ file.DirectoryItems[i] = ParseDirectoryItem(data, initialOffset);
}
}
@@ -147,8 +150,9 @@ namespace SabreTools.Serialization.Deserializers
/// Parse a Stream into a DirectoryItem
///
/// Stream to parse
+ /// Initial offset to use in address comparisons
/// Filled DirectoryItem on success, null on error
- public static DirectoryItem ParseDirectoryItem(Stream data)
+ public static DirectoryItem ParseDirectoryItem(Stream data, long initialOffset)
{
var obj = new DirectoryItem();
@@ -160,7 +164,7 @@ namespace SabreTools.Serialization.Deserializers
long currentPosition = data.Position;
// Seek to the name offset
- data.Seek(obj.NameOffset, SeekOrigin.Begin);
+ data.Seek(initialOffset + obj.NameOffset, SeekOrigin.Begin);
// Read the name
obj.Name = data.ReadNullTerminatedAnsiString();