[bugs] [PATCH] Check for the year span 1902-2037.

Reintroduce year check for systems with a 32-bit time_t type.
Remove the lower limit (1902) for systems with a 64-bit time_t.
This limits movements in the calendar (for 32-bit systems) and in no way
ensures constistency of data.

Commit a12833e removed the upper limit (2037) on dates but left the lower
limit (1902). It did not ensure the support of the target system.
---
 src/calcurse.h    | 11 ++++++++---
 src/ui-calendar.c | 24 ++++++++++++++++++------
 src/utils.c       | 14 ++++++++------
 3 files changed, 34 insertions(+), 15 deletions(-)

diff --git a/src/calcurse.h b/src/calcurse.h
index 59b46b5..3f9a365 100644
--- a/src/calcurse.h
+++ b/src/calcurse.h
@@ -303,10 +303,15 @@ enum datefmt {
 /* Day heading default format. */
 #define DAY_HEADING_DEFAULT "%B %-d, %Y"
 
+/*
+ * Calcurse representation of the date of a day in the calendar.
+ * When time_t is a 32-bit signed integer, the year range is 1902 - 2037.
+ */
+#define YEAR1902_2037 (sizeof(time_t) == 4)
 struct date {
-	unsigned dd;
-	unsigned mm;
-	unsigned yyyy;
+	unsigned dd;		/* day: 1 - 31 */
+	unsigned mm;		/* month: 1 - 12 */
+	unsigned yyyy;		/* year AD */
 };
 
 #define ISLEAP(y) ((((y) % 4) == 0 && ((y) % 100) != 0) || ((y) % 400) == 0)
diff --git a/src/ui-calendar.c b/src/ui-calendar.c
index a2a0e8b..97656c6 100644
--- a/src/ui-calendar.c
+++ b/src/ui-calendar.c
@@ -708,18 +708,30 @@ void ui_calendar_move(enum move move, int count)
 		ret = 1;
 		/* NOTREACHED */
 	}
-
-	if (ret == 0) {
+   	if (ret == 1 || (YEAR1902_2037 && t.tm_year < 2)
+		     || (YEAR1902_2037 && t.tm_year > 137)) {
+		char *out, *msg = _("The move failed (%d/%d/%d, ret=%d)."), ch;
+		asprintf(&out, msg, t.tm_mday, t.tm_mon + 1, t.tm_year + 1900, ret);
+		do {
+			status_mesg(out, _("Press [ENTER] to continue"));
+			ch = keys_wgetch(win[KEY].p);
+		} while (ch != '\n');
+		mem_free(out);
+		wins_update(FLAG_STA);
 		if (t.tm_year < 2) {
 			t.tm_mday = 1;
 			t.tm_mon = 0;
 			t.tm_year = 2;
 		}
-
-		slctd_day.dd = t.tm_mday;
-		slctd_day.mm = t.tm_mon + 1;
-		slctd_day.yyyy = t.tm_year + 1900;
+		if (t.tm_year > 137) {
+			t.tm_mday = 31;
+			t.tm_mon = 11;
+			t.tm_year = 137;
+		}
 	}
+	slctd_day.dd = t.tm_mday;
+	slctd_day.mm = t.tm_mon + 1;
+	slctd_day.yyyy = t.tm_year + 1900;
 }
 
 /* Returns the beginning of current year as a long. */
diff --git a/src/utils.c b/src/utils.c
index 11d4582..9c89551 100644
--- a/src/utils.c
+++ b/src/utils.c
@@ -481,7 +481,7 @@ void date_sec2date_fmt(long sec, const char *fmt, char *datef)
 }
 
 /*
- * Used to change date by adding a certain amount of days or weeks.
+ * Used to change date by adding a certain amount of days or months.
  * Returns 0 on success, 1 otherwise.
  */
 int date_change(struct tm *date, int delta_month, int delta_day)
@@ -501,7 +501,7 @@ int date_change(struct tm *date, int delta_month, int delta_day)
 }
 
 /*
- * Used to change date by adding a certain amount of days or weeks.
+ * Used to change date by adding a certain amount of days or months.
  */
 long date_sec_change(long date, int delta_month, int delta_day)
 {
@@ -540,7 +540,7 @@ long update_time_in_date(long date, unsigned hr, unsigned mn)
 }
 
 /*
- * Returns the date in seconds from year 1900.
+ * Returns the date in seconds from year 1970.
  * If no date is entered, current date is chosen.
  */
 time_t get_sec_date(struct date date)
@@ -617,7 +617,7 @@ item_in_popup(const char *a_start, const char *a_end, const char *msg,
 	delwin(popup_win);
 }
 
-/* Returns the beginning of current day in seconds from 1900. */
+/* Returns the beginning of current day in seconds from 1970. */
 time_t get_today(void)
 {
 	struct tm lt;
@@ -749,11 +749,13 @@ static void get_weekday_ymd(int *year, int *month, int *day, int weekday)
 }
 
 /*
- * Check if a date is valid.
+ * Check if a calcurse date is valid.
  */
 int check_date(unsigned year, unsigned month, unsigned day)
 {
-	return (year >= 1902 && month >= 1 && month <= 12 && day >= 1 &&
+	return ((YEAR1902_2037 ? year >= 1902 && year <= 2037 : 1) &&
+		month >= 1 && month <= 12 &&
+		day >= 1 &&
 		day <= days[month - 1] + (month == 2 && ISLEAP(year)) ? 1 : 0);
 }
 
-- 
2.14.2.666.gea220ee40

Links