mingw: be more defensive when making the environment block

Outside of our Windows-specific code, the end of the environment can be
marked also by a pointer to a NUL character, not only by a NULL pointer
as our code assumed so far.

That led to a buffer overrun in `make_environment_block()` when running
`git-remote-https` in `mintty` (because `curl_global_init()` added the
`CHARSET` environment variable *outside* of `mingw_putenv()`, ending the
environment in a pointer to an empty string).

Side note for future debugging on Windows: when running programs in
`mintty`, the standard input/output/error is not connected to a Win32
Console, but instead is pipe()d. That means that even stderr may not be
written completely before a crash, but has to be fflush()ed explicitly.
For example, when debugging crashes, the developer should insert an
`fflush(stderr);` at the end of the `error()` function defined in
usage.c.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
This commit is contained in:
Johannes Schindelin
2015-03-18 10:57:52 +01:00
committed by Jameson Miller
parent 3cd10cf43d
commit bfed19c720

View File

@@ -1094,7 +1094,7 @@ static wchar_t *make_environment_block(char **deltaenv)
char **tmpenv;
int i = 0, size = environ_size, wenvsz = 0, wenvpos = 0;
while (deltaenv && deltaenv[i])
while (deltaenv && deltaenv[i] && *deltaenv[i])
i++;
/* copy the environment, leaving space for changes */
@@ -1102,11 +1102,11 @@ static wchar_t *make_environment_block(char **deltaenv)
memcpy(tmpenv, environ, size * sizeof(char*));
/* merge supplied environment changes into the temporary environment */
for (i = 0; deltaenv && deltaenv[i]; i++)
for (i = 0; deltaenv && deltaenv[i] && *deltaenv[i]; i++)
size = do_putenv(tmpenv, deltaenv[i], size, 0);
/* create environment block from temporary environment */
for (i = 0; tmpenv[i]; i++) {
for (i = 0; tmpenv[i] && *tmpenv[i]; i++) {
size = 2 * strlen(tmpenv[i]) + 2; /* +2 for final \0 */
ALLOC_GROW(wenvblk, (wenvpos + size) * sizeof(wchar_t), wenvsz);
wenvpos += xutftowcs(&wenvblk[wenvpos], tmpenv[i], size) + 1;