From 814d402d4c9c011ee7e357e74cca6a64176a33d8 Mon Sep 17 00:00:00 2001 From: Nicolas Pennequin Date: Sat, 21 Apr 2007 19:31:46 +0000 Subject: More strict WPS parsing and displaying code. If there are errors, WPS loading will fail and the default WPS will be displayed. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@13236 a1c6a512-1295-4272-9138-f99709370657 --- apps/gui/gwps-common.c | 24 ++----------------- apps/gui/wps_parser.c | 65 ++++++++++++++++++++++++-------------------------- 2 files changed, 33 insertions(+), 56 deletions(-) (limited to 'apps') diff --git a/apps/gui/gwps-common.c b/apps/gui/gwps-common.c index d6576a2b3c..8022209189 100644 --- a/apps/gui/gwps-common.c +++ b/apps/gui/gwps-common.c @@ -1275,16 +1275,6 @@ static char *get_token_value(struct gui_wps *gwps, */ static int find_conditional_end(struct wps_data *data, int index) { - int type = data->tokens[index].type; - - if (type != WPS_TOKEN_CONDITIONAL_START - && type != WPS_TOKEN_CONDITIONAL_OPTION) - { - /* this function should only be used with "index" pointing to a - WPS_TOKEN_CONDITIONAL_START or a WPS_TOKEN_CONDITIONAL_OPTION */ - return index + 1; - } - int ret = index; while (data->tokens[ret].type != WPS_TOKEN_CONDITIONAL_END) ret = data->tokens[ret].value.i; @@ -1304,18 +1294,8 @@ static int evaluate_conditional(struct gui_wps *gwps, int cond_index) struct wps_data *data = gwps->data; int ret, i; - int num_options = data->tokens[cond_index].value.i; char result[128], *value; - int cond_start = cond_index; - - /* find the index of the conditional start token */ - while (data->tokens[cond_start].type != WPS_TOKEN_CONDITIONAL_START - && cond_start < data->num_tokens) - cond_start++; - - /* if the number of options is 0, the conditional is invalid */ - if (num_options == 0) - return cond_start; + int num_options = data->tokens[cond_index].value.i; /* treat ?xx constructs as if they had 2 options. */ if (num_options < 2) @@ -1334,7 +1314,7 @@ static int evaluate_conditional(struct gui_wps *gwps, int cond_index) intval = num_options; /* skip to the right enum case */ - int next = cond_start; + int next = cond_index + 2; for (i = 1; i < intval; i++) { next = data->tokens[next].value.i; diff --git a/apps/gui/wps_parser.c b/apps/gui/wps_parser.c index 5f1149968f..daf318bbcd 100644 --- a/apps/gui/wps_parser.c +++ b/apps/gui/wps_parser.c @@ -278,22 +278,6 @@ static void wps_start_new_subline(struct wps_data *data) data->lines[data->num_lines].num_sublines++; } -static void close_conditionals(struct wps_data *data, int n) -{ - int i; - for (i = 0; i < n; i++) - { - data->tokens[data->num_tokens].type = WPS_TOKEN_CONDITIONAL_END; - if (lastcond[level]) - data->tokens[lastcond[level]].value.i = data->num_tokens; - - lastcond[level] = 0; - data->num_tokens++; - data->tokens[condindex[level]].value.i = numoptions[level]; - level--; - } -} - #ifdef HAVE_LCD_BITMAP static int parse_statusbar_enable(const char *wps_bufptr, @@ -600,8 +584,8 @@ static int parse_token(const char *wps_bufptr, struct wps_data *wps_data) /* escaped characters */ token->type = WPS_TOKEN_CHARACTER; token->value.c = *wps_bufptr; + taglen = 1; wps_data->num_tokens++; - skip++; break; case '?': @@ -611,10 +595,8 @@ static int parse_token(const char *wps_bufptr, struct wps_data *wps_data) condindex[level] = wps_data->num_tokens; numoptions[level] = 1; wps_data->num_tokens++; - token++; - wps_bufptr++; - skip++; - /* no "break" because a '?' is followed by a regular tag */ + taglen = 1 + parse_token(wps_bufptr + 1, wps_data); + break; default: /* find what tag we have */ @@ -622,8 +604,7 @@ static int parse_token(const char *wps_bufptr, struct wps_data *wps_data) strncmp(wps_bufptr, tag->name, strlen(tag->name)) != 0; tag++) ; - taglen = strlen(tag->name); - skip += taglen; + taglen = (tag->type != WPS_TOKEN_UNKNOWN) ? strlen(tag->name) : 2; token->type = tag->type; wps_data->sublines[wps_data->num_sublines].line_type |= tag->refresh_type; @@ -643,6 +624,7 @@ static int parse_token(const char *wps_bufptr, struct wps_data *wps_data) break; } + skip += taglen; return skip; } @@ -657,6 +639,7 @@ static bool wps_parse(struct wps_data *data, const char *wps_bufptr) char *current_string = data->string_buffer; int stringbuf_used = 0; + level = -1; while(*wps_bufptr && data->num_tokens < WPS_MAX_TOKENS - 1 && data->num_lines < WPS_MAX_LINES) @@ -671,8 +654,8 @@ static bool wps_parse(struct wps_data *data, const char *wps_bufptr) /* Alternating sublines separator */ case ';': - if (level >= 0) - close_conditionals(data, level + 1); + if (level >= 0) /* there are unclosed conditionals */ + return false; if (data->num_sublines+1 < WPS_MAX_SUBLINES) wps_start_new_subline(data); @@ -683,22 +666,32 @@ static bool wps_parse(struct wps_data *data, const char *wps_bufptr) /* Conditional list start */ case '<': + if (data->tokens[data->num_tokens-2].type != WPS_TOKEN_CONDITIONAL) + return false; + data->tokens[data->num_tokens].type = WPS_TOKEN_CONDITIONAL_START; lastcond[level] = data->num_tokens++; break; /* Conditional list end */ case '>': - if (level < 0) /* not in a conditional, ignore the char */ - break; + if (level < 0) /* not in a conditional, invalid char */ + return false; + + data->tokens[data->num_tokens].type = WPS_TOKEN_CONDITIONAL_END; + if (lastcond[level]) + data->tokens[lastcond[level]].value.i = data->num_tokens; - close_conditionals(data, 1); + lastcond[level] = 0; + data->num_tokens++; + data->tokens[condindex[level]].value.i = numoptions[level]; + level--; break; /* Conditional list option */ case '|': - if (level < 0) /* not in a conditional, ignore the char */ - break; + if (level < 0) /* not in a conditional, invalid char */ + return false; data->tokens[data->num_tokens].type = WPS_TOKEN_CONDITIONAL_OPTION; if (lastcond[level]) @@ -711,16 +704,16 @@ static bool wps_parse(struct wps_data *data, const char *wps_bufptr) /* Comment */ case '#': - if (level >= 0) - close_conditionals(data, level + 1); + if (level >= 0) /* there are unclosed conditionals */ + return false; wps_bufptr += skip_end_of_line(wps_bufptr); break; /* End of this line */ case '\n': - if (level >= 0) - close_conditionals(data, level + 1); + if (level >= 0) /* there are unclosed conditionals */ + return false; wps_start_new_subline(data); data->num_lines++; /* Start a new line */ @@ -979,7 +972,11 @@ bool wps_data_load(struct wps_data *wps_data, /* parse the WPS source */ if (!wps_parse(wps_data, wps_buffer)) + { + DEBUGF("Failed parsing of %s\n", buf); + wps_reset(wps_data); return false; + } wps_data->wps_loaded = true; -- cgit v1.2.3