Merge remote-tracking branch 'origin/maint-0.2.2'

This commit is contained in:
Nick Mathewson 2011-04-28 17:15:31 -04:00
commit 8b33928676
3 changed files with 103 additions and 24 deletions

6
changes/gmtime_null Normal file
View File

@ -0,0 +1,6 @@
o Minor bugfixes
- On some platforms, gmtime and localtime can return NULL under
certain circumstances even for well-defined values of time_t.
Try to detect and make up for this deficiency. Possible fix for
bug 2077. Bugfix on all versions of Tor. Found by boboper.

View File

@ -2097,14 +2097,88 @@ tor_gettimeofday(struct timeval *timeval)
#define TIME_FNS_NEED_LOCKS
#endif
static struct tm *
correct_tm(int islocal, const time_t *timep, struct tm *resultbuf,
struct tm *r)
{
const char *outcome;
if (PREDICT_LIKELY(r)) {
if (r->tm_year > 8099) { /* We can't strftime dates after 9999 CE. */
r->tm_year = 8099;
r->tm_mon = 11;
r->tm_mday = 31;
r->tm_yday = 365;
r->tm_hour = 23;
r->tm_min = 59;
r->tm_sec = 59;
}
return r;
}
/* If we get here, gmtime or localtime returned NULL. It might have done
* this because of overrun or underrun, or it might have done it because of
* some other weird issue. */
if (timep) {
if (*timep < 0) {
r = resultbuf;
r->tm_year = 70; /* 1970 CE */
r->tm_mon = 0;
r->tm_mday = 1;
r->tm_yday = 1;
r->tm_hour = 0;
r->tm_min = 0 ;
r->tm_sec = 0;
outcome = "Rounding up to 1970";
goto done;
} else if (*timep >= INT32_MAX) {
/* Rounding down to INT32_MAX isn't so great, but keep in mind that we
* only do it if gmtime/localtime tells us NULL. */
r = resultbuf;
r->tm_year = 137; /* 2037 CE */
r->tm_mon = 11;
r->tm_mday = 31;
r->tm_yday = 365;
r->tm_hour = 23;
r->tm_min = 59;
r->tm_sec = 59;
outcome = "Rounding down to 2037";
goto done;
}
}
/* If we get here, then gmtime/localtime failed without getting an extreme
* value for *timep */
tor_fragile_assert();
r = resultbuf;
memset(resultbuf, 0, sizeof(struct tm));
outcome="can't recover";
done:
log_warn(LD_BUG, "%s("I64_FORMAT") failed with error %s: %s",
islocal?"localtime":"gmtime",
timep?I64_PRINTF_ARG(*timep):0,
strerror(errno),
outcome);
return r;
}
/** @{ */
/** As localtime_r, but defined for platforms that don't have it:
*
* Convert *<b>timep</b> to a struct tm in local time, and store the value in
* *<b>result</b>. Return the result on success, or NULL on failure.
*/
#ifndef HAVE_LOCALTIME_R
#ifdef TIME_FNS_NEED_LOCKS
#ifdef HAVE_LOCALTIME_R
struct tm *
tor_localtime_r(const time_t *timep, struct tm *result)
{
struct tm *r;
r = localtime_r(timep, result);
return correct_tm(1, timep, result, r);
}
#elif defined(TIME_FNS_NEED_LOCKS)
struct tm *
tor_localtime_r(const time_t *timep, struct tm *result)
{
@ -2114,9 +2188,10 @@ tor_localtime_r(const time_t *timep, struct tm *result)
tor_assert(result);
tor_mutex_acquire(m);
r = localtime(timep);
memcpy(result, r, sizeof(struct tm));
if (r)
memcpy(result, r, sizeof(struct tm));
tor_mutex_release(m);
return result;
return correct_tm(1, timep, result, r);
}
#else
struct tm *
@ -2125,11 +2200,11 @@ tor_localtime_r(const time_t *timep, struct tm *result)
struct tm *r;
tor_assert(result);
r = localtime(timep);
memcpy(result, r, sizeof(struct tm));
return result;
if (r)
memcpy(result, r, sizeof(struct tm));
return correct_tm(1, timep, result, r);
}
#endif
#endif
/** @} */
/** @{ */
@ -2138,8 +2213,15 @@ tor_localtime_r(const time_t *timep, struct tm *result)
* Convert *<b>timep</b> to a struct tm in UTC, and store the value in
* *<b>result</b>. Return the result on success, or NULL on failure.
*/
#ifndef HAVE_GMTIME_R
#ifdef TIME_FNS_NEED_LOCKS
#ifdef HAVE_GMTIME_R
struct tm *
tor_gmtime_r(const time_t *timep, struct tm *result)
{
struct tm *r;
r = gmtime_r(timep, result);
return correct_tm(0, timep, result, r);
}
#elif defined(TIME_FNS_NEED_LOCKS)
struct tm *
tor_gmtime_r(const time_t *timep, struct tm *result)
{
@ -2149,9 +2231,10 @@ tor_gmtime_r(const time_t *timep, struct tm *result)
tor_assert(result);
tor_mutex_acquire(m);
r = gmtime(timep);
memcpy(result, r, sizeof(struct tm));
if (r)
memcpy(result, r, sizeof(struct tm));
tor_mutex_release(m);
return result;
return correct_tm(0, timep, result, r);
}
#else
struct tm *
@ -2160,12 +2243,11 @@ tor_gmtime_r(const time_t *timep, struct tm *result)
struct tm *r;
tor_assert(result);
r = gmtime(timep);
memcpy(result, r, sizeof(struct tm));
return result;
if (r)
memcpy(result, r, sizeof(struct tm));
return correct_tm(0, timep, result, r);
}
#endif
#endif
/** @} */
#if defined(USE_WIN32_THREADS)
void

View File

@ -323,17 +323,8 @@ struct timeval {
void tor_gettimeofday(struct timeval *timeval);
#ifdef HAVE_LOCALTIME_R
#define tor_localtime_r localtime_r
#else
struct tm *tor_localtime_r(const time_t *timep, struct tm *result);
#endif
#ifdef HAVE_GMTIME_R
#define tor_gmtime_r gmtime_r
#else
struct tm *tor_gmtime_r(const time_t *timep, struct tm *result);
#endif
#ifndef timeradd
/** Replacement for timeradd on platforms that do not have it: sets tvout to