From 6886ae0dae3bbc418e6fac5467de830b9f7225c4 Mon Sep 17 00:00:00 2001 From: Jaromir Wysoglad Date: Fri, 6 Sep 2019 00:06:19 +0200 Subject: SDL: Copy result of SDL_iconv_string() --- backends/platform/sdl/sdl.cpp | 32 ++++++++++++++++++++++++++++---- 1 file changed, 28 insertions(+), 4 deletions(-) diff --git a/backends/platform/sdl/sdl.cpp b/backends/platform/sdl/sdl.cpp index c89a560976..39933cc94c 100644 --- a/backends/platform/sdl/sdl.cpp +++ b/backends/platform/sdl/sdl.cpp @@ -28,6 +28,7 @@ #include "common/taskbar.h" #include "common/textconsole.h" #include "common/translation.h" +#include "common/encoding.h" #include "backends/saves/default/default-saves.h" @@ -772,19 +773,42 @@ char *OSystem_SDL::convertEncoding(const char *to, const char *from, const char int zeroBytes = 1; if (Common::String(from).hasPrefixIgnoreCase("utf-16")) zeroBytes = 2; - if (Common::String(from).hasPrefixIgnoreCase("utf-32")) + else if (Common::String(from).hasPrefixIgnoreCase("utf-32")) zeroBytes = 4; + char *result; // SDL_iconv_string() takes char * instead of const char * as it's third parameter // with some older versions of SDL. #if SDL_VERSION_ATLEAST(2, 0, 0) - return SDL_iconv_string(to, from, string, length + zeroBytes); + result = SDL_iconv_string(to, from, string, length + zeroBytes); #else char *stringCopy = (char *) calloc(sizeof(char), length + zeroBytes); memcpy(stringCopy, string, length); - char *result = SDL_iconv_string(to, from, stringCopy, length + zeroBytes); + result = SDL_iconv_string(to, from, stringCopy, length + zeroBytes); free(stringCopy); - return result; #endif + if (result == nullptr) + return nullptr; + + // We need to copy the result, so that we can use SDL_free() + // on the string returned by SDL_iconv_string() and free() + // can then be used on the copyed and returned string. + // Sometimes free() and SDL_free() aren't compatible and + // using free() instead of SDL_free() can cause crashes. + size_t newLength = Common::Encoding::stringLength(result, to); + zeroBytes = 1; + if (Common::String(to).hasPrefixIgnoreCase("utf-16")) + zeroBytes = 2; + else if (Common::String(to).hasPrefixIgnoreCase("utf-32")) + zeroBytes = 4; + char *finalResult = (char *) malloc(newLength + zeroBytes); + if (!finalResult) { + warning("Could not allocate memory for encoding conversion"); + SDL_free(result); + return nullptr; + } + memcpy(finalResult, result, newLength + zeroBytes); + SDL_free(result); + return finalResult; } -- cgit v1.2.3