From 78a11cf648442816c346cac9a756b782c918067b Mon Sep 17 00:00:00 2001 From: Jonathan Gordon Date: Fri, 24 Dec 2010 07:58:26 +0000 Subject: Fix FS#11829 - %?xx<....> Crashes on targets where the %xx feature tag isnt avilable. rather hacky fix though better than crashing. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@28890 a1c6a512-1295-4272-9138-f99709370657 --- lib/skin_parser/skin_parser.c | 72 +++++++++++++++++++++++++++---------------- 1 file changed, 45 insertions(+), 27 deletions(-) diff --git a/lib/skin_parser/skin_parser.c b/lib/skin_parser/skin_parser.c index 80f5f61699..e9f0bf8b47 100644 --- a/lib/skin_parser/skin_parser.c +++ b/lib/skin_parser/skin_parser.c @@ -969,37 +969,55 @@ static int skin_parse_conditional(struct skin_element* element, const char** doc cursor = bookmark; #endif /* Parsing the children */ - element->children = skin_alloc_children(children); - if (!element->children) - return 0; - element->children_count = children; - - for(i = 0; i < children; i++) + + /* Feature tags could end up having 0 children which breaks + * the render in dangerous ways. Minor hack, but insert an empty + * child. (e.g %?xx when xx isnt available ) */ + + if (children == 0) { - element->children[i] = skin_parse_code_as_arg(&cursor); - if (element->children[i] == NULL) - return 0; - skip_whitespace(&cursor); + const char* emptyline= ""; + children = 1; + element->children = skin_alloc_children(children); + if (!element->children) + return 0; + element->children_count = children; + element->children[0] = skin_parse_code_as_arg(&emptyline); + } + else + { + element->children = skin_alloc_children(children); + if (!element->children) + return 0; + element->children_count = children; + + for(i = 0; i < children; i++) + { + element->children[i] = skin_parse_code_as_arg(&cursor); + if (element->children[i] == NULL) + return 0; + skip_whitespace(&cursor); #ifdef ROCKBOX - if ((element->tag->flags&FEATURE_TAG) && feature_available) - cursor = conditional_end; + if ((element->tag->flags&FEATURE_TAG) && feature_available) + cursor = conditional_end; #endif - if(i < children - 1 && *cursor != ENUMLISTSEPARATESYM) - { - skin_error(SEPARATOR_EXPECTED, cursor); - return 0; - } - else if(i == children - 1 && *cursor != ENUMLISTCLOSESYM) - { - skin_error(CLOSE_EXPECTED, cursor); - return 0; - } - else - { - cursor++; - } - } + if(i < children - 1 && *cursor != ENUMLISTSEPARATESYM) + { + skin_error(SEPARATOR_EXPECTED, cursor); + return 0; + } + else if(i == children - 1 && *cursor != ENUMLISTCLOSESYM) + { + skin_error(CLOSE_EXPECTED, cursor); + return 0; + } + else + { + cursor++; + } + } + } *document = cursor; return 1; -- cgit v1.2.3