diff --git a/src/system/dmod_system.c b/src/system/dmod_system.c index 62fb84f..fbc429f 100644 --- a/src/system/dmod_system.c +++ b/src/system/dmod_system.c @@ -1237,15 +1237,81 @@ bool Dmod_ReadModuleHeader(const char* FilePath, Dmod_ModuleHeader_t* Header) return false; } - if( Dmod_FileRead( Header, sizeof(Dmod_ModuleHeader_t), 1, file ) != 1 ) + // Get file size + size_t fileSize = Dmod_FileSize( file ); + if( fileSize == 0 ) + { + DMOD_LOG_ERROR("Cannot read module header - file is empty\n"); + Dmod_FileClose( file ); + return false; + } + + // Read file into buffer to check for compression + void* buffer = Dmod_Malloc( fileSize ); + if( buffer == NULL ) + { + DMOD_LOG_ERROR("Cannot read module header - cannot allocate memory\n"); + Dmod_FileClose( file ); + return false; + } + + if( Dmod_FileRead( buffer, 1, fileSize, file ) != fileSize ) { - DMOD_LOG_ERROR("Cannot read module header - cannot read header\n"); + DMOD_LOG_ERROR("Cannot read module header - cannot read file\n"); + Dmod_Free( buffer ); Dmod_FileClose( file ); return false; } Dmod_FileClose( file ); + // Check if file is compressed (DMFC) + void* dmfData = buffer; + size_t dmfSize = fileSize; + bool dmfDataNeedsFree = false; + + if( Dmod_IsDMFC(buffer, fileSize) ) + { + // Decompress the file + if( !Dmod_FromDMFC(buffer, fileSize, &dmfData, &dmfSize) ) + { + DMOD_LOG_ERROR("Cannot read module header - failed to decompress DMFC file\n"); + Dmod_Free( buffer ); + return false; + } + Dmod_Free( buffer ); + dmfDataNeedsFree = true; + } + + // Verify decompressed size is sufficient + if( dmfSize < sizeof(Dmod_ModuleHeader_t) ) + { + DMOD_LOG_ERROR("Cannot read module header - decompressed data too small\n"); + // Clean up + if( dmfDataNeedsFree ) + { + Dmod_Free( dmfData ); + } + else + { + Dmod_Free( buffer ); + } + return false; + } + + // Copy header from decompressed data + memcpy( Header, dmfData, sizeof(Dmod_ModuleHeader_t) ); + + // Clean up + if( dmfDataNeedsFree ) + { + Dmod_Free( dmfData ); + } + else + { + Dmod_Free( buffer ); + } + return true; }