summaryrefslogtreecommitdiffstats
path: root/apps
diff options
context:
space:
mode:
authorNicolas Pennequin <nicolas.pennequin@free.fr>2007-04-15 02:59:34 +0000
committerNicolas Pennequin <nicolas.pennequin@free.fr>2007-04-15 02:59:34 +0000
commit2e1169bddaa424ae5eef36e2ec12e2a3cb0adc68 (patch)
tree6967092524e64d2365034073efef820b41d31a2d /apps
parentac946416060c19eb6cfe9da3d1885baee329df30 (diff)
downloadrockbox-2e1169bddaa424ae5eef36e2ec12e2a3cb0adc68.tar.gz
rockbox-2e1169bddaa424ae5eef36e2ec12e2a3cb0adc68.zip
* Make the WPS parser close open conditionals on new sublines and comments as well as new lines.
* Make the displaying code check for invalid conditional constructs in order to avoid some rare cases of infinite looping. * Make the WPS parser check that it doesn't read more strings than it can. * Increase the string buffer size (from 512 to 1024, to accomodate the TextBox WPS which uses a lot of unicode characters). git-svn-id: svn://svn.rockbox.org/rockbox/trunk@13162 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps')
-rw-r--r--apps/gui/gwps-common.c8
-rw-r--r--apps/gui/gwps.h2
-rw-r--r--apps/gui/wps_debug.c13
-rw-r--r--apps/gui/wps_parser.c64
4 files changed, 55 insertions, 32 deletions
diff --git a/apps/gui/gwps-common.c b/apps/gui/gwps-common.c
index 6c58c1d666..b4a2cf9596 100644
--- a/apps/gui/gwps-common.c
+++ b/apps/gui/gwps-common.c
@@ -1279,9 +1279,9 @@ static int find_conditional_end(struct wps_data *data, int index)
}
int ret = index;
- do
+ while (data->tokens[ret].value.i != 0
+ && data->tokens[data->tokens[ret].value.i].type != WPS_TOKEN_CONDITIONAL_END)
ret = data->tokens[ret].value.i;
- while (data->tokens[ret].type != WPS_TOKEN_CONDITIONAL_END);
/* ret now is the index to the end token for the conditional. */
return ret;
@@ -1307,6 +1307,10 @@ static int evaluate_conditional(struct gui_wps *gwps, int cond_index)
&& 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. */
if (num_options < 2)
num_options = 2;
diff --git a/apps/gui/gwps.h b/apps/gui/gwps.h
index 7d20bc94cf..801a37902e 100644
--- a/apps/gui/gwps.h
+++ b/apps/gui/gwps.h
@@ -76,7 +76,7 @@ struct align_pos {
#define WPS_MAX_SUBLINES (WPS_MAX_LINES*3)
#define WPS_MAX_TOKENS 1024
#define WPS_MAX_STRINGS 128
-#define STRING_BUFFER_SIZE 512
+#define STRING_BUFFER_SIZE 1024
#define WPS_MAX_COND_LEVEL 10
#else
diff --git a/apps/gui/wps_debug.c b/apps/gui/wps_debug.c
index 96f3e57038..e7d3f4592a 100644
--- a/apps/gui/wps_debug.c
+++ b/apps/gui/wps_debug.c
@@ -398,13 +398,16 @@ void print_line_info(struct wps_data *data)
void print_wps_strings(struct wps_data *data)
{
DEBUGF("Strings:\n");
- int i, len = 0;
- for (i=0; i < data->num_strings; i++)
+ int i, len = 0, buf_used = 0;
+ for (i = 0; i < data->num_strings; i++)
{
len += strlen(data->strings[i]);
- DEBUGF("%2d: '%s'\n", i, data->strings[i]);
+ buf_used += strlen(data->strings[i]) + 1;
+ DEBUGF("%2d: (%2d) '%s'\n", i, strlen(data->strings[i]), data->strings[i]);
}
- DEBUGF("Total length: %d\n", len);
+ DEBUGF("\n");
+ DEBUGF("Total string length: %d\n", len);
+ DEBUGF("String buffer used: %d out of %d bytes\n", buf_used, STRING_BUFFER_SIZE);
DEBUGF("\n");
}
@@ -413,7 +416,7 @@ void print_img_cond_indexes(struct wps_data *data)
{
DEBUGF("Image conditional indexes:\n");
int i;
- for (i=0; i < MAX_IMAGES; i++)
+ for (i = 0; i < MAX_IMAGES; i++)
{
if (data->img[i].cond_index)
DEBUGF("%2d: %d\n", i, data->img[i].cond_index);
diff --git a/apps/gui/wps_parser.c b/apps/gui/wps_parser.c
index e72079ce71..2c7a000367 100644
--- a/apps/gui/wps_parser.c
+++ b/apps/gui/wps_parser.c
@@ -270,12 +270,29 @@ static int skip_end_of_line(const char *wps_bufptr)
}
/* Starts a new subline in the current line during parsing */
-static void wps_start_new_subline(struct wps_data *data) {
+static void wps_start_new_subline(struct wps_data *data)
+{
data->num_sublines++;
data->sublines[data->num_sublines].first_token_idx = data->num_tokens;
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,
@@ -638,6 +655,7 @@ static bool wps_parse(struct wps_data *data, const char *wps_bufptr)
return false;
char *current_string = data->string_buffer;
+ int stringbuf_used = 0;
while(*wps_bufptr && data->num_tokens < WPS_MAX_TOKENS - 1
&& data->num_lines < WPS_MAX_LINES)
@@ -652,6 +670,9 @@ 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 (data->num_sublines+1 < WPS_MAX_SUBLINES)
wps_start_new_subline(data);
else
@@ -670,17 +691,7 @@ static bool wps_parse(struct wps_data *data, const char *wps_bufptr)
if (level < 0) /* not in a conditional, ignore the char */
break;
-condlistend: /* close a conditional. sometimes we want to close them even when
- we don't have a closing token, e.g. at the end of a line. */
-
- 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--;
+ close_conditionals(data, 1);
break;
/* Conditional list option */
@@ -699,19 +710,17 @@ condlistend: /* close a conditional. sometimes we want to close them even when
/* Comment */
case '#':
+ if (level >= 0)
+ close_conditionals(data, level + 1);
+
wps_bufptr += skip_end_of_line(wps_bufptr);
break;
/* End of this line */
case '\n':
if (level >= 0)
- {
- /* We have unclosed conditionals, so we
- close them before adding the EOL token */
- wps_bufptr--;
- goto condlistend;
- break;
- }
+ close_conditionals(data, level + 1);
+
wps_start_new_subline(data);
data->num_lines++; /* Start a new line */
@@ -726,29 +735,36 @@ condlistend: /* close a conditional. sometimes we want to close them even when
/* String */
default:
- if (data->num_strings < WPS_MAX_STRINGS)
+ if (data->num_strings < WPS_MAX_STRINGS
+ && stringbuf_used < STRING_BUFFER_SIZE - 1)
{
data->tokens[data->num_tokens].type = WPS_TOKEN_STRING;
data->strings[data->num_strings] = current_string;
- data->tokens[data->num_tokens].value.i = data->num_strings++;
+ data->tokens[data->num_tokens].value.i = data->num_strings;
data->num_tokens++;
/* Copy the first byte */
*current_string++ = *(wps_bufptr - 1);
+ stringbuf_used++;
- /* continue until we hit something that ends the string */
+ /* continue until we hit something that ends the string
+ or we run out of memory */
while(wps_bufptr && *wps_bufptr != '#' &&
*wps_bufptr != '%' && *wps_bufptr != ';' &&
*wps_bufptr != '<' && *wps_bufptr != '>' &&
- *wps_bufptr != '|' && *wps_bufptr != '\n')
+ *wps_bufptr != '|' && *wps_bufptr != '\n' &&
+ stringbuf_used < STRING_BUFFER_SIZE - 1)
{
*current_string++ = *wps_bufptr++;
+ stringbuf_used++;
}
/* null terminate the string */
*current_string++ = '\0';
- }
+ stringbuf_used++;
+ data->num_strings++;
+ }
break;
}
}