Fix crash using "--command" on Windows
Use after free error accessing command line arguments on windows. Resolve by duplicating the arguments when a "--command" is passed in.
This commit is contained in:
@@ -567,8 +567,8 @@ int main(int argc,
|
|||||||
if (G.background) {
|
if (G.background) {
|
||||||
int exit_code;
|
int exit_code;
|
||||||
if (app_state.main_arg_deferred != nullptr) {
|
if (app_state.main_arg_deferred != nullptr) {
|
||||||
exit_code = main_arg_handle_deferred();
|
exit_code = main_arg_deferred_handle();
|
||||||
MEM_freeN(app_state.main_arg_deferred);
|
main_arg_deferred_free();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
exit_code = G.is_break ? EXIT_FAILURE : EXIT_SUCCESS;
|
exit_code = G.is_break ? EXIT_FAILURE : EXIT_SUCCESS;
|
||||||
|
|||||||
@@ -429,6 +429,28 @@ fail:
|
|||||||
* (Python in particular) * to be initialized.
|
* (Python in particular) * to be initialized.
|
||||||
* \{ */
|
* \{ */
|
||||||
|
|
||||||
|
/* When the deferred argument is handled on Windows the `argv` will have been freed,
|
||||||
|
* see `USE_WIN32_UNICODE_ARGS` in `creator.cc`. */
|
||||||
|
|
||||||
|
# ifdef WIN32
|
||||||
|
static char **argv_duplicate(const char **argv, int argc)
|
||||||
|
{
|
||||||
|
char **argv_copy = static_cast<char **>(MEM_mallocN(sizeof(*argv_copy) * argc, __func__));
|
||||||
|
for (int i = 0; i < argc; i++) {
|
||||||
|
argv_copy[i] = BLI_strdup(argv[i]);
|
||||||
|
}
|
||||||
|
return argv_copy;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void argv_free(char **argv, int argc)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < argc; i++) {
|
||||||
|
MEM_freeN(argv[i]);
|
||||||
|
}
|
||||||
|
MEM_freeN(argv);
|
||||||
|
}
|
||||||
|
# endif /* !WIN32 */
|
||||||
|
|
||||||
struct BA_ArgCallback_Deferred {
|
struct BA_ArgCallback_Deferred {
|
||||||
BA_ArgCallback func;
|
BA_ArgCallback func;
|
||||||
int argc;
|
int argc;
|
||||||
@@ -453,9 +475,22 @@ static void main_arg_deferred_setup(BA_ArgCallback func, int argc, const char **
|
|||||||
d->argv = argv;
|
d->argv = argv;
|
||||||
d->data = data;
|
d->data = data;
|
||||||
d->exit_code = 0;
|
d->exit_code = 0;
|
||||||
|
# ifdef WIN32
|
||||||
|
d->argv = const_cast<const char **>(argv_duplicate(d->argv, d->argc));
|
||||||
|
# endif
|
||||||
app_state.main_arg_deferred = d;
|
app_state.main_arg_deferred = d;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void main_arg_deferred_free()
|
||||||
|
{
|
||||||
|
BA_ArgCallback_Deferred *d = app_state.main_arg_deferred;
|
||||||
|
app_state.main_arg_deferred = nullptr;
|
||||||
|
# ifdef WIN32
|
||||||
|
argv_free(const_cast<char **>(d->argv), d->argc);
|
||||||
|
# endif
|
||||||
|
MEM_freeN(d);
|
||||||
|
}
|
||||||
|
|
||||||
static void main_arg_deferred_exit_code_set(int exit_code)
|
static void main_arg_deferred_exit_code_set(int exit_code)
|
||||||
{
|
{
|
||||||
BA_ArgCallback_Deferred *d = app_state.main_arg_deferred;
|
BA_ArgCallback_Deferred *d = app_state.main_arg_deferred;
|
||||||
@@ -463,7 +498,7 @@ static void main_arg_deferred_exit_code_set(int exit_code)
|
|||||||
d->exit_code = exit_code;
|
d->exit_code = exit_code;
|
||||||
}
|
}
|
||||||
|
|
||||||
int main_arg_handle_deferred()
|
int main_arg_deferred_handle()
|
||||||
{
|
{
|
||||||
BA_ArgCallback_Deferred *d = app_state.main_arg_deferred;
|
BA_ArgCallback_Deferred *d = app_state.main_arg_deferred;
|
||||||
d->func(d->argc, d->argv, d->data);
|
d->func(d->argc, d->argv, d->data);
|
||||||
|
|||||||
@@ -38,7 +38,8 @@ int main_args_handle_load_file(int argc, const char **argv, void *data);
|
|||||||
* Handle an argument which requested deferred evaluation.
|
* Handle an argument which requested deferred evaluation.
|
||||||
* Needed when arguments which evaluate early need Python to be initialized for example.
|
* Needed when arguments which evaluate early need Python to be initialized for example.
|
||||||
*/
|
*/
|
||||||
int main_arg_handle_deferred();
|
int main_arg_deferred_handle();
|
||||||
|
void main_arg_deferred_free();
|
||||||
|
|
||||||
/* `creator_signals.cc` */
|
/* `creator_signals.cc` */
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user