diff options
author | Lukas Fleischer <calcurse@cryptocrack.de> | 2012-11-22 22:23:58 +0100 |
---|---|---|
committer | Lukas Fleischer <calcurse@cryptocrack.de> | 2012-11-22 22:58:04 +0100 |
commit | e269f09438ad1bfaef044c5781615cba45ab7690 (patch) | |
tree | c68bd062390f59525ae5cf061c131f52a513d1b7 /src/utils.c | |
parent | 6b6067a53bd6e78215f4c39cc0d9fa2258b6e095 (diff) | |
download | calcurse-e269f09438ad1bfaef044c5781615cba45ab7690.zip |
Replace localtime() with localtime_r()
Since the result of localtime() is stored in a statically allocated
structure, data was overwritten when a context switch occurred during
(or shortly after) the execution of localtime(), potentially resulting
in critical data corruption. BUG#7 and BUG#8 are likely related.
This patch converts all usages of localtime() with localtime_r(), which
is thread-safe.
Reported-by: Baptiste Jonglez <baptiste@jonglez.org>
Reported-by: Erik Saule <esaule@bmi.osu.edu>
Signed-off-by: Lukas Fleischer <calcurse@cryptocrack.de>
Diffstat (limited to 'src/utils.c')
-rw-r--r-- | src/utils.c | 81 |
1 files changed, 47 insertions, 34 deletions
diff --git a/src/utils.c b/src/utils.c index 14de867..da8eade 100644 --- a/src/utils.c +++ b/src/utils.c @@ -337,18 +337,26 @@ long get_item_time(long date) int get_item_hour(long date) { - return (localtime((time_t *) & date))->tm_hour; + struct tm lt; + + localtime_r((time_t *)&date, <); + return lt.tm_hour; } int get_item_min(long date) { - return (localtime((time_t *) & date))->tm_min; + struct tm lt; + + localtime_r((time_t *)&date, <); + return lt.tm_min; } long date2sec(struct date day, unsigned hour, unsigned min) { time_t t = now(); - struct tm start = *(localtime(&t)); + struct tm start; + + localtime_r(&t, &start); start.tm_mon = day.mm - 1; start.tm_mday = day.dd; @@ -367,14 +375,14 @@ long date2sec(struct date day, unsigned hour, unsigned min) /* Return a string containing the date, given a date in seconds. */ char *date_sec2date_str(long sec, const char *datefmt) { - struct tm *lt; + struct tm lt; char *datestr = (char *)mem_calloc(BUFSIZ, sizeof(char)); if (sec == 0) strncpy(datestr, "0", BUFSIZ); else { - lt = localtime((time_t *) & sec); - strftime(datestr, BUFSIZ, datefmt, lt); + localtime_r((time_t *)&sec, <); + strftime(datestr, BUFSIZ, datefmt, <); } return datestr; @@ -389,8 +397,9 @@ void date_sec2date_fmt(long sec, const char *fmt, char *datef) setlocale (LC_ALL, "C"); #endif - struct tm *lt = localtime((time_t *)&sec); - strftime(datef, BUFSIZ, fmt, lt); + struct tm lt; + localtime_r((time_t *)&sec, <); + strftime(datef, BUFSIZ, fmt, <); #if ENABLE_NLS setlocale (LC_ALL, locale_old); @@ -403,15 +412,15 @@ void date_sec2date_fmt(long sec, const char *fmt, char *datef) */ long date_sec_change(long date, int delta_month, int delta_day) { - struct tm *lt; + struct tm lt; time_t t; t = date; - lt = localtime(&t); - lt->tm_mon += delta_month; - lt->tm_mday += delta_day; - lt->tm_isdst = -1; - t = mktime(lt); + localtime_r(&t, <); + lt.tm_mon += delta_month; + lt.tm_mday += delta_day; + lt.tm_isdst = -1; + t = mktime(<); EXIT_IF(t == -1, _("failure in mktime")); return t; @@ -423,14 +432,14 @@ long date_sec_change(long date, int delta_month, int delta_day) */ long update_time_in_date(long date, unsigned hr, unsigned mn) { - struct tm *lt; + struct tm lt; time_t t, new_date; t = date; - lt = localtime(&t); - lt->tm_hour = hr; - lt->tm_min = mn; - new_date = mktime(lt); + localtime_r(&t, <); + lt.tm_hour = hr; + lt.tm_min = mn; + new_date = mktime(<); EXIT_IF(new_date == -1, _("error in mktime")); return new_date; @@ -442,7 +451,7 @@ long update_time_in_date(long date, unsigned hr, unsigned mn) */ long get_sec_date(struct date date) { - struct tm *ptrtime; + struct tm ptrtime; time_t timer; long long_date; char current_day[] = "dd "; @@ -451,10 +460,10 @@ long get_sec_date(struct date date) if (date.yyyy == 0 && date.mm == 0 && date.dd == 0) { timer = time(NULL); - ptrtime = localtime(&timer); - strftime(current_day, strlen(current_day), "%d", ptrtime); - strftime(current_month, strlen(current_month), "%m", ptrtime); - strftime(current_year, strlen(current_year), "%Y", ptrtime); + localtime_r(&timer, &ptrtime); + strftime(current_day, strlen(current_day), "%d", &ptrtime); + strftime(current_month, strlen(current_month), "%m", &ptrtime); + strftime(current_year, strlen(current_year), "%Y", &ptrtime); date.mm = atoi(current_month); date.dd = atoi(current_day); date.yyyy = atoi(current_year); @@ -518,16 +527,16 @@ item_in_popup(const char *saved_a_start, const char *saved_a_end, /* Returns the beginning of current day in seconds from 1900. */ long get_today(void) { - struct tm *lt; + struct tm lt; time_t current_time; long current_day; struct date day; current_time = time(NULL); - lt = localtime(¤t_time); - day.mm = lt->tm_mon + 1; - day.dd = lt->tm_mday; - day.yyyy = lt->tm_year + 1900; + localtime_r(¤t_time, <); + day.mm = lt.tm_mon + 1; + day.dd = lt.tm_mday; + day.yyyy = lt.tm_year + 1900; current_day = date2sec(day, 0, 0); return current_day; @@ -541,10 +550,12 @@ long now(void) char *nowstr(void) { + struct tm lt; static char buf[BUFSIZ]; time_t t = now(); - strftime(buf, sizeof buf, "%a %b %d %T %Y", localtime(&t)); + localtime_r(&t, <); + strftime(buf, sizeof buf, "%a %b %d %T %Y", <); return buf; } @@ -1183,15 +1194,17 @@ static void print_date(long date, long day, const char *extformat) printf("%ld", date); else { time_t t = date; - struct tm *lt = localtime((time_t *) & t); + struct tm lt; + + localtime_r((time_t *)&t, <); if (extformat[0] == '\0' || !strcmp(extformat, "default")) { if (date >= day && date <= day + DAYINSEC) - strftime(buf, BUFSIZ, "%H:%M", lt); + strftime(buf, BUFSIZ, "%H:%M", <); else - strftime(buf, BUFSIZ, "..:..", lt); + strftime(buf, BUFSIZ, "..:..", <); } else { - strftime(buf, BUFSIZ, extformat, lt); + strftime(buf, BUFSIZ, extformat, <); } printf("%s", buf); |