summaryrefslogtreecommitdiff
path: root/apps
diff options
context:
space:
mode:
authorNicolas Pennequin <nicolas.pennequin@free.fr>2007-04-21 19:31:46 +0000
committerNicolas Pennequin <nicolas.pennequin@free.fr>2007-04-21 19:31:46 +0000
commit814d402d4c9c011ee7e357e74cca6a64176a33d8 (patch)
tree69f55addc2e6e88441cd9a906ae3b207e461c29a /apps
parenteb85f14f9549b328cdd76c93ecdf6862a5d0b341 (diff)
downloadrockbox-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.c24
-rw-r--r--apps/gui/wps_parser.c65
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*/
1276static int find_conditional_end(struct wps_data *data, int index) 1276static 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
281static 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
299static int parse_statusbar_enable(const char *wps_bufptr, 283static 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