From c8e65e1e306d1f53cffb726308071c0e8c70afb8 Mon Sep 17 00:00:00 2001 From: Matt Nadareski Date: Wed, 3 Sep 2025 13:46:12 -0400 Subject: [PATCH] Add section string lock --- .../Wrappers/PortableExecutable.cs | 64 +++++++++++-------- 1 file changed, 36 insertions(+), 28 deletions(-) diff --git a/SabreTools.Serialization/Wrappers/PortableExecutable.cs b/SabreTools.Serialization/Wrappers/PortableExecutable.cs index b21aa28d..5703c0a8 100644 --- a/SabreTools.Serialization/Wrappers/PortableExecutable.cs +++ b/SabreTools.Serialization/Wrappers/PortableExecutable.cs @@ -742,6 +742,11 @@ namespace SabreTools.Serialization.Wrappers /// private List[]? _sectionStringData = null; + /// + /// Lock object for + /// + private readonly object _sectionStringDataLock = new(); + /// /// Stub executable data, if it exists /// @@ -2271,40 +2276,43 @@ namespace SabreTools.Serialization.Wrappers /// Section strings on success, null on error public List? GetSectionStrings(int index) { - // If we have no sections - if (SectionNames == null || SectionNames.Length == 0 || SectionTable == null || SectionTable.Length == 0) - return null; - - // If the section doesn't exist - if (index < 0 || index >= SectionTable.Length) - return null; - - // Get the section data from the table - var section = SectionTable[index]; - if (section == null) - return null; - - uint address = section.VirtualAddress.ConvertVirtualAddress(SectionTable); - if (address == 0) - return null; - - // Set the section size - uint size = section.SizeOfRawData; - lock (_sourceDataLock) + lock (_sectionStringDataLock) { + // If we already have cached data, just use that immediately + if (_sectionStringData != null && _sectionStringData[index] != null && _sectionStringData[index].Count > 0) + return _sectionStringData[index]; + + // If we have no sections + if (SectionNames == null || SectionNames.Length == 0 || SectionTable == null || SectionTable.Length == 0) + return null; + // Create the section string array if we have to _sectionStringData ??= new List[SectionNames.Length]; - // If we already have cached data, just use that immediately - if (_sectionStringData[index] != null && _sectionStringData[index].Count > 0) - return _sectionStringData[index]; + // If the section doesn't exist + if (index < 0 || index >= SectionTable.Length) + return null; - // Populate the section string data based on the source - List? sectionStringData = _dataSource.ReadStringsFrom((int)address, (int)size); + // Get the section data from the table + var section = SectionTable[index]; + if (section == null) + return null; - // Cache and return the section string data, even if null - _sectionStringData[index] = sectionStringData ?? []; - return sectionStringData; + uint address = section.VirtualAddress.ConvertVirtualAddress(SectionTable); + if (address == 0) + return null; + + // Set the section size + uint size = section.SizeOfRawData; + lock (_sourceDataLock) + { + // Populate the section string data based on the source + List? sectionStringData = _dataSource.ReadStringsFrom((int)address, (int)size); + + // Cache and return the section string data, even if null + _sectionStringData[index] = sectionStringData ?? []; + return sectionStringData; + } } }