From 946481c2aabad1ebb4643fcd35ee8334c7addf1d Mon Sep 17 00:00:00 2001 From: Connor McLaughlin Date: Sat, 6 Nov 2021 10:48:23 +1000 Subject: [PATCH] System: Add a workaround for PSF files with incorrect header --- src/core/bios.cpp | 5 ++++- src/core/system.cpp | 23 +++++++++++++---------- 2 files changed, 17 insertions(+), 11 deletions(-) diff --git a/src/core/bios.cpp b/src/core/bios.cpp index 26b4de2bc..4113e22c7 100644 --- a/src/core/bios.cpp +++ b/src/core/bios.cpp @@ -247,7 +247,10 @@ bool IsValidPSExeHeader(const PSEXEHeader& header, u32 file_size) return false; if ((header.file_size + sizeof(PSEXEHeader)) > file_size) - return false; + { + Log_WarningPrintf("Incorrect file size in PS-EXE header: %u bytes should not be greater than %u bytes", + header.file_size, file_size - sizeof(PSEXEHeader)); + } return true; } diff --git a/src/core/system.cpp b/src/core/system.cpp index cdf82c765..66b386e9c 100644 --- a/src/core/system.cpp +++ b/src/core/system.cpp @@ -1659,16 +1659,17 @@ static bool LoadEXEToRAM(const char* filename, bool patch_bios) } } - if (header.file_size >= 4) + const u32 file_data_size = std::min(file_size - sizeof(BIOS::PSEXEHeader), header.file_size); + if (file_data_size >= 4) { - std::vector data_words((header.file_size + 3) / 4); - if (std::fread(data_words.data(), header.file_size, 1, fp) != 1) + std::vector data_words((file_data_size + 3) / 4); + if (std::fread(data_words.data(), file_data_size, 1, fp) != 1) { std::fclose(fp); return false; } - const u32 num_words = header.file_size / 4; + const u32 num_words = file_data_size / 4; u32 address = header.load_address; for (u32 i = 0; i < num_words; i++) { @@ -1711,7 +1712,8 @@ bool InjectEXEFromBuffer(const void* buffer, u32 buffer_size, bool patch_bios) std::memcpy(&header, buffer_ptr, sizeof(header)); buffer_ptr += sizeof(header); - if (!BIOS::IsValidPSExeHeader(header, static_cast(buffer_end - buffer_ptr))) + const u32 file_size = static_cast(static_cast(buffer_end - buffer_ptr)); + if (!BIOS::IsValidPSExeHeader(header, file_size)) return false; if (header.memfill_size > 0) @@ -1725,15 +1727,16 @@ bool InjectEXEFromBuffer(const void* buffer, u32 buffer_size, bool patch_bios) } } - if (header.file_size >= 4) + const u32 file_data_size = std::min(file_size - sizeof(BIOS::PSEXEHeader), header.file_size); + if (file_data_size >= 4) { - std::vector data_words((header.file_size + 3) / 4); - if ((buffer_end - buffer_ptr) < header.file_size) + std::vector data_words((file_data_size + 3) / 4); + if ((buffer_end - buffer_ptr) < file_data_size) return false; - std::memcpy(data_words.data(), buffer_ptr, header.file_size); + std::memcpy(data_words.data(), buffer_ptr, file_data_size); - const u32 num_words = header.file_size / 4; + const u32 num_words = file_data_size / 4; u32 address = header.load_address; for (u32 i = 0; i < num_words; i++) {