On Thu, Feb 14, 2013 at 1:34 AM, Paul Eggert <[email protected]> wrote:
> On 02/13/2013 06:54 PM, Michael Goffioul wrote:
> > what would be the correct fix?
>
> Does the following fix things? Totally untested; I don't use MSVC.
>
> diff --git a/lib/putenv.c b/lib/putenv.c
> index 5f0feda..5108f41 100644
> --- a/lib/putenv.c
> +++ b/lib/putenv.c
> @@ -115,6 +115,38 @@ putenv (char *string)
>
> if (*ep == NULL)
> {
> +#if HAVE__PUTENV
> + /* Rely on _putenv to allocate the new environment. If other
> + parts of the application use _putenv, the !HAVE__PUTENV code
> + would fight over who owns the environ vector, causing a crash.
> */
> + if (name_end[1])
> + return _putenv (string);
> + else
> + {
> + /* _putenv ("NAME=") unsets NAME, so invoke _putenv ("NAME=x")
> + to allocate the environ vector and then replace the new
> + entry with "NAME=". */
> + int putenv_result, putenv_errno;
> + char *name_x = malloc (name_end - string + sizeof "=x");
> + if (!name_x)
> + return -1;
> + memcpy (name_x, string, name_end - string + 1);
> + name_x[name_end - string + 1] = 'x';
> + name_x[name_end - string + 2] = 0;
> + putenv_result = _putenv (name_x);
> + putenv_errno = errno;
> + if (putenv_result == 0)
> + for (ep = environ; *ep; ep++)
> + if (*ep == name_x)
> + {
> + *ep = string;
> + break;
> + }
> + free (name_x);
> + __set_errno (putenv_errno);
> + return putenv_result;
> + }
> +#else
> static char **last_environ = NULL;
> char **new_environ = (char **) malloc ((size + 2) * sizeof (char
> *));
> if (new_environ == NULL)
> @@ -126,6 +158,7 @@ putenv (char *string)
> free (last_environ);
> last_environ = new_environ;
> environ = new_environ;
> +#endif
> }
> else
> *ep = string;
> diff --git a/m4/putenv.m4 b/m4/putenv.m4
> index 9de5352..03ed4f9 100644
> --- a/m4/putenv.m4
> +++ b/m4/putenv.m4
> @@ -48,3 +48,9 @@ AC_DEFUN([gl_FUNC_PUTENV],
> ;;
> esac
> ])
> +
> +# Prerequisites of lib/putenv.c.
> +AC_DEFUN([gl_PREREQ_PUTENV],
> +[
> + AC_CHECK_FUNCS([_putenv])
> +])
> diff --git a/modules/putenv b/modules/putenv
> index 3321a5e..e39f145 100644
> --- a/modules/putenv
> +++ b/modules/putenv
> @@ -14,6 +14,7 @@ configure.ac:
> gl_FUNC_PUTENV
> if test $REPLACE_PUTENV = 1; then
> AC_LIBOBJ([putenv])
> + gl_PREREQ_PUTENV
> fi
> gl_STDLIB_MODULE_INDICATOR([putenv])
>
> @@ -27,4 +28,3 @@ LGPL
>
> Maintainer:
> Jim Meyering, glibc
> -
>
>
Yes, it fixes the problem. No heap corruption reported anymore. Thanks.
Michael.