forked from len0rd/rockbox
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
This commit is contained in:
parent
eb85f14f95
commit
814d402d4c
2 changed files with 33 additions and 56 deletions
|
|
@ -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<true> 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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
close_conditionals(data, 1);
|
||||
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--;
|
||||
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;
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue