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;