diff options
author | Nicolas Pennequin <nicolas.pennequin@free.fr> | 2008-07-12 15:12:09 +0000 |
---|---|---|
committer | Nicolas Pennequin <nicolas.pennequin@free.fr> | 2008-07-12 15:12:09 +0000 |
commit | ae055017169f699f262606fd307e836d456d2535 (patch) | |
tree | 962ca43faf2829da6629496cfcd3782f3ce9fd8a | |
parent | 70029587ca0a7a2c0ffdbc48145c369385dfc803 (diff) | |
download | rockbox-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.h | 9 | ||||
-rw-r--r-- | apps/gui/wps_debug.c | 16 | ||||
-rw-r--r-- | apps/gui/wps_parser.c | 69 |
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 | ||
129 | enum 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 | |||
129 | enum wps_token_type { | 138 | enum 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__) |
39 | extern bool debug_wps; | 34 | extern bool debug_wps; |
40 | extern int wps_verbose_level; | 35 | extern 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 | ||
577 | void print_debug_info(struct wps_data *data, int fail, int line) | 572 | void 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. */ |
69 | static int level = -1; | 64 | static 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 | ||