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
This commit is contained in:
Václav Slavík
2014-12-07 16:40:21 +00:00
parent bb7e69b7d6
commit 5c472ee4c6

View File

@@ -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;
}
}