diff options
author | Jaromir Wysoglad | 2019-09-06 00:06:19 +0200 |
---|---|---|
committer | Thierry Crozat | 2019-09-05 23:52:46 +0100 |
commit | 6886ae0dae3bbc418e6fac5467de830b9f7225c4 (patch) | |
tree | 4383bb2a3e57e48801aa6957f4db1fb9c8fe45b8 /backends/platform/sdl | |
parent | 26bf329b9581985f04ccb26f41370a13836363ff (diff) | |
download | scummvm-rg350-6886ae0dae3bbc418e6fac5467de830b9f7225c4.tar.gz scummvm-rg350-6886ae0dae3bbc418e6fac5467de830b9f7225c4.tar.bz2 scummvm-rg350-6886ae0dae3bbc418e6fac5467de830b9f7225c4.zip |
SDL: Copy result of SDL_iconv_string()
Diffstat (limited to 'backends/platform/sdl')
-rw-r--r-- | backends/platform/sdl/sdl.cpp | 32 |
1 files 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; } |