mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-13 06:33:44 +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
|
#define TIME_FNS_NEED_LOCKS
|
||||||
#endif
|
#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:
|
/** 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
|
* 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.
|
* *<b>result</b>. Return the result on success, or NULL on failure.
|
||||||
*/
|
*/
|
||||||
#ifndef HAVE_LOCALTIME_R
|
#ifdef HAVE_LOCALTIME_R
|
||||||
#ifdef TIME_FNS_NEED_LOCKS
|
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 *
|
struct tm *
|
||||||
tor_localtime_r(const time_t *timep, struct tm *result)
|
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_assert(result);
|
||||||
tor_mutex_acquire(m);
|
tor_mutex_acquire(m);
|
||||||
r = localtime(timep);
|
r = localtime(timep);
|
||||||
memcpy(result, r, sizeof(struct tm));
|
if (r)
|
||||||
|
memcpy(result, r, sizeof(struct tm));
|
||||||
tor_mutex_release(m);
|
tor_mutex_release(m);
|
||||||
return result;
|
return correct_tm(1, timep, result, r);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
struct tm *
|
struct tm *
|
||||||
@ -2125,11 +2200,11 @@ tor_localtime_r(const time_t *timep, struct tm *result)
|
|||||||
struct tm *r;
|
struct tm *r;
|
||||||
tor_assert(result);
|
tor_assert(result);
|
||||||
r = localtime(timep);
|
r = localtime(timep);
|
||||||
memcpy(result, r, sizeof(struct tm));
|
if (r)
|
||||||
return result;
|
memcpy(result, r, sizeof(struct tm));
|
||||||
|
return correct_tm(1, timep, result, r);
|
||||||
}
|
}
|
||||||
#endif
|
#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
|
* 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.
|
* *<b>result</b>. Return the result on success, or NULL on failure.
|
||||||
*/
|
*/
|
||||||
#ifndef HAVE_GMTIME_R
|
#ifdef HAVE_GMTIME_R
|
||||||
#ifdef TIME_FNS_NEED_LOCKS
|
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 *
|
struct tm *
|
||||||
tor_gmtime_r(const time_t *timep, struct tm *result)
|
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_assert(result);
|
||||||
tor_mutex_acquire(m);
|
tor_mutex_acquire(m);
|
||||||
r = gmtime(timep);
|
r = gmtime(timep);
|
||||||
memcpy(result, r, sizeof(struct tm));
|
if (r)
|
||||||
|
memcpy(result, r, sizeof(struct tm));
|
||||||
tor_mutex_release(m);
|
tor_mutex_release(m);
|
||||||
return result;
|
return correct_tm(0, timep, result, r);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
struct tm *
|
struct tm *
|
||||||
@ -2160,12 +2243,11 @@ tor_gmtime_r(const time_t *timep, struct tm *result)
|
|||||||
struct tm *r;
|
struct tm *r;
|
||||||
tor_assert(result);
|
tor_assert(result);
|
||||||
r = gmtime(timep);
|
r = gmtime(timep);
|
||||||
memcpy(result, r, sizeof(struct tm));
|
if (r)
|
||||||
return result;
|
memcpy(result, r, sizeof(struct tm));
|
||||||
|
return correct_tm(0, timep, result, r);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#endif
|
|
||||||
/** @} */
|
|
||||||
|
|
||||||
#if defined(USE_WIN32_THREADS)
|
#if defined(USE_WIN32_THREADS)
|
||||||
void
|
void
|
||||||
|
@ -323,17 +323,8 @@ struct timeval {
|
|||||||
|
|
||||||
void tor_gettimeofday(struct timeval *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);
|
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);
|
struct tm *tor_gmtime_r(const time_t *timep, struct tm *result);
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef timeradd
|
#ifndef timeradd
|
||||||
/** Replacement for timeradd on platforms that do not have it: sets tvout to
|
/** Replacement for timeradd on platforms that do not have it: sets tvout to
|
||||||
|
Loading…
Reference in New Issue
Block a user