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>
This commit is contained in:
Lars Henriksen 2019-01-16 08:54:57 +01:00 committed by Lukas Fleischer
parent 03340db72e
commit 870fa1aa32
3 changed files with 47 additions and 14 deletions

View File

@ -1203,8 +1203,8 @@ int starts_with(const char *, const char *);
int starts_with_ci(const char *, const char *); int starts_with_ci(const char *, const char *);
int hash_matches(const char *, const char *); int hash_matches(const char *, const char *);
int show_dialogs(void); int show_dialogs(void);
int overflow_add(int, int, int *); long overflow_add(long, long, long *);
int overflow_mul(int, int, int *); long overflow_mul(long, long, long *);
/* vars.c */ /* vars.c */
extern int col, row; extern int col, row;

View File

@ -671,19 +671,46 @@ int day_paste_item(struct day_item *p, time_t date)
/* No previously cut item. */ /* No previously cut item. */
return 0; return 0;
} }
/*
* Valid until date of recurrent items?
* Careful: p->start is not yet set.
*/
time_t until;
switch (p->type) { switch (p->type) {
case EVNT: case EVNT:
event_paste_item(p->item.ev, date); event_paste_item(p->item.ev, date);
break; break;
case RECUR_EVNT: case RECUR_EVNT:
/* 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); recur_event_paste_item(p->item.rev, date);
else
return 0;
break; break;
case APPT: case APPT:
apoint_paste_item(p->item.apt, date); apoint_paste_item(p->item.apt, date);
break; break;
case RECUR_APPT: case RECUR_APPT:
/* 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); recur_apoint_paste_item(p->item.rapt, date);
else
return 0;
break; break;
default: default:
EXIT(_("unknown item type")); EXIT(_("unknown item type"));

View File

@ -1024,12 +1024,11 @@ int parse_date_duration(const char *string, unsigned *days, time_t start)
dur += in; dur += in;
if (start) { if (start) {
/* wanted: start = start + dur * DAYINSEC */ /* wanted: start = start + dur * DAYINSEC */
int p, s; long p;
if (overflow_mul(dur, DAYINSEC, &p)) if (overflow_mul(dur, DAYINSEC, &p))
return 0; return 0;
if (overflow_add(start, p, &s)) if (overflow_add(start, p, &start))
return 0; return 0;
start = s;
if (!check_sec(&start)) if (!check_sec(&start))
return 0; return 0;
} }
@ -1115,7 +1114,7 @@ int parse_duration(const char *string, unsigned *duration, time_t start)
const char *p; const char *p;
unsigned in = 0, frac = 0, denom = 1; unsigned in = 0, frac = 0, denom = 1;
unsigned dur = 0; long dur = 0;
if (!string || *string == '\0') if (!string || *string == '\0')
return 0; return 0;
@ -1187,7 +1186,7 @@ int parse_duration(const char *string, unsigned *duration, time_t start)
if (start) { if (start) {
/* wanted: end = start + dur * MININSEC */ /* wanted: end = start + dur * MININSEC */
time_t end; time_t end;
int p, s; long p, s;
if (overflow_mul(dur, MININSEC, &p)) if (overflow_mul(dur, MININSEC, &p))
return 0; return 0;
if (overflow_add(start, p, &s)) 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? */ /* Is the resulting time + dur a valid end time? */
if (dur) { if (dur) {
/* want: sec = *ts + dur */ /* want: sec = *ts + dur */
int s; time_t sec;
if (overflow_add(*ts, dur, &s)) if (overflow_add(*ts, dur, &sec))
return 0; return 0;
time_t sec = s;
if (!check_sec(&sec)) if (!check_sec(&sec))
return 0; return 0;
} }
@ -1947,12 +1945,16 @@ int show_dialogs(void)
/* /*
* Overflow check for addition with positive second term. * 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) if (y < 0)
return 1; return 1;
if (INT_MAX - y < x) if (INT_MAX - y < x)
return 1; return 1;
exit:
*z = x + y; *z = x + y;
return 0; return 0;
} }
@ -1960,12 +1962,16 @@ int overflow_add(int x, int y, int *z)
/* /*
* Overflow check for multiplication with positive terms. * 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) if (x < 0 || y <= 0)
return 1; return 1;
if (INT_MAX / y < x) if (INT_MAX / y < x)
return 1; return 1;
exit:
*z = x * y; *z = x * y;
return 0; return 0;
} }