diff --git a/src/localisation/language.cpp b/src/localisation/language.cpp index 87fabc2fc3..1e74be1265 100644 --- a/src/localisation/language.cpp +++ b/src/localisation/language.cpp @@ -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); } } diff --git a/src/localisation/language.h b/src/localisation/language.h index c509c7b37e..b6062821a1 100644 --- a/src/localisation/language.h +++ b/src/localisation/language.h @@ -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); diff --git a/src/localisation/localisation.c b/src/localisation/localisation.c index e5c53a912a..8f76f1927b 100644 --- a/src/localisation/localisation.c +++ b/src/localisation/localisation.c @@ -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; diff --git a/src/localisation/localisation.h b/src/localisation/localisation.h index b573e5a145..3700edd706 100644 --- a/src/localisation/localisation.h +++ b/src/localisation/localisation.h @@ -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); diff --git a/src/object/StringTable.cpp b/src/object/StringTable.cpp index 44123f1f83..d5d7d988d7 100644 --- a/src/object/StringTable.cpp +++ b/src/object/StringTable.cpp @@ -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)) { diff --git a/src/scenario/ScenarioRepository.cpp b/src/scenario/ScenarioRepository.cpp index 8c909de624..190d6999a3 100644 --- a/src/scenario/ScenarioRepository.cpp +++ b/src/scenario/ScenarioRepository.cpp @@ -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; }