From 25024ea295b228edb897b243a671d7dad25a0986 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Wed, 22 May 2024 17:32:17 -0400 Subject: [PATCH] windows: Before SDL_main has run, use WideCharToMultibyte, not SDL_iconv. Otherwise, this will crash if the app sets its own SDL_malloc allocator, since SDL_iconv uses SDL_malloc. WideCharToMultibyte lets us calculate the needed memory for the argv[] string conversions, and then we use the win32 HeapAlloc() API to get some memory for it. Fixes #8967. --- src/core/gdk/SDL_gdk.cpp | 19 +++++++++++-------- src/core/windows/SDL_windows.c | 19 +++++++++++-------- 2 files changed, 22 insertions(+), 16 deletions(-) diff --git a/src/core/gdk/SDL_gdk.cpp b/src/core/gdk/SDL_gdk.cpp index 91d7217451..8e7a8caaa4 100644 --- a/src/core/gdk/SDL_gdk.cpp +++ b/src/core/gdk/SDL_gdk.cpp @@ -108,18 +108,21 @@ int SDL_RunApp(int, char**, SDL_main_func mainFunction, void *reserved) return OutOfMemory(); } for (i = 0; i < argc; ++i) { - DWORD len; - char *arg = WIN_StringToUTF8W(argvw[i]); - if (arg == NULL) { - return OutOfMemory(); + const int utf8size = WideCharToMultiByte(CP_UTF8, 0, argvw[i], -1, NULL, 0, NULL, NULL); + if (!utf8size) { // uhoh? + SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Fatal Error", "Error processing command line arguments", NULL); + return -1; } - len = (DWORD)SDL_strlen(arg); - argv[i] = (char *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len + 1); + + argv[i] = (char *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, utf8size); // this size includes the null-terminator character. if (!argv[i]) { return OutOfMemory(); } - SDL_memcpy(argv[i], arg, len); - SDL_free(arg); + + if (WideCharToMultiByte(CP_UTF8, 0, argvw[i], -1, argv[i], utf8size, NULL, NULL) == 0) { // failed? uhoh! + SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Fatal Error", "Error processing command line arguments", NULL); + return -1; + } } argv[i] = NULL; LocalFree(argvw); diff --git a/src/core/windows/SDL_windows.c b/src/core/windows/SDL_windows.c index b216706072..eea88ff8e6 100644 --- a/src/core/windows/SDL_windows.c +++ b/src/core/windows/SDL_windows.c @@ -431,18 +431,21 @@ int MINGW32_FORCEALIGN SDL_RunApp(int _argc, char* _argv[], SDL_main_func mainFu return OutOfMemory(); } for (i = 0; i < argc; ++i) { - DWORD len; - char *arg = WIN_StringToUTF8W(argvw[i]); - if (!arg) { - return OutOfMemory(); + const int utf8size = WideCharToMultiByte(CP_UTF8, 0, argvw[i], -1, NULL, 0, NULL, NULL); + if (!utf8size) { // uhoh? + SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Fatal Error", "Error processing command line arguments", NULL); + return -1; } - len = (DWORD)SDL_strlen(arg); - argv[i] = (char *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len + 1); + + argv[i] = (char *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, utf8size); // this size includes the null-terminator character. if (!argv[i]) { return OutOfMemory(); } - SDL_memcpy(argv[i], arg, len); - SDL_free(arg); + + if (WideCharToMultiByte(CP_UTF8, 0, argvw[i], -1, argv[i], utf8size, NULL, NULL) == 0) { // failed? uhoh! + SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Fatal Error", "Error processing command line arguments", NULL); + return -1; + } } argv[i] = NULL; LocalFree(argvw);