diff --git a/SabreTools.Serialization/Deserializers/PortableExecutable.cs b/SabreTools.Serialization/Deserializers/PortableExecutable.cs
index ecf57e14..7a6665db 100644
--- a/SabreTools.Serialization/Deserializers/PortableExecutable.cs
+++ b/SabreTools.Serialization/Deserializers/PortableExecutable.cs
@@ -1417,9 +1417,16 @@ namespace SabreTools.Serialization.Deserializers
obj.Codepage = data.ReadUInt32LittleEndian();
obj.Reserved = data.ReadUInt32LittleEndian();
+ // Empty entries are valid
+ if (obj.Size == 0)
+ {
+ obj.Data = [];
+ return obj;
+ }
+
// Read the data from the offset
long offset = initialOffset + obj.DataRVA.ConvertVirtualAddress(sections);
- if (offset > initialOffset && obj.Size > 0 && offset + obj.Size < data.Length)
+ if (offset > initialOffset && offset + obj.Size < data.Length)
{
data.Seek(offset, SeekOrigin.Begin);
obj.Data = data.ReadBytes((int)obj.Size);
@@ -1432,26 +1439,26 @@ namespace SabreTools.Serialization.Deserializers
/// Parse a Stream into an ResourceDirectoryEntry
///
/// Stream to parse
+ /// Indicates if the value is a name entry or not
/// Table start address for relative reads
/// Filled ResourceDirectoryEntry on success, null on error
- public static ResourceDirectoryEntry ParseResourceDirectoryEntry(Stream data, long tableStart)
+ public static ResourceDirectoryEntry ParseResourceDirectoryEntry(Stream data, bool nameEntry, long tableStart)
{
var obj = new ResourceDirectoryEntry();
- uint first = data.ReadUInt32LittleEndian();
- if ((first & 0x80000000) != 0)
- obj.NameOffset = first & ~0x80000000;
+ if (nameEntry)
+ obj.NameOffset = data.ReadUInt32LittleEndian();
else
- obj.IntegerID = first;
+ obj.IntegerID = obj.NameOffset;
- uint second = data.ReadUInt32LittleEndian();
- if ((second & 0x80000000) != 0)
- obj.SubdirectoryOffset = second & ~0x80000000;
+ uint offset = data.ReadUInt32LittleEndian();
+ if ((offset & 0x80000000) != 0)
+ obj.SubdirectoryOffset = offset & ~0x80000000;
else
- obj.DataEntryOffset = second;
+ obj.DataEntryOffset = offset;
// Read the name from the offset, if needed
- if (obj.NameOffset > 0)
+ if (nameEntry && obj.NameOffset > 0)
{
long nameOffset = tableStart + obj.NameOffset;
if (nameOffset > tableStart && nameOffset < data.Length)
@@ -1505,24 +1512,22 @@ namespace SabreTools.Serialization.Deserializers
obj.NumberOfNameEntries = data.ReadUInt16LittleEndian();
obj.NumberOfIDEntries = data.ReadUInt16LittleEndian();
- // If we have no entries
+ // Create the entry array
int totalEntryCount = obj.NumberOfNameEntries + obj.NumberOfIDEntries;
- if (totalEntryCount == 0)
+ obj.Entries = new ResourceDirectoryEntry[totalEntryCount];
+ if (obj.Entries.Length == 0)
return obj;
// Perform top-level pass of data
- obj.Entries = new ResourceDirectoryEntry[totalEntryCount];
for (int i = 0; i < totalEntryCount; i++)
{
- obj.Entries[i] = ParseResourceDirectoryEntry(data, tableStart);
+ bool nameEntry = i < obj.NumberOfNameEntries;
+ obj.Entries[i] = ParseResourceDirectoryEntry(data, nameEntry, tableStart);
}
// Loop through and process the entries
foreach (var entry in obj.Entries)
{
- if (entry == null)
- continue;
-
if (entry.DataEntryOffset > 0)
{
long offset = tableStart + entry.DataEntryOffset;