aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJaromir Wysoglad2019-09-06 00:06:19 +0200
committerThierry Crozat2019-09-05 23:52:46 +0100
commit6886ae0dae3bbc418e6fac5467de830b9f7225c4 (patch)
tree4383bb2a3e57e48801aa6957f4db1fb9c8fe45b8
parent26bf329b9581985f04ccb26f41370a13836363ff (diff)
downloadscummvm-rg350-6886ae0dae3bbc418e6fac5467de830b9f7225c4.tar.gz
scummvm-rg350-6886ae0dae3bbc418e6fac5467de830b9f7225c4.tar.bz2
scummvm-rg350-6886ae0dae3bbc418e6fac5467de830b9f7225c4.zip
SDL: Copy result of SDL_iconv_string()
-rw-r--r--backends/platform/sdl/sdl.cpp32
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;
}