time zone problems with util/timegm.c on mingw32

David Shaw dshaw at jabberwocky.com
Mon Jun 11 01:42:38 CEST 2007


On Sun, Jun 10, 2007 at 07:00:22PM +0200, Fabian Keil wrote:
> A while ago I needed a fallback timegm() version
> for Privoxy and chose the one from gnupg 1.x's
> util/timegm.c because it appeared to be working
> on mingw32 and the license was compatible.
> 
> Apparently I didn't test it properly, because I
> just noticed that it causes time zone problems
> if getenv("TZ") is NULL. On my Windows test system
> this (now) seems to be the case.
> 
> As a result the first timegm() call changes the time
> zone settings (for me it causes a 2h offset for
> localtime() called later on) while the next timegm()
> call fixes the problem again. The timegm() call after
> that restarts the cycle ...
> 
> This, and a minor memory leak, can be fixed
> (on my mingw32 test system) with:
> 
> --- util/timegm.c       Wed Jul 27 19:02:56 2005
> +++ util/timegm.c.patched       Sun Jun 10 18:52:30 2007
> @@ -54,13 +54,14 @@
>           strcpy(old_zone,"TZ=");
>           strcat(old_zone,zone);
>           putenv(old_zone);     
> +         free(old_zone);

That's intentional, and not a leak.  putenv() is supposed to insert
its argument directly into the environment.  If you free that
argument, you corrupt the environment when (eventually) something else
uses that memory.  There are some nonstandard putenv()s that make a
copy like setenv() does, but the trick is knowing which you have - it
is safest to assume that your putenv() follows the standard.

>  #ifdef HAVE_UNSETENV
>      unsetenv("TZ");
>  #else
> -    putenv("TZ");
> +    putenv("TZ=");
>  #endif

This is mingw-specific (and wrong, as "TZ=" should insert an empty
string, and not remove TZ from the environment).  Most platforms use
"TZ" (without the = sign) to remove something from the environment.
Even that, however, is non-standard behavior, which is why we try to
use unsetenv() when possible.  Arguably for the most standards-based
code in GnuPG (though probably not your usage), if unsetenv isn't
available, we should just give up and leak the memory.

Doing environment work without leaking memory is difficult on some
platforms.  Doing it portably across many platforms is nearly
impossible.

David



More information about the Gnupg-devel mailing list