Fix ical import logging

The following issues have been fixed:

Functions ical_read_event() and ical_read__todo() do not check the return value
of functions which may fail, in which case an item is not skipped even though
a problem may have been logged by the called function.

Function ical_read_note() fails on empty DESCRIPTION, but does not log it.

Function ical_read_exdate() may log a failure, but cannot fail itself.

Function ical_read_summary() can fail, but not log a failure.

Function ical_read_todo() do not skip a todo with an invalid priority.

Additionally:

A safety check has been added to ical_get_value(), and log messages resulting
from failures have been made uniform.

Signed-off-by: Lars Henriksen <LarsHenriksen@get2net.dk>
Signed-off-by: Lukas Fleischer <lfleischer@calcurse.org>
This commit is contained in:
Lars Henriksen 2020-03-18 20:35:55 +01:00 committed by Lukas Fleischer
parent 63c2d4d503
commit 1cb2691342

View File

@ -704,6 +704,8 @@ static long ical_compute_rpt_until(long start, ical_rpt_t * rpt)
*/ */
static char *ical_get_value(char *p) static char *ical_get_value(char *p)
{ {
if (!(p && *p))
return NULL;
for (; *p != ':'; p++) { for (; *p != ':'; p++) {
if (*p == '"') if (*p == '"')
for (p++; *p != '"' && *p != '\0'; p++); for (p++; *p != '"' && *p != '\0'; p++);
@ -764,7 +766,7 @@ static ical_rpt_t *ical_read_rrule(FILE * log, char *rrulestr,
p = ical_get_value(rrulestr); p = ical_get_value(rrulestr);
if (!p) { if (!p) {
ical_log(log, ICAL_VEVENT, itemline, ical_log(log, ICAL_VEVENT, itemline,
_("recurrence rule malformed.")); _("malformed recurrence line."));
(*noskipped)++; (*noskipped)++;
return NULL; return NULL;
} }
@ -844,7 +846,7 @@ static void ical_add_exc(llist_t * exc_head, long date)
* This property defines the list of date/time exceptions for a * This property defines the list of date/time exceptions for a
* recurring calendar component. * recurring calendar component.
*/ */
static void static int
ical_read_exdate(llist_t * exc, FILE * log, char *exstr, ical_read_exdate(llist_t * exc, FILE * log, char *exstr,
unsigned *noskipped, const int itemline) unsigned *noskipped, const int itemline)
{ {
@ -853,9 +855,9 @@ ical_read_exdate(llist_t * exc, FILE * log, char *exstr,
p = ical_get_value(exstr); p = ical_get_value(exstr);
if (!p) { if (!p) {
ical_log(log, ICAL_VEVENT, itemline, ical_log(log, ICAL_VEVENT, itemline,
_("recurrence exception dates malformed.")); _("malformed exceptions line."));
(*noskipped)++; (*noskipped)++;
return; return 0;
} }
while ((q = strchr(p, ',')) != NULL) { while ((q = strchr(p, ',')) != NULL) {
@ -868,6 +870,8 @@ ical_read_exdate(llist_t * exc, FILE * log, char *exstr,
p = ++q; p = ++q;
} }
ical_add_exc(exc, ical_datetime2time_t(p, NULL)); ical_add_exc(exc, ical_datetime2time_t(p, NULL));
return 1;
} }
/* Return an allocated string containing the name of the newly created note. */ /* Return an allocated string containing the name of the newly created note. */
@ -880,19 +884,20 @@ static char *ical_read_note(char *line, unsigned *noskipped,
p = ical_get_value(line); p = ical_get_value(line);
if (!p) { if (!p) {
ical_log(log, item_type, itemline, ical_log(log, item_type, itemline,
_("description malformed.")); _("malformed description line."));
(*noskipped)++; (*noskipped)++;
return NULL; return NULL;
} }
notestr = ical_unformat_line(p); notestr = ical_unformat_line(p);
if (notestr == NULL) { if (!notestr) {
ical_log(log, item_type, itemline, ical_log(log, item_type, itemline, _("malformed description."));
_("could not get entire item description."));
(*noskipped)++; (*noskipped)++;
return NULL; return NULL;
} else if (strlen(notestr) == 0) { } else if (strlen(notestr) == 0) {
mem_free(notestr); mem_free(notestr);
ical_log(log, item_type, itemline, _("empty description."));
(*noskipped)++;
return NULL; return NULL;
} else { } else {
note = generate_note(notestr); note = generate_note(notestr);
@ -902,17 +907,25 @@ static char *ical_read_note(char *line, unsigned *noskipped,
} }
/* Returns an allocated string containing the ical item summary. */ /* Returns an allocated string containing the ical item summary. */
static char *ical_read_summary(char *line) static char *ical_read_summary(char *line, unsigned *noskipped,
ical_types_e item_type, const int itemline,
FILE * log)
{ {
char *p, *summary; char *p, *summary;
p = ical_get_value(line); p = ical_get_value(line);
if (!p) if (!p) {
ical_log(log, item_type, itemline, _("malformed summary line"));
(*noskipped)++;
return NULL; return NULL;
}
summary = ical_unformat_line(p); summary = ical_unformat_line(p);
if (!summary) if (!summary) {
ical_log(log, item_type, itemline, _("malformed summary."));
(*noskipped)++;
return NULL; return NULL;
}
/* Event summaries must not contain newlines. */ /* Event summaries must not contain newlines. */
for (p = strchr(summary, '\n'); p; p = strchr(p, '\n')) for (p = strchr(summary, '\n'); p; p = strchr(p, '\n'))
@ -958,12 +971,12 @@ ical_read_event(FILE * fdi, FILE * log, unsigned *noevents,
if (!vevent.mesg) { if (!vevent.mesg) {
ical_log(log, ICAL_VEVENT, ITEMLINE, ical_log(log, ICAL_VEVENT, ITEMLINE,
_("could not retrieve item summary.")); _("could not retrieve item summary."));
goto cleanup; goto skip;
} }
if (vevent.start == 0) { if (vevent.start == 0) {
ical_log(log, ICAL_VEVENT, ITEMLINE, ical_log(log, ICAL_VEVENT, ITEMLINE,
_("item start date is not defined.")); _("item start date is not defined."));
goto cleanup; goto skip;
} }
if (vevent_type == APPOINTMENT && vevent.dur == 0) { if (vevent_type == APPOINTMENT && vevent.dur == 0) {
@ -974,7 +987,7 @@ ical_read_event(FILE * fdi, FILE * log, unsigned *noevents,
if (vevent.dur < 0) { if (vevent.dur < 0) {
ical_log(log, ICAL_VEVENT, ITEMLINE, ical_log(log, ICAL_VEVENT, ITEMLINE,
_("item has a negative duration.")); _("item has a negative duration."));
goto cleanup; goto skip;
} }
} }
@ -1003,7 +1016,7 @@ ical_read_event(FILE * fdi, FILE * log, unsigned *noevents,
case UNDEFINED: case UNDEFINED:
ical_log(log, ICAL_VEVENT, ITEMLINE, ical_log(log, ICAL_VEVENT, ITEMLINE,
_("item could not be identified.")); _("item could not be identified."));
goto cleanup; goto skip;
break; break;
} }
@ -1014,50 +1027,58 @@ ical_read_event(FILE * fdi, FILE * log, unsigned *noevents,
p = ical_get_value(buf); p = ical_get_value(buf);
if (!p) { if (!p) {
ical_log(log, ICAL_VEVENT, ITEMLINE, ical_log(log, ICAL_VEVENT, ITEMLINE,
_("event start time malformed.")); _("malformed start time line."));
goto cleanup; goto skip;
} }
vevent.start = ical_datetime2time_t(p, &vevent_type); vevent.start = ical_datetime2time_t(p, &vevent_type);
if (!vevent.start) { if (!vevent.start) {
ical_log(log, ICAL_VEVENT, ITEMLINE, ical_log(log, ICAL_VEVENT, ITEMLINE,
_("could not retrieve event start time.")); _("could not retrieve event start time."));
goto cleanup; goto skip;
} }
} else if (starts_with_ci(buf, "DTEND")) { } else if (starts_with_ci(buf, "DTEND")) {
p = ical_get_value(buf); p = ical_get_value(buf);
if (!p) { if (!p) {
ical_log(log, ICAL_VEVENT, ITEMLINE, ical_log(log, ICAL_VEVENT, ITEMLINE,
_("event end time malformed.")); _("malformed end time line."));
goto cleanup; goto skip;
} }
vevent.end = ical_datetime2time_t(p, &vevent_type); vevent.end = ical_datetime2time_t(p, &vevent_type);
if (!vevent.end) { if (!vevent.end) {
ical_log(log, ICAL_VEVENT, ITEMLINE, ical_log(log, ICAL_VEVENT, ITEMLINE,
_("could not retrieve event end time.")); _("could not retrieve event end time."));
goto cleanup; goto skip;
} }
} else if (starts_with_ci(buf, "DURATION")) { } else if (starts_with_ci(buf, "DURATION")) {
vevent.dur = ical_dur2long(buf); vevent.dur = ical_dur2long(buf);
if (vevent.dur <= 0) { if (vevent.dur <= 0) {
ical_log(log, ICAL_VEVENT, ITEMLINE, ical_log(log, ICAL_VEVENT, ITEMLINE,
_("item duration malformed.")); _("item duration malformed."));
goto cleanup; goto skip;
} }
} else if (starts_with_ci(buf, "RRULE")) { } else if (starts_with_ci(buf, "RRULE")) {
vevent.rpt = ical_read_rrule(log, buf, noskipped, vevent.rpt = ical_read_rrule(log, buf, noskipped,
ITEMLINE); ITEMLINE);
if (!vevent.rpt)
goto cleanup;
} else if (starts_with_ci(buf, "EXDATE")) { } else if (starts_with_ci(buf, "EXDATE")) {
ical_read_exdate(&vevent.exc, log, buf, noskipped, if (!ical_read_exdate(&vevent.exc, log, buf, noskipped,
ITEMLINE); ITEMLINE))
goto cleanup;
} else if (starts_with_ci(buf, "SUMMARY")) { } else if (starts_with_ci(buf, "SUMMARY")) {
vevent.mesg = ical_read_summary(buf); vevent.mesg = ical_read_summary(buf, noskipped,
ICAL_VEVENT, ITEMLINE, log);
if (!vevent.mesg)
goto cleanup;
} else if (starts_with_ci(buf, "BEGIN:VALARM")) { } else if (starts_with_ci(buf, "BEGIN:VALARM")) {
skip_alarm = vevent.has_alarm = 1; skip_alarm = vevent.has_alarm = 1;
} else if (starts_with_ci(buf, "DESCRIPTION")) { } else if (starts_with_ci(buf, "DESCRIPTION")) {
vevent.note = ical_read_note(buf, noskipped, vevent.note = ical_read_note(buf, noskipped,
ICAL_VEVENT, ITEMLINE, log); ICAL_VEVENT, ITEMLINE, log);
if (!vevent.note)
goto cleanup;
} }
} }
@ -1065,8 +1086,10 @@ ical_read_event(FILE * fdi, FILE * log, unsigned *noevents,
_("The ical file seems to be malformed. " _("The ical file seems to be malformed. "
"The end of item was not found.")); "The end of item was not found."));
cleanup: skip:
(*noskipped)++;
cleanup:
if (vevent.note) if (vevent.note)
mem_free(vevent.note); mem_free(vevent.note);
if (vevent.mesg) if (vevent.mesg)
@ -1074,7 +1097,6 @@ cleanup:
if (vevent.rpt) if (vevent.rpt)
mem_free(vevent.rpt); mem_free(vevent.rpt);
LLIST_FREE(&vevent.exc); LLIST_FREE(&vevent.exc);
(*noskipped)++;
} }
static void static void
@ -1121,16 +1143,23 @@ ical_read_todo(FILE * fdi, FILE * log, unsigned *notodos, unsigned *noskipped,
ical_log(log, ICAL_VTODO, ITEMLINE, ical_log(log, ICAL_VTODO, ITEMLINE,
_("item priority is invalid " _("item priority is invalid "
"(must be between 0 and 9).")); "(must be between 0 and 9)."));
goto skip;
} }
} else if (starts_with_ci(buf, "STATUS:COMPLETED")) { } else if (starts_with_ci(buf, "STATUS:COMPLETED")) {
vtodo.completed = 1; vtodo.completed = 1;
} else if (starts_with_ci(buf, "SUMMARY")) { } else if (starts_with_ci(buf, "SUMMARY")) {
vtodo.mesg = ical_read_summary(buf); vtodo.mesg =
ical_read_summary(buf, noskipped, ICAL_VTODO,
ITEMLINE, log);
if (!vtodo.mesg)
goto cleanup;
} else if (starts_with_ci(buf, "BEGIN:VALARM")) { } else if (starts_with_ci(buf, "BEGIN:VALARM")) {
skip_alarm = 1; skip_alarm = 1;
} else if (starts_with_ci(buf, "DESCRIPTION")) { } else if (starts_with_ci(buf, "DESCRIPTION")) {
vtodo.note = ical_read_note(buf, noskipped, ICAL_VTODO, vtodo.note = ical_read_note(buf, noskipped, ICAL_VTODO,
ITEMLINE, log); ITEMLINE, log);
if (!vtodo.note)
goto cleanup;
} }
} }
@ -1138,12 +1167,13 @@ ical_read_todo(FILE * fdi, FILE * log, unsigned *notodos, unsigned *noskipped,
_("The ical file seems to be malformed. " _("The ical file seems to be malformed. "
"The end of item was not found.")); "The end of item was not found."));
skip:
(*noskipped)++;
cleanup: cleanup:
if (vtodo.note) if (vtodo.note)
mem_free(vtodo.note); mem_free(vtodo.note);
if (vtodo.mesg) if (vtodo.mesg)
mem_free(vtodo.mesg); mem_free(vtodo.mesg);
(*noskipped)++;
} }
/* Import calcurse data. */ /* Import calcurse data. */