Compare commits

..

8 Commits
1.6.4 ... 1.6.6

Author SHA1 Message Date
Matt Nadareski
4ae4cd80b1 Bump version 2024-05-30 21:07:04 -04:00
Matt Nadareski
6eb27c66fc Merge pull request #8 from TheRogueArchivist/streamdatalock
Add lock for reading data from stream
2024-05-30 12:30:33 -04:00
TheRogueArchivist
f96fd17fd3 Add lock for reading data from stream 2024-05-27 15:36:04 -06:00
Matt Nadareski
c255a2494d Fix IS-CAB file group name parsing 2024-05-18 21:27:09 -04:00
Matt Nadareski
86a9846300 Bump version 2024-05-15 15:10:58 -04:00
Matt Nadareski
db877d253c Update Models, fix build 2024-05-15 14:59:55 -04:00
Matt Nadareski
0acf1e3b08 Handle bounds-defying reads 2024-05-15 13:38:44 -04:00
Matt Nadareski
362ed3a9b6 Protect against odd end-of-stream issues 2024-05-15 13:08:51 -04:00
12 changed files with 144 additions and 145 deletions

View File

@@ -27,7 +27,7 @@
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.9.0" />
<PackageReference Include="SabreTools.Models" Version="1.4.6" />
<PackageReference Include="SabreTools.Models" Version="1.4.8" />
<PackageReference Include="xunit" Version="2.8.0" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.8.0">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>

View File

@@ -489,7 +489,7 @@ namespace SabreTools.Serialization.Deserializers
if (majorVersion >= 17)
fileGroup.Name = data.ReadNullTerminatedUnicodeString();
else
fileGroup.Name = data.ReadNullTerminatedUnicodeString();
fileGroup.Name = data.ReadNullTerminatedAnsiString();
}
// Seek back to the correct offset

View File

@@ -476,7 +476,7 @@ namespace SabreTools.Serialization.Deserializers
var entry = new ResidentNamesTableEntry();
entry.Length = data.ReadByteValue();
if (entry.Length > 0)
if (entry.Length > 0 && data.Position + entry.Length <= data.Length)
{
byte[]? name = data.ReadBytes(entry.Length);
if (name != null)
@@ -810,7 +810,7 @@ namespace SabreTools.Serialization.Deserializers
var entry = new ImportModuleNameTableEntry();
entry.Length = data.ReadByteValue();
if (entry.Length > 0)
if (entry.Length > 0 && data.Position + entry.Length <= data.Length)
{
byte[]? name = data.ReadBytes(entry.Length);
if (name != null)
@@ -831,7 +831,7 @@ namespace SabreTools.Serialization.Deserializers
var entry = new ImportModuleProcedureNameTableEntry();
entry.Length = data.ReadByteValue();
if (entry.Length > 0)
if (entry.Length > 0 && data.Position + entry.Length <= data.Length)
{
byte[]? name = data.ReadBytes(entry.Length);
if (name != null)
@@ -862,7 +862,7 @@ namespace SabreTools.Serialization.Deserializers
var entry = new NonResidentNamesTableEntry();
entry.Length = data.ReadByteValue();
if (entry.Length > 0)
if (entry.Length > 0 && data.Position + entry.Length <= data.Length)
{
byte[]? name = data.ReadBytes(entry.Length);
if (name != null)

View File

@@ -372,7 +372,7 @@ namespace SabreTools.Serialization.Deserializers
// TODO: Use marshalling here instead of building
var residentNameTable = new List<ResidentNameTableEntry>();
while (data.Position < endOffset)
while (data.Position < endOffset && data.Position < data.Length)
{
var entry = ParseResidentNameTableEntry(data);
if (entry == null)
@@ -445,7 +445,7 @@ namespace SabreTools.Serialization.Deserializers
// TODO: Use marshalling here instead of building
var importedNameTable = new Dictionary<ushort, ImportedNameTableEntry>();
while (data.Position < endOffset)
while (data.Position < endOffset && data.Position < data.Length)
{
ushort currentOffset = (ushort)data.Position;
var entry = ParseImportedNameTableEntry(data);
@@ -485,7 +485,7 @@ namespace SabreTools.Serialization.Deserializers
// TODO: Use marshalling here instead of building
var entryTable = new List<EntryTableBundle>();
while (data.Position < endOffset)
while (data.Position < endOffset && data.Position < data.Length)
{
var entry = new EntryTableBundle();
entry.EntryCount = data.ReadByteValue();
@@ -524,7 +524,7 @@ namespace SabreTools.Serialization.Deserializers
// TODO: Use marshalling here instead of building
var residentNameTable = new List<NonResidentNameTableEntry>();
while (data.Position < endOffset)
while (data.Position < endOffset && data.Position < data.Length)
{
var entry = ParseNonResidentNameTableEntry(data);
if (entry == null)

View File

@@ -368,7 +368,7 @@ namespace SabreTools.Serialization.Deserializers
record.CentralDirectorySize = data.ReadUInt32();
record.CentralDirectoryOffset = data.ReadUInt32();
record.FileCommentLength = data.ReadUInt16();
if (record.FileCommentLength > 0)
if (record.FileCommentLength > 0 && data.Position + record.FileCommentLength <= data.Length)
{
byte[] commentBytes = data.ReadBytes(record.FileCommentLength);
if (commentBytes.Length != record.FileCommentLength)
@@ -501,7 +501,7 @@ namespace SabreTools.Serialization.Deserializers
header.ExternalFileAttributes = data.ReadUInt32();
header.RelativeOffsetOfLocalHeader = data.ReadUInt32();
if (header.FileNameLength > 0)
if (header.FileNameLength > 0 && data.Position + header.FileNameLength <= data.Length)
{
byte[] filenameBytes = data.ReadBytes(header.FileNameLength);
if (filenameBytes.Length != header.FileNameLength)
@@ -509,7 +509,7 @@ namespace SabreTools.Serialization.Deserializers
header.FileName = Encoding.ASCII.GetString(filenameBytes);
}
if (header.ExtraFieldLength > 0)
if (header.ExtraFieldLength > 0 && data.Position + header.ExtraFieldLength <= data.Length)
{
byte[] extraBytes = data.ReadBytes(header.ExtraFieldLength);
if (extraBytes.Length != header.ExtraFieldLength)
@@ -517,7 +517,7 @@ namespace SabreTools.Serialization.Deserializers
header.ExtraField = extraBytes;
}
if (header.FileCommentLength > 0)
if (header.FileCommentLength > 0 && data.Position + header.FileCommentLength <= data.Length)
{
byte[] commentBytes = data.ReadBytes(header.FileCommentLength);
if (commentBytes.Length != header.FileCommentLength)
@@ -593,7 +593,7 @@ namespace SabreTools.Serialization.Deserializers
return null;
record.ExtraFieldLength = data.ReadUInt32();
if (record.ExtraFieldLength > 0)
if (record.ExtraFieldLength > 0 && data.Position + record.ExtraFieldLength <= data.Length)
{
byte[] extraBytes = data.ReadBytes((int)record.ExtraFieldLength);
if (extraBytes.Length != record.ExtraFieldLength)
@@ -630,7 +630,7 @@ namespace SabreTools.Serialization.Deserializers
header.FileNameLength = data.ReadUInt16();
header.ExtraFieldLength = data.ReadUInt16();
if (header.FileNameLength > 0)
if (header.FileNameLength > 0 && data.Position + header.FileNameLength <= data.Length)
{
byte[] filenameBytes = data.ReadBytes(header.FileNameLength);
if (filenameBytes.Length != header.FileNameLength)
@@ -638,7 +638,7 @@ namespace SabreTools.Serialization.Deserializers
header.FileName = Encoding.ASCII.GetString(filenameBytes);
}
if (header.ExtraFieldLength > 0)
if (header.ExtraFieldLength > 0 && data.Position + header.ExtraFieldLength <= data.Length)
{
byte[] extraBytes = data.ReadBytes(header.ExtraFieldLength);
if (extraBytes.Length != header.ExtraFieldLength)

View File

@@ -668,7 +668,7 @@ namespace SabreTools.Serialization.Deserializers
entry.CertificateType = (WindowsCertificateType)data.ReadUInt16();
int certificateDataLength = (int)(entry.Length - 8);
if (certificateDataLength > 0)
if (certificateDataLength > 0 && data.Position + certificateDataLength <= data.Length)
entry.Certificate = data.ReadBytes(certificateDataLength);
attributeCertificateTable.Add(entry);
@@ -703,7 +703,7 @@ namespace SabreTools.Serialization.Deserializers
// TODO: Use marshalling here instead of building
var baseRelocationTable = new List<BaseRelocationBlock>();
while (data.Position < endOffset)
while (data.Position < endOffset && data.Position < data.Length)
{
var baseRelocationBlock = new BaseRelocationBlock();
@@ -724,12 +724,12 @@ namespace SabreTools.Serialization.Deserializers
totalSize += 2;
}
baseRelocationBlock.TypeOffsetFieldEntries = typeOffsetFieldEntries.ToArray();
baseRelocationBlock.TypeOffsetFieldEntries = [.. typeOffsetFieldEntries];
baseRelocationTable.Add(baseRelocationBlock);
}
return baseRelocationTable.ToArray();
return [.. baseRelocationTable];
}
/// <summary>
@@ -745,7 +745,7 @@ namespace SabreTools.Serialization.Deserializers
var debugDirectoryTable = new List<DebugDirectoryEntry>();
while (data.Position < endOffset)
while (data.Position < endOffset && data.Position < data.Length)
{
var debugDirectoryEntry = data.ReadType<DebugDirectoryEntry>();
if (debugDirectoryEntry == null)
@@ -1164,7 +1164,7 @@ namespace SabreTools.Serialization.Deserializers
var resourceDirectoryString = new ResourceDirectoryString();
resourceDirectoryString.Length = data.ReadUInt16();
if (resourceDirectoryString.Length > 0)
if (resourceDirectoryString.Length > 0 && data.Position + resourceDirectoryString.Length <= data.Length)
resourceDirectoryString.UnicodeString = data.ReadBytes(resourceDirectoryString.Length * 2);
entry.Name = resourceDirectoryString;

View File

@@ -67,7 +67,10 @@ namespace SabreTools.Serialization.Deserializers
#region Archive Hashes
if (header?.Version == 2 && file.ExtendedHeader != null && file.ExtendedHeader.ArchiveHashLength > 0)
if (header?.Version == 2
&& file.ExtendedHeader != null
&& file.ExtendedHeader.ArchiveHashLength > 0
&& data.Position + file.ExtendedHeader.ArchiveHashLength <= data.Length)
{
// Create the archive hashes list
var archiveHashes = new List<ArchiveHash>();
@@ -218,7 +221,9 @@ namespace SabreTools.Serialization.Deserializers
// Get the preload data pointer
long preloadDataPointer = -1; int preloadDataLength = -1;
if (directoryEntry.ArchiveIndex == HL_VPK_NO_ARCHIVE && directoryEntry.EntryLength > 0)
if (directoryEntry.ArchiveIndex == HL_VPK_NO_ARCHIVE
&& directoryEntry.EntryLength > 0
&& data.Position + directoryEntry.EntryLength <= data.Length)
{
preloadDataPointer = directoryEntry.EntryOffset;
preloadDataLength = (int)directoryEntry.EntryLength;
@@ -231,7 +236,9 @@ namespace SabreTools.Serialization.Deserializers
// If we had a valid preload data pointer
byte[]? preloadData = null;
if (preloadDataPointer >= 0 && preloadDataLength > 0)
if (preloadDataPointer >= 0
&& preloadDataLength > 0
&& data.Position + preloadDataLength <= data.Length)
{
// Cache the current offset
long initialOffset = data.Position;

View File

@@ -604,7 +604,11 @@ namespace SabreTools.Serialization
#region Class resource
currentOffset = offset;
ushort classResourceIdentifier = entry.Data.ReadUInt16(ref offset);
ushort classResourceIdentifier;
if (offset >= entry.Data.Length)
classResourceIdentifier = 0x0000;
else
classResourceIdentifier = entry.Data.ReadUInt16(ref offset);
offset = currentOffset;
// 0x0000 means no elements
@@ -640,7 +644,11 @@ namespace SabreTools.Serialization
#region Title resource
currentOffset = offset;
ushort titleResourceIdentifier = entry.Data.ReadUInt16(ref offset);
ushort titleResourceIdentifier;
if (offset >= entry.Data.Length)
titleResourceIdentifier = 0x0000;
else
titleResourceIdentifier = entry.Data.ReadUInt16(ref offset);
offset = currentOffset;
// 0x0000 means no elements
@@ -900,7 +908,7 @@ namespace SabreTools.Serialization
if (menuHeaderExtended == null)
return null;
menuResource.ExtendedMenuHeader = menuHeaderExtended;
menuResource.MenuHeader = menuHeaderExtended;
#endregion
@@ -929,7 +937,7 @@ namespace SabreTools.Serialization
}
}
menuResource.ExtendedMenuItems = [.. extendedMenuItems];
menuResource.MenuItems = [.. extendedMenuItems];
#endregion
}
@@ -937,7 +945,7 @@ namespace SabreTools.Serialization
{
#region Menu header
var menuHeader = entry.Data.ReadType<MenuHeader>(ref offset);
var menuHeader = entry.Data.ReadType<NormalMenuHeader>(ref offset);
if (menuHeader == null)
return null;
@@ -1076,21 +1084,9 @@ namespace SabreTools.Serialization
// Loop through and add
while (offset < entry.Data.Length)
{
ushort stringLength = entry.Data.ReadUInt16(ref offset);
if (stringLength == 0)
string? stringValue = entry.Data.ReadPrefixedUnicodeString(ref offset);
if (stringValue != null)
{
stringTable[stringIndex++] = "[EMPTY]";
}
else
{
if (stringLength * 2 > entry.Data.Length - offset)
{
Console.WriteLine($"{stringLength * 2} requested but {entry.Data.Length - offset} remains");
stringLength = (ushort)((entry.Data.Length - offset) / 2);
}
string stringValue = Encoding.Unicode.GetString(entry.Data, offset, stringLength * 2);
offset += stringLength * 2;
stringValue = stringValue.Replace("\n", "\\n").Replace("\r", newValue: "\\r");
stringTable[stringIndex++] = stringValue;
}
@@ -1127,7 +1123,7 @@ namespace SabreTools.Serialization
versionInfo.Padding1 = entry.Data.ReadUInt16(ref offset);
// Read fixed file info
if (versionInfo.ValueLength > 0)
if (versionInfo.ValueLength > 0 && offset + versionInfo.ValueLength <= entry.Data.Length)
{
var fixedFileInfo = entry.Data.ReadType<FixedFileInfo>(ref offset);

View File

@@ -1120,79 +1120,67 @@ namespace SabreTools.Serialization.Printers
if (menu.MenuHeader != null)
{
builder.AppendLine(menu.MenuHeader.Version, $"{padding}Version");
builder.AppendLine(menu.MenuHeader.HeaderSize, $"{padding}Header size");
if (menu.MenuHeader is NormalMenuHeader normalMenuHeader)
{
builder.AppendLine(normalMenuHeader.Version, $"{padding}Version");
builder.AppendLine(normalMenuHeader.HeaderSize, $"{padding}Header size");
}
else if (menu.MenuHeader is MenuHeaderExtended menuHeaderExtended)
{
builder.AppendLine(menuHeaderExtended.Version, $"{padding}Version");
builder.AppendLine(menuHeaderExtended.Offset, $"{padding}Offset");
builder.AppendLine(menuHeaderExtended.HelpID, $"{padding}Help ID");
}
else
{
builder.AppendLine($"{padding}Menu header found, but malformed");
}
builder.AppendLine();
builder.AppendLine($"{padding}Menu items");
builder.AppendLine($"{padding}-------------------------");
if (menu.MenuItems == null || menu.MenuItems.Length == 0)
{
builder.AppendLine($"{padding}No menu items");
return;
}
for (int i = 0; i < menu.MenuItems.Length; i++)
{
var menuItem = menu.MenuItems[i];
builder.AppendLine($"{padding}Menu item {i}");
if (menuItem == null)
{
builder.AppendLine($"{padding} [NULL]");
continue;
}
if (menuItem is NormalMenuItem normalMenuItem)
{
builder.AppendLine($"{padding} Resource info: {normalMenuItem.NormalResInfo} (0x{normalMenuItem.NormalResInfo:X})");
builder.AppendLine(normalMenuItem.NormalMenuText, $"{padding} Menu text");
}
else if (menuItem is PopupMenuItem popupMenuItem)
{
builder.AppendLine($"{padding} Item type: {popupMenuItem.PopupItemType} (0x{popupMenuItem.PopupItemType:X})");
builder.AppendLine($"{padding} State: {popupMenuItem.PopupState} (0x{popupMenuItem.PopupState:X})");
builder.AppendLine(popupMenuItem.PopupID, $"{padding} ID");
builder.AppendLine($"{padding} Resource info: {popupMenuItem.PopupResInfo} (0x{popupMenuItem.PopupResInfo:X})");
builder.AppendLine(popupMenuItem.PopupMenuText, $"{padding} Menu text");
}
}
}
else if (menu.ExtendedMenuHeader != null)
builder.AppendLine($"{padding}Menu items");
builder.AppendLine($"{padding}-------------------------");
if (menu.MenuItems == null || menu.MenuItems.Length == 0)
{
builder.AppendLine(menu.ExtendedMenuHeader.Version, $"{padding}Version");
builder.AppendLine(menu.ExtendedMenuHeader.Offset, $"{padding}Offset");
builder.AppendLine(menu.ExtendedMenuHeader.HelpID, $"{padding}Help ID");
builder.AppendLine();
builder.AppendLine($"{padding}Menu items");
builder.AppendLine($"{padding}-------------------------");
if (menu.ExtendedMenuHeader.Offset == 0
|| menu.ExtendedMenuItems == null
|| menu.ExtendedMenuItems.Length == 0)
{
builder.AppendLine($"{padding}No menu items");
return;
}
for (int i = 0; i < menu.ExtendedMenuItems.Length; i++)
{
var menuItem = menu.ExtendedMenuItems[i];
builder.AppendLine($"{padding}Menu item {i}");
if (menuItem == null)
{
builder.AppendLine($"{padding} [NULL]");
continue;
}
builder.AppendLine($"{padding} Item type: {menuItem.ItemType} (0x{menuItem.ItemType:X})");
builder.AppendLine($"{padding} State: {menuItem.State} (0x{menuItem.State:X})");
builder.AppendLine(menuItem.ID, $"{padding} ID");
builder.AppendLine($"{padding} Flags: {menuItem.Flags} (0x{menuItem.Flags:X})");
builder.AppendLine(menuItem.MenuText, $"{padding} Menu text");
}
builder.AppendLine($"{padding}No menu items");
return;
}
else
for (int i = 0; i < menu.MenuItems.Length; i++)
{
builder.AppendLine($"{padding}Menu resource found, but malformed");
var menuItem = menu.MenuItems[i];
builder.AppendLine($"{padding}Menu item {i}");
if (menuItem == null)
{
builder.AppendLine($"{padding} [NULL]");
continue;
}
if (menuItem is NormalMenuItem normalMenuItem)
{
builder.AppendLine($"{padding} Resource info: {normalMenuItem.NormalResInfo} (0x{normalMenuItem.NormalResInfo:X})");
builder.AppendLine(normalMenuItem.NormalMenuText, $"{padding} Menu text");
}
else if (menuItem is PopupMenuItem popupMenuItem)
{
builder.AppendLine($"{padding} Item type: {popupMenuItem.PopupItemType} (0x{popupMenuItem.PopupItemType:X})");
builder.AppendLine($"{padding} State: {popupMenuItem.PopupState} (0x{popupMenuItem.PopupState:X})");
builder.AppendLine(popupMenuItem.PopupID, $"{padding} ID");
builder.AppendLine($"{padding} Resource info: {popupMenuItem.PopupResInfo} (0x{popupMenuItem.PopupResInfo:X})");
builder.AppendLine(popupMenuItem.PopupMenuText, $"{padding} Menu text");
}
else if (menuItem is MenuItemExtended menuItemExtended)
{
builder.AppendLine($"{padding} Item type: {menuItemExtended.ItemType} (0x{menuItemExtended.ItemType:X})");
builder.AppendLine($"{padding} State: {menuItemExtended.State} (0x{menuItemExtended.State:X})");
builder.AppendLine(menuItemExtended.ID, $"{padding} ID");
builder.AppendLine($"{padding} Flags: {menuItemExtended.Flags} (0x{menuItemExtended.Flags:X})");
builder.AppendLine(menuItemExtended.MenuText, $"{padding} Menu text");
}
else
{
builder.AppendLine($"{padding} Menu item found, but malformed");
}
}
}

View File

@@ -8,7 +8,7 @@
<LangVersion>latest</LangVersion>
<Nullable>enable</Nullable>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<Version>1.6.4</Version>
<Version>1.6.6</Version>
<!-- Package Properties -->
<Authors>Matt Nadareski</Authors>
@@ -31,7 +31,7 @@
<PackageReference Include="SabreTools.ASN1" Version="1.3.2" />
<PackageReference Include="SabreTools.Hashing" Version="1.2.0" />
<PackageReference Include="SabreTools.IO" Version="1.4.11" />
<PackageReference Include="SabreTools.Models" Version="1.4.6" />
<PackageReference Include="SabreTools.Models" Version="1.4.8" />
</ItemGroup>
</Project>

View File

@@ -1188,68 +1188,68 @@ namespace SabreTools.Serialization.Wrappers
{
switch ((Models.PortableExecutable.ResourceType)resourceType)
{
case SabreTools.Models.PortableExecutable.ResourceType.RT_CURSOR:
case Models.PortableExecutable.ResourceType.RT_CURSOR:
value = entry.Data;
break;
case SabreTools.Models.PortableExecutable.ResourceType.RT_BITMAP:
case Models.PortableExecutable.ResourceType.RT_BITMAP:
value = entry.Data;
break;
case SabreTools.Models.PortableExecutable.ResourceType.RT_ICON:
case Models.PortableExecutable.ResourceType.RT_ICON:
value = entry.Data;
break;
case SabreTools.Models.PortableExecutable.ResourceType.RT_MENU:
case Models.PortableExecutable.ResourceType.RT_MENU:
value = entry.AsMenu();
break;
case SabreTools.Models.PortableExecutable.ResourceType.RT_DIALOG:
case Models.PortableExecutable.ResourceType.RT_DIALOG:
value = entry.AsDialogBox();
break;
case SabreTools.Models.PortableExecutable.ResourceType.RT_STRING:
case Models.PortableExecutable.ResourceType.RT_STRING:
value = entry.AsStringTable();
break;
case SabreTools.Models.PortableExecutable.ResourceType.RT_FONTDIR:
case Models.PortableExecutable.ResourceType.RT_FONTDIR:
value = entry.Data;
break;
case SabreTools.Models.PortableExecutable.ResourceType.RT_FONT:
case Models.PortableExecutable.ResourceType.RT_FONT:
value = entry.Data;
break;
case SabreTools.Models.PortableExecutable.ResourceType.RT_ACCELERATOR:
case Models.PortableExecutable.ResourceType.RT_ACCELERATOR:
value = entry.AsAcceleratorTableResource();
break;
case SabreTools.Models.PortableExecutable.ResourceType.RT_RCDATA:
case Models.PortableExecutable.ResourceType.RT_RCDATA:
value = entry.Data;
break;
case SabreTools.Models.PortableExecutable.ResourceType.RT_MESSAGETABLE:
case Models.PortableExecutable.ResourceType.RT_MESSAGETABLE:
value = entry.AsMessageResourceData();
break;
case SabreTools.Models.PortableExecutable.ResourceType.RT_GROUP_CURSOR:
case Models.PortableExecutable.ResourceType.RT_GROUP_CURSOR:
value = entry.Data;
break;
case SabreTools.Models.PortableExecutable.ResourceType.RT_GROUP_ICON:
case Models.PortableExecutable.ResourceType.RT_GROUP_ICON:
value = entry.Data;
break;
case SabreTools.Models.PortableExecutable.ResourceType.RT_VERSION:
case Models.PortableExecutable.ResourceType.RT_VERSION:
_versionInfo = entry.AsVersionInfo();
value = _versionInfo;
break;
case SabreTools.Models.PortableExecutable.ResourceType.RT_DLGINCLUDE:
case Models.PortableExecutable.ResourceType.RT_DLGINCLUDE:
value = entry.Data;
break;
case SabreTools.Models.PortableExecutable.ResourceType.RT_PLUGPLAY:
case Models.PortableExecutable.ResourceType.RT_PLUGPLAY:
value = entry.Data;
break;
case SabreTools.Models.PortableExecutable.ResourceType.RT_VXD:
case Models.PortableExecutable.ResourceType.RT_VXD:
value = entry.Data;
break;
case SabreTools.Models.PortableExecutable.ResourceType.RT_ANICURSOR:
case Models.PortableExecutable.ResourceType.RT_ANICURSOR:
value = entry.Data;
break;
case SabreTools.Models.PortableExecutable.ResourceType.RT_ANIICON:
case Models.PortableExecutable.ResourceType.RT_ANIICON:
value = entry.Data;
break;
case SabreTools.Models.PortableExecutable.ResourceType.RT_HTML:
case Models.PortableExecutable.ResourceType.RT_HTML:
value = entry.Data;
break;
case SabreTools.Models.PortableExecutable.ResourceType.RT_MANIFEST:
case Models.PortableExecutable.ResourceType.RT_MANIFEST:
_assemblyManifest = entry.AsAssemblyManifest();
value = _versionInfo;
break;
@@ -1335,7 +1335,7 @@ namespace SabreTools.Serialization.Wrappers
/// <param name="name">Name of the section to check for</param>
/// <param name="exact">True to enable exact matching of names, false for starts-with</param>
/// <returns>Section data on success, null on error</returns>
public SabreTools.Models.PortableExecutable.SectionHeader? GetFirstSection(string? name, bool exact = false)
public Models.PortableExecutable.SectionHeader? GetFirstSection(string? name, bool exact = false)
{
// If we have no sections
if (SectionNames == null || !SectionNames.Any() || this.Model.SectionTable == null || !this.Model.SectionTable.Any())
@@ -1360,7 +1360,7 @@ namespace SabreTools.Serialization.Wrappers
/// <param name="name">Name of the section to check for</param>
/// <param name="exact">True to enable exact matching of names, false for starts-with</param>
/// <returns>Section data on success, null on error</returns>
public SabreTools.Models.PortableExecutable.SectionHeader? GetLastSection(string? name, bool exact = false)
public Models.PortableExecutable.SectionHeader? GetLastSection(string? name, bool exact = false)
{
// If we have no sections
if (SectionNames == null || !SectionNames.Any() || this.Model.SectionTable == null || !this.Model.SectionTable.Any())
@@ -1384,7 +1384,7 @@ namespace SabreTools.Serialization.Wrappers
/// </summary>
/// <param name="index">Index of the section to check for</param>
/// <returns>Section data on success, null on error</returns>
public SabreTools.Models.PortableExecutable.SectionHeader? GetSection(int index)
public Models.PortableExecutable.SectionHeader? GetSection(int index)
{
// If we have no sections
if (this.Model.SectionTable == null || !this.Model.SectionTable.Any())

View File

@@ -29,6 +29,11 @@ namespace SabreTools.Serialization.Wrappers
/// </summary>
protected DataSource _dataSource = DataSource.UNKNOWN;
/// <summary>
/// Lock object for reading from the source
/// </summary>
private readonly object _streamDataLock = new();
/// <summary>
/// Source byte array data
/// </summary>
@@ -193,11 +198,14 @@ namespace SabreTools.Serialization.Wrappers
break;
case DataSource.Stream:
long currentLocation = _streamData!.Position;
_streamData.Seek(position, SeekOrigin.Begin);
sectionData = _streamData.ReadBytes(length);
_streamData.Seek(currentLocation, SeekOrigin.Begin);
break;
lock (_streamDataLock)
{
long currentLocation = _streamData!.Position;
_streamData.Seek(position, SeekOrigin.Begin);
sectionData = _streamData.ReadBytes(length);
_streamData.Seek(currentLocation, SeekOrigin.Begin);
break;
}
}
return sectionData;