summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicolas Pennequin <nicolas.pennequin@free.fr>2008-07-12 15:12:09 +0000
committerNicolas Pennequin <nicolas.pennequin@free.fr>2008-07-12 15:12:09 +0000
commitae055017169f699f262606fd307e836d456d2535 (patch)
tree962ca43faf2829da6629496cfcd3782f3ce9fd8a
parent70029587ca0a7a2c0ffdbc48145c369385dfc803 (diff)
downloadrockbox-ae055017169f699f262606fd307e836d456d2535.tar.gz
rockbox-ae055017169f699f262606fd307e836d456d2535.zip
Introduce a new WPS parsing error case: limits exceeded. It includes the cases when there are too many tokens, lines, sublines, viewports, strings, characters or conditional levels. This prevents the parser from failing silently or going on, as it used to do in those cases. Thanks to fml (Alexander Levin) for mentioning this issue.
I also changed the error types from #defines to an enum, for cleanliness. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@18015 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--apps/gui/gwps.h9
-rw-r--r--apps/gui/wps_debug.c16
-rw-r--r--apps/gui/wps_parser.c69
3 files changed, 53 insertions, 41 deletions
diff --git a/apps/gui/gwps.h b/apps/gui/gwps.h
index 69a84f915b..99bf701a7d 100644
--- a/apps/gui/gwps.h
+++ b/apps/gui/gwps.h
@@ -126,6 +126,15 @@ struct align_pos {
126 (1/HZ sec, or 100ths of sec) */ 126 (1/HZ sec, or 100ths of sec) */
127#define SUBLINE_RESET -1 127#define SUBLINE_RESET -1
128 128
129enum wps_parse_error {
130 PARSE_OK,
131 PARSE_FAIL_UNCLOSED_COND,
132 PARSE_FAIL_INVALID_CHAR,
133 PARSE_FAIL_COND_SYNTAX_ERROR,
134 PARSE_FAIL_COND_INVALID_PARAM,
135 PARSE_FAIL_LIMITS_EXCEEDED,
136};
137
129enum wps_token_type { 138enum wps_token_type {
130 WPS_NO_TOKEN, /* for WPS tags we don't want to save as tokens */ 139 WPS_NO_TOKEN, /* for WPS tags we don't want to save as tokens */
131 WPS_TOKEN_UNKNOWN, 140 WPS_TOKEN_UNKNOWN,
diff --git a/apps/gui/wps_debug.c b/apps/gui/wps_debug.c
index 2295b4db6e..4e6af388ac 100644
--- a/apps/gui/wps_debug.c
+++ b/apps/gui/wps_debug.c
@@ -30,11 +30,6 @@
30#include "debug.h" 30#include "debug.h"
31#endif 31#endif
32 32
33#define PARSE_FAIL_UNCLOSED_COND 1
34#define PARSE_FAIL_INVALID_CHAR 2
35#define PARSE_FAIL_COND_SYNTAX_ERROR 3
36#define PARSE_FAIL_COND_INVALID_PARAM 4
37
38#if defined(SIMULATOR) || defined(__PCTOOL__) 33#if defined(SIMULATOR) || defined(__PCTOOL__)
39extern bool debug_wps; 34extern bool debug_wps;
40extern int wps_verbose_level; 35extern int wps_verbose_level;
@@ -574,7 +569,7 @@ static void print_wps_strings(struct wps_data *data)
574} 569}
575#endif 570#endif
576 571
577void print_debug_info(struct wps_data *data, int fail, int line) 572void print_debug_info(struct wps_data *data, enum wps_parse_error fail, int line)
578{ 573{
579#if defined(SIMULATOR) || defined(__PCTOOL__) 574#if defined(SIMULATOR) || defined(__PCTOOL__)
580 if (debug_wps && wps_verbose_level) 575 if (debug_wps && wps_verbose_level)
@@ -590,13 +585,16 @@ void print_debug_info(struct wps_data *data, int fail, int line)
590 WPS_MAX_TOKENS - 1); 585 WPS_MAX_TOKENS - 1);
591 } 586 }
592 587
593 if (fail) 588 if (fail != PARSE_OK)
594 { 589 {
595 char buf[64]; 590 char buf[64];
596 591
597 DEBUGF("Failed parsing on line %d : ", line); 592 DEBUGF("Failed parsing on line %d : ", line);
598 switch (fail) 593 switch (fail)
599 { 594 {
595 case PARSE_OK:
596 break;
597
600 case PARSE_FAIL_UNCLOSED_COND: 598 case PARSE_FAIL_UNCLOSED_COND:
601 DEBUGF("Unclosed conditional"); 599 DEBUGF("Unclosed conditional");
602 break; 600 break;
@@ -624,6 +622,10 @@ void print_debug_info(struct wps_data *data, int fail, int line)
624 buf, sizeof(buf)) 622 buf, sizeof(buf))
625 ); 623 );
626 break; 624 break;
625
626 case PARSE_FAIL_LIMITS_EXCEEDED:
627 DEBUGF("Limits exceeded");
628 break;
627 } 629 }
628 DEBUGF("\n"); 630 DEBUGF("\n");
629 } 631 }
diff --git a/apps/gui/wps_parser.c b/apps/gui/wps_parser.c
index 163bf84917..88a237cb0f 100644
--- a/apps/gui/wps_parser.c
+++ b/apps/gui/wps_parser.c
@@ -59,11 +59,6 @@
59 59
60#define WPS_ERROR_INVALID_PARAM -1 60#define WPS_ERROR_INVALID_PARAM -1
61 61
62#define PARSE_FAIL_UNCLOSED_COND 1
63#define PARSE_FAIL_INVALID_CHAR 2
64#define PARSE_FAIL_COND_SYNTAX_ERROR 3
65#define PARSE_FAIL_COND_INVALID_PARAM 4
66
67/* level of current conditional. 62/* level of current conditional.
68 -1 means we're not in a conditional. */ 63 -1 means we're not in a conditional. */
69static int level = -1; 64static int level = -1;
@@ -1186,7 +1181,7 @@ static bool wps_parse(struct wps_data *data, const char *wps_bufptr)
1186 1181
1187 char *stringbuf = data->string_buffer; 1182 char *stringbuf = data->string_buffer;
1188 int stringbuf_used = 0; 1183 int stringbuf_used = 0;
1189 int fail = 0; 1184 enum wps_parse_error fail = PARSE_OK;
1190 int ret; 1185 int ret;
1191 line = 1; 1186 line = 1;
1192 level = -1; 1187 level = -1;
@@ -1205,6 +1200,11 @@ static bool wps_parse(struct wps_data *data, const char *wps_bufptr)
1205 fail = PARSE_FAIL_COND_INVALID_PARAM; 1200 fail = PARSE_FAIL_COND_INVALID_PARAM;
1206 break; 1201 break;
1207 } 1202 }
1203 else if (level >= WPS_MAX_COND_LEVEL - 1)
1204 {
1205 fail = PARSE_FAIL_LIMITS_EXCEEDED;
1206 break;
1207 }
1208 wps_bufptr += ret; 1208 wps_bufptr += ret;
1209 break; 1209 break;
1210 1210
@@ -1219,7 +1219,7 @@ static bool wps_parse(struct wps_data *data, const char *wps_bufptr)
1219 if (data->num_sublines+1 < WPS_MAX_SUBLINES) 1219 if (data->num_sublines+1 < WPS_MAX_SUBLINES)
1220 wps_start_new_subline(data); 1220 wps_start_new_subline(data);
1221 else 1221 else
1222 wps_bufptr += skip_end_of_line(wps_bufptr); 1222 fail = PARSE_FAIL_LIMITS_EXCEEDED;
1223 1223
1224 break; 1224 break;
1225 1225
@@ -1343,38 +1343,35 @@ static bool wps_parse(struct wps_data *data, const char *wps_bufptr)
1343 /* If a matching string is found, found is true and i is 1343 /* If a matching string is found, found is true and i is
1344 the index of the string. If not, found is false */ 1344 the index of the string. If not, found is false */
1345 1345
1346 /* If it's NOT a duplicate, do nothing if we already have 1346 if (!found)
1347 too many unique strings */
1348 if (found ||
1349 (stringbuf_used < STRING_BUFFER_SIZE - 1 &&
1350 data->num_strings < WPS_MAX_STRINGS))
1351 { 1347 {
1352 if (!found) 1348 /* new string */
1353 {
1354 /* new string */
1355
1356 /* truncate? */
1357 if (stringbuf_used + len > STRING_BUFFER_SIZE - 1)
1358 len = STRING_BUFFER_SIZE - stringbuf_used - 1;
1359
1360 strncpy(stringbuf, string_start, len);
1361 *(stringbuf + len) = '\0';
1362 1349
1363 data->strings[data->num_strings] = stringbuf; 1350 if (stringbuf_used + len > STRING_BUFFER_SIZE - 1
1364 stringbuf += len + 1; 1351 || data->num_strings >= WPS_MAX_STRINGS)
1365 stringbuf_used += len + 1;
1366 data->tokens[data->num_tokens].value.i =
1367 data->num_strings;
1368 data->num_strings++;
1369 }
1370 else
1371 { 1352 {
1372 /* another ocurrence of an existing string */ 1353 /* too many strings or characters */
1373 data->tokens[data->num_tokens].value.i = i; 1354 fail = PARSE_FAIL_LIMITS_EXCEEDED;
1355 break;
1374 } 1356 }
1375 data->tokens[data->num_tokens].type = WPS_TOKEN_STRING; 1357
1376 data->num_tokens++; 1358 strncpy(stringbuf, string_start, len);
1359 *(stringbuf + len) = '\0';
1360
1361 data->strings[data->num_strings] = stringbuf;
1362 stringbuf += len + 1;
1363 stringbuf_used += len + 1;
1364 data->tokens[data->num_tokens].value.i =
1365 data->num_strings;
1366 data->num_strings++;
1377 } 1367 }
1368 else
1369 {
1370 /* another occurrence of an existing string */
1371 data->tokens[data->num_tokens].value.i = i;
1372 }
1373 data->tokens[data->num_tokens].type = WPS_TOKEN_STRING;
1374 data->num_tokens++;
1378 } 1375 }
1379 break; 1376 break;
1380 } 1377 }
@@ -1382,6 +1379,10 @@ static bool wps_parse(struct wps_data *data, const char *wps_bufptr)
1382 1379
1383 if (!fail && level >= 0) /* there are unclosed conditionals */ 1380 if (!fail && level >= 0) /* there are unclosed conditionals */
1384 fail = PARSE_FAIL_UNCLOSED_COND; 1381 fail = PARSE_FAIL_UNCLOSED_COND;
1382
1383 if (*wps_bufptr && !fail)
1384 /* one of the limits of the while loop was exceeded */
1385 fail = PARSE_FAIL_LIMITS_EXCEEDED;
1385 1386
1386 data->viewports[data->num_viewports].last_line = data->num_lines - 1; 1387 data->viewports[data->num_viewports].last_line = data->num_lines - 1;
1387 1388