mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-11 05:33:47 +01:00
Merge remote-tracking branch 'origin/maint-0.2.2'
This commit is contained in:
commit
8b33928676
6
changes/gmtime_null
Normal file
6
changes/gmtime_null
Normal 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.
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user