From b6ebdef7efaa124206352ffffa4cb54c00236c0e Mon Sep 17 00:00:00 2001 From: nirenjan Date: Thu, 4 Jun 2020 15:28:39 -0700 Subject: [PATCH] Handle time out of range in libx52_set_clock Prior to this change, the assumption was that localtime/gmtime would never fail, regardless of the time value provided to it. However, testing on an Ubuntu 20.04 machine revealed that the representable range of time_t was about 56 bits, values that exceed a 56 bit representation would cause localtime/gmtime to return a NULL pointer. This change replaces the use of localtime/gmtime with their corresponding thread-safe variants, and checks the return value against NULL. If it matches a NULL value, then it will return an error and not update the clocks. --- ChangeLog.md | 1 + lib/libx52/libx52.h | 4 ++-- lib/libx52/x52_date_time.c | 12 ++++++++++-- 3 files changed, 13 insertions(+), 4 deletions(-) diff --git a/ChangeLog.md b/ChangeLog.md index ae94d8f..aab9c8f 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -21,6 +21,7 @@ The format is based upon [Keep a Changelog]. ### Fixed - Error reporting in x52cli and x52test commands. +- Handling of very large time_t values in `libx52_set_clock` ## [0.2.0] - 2020-04-14 ### Changed diff --git a/lib/libx52/libx52.h b/lib/libx52/libx52.h index dc45465..70a66a9 100644 --- a/lib/libx52/libx52.h +++ b/lib/libx52/libx52.h @@ -178,7 +178,7 @@ typedef enum { /** No change necessary, try again */ LIBX52_ERROR_TRY_AGAIN, - /** Clock timezone out of range */ + /** Clock time value or timezone out of range */ LIBX52_ERROR_OUT_OF_RANGE, /** Error encountered during USB interaction */ @@ -454,7 +454,7 @@ int libx52_set_clock(libx52_device *x52, time_t time, int local); * @param[in] offset Offset in minutes from GMT (east is positive, west * is negative) * - * @returns + * @returns * - 0 on success * - \ref LIBX52_ERROR_INVALID_PARAM if \p x52 is invalid * - \ref LIBX52_ERROR_NOT_SUPPORTED if \p clock is \ref LIBX52_CLOCK_1 diff --git a/lib/libx52/x52_date_time.c b/lib/libx52/x52_date_time.c index 1dafd19..fdce05a 100644 --- a/lib/libx52/x52_date_time.c +++ b/lib/libx52/x52_date_time.c @@ -19,6 +19,7 @@ int libx52_set_clock(libx52_device *x52, time_t time, int local) { struct tm timeval; + struct tm *ptr; int local_tz; int local_date_day; int local_date_month; @@ -32,17 +33,24 @@ int libx52_set_clock(libx52_device *x52, time_t time, int local) } if (local) { - timeval = *localtime(&time); + ptr = localtime_r(&time, &timeval); /* timezone from time.h presents the offset in seconds west of GMT. * Negate and divide by 60 to get the offset in minutes east of GMT. */ local_tz = (int)(-timezone / 60); } else { - timeval = *gmtime(&time); + ptr = gmtime_r(&time, &timeval); /* No offset from GMT */ local_tz = 0; } + if (ptr == NULL) { + /* Time conversion failed. This happens if the time value exceeds the + * range which can be represented. + */ + return LIBX52_ERROR_OUT_OF_RANGE; + } + local_date_day = timeval.tm_mday; local_date_month = timeval.tm_mon + 1; local_date_year = timeval.tm_year % 100;