mirror of https://github.com/nirenjan/libx52.git
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.pull/22/head
parent
cdc6a594e4
commit
b6ebdef7ef
|
@ -21,6 +21,7 @@ The format is based upon [Keep a Changelog].
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
- Error reporting in x52cli and x52test commands.
|
- Error reporting in x52cli and x52test commands.
|
||||||
|
- Handling of very large time_t values in `libx52_set_clock`
|
||||||
|
|
||||||
## [0.2.0] - 2020-04-14
|
## [0.2.0] - 2020-04-14
|
||||||
### Changed
|
### Changed
|
||||||
|
|
|
@ -178,7 +178,7 @@ typedef enum {
|
||||||
/** No change necessary, try again */
|
/** No change necessary, try again */
|
||||||
LIBX52_ERROR_TRY_AGAIN,
|
LIBX52_ERROR_TRY_AGAIN,
|
||||||
|
|
||||||
/** Clock timezone out of range */
|
/** Clock time value or timezone out of range */
|
||||||
LIBX52_ERROR_OUT_OF_RANGE,
|
LIBX52_ERROR_OUT_OF_RANGE,
|
||||||
|
|
||||||
/** Error encountered during USB interaction */
|
/** Error encountered during USB interaction */
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
int libx52_set_clock(libx52_device *x52, time_t time, int local)
|
int libx52_set_clock(libx52_device *x52, time_t time, int local)
|
||||||
{
|
{
|
||||||
struct tm timeval;
|
struct tm timeval;
|
||||||
|
struct tm *ptr;
|
||||||
int local_tz;
|
int local_tz;
|
||||||
int local_date_day;
|
int local_date_day;
|
||||||
int local_date_month;
|
int local_date_month;
|
||||||
|
@ -32,17 +33,24 @@ int libx52_set_clock(libx52_device *x52, time_t time, int local)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (local) {
|
if (local) {
|
||||||
timeval = *localtime(&time);
|
ptr = localtime_r(&time, &timeval);
|
||||||
/* timezone from time.h presents the offset in seconds west of GMT.
|
/* 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.
|
* Negate and divide by 60 to get the offset in minutes east of GMT.
|
||||||
*/
|
*/
|
||||||
local_tz = (int)(-timezone / 60);
|
local_tz = (int)(-timezone / 60);
|
||||||
} else {
|
} else {
|
||||||
timeval = *gmtime(&time);
|
ptr = gmtime_r(&time, &timeval);
|
||||||
/* No offset from GMT */
|
/* No offset from GMT */
|
||||||
local_tz = 0;
|
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_day = timeval.tm_mday;
|
||||||
local_date_month = timeval.tm_mon + 1;
|
local_date_month = timeval.tm_mon + 1;
|
||||||
local_date_year = timeval.tm_year % 100;
|
local_date_year = timeval.tm_year % 100;
|
||||||
|
|
Loading…
Reference in New Issue