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)
|
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;
|
int ret = index;
|
||||||
while (data->tokens[ret].type != WPS_TOKEN_CONDITIONAL_END)
|
while (data->tokens[ret].type != WPS_TOKEN_CONDITIONAL_END)
|
||||||
ret = data->tokens[ret].value.i;
|
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;
|
struct wps_data *data = gwps->data;
|
||||||
|
|
||||||
int ret, i;
|
int ret, i;
|
||||||
int num_options = data->tokens[cond_index].value.i;
|
|
||||||
char result[128], *value;
|
char result[128], *value;
|
||||||
int cond_start = cond_index;
|
int num_options = data->tokens[cond_index].value.i;
|
||||||
|
|
||||||
/* 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;
|
|
||||||
|
|
||||||
/* treat ?xx<true> constructs as if they had 2 options. */
|
/* treat ?xx<true> constructs as if they had 2 options. */
|
||||||
if (num_options < 2)
|
if (num_options < 2)
|
||||||
|
|
@ -1334,7 +1314,7 @@ static int evaluate_conditional(struct gui_wps *gwps, int cond_index)
|
||||||
intval = num_options;
|
intval = num_options;
|
||||||
|
|
||||||
/* skip to the right enum case */
|
/* skip to the right enum case */
|
||||||
int next = cond_start;
|
int next = cond_index + 2;
|
||||||
for (i = 1; i < intval; i++)
|
for (i = 1; i < intval; i++)
|
||||||
{
|
{
|
||||||
next = data->tokens[next].value.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++;
|
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
|
#ifdef HAVE_LCD_BITMAP
|
||||||
|
|
||||||
static int parse_statusbar_enable(const char *wps_bufptr,
|
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 */
|
/* escaped characters */
|
||||||
token->type = WPS_TOKEN_CHARACTER;
|
token->type = WPS_TOKEN_CHARACTER;
|
||||||
token->value.c = *wps_bufptr;
|
token->value.c = *wps_bufptr;
|
||||||
|
taglen = 1;
|
||||||
wps_data->num_tokens++;
|
wps_data->num_tokens++;
|
||||||
skip++;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case '?':
|
case '?':
|
||||||
|
|
@ -611,10 +595,8 @@ static int parse_token(const char *wps_bufptr, struct wps_data *wps_data)
|
||||||
condindex[level] = wps_data->num_tokens;
|
condindex[level] = wps_data->num_tokens;
|
||||||
numoptions[level] = 1;
|
numoptions[level] = 1;
|
||||||
wps_data->num_tokens++;
|
wps_data->num_tokens++;
|
||||||
token++;
|
taglen = 1 + parse_token(wps_bufptr + 1, wps_data);
|
||||||
wps_bufptr++;
|
break;
|
||||||
skip++;
|
|
||||||
/* no "break" because a '?' is followed by a regular tag */
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
/* find what tag we have */
|
/* 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;
|
strncmp(wps_bufptr, tag->name, strlen(tag->name)) != 0;
|
||||||
tag++) ;
|
tag++) ;
|
||||||
|
|
||||||
taglen = strlen(tag->name);
|
taglen = (tag->type != WPS_TOKEN_UNKNOWN) ? strlen(tag->name) : 2;
|
||||||
skip += taglen;
|
|
||||||
token->type = tag->type;
|
token->type = tag->type;
|
||||||
wps_data->sublines[wps_data->num_sublines].line_type |= tag->refresh_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;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
skip += taglen;
|
||||||
return skip;
|
return skip;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -657,6 +639,7 @@ static bool wps_parse(struct wps_data *data, const char *wps_bufptr)
|
||||||
|
|
||||||
char *current_string = data->string_buffer;
|
char *current_string = data->string_buffer;
|
||||||
int stringbuf_used = 0;
|
int stringbuf_used = 0;
|
||||||
|
level = -1;
|
||||||
|
|
||||||
while(*wps_bufptr && data->num_tokens < WPS_MAX_TOKENS - 1
|
while(*wps_bufptr && data->num_tokens < WPS_MAX_TOKENS - 1
|
||||||
&& data->num_lines < WPS_MAX_LINES)
|
&& 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 */
|
/* Alternating sublines separator */
|
||||||
case ';':
|
case ';':
|
||||||
if (level >= 0)
|
if (level >= 0) /* there are unclosed conditionals */
|
||||||
close_conditionals(data, level + 1);
|
return false;
|
||||||
|
|
||||||
if (data->num_sublines+1 < WPS_MAX_SUBLINES)
|
if (data->num_sublines+1 < WPS_MAX_SUBLINES)
|
||||||
wps_start_new_subline(data);
|
wps_start_new_subline(data);
|
||||||
|
|
@ -683,22 +666,32 @@ static bool wps_parse(struct wps_data *data, const char *wps_bufptr)
|
||||||
|
|
||||||
/* Conditional list start */
|
/* Conditional list start */
|
||||||
case '<':
|
case '<':
|
||||||
|
if (data->tokens[data->num_tokens-2].type != WPS_TOKEN_CONDITIONAL)
|
||||||
|
return false;
|
||||||
|
|
||||||
data->tokens[data->num_tokens].type = WPS_TOKEN_CONDITIONAL_START;
|
data->tokens[data->num_tokens].type = WPS_TOKEN_CONDITIONAL_START;
|
||||||
lastcond[level] = data->num_tokens++;
|
lastcond[level] = data->num_tokens++;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* Conditional list end */
|
/* Conditional list end */
|
||||||
case '>':
|
case '>':
|
||||||
if (level < 0) /* not in a conditional, ignore the char */
|
if (level < 0) /* not in a conditional, invalid char */
|
||||||
break;
|
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;
|
break;
|
||||||
|
|
||||||
/* Conditional list option */
|
/* Conditional list option */
|
||||||
case '|':
|
case '|':
|
||||||
if (level < 0) /* not in a conditional, ignore the char */
|
if (level < 0) /* not in a conditional, invalid char */
|
||||||
break;
|
return false;
|
||||||
|
|
||||||
data->tokens[data->num_tokens].type = WPS_TOKEN_CONDITIONAL_OPTION;
|
data->tokens[data->num_tokens].type = WPS_TOKEN_CONDITIONAL_OPTION;
|
||||||
if (lastcond[level])
|
if (lastcond[level])
|
||||||
|
|
@ -711,16 +704,16 @@ static bool wps_parse(struct wps_data *data, const char *wps_bufptr)
|
||||||
|
|
||||||
/* Comment */
|
/* Comment */
|
||||||
case '#':
|
case '#':
|
||||||
if (level >= 0)
|
if (level >= 0) /* there are unclosed conditionals */
|
||||||
close_conditionals(data, level + 1);
|
return false;
|
||||||
|
|
||||||
wps_bufptr += skip_end_of_line(wps_bufptr);
|
wps_bufptr += skip_end_of_line(wps_bufptr);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* End of this line */
|
/* End of this line */
|
||||||
case '\n':
|
case '\n':
|
||||||
if (level >= 0)
|
if (level >= 0) /* there are unclosed conditionals */
|
||||||
close_conditionals(data, level + 1);
|
return false;
|
||||||
|
|
||||||
wps_start_new_subline(data);
|
wps_start_new_subline(data);
|
||||||
data->num_lines++; /* Start a new line */
|
data->num_lines++; /* Start a new line */
|
||||||
|
|
@ -979,7 +972,11 @@ bool wps_data_load(struct wps_data *wps_data,
|
||||||
|
|
||||||
/* parse the WPS source */
|
/* parse the WPS source */
|
||||||
if (!wps_parse(wps_data, wps_buffer))
|
if (!wps_parse(wps_data, wps_buffer))
|
||||||
|
{
|
||||||
|
DEBUGF("Failed parsing of %s\n", buf);
|
||||||
|
wps_reset(wps_data);
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
wps_data->wps_loaded = true;
|
wps_data->wps_loaded = true;
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue