mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-24 04:13:28 +01:00
Merge branch 'maint-0.4.5' into maint-0.4.6
This commit is contained in:
commit
167f3bc4ec
7
changes/bug40383
Normal file
7
changes/bug40383
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
o Minor bugfixes (timekeeping):
|
||||||
|
- Calculate the time of day correctly on systems where the time_t
|
||||||
|
type includes leap seconds. (This is not the case on most
|
||||||
|
operating systems, but on those where it occurs, our tor_timegm
|
||||||
|
function did not correctly invert the system's gmtime function,
|
||||||
|
which could result in assertion failures when calculating
|
||||||
|
voting schedules.) Fixes bug 40383; bugfix on 0.2.0.3-alpha.
|
@ -806,6 +806,7 @@ AC_CHECK_FUNCS(
|
|||||||
strtoull \
|
strtoull \
|
||||||
sysconf \
|
sysconf \
|
||||||
sysctl \
|
sysctl \
|
||||||
|
timegm \
|
||||||
truncate \
|
truncate \
|
||||||
uname \
|
uname \
|
||||||
usleep \
|
usleep \
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
* and handles a larger variety of types. It converts between different time
|
* and handles a larger variety of types. It converts between different time
|
||||||
* formats, and encodes and decodes them from strings.
|
* formats, and encodes and decodes them from strings.
|
||||||
**/
|
**/
|
||||||
|
#define TIME_FMT_PRIVATE
|
||||||
|
|
||||||
#include "lib/encoding/time_fmt.h"
|
#include "lib/encoding/time_fmt.h"
|
||||||
#include "lib/log/log.h"
|
#include "lib/log/log.h"
|
||||||
@ -25,6 +26,7 @@
|
|||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
#ifdef HAVE_SYS_TIME_H
|
#ifdef HAVE_SYS_TIME_H
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
@ -92,8 +94,8 @@ static const int days_per_month[] =
|
|||||||
/** Compute a time_t given a struct tm. The result is given in UTC, and
|
/** Compute a time_t given a struct tm. The result is given in UTC, and
|
||||||
* does not account for leap seconds. Return 0 on success, -1 on failure.
|
* does not account for leap seconds. Return 0 on success, -1 on failure.
|
||||||
*/
|
*/
|
||||||
int
|
ATTR_UNUSED STATIC int
|
||||||
tor_timegm(const struct tm *tm, time_t *time_out)
|
tor_timegm_impl(const struct tm *tm, time_t *time_out)
|
||||||
{
|
{
|
||||||
/* This is a pretty ironclad timegm implementation, snarfed from Python2.2.
|
/* This is a pretty ironclad timegm implementation, snarfed from Python2.2.
|
||||||
* It's way more brute-force than fiddling with tzset().
|
* It's way more brute-force than fiddling with tzset().
|
||||||
@ -162,6 +164,35 @@ tor_timegm(const struct tm *tm, time_t *time_out)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Compute a time_t given a struct tm. The result here should be an inverse
|
||||||
|
* of the system's gmtime() function. Return 0 on success, -1 on failure.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
tor_timegm(const struct tm *tm, time_t *time_out)
|
||||||
|
{
|
||||||
|
#ifdef HAVE_TIMEGM
|
||||||
|
/* If the system gives us a timegm(), use it: if the system's time_t
|
||||||
|
* includes leap seconds, then we can hope that its timegm() knows too.
|
||||||
|
*
|
||||||
|
* https://k5wiki.kerberos.org/wiki/Leap_second_handling says the in
|
||||||
|
* general we can rely on any system with leap seconds also having a
|
||||||
|
* timegm implementation. Let's hope it's right!
|
||||||
|
* */
|
||||||
|
time_t result = timegm((struct tm *) tm);
|
||||||
|
if (result == -1) {
|
||||||
|
log_warn(LD_BUG, "timegm() could not convert time: %s", strerror(errno));
|
||||||
|
*time_out = 0;
|
||||||
|
return -1;
|
||||||
|
} else {
|
||||||
|
*time_out = result;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
/* The system doesn't have timegm; we'll have to use our own. */
|
||||||
|
return tor_timegm_impl(tm, time_out);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
/* strftime is locale-specific, so we need to replace those parts */
|
/* strftime is locale-specific, so we need to replace those parts */
|
||||||
|
|
||||||
/** A c-locale array of 3-letter names of weekdays, starting with Sun. */
|
/** A c-locale array of 3-letter names of weekdays, starting with Sun. */
|
||||||
|
@ -18,6 +18,8 @@
|
|||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include "lib/testsupport/testsupport.h"
|
||||||
|
|
||||||
struct tm;
|
struct tm;
|
||||||
struct timeval;
|
struct timeval;
|
||||||
|
|
||||||
@ -41,4 +43,8 @@ int parse_iso_time_nospace(const char *cp, time_t *t);
|
|||||||
int parse_http_time(const char *buf, struct tm *tm);
|
int parse_http_time(const char *buf, struct tm *tm);
|
||||||
int format_time_interval(char *out, size_t out_len, long interval);
|
int format_time_interval(char *out, size_t out_len, long interval);
|
||||||
|
|
||||||
|
#ifdef TIME_FMT_PRIVATE
|
||||||
|
STATIC int tor_timegm_impl(const struct tm *tm, time_t *time_out);
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif /* !defined(TOR_TIME_FMT_H) */
|
#endif /* !defined(TOR_TIME_FMT_H) */
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
#define COMPAT_TIME_PRIVATE
|
#define COMPAT_TIME_PRIVATE
|
||||||
#define UTIL_MALLOC_PRIVATE
|
#define UTIL_MALLOC_PRIVATE
|
||||||
#define PROCESS_WIN32_PRIVATE
|
#define PROCESS_WIN32_PRIVATE
|
||||||
|
#define TIME_FMT_PRIVATE
|
||||||
#include "lib/testsupport/testsupport.h"
|
#include "lib/testsupport/testsupport.h"
|
||||||
#include "core/or/or.h"
|
#include "core/or/or.h"
|
||||||
#include "lib/buf/buffers.h"
|
#include "lib/buf/buffers.h"
|
||||||
@ -111,7 +112,7 @@ static time_t
|
|||||||
tor_timegm_wrapper(const struct tm *tm)
|
tor_timegm_wrapper(const struct tm *tm)
|
||||||
{
|
{
|
||||||
time_t t;
|
time_t t;
|
||||||
if (tor_timegm(tm, &t) < 0)
|
if (tor_timegm_impl(tm, &t) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
@ -1501,6 +1502,28 @@ test_util_parse_http_time(void *arg)
|
|||||||
teardown_capture_of_logs();
|
teardown_capture_of_logs();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_util_timegm_real(void *arg)
|
||||||
|
{
|
||||||
|
(void)arg;
|
||||||
|
/* Get the real timegm again! We're not testing our impl; we want the
|
||||||
|
* one that will actually get called. */
|
||||||
|
#undef tor_timegm
|
||||||
|
|
||||||
|
/* Now check: is timegm the real inverse of gmtime? */
|
||||||
|
time_t now = time(NULL), time2=0;
|
||||||
|
struct tm tm, *p;
|
||||||
|
p = tor_gmtime_r(&now, &tm);
|
||||||
|
tt_ptr_op(p, OP_NE, NULL);
|
||||||
|
|
||||||
|
int r = tor_timegm(&tm, &time2);
|
||||||
|
tt_int_op(r, OP_EQ, 0);
|
||||||
|
tt_i64_op((int64_t) now, OP_EQ, (int64_t) time2);
|
||||||
|
|
||||||
|
done:
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
test_util_config_line(void *arg)
|
test_util_config_line(void *arg)
|
||||||
{
|
{
|
||||||
@ -7036,6 +7059,7 @@ struct testcase_t util_tests[] = {
|
|||||||
UTIL_TEST(monotonic_time_ratchet, TT_FORK),
|
UTIL_TEST(monotonic_time_ratchet, TT_FORK),
|
||||||
UTIL_TEST(monotonic_time_zero, 0),
|
UTIL_TEST(monotonic_time_zero, 0),
|
||||||
UTIL_TEST(monotonic_time_add_msec, 0),
|
UTIL_TEST(monotonic_time_add_msec, 0),
|
||||||
|
UTIL_TEST(timegm_real, 0),
|
||||||
UTIL_TEST(htonll, 0),
|
UTIL_TEST(htonll, 0),
|
||||||
UTIL_TEST(get_unquoted_path, 0),
|
UTIL_TEST(get_unquoted_path, 0),
|
||||||
UTIL_TEST(map_anon, 0),
|
UTIL_TEST(map_anon, 0),
|
||||||
|
Loading…
Reference in New Issue
Block a user