This is the mail archive of the newlib@sourceware.org mailing list for the newlib project.
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |
Other format: | [Raw text] |
On Mar 25 18:09, Craig Howland wrote: > On 03/25/2015 05:46 PM, Yaakov Selkowitz wrote: > >* libc/time/strftime.c (strftime) <%Z>: Initialize tznam to NULL. > >Use _tzname as fallback if TM_ZONE is NULL. > >--- > >The following testcase (based on a real-world crash of WebKitGTK+ on > >my system when attempting to authorize a Google account) crashes on > >Cygwin: > > > >#include <time.h> > >#include <stdio.h> > >#include <string.h> > > > >int main (void) { > > struct tm tm = { 53, 54, 18, 23, 2, 115, 1, 81, 1, -18000, NULL }; > > char s[32]; > > /* tzset(); */ > > strftime (s, 32, "%Z", &tm); > > printf("%d: %s\n", strlen(s), s); > > return 0; > >} > > > >The crash was due to a strlen(NULL) a few lines later, which should NOT > >happen. glibc takes this a step further and calls tzset() if not yet > >called so that the returned string matches the local timezone (instead > >of "GMT", or on Cygwin, " "). The question is how to (portably) > >determine if tzset() has been called already or not (e.g. a global > >variable?). > > > > newlib/libc/time/strftime.c | 6 +++--- > > 1 file changed, 3 insertions(+), 3 deletions(-) > > > >diff --git a/newlib/libc/time/strftime.c b/newlib/libc/time/strftime.c > >index 7db3383..ee604c2 100644 > >--- a/newlib/libc/time/strftime.c > >+++ b/newlib/libc/time/strftime.c > >@@ -1311,7 +1311,7 @@ recurse: > > if (tim_p->tm_isdst >= 0) > > { > > size_t size; > >- const char *tznam; > >+ const char *tznam = NULL; > > TZ_LOCK; > > #if defined (__CYGWIN__) > >@@ -1320,9 +1320,9 @@ recurse: > > tznam = __cygwin_gettzname (tim_p); > > #elif defined (__TM_ZONE) > > tznam = tim_p->__TM_ZONE; > >-#else > >- tznam = _tzname[tim_p->tm_isdst > 0]; > > #endif > >+ if (!tznam) > >+ tznam = _tzname[tim_p->tm_isdst > 0]; > > /* Note that in case of wcsftime this loop only works for > > timezone abbreviations using the portable codeset (aka ASCII). > > This seems to be the case, but if that ever changes, this > There was a discussion under way a while ago related to tzset(), the results > of which never were implemented (mainly due to it slipping off my horizon). > See https://sourceware.org/ml/newlib/2013/msg00443.html for the final word. > In short, ctime(), localtime(), mktime(), and strftime() all should call > tzset(), while it should be removed from setenv(). Checking for having been > called already is really not needed, since the user can change the > environment at any time, so that tzset() really needs to be called every > time. > Craig I agree. I took another look into glibc's implementation of strftime and it's calling tzset whenever the 'z' or 'Z' format is used. It just keeps a marker around as an extra parameter so it never calls tzset more than once, even if the function recurses. Corinna -- Corinna Vinschen Cygwin Maintainer Red Hat
Attachment:
pgplfKrPwodjZ.pgp
Description: PGP signature
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |