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 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;

View File

@ -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"));

View File

@ -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;
}