diff options
-rw-r--r-- | compat/mingw.c | 43 |
1 files changed, 28 insertions, 15 deletions
diff --git a/compat/mingw.c b/compat/mingw.c index 967c1a0a58..a99ebd081a 100644 --- a/compat/mingw.c +++ b/compat/mingw.c @@ -2033,9 +2033,23 @@ static NORETURN void die_startup() exit(128); } +static void *malloc_startup(size_t size) +{ + void *result = malloc(size); + if (!result) + die_startup(); + return result; +} + +static char *wcstoutfdup_startup(char *buffer, const wchar_t *wcs, size_t len) +{ + len = xwcstoutf(buffer, wcs, len) + 1; + return memcpy(malloc_startup(len), buffer, len); +} + void mingw_startup() { - int i, len, maxlen, argc; + int i, maxlen, argc; char *buffer; wchar_t **wenv, **wargv; _startupinfo si; @@ -2052,26 +2066,25 @@ void mingw_startup() for (i = 0; wenv[i]; i++) maxlen = max(maxlen, wcslen(wenv[i])); - /* nedmalloc can't free CRT memory, allocate resizable environment list */ - environ = NULL; + /* + * nedmalloc can't free CRT memory, allocate resizable environment + * list. Note that xmalloc / xmemdupz etc. call getenv, so we cannot + * use it while initializing the environment itself. + */ environ_size = i + 1; - ALLOC_GROW(environ, environ_size * sizeof(char*), environ_alloc); + environ_alloc = alloc_nr(environ_size * sizeof(char*)); + environ = malloc_startup(environ_alloc); /* allocate buffer (wchar_t encodes to max 3 UTF-8 bytes) */ maxlen = 3 * maxlen + 1; - buffer = xmalloc(maxlen); + buffer = malloc_startup(maxlen); /* convert command line arguments and environment to UTF-8 */ - len = xwcstoutf(buffer, _wpgmptr, maxlen); - __argv[0] = xmemdupz(buffer, len); - for (i = 1; i < argc; i++) { - len = xwcstoutf(buffer, wargv[i], maxlen); - __argv[i] = xmemdupz(buffer, len); - } - for (i = 0; wenv[i]; i++) { - len = xwcstoutf(buffer, wenv[i], maxlen); - environ[i] = xmemdupz(buffer, len); - } + __argv[0] = wcstoutfdup_startup(buffer, _wpgmptr, maxlen); + for (i = 1; i < argc; i++) + __argv[i] = wcstoutfdup_startup(buffer, wargv[i], maxlen); + for (i = 0; wenv[i]; i++) + environ[i] = wcstoutfdup_startup(buffer, wenv[i], maxlen); environ[i] = NULL; free(buffer); |