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/branches/WX_3_0_BRANCH@78256 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -137,8 +137,8 @@ static struct InitData
|
|||||||
nInitCount = 0;
|
nInitCount = 0;
|
||||||
|
|
||||||
#if wxUSE_UNICODE
|
#if wxUSE_UNICODE
|
||||||
argc = 0;
|
argc = argcOrig = 0;
|
||||||
// argv = NULL; -- not even really needed
|
// argv = argvOrig = NULL; -- not even really needed
|
||||||
#endif // wxUSE_UNICODE
|
#endif // wxUSE_UNICODE
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -157,6 +157,12 @@ static struct InitData
|
|||||||
// for example), we remember the converted argv here because we'll have to
|
// for example), we remember the converted argv here because we'll have to
|
||||||
// free it when doing cleanup to avoid memory leaks
|
// free it when doing cleanup to avoid memory leaks
|
||||||
wchar_t **argv;
|
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
|
#endif // wxUSE_UNICODE
|
||||||
|
|
||||||
wxDECLARE_NO_COPY_CLASS(InitData);
|
wxDECLARE_NO_COPY_CLASS(InitData);
|
||||||
@@ -174,7 +180,9 @@ static struct InitData
|
|||||||
|
|
||||||
static void ConvertArgsToUnicode(int argc, char **argv)
|
static void ConvertArgsToUnicode(int argc, char **argv)
|
||||||
{
|
{
|
||||||
|
gs_initData.argvOrig = new wchar_t *[argc + 1];
|
||||||
gs_initData.argv = new wchar_t *[argc + 1];
|
gs_initData.argv = new wchar_t *[argc + 1];
|
||||||
|
|
||||||
int wargc = 0;
|
int wargc = 0;
|
||||||
for ( int i = 0; i < argc; i++ )
|
for ( int i = 0; i < argc; i++ )
|
||||||
{
|
{
|
||||||
@@ -190,25 +198,28 @@ static void ConvertArgsToUnicode(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
else // converted ok
|
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.argcOrig = gs_initData.argc = wargc;
|
||||||
gs_initData.argv[wargc] = NULL;
|
gs_initData.argvOrig[wargc] =gs_initData.argv[wargc] = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void FreeConvertedArgs()
|
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);
|
wxDELETEA(gs_initData.argv);
|
||||||
gs_initData.argc = 0;
|
gs_initData.argcOrig = gs_initData.argc = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user