Fixed infinite loop when trying to load invalid rom files (when file size does not match header)

This commit is contained in:
Sour 2019-01-20 15:04:23 -05:00
parent 1ef80d8cec
commit 2ef8e235c6
3 changed files with 13 additions and 33 deletions

View file

@ -248,30 +248,3 @@ PpuModel NESHeader::GetVsSystemPpuModel()
} }
return PpuModel::Ppu2C03; return PpuModel::Ppu2C03;
} }
void NESHeader::SanitizeHeader(size_t romLength)
{
uint32_t originalPrgSize = GetPrgSize();
uint32_t originalChrSize = GetChrSize();
size_t calculatedLength = sizeof(NESHeader) + GetPrgSize();
while(calculatedLength > romLength) {
Byte9 = 0;
PrgCount--;
calculatedLength = sizeof(NESHeader) + GetPrgSize();
}
calculatedLength = sizeof(NESHeader) + GetPrgSize() + GetChrSize();
while(calculatedLength > romLength) {
Byte9 = 0;
ChrCount--;
calculatedLength = sizeof(NESHeader) + GetPrgSize() + GetChrSize();
}
if(originalPrgSize != GetPrgSize()) {
MessageManager::Log("[iNes] Invalid ROM file length - PRG data has been truncated.");
}
if(originalChrSize != GetChrSize()) {
MessageManager::Log("[iNes] Invalid ROM file length - CHR data has been truncated.");
}
}

View file

@ -48,5 +48,4 @@ struct NESHeader
GameInputType GetInputType(); GameInputType GetInputType();
VsSystemType GetVsSystemType(); VsSystemType GetVsSystemType();
PpuModel GetVsSystemPpuModel(); PpuModel GetVsSystemPpuModel();
void SanitizeHeader(size_t romLength);
}; };

View file

@ -15,11 +15,9 @@ RomData iNesLoader::LoadRom(vector<uint8_t>& romFile, NESHeader *preloadedHeader
uint32_t dataSize = (uint32_t)romFile.size(); uint32_t dataSize = (uint32_t)romFile.size();
if(preloadedHeader) { if(preloadedHeader) {
header = *preloadedHeader; header = *preloadedHeader;
header.SanitizeHeader(romFile.size() + sizeof(NESHeader));
} else { } else {
memcpy((char*)&header, buffer, sizeof(NESHeader)); memcpy((char*)&header, buffer, sizeof(NESHeader));
buffer += sizeof(NESHeader); buffer += sizeof(NESHeader);
header.SanitizeHeader(romFile.size());
dataSize -= sizeof(NESHeader); dataSize -= sizeof(NESHeader);
} }
@ -46,9 +44,16 @@ RomData iNesLoader::LoadRom(vector<uint8_t>& romFile, NESHeader *preloadedHeader
romData.SaveRamSize = header.GetSaveRamSize(); romData.SaveRamSize = header.GetSaveRamSize();
if(romData.Info.HasTrainer) { if(romData.Info.HasTrainer) {
//512-byte trainer at $7000-$71FF (stored before PRG data) if(dataSize >= 512) {
romData.TrainerData.insert(romData.TrainerData.end(), buffer, buffer + 512); //512-byte trainer at $7000-$71FF (stored before PRG data)
buffer += 512; romData.TrainerData.insert(romData.TrainerData.end(), buffer, buffer + 512);
buffer += 512;
dataSize -= 512;
} else {
romData.Error = true;
MessageManager::Log("[iNes] Invalid file (file length does not match header information) - load operation cancelled.");
return romData;
}
} }
size_t bytesRead = buffer - romFile.data(); size_t bytesRead = buffer - romFile.data();
@ -68,8 +73,11 @@ RomData iNesLoader::LoadRom(vector<uint8_t>& romFile, NESHeader *preloadedHeader
if(prgSize + chrSize > dataSize) { if(prgSize + chrSize > dataSize) {
//Invalid rom file //Invalid rom file
MessageManager::Log("[iNes] Invalid file (file length does not match header information) - load operation cancelled.");
romData.Error = true; romData.Error = true;
return romData; return romData;
} else if(prgSize + chrSize < dataSize) {
MessageManager::Log("[iNes] Warning: File is larger than excepted (based on the file header).");
} }
romData.PrgRom.insert(romData.PrgRom.end(), buffer, buffer + prgSize); romData.PrgRom.insert(romData.PrgRom.end(), buffer, buffer + prgSize);