Skip to content

Commit

Permalink
timespec: define TLOG_TIME_T_MIN, TLOG_TIME_T_MAX
Browse files Browse the repository at this point in the history
The library makes the false assumption that time_t is equivalent to long.
To avoid the year 2038 problem Linux distributions have moved to using
64-bit time_t on 32-bit architectures.

Replace the LONG_MIN and LONG_MAX by new symbols TLOG_TIME_T_MIN,
TLOG_TIME_T_MAX.

Closes: Scribery#369

Signed-off-by: Heinrich Schuchardt <[email protected]>
  • Loading branch information
xypron committed May 15, 2024
1 parent 661833d commit c62a4af
Show file tree
Hide file tree
Showing 5 changed files with 46 additions and 41 deletions.
9 changes: 7 additions & 2 deletions include/tlog/timespec.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,11 @@
#include <stdbool.h>
#include <assert.h>

#define TLOG_TIME_T_MIN \
(sizeof(time_t) == sizeof(long) ? LONG_MIN : LLONG_MIN)
#define TLOG_TIME_T_MAX \
(sizeof(time_t) == sizeof(long) ? LONG_MAX : LLONG_MAX)

/** Zero timespec initializer */
#define TLOG_TIMESPEC_ZERO ((struct timespec){0, 0})

Expand All @@ -46,11 +51,11 @@ extern const struct timespec tlog_timespec_max;

/** Maximum value a double-precision floating point timespec can be */
#define TLOG_TIMESPEC_FP_MAX \
nextafter((double)LONG_MAX + (double)0.999999999, 0)
nextafter((double)TLOG_TIME_T_MAX + (double)0.999999999, 0)

/** Minimum value a double-precision floating point timespec can be */
#define TLOG_TIMESPEC_FP_MIN \
nextafter((double)LONG_MIN - (double)0.999999999, 0)
nextafter((double)TLOG_TIME_T_MIN - (double)0.999999999, 0)

/** Nanoseconds per second */
#define TLOG_TIMESPEC_NSEC_PER_SEC 1000000000
Expand Down
12 changes: 6 additions & 6 deletions lib/tlog/timespec.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,9 @@
/* NOTE: Not using the macro from the header to workaround a gcc 4.8 bug */
const struct timespec tlog_timespec_zero = {0, 0};

const struct timespec tlog_timespec_min = {LONG_MIN, -TLOG_TIMESPEC_NSEC_PER_SEC + 1};
const struct timespec tlog_timespec_min = {TLOG_TIME_T_MIN, -TLOG_TIMESPEC_NSEC_PER_SEC + 1};

const struct timespec tlog_timespec_max = {LONG_MAX, TLOG_TIMESPEC_NSEC_PER_SEC - 1};
const struct timespec tlog_timespec_max = {TLOG_TIME_T_MAX, TLOG_TIMESPEC_NSEC_PER_SEC - 1};

#define TLOG_TIMESPEC_FP_OP_ADD +
#define TLOG_TIMESPEC_FP_OP_SUB -
Expand Down Expand Up @@ -156,7 +156,7 @@ tlog_timespec_cap_add(const struct timespec *a,
if (tmp.tv_sec >= 0 ? tmp.tv_nsec >= TLOG_TIMESPEC_NSEC_PER_SEC
: tmp.tv_nsec > 0) {
/* If overflow */
if (tmp.tv_sec == LONG_MAX) {
if (tmp.tv_sec == TLOG_TIME_T_MAX) {
*res = tlog_timespec_max;
goto exit;
}
Expand All @@ -167,7 +167,7 @@ tlog_timespec_cap_add(const struct timespec *a,
if (tmp.tv_sec > 0 ? tmp.tv_nsec < 0
: tmp.tv_nsec <= -TLOG_TIMESPEC_NSEC_PER_SEC) {
/* If overflow */
if (tmp.tv_sec == LONG_MIN) {
if (tmp.tv_sec == TLOG_TIME_T_MIN) {
*res = tlog_timespec_min;
goto exit;
}
Expand Down Expand Up @@ -217,7 +217,7 @@ tlog_timespec_cap_sub(const struct timespec *a,
if (tmp.tv_sec >= 0 ? tmp.tv_nsec >= TLOG_TIMESPEC_NSEC_PER_SEC
: tmp.tv_nsec > 0) {
/* If overflow */
if (tmp.tv_sec == LONG_MAX) {
if (tmp.tv_sec == TLOG_TIME_T_MAX) {
*res = tlog_timespec_max;
goto exit;
}
Expand All @@ -228,7 +228,7 @@ tlog_timespec_cap_sub(const struct timespec *a,
if (tmp.tv_sec > 0 ? tmp.tv_nsec < 0
: tmp.tv_nsec <= -TLOG_TIMESPEC_NSEC_PER_SEC) {
/* If overflow */
if (tmp.tv_sec == LONG_MIN) {
if (tmp.tv_sec == TLOG_TIME_T_MIN) {
*res = tlog_timespec_min;
goto exit;
}
Expand Down
6 changes: 3 additions & 3 deletions lib/tlog/timestr.c
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ tlog_timestr_parser_feed(struct tlog_timestr_parser *parser, char c)
comp = 0;
} else {
comp = parser->comp_list[parser->comp_num - 1];
if (comp > (LONG_MAX - digit) / 10) {
if (comp > (TLOG_TIME_T_MAX - digit) / 10) {
return false;
}
}
Expand Down Expand Up @@ -112,11 +112,11 @@ tlog_timestr_parser_yield(const struct tlog_timestr_parser *parser,
for (i = 0; i < parser->comp_num; i++) {
mul = mul_list[parser->comp_num - 1 - i];
comp = parser->comp_list[i];
if (comp > LONG_MAX / mul) {
if (comp > TLOG_TIME_T_MAX / mul) {
return false;
}
comp *= mul;
if (comp > LONG_MAX - ts.tv_sec) {
if (comp > TLOG_TIME_T_MAX - ts.tv_sec) {
return false;
}
ts.tv_sec += comp;
Expand Down
42 changes: 21 additions & 21 deletions src/tltest/tltest-timespec.c
Original file line number Diff line number Diff line change
Expand Up @@ -149,21 +149,21 @@ main(void)
TEST(all_sub, TS(0, TLOG_TIMESPEC_NSEC_PER_SEC - 1), TS(0, -2), TS(1, 1));
TEST(all_sub, TS(1, 500000000), TS(2, 0), TS(0, -500000000));
TEST(all_sub, TS(-1, -500000000), TS(-2, 0), TS(0, 500000000));
TEST(int_sub, TS(0, 0), tlog_timespec_max, TS(LONG_MIN + 1, -TLOG_TIMESPEC_NSEC_PER_SEC + 1));
TEST(int_sub, TS(0, 0), tlog_timespec_max, TS(TLOG_TIME_T_MIN + 1, -TLOG_TIMESPEC_NSEC_PER_SEC + 1));

TEST(sub, tlog_timespec_min, TS(0, 1), TS(LONG_MAX, 0));
TEST(sub, tlog_timespec_min, TS(0, 1), TS(TLOG_TIME_T_MAX, 0));
TEST(cap_sub, tlog_timespec_min, TS(0, 1), tlog_timespec_min);
TEST(fp_sub, tlog_timespec_min, TS(0, 1), min_fp);

TEST(int_sub, TS(LONG_MIN / 2, -499999999),
TS(LONG_MAX / 2 + 1, 500000000),
TEST(int_sub, TS(TLOG_TIME_T_MIN / 2, -499999999),
TS(TLOG_TIME_T_MAX / 2 + 1, 500000000),
tlog_timespec_min);
TEST(fp_sub, TS(LONG_MIN / 2, -499999999),
TS(LONG_MAX / 2 + 1, 500000000),
TEST(fp_sub, TS(TLOG_TIME_T_MIN / 2, -499999999),
TS(TLOG_TIME_T_MAX / 2 + 1, 500000000),
min_fp);
TEST(int_sub, TS(LONG_MAX / 2, 499999999), TS(LONG_MIN / 2, -500000000),
TEST(int_sub, TS(TLOG_TIME_T_MAX / 2, 499999999), TS(TLOG_TIME_T_MIN / 2, -500000000),
tlog_timespec_max);
TEST(fp_sub, TS(LONG_MAX / 2, 499999999), TS(LONG_MIN / 2, -500000000),
TEST(fp_sub, TS(TLOG_TIME_T_MAX / 2, 499999999), TS(TLOG_TIME_T_MIN / 2, -500000000),
max_fp);

TEST(cap_sub, tlog_timespec_min, tlog_timespec_max, tlog_timespec_min);
Expand All @@ -190,7 +190,7 @@ main(void)
TEST(all_add, TS(0, TLOG_TIMESPEC_NSEC_PER_SEC - 1), TS(0, 0), TS(0, TLOG_TIMESPEC_NSEC_PER_SEC - 1));
TEST(all_add, TS(0, TLOG_TIMESPEC_NSEC_PER_SEC - 1), TS(0, 1), TS(1, 0));
TEST(all_add, TS(1, TLOG_TIMESPEC_NSEC_PER_SEC - 1), TS(0, 1), TS(2, 0));
TEST(add, tlog_timespec_max, TS(0, 1), TS(LONG_MIN, 0));
TEST(add, tlog_timespec_max, TS(0, 1), TS(TLOG_TIME_T_MIN, 0));
TEST(cap_add, tlog_timespec_max, TS(0, 1), tlog_timespec_max);
TEST(fp_add, tlog_timespec_max, TS(0, 1), max_fp);
TEST(all_add, TS(0, -1), TS(0, 1), TS(0, 0));
Expand All @@ -206,24 +206,24 @@ main(void)
TEST(all_add, TS(-1, -500000000), TS(2, 0), TS(0, 500000000));
TEST(all_add, TS(1, 500000000), TS(-2, 0), TS(0, -500000000));

TEST(int_add, TS(LONG_MAX / 2, 499999999),
TS(LONG_MAX / 2 + 1, 500000000),
TEST(int_add, TS(TLOG_TIME_T_MAX / 2, 499999999),
TS(TLOG_TIME_T_MAX / 2 + 1, 500000000),
tlog_timespec_max);
TEST(fp_add, TS(LONG_MAX / 2, 499999999),
TS(LONG_MAX / 2 + 1, 500000000),
TEST(fp_add, TS(TLOG_TIME_T_MAX / 2, 499999999),
TS(TLOG_TIME_T_MAX / 2 + 1, 500000000),
max_fp);
TEST(int_add, TS(LONG_MIN / 2, -499999999),
TS(LONG_MIN / 2, -500000000),
TEST(int_add, TS(TLOG_TIME_T_MIN / 2, -499999999),
TS(TLOG_TIME_T_MIN / 2, -500000000),
tlog_timespec_min);
TEST(fp_add, TS(LONG_MIN / 2, -499999999),
TS(LONG_MIN / 2, -500000000),
TEST(fp_add, TS(TLOG_TIME_T_MIN / 2, -499999999),
TS(TLOG_TIME_T_MIN / 2, -500000000),
min_fp);

TEST(add, tlog_timespec_max, TS(0, 1), TS(LONG_MIN, 0));
TEST(add, tlog_timespec_max, TS(0, 1), TS(TLOG_TIME_T_MIN, 0));
TEST(cap_add, tlog_timespec_max, TS(0, 1), tlog_timespec_max);
TEST(fp_add, tlog_timespec_max, TS(0, 1), max_fp);

TEST(add, tlog_timespec_min, TS(0, -1), TS(LONG_MAX, 0));
TEST(add, tlog_timespec_min, TS(0, -1), TS(TLOG_TIME_T_MAX, 0));
TEST(cap_add, tlog_timespec_min, TS(0, -1), tlog_timespec_min);
TEST(fp_add, tlog_timespec_min, TS(0, -1), min_fp);

Expand Down Expand Up @@ -296,8 +296,8 @@ main(void)

TEST(fp_div, tlog_timespec_max, tlog_timespec_max, TS(1, 0));
TEST(fp_div, tlog_timespec_min, tlog_timespec_min, TS(1, 0));
TEST(fp_div, tlog_timespec_max, TS(LONG_MIN+1, -TLOG_TIMESPEC_NSEC_PER_SEC + 1), TS(-1, 0));
TEST(fp_div, TS(LONG_MIN+1, -TLOG_TIMESPEC_NSEC_PER_SEC + 1), tlog_timespec_max, TS(-1, 0));
TEST(fp_div, tlog_timespec_max, TS(TLOG_TIME_T_MIN+1, -TLOG_TIMESPEC_NSEC_PER_SEC + 1), TS(-1, 0));
TEST(fp_div, TS(TLOG_TIME_T_MIN+1, -TLOG_TIMESPEC_NSEC_PER_SEC + 1), tlog_timespec_max, TS(-1, 0));

TEST(fp_div, tlog_timespec_max, TS(1, 0), max_fp);
TEST(fp_div, tlog_timespec_min, TS(1, 0), min_fp);
Expand Down
18 changes: 9 additions & 9 deletions src/tltest/tltest-timestr.c
Original file line number Diff line number Diff line change
Expand Up @@ -119,17 +119,17 @@ main(void)
TEST("10:10:10", true, TS(60*60*10 + 60*10 + 10, 0));
TEST("10:10:10.10", true, TS(60*60*10 + 60*10 + 10, 100000000));

snprintf(buf, sizeof(buf), "%ld", LONG_MAX);
TEST(buf, true, TS(LONG_MAX, 0));
snprintf(buf, sizeof(buf), "%ld:", LONG_MAX);
snprintf(buf, sizeof(buf), "%lld", (long long)TLOG_TIME_T_MAX);
TEST(buf, true, TS(TLOG_TIME_T_MAX, 0));
snprintf(buf, sizeof(buf), "%lld:", (long long)TLOG_TIME_T_MAX);
TEST(buf, false, TS(0, 0));
snprintf(buf, sizeof(buf), "%ld:", LONG_MAX / 60);
TEST(buf, true, TS(LONG_MAX / 60 * 60, 0));
snprintf(buf, sizeof(buf), "%ld:", LONG_MAX / 60 + 1);
snprintf(buf, sizeof(buf), "%lld:", (long long)TLOG_TIME_T_MAX / 60);
TEST(buf, true, TS(TLOG_TIME_T_MAX / 60 * 60, 0));
snprintf(buf, sizeof(buf), "%lld:", (long long)TLOG_TIME_T_MAX / 60 + 1);
TEST(buf, false, TS(0, 0));
snprintf(buf, sizeof(buf), "%ld::", LONG_MAX / (60 * 60));
TEST(buf, true, TS(LONG_MAX / (60 * 60) * (60 * 60), 0));
snprintf(buf, sizeof(buf), "%ld::", LONG_MAX / (60 * 60) + 1);
snprintf(buf, sizeof(buf), "%lld::", (long long)TLOG_TIME_T_MAX / (60 * 60));
TEST(buf, true, TS(TLOG_TIME_T_MAX / (60 * 60) * (60 * 60), 0));
snprintf(buf, sizeof(buf), "%lld::", (long long)TLOG_TIME_T_MAX / (60 * 60) + 1);
TEST(buf, false, TS(0, 0));

TEST("999999999999999999999999999", false, TS(0, 0));
Expand Down

0 comments on commit c62a4af

Please sign in to comment.