Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
George Kadianakis
Tor
Commits
167f3bc4
Commit
167f3bc4
authored
Jul 06, 2021
by
George Kadianakis
Browse files
Merge branch 'maint-0.4.5' into maint-0.4.6
parents
2758ae30
98b9df61
Changes
5
Show whitespace changes
Inline
Side-by-side
changes/bug40383
0 → 100644
View file @
167f3bc4
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.
configure.ac
View file @
167f3bc4
...
...
@@ -806,6 +806,7 @@ AC_CHECK_FUNCS(
strtoull \
sysconf \
sysctl \
timegm \
truncate \
uname \
usleep \
...
...
src/lib/encoding/time_fmt.c
View file @
167f3bc4
...
...
@@ -13,6 +13,7 @@
* and handles a larger variety of types. It converts between different time
* formats, and encodes and decodes them from strings.
**/
#define TIME_FMT_PRIVATE
#include
"lib/encoding/time_fmt.h"
#include
"lib/log/log.h"
...
...
@@ -25,6 +26,7 @@
#include
<string.h>
#include
<time.h>
#include
<errno.h>
#ifdef HAVE_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
* does not account for leap seconds. Return 0 on success, -1 on failure.
*/
int
tor_timegm
(
const
struct
tm
*
tm
,
time_t
*
time_out
)
ATTR_UNUSED
STATIC
int
tor_timegm
_impl
(
const
struct
tm
*
tm
,
time_t
*
time_out
)
{
/* This is a pretty ironclad timegm implementation, snarfed from Python2.2.
* 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
;
}
/** 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 */
/** A c-locale array of 3-letter names of weekdays, starting with Sun. */
...
...
src/lib/encoding/time_fmt.h
View file @
167f3bc4
...
...
@@ -18,6 +18,8 @@
#include
<sys/types.h>
#endif
#include
"lib/testsupport/testsupport.h"
struct
tm
;
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
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) */
src/test/test_util.c
View file @
167f3bc4
...
...
@@ -7,6 +7,7 @@
#define COMPAT_TIME_PRIVATE
#define UTIL_MALLOC_PRIVATE
#define PROCESS_WIN32_PRIVATE
#define TIME_FMT_PRIVATE
#include
"lib/testsupport/testsupport.h"
#include
"core/or/or.h"
#include
"lib/buf/buffers.h"
...
...
@@ -111,7 +112,7 @@ static time_t
tor_timegm_wrapper
(
const
struct
tm
*
tm
)
{
time_t
t
;
if
(
tor_timegm
(
tm
,
&
t
)
<
0
)
if
(
tor_timegm
_impl
(
tm
,
&
t
)
<
0
)
return
-
1
;
return
t
;
}
...
...
@@ -1501,6 +1502,28 @@ test_util_parse_http_time(void *arg)
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
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_zero
,
0
),
UTIL_TEST
(
monotonic_time_add_msec
,
0
),
UTIL_TEST
(
timegm_real
,
0
),
UTIL_TEST
(
htonll
,
0
),
UTIL_TEST
(
get_unquoted_path
,
0
),
UTIL_TEST
(
map_anon
,
0
),
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment