From 99846e20b721de3cc83fff3d2d914237bf59dd2b Mon Sep 17 00:00:00 2001 From: Robert Crossfield Date: Sun, 24 May 2026 12:15:06 +1000 Subject: [PATCH] Harden loose-resource RNC decompression checks --- Source/Resources.cpp | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/Source/Resources.cpp b/Source/Resources.cpp index d6486d19..acf7cb24 100644 --- a/Source/Resources.cpp +++ b/Source/Resources.cpp @@ -38,15 +38,29 @@ tSharedBuffer cResources::fileGet( std::string pFilename ) { } tSharedBuffer cResources::fileDeRNC(tSharedBuffer pBuffer) { + constexpr uint32 RNCHeaderSize = 18; + constexpr uint32 MaxUnpackedSize = 64 * 1024 * 1024; + + if (pBuffer->size() < RNCHeaderSize) + return pBuffer; + uint32 Header = readBEDWord(pBuffer->data()); if (Header != 'RNC\01') return pBuffer; uint32 Size = readBEDWord(pBuffer->data() + 4); + uint32 PackedSize = readBEDWord(pBuffer->data() + 8); + + if ((PackedSize > (pBuffer->size() - RNCHeaderSize)) || !Size || (Size > MaxUnpackedSize)) + return pBuffer; auto Unpacked = std::make_shared>(); Unpacked->resize(Size); - rnc_unpack(pBuffer->data(), Unpacked->data()); + + long Result = rnc_unpack(pBuffer->data(), Unpacked->data()); + if (Result != static_cast(Size)) + return pBuffer; + return Unpacked; }