From 718c5f9376a8656d358a249454c2eb0a0524bfaa Mon Sep 17 00:00:00 2001 From: workkavint-ship-it Date: Fri, 29 May 2026 13:06:52 +0530 Subject: [PATCH 01/14] *fix(ASN1): fix buffer cleanup and length parsing** Used delete[] instead of delete for array allocated with new[], which was causing heap corruption on buffer release. Also fixed two logical-AND (&&) operators that should have been bitwise-AND (&) when extracting the high byte of the length field, which was silently zeroing out the upper byte for any length value > 0xFF. --- Source/core/ASN1.h | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/Source/core/ASN1.h b/Source/core/ASN1.h index 2d9a033184..c6b0fbff29 100644 --- a/Source/core/ASN1.h +++ b/Source/core/ASN1.h @@ -52,12 +52,10 @@ namespace Core { { if (_buffer != nullptr) { _buffer[0] = 1; -PUSH_WARNING(DISABLE_WARNING_CONSTANT_LOGICAL_OPERAND) _buffer[1] = (length & 0xFF); - _buffer[2] = ((length >> 8) && 0xFF); + _buffer[2] = ((length >> 8) & 0xFF); _buffer[3] = (length & 0xFF); - _buffer[4] = ((length >> 8) && 0xFF); -POP_WARNING() + _buffer[4] = ((length >> 8) & 0xFF); } } Buffer(const Buffer& copy) @@ -134,7 +132,7 @@ POP_WARNING() { if (_buffer != nullptr) { if (_buffer[0] == 1) { - delete _buffer; + delete[] _buffer; } else { _buffer[0] = _buffer[0] - 1; } From 776379cf7fea0445887ad1d20af9d097e3bb60bf Mon Sep 17 00:00:00 2001 From: workkavint-ship-it Date: Fri, 29 May 2026 13:10:26 +0530 Subject: [PATCH 02/14] fix(DataElementFile): null check MapViewOfFile and fix inverted handle condition Added a null guard on the MapViewOfFile return value before passing it to UpdateCache a failed mapping would have written null into the buffer. Fixed the inverted INVALID_HANDLE_VALUE check in Reallocation so that MapViewOfFileEx is called with a valid handle, not a broken one. --- Source/core/DataElementFile.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Source/core/DataElementFile.cpp b/Source/core/DataElementFile.cpp index e7734fd6cc..4c19bd6153 100644 --- a/Source/core/DataElementFile.cpp +++ b/Source/core/DataElementFile.cpp @@ -126,8 +126,9 @@ namespace Core { void* newBuffer = (::MapViewOfFile(m_MemoryMappedFile, flags, 0, 0, mapSize)); - // Seems like everything succeeded. Lets map it. - UpdateCache(0, static_cast(newBuffer), requiredSize, mapSize); + if (newBuffer != nullptr) { + UpdateCache(0, static_cast(newBuffer), requiredSize, mapSize); + } } } } @@ -166,7 +167,7 @@ namespace Core { } } - if (m_MemoryMappedFile == INVALID_HANDLE_VALUE) { + if (m_MemoryMappedFile != INVALID_HANDLE_VALUE) { DWORD flags = ((m_Flags & File::USER_READ) != 0 ? FILE_MAP_READ : 0) | ((m_Flags & File::USER_WRITE) != 0 ? FILE_MAP_WRITE : 0); void* newBuffer = ::MapViewOfFileEx(m_MemoryMappedFile, flags, 0, 0, static_cast(requestedSize), Buffer()); From c7961f02da4b380e44c4b1ac15d191784b20685f Mon Sep 17 00:00:00 2001 From: workkavint-ship-it Date: Fri, 29 May 2026 13:17:22 +0530 Subject: [PATCH 03/14] fix(ResourceMonitor): guard readlink failure and malloc null in Worker Changed readlink result type from size_t to ssize_t and added a check so a failure (-1) no longer wraps to SIZE_MAX and writes out of bounds. Wrapped the pollfd array writes in a != nullptr check after malloc to prevent a null dereference when the system is out of memory. --- Source/core/ResourceMonitor.h | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/Source/core/ResourceMonitor.h b/Source/core/ResourceMonitor.h index e0522e1061..3e5c4a4fe6 100644 --- a/Source/core/ResourceMonitor.h +++ b/Source/core/ResourceMonitor.h @@ -209,8 +209,12 @@ namespace Core { char procfn[64]; snprintf(procfn, sizeof(procfn), "/proc/self/fd/%d", info.descriptor); - size_t len = readlink(procfn, info.filename, sizeof(info.filename) - 1); - info.filename[len] = '\0'; + ssize_t len = readlink(procfn, info.filename, sizeof(info.filename) - 1); + if (len >= 0) { + info.filename[len] = '\0'; + } else { + info.filename[0] = '\0'; + } #endif #ifdef __WINDOWS__ info.monitor = 0; @@ -410,9 +414,11 @@ POP_WARNING() // Resize the array to fit.. _descriptorArray = static_cast<::pollfd*>(::malloc(sizeof(::pollfd) * _descriptorArrayLength)); - _descriptorArray[0].fd = _signalDescriptor; - _descriptorArray[0].events = POLLIN; - _descriptorArray[0].revents = 0; + if (_descriptorArray != nullptr) { + _descriptorArray[0].fd = _signalDescriptor; + _descriptorArray[0].events = POLLIN; + _descriptorArray[0].revents = 0; + } } int filledFileDescriptors = 1; From 6ab3f504b32668a83d63f17d8a00a765ba1bd15c Mon Sep 17 00:00:00 2001 From: workkavint-ship-it Date: Fri, 29 May 2026 13:19:29 +0530 Subject: [PATCH 04/14] fix(FileSystem): fix unreachable FindClose causing handle leak on Windows The handle was overwritten with INVALID_HANDLE_VALUE before the null check, making FindClose permanently unreachable. Moved the assignment after the close so every FindFirstFile handle gets properly released. --- Source/core/FileSystem.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/Source/core/FileSystem.h b/Source/core/FileSystem.h index f1c5c2a02d..a5ffcb192b 100644 --- a/Source/core/FileSystem.h +++ b/Source/core/FileSystem.h @@ -753,8 +753,6 @@ POP_WARNING() } void Reset() { - _dirFD = INVALID_HANDLE_VALUE; - if (_dirFD != INVALID_HANDLE_VALUE) { ::FindClose(_dirFD); _dirFD = INVALID_HANDLE_VALUE; From f5468dea431ca2fb28c6e6ca73c350540b5b1570 Mon Sep 17 00:00:00 2001 From: workkavint-ship-it Date: Fri, 29 May 2026 13:24:36 +0530 Subject: [PATCH 05/14] fix(IPFrame): remove spurious & in DestinationMAC memcpy &MACAddress was copying the address of the local pointer variable instead of the MAC bytes it points to, producing garbage destination addresses in every Ethernet frame. Matches how SourceMAC already works. --- Source/core/IPFrame.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/core/IPFrame.h b/Source/core/IPFrame.h index 713c8f7855..2929d2f6ce 100644 --- a/Source/core/IPFrame.h +++ b/Source/core/IPFrame.h @@ -71,7 +71,7 @@ namespace Core { return (&(_buffer[0])); } void DestinationMAC(const uint8_t MACAddress[]) { - memcpy(&(_buffer[0]), &MACAddress, MACSize); + memcpy(&(_buffer[0]), MACAddress, MACSize); } uint8_t* Frame() { return (SIZE > 0 ? &(_buffer[HeaderSize]) : nullptr); From a15e437fbd986afebf17df1b5cc2582b35f44642 Mon Sep 17 00:00:00 2001 From: workkavint-ship-it Date: Fri, 29 May 2026 13:33:34 +0530 Subject: [PATCH 06/14] fix(Netlink): move constructor was clearing itself instead of the source When moving a Netlink object, the constructor was wiping its own freshly copied values instead of clearing the object it moved from. The new object always ended up empty. Now it correctly leaves the source in a reset state. --- Source/core/Netlink.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Source/core/Netlink.h b/Source/core/Netlink.h index a6b20dbeb0..ad17af447c 100644 --- a/Source/core/Netlink.h +++ b/Source/core/Netlink.h @@ -175,9 +175,9 @@ namespace Core { , _flags(move._flags) , _mySequence(move._mySequence) { - _type = NLMSG_DONE; - _flags = 0; - _mySequence = ~0; + move._type = NLMSG_DONE; + move._flags = 0; + move._mySequence = ~0; } virtual ~Netlink() = default; From 964d3c493370b2f81e3eb8c3db0bac44ad534c2b Mon Sep 17 00:00:00 2001 From: workkavint-ship-it Date: Fri, 29 May 2026 14:21:12 +0530 Subject: [PATCH 07/14] fix(RequestResponse): fix State() wrong member and Response() copy-paste bug MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit State() was referencing m_Responded which doesn't exist — the actual member is m_State. Response() was returning *m_Request instead of *m_Response, a copy-paste mistake that gave callers the request back when they asked for the response. --- Source/core/RequestResponse.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Source/core/RequestResponse.h b/Source/core/RequestResponse.h index 9b64d4eb12..9c78c9f5ed 100644 --- a/Source/core/RequestResponse.h +++ b/Source/core/RequestResponse.h @@ -81,7 +81,7 @@ namespace Platform { public: inline RequestResponseState State() const { - return (m_Responded); + return (m_State); } inline REQUEST& Request() @@ -91,7 +91,7 @@ namespace Platform { inline RESPONSE& Response() { - return (*m_Request); + return (*m_Response); } private: From aa3e460cba5c347761249d0954d7e3765db8e536 Mon Sep 17 00:00:00 2001 From: workkavint-ship-it Date: Fri, 29 May 2026 14:24:09 +0530 Subject: [PATCH 08/14] fix(NetworkInfo): null deref in MACAddress and ifaddrs leak on macOS Both MACAddress overloads on Windows were dereferencing the info pointer without checking if it was null first. On macOS, the interface list from getifaddrs was never freed causing a memory leak on every call, and the iteration was starting at ifa_next which silently dropped the first adapter. --- Source/core/NetworkInfo.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/Source/core/NetworkInfo.cpp b/Source/core/NetworkInfo.cpp index 0f877b6268..ff85f0dfd5 100644 --- a/Source/core/NetworkInfo.cpp +++ b/Source/core/NetworkInfo.cpp @@ -419,7 +419,7 @@ namespace Core { string result; PIP_ADAPTER_ADDRESSES info = LoadAdapterInfo(_index); - if (info->PhysicalAddressLength != 0) { + if ((info != nullptr) && (info->PhysicalAddressLength != 0)) { ConvertMACToString(info->PhysicalAddress, static_cast(info->PhysicalAddressLength), delimiter, result); } return (result); @@ -451,7 +451,7 @@ namespace Core { PIP_ADAPTER_ADDRESSES info = LoadAdapterInfo(_index); - if (info->PhysicalAddressLength != 0) { + if ((info != nullptr) && (info->PhysicalAddressLength != 0)) { ASSERT(length >= info->PhysicalAddressLength); ::memcpy(buffer, info->PhysicalAddress, info->PhysicalAddressLength); if (length > info->PhysicalAddressLength) { @@ -561,7 +561,7 @@ namespace Core { Adapters adapters; if (!getifaddrs(&interfaces)) { - struct ifaddrs* index = interfaces->ifa_next; + struct ifaddrs* index = interfaces; while (index != nullptr) { Adapters::iterator adapterIndex = adapters.find(index->ifa_name); @@ -583,7 +583,8 @@ namespace Core { addresses = index->second; } } - } + + freeifaddrs(interfaces); return adapters.size(); } From 2d43bb8a03effba120512ae6c86efc63f4379bc6 Mon Sep 17 00:00:00 2001 From: workkavint-ship-it Date: Fri, 29 May 2026 14:28:05 +0530 Subject: [PATCH 09/14] fix(SerialPort): guard calloc result before pointer arithmetic If calloc failed, the code was doing pointer arithmetic on null and assigning it to the receive buffer undefined behavior and a crash. Wrapped both buffer assignments in a null check so they only run when the allocation actually succeeded. --- Source/core/SerialPort.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Source/core/SerialPort.cpp b/Source/core/SerialPort.cpp index cd9566eb7a..3d2b1fed52 100644 --- a/Source/core/SerialPort.cpp +++ b/Source/core/SerialPort.cpp @@ -934,8 +934,10 @@ void SerialPort::Read(const uint16_t readBytes) uint8_t* allocatedMemory = static_cast(::calloc(_sendBufferSize + _receiveBufferSize, 1)); - _sendBuffer = allocatedMemory; - _receiveBuffer = &(allocatedMemory[_sendBufferSize]); + if (allocatedMemory != nullptr) { + _sendBuffer = allocatedMemory; + _receiveBuffer = &(allocatedMemory[_sendBufferSize]); + } } From 48bffe90db4b35ef1d115109dd868d27bdb4262a Mon Sep 17 00:00:00 2001 From: workkavint-ship-it Date: Fri, 29 May 2026 14:31:03 +0530 Subject: [PATCH 10/14] fix(SystemInfo): initialize m_pageSize on Apple to avoid divide by zero On Apple builds m_pageSize was hardcoded to 0 while Linux used sysconf. Any call to GetPhysicalPageCount() on macOS would divide by zero and crash. Now uses sysconf(_SC_PAGESIZE) the same way Linux already does. --- Source/core/SystemInfo.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/core/SystemInfo.cpp b/Source/core/SystemInfo.cpp index ea88cb526f..480ec4f148 100644 --- a/Source/core/SystemInfo.cpp +++ b/Source/core/SystemInfo.cpp @@ -147,7 +147,7 @@ namespace Core { #ifdef __APPLE__ m_uptime = 0; m_totalram = 0; - m_pageSize = 0; + m_pageSize = static_cast(sysconf(_SC_PAGESIZE)); m_freeram = 0; m_totalswap=0; m_freeswap=0; From 38334d2e77ae1b660d3697d622538c923aa011d9 Mon Sep 17 00:00:00 2001 From: workkavint-ship-it Date: Fri, 29 May 2026 14:33:32 +0530 Subject: [PATCH 11/14] fix(WarningReportingControl): IsModuleExcluded compared wrong container end _modules.find() was compared against _callsigns.end() instead of _modules.end(). Iterators from different containers are never equal so every module was permanently treated as excluded, silently disabling all warning reporting regardless of the exclusion list contents. --- Source/core/WarningReportingControl.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/core/WarningReportingControl.h b/Source/core/WarningReportingControl.h index bbdc9637ab..1330885468 100644 --- a/Source/core/WarningReportingControl.h +++ b/Source/core/WarningReportingControl.h @@ -165,7 +165,7 @@ namespace WarningReporting { } bool IsModuleExcluded(const string& module) const { - return _modules.find(module) != _callsigns.end(); + return _modules.find(module) != _modules.end(); } void InsertCallsign(const string& callsign) { From 106ca81e5491476027fc78907595b65e36c439d2 Mon Sep 17 00:00:00 2001 From: workkavint-ship-it Date: Fri, 29 May 2026 14:35:32 +0530 Subject: [PATCH 12/14] fix(DataElement): fix reversed subtraction in Size() causing underflow Size() was returning m_Offset - m_Buffer.Size() instead of the other way around. Since both are unsigned, when offset is less than the buffer size the subtraction wraps to a huge garbage value. IsValid() right above confirms the correct intent: remaining bytes = buffer size - offset. --- Source/core/DataElement.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/core/DataElement.h b/Source/core/DataElement.h index 10371da4f1..65e2f7b63d 100644 --- a/Source/core/DataElement.h +++ b/Source/core/DataElement.h @@ -953,7 +953,7 @@ POP_WARNING() inline uint64_t Size() const { - return (m_Offset - m_Buffer.Size()); + return (m_Buffer.Size() - m_Offset); } inline void SkipBytes(const unsigned int bytes) From 3e7bd0bc877c148a37fb4603e7269ad65605551f Mon Sep 17 00:00:00 2001 From: workkavint-ship-it Date: Fri, 29 May 2026 14:37:28 +0530 Subject: [PATCH 13/14] fix(SocketPort): ensure null termination after strncpy for interface name strncpy with IFNAMSIZ-1 leaves the buffer unterminated when the interface name is exactly 15 characters long. Added explicit null termination at IFNAMSIZ-1 after both the Apple and Linux strncpy calls to guarantee the string is always safely terminated before being passed to the kernel. --- Source/core/SocketPort.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Source/core/SocketPort.cpp b/Source/core/SocketPort.cpp index 30f1fe0146..ca6219ce7c 100644 --- a/Source/core/SocketPort.cpp +++ b/Source/core/SocketPort.cpp @@ -883,10 +883,12 @@ namespace Thunder { struct ifreq interface; #ifdef __APPLE__ strncpy(interface.ifr_name, specificInterface.c_str(), IFNAMSIZ - 1); + interface.ifr_name[IFNAMSIZ - 1] = '\0'; int index = if_nametoindex(interface.ifr_name); if (::setsockopt(l_Result, IPPROTO_IP, IP_BOUND_IF, (const char*)&index, sizeof(index)) < 0) { #else strncpy(interface.ifr_ifrn.ifrn_name, specificInterface.c_str(), IFNAMSIZ - 1); + interface.ifr_ifrn.ifrn_name[IFNAMSIZ - 1] = '\0'; if (::setsockopt(l_Result, SOL_SOCKET, SO_BINDTODEVICE, (const char*)&interface, sizeof(interface)) < 0) { #endif From 7398fba5ba91a92afd89f1cd64714aca7757be85 Mon Sep 17 00:00:00 2001 From: workkavint-ship-it Date: Fri, 29 May 2026 16:38:49 +0530 Subject: [PATCH 14/14] fix(NetworkInfo): restore missing closing brace in LoadAdapterInfo --- Source/core/NetworkInfo.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/Source/core/NetworkInfo.cpp b/Source/core/NetworkInfo.cpp index ff85f0dfd5..c4d50f69fd 100644 --- a/Source/core/NetworkInfo.cpp +++ b/Source/core/NetworkInfo.cpp @@ -585,6 +585,7 @@ namespace Core { } freeifaddrs(interfaces); + } return adapters.size(); }