1
0
mirror of https://github.com/OpenRCT2/OpenRCT2 synced 2026-01-04 13:42:55 +01:00

Prevent invalid access in malformed objects

This commit is contained in:
Michał Janiszewski
2016-12-26 23:42:19 +01:00
committed by Ted John
parent c3035b7601
commit 3aa0eb9bcd
6 changed files with 18 additions and 19 deletions

View File

@@ -142,12 +142,12 @@ static wchar_t convert_specific_language_character_to_unicode(int languageId, wc
}
}
static utf8 * convert_multibyte_charset(const char * src, int languageId)
static utf8 * convert_multibyte_charset(const char * src, size_t srcMaxSize, int languageId)
{
constexpr char CODEPOINT_DOUBLEBYTE = (char)0xFF;
auto sb = StringBuilder(64);
for (const char * ch = src; *ch != 0;)
for (const char * ch = src; (ch < src + srcMaxSize) && (*ch != 0);)
{
if (*ch == CODEPOINT_DOUBLEBYTE)
{
@@ -181,15 +181,15 @@ static bool rct2_language_is_multibyte_charset(int languageId)
}
}
utf8 *rct2_language_string_to_utf8(const char *src, int languageId)
utf8 *rct2_language_string_to_utf8(const char *src, size_t srcSize, int languageId)
{
if (rct2_language_is_multibyte_charset(languageId))
{
return convert_multibyte_charset(src, languageId);
return convert_multibyte_charset(src, srcSize, languageId);
}
else
{
return win1252_to_utf8_alloc(src);
return win1252_to_utf8_alloc(src, srcSize);
}
}

View File

@@ -79,7 +79,7 @@ int utf8_length(const utf8 *text);
wchar_t *utf8_to_widechar(const utf8 *src);
utf8 *widechar_to_utf8(const wchar_t *src);
utf8 *rct2_language_string_to_utf8(const char *src, int languageId);
utf8 *rct2_language_string_to_utf8(const char *src, size_t srcSize, int languageId);
bool language_get_localised_scenario_strings(const utf8 *scenarioFilename, rct_string_id *outStringIds);
rct_string_id language_allocate_object_string(const utf8 * target);
void language_free_object_string(rct_string_id stringId);

View File

@@ -1213,18 +1213,17 @@ void format_string_to_upper(utf8 *dest, size_t size, rct_string_id format, void
}
}
utf8 *win1252_to_utf8_alloc(const char *src)
utf8 *win1252_to_utf8_alloc(const char *src, size_t srcMaxSize)
{
size_t reservedSpace = (strlen(src) * 4) + 1;
size_t stringLength = strnlen(src, srcMaxSize);
size_t reservedSpace = (stringLength * 4) + 1;
utf8 *result = malloc(reservedSpace);
int actualSpace = win1252_to_utf8(result, src, reservedSpace);
int actualSpace = win1252_to_utf8(result, src, stringLength, reservedSpace);
return (utf8*)realloc(result, actualSpace);
}
int win1252_to_utf8(utf8string dst, const char *src, size_t maxBufferLength)
int win1252_to_utf8(utf8string dst, const char *src, size_t srcLength, size_t maxBufferLength)
{
size_t srcLength = strlen(src);
#ifdef __WINDOWS__
utf16 stackBuffer[256];
utf16 *heapBuffer = NULL;

View File

@@ -44,8 +44,8 @@ rct_string_id user_string_allocate(int base, const utf8 *text);
void user_string_free(rct_string_id id);
bool is_user_string_id(rct_string_id stringId);
utf8 *win1252_to_utf8_alloc(const char *src);
int win1252_to_utf8(utf8string dst, const char *src, size_t maxBufferLength);
utf8 *win1252_to_utf8_alloc(const char *src, size_t srcMaxSize);
int win1252_to_utf8(utf8string dst, const char *src, size_t srcLength, size_t maxBufferLength);
int rct2_to_utf8(utf8 *dst, const char *src);
int utf8_to_rct2(char *dst, const utf8 *src);

View File

@@ -57,9 +57,8 @@ void StringTable::Read(IReadObjectContext * context, IStream * stream, uint8 id)
entry.Id = id;
entry.LanguageId = languageId;
char * stringAsWin1252 = stream->ReadString();
utf8 * stringAsUtf8 = rct2_language_string_to_utf8(stringAsWin1252, languageId);
Memory::Free(stringAsWin1252);
std::string stringAsWin1252 = stream->ReadStdString();
utf8 * stringAsUtf8 = rct2_language_string_to_utf8(stringAsWin1252.c_str(), stringAsWin1252.size(), languageId);
if (StringIsBlank(stringAsUtf8))
{

View File

@@ -23,6 +23,7 @@
#include "../core/Math.hpp"
#include "../core/Path.hpp"
#include "../core/String.hpp"
#include "../core/Util.hpp"
#include "../PlatformEnvironment.h"
#include "ScenarioRepository.h"
#include "ScenarioSources.h"
@@ -450,7 +451,7 @@ private:
if (scBasic.company_value > highscore->company_value)
{
SafeFree(highscore->name);
highscore->name = win1252_to_utf8_alloc(scBasic.completed_by);
highscore->name = win1252_to_utf8_alloc(scBasic.completed_by, Util::CountOf(scBasic.completed_by));
highscore->company_value = scBasic.company_value;
highscore->timestamp = DATETIME64_MIN;
break;
@@ -461,7 +462,7 @@ private:
{
scenario_highscore_entry * highscore = InsertHighscore();
highscore->fileName = String::Duplicate(scBasic.path);
highscore->name = win1252_to_utf8_alloc(scBasic.completed_by);
highscore->name = win1252_to_utf8_alloc(scBasic.completed_by, Util::CountOf(scBasic.completed_by));
highscore->company_value = scBasic.company_value;
highscore->timestamp = DATETIME64_MIN;
}