From 9e160fac16e81c42ac368f450b9cc4df29753e00 Mon Sep 17 00:00:00 2001 From: Lukas Fleischer Date: Sun, 27 Mar 2016 12:54:10 +0200 Subject: Do not assume that days always have 86400 seconds Make that date membership is computed correctly, even if a day has less than 86400 seconds (e.g. after changing clocks). Reported-by: Hakan Jerning Signed-off-by: Lukas Fleischer --- src/apoint.c | 3 +-- src/calcurse.h | 1 + src/event.c | 2 +- src/recur.c | 4 ++-- src/utils.c | 24 ++++++++++++++++++++++++ test/Makefile.am | 2 ++ test/data/apts-regress-001 | 1 + test/regress-001.sh | 15 +++++++++++++++ 8 files changed, 47 insertions(+), 5 deletions(-) create mode 100644 test/data/apts-regress-001 create mode 100755 test/regress-001.sh diff --git a/src/apoint.c b/src/apoint.c index cb23ead..409e889 100644 --- a/src/apoint.c +++ b/src/apoint.c @@ -119,8 +119,7 @@ struct apoint *apoint_new(char *mesg, char *note, long start, long dur, unsigned apoint_inday(struct apoint *i, long *start) { - return (i->start <= *start + DAYINSEC - && i->start + i->dur > *start); + return (date_cmp_day(i->start, *start) == 0); } void apoint_sec2str(struct apoint *o, long day, char *start, char *end) diff --git a/src/calcurse.h b/src/calcurse.h index d337145..3aab885 100644 --- a/src/calcurse.h +++ b/src/calcurse.h @@ -1111,6 +1111,7 @@ int get_item_min(long); struct tm date2tm(struct date, unsigned, unsigned); time_t date2sec(struct date, unsigned, unsigned); time_t utcdate2sec(struct date, unsigned, unsigned); +int date_cmp_day(time_t, time_t); char *date_sec2date_str(long, const char *); void date_sec2date_fmt(long, const char *, char *); int date_change(struct tm *, int, int); diff --git a/src/event.c b/src/event.c index ad26f19..4f6965c 100644 --- a/src/event.c +++ b/src/event.c @@ -107,7 +107,7 @@ struct event *event_new(char *mesg, char *note, long day, int id) /* Check if the event belongs to the selected day */ unsigned event_inday(struct event *i, long *start) { - return (i->day < *start + DAYINSEC && i->day >= *start); + return (date_cmp_day(i->day, *start) == 0); } char *event_tostr(struct event *o) diff --git a/src/recur.c b/src/recur.c index 186acbe..10a2623 100644 --- a/src/recur.c +++ b/src/recur.c @@ -683,7 +683,7 @@ static long diff_years(struct tm lt_start, struct tm lt_end) static int exc_inday(struct excp *exc, long *day_start) { - return (exc->st >= *day_start && exc->st < *day_start + DAYINSEC); + return (date_cmp_day(exc->st, *day_start) == 0); } /* @@ -706,7 +706,7 @@ recur_item_find_occurrence(long item_start, long item_dur, struct tm lt_day, lt_item, lt_item_day; time_t t; - if (day_start < item_start - DAYINSEC + 1) + if (date_cmp_day(day_start, item_start) < 0) return 0; if (rpt_until != 0 && day_start >= rpt_until + item_dur) diff --git a/src/utils.c b/src/utils.c index 4300b59..50f2507 100644 --- a/src/utils.c +++ b/src/utils.c @@ -418,6 +418,30 @@ time_t utcdate2sec(struct date day, unsigned hour, unsigned min) return t; } +/* Compare two dates (without comparing times). */ +int date_cmp_day(time_t d1, time_t d2) +{ + struct tm lt1, lt2; + + localtime_r((time_t *)&d1, <1); + localtime_r((time_t *)&d2, <2); + + if (lt1.tm_year < lt2.tm_year) + return -1; + if (lt1.tm_year > lt2.tm_year) + return 1; + if (lt1.tm_mon < lt2.tm_mon) + return -1; + if (lt1.tm_mon > lt2.tm_mon) + return 1; + if (lt1.tm_mday < lt2.tm_mday) + return -1; + if (lt1.tm_mday > lt2.tm_mday) + return 1; + + return 0; +} + /* Return a string containing the date, given a date in seconds. */ char *date_sec2date_str(long sec, const char *datefmt) { diff --git a/test/Makefile.am b/test/Makefile.am index efc3d12..f8d6088 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -52,6 +52,7 @@ TESTS = \ next-001.sh \ search-001.sh \ bug-002.sh \ + regress-001.sh \ recur-001.sh \ recur-002.sh \ recur-003.sh \ @@ -105,6 +106,7 @@ EXTRA_DIST = \ data/apts-event-006 \ data/apts-filter-001 \ data/apts-recur \ + data/apts-regress-001 \ data/conf \ data/ical-001.ical \ data/ical-002.ical \ diff --git a/test/data/apts-regress-001 b/test/data/apts-regress-001 new file mode 100644 index 0000000..8eaae31 --- /dev/null +++ b/test/data/apts-regress-001 @@ -0,0 +1 @@ +03/28/2016 [1] Day after clock adjustment diff --git a/test/regress-001.sh b/test/regress-001.sh new file mode 100755 index 0000000..3ad6deb --- /dev/null +++ b/test/regress-001.sh @@ -0,0 +1,15 @@ +#!/bin/sh + +. "${TEST_INIT:-./test-init.sh}" + +if [ "$1" = 'actual' ]; then + "$CALCURSE" --read-only -D "$DATA_DIR"/ -c "$DATA_DIR/apts-regress-001" \ + -Q --filter-type=cal --from=2016-03-27 --days=2 +elif [ "$1" = 'expected' ]; then + cat <