mirror of https://github.com/OpenRCT2/OpenRCT2.git
Fix #4558: Crash on loading invalid scenario
This commit is contained in:
parent
952c412334
commit
3c4a683701
|
@ -800,7 +800,7 @@ extern "C"
|
|||
return 0;
|
||||
}
|
||||
|
||||
size_t chunkSize = sawyercoding_read_chunk(rw, chunk);
|
||||
size_t chunkSize = sawyercoding_read_chunk_with_size(rw, chunk, 0x600000);
|
||||
chunk = Memory::Reallocate(chunk, chunkSize);
|
||||
if (chunk == nullptr)
|
||||
{
|
||||
|
|
|
@ -135,7 +135,7 @@ bool object_read_and_load_entries(SDL_RWops* rw)
|
|||
{
|
||||
// Read all the object entries
|
||||
rct_object_entry *entries = malloc(OBJECT_ENTRY_COUNT * sizeof(rct_object_entry));
|
||||
sawyercoding_read_chunk(rw, (uint8*)entries);
|
||||
sawyercoding_read_chunk_with_size(rw, (uint8*)entries, OBJECT_ENTRY_COUNT * sizeof(rct_object_entry));
|
||||
bool result = object_load_entries(entries);
|
||||
free(entries);
|
||||
return result;
|
||||
|
|
|
@ -97,11 +97,20 @@ bool scenario_load_basic(const char *path, rct_s6_header *header, rct_s6_info *i
|
|||
SDL_RWops* rw = SDL_RWFromFile(path, "rb");
|
||||
if (rw != NULL) {
|
||||
// Read first chunk
|
||||
sawyercoding_read_chunk(rw, (uint8*)header);
|
||||
size_t loaded_size = sawyercoding_read_chunk_with_size(rw, (uint8*)header, sizeof(rct_s6_header));
|
||||
if (loaded_size != sizeof(rct_s6_header)) {
|
||||
log_error("Failed to read header from scenario %s", path);
|
||||
SDL_RWclose(rw);
|
||||
return false;
|
||||
}
|
||||
if (header->type == S6_TYPE_SCENARIO) {
|
||||
// Read second chunk
|
||||
sawyercoding_read_chunk(rw, (uint8*)info);
|
||||
loaded_size = sawyercoding_read_chunk_with_size(rw, (uint8*)info, sizeof(rct_s6_info));
|
||||
SDL_RWclose(rw);
|
||||
if (loaded_size != sizeof(rct_s6_info)) {
|
||||
log_error("Failed to read info from scenario %s", path);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
} else {
|
||||
log_error("invalid scenario, %s", path);
|
||||
|
|
|
@ -84,7 +84,7 @@ bool sawyercoding_read_chunk_safe(SDL_RWops *rw, void *dst, size_t dstLength)
|
|||
{
|
||||
// Allocate 16 MB to store uncompressed data
|
||||
uint8 *tempBuffer = malloc(16 * 1024 * 1024);
|
||||
size_t uncompressedLength = sawyercoding_read_chunk(rw, tempBuffer);
|
||||
size_t uncompressedLength = sawyercoding_read_chunk_with_size(rw, tempBuffer, 16 * 1024 * 1024);
|
||||
if (uncompressedLength == SIZE_MAX) {
|
||||
free(tempBuffer);
|
||||
return false;
|
||||
|
@ -109,51 +109,6 @@ bool sawyercoding_skip_chunk(SDL_RWops *rw)
|
|||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* rct2: 0x0067685F
|
||||
* buffer (esi)
|
||||
*/
|
||||
size_t sawyercoding_read_chunk(SDL_RWops* rw, uint8 *buffer)
|
||||
{
|
||||
sawyercoding_chunk_header chunkHeader;
|
||||
|
||||
// Read chunk header
|
||||
if (SDL_RWread(rw, &chunkHeader, sizeof(sawyercoding_chunk_header), 1) != 1) {
|
||||
log_error("Unable to read chunk header!");
|
||||
return -1;
|
||||
}
|
||||
|
||||
uint8* src_buffer = malloc(chunkHeader.length);
|
||||
|
||||
// Read chunk data
|
||||
if (SDL_RWread(rw, src_buffer, chunkHeader.length, 1) != 1) {
|
||||
free(src_buffer);
|
||||
log_error("Unable to read chunk data!");
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Decode chunk data
|
||||
switch (chunkHeader.encoding) {
|
||||
case CHUNK_ENCODING_NONE:
|
||||
memcpy(buffer, src_buffer, chunkHeader.length);
|
||||
break;
|
||||
case CHUNK_ENCODING_RLE:
|
||||
chunkHeader.length = (uint32)decode_chunk_rle(src_buffer, buffer, chunkHeader.length);
|
||||
break;
|
||||
case CHUNK_ENCODING_RLECOMPRESSED:
|
||||
chunkHeader.length = (uint32)decode_chunk_rle(src_buffer, buffer, chunkHeader.length);
|
||||
chunkHeader.length = (uint32)decode_chunk_repeat(buffer, chunkHeader.length);
|
||||
break;
|
||||
case CHUNK_ENCODING_ROTATE:
|
||||
memcpy(buffer, src_buffer, chunkHeader.length);
|
||||
decode_chunk_rotate(buffer, chunkHeader.length);
|
||||
break;
|
||||
}
|
||||
free(src_buffer);
|
||||
return chunkHeader.length;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* rct2: 0x0067685F
|
||||
|
|
|
@ -51,7 +51,6 @@ int sawyercoding_validate_checksum(SDL_RWops* rw);
|
|||
uint32 sawyercoding_calculate_checksum(const uint8* buffer, size_t length);
|
||||
bool sawyercoding_read_chunk_safe(SDL_RWops *rw, void *dst, size_t dstLength);
|
||||
bool sawyercoding_skip_chunk(SDL_RWops *rw);
|
||||
size_t sawyercoding_read_chunk(SDL_RWops* rw, uint8 *buffer);
|
||||
size_t sawyercoding_read_chunk_with_size(SDL_RWops* rw, uint8 *buffer, const size_t buffer_size);
|
||||
size_t sawyercoding_write_chunk_buffer(uint8 *dst_file, uint8* buffer, sawyercoding_chunk_header chunkHeader);
|
||||
size_t sawyercoding_decode_sv4(const uint8 *src, uint8 *dst, size_t length, size_t bufferLength);
|
||||
|
|
Loading…
Reference in New Issue