util: avoid undefined behavior in timestamp conversion

This commit is contained in:
Miroslav Lichvar 2017-07-24 15:42:27 +02:00
parent bd3fb49a1e
commit 0c54cf316d
2 changed files with 9 additions and 7 deletions

View file

@ -43,6 +43,10 @@ void test_unit(void) {
ntp_ts.hi = htonl(JAN_1970); ntp_ts.hi = htonl(JAN_1970);
ntp_ts.lo = 0xffffffff; ntp_ts.lo = 0xffffffff;
UTI_Ntp64ToTimespec(&ntp_ts, &ts); UTI_Ntp64ToTimespec(&ntp_ts, &ts);
TEST_CHECK(ts.tv_sec == 0);
TEST_CHECK(ts.tv_nsec == 999999999);
UTI_AddDoubleToTimespec(&ts, 1e-9, &ts);
TEST_CHECK(ts.tv_sec == 1); TEST_CHECK(ts.tv_sec == 1);
TEST_CHECK(ts.tv_nsec == 0); TEST_CHECK(ts.tv_nsec == 0);

12
util.c
View file

@ -180,7 +180,7 @@ UTI_DiffTimespecs(struct timespec *result, struct timespec *a, struct timespec *
double double
UTI_DiffTimespecsToDouble(struct timespec *a, struct timespec *b) UTI_DiffTimespecsToDouble(struct timespec *a, struct timespec *b)
{ {
return (a->tv_sec - b->tv_sec) + 1.0e-9 * (a->tv_nsec - b->tv_nsec); return ((double)a->tv_sec - (double)b->tv_sec) + 1.0e-9 * (a->tv_nsec - b->tv_nsec);
} }
/* ================================================== */ /* ================================================== */
@ -778,9 +778,7 @@ UTI_Ntp64ToTimespec(NTP_int64 *src, struct timespec *dest)
dest->tv_sec = ntp_sec - JAN_1970; dest->tv_sec = ntp_sec - JAN_1970;
#endif #endif
dest->tv_nsec = ntp_frac / NSEC_PER_NTP64 + 0.5; dest->tv_nsec = ntp_frac / NSEC_PER_NTP64;
UTI_NormaliseTimespec(dest);
} }
/* ================================================== */ /* ================================================== */
@ -840,12 +838,11 @@ UTI_Log2ToDouble(int l)
void void
UTI_TimespecNetworkToHost(Timespec *src, struct timespec *dest) UTI_TimespecNetworkToHost(Timespec *src, struct timespec *dest)
{ {
uint32_t sec_low; uint32_t sec_low, nsec;
#ifdef HAVE_LONG_TIME_T #ifdef HAVE_LONG_TIME_T
uint32_t sec_high; uint32_t sec_high;
#endif #endif
dest->tv_nsec = ntohl(src->tv_nsec);
sec_low = ntohl(src->tv_sec_low); sec_low = ntohl(src->tv_sec_low);
#ifdef HAVE_LONG_TIME_T #ifdef HAVE_LONG_TIME_T
sec_high = ntohl(src->tv_sec_high); sec_high = ntohl(src->tv_sec_high);
@ -857,7 +854,8 @@ UTI_TimespecNetworkToHost(Timespec *src, struct timespec *dest)
dest->tv_sec = sec_low; dest->tv_sec = sec_low;
#endif #endif
UTI_NormaliseTimespec(dest); nsec = ntohl(src->tv_nsec);
dest->tv_nsec = CLAMP(0U, nsec, 999999999U);
} }
/* ================================================== */ /* ================================================== */