Add stricter syntax checking to io_load_*()

Be more restrictive with what we allow in data files and bail out if a
line doesn't conform to our specification, especially in regard to
separators. This prevents unexpected behavior when a data file is edited
manually. As a bonus, this fixes a whole pile of compiler warnings
previously seen with "-Wunused-result".

Signed-off-by: Lukas Fleischer <calcurse@cryptocrack.de>
This commit is contained in:
Lukas Fleischer 2012-02-18 14:05:24 +01:00
parent 894ac2d70d
commit 5130c4d028

View File

@ -492,9 +492,7 @@ io_load_app (void)
*/ */
if (fscanf (data_file, "%u / %u / %u ", if (fscanf (data_file, "%u / %u / %u ",
&start.tm_mon, &start.tm_mday, &start.tm_year) != 3) &start.tm_mon, &start.tm_mday, &start.tm_year) != 3)
{ EXIT (_("syntax error in the item date"));
EXIT (_("syntax error in the item date"));
}
/* Read the next character : if it is an '@' then we have /* Read the next character : if it is an '@' then we have
* an appointment, else if it is an '[' we have en event. * an appointment, else if it is an '[' we have en event.
@ -506,22 +504,23 @@ io_load_app (void)
else if (c == '[') else if (c == '[')
is_event = 1; is_event = 1;
else else
{ EXIT (_("no event nor appointment found"));
EXIT (_("no event nor appointment found"));
}
ungetc (c, data_file);
/* Read the remaining informations. */ /* Read the remaining informations. */
if (is_appointment) if (is_appointment)
{ {
fscanf (data_file, "@ %u : %u -> %u / %u / %u @ %u : %u ", if (fscanf (data_file, " %u : %u -> %u / %u / %u @ %u : %u ",
&start.tm_hour, &start.tm_min, &start.tm_hour, &start.tm_min,
&end.tm_mon, &end.tm_mday, &end.tm_year, &end.tm_mon, &end.tm_mday, &end.tm_year,
&end.tm_hour, &end.tm_min); &end.tm_hour, &end.tm_min) != 7)
EXIT (_("syntax error in item time or duration"));
} }
else if (is_event) else if (is_event)
{ {
fscanf (data_file, "[%d] ", &id); if (fscanf (data_file, " %d ", &id) != 1 || getc (data_file) != ']')
EXIT (_("syntax error in item identifier"));
while ((c = getc (data_file)) == ' ');
ungetc (c, data_file);
} }
else else
{ {
@ -534,22 +533,22 @@ io_load_app (void)
if (c == '{') if (c == '{')
{ {
ungetc (c, data_file);
is_recursive = 1; is_recursive = 1;
fscanf (data_file, "{ %d%c ", &freq, &type); if (fscanf (data_file, " %d%c ", &freq, &type) != 2)
EXIT (_("syntax error in item repetition"));
c = getc (data_file); c = getc (data_file);
if (c == '}') if (c == '}')
{ /* endless recurrent item */ { /* endless recurrent item */
ungetc (c, data_file);
fscanf (data_file, "} ");
until.tm_year = 0; until.tm_year = 0;
} while ((c = getc (data_file)) == ' ');
else if (c == '-')
{
ungetc (c, data_file); ungetc (c, data_file);
fscanf (data_file, " -> %u / %u / %u ", }
&until.tm_mon, &until.tm_mday, &until.tm_year); else if (c == '-' && getc (data_file) == '>')
{
if (fscanf (data_file, " %u / %u / %u ", &until.tm_mon,
&until.tm_mday, &until.tm_year) != 3)
EXIT (_("syntax error in item repetition"));
c = getc (data_file); c = getc (data_file);
if (c == '!') if (c == '!')
{ {
@ -557,11 +556,13 @@ io_load_app (void)
recur_exc_scan (&exc, data_file); recur_exc_scan (&exc, data_file);
c = getc (data_file); c = getc (data_file);
} }
else else if (c == '}')
{ {
while ((c = getc (data_file)) == ' ');
ungetc (c, data_file); ungetc (c, data_file);
fscanf (data_file, "} ");
} }
else
EXIT (_("syntax error in item repetition"));
} }
else if (c == '!') else if (c == '!')
{ // endless item with exceptions { // endless item with exceptions
@ -601,16 +602,18 @@ io_load_app (void)
c = getc (data_file); c = getc (data_file);
if (c == '!') if (c == '!')
{ {
ungetc (c, data_file);
fscanf (data_file, " ! ");
state |= APOINT_NOTIFY; state |= APOINT_NOTIFY;
while ((c = getc (data_file)) == ' ');
ungetc (c, data_file);
}
else if (c == '|')
{
state = 0L;
while ((c = getc (data_file)) == ' ');
ungetc (c, data_file);
} }
else else
{ EXIT (_("syntax error in item repetition"));
ungetc (c, data_file);
fscanf (data_file, " | ");
state = 0L;
}
if (is_recursive) if (is_recursive)
{ {
recur_apoint_scan (data_file, start, end, recur_apoint_scan (data_file, start, end,
@ -664,12 +667,13 @@ io_load_todo (void)
{ {
c = getc (data_file); c = getc (data_file);
if (c == EOF) if (c == EOF)
{ break;
break;
}
else if (c == '[') else if (c == '[')
{ /* new style with id */ { /* new style with id */
fscanf (data_file, "%d]", &id); if (fscanf (data_file, " %d ", &id) != 1 || getc (data_file) != ']')
EXIT (_("syntax error in item identifier"));
while ((c = getc (data_file)) == ' ');
ungetc (c, data_file);
} }
else else
{ {
@ -681,9 +685,13 @@ io_load_todo (void)
if (c == '>') if (c == '>')
note_read (note, data_file); note_read (note, data_file);
else else
note[0] = '\0'; {
note[0] = '\0';
ungetc (c, data_file);
}
/* Then read todo description. */ /* Then read todo description. */
fgets (buf, sizeof buf, data_file); if (!fgets (buf, sizeof buf, data_file))
buf[0] = '\0';
newline = strchr (buf, '\n'); newline = strchr (buf, '\n');
if (newline) if (newline)
*newline = '\0'; *newline = '\0';