From 5c472ee4c66a8b09099f85378f9c8c7058bc7795 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=A1clav=20Slav=C3=ADk?= Date: Sun, 7 Dec 2014 16:40:21 +0000 Subject: [PATCH] Don't crash on OS X on exit if -NS* argument used When converting argv[] from char* to wchar_t* in ConvertArgsToUnicode(), keep an extra (shallow) copy of argc and the argv[] array so that it can be safely freed in FreeConvertedArgs(). The reason is that other functions such as wxApp::Initialize() may modify argv[] and remove some arguments from it; this is indeed exactly what wxOSX does. After such changes, gs_initData.argv would no longer be in the original state and could contain e.g. duplicate pointers or be missing some of the pointers that we should free. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@78254 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- src/common/init.cpp | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/src/common/init.cpp b/src/common/init.cpp index 081c407fc4..fc72bd1d18 100644 --- a/src/common/init.cpp +++ b/src/common/init.cpp @@ -137,8 +137,8 @@ static struct InitData nInitCount = 0; #if wxUSE_UNICODE - argc = 0; - // argv = NULL; -- not even really needed + argc = argcOrig = 0; + // argv = argvOrig = NULL; -- not even really needed #endif // wxUSE_UNICODE } @@ -157,6 +157,12 @@ static struct InitData // for example), we remember the converted argv here because we'll have to // free it when doing cleanup to avoid memory leaks wchar_t **argv; + + // we also need to keep two copies, one passed to other functions, and one + // unmodified original; somebody may modify the former, so we need to have + // the latter to be able to free everything correctly + int argcOrig; + wchar_t **argvOrig; #endif // wxUSE_UNICODE wxDECLARE_NO_COPY_CLASS(InitData); @@ -174,7 +180,9 @@ static struct InitData static void ConvertArgsToUnicode(int argc, char **argv) { + gs_initData.argvOrig = new wchar_t *[argc + 1]; gs_initData.argv = new wchar_t *[argc + 1]; + int wargc = 0; for ( int i = 0; i < argc; i++ ) { @@ -190,25 +198,28 @@ static void ConvertArgsToUnicode(int argc, char **argv) } else // converted ok { - gs_initData.argv[wargc++] = wxStrdup(buf); + gs_initData.argvOrig[wargc] = gs_initData.argv[wargc] = wxStrdup(buf); + wargc++; } } - gs_initData.argc = wargc; - gs_initData.argv[wargc] = NULL; + gs_initData.argcOrig = gs_initData.argc = wargc; + gs_initData.argvOrig[wargc] =gs_initData.argv[wargc] = NULL; } static void FreeConvertedArgs() { - if ( gs_initData.argv ) + if ( gs_initData.argvOrig ) { - for ( int i = 0; i < gs_initData.argc; i++ ) + for ( int i = 0; i < gs_initData.argcOrig; i++ ) { - free(gs_initData.argv[i]); + free(gs_initData.argvOrig[i]); + // gs_initData.argv[i] normally points to the same data } + wxDELETEA(gs_initData.argvOrig); wxDELETEA(gs_initData.argv); - gs_initData.argc = 0; + gs_initData.argcOrig = gs_initData.argc = 0; } }