mirror of https://github.com/OpenRCT2/OpenRCT2.git
Re-introduce checksum validation
This commit is contained in:
parent
fed4c248e3
commit
bb62bbebb3
|
@ -97,4 +97,41 @@ namespace SawyerEncoding
|
||||||
}
|
}
|
||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ValidateChecksum(IStream * stream)
|
||||||
|
{
|
||||||
|
// Get data size
|
||||||
|
uint64 initialPosition = stream->GetPosition();
|
||||||
|
uint64 dataSize = stream->GetLength() - initialPosition;
|
||||||
|
if (dataSize < 8)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
dataSize -= 4;
|
||||||
|
|
||||||
|
// Calculate checksum
|
||||||
|
uint32 checksum = 0;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
uint8 buffer[4096];
|
||||||
|
uint64 bufferSize = Math::Min(dataSize, sizeof(buffer));
|
||||||
|
stream->Read(buffer, bufferSize);
|
||||||
|
|
||||||
|
for (uint64 i = 0; i < bufferSize; i++)
|
||||||
|
{
|
||||||
|
checksum += buffer[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
dataSize -= bufferSize;
|
||||||
|
}
|
||||||
|
while (dataSize != 0);
|
||||||
|
|
||||||
|
// Read file checksum
|
||||||
|
uint32 fileChecksum = stream->ReadValue<uint32>();
|
||||||
|
|
||||||
|
// Rewind
|
||||||
|
stream->SetPosition(initialPosition);
|
||||||
|
|
||||||
|
return checksum == fileChecksum;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,4 +31,6 @@ namespace SawyerEncoding
|
||||||
{
|
{
|
||||||
return TryReadChunk(dst, sizeof(T), stream);
|
return TryReadChunk(dst, sizeof(T), stream);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ValidateChecksum(IStream * stream);
|
||||||
}
|
}
|
||||||
|
|
|
@ -85,15 +85,6 @@ public:
|
||||||
|
|
||||||
void LoadSavedGame(const utf8 * path) override
|
void LoadSavedGame(const utf8 * path) override
|
||||||
{
|
{
|
||||||
// if (!sawyercoding_validate_checksum(rw))
|
|
||||||
// {
|
|
||||||
// gErrorType = ERROR_TYPE_FILE_LOAD;
|
|
||||||
// gGameCommandErrorTitle = STR_FILE_CONTAINS_INVALID_DATA;
|
|
||||||
//
|
|
||||||
// log_error("failed to load saved game, invalid checksum");
|
|
||||||
// throw IOException("Invalid SV6 checksum.");
|
|
||||||
// }
|
|
||||||
|
|
||||||
auto fs = FileStream(path, FILE_MODE_OPEN);
|
auto fs = FileStream(path, FILE_MODE_OPEN);
|
||||||
LoadFromStream(&fs, false);
|
LoadFromStream(&fs, false);
|
||||||
_s6Path = path;
|
_s6Path = path;
|
||||||
|
@ -101,17 +92,6 @@ public:
|
||||||
|
|
||||||
void LoadScenario(const utf8 * path) override
|
void LoadScenario(const utf8 * path) override
|
||||||
{
|
{
|
||||||
// if (!gConfigGeneral.allow_loading_with_incorrect_checksum && !sawyercoding_validate_checksum(rw))
|
|
||||||
// {
|
|
||||||
// SDL_RWclose(rw);
|
|
||||||
//
|
|
||||||
// gErrorType = ERROR_TYPE_FILE_LOAD;
|
|
||||||
// gErrorStringId = STR_FILE_CONTAINS_INVALID_DATA;
|
|
||||||
//
|
|
||||||
// log_error("failed to load scenario, invalid checksum");
|
|
||||||
// throw IOException("Invalid SC6 checksum.");
|
|
||||||
// }
|
|
||||||
|
|
||||||
auto fs = FileStream(path, FILE_MODE_OPEN);
|
auto fs = FileStream(path, FILE_MODE_OPEN);
|
||||||
LoadFromStream(&fs, true);
|
LoadFromStream(&fs, true);
|
||||||
_s6Path = path;
|
_s6Path = path;
|
||||||
|
@ -119,6 +99,11 @@ public:
|
||||||
|
|
||||||
void LoadFromStream(IStream * stream, bool isScenario)
|
void LoadFromStream(IStream * stream, bool isScenario)
|
||||||
{
|
{
|
||||||
|
if (!gConfigGeneral.allow_loading_with_incorrect_checksum && !SawyerEncoding::ValidateChecksum(stream))
|
||||||
|
{
|
||||||
|
throw IOException("Invalid checksum.");
|
||||||
|
}
|
||||||
|
|
||||||
SawyerEncoding::ReadChunkTolerant(&_s6.header, sizeof(_s6.header), stream);
|
SawyerEncoding::ReadChunkTolerant(&_s6.header, sizeof(_s6.header), stream);
|
||||||
|
|
||||||
log_verbose("saved game classic_flag = 0x%02x\n", _s6.header.classic_flag);
|
log_verbose("saved game classic_flag = 0x%02x\n", _s6.header.classic_flag);
|
||||||
|
|
Loading…
Reference in New Issue