# HG changeset patch # User Stu Tomlinson # Date 1195749938 0 # Node ID 31101e7d275f301c62bb43cc3c17f6ff465c3087 # Parent 18fb032a602ab53eedc55cc1a979bf7514c69e08 'man 3 ctime' says of localtime() (and friends): "The return value points to a statically allocated struct which might be overwritten by subsequent calls to any of the date and time functions. The localtime_r() function does the same, but stores the data in a user-supplied struct." purple_str_to_time() had multiple calls to date and time functions, although I didn't experience any problems in my testing I figured it would be better to use localtime_r() and provide our own struct. I hope I got this right. At least 'make check' still works :) diff -r 18fb032a602a -r 31101e7d275f libpurple/util.c --- a/libpurple/util.c Thu Nov 22 16:37:08 2007 +0000 +++ b/libpurple/util.c Thu Nov 22 16:45:38 2007 +0000 @@ -753,13 +753,13 @@ struct tm *tm, long *tz_off, const char **rest) { time_t retval = 0; - struct tm *t; + static struct tm t; const char *c = timestamp; int year = 0; long tzoff = PURPLE_NO_TZ_OFF; time(&retval); - t = localtime(&retval); + localtime_r(&retval, &t); /* 4 digit year */ if (sscanf(c, "%04d", &year) && year > 1900) @@ -767,11 +767,11 @@ c += 4; if (*c == '-') c++; - t->tm_year = year - 1900; + t.tm_year = year - 1900; } /* 2 digit month */ - if (!sscanf(c, "%02d", &t->tm_mon)) + if (!sscanf(c, "%02d", &t.tm_mon)) { if (rest != NULL && *c != '\0') *rest = c; @@ -780,10 +780,10 @@ c += 2; if (*c == '-' || *c == '/') c++; - t->tm_mon -= 1; + t.tm_mon -= 1; /* 2 digit day */ - if (!sscanf(c, "%02d", &t->tm_mday)) + if (!sscanf(c, "%02d", &t.tm_mday)) { if (rest != NULL && *c != '\0') *rest = c; @@ -794,13 +794,13 @@ { c++; - if (!sscanf(c, "%04d", &t->tm_year)) + if (!sscanf(c, "%04d", &t.tm_year)) { if (rest != NULL && *c != '\0') *rest = c; return 0; } - t->tm_year -= 1900; + t.tm_year -= 1900; } else if (*c == 'T' || *c == '.') { @@ -808,14 +808,14 @@ /* we have more than a date, keep going */ /* 2 digit hour */ - if ((sscanf(c, "%02d:%02d:%02d", &t->tm_hour, &t->tm_min, &t->tm_sec) == 3 && (c = c + 8)) || - (sscanf(c, "%02d%02d%02d", &t->tm_hour, &t->tm_min, &t->tm_sec) == 3 && (c = c + 6))) + if ((sscanf(c, "%02d:%02d:%02d", &t.tm_hour, &t.tm_min, &t.tm_sec) == 3 && (c = c + 8)) || + (sscanf(c, "%02d%02d%02d", &t.tm_hour, &t.tm_min, &t.tm_sec) == 3 && (c = c + 6))) { gboolean offset_positive = FALSE; int tzhrs; int tzmins; - t->tm_isdst = -1; + t.tm_isdst = -1; if (*c == '.') { do { @@ -833,22 +833,22 @@ tzoff *= -1; /* We don't want the C library doing DST calculations * if we know the UTC offset already. */ - t->tm_isdst = 0; + t.tm_isdst = 0; } else if (utc) { - struct tm *tmptm; + static struct tm tmptm; time_t tmp; - tmp = mktime(t); + tmp = mktime(&t); /* we care about whether it *was* dst, and the offset, here on this * date, not whether we are currently observing dst locally *now*. * This isn't perfect, because we would need to know in advance the * offset we are trying to work out in advance to be sure this * works for times around dst transitions but it'll have to do. */ - tmptm = localtime(&tmp); - t->tm_isdst = tmptm->tm_isdst; + localtime_r(&tmp, &tmptm); + t.tm_isdst = tmptm.tm_isdst; #ifdef HAVE_TM_GMTOFF - t->tm_gmtoff = tmptm->tm_gmtoff; + t.tm_gmtoff = tmptm.tm_gmtoff; #endif } @@ -878,7 +878,7 @@ tzoff += sys_tzoff; #else #ifdef HAVE_TM_GMTOFF - tzoff += t->tm_gmtoff; + tzoff += t.tm_gmtoff; #else # ifdef HAVE_TIMEZONE tzset(); /* making sure */ @@ -897,12 +897,12 @@ if (tm != NULL) { - *tm = *t; + memcpy(tm, &t, sizeof(struct tm)); tm->tm_isdst = -1; mktime(tm); } - retval = mktime(t); + retval = mktime(&t); if (tzoff != PURPLE_NO_TZ_OFF) retval += tzoff;