diff options
author | Nicolas Pennequin <nicolas.pennequin@free.fr> | 2007-04-21 19:31:46 +0000 |
---|---|---|
committer | Nicolas Pennequin <nicolas.pennequin@free.fr> | 2007-04-21 19:31:46 +0000 |
commit | 814d402d4c9c011ee7e357e74cca6a64176a33d8 (patch) | |
tree | 69f55addc2e6e88441cd9a906ae3b207e461c29a /apps | |
parent | eb85f14f9549b328cdd76c93ecdf6862a5d0b341 (diff) | |
download | rockbox-814d402d4c9c011ee7e357e74cca6a64176a33d8.tar.gz rockbox-814d402d4c9c011ee7e357e74cca6a64176a33d8.zip |
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
Diffstat (limited to 'apps')
-rw-r--r-- | apps/gui/gwps-common.c | 24 | ||||
-rw-r--r-- | apps/gui/wps_parser.c | 65 |
2 files changed, 33 insertions, 56 deletions
diff --git a/apps/gui/gwps-common.c b/apps/gui/gwps-common.c index d6576a2b3c..8022209189 100644 --- a/apps/gui/gwps-common.c +++ b/apps/gui/gwps-common.c | |||
@@ -1275,16 +1275,6 @@ static char *get_token_value(struct gui_wps *gwps, | |||
1275 | */ | 1275 | */ |
1276 | static int find_conditional_end(struct wps_data *data, int index) | 1276 | static int find_conditional_end(struct wps_data *data, int index) |
1277 | { | 1277 | { |
1278 | int type = data->tokens[index].type; | ||
1279 | |||
1280 | if (type != WPS_TOKEN_CONDITIONAL_START | ||
1281 | && type != WPS_TOKEN_CONDITIONAL_OPTION) | ||
1282 | { | ||
1283 | /* this function should only be used with "index" pointing to a | ||
1284 | WPS_TOKEN_CONDITIONAL_START or a WPS_TOKEN_CONDITIONAL_OPTION */ | ||
1285 | return index + 1; | ||
1286 | } | ||
1287 | |||
1288 | int ret = index; | 1278 | int ret = index; |
1289 | while (data->tokens[ret].type != WPS_TOKEN_CONDITIONAL_END) | 1279 | while (data->tokens[ret].type != WPS_TOKEN_CONDITIONAL_END) |
1290 | ret = data->tokens[ret].value.i; | 1280 | ret = data->tokens[ret].value.i; |
@@ -1304,18 +1294,8 @@ static int evaluate_conditional(struct gui_wps *gwps, int cond_index) | |||
1304 | struct wps_data *data = gwps->data; | 1294 | struct wps_data *data = gwps->data; |
1305 | 1295 | ||
1306 | int ret, i; | 1296 | int ret, i; |
1307 | int num_options = data->tokens[cond_index].value.i; | ||
1308 | char result[128], *value; | 1297 | char result[128], *value; |
1309 | int cond_start = cond_index; | 1298 | int num_options = data->tokens[cond_index].value.i; |
1310 | |||
1311 | /* find the index of the conditional start token */ | ||
1312 | while (data->tokens[cond_start].type != WPS_TOKEN_CONDITIONAL_START | ||
1313 | && cond_start < data->num_tokens) | ||
1314 | cond_start++; | ||
1315 | |||
1316 | /* if the number of options is 0, the conditional is invalid */ | ||
1317 | if (num_options == 0) | ||
1318 | return cond_start; | ||
1319 | 1299 | ||
1320 | /* treat ?xx<true> constructs as if they had 2 options. */ | 1300 | /* treat ?xx<true> constructs as if they had 2 options. */ |
1321 | if (num_options < 2) | 1301 | if (num_options < 2) |
@@ -1334,7 +1314,7 @@ static int evaluate_conditional(struct gui_wps *gwps, int cond_index) | |||
1334 | intval = num_options; | 1314 | intval = num_options; |
1335 | 1315 | ||
1336 | /* skip to the right enum case */ | 1316 | /* skip to the right enum case */ |
1337 | int next = cond_start; | 1317 | int next = cond_index + 2; |
1338 | for (i = 1; i < intval; i++) | 1318 | for (i = 1; i < intval; i++) |
1339 | { | 1319 | { |
1340 | next = data->tokens[next].value.i; | 1320 | next = data->tokens[next].value.i; |
diff --git a/apps/gui/wps_parser.c b/apps/gui/wps_parser.c index 5f1149968f..daf318bbcd 100644 --- a/apps/gui/wps_parser.c +++ b/apps/gui/wps_parser.c | |||
@@ -278,22 +278,6 @@ static void wps_start_new_subline(struct wps_data *data) | |||
278 | data->lines[data->num_lines].num_sublines++; | 278 | data->lines[data->num_lines].num_sublines++; |
279 | } | 279 | } |
280 | 280 | ||
281 | static void close_conditionals(struct wps_data *data, int n) | ||
282 | { | ||
283 | int i; | ||
284 | for (i = 0; i < n; i++) | ||
285 | { | ||
286 | data->tokens[data->num_tokens].type = WPS_TOKEN_CONDITIONAL_END; | ||
287 | if (lastcond[level]) | ||
288 | data->tokens[lastcond[level]].value.i = data->num_tokens; | ||
289 | |||
290 | lastcond[level] = 0; | ||
291 | data->num_tokens++; | ||
292 | data->tokens[condindex[level]].value.i = numoptions[level]; | ||
293 | level--; | ||
294 | } | ||
295 | } | ||
296 | |||
297 | #ifdef HAVE_LCD_BITMAP | 281 | #ifdef HAVE_LCD_BITMAP |
298 | 282 | ||
299 | static int parse_statusbar_enable(const char *wps_bufptr, | 283 | 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) | |||
600 | /* escaped characters */ | 584 | /* escaped characters */ |
601 | token->type = WPS_TOKEN_CHARACTER; | 585 | token->type = WPS_TOKEN_CHARACTER; |
602 | token->value.c = *wps_bufptr; | 586 | token->value.c = *wps_bufptr; |
587 | taglen = 1; | ||
603 | wps_data->num_tokens++; | 588 | wps_data->num_tokens++; |
604 | skip++; | ||
605 | break; | 589 | break; |
606 | 590 | ||
607 | case '?': | 591 | case '?': |
@@ -611,10 +595,8 @@ static int parse_token(const char *wps_bufptr, struct wps_data *wps_data) | |||
611 | condindex[level] = wps_data->num_tokens; | 595 | condindex[level] = wps_data->num_tokens; |
612 | numoptions[level] = 1; | 596 | numoptions[level] = 1; |
613 | wps_data->num_tokens++; | 597 | wps_data->num_tokens++; |
614 | token++; | 598 | taglen = 1 + parse_token(wps_bufptr + 1, wps_data); |
615 | wps_bufptr++; | 599 | break; |
616 | skip++; | ||
617 | /* no "break" because a '?' is followed by a regular tag */ | ||
618 | 600 | ||
619 | default: | 601 | default: |
620 | /* find what tag we have */ | 602 | /* find what tag we have */ |
@@ -622,8 +604,7 @@ static int parse_token(const char *wps_bufptr, struct wps_data *wps_data) | |||
622 | strncmp(wps_bufptr, tag->name, strlen(tag->name)) != 0; | 604 | strncmp(wps_bufptr, tag->name, strlen(tag->name)) != 0; |
623 | tag++) ; | 605 | tag++) ; |
624 | 606 | ||
625 | taglen = strlen(tag->name); | 607 | taglen = (tag->type != WPS_TOKEN_UNKNOWN) ? strlen(tag->name) : 2; |
626 | skip += taglen; | ||
627 | token->type = tag->type; | 608 | token->type = tag->type; |
628 | wps_data->sublines[wps_data->num_sublines].line_type |= tag->refresh_type; | 609 | wps_data->sublines[wps_data->num_sublines].line_type |= tag->refresh_type; |
629 | 610 | ||
@@ -643,6 +624,7 @@ static int parse_token(const char *wps_bufptr, struct wps_data *wps_data) | |||
643 | break; | 624 | break; |
644 | } | 625 | } |
645 | 626 | ||
627 | skip += taglen; | ||
646 | return skip; | 628 | return skip; |
647 | } | 629 | } |
648 | 630 | ||
@@ -657,6 +639,7 @@ static bool wps_parse(struct wps_data *data, const char *wps_bufptr) | |||
657 | 639 | ||
658 | char *current_string = data->string_buffer; | 640 | char *current_string = data->string_buffer; |
659 | int stringbuf_used = 0; | 641 | int stringbuf_used = 0; |
642 | level = -1; | ||
660 | 643 | ||
661 | while(*wps_bufptr && data->num_tokens < WPS_MAX_TOKENS - 1 | 644 | while(*wps_bufptr && data->num_tokens < WPS_MAX_TOKENS - 1 |
662 | && data->num_lines < WPS_MAX_LINES) | 645 | && data->num_lines < WPS_MAX_LINES) |
@@ -671,8 +654,8 @@ static bool wps_parse(struct wps_data *data, const char *wps_bufptr) | |||
671 | 654 | ||
672 | /* Alternating sublines separator */ | 655 | /* Alternating sublines separator */ |
673 | case ';': | 656 | case ';': |
674 | if (level >= 0) | 657 | if (level >= 0) /* there are unclosed conditionals */ |
675 | close_conditionals(data, level + 1); | 658 | return false; |
676 | 659 | ||
677 | if (data->num_sublines+1 < WPS_MAX_SUBLINES) | 660 | if (data->num_sublines+1 < WPS_MAX_SUBLINES) |
678 | wps_start_new_subline(data); | 661 | wps_start_new_subline(data); |
@@ -683,22 +666,32 @@ static bool wps_parse(struct wps_data *data, const char *wps_bufptr) | |||
683 | 666 | ||
684 | /* Conditional list start */ | 667 | /* Conditional list start */ |
685 | case '<': | 668 | case '<': |
669 | if (data->tokens[data->num_tokens-2].type != WPS_TOKEN_CONDITIONAL) | ||
670 | return false; | ||
671 | |||
686 | data->tokens[data->num_tokens].type = WPS_TOKEN_CONDITIONAL_START; | 672 | data->tokens[data->num_tokens].type = WPS_TOKEN_CONDITIONAL_START; |
687 | lastcond[level] = data->num_tokens++; | 673 | lastcond[level] = data->num_tokens++; |
688 | break; | 674 | break; |
689 | 675 | ||
690 | /* Conditional list end */ | 676 | /* Conditional list end */ |
691 | case '>': | 677 | case '>': |
692 | if (level < 0) /* not in a conditional, ignore the char */ | 678 | if (level < 0) /* not in a conditional, invalid char */ |
693 | break; | 679 | return false; |
680 | |||
681 | data->tokens[data->num_tokens].type = WPS_TOKEN_CONDITIONAL_END; | ||
682 | if (lastcond[level]) | ||
683 | data->tokens[lastcond[level]].value.i = data->num_tokens; | ||
694 | 684 | ||
695 | close_conditionals(data, 1); | 685 | lastcond[level] = 0; |
686 | data->num_tokens++; | ||
687 | data->tokens[condindex[level]].value.i = numoptions[level]; | ||
688 | level--; | ||
696 | break; | 689 | break; |
697 | 690 | ||
698 | /* Conditional list option */ | 691 | /* Conditional list option */ |
699 | case '|': | 692 | case '|': |
700 | if (level < 0) /* not in a conditional, ignore the char */ | 693 | if (level < 0) /* not in a conditional, invalid char */ |
701 | break; | 694 | return false; |
702 | 695 | ||
703 | data->tokens[data->num_tokens].type = WPS_TOKEN_CONDITIONAL_OPTION; | 696 | data->tokens[data->num_tokens].type = WPS_TOKEN_CONDITIONAL_OPTION; |
704 | if (lastcond[level]) | 697 | if (lastcond[level]) |
@@ -711,16 +704,16 @@ static bool wps_parse(struct wps_data *data, const char *wps_bufptr) | |||
711 | 704 | ||
712 | /* Comment */ | 705 | /* Comment */ |
713 | case '#': | 706 | case '#': |
714 | if (level >= 0) | 707 | if (level >= 0) /* there are unclosed conditionals */ |
715 | close_conditionals(data, level + 1); | 708 | return false; |
716 | 709 | ||
717 | wps_bufptr += skip_end_of_line(wps_bufptr); | 710 | wps_bufptr += skip_end_of_line(wps_bufptr); |
718 | break; | 711 | break; |
719 | 712 | ||
720 | /* End of this line */ | 713 | /* End of this line */ |
721 | case '\n': | 714 | case '\n': |
722 | if (level >= 0) | 715 | if (level >= 0) /* there are unclosed conditionals */ |
723 | close_conditionals(data, level + 1); | 716 | return false; |
724 | 717 | ||
725 | wps_start_new_subline(data); | 718 | wps_start_new_subline(data); |
726 | data->num_lines++; /* Start a new line */ | 719 | data->num_lines++; /* Start a new line */ |
@@ -979,7 +972,11 @@ bool wps_data_load(struct wps_data *wps_data, | |||
979 | 972 | ||
980 | /* parse the WPS source */ | 973 | /* parse the WPS source */ |
981 | if (!wps_parse(wps_data, wps_buffer)) | 974 | if (!wps_parse(wps_data, wps_buffer)) |
975 | { | ||
976 | DEBUGF("Failed parsing of %s\n", buf); | ||
977 | wps_reset(wps_data); | ||
982 | return false; | 978 | return false; |
979 | } | ||
983 | 980 | ||
984 | wps_data->wps_loaded = true; | 981 | wps_data->wps_loaded = true; |
985 | 982 | ||