From 870fa1aa327c443979bddfc862a691597b8a2273 Mon Sep 17 00:00:00 2001
From: Lars Henriksen <LarsHenriksen@get2net.dk>
Date: Wed, 16 Jan 2019 08:54:57 +0100
Subject: Overflow check for 32-bit types only

Included is a check of the 'until' date for pasted recurrent items.

Signed-off-by: Lars Henriksen <LarsHenriksen@get2net.dk>
Signed-off-by: Lukas Fleischer <lfleischer@calcurse.org>
---
 src/calcurse.h |  4 ++--
 src/day.c      | 31 +++++++++++++++++++++++++++++--
 src/utils.c    | 26 ++++++++++++++++----------
 3 files changed, 47 insertions(+), 14 deletions(-)

(limited to 'src')

diff --git a/src/calcurse.h b/src/calcurse.h
index 0f3bd8a..3efde84 100644
--- a/src/calcurse.h
+++ b/src/calcurse.h
@@ -1203,8 +1203,8 @@ int starts_with(const char *, const char *);
 int starts_with_ci(const char *, const char *);
 int hash_matches(const char *, const char *);
 int show_dialogs(void);
-int overflow_add(int, int, int *);
-int overflow_mul(int, int, int *);
+long overflow_add(long, long, long *);
+long overflow_mul(long, long, long *);
 
 /* vars.c */
 extern int col, row;
diff --git a/src/day.c b/src/day.c
index ceded38..50d6639 100644
--- a/src/day.c
+++ b/src/day.c
@@ -671,19 +671,46 @@ int day_paste_item(struct day_item *p, time_t date)
 		/* No previously cut item. */
 		return 0;
 	}
+	/*
+	 * Valid until date of recurrent items?
+	 * Careful: p->start is not yet set.
+	 */
+	time_t until;
 
 	switch (p->type) {
 	case EVNT:
 		event_paste_item(p->item.ev, date);
 		break;
 	case RECUR_EVNT:
-		recur_event_paste_item(p->item.rev, date);
+		/* want: until = shift + old_until */
+		if (p->item.rev->rpt->until &&
+		    overflow_add(
+			date - p->item.rev->day,
+			p->item.rev->rpt->until,
+			&until)
+		)
+			return 0;
+		if (check_sec(&until))
+			recur_event_paste_item(p->item.rev, date);
+		else
+			return 0;
 		break;
 	case APPT:
 		apoint_paste_item(p->item.apt, date);
 		break;
 	case RECUR_APPT:
-		recur_apoint_paste_item(p->item.rapt, date);
+		/* wanted: until = shift + old_until */
+		if (p->item.rapt->rpt->until &&
+		    overflow_add(
+			date - update_time_in_date(p->item.rapt->start, 0, 0),
+			p->item.rapt->rpt->until,
+			&until)
+		)
+			return 0;
+		if (check_sec(&until))
+			recur_apoint_paste_item(p->item.rapt, date);
+		else
+			return 0;
 		break;
 	default:
 		EXIT(_("unknown item type"));
diff --git a/src/utils.c b/src/utils.c
index 5457319..a194b10 100644
--- a/src/utils.c
+++ b/src/utils.c
@@ -1024,12 +1024,11 @@ int parse_date_duration(const char *string, unsigned *days, time_t start)
 	dur += in;
 	if (start) {
 		/* wanted: start = start + dur * DAYINSEC */
-		int p, s;
+		long p;
 		if (overflow_mul(dur, DAYINSEC, &p))
 			return 0;
-		if (overflow_add(start, p, &s))
+		if (overflow_add(start, p, &start))
 			return 0;
-		start = s;
 		if (!check_sec(&start))
 			return 0;
 	}
@@ -1115,7 +1114,7 @@ int parse_duration(const char *string, unsigned *duration, time_t start)
 
 	const char *p;
 	unsigned in = 0, frac = 0, denom = 1;
-	unsigned dur = 0;
+	long dur = 0;
 
 	if (!string || *string == '\0')
 		return 0;
@@ -1187,7 +1186,7 @@ int parse_duration(const char *string, unsigned *duration, time_t start)
 	if (start) {
 		/* wanted: end = start + dur * MININSEC */
 		time_t end;
-		int p, s;
+		long p, s;
 		if (overflow_mul(dur, MININSEC, &p))
 			return 0;
 		if (overflow_add(start, p, &s))
@@ -1250,10 +1249,9 @@ int parse_datetime(const char *string, time_t *ts, time_t dur)
 	/* Is the resulting time + dur a valid end time? */
 	if (dur) {
 		/* want: sec = *ts + dur */
-		int s;
-		if (overflow_add(*ts, dur, &s))
+		time_t sec;
+		if (overflow_add(*ts, dur, &sec))
 			return 0;
-		time_t sec = s;
 		if (!check_sec(&sec))
 			return 0;
 	}
@@ -1947,12 +1945,16 @@ int show_dialogs(void)
 /*
  * Overflow check for addition with positive second term.
  */
-int overflow_add(int x, int y, int *z)
+long overflow_add(long x, long y, long *z)
 {
+	if (!YEAR1902_2037)
+		goto exit;
+
 	if (y < 0)
 		return 1;
 	if (INT_MAX - y < x)
 		return 1;
+   exit:
 	*z = x + y;
 	return 0;
 }
@@ -1960,12 +1962,16 @@ int overflow_add(int x, int y, int *z)
 /*
  * Overflow check for multiplication with positive terms.
  */
-int overflow_mul(int x, int y, int *z)
+long overflow_mul(long x, long y, long *z)
 {
+	if (!YEAR1902_2037)
+		goto exit;
+
 	if (x < 0 || y <= 0)
 		return 1;
 	if (INT_MAX / y < x)
 		return 1;
+   exit:
 	*z = x * y;
 	return 0;
 }
-- 
cgit v1.2.3-70-g09d2