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:
parent
894ac2d70d
commit
5130c4d028
68
src/io.c
68
src/io.c
@ -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';
|
||||||
|
Loading…
x
Reference in New Issue
Block a user