diff options
Diffstat (limited to 'backends/platform')
| -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;  }  | 
