Check RLE chunk size

This commit is contained in:
Michał Janiszewski 2016-06-23 22:48:46 +02:00 committed by Ted John
parent 17f8f9fabd
commit da08b963c9
2 changed files with 34 additions and 3 deletions

View File

@ -83,12 +83,12 @@ int object_load_file(int groupIndex, const rct_object_entry *entry, int* chunkSi
if (*chunkSize == 0xFFFFFFFF) {
chunk = (uint8*)malloc(0x600000);
assert(chunk != NULL);
*chunkSize = sawyercoding_read_chunk(rw, chunk);
*chunkSize = sawyercoding_read_chunk_with_size(rw, chunk, 0x600000);
chunk = realloc(chunk, *chunkSize);
}
else {
chunk = (uint8*)malloc(*chunkSize);
*chunkSize = sawyercoding_read_chunk(rw, chunk);
*chunkSize = sawyercoding_read_chunk_with_size(rw, chunk, *chunkSize);
}
SDL_RWclose(rw);
if (chunk == NULL) {

View File

@ -21,6 +21,7 @@
#include "util.h"
static size_t decode_chunk_rle(const uint8* src_buffer, uint8* dst_buffer, size_t length);
static size_t decode_chunk_rle_with_size(const uint8* src_buffer, uint8* dst_buffer, size_t length, size_t dstSize);
static size_t decode_chunk_repeat(uint8 *buffer, size_t length);
static void decode_chunk_rotate(uint8 *buffer, size_t length);
@ -171,7 +172,7 @@ size_t sawyercoding_read_chunk_with_size(SDL_RWops* rw, uint8 *buffer, const siz
memcpy(buffer, src_buffer, chunkHeader.length);
break;
case CHUNK_ENCODING_RLE:
chunkHeader.length = decode_chunk_rle(src_buffer, buffer, chunkHeader.length);
chunkHeader.length = decode_chunk_rle_with_size(src_buffer, buffer, chunkHeader.length, buffer_size);
break;
case CHUNK_ENCODING_RLECOMPRESSED:
chunkHeader.length = decode_chunk_rle(src_buffer, buffer, chunkHeader.length);
@ -360,6 +361,36 @@ static size_t decode_chunk_rle(const uint8* src_buffer, uint8* dst_buffer, size_
return dst - dst_buffer;
}
/**
*
* rct2: 0x0067693A
*/
static size_t decode_chunk_rle_with_size(const uint8* src_buffer, uint8* dst_buffer, size_t length, size_t dstSize)
{
size_t count;
uint8 *dst, rleCodeByte;
dst = dst_buffer;
for (size_t i = 0; i < length; i++) {
rleCodeByte = src_buffer[i];
if (rleCodeByte & 128) {
i++;
count = 257 - rleCodeByte;
memset(dst, src_buffer[i], count);
dst = (uint8*)((uintptr_t)dst + count);
} else {
assert(dst + rleCodeByte + 1 <= dst_buffer + dstSize);
memcpy(dst, src_buffer + i + 1, rleCodeByte + 1);
dst = (uint8*)((uintptr_t)dst + rleCodeByte + 1);
i += rleCodeByte + 1;
}
}
// Return final size
return dst - dst_buffer;
}
/**
*
* rct2: 0x006769F1