1
0
mirror of https://github.com/rkd77/elinks.git synced 2024-12-04 14:46:47 -05:00

config: Skip values of unrecognized options.

To avoid parsing them as commands.
(cherry picked from commit e06416d248)
This commit is contained in:
Kalle Olavi Niemitalo 2008-02-03 04:05:03 +02:00 committed by Kalle Olavi Niemitalo
parent f4e8682193
commit f67ddcf851

View File

@ -128,6 +128,51 @@ skip_white(struct conf_parsing_pos *pos)
pos->look = start; pos->look = start;
} }
/** Skip a quoted string.
* This function allows "mismatching quotes' because str_rd() does so. */
static void
skip_quoted(struct conf_parsing_pos *pos)
{
assert(isquote(*pos->look));
if_assert_failed return;
pos->look++;
for (;;) {
if (!*pos->look)
return;
if (isquote(*pos->look)) {
pos->look++;
return;
}
if (*pos->look == '\\' && pos->look[1])
pos->look++;
if (*pos->look == '\n')
pos->line++;
pos->look++;
}
}
/** Skip the value of an option.
*
* This job is normally done by the reader function that corresponds
* to the type of the option. However, if ELinks does not recognize
* the name of the option, it cannot look up the type and has to use
* this function instead. */
static void
skip_option_value(struct conf_parsing_pos *pos)
{
if (isquote(*pos->look)) {
/* Looks like OPT_STRING, OPT_CODEPAGE, OPT_LANGUAGE,
* or OPT_COLOR. */
skip_quoted(pos);
} else {
/* Looks like OPT_BOOL, OPT_INT, or OPT_LONG. */
while (isasciialnum(*pos->look) || *pos->look == '.'
|| *pos->look == '+' || *pos->look == '-')
pos->look++;
}
}
/* Parse a command. Returns error code. */ /* Parse a command. Returns error code. */
/* If dynamic string credentials are supplied, we will mirror the command at /* If dynamic string credentials are supplied, we will mirror the command at
* the end of the string; however, we won't load the option value to the tree, * the end of the string; however, we won't load the option value to the tree,
@ -177,19 +222,37 @@ parse_set(struct option *opt_tree, struct conf_parsing_state *state,
{ {
struct option *opt; struct option *opt;
unsigned char *val; unsigned char *val;
const struct conf_parsing_pos pos_before_value = state->pos;
opt = mirror ? get_opt_rec_real(opt_tree, optname) : get_opt_rec(opt_tree, optname); opt = mirror ? get_opt_rec_real(opt_tree, optname) : get_opt_rec(opt_tree, optname);
mem_free(optname); mem_free(optname);
if (!opt || (opt->flags & OPT_HIDDEN)) if (!opt || (opt->flags & OPT_HIDDEN)) {
return show_parse_error(state, ERROR_OPTION); show_parse_error(state, ERROR_OPTION);
skip_option_value(&state->pos);
return ERROR_OPTION;
}
if (!option_types[opt->type].read) if (!option_types[opt->type].read) {
return show_parse_error(state, ERROR_VALUE); show_parse_error(state, ERROR_VALUE);
skip_option_value(&state->pos);
return ERROR_VALUE;
}
val = option_types[opt->type].read(opt, &state->pos.look, val = option_types[opt->type].read(opt, &state->pos.look,
&state->pos.line); &state->pos.line);
if (!val) return show_parse_error(state, ERROR_VALUE); if (!val) {
/* The reader function failed. Jump back to
* the beginning of the value and skip it with
* the generic code. For the error message,
* use the line number at the beginning of the
* value, because the ending position is not
* interesting if there is an unclosed quote. */
state->pos = pos_before_value;
show_parse_error(state, ERROR_VALUE);
skip_option_value(&state->pos);
return ERROR_VALUE;
}
if (mirror) { if (mirror) {
if (opt->flags & OPT_DELETED) if (opt->flags & OPT_DELETED)