Fix multiple potential null pointer dereferencess

GCC's optimizer thinks all of these _will_ fail at some point

Change-Id: I287eeb574162a5d3b3347654d25aa1f53e9f5563
This commit is contained in:
Solomon Peachy 2020-10-27 11:14:23 -04:00
parent 621e363e70
commit a605cdf700
8 changed files with 160 additions and 88 deletions

View file

@ -219,7 +219,9 @@ bool skinlist_draw(struct screen *display, struct gui_synclist *list)
{ {
int original_x, original_y; int original_x, original_y;
skin_viewport = SKINOFFSETTOPTR(get_skin_buffer(wps.data), viewport->data); skin_viewport = SKINOFFSETTOPTR(get_skin_buffer(wps.data), viewport->data);
char *viewport_label = SKINOFFSETTOPTR(get_skin_buffer(wps.data), skin_viewport->label); char *viewport_label = NULL;
if (skin_viewport)
viewport_label = SKINOFFSETTOPTR(get_skin_buffer(wps.data), skin_viewport->label);
if (viewport->children == 0 || !viewport_label || if (viewport->children == 0 || !viewport_label ||
(skin_viewport->label && strcmp(label, viewport_label)) (skin_viewport->label && strcmp(label, viewport_label))
) )
@ -254,13 +256,17 @@ bool skinlist_draw(struct screen *display, struct gui_synclist *list)
while (imglist) while (imglist)
{ {
struct wps_token *token = SKINOFFSETTOPTR(get_skin_buffer(wps.data), imglist->token); struct wps_token *token = SKINOFFSETTOPTR(get_skin_buffer(wps.data), imglist->token);
struct gui_img *img = SKINOFFSETTOPTR(get_skin_buffer(wps.data), token->value.data); struct gui_img *img = NULL;
img->display = -1; if (token)
img = SKINOFFSETTOPTR(get_skin_buffer(wps.data), token->value.data);
if (img)
img->display = -1;
imglist = SKINOFFSETTOPTR(get_skin_buffer(wps.data), imglist->next); imglist = SKINOFFSETTOPTR(get_skin_buffer(wps.data), imglist->next);
} }
struct skin_element** children = SKINOFFSETTOPTR(get_skin_buffer(wps.data), viewport->children); struct skin_element** children = SKINOFFSETTOPTR(get_skin_buffer(wps.data), viewport->children);
skin_render_viewport(SKINOFFSETTOPTR(get_skin_buffer(wps.data), (intptr_t)children[0]), if (children && *children)
&wps, skin_viewport, SKIN_REFRESH_ALL); skin_render_viewport(SKINOFFSETTOPTR(get_skin_buffer(wps.data), (intptr_t)children[0]),
&wps, skin_viewport, SKIN_REFRESH_ALL);
wps_display_images(&wps, &skin_viewport->vp); wps_display_images(&wps, &skin_viewport->vp);
/* force disableing scroll because it breaks later */ /* force disableing scroll because it breaks later */
if (!is_selected) if (!is_selected)
@ -278,4 +284,3 @@ bool skinlist_draw(struct screen *display, struct gui_synclist *list)
current_drawing_line = list->selected_item; current_drawing_line = list->selected_item;
return true; return true;
} }

View file

@ -390,16 +390,20 @@ void wps_display_images(struct gui_wps *gwps, struct viewport* vp)
while (list) while (list)
{ {
struct wps_token *token = SKINOFFSETTOPTR(get_skin_buffer(data), list->token); struct wps_token *token = SKINOFFSETTOPTR(get_skin_buffer(data), list->token);
struct gui_img *img = (struct gui_img*)SKINOFFSETTOPTR(get_skin_buffer(data), token->value.data); struct gui_img *img = NULL;
if (img->using_preloaded_icons && img->display >= 0) if (token)
{ img = (struct gui_img*)SKINOFFSETTOPTR(get_skin_buffer(data), token->value.data);
screen_put_icon(display, img->x, img->y, img->display); if (img) {
} if (img->using_preloaded_icons && img->display >= 0)
else if (img->loaded)
{
if (img->display >= 0)
{ {
wps_draw_image(gwps, img, img->display, vp); screen_put_icon(display, img->x, img->y, img->display);
}
else if (img->loaded)
{
if (img->display >= 0)
{
wps_draw_image(gwps, img, img->display, vp);
}
} }
} }
list = SKINOFFSETTOPTR(get_skin_buffer(data), list->next); list = SKINOFFSETTOPTR(get_skin_buffer(data), list->next);

View file

@ -183,13 +183,16 @@ void *skin_find_item(const char *label, enum skin_find_what what,
{ {
bool skip = false; bool skip = false;
struct wps_token *token = NULL; struct wps_token *token = NULL;
itemlabel = NULL;
if (!isvplist) if (!isvplist)
token = SKINOFFSETTOPTR(databuf, list.linkedlist->token); token = SKINOFFSETTOPTR(databuf, list.linkedlist->token);
switch (what) if (token)
switch (what)
{ {
case SKIN_FIND_UIVP: case SKIN_FIND_UIVP:
case SKIN_FIND_VP: case SKIN_FIND_VP:
ret = SKINOFFSETTOPTR(databuf, list.vplist->data); ret = SKINOFFSETTOPTR(databuf, list.vplist->data);
if (!ret) break;
if (((struct skin_viewport *)ret)->label == VP_DEFAULT_LABEL) if (((struct skin_viewport *)ret)->label == VP_DEFAULT_LABEL)
itemlabel = VP_DEFAULT_LABEL_STRING; itemlabel = VP_DEFAULT_LABEL_STRING;
else else
@ -199,10 +202,12 @@ void *skin_find_item(const char *label, enum skin_find_what what,
break; break;
case SKIN_FIND_IMAGE: case SKIN_FIND_IMAGE:
ret = SKINOFFSETTOPTR(databuf, token->value.data); ret = SKINOFFSETTOPTR(databuf, token->value.data);
if (!ret) break;
itemlabel = SKINOFFSETTOPTR(databuf, ((struct gui_img *)ret)->label); itemlabel = SKINOFFSETTOPTR(databuf, ((struct gui_img *)ret)->label);
break; break;
#ifdef HAVE_TOUCHSCREEN #ifdef HAVE_TOUCHSCREEN
case SKIN_FIND_TOUCHREGION: case SKIN_FIND_TOUCHREGION:
if (!ret) break;
ret = SKINOFFSETTOPTR(databuf, token->value.data); ret = SKINOFFSETTOPTR(databuf, token->value.data);
itemlabel = SKINOFFSETTOPTR(databuf, ((struct touchregion *)ret)->label); itemlabel = SKINOFFSETTOPTR(databuf, ((struct touchregion *)ret)->label);
break; break;
@ -210,6 +215,7 @@ void *skin_find_item(const char *label, enum skin_find_what what,
#ifdef HAVE_SKIN_VARIABLES #ifdef HAVE_SKIN_VARIABLES
case SKIN_VARIABLE: case SKIN_VARIABLE:
ret = SKINOFFSETTOPTR(databuf, token->value.data); ret = SKINOFFSETTOPTR(databuf, token->value.data);
if (!ret) break;
itemlabel = SKINOFFSETTOPTR(databuf, ((struct skin_var *)ret)->label); itemlabel = SKINOFFSETTOPTR(databuf, ((struct skin_var *)ret)->label);
break; break;
#endif #endif
@ -1708,23 +1714,30 @@ void skin_data_free_buflib_allocs(struct wps_data *wps_data)
{ {
if (wps_data->wps_loaded) if (wps_data->wps_loaded)
skin_buffer = get_skin_buffer(wps_data); skin_buffer = get_skin_buffer(wps_data);
if (!skin_buffer)
return;
#ifndef __PCTOOL__ #ifndef __PCTOOL__
struct skin_token_list *list = SKINOFFSETTOPTR(skin_buffer, wps_data->images); struct skin_token_list *list = SKINOFFSETTOPTR(skin_buffer, wps_data->images);
int *font_ids = SKINOFFSETTOPTR(skin_buffer, wps_data->font_ids); int *font_ids = SKINOFFSETTOPTR(skin_buffer, wps_data->font_ids);
while (list) while (list)
{ {
struct wps_token *token = SKINOFFSETTOPTR(skin_buffer, list->token); struct wps_token *token = SKINOFFSETTOPTR(skin_buffer, list->token);
struct gui_img *img = (struct gui_img*)SKINOFFSETTOPTR(skin_buffer, token->value.data); struct gui_img *img = NULL;
if (img->buflib_handle > 0) if (token)
img = (struct gui_img*)SKINOFFSETTOPTR(skin_buffer, token->value.data);
if (img && img->buflib_handle > 0)
{ {
struct skin_token_list *imglist = SKINOFFSETTOPTR(skin_buffer, list->next); struct skin_token_list *imglist = SKINOFFSETTOPTR(skin_buffer, list->next);
core_free(img->buflib_handle);
core_free(img->buflib_handle);
while (imglist) while (imglist)
{ {
struct wps_token *freetoken = SKINOFFSETTOPTR(skin_buffer, imglist->token); struct wps_token *freetoken = SKINOFFSETTOPTR(skin_buffer, imglist->token);
struct gui_img *freeimg = (struct gui_img*)SKINOFFSETTOPTR(skin_buffer, freetoken->value.data); struct gui_img *freeimg = NULL;
if (img->buflib_handle == freeimg->buflib_handle) if (freetoken)
freeimg = (struct gui_img*)SKINOFFSETTOPTR(skin_buffer, freetoken->value.data);
if (freeimg && img->buflib_handle == freeimg->buflib_handle)
freeimg->buflib_handle = -1; freeimg->buflib_handle = -1;
imglist = SKINOFFSETTOPTR(skin_buffer, imglist->next); imglist = SKINOFFSETTOPTR(skin_buffer, imglist->next);
} }
@ -1885,8 +1898,10 @@ static bool load_skin_bitmaps(struct wps_data *wps_data, char *bmpdir)
while (list) while (list)
{ {
struct wps_token *token = SKINOFFSETTOPTR(skin_buffer, list->token); struct wps_token *token = SKINOFFSETTOPTR(skin_buffer, list->token);
if (!token) goto skip;
struct gui_img *img = (struct gui_img*)SKINOFFSETTOPTR(skin_buffer, token->value.data); struct gui_img *img = (struct gui_img*)SKINOFFSETTOPTR(skin_buffer, token->value.data);
if (!img->loaded)
if (img && !img->loaded)
{ {
if (img->using_preloaded_icons) if (img->using_preloaded_icons)
{ {
@ -1901,20 +1916,22 @@ static bool load_skin_bitmaps(struct wps_data *wps_data, char *bmpdir)
handle = load_skin_bmp(wps_data, &img->bm, bmpdir); handle = load_skin_bmp(wps_data, &img->bm, bmpdir);
img->buflib_handle = handle; img->buflib_handle = handle;
img->loaded = img->buflib_handle >= 0; img->loaded = img->buflib_handle >= 0;
if (img->loaded) if (img->loaded)
{ {
struct skin_token_list *imglist = SKINOFFSETTOPTR(skin_buffer, list->next); struct skin_token_list *imglist = SKINOFFSETTOPTR(skin_buffer, list->next);
img->subimage_height = img->bm.height / img->num_subimages; img->subimage_height = img->bm.height / img->num_subimages;
while (imglist) while (imglist)
{ {
token = SKINOFFSETTOPTR(skin_buffer, imglist->token); token = SKINOFFSETTOPTR(skin_buffer, imglist->token);
img = (struct gui_img*)SKINOFFSETTOPTR(skin_buffer, token->value.data); if (token) {
if (!strcmp(path, img->bm.data)) img = (struct gui_img*)SKINOFFSETTOPTR(skin_buffer, token->value.data);
{ if (img && !strcmp(path, img->bm.data))
img->loaded = true; {
img->buflib_handle = handle; img->loaded = true;
img->subimage_height = img->bm.height / img->num_subimages; img->buflib_handle = handle;
img->subimage_height = img->bm.height / img->num_subimages;
}
} }
imglist = SKINOFFSETTOPTR(skin_buffer, imglist->next); imglist = SKINOFFSETTOPTR(skin_buffer, imglist->next);
} }
@ -1923,6 +1940,7 @@ static bool load_skin_bitmaps(struct wps_data *wps_data, char *bmpdir)
retval = false; retval = false;
} }
} }
skip:
list = SKINOFFSETTOPTR(skin_buffer, list->next); list = SKINOFFSETTOPTR(skin_buffer, list->next);
} }
@ -1947,6 +1965,7 @@ static bool skin_load_fonts(struct wps_data *data)
/* first, find the viewports that have a non-sys/ui-font font */ /* first, find the viewports that have a non-sys/ui-font font */
struct skin_viewport *skin_vp = struct skin_viewport *skin_vp =
SKINOFFSETTOPTR(skin_buffer, vp_list->data); SKINOFFSETTOPTR(skin_buffer, vp_list->data);
if (!skin_vp) continue;
struct viewport *vp = &skin_vp->vp; struct viewport *vp = &skin_vp->vp;
font_id = skin_vp->parsed_fontid; font_id = skin_vp->parsed_fontid;
@ -2507,9 +2526,10 @@ bool skin_data_load(enum screen_type screen, struct wps_data *wps_data,
while (regions) while (regions)
{ {
struct wps_token *token = SKINOFFSETTOPTR(skin_buffer, regions->token); struct wps_token *token = SKINOFFSETTOPTR(skin_buffer, regions->token);
struct touchregion *r = SKINOFFSETTOPTR(skin_buffer, token->value.data); struct touchregion *r = NULL;
if (token)
if (r->action != ACTION_TOUCH_SCROLLBAR && r = SKINOFFSETTOPTR(skin_buffer, token->value.data);
if (r && r->action != ACTION_TOUCH_SCROLLBAR &&
r->action != ACTION_TOUCH_VOLUME) r->action != ACTION_TOUCH_VOLUME)
{ {
user_touch_region_found = true; user_touch_region_found = true;

View file

@ -96,7 +96,7 @@ static bool do_non_text_tags(struct gui_wps *gwps, struct skin_draw_info *info,
struct skin_element *element, struct skin_viewport* skin_vp) struct skin_element *element, struct skin_viewport* skin_vp)
{ {
struct wps_token *token = (struct wps_token *)SKINOFFSETTOPTR(skin_buffer, element->data); struct wps_token *token = (struct wps_token *)SKINOFFSETTOPTR(skin_buffer, element->data);
if (!token) return false;
struct viewport *vp = &skin_vp->vp; struct viewport *vp = &skin_vp->vp;
struct wps_data *data = gwps->data; struct wps_data *data = gwps->data;
bool do_refresh = (element->tag->flags & info->refresh_type) > 0; bool do_refresh = (element->tag->flags & info->refresh_type) > 0;
@ -107,7 +107,9 @@ static bool do_non_text_tags(struct gui_wps *gwps, struct skin_draw_info *info,
case SKIN_TOKEN_VIEWPORT_FGCOLOUR: case SKIN_TOKEN_VIEWPORT_FGCOLOUR:
{ {
struct viewport_colour *col = SKINOFFSETTOPTR(skin_buffer, token->value.data); struct viewport_colour *col = SKINOFFSETTOPTR(skin_buffer, token->value.data);
if (!col) return false;
struct viewport *vp = SKINOFFSETTOPTR(skin_buffer, col->vp); struct viewport *vp = SKINOFFSETTOPTR(skin_buffer, col->vp);
if (!vp) return false;
vp->fg_pattern = col->colour; vp->fg_pattern = col->colour;
skin_vp->fgbg_changed = true; skin_vp->fgbg_changed = true;
} }
@ -115,7 +117,9 @@ static bool do_non_text_tags(struct gui_wps *gwps, struct skin_draw_info *info,
case SKIN_TOKEN_VIEWPORT_BGCOLOUR: case SKIN_TOKEN_VIEWPORT_BGCOLOUR:
{ {
struct viewport_colour *col = SKINOFFSETTOPTR(skin_buffer, token->value.data); struct viewport_colour *col = SKINOFFSETTOPTR(skin_buffer, token->value.data);
if (!col) return false;
struct viewport *vp = SKINOFFSETTOPTR(skin_buffer, col->vp); struct viewport *vp = SKINOFFSETTOPTR(skin_buffer, col->vp);
if (!vp) return false;
vp->bg_pattern = col->colour; vp->bg_pattern = col->colour;
skin_vp->fgbg_changed = true; skin_vp->fgbg_changed = true;
} }
@ -124,6 +128,7 @@ static bool do_non_text_tags(struct gui_wps *gwps, struct skin_draw_info *info,
{ {
struct line_desc *data = SKINOFFSETTOPTR(skin_buffer, token->value.data); struct line_desc *data = SKINOFFSETTOPTR(skin_buffer, token->value.data);
struct line_desc *linedes = &info->line_desc; struct line_desc *linedes = &info->line_desc;
if (!data || !linedes) return false;
/* gradient colors are handled with a separate tag /* gradient colors are handled with a separate tag
* (SKIN_TOKEN_VIEWPORT_GRADIENT_SETUP, see below). since it may * (SKIN_TOKEN_VIEWPORT_GRADIENT_SETUP, see below). since it may
* come before the text style tag color fields need to be preserved */ * come before the text style tag color fields need to be preserved */
@ -147,6 +152,7 @@ static bool do_non_text_tags(struct gui_wps *gwps, struct skin_draw_info *info,
{ {
struct gradient_config *cfg = SKINOFFSETTOPTR(skin_buffer, token->value.data); struct gradient_config *cfg = SKINOFFSETTOPTR(skin_buffer, token->value.data);
struct line_desc *linedes = &info->line_desc; struct line_desc *linedes = &info->line_desc;
if (!cfg || !linedes) return false;
linedes->text_color = cfg->text; linedes->text_color = cfg->text;
linedes->line_color = cfg->start; linedes->line_color = cfg->start;
linedes->line_end_color = cfg->end; linedes->line_end_color = cfg->end;
@ -162,17 +168,19 @@ static bool do_non_text_tags(struct gui_wps *gwps, struct skin_draw_info *info,
{ {
struct skin_viewport *skinvp = SKINOFFSETTOPTR(skin_buffer, viewport->data); struct skin_viewport *skinvp = SKINOFFSETTOPTR(skin_buffer, viewport->data);
char *vplabel = SKINOFFSETTOPTR(skin_buffer, skinvp->label); if (skinvp) {
if (skinvp->label == VP_DEFAULT_LABEL) char *vplabel = SKINOFFSETTOPTR(skin_buffer, skinvp->label);
vplabel = VP_DEFAULT_LABEL_STRING; if (skinvp->label == VP_DEFAULT_LABEL)
if (vplabel && !skinvp->is_infovp && vplabel = VP_DEFAULT_LABEL_STRING;
!strcmp(vplabel, label)) if (vplabel && !skinvp->is_infovp &&
{ !strcmp(vplabel, label))
if (skinvp->hidden_flags&VP_DRAW_HIDDEN)
{ {
temp |= VP_DRAW_WASHIDDEN; if (skinvp->hidden_flags&VP_DRAW_HIDDEN)
{
temp |= VP_DRAW_WASHIDDEN;
}
skinvp->hidden_flags = temp;
} }
skinvp->hidden_flags = temp;
} }
viewport = SKINOFFSETTOPTR(skin_buffer, viewport->next); viewport = SKINOFFSETTOPTR(skin_buffer, viewport->next);
} }
@ -195,12 +203,13 @@ static bool do_non_text_tags(struct gui_wps *gwps, struct skin_draw_info *info,
{ {
struct draw_rectangle *rect = struct draw_rectangle *rect =
SKINOFFSETTOPTR(skin_buffer, token->value.data); SKINOFFSETTOPTR(skin_buffer, token->value.data);
if (!rect) break;
#ifdef HAVE_LCD_COLOR #ifdef HAVE_LCD_COLOR
if (rect->start_colour != rect->end_colour && if (rect->start_colour != rect->end_colour &&
gwps->display->screen_type == SCREEN_MAIN) gwps->display->screen_type == SCREEN_MAIN)
{ {
gwps->display->gradient_fillrect(rect->x, rect->y, rect->width, gwps->display->gradient_fillrect(rect->x, rect->y, rect->width,
rect->height, rect->start_colour, rect->end_colour); rect->height, rect->start_colour, rect->end_colour);
} }
else else
#endif #endif
@ -210,7 +219,7 @@ static bool do_non_text_tags(struct gui_wps *gwps, struct skin_draw_info *info,
vp->fg_pattern = rect->start_colour; vp->fg_pattern = rect->start_colour;
#endif #endif
gwps->display->fillrect(rect->x, rect->y, rect->width, gwps->display->fillrect(rect->x, rect->y, rect->width,
rect->height); rect->height);
#if LCD_DEPTH > 1 #if LCD_DEPTH > 1
vp->fg_pattern = backup; vp->fg_pattern = backup;
#endif #endif
@ -245,6 +254,7 @@ static bool do_non_text_tags(struct gui_wps *gwps, struct skin_draw_info *info,
case SKIN_TOKEN_IMAGE_DISPLAY_9SEGMENT: case SKIN_TOKEN_IMAGE_DISPLAY_9SEGMENT:
{ {
struct image_display *id = SKINOFFSETTOPTR(skin_buffer, token->value.data); struct image_display *id = SKINOFFSETTOPTR(skin_buffer, token->value.data);
if (!id) break;
const char* label = SKINOFFSETTOPTR(skin_buffer, id->label); const char* label = SKINOFFSETTOPTR(skin_buffer, id->label);
struct gui_img *img = skin_find_item(label,SKIN_FIND_IMAGE, data); struct gui_img *img = skin_find_item(label,SKIN_FIND_IMAGE, data);
if (img && img->loaded) if (img && img->loaded)
@ -313,7 +323,6 @@ static bool do_non_text_tags(struct gui_wps *gwps, struct skin_draw_info *info,
skin_render_playlistviewer(SKINOFFSETTOPTR(skin_buffer, token->value.data), gwps, skin_render_playlistviewer(SKINOFFSETTOPTR(skin_buffer, token->value.data), gwps,
info->skin_vp, info->refresh_type); info->skin_vp, info->refresh_type);
break; break;
#ifdef HAVE_SKIN_VARIABLES #ifdef HAVE_SKIN_VARIABLES
case SKIN_TOKEN_VAR_SET: case SKIN_TOKEN_VAR_SET:
{ {
@ -374,19 +383,21 @@ static void do_tags_in_hidden_conditional(struct skin_element* branch,
{ {
do_tags_in_hidden_conditional(get_child(child->children, i), info); do_tags_in_hidden_conditional(get_child(child->children, i), info);
} }
child = SKINOFFSETTOPTR(skin_buffer, child->next); goto skip;
continue;
} }
else if (child->type != TAG || !SKINOFFSETTOPTR(skin_buffer, child->data)) else if (child->type != TAG || !SKINOFFSETTOPTR(skin_buffer, child->data))
{ {
child = SKINOFFSETTOPTR(skin_buffer, child->next); goto skip;
continue;
} }
token = (struct wps_token *)SKINOFFSETTOPTR(skin_buffer, child->data); token = (struct wps_token *)SKINOFFSETTOPTR(skin_buffer, child->data);
/* clear all pictures in the conditional and nested ones */ /* clear all pictures in the conditional and nested ones */
if (token->type == SKIN_TOKEN_IMAGE_PRELOAD_DISPLAY) if (token->type == SKIN_TOKEN_IMAGE_PRELOAD_DISPLAY)
{ {
struct image_display *id = SKINOFFSETTOPTR(skin_buffer, token->value.data); struct image_display *id = SKINOFFSETTOPTR(skin_buffer, token->value.data);
if (!id) goto skip;
struct gui_img *img = skin_find_item(SKINOFFSETTOPTR(skin_buffer, id->label), struct gui_img *img = skin_find_item(SKINOFFSETTOPTR(skin_buffer, id->label),
SKIN_FIND_IMAGE, data); SKIN_FIND_IMAGE, data);
clear_image_pos(gwps, img); clear_image_pos(gwps, img);
@ -404,6 +415,7 @@ static void do_tags_in_hidden_conditional(struct skin_element* branch,
viewport = SKINOFFSETTOPTR(skin_buffer, viewport->next)) viewport = SKINOFFSETTOPTR(skin_buffer, viewport->next))
{ {
struct skin_viewport *skin_viewport = SKINOFFSETTOPTR(skin_buffer, viewport->data); struct skin_viewport *skin_viewport = SKINOFFSETTOPTR(skin_buffer, viewport->data);
if (!skin_viewport) continue;
char *vplabel = SKINOFFSETTOPTR(skin_buffer, skin_viewport->label); char *vplabel = SKINOFFSETTOPTR(skin_buffer, skin_viewport->label);
if (skin_viewport->label == VP_DEFAULT_LABEL) if (skin_viewport->label == VP_DEFAULT_LABEL)
vplabel = VP_DEFAULT_LABEL_STRING; vplabel = VP_DEFAULT_LABEL_STRING;
@ -451,6 +463,7 @@ static void do_tags_in_hidden_conditional(struct skin_element* branch,
playback_current_aa_hid(data->playback_aa_slot), true); playback_current_aa_hid(data->playback_aa_slot), true);
} }
#endif #endif
skip:
child = SKINOFFSETTOPTR(skin_buffer, child->next); child = SKINOFFSETTOPTR(skin_buffer, child->next);
} }
} }
@ -517,6 +530,7 @@ static bool skin_render_line(struct skin_element* line, struct skin_draw_info *i
{ {
case CONDITIONAL: case CONDITIONAL:
conditional = SKINOFFSETTOPTR(skin_buffer, child->data); conditional = SKINOFFSETTOPTR(skin_buffer, child->data);
if (!conditional) break;
last_value = conditional->last_value; last_value = conditional->last_value;
value = evaluate_conditional(info->gwps, info->offset, value = evaluate_conditional(info->gwps, info->offset,
conditional, child->children_count); conditional, child->children_count);
@ -623,7 +637,8 @@ static int get_subline_timeout(struct gui_wps *gwps, struct skin_element* line)
element->tag->type == SKIN_TOKEN_SUBLINE_TIMEOUT ) element->tag->type == SKIN_TOKEN_SUBLINE_TIMEOUT )
{ {
token = SKINOFFSETTOPTR(skin_buffer, element->data); token = SKINOFFSETTOPTR(skin_buffer, element->data);
return token->value.i; if (token)
return token->value.i;
} }
else if (element->type == CONDITIONAL) else if (element->type == CONDITIONAL)
{ {
@ -726,8 +741,11 @@ void skin_render_viewport(struct skin_element* viewport, struct gui_wps *gwps,
while (imglist) while (imglist)
{ {
struct wps_token *token = SKINOFFSETTOPTR(skin_buffer, imglist->token); struct wps_token *token = SKINOFFSETTOPTR(skin_buffer, imglist->token);
struct gui_img *img = (struct gui_img *)SKINOFFSETTOPTR(skin_buffer, token->value.data); if (token) {
img->display = -1; struct gui_img *img = (struct gui_img *)SKINOFFSETTOPTR(skin_buffer, token->value.data);
if (img)
img->display = -1;
}
imglist = SKINOFFSETTOPTR(skin_buffer, imglist->next); imglist = SKINOFFSETTOPTR(skin_buffer, imglist->next);
} }
@ -756,7 +774,6 @@ void skin_render_viewport(struct skin_element* viewport, struct gui_wps *gwps,
align->center = NULL; align->center = NULL;
align->right = NULL; align->right = NULL;
if (line->type == LINE_ALTERNATOR) if (line->type == LINE_ALTERNATOR)
func = skin_render_alternator; func = skin_render_alternator;
else if (line->type == LINE) else if (line->type == LINE)
@ -819,9 +836,10 @@ void skin_render(struct gui_wps *gwps, unsigned refresh_mode)
display->clear_viewport(); display->clear_viewport();
} }
} }
viewport = SKINOFFSETTOPTR(skin_buffer, data->tree); viewport = SKINOFFSETTOPTR(skin_buffer, data->tree);
if (!viewport) return;
skin_viewport = SKINOFFSETTOPTR(skin_buffer, viewport->data); skin_viewport = SKINOFFSETTOPTR(skin_buffer, viewport->data);
if (!skin_viewport) return;
label = SKINOFFSETTOPTR(skin_buffer, skin_viewport->label); label = SKINOFFSETTOPTR(skin_buffer, skin_viewport->label);
if (skin_viewport->label == VP_DEFAULT_LABEL) if (skin_viewport->label == VP_DEFAULT_LABEL)
label = VP_DEFAULT_LABEL_STRING; label = VP_DEFAULT_LABEL_STRING;
@ -833,8 +851,10 @@ void skin_render(struct gui_wps *gwps, unsigned refresh_mode)
viewport; viewport;
viewport = SKINOFFSETTOPTR(skin_buffer, viewport->next)) viewport = SKINOFFSETTOPTR(skin_buffer, viewport->next))
{ {
/* SETUP */ /* SETUP */
skin_viewport = SKINOFFSETTOPTR(skin_buffer, viewport->data); skin_viewport = SKINOFFSETTOPTR(skin_buffer, viewport->data);
if (!skin_viewport) continue;
unsigned vp_refresh_mode = refresh_mode; unsigned vp_refresh_mode = refresh_mode;
#if (LCD_DEPTH > 1) || (defined(HAVE_REMOTE_LCD) && LCD_REMOTE_DEPTH > 1) #if (LCD_DEPTH > 1) || (defined(HAVE_REMOTE_LCD) && LCD_REMOTE_DEPTH > 1)
if (skin_viewport->output_to_backdrop_buffer) if (skin_viewport->output_to_backdrop_buffer)

View file

@ -163,7 +163,7 @@ const char *get_cuesheetid3_token(struct wps_token *token, struct mp3entry *id3,
struct cuesheet *cue = id3?id3->cuesheet:NULL; struct cuesheet *cue = id3?id3->cuesheet:NULL;
if (!cue || !cue->curr_track) if (!cue || !cue->curr_track)
return NULL; return NULL;
struct cue_track_info *track = cue->curr_track; struct cue_track_info *track = cue->curr_track;
if (offset_tracks) if (offset_tracks)
{ {
@ -185,7 +185,7 @@ const char *get_cuesheetid3_token(struct wps_token *token, struct mp3entry *id3,
case SKIN_TOKEN_METADATA_TRACK_TITLE: case SKIN_TOKEN_METADATA_TRACK_TITLE:
return *track->title ? track->title : NULL; return *track->title ? track->title : NULL;
case SKIN_TOKEN_METADATA_TRACK_NUMBER: case SKIN_TOKEN_METADATA_TRACK_NUMBER:
snprintf(buf, buf_size, "%d/%d", snprintf(buf, buf_size, "%d/%d",
cue->curr_track_idx+offset_tracks+1, cue->track_count); cue->curr_track_idx+offset_tracks+1, cue->track_count);
return buf; return buf;
default: default:
@ -200,7 +200,7 @@ static const char* get_filename_token(struct wps_token *token, char* filename,
if (filename) if (filename)
{ {
switch (token->type) switch (token->type)
{ {
case SKIN_TOKEN_FILE_PATH: case SKIN_TOKEN_FILE_PATH:
return filename; return filename;
case SKIN_TOKEN_FILE_NAME: case SKIN_TOKEN_FILE_NAME:
@ -478,7 +478,7 @@ const char *get_radio_token(struct wps_token *token, int preset_offset,
{ {
*intval = val; *intval = val;
} }
else else
{ {
*intval = 1+(limit-1)*(val-min)/(max-1-min); *intval = 1+(limit-1)*(val-min)/(max-1-min);
} }
@ -514,7 +514,7 @@ const char *get_radio_token(struct wps_token *token, int preset_offset,
return buf; return buf;
} }
case SKIN_TOKEN_PRESET_COUNT: case SKIN_TOKEN_PRESET_COUNT:
snprintf(buf, buf_size, "%d", radio_preset_count()); snprintf(buf, buf_size, "%d", radio_preset_count());
if (intval) if (intval)
*intval = radio_preset_count(); *intval = radio_preset_count();
return buf; return buf;
@ -580,7 +580,7 @@ static const char* NOINLINE get_lif_token_value(struct gui_wps *gwps,
int b; int b;
bool number_set = true; bool number_set = true;
struct wps_token *liftoken = SKINOFFSETTOPTR(get_skin_buffer(gwps->data), lif->token); struct wps_token *liftoken = SKINOFFSETTOPTR(get_skin_buffer(gwps->data), lif->token);
const char* out_text = get_token_value(gwps, liftoken, offset, buf, buf_size, &a); const char* out_text = get_token_value(gwps, liftoken, offset, buf, buf_size, &a);
if (a == -1 && liftoken->type != SKIN_TOKEN_VOLUME) if (a == -1 && liftoken->type != SKIN_TOKEN_VOLUME)
{ {
a = (out_text && *out_text) ? 1 : 0; a = (out_text && *out_text) ? 1 : 0;
@ -610,10 +610,13 @@ static const char* NOINLINE get_lif_token_value(struct gui_wps *gwps,
char temp_buf[MAX_PATH]; char temp_buf[MAX_PATH];
const char *outb; const char *outb;
struct skin_element *element = SKINOFFSETTOPTR(get_skin_buffer(gwps->data), lif->operand.data.code); struct skin_element *element = SKINOFFSETTOPTR(get_skin_buffer(gwps->data), lif->operand.data.code);
if (!element) return NULL;
struct wps_token *token = SKINOFFSETTOPTR(get_skin_buffer(gwps->data), element->data); struct wps_token *token = SKINOFFSETTOPTR(get_skin_buffer(gwps->data), element->data);
b = lif->num_options; b = lif->num_options;
outb = get_token_value(gwps, token, offset, temp_buf, outb = get_token_value(gwps, token, offset, temp_buf,
sizeof(temp_buf), &b); sizeof(temp_buf), &b);
if (b == -1 && liftoken->type != SKIN_TOKEN_VOLUME) if (b == -1 && liftoken->type != SKIN_TOKEN_VOLUME)
{ {
if (!out_text || !outb) if (!out_text || !outb)
@ -631,7 +634,7 @@ static const char* NOINLINE get_lif_token_value(struct gui_wps *gwps,
case DEFAULT: case DEFAULT:
break; break;
} }
switch (lif->op) switch (lif->op)
{ {
case IF_EQUALS: case IF_EQUALS:
@ -666,10 +669,12 @@ const char *get_token_value(struct gui_wps *gwps,
{ {
if (!gwps) if (!gwps)
return NULL; return NULL;
if (!token)
return NULL;
struct wps_data *data = gwps->data; struct wps_data *data = gwps->data;
struct wps_state *state = skin_get_global_state(); struct wps_state *state = skin_get_global_state();
struct mp3entry *id3; /* Think very carefully about using this. struct mp3entry *id3; /* Think very carefully about using this.
maybe get_id3_token() is the better place? */ maybe get_id3_token() is the better place? */
const char *out_text = NULL; const char *out_text = NULL;
char *filename = NULL; char *filename = NULL;
@ -680,7 +685,7 @@ const char *get_token_value(struct gui_wps *gwps,
id3 = get_mp3entry_from_offset(token->next? 1: offset, &filename); id3 = get_mp3entry_from_offset(token->next? 1: offset, &filename);
if (id3) if (id3)
filename = id3->path; filename = id3->path;
#if CONFIG_RTC #if CONFIG_RTC
struct tm* tm = NULL; struct tm* tm = NULL;
@ -702,10 +707,10 @@ const char *get_token_value(struct gui_wps *gwps,
limit = *intval; limit = *intval;
*intval = -1; *intval = -1;
} }
if (id3 && id3 == state->id3 && id3->cuesheet ) if (id3 && id3 == state->id3 && id3->cuesheet )
{ {
out_text = get_cuesheetid3_token(token, id3, out_text = get_cuesheetid3_token(token, id3,
token->next?1:offset, buf, buf_size); token->next?1:offset, buf, buf_size);
if (out_text) if (out_text)
return out_text; return out_text;
@ -734,6 +739,7 @@ const char *get_token_value(struct gui_wps *gwps,
char *skinbuffer = get_skin_buffer(data); char *skinbuffer = get_skin_buffer(data);
struct skin_element *element = struct skin_element *element =
SKINOFFSETTOPTR(skinbuffer, token->value.data); SKINOFFSETTOPTR(skinbuffer, token->value.data);
if (!element || !element->params) return NULL;
struct skin_tag_parameter* params = struct skin_tag_parameter* params =
SKINOFFSETTOPTR(skinbuffer, element->params); SKINOFFSETTOPTR(skinbuffer, element->params);
struct skin_tag_parameter* thistag; struct skin_tag_parameter* thistag;
@ -742,6 +748,7 @@ const char *get_token_value(struct gui_wps *gwps,
thistag = &params[i]; thistag = &params[i];
struct skin_element *tokenelement = struct skin_element *tokenelement =
SKINOFFSETTOPTR(skinbuffer, thistag->data.code); SKINOFFSETTOPTR(skinbuffer, thistag->data.code);
if (!tokenelement) return NULL;
out_text = get_token_value(gwps, out_text = get_token_value(gwps,
SKINOFFSETTOPTR(skinbuffer, tokenelement->data), SKINOFFSETTOPTR(skinbuffer, tokenelement->data),
offset, buf, buf_size, intval); offset, buf, buf_size, intval);
@ -753,10 +760,12 @@ const char *get_token_value(struct gui_wps *gwps,
return truecount ? "true" : NULL; return truecount ? "true" : NULL;
} }
break; break;
case SKIN_TOKEN_SUBSTRING: case SKIN_TOKEN_SUBSTRING:
{ {
struct substring *ss = SKINOFFSETTOPTR(get_skin_buffer(data), token->value.data); struct substring *ss = SKINOFFSETTOPTR(get_skin_buffer(data), token->value.data);
const char *token_val = get_token_value(gwps, if (!ss) return NULL;
const char *token_val = get_token_value(gwps,
SKINOFFSETTOPTR(get_skin_buffer(data), ss->token), offset, SKINOFFSETTOPTR(get_skin_buffer(data), ss->token), offset,
buf, buf_size, intval); buf, buf_size, intval);
if (token_val) if (token_val)
@ -788,13 +797,13 @@ const char *get_token_value(struct gui_wps *gwps,
if (ss->expect_number && if (ss->expect_number &&
intval && (buf[0] >= '0' && buf[0] <= '9')) intval && (buf[0] >= '0' && buf[0] <= '9'))
*intval = atoi(buf) + 1; /* so 0 is the first item */ *intval = atoi(buf) + 1; /* so 0 is the first item */
return buf; return buf;
} }
return NULL; return NULL;
} }
break; break;
case SKIN_TOKEN_CHARACTER: case SKIN_TOKEN_CHARACTER:
if (token->value.c == '\n') if (token->value.c == '\n')
return NULL; return NULL;
@ -802,7 +811,7 @@ const char *get_token_value(struct gui_wps *gwps,
case SKIN_TOKEN_STRING: case SKIN_TOKEN_STRING:
return (char*)SKINOFFSETTOPTR(get_skin_buffer(data), token->value.data); return (char*)SKINOFFSETTOPTR(get_skin_buffer(data), token->value.data);
case SKIN_TOKEN_TRANSLATEDSTRING: case SKIN_TOKEN_TRANSLATEDSTRING:
return (char*)P2STR(ID2P(token->value.i)); return (char*)P2STR(ID2P(token->value.i));
@ -821,6 +830,7 @@ const char *get_token_value(struct gui_wps *gwps,
case SKIN_TOKEN_LIST_ITEM_TEXT: case SKIN_TOKEN_LIST_ITEM_TEXT:
{ {
struct listitem *li = (struct listitem *)SKINOFFSETTOPTR(get_skin_buffer(data), token->value.data); struct listitem *li = (struct listitem *)SKINOFFSETTOPTR(get_skin_buffer(data), token->value.data);
if (!li) return NULL;
return skinlist_get_item_text(li->offset, li->wrap, buf, buf_size); return skinlist_get_item_text(li->offset, li->wrap, buf, buf_size);
} }
case SKIN_TOKEN_LIST_ITEM_ROW: case SKIN_TOKEN_LIST_ITEM_ROW:
@ -843,6 +853,7 @@ const char *get_token_value(struct gui_wps *gwps,
case SKIN_TOKEN_LIST_ITEM_ICON: case SKIN_TOKEN_LIST_ITEM_ICON:
{ {
struct listitem *li = (struct listitem *)SKINOFFSETTOPTR(get_skin_buffer(data), token->value.data); struct listitem *li = (struct listitem *)SKINOFFSETTOPTR(get_skin_buffer(data), token->value.data);
if (!li) return NULL;
int icon = skinlist_get_item_icon(li->offset, li->wrap); int icon = skinlist_get_item_icon(li->offset, li->wrap);
if (intval) if (intval)
*intval = icon; *intval = icon;
@ -905,11 +916,12 @@ const char *get_token_value(struct gui_wps *gwps,
if (in_radio_screen() || (get_radio_status() != FMRADIO_OFF)) if (in_radio_screen() || (get_radio_status() != FMRADIO_OFF))
{ {
struct skin_albumart *aa = SKINOFFSETTOPTR(get_skin_buffer(data), data->albumart); struct skin_albumart *aa = SKINOFFSETTOPTR(get_skin_buffer(data), data->albumart);
if (!aa) return NULL;
struct dim dim = {aa->width, aa->height}; struct dim dim = {aa->width, aa->height};
handle = radio_get_art_hid(&dim); handle = radio_get_art_hid(&dim);
} }
#endif #endif
if (handle >= 0) if (handle >= 0)
return "C"; return "C";
} }
return NULL; return NULL;
@ -1009,7 +1021,7 @@ const char *get_token_value(struct gui_wps *gwps,
int mode = 1; /* stop */ int mode = 1; /* stop */
if (status == STATUS_PLAY) if (status == STATUS_PLAY)
mode = 2; /* play */ mode = 2; /* play */
if (state->is_fading || if (state->is_fading ||
(status == STATUS_PAUSE && !status_get_ffmode())) (status == STATUS_PAUSE && !status_get_ffmode()))
mode = 3; /* pause */ mode = 3; /* pause */
else else
@ -1336,13 +1348,13 @@ const char *get_token_value(struct gui_wps *gwps,
token->value.i)) token->value.i))
return "v"; return "v";
return NULL; return NULL;
case SKIN_TOKEN_LASTTOUCH: case SKIN_TOKEN_LASTTOUCH:
{ {
#ifdef HAVE_TOUCHSCREEN #ifdef HAVE_TOUCHSCREEN
unsigned int last_touch = touchscreen_last_touch(); unsigned int last_touch = touchscreen_last_touch();
char *skin_base = get_skin_buffer(data); char *skin_base = get_skin_buffer(data);
struct touchregion_lastpress *data = SKINOFFSETTOPTR(skin_base, token->value.data); struct touchregion_lastpress *data = SKINOFFSETTOPTR(skin_base, token->value.data);
if (!data) return NULL;
struct touchregion *region = SKINOFFSETTOPTR(skin_base, data->region); struct touchregion *region = SKINOFFSETTOPTR(skin_base, data->region);
if (region) if (region)
last_touch = region->last_press; last_touch = region->last_press;
@ -1669,10 +1681,8 @@ const char *get_token_value(struct gui_wps *gwps,
} }
return NULL; return NULL;
#endif #endif
default: default:
return NULL; return NULL;
} }
} }

View file

@ -86,14 +86,15 @@ int sb_preproccess(enum screen_type screen, struct wps_data *data)
int sb_postproccess(enum screen_type screen, struct wps_data *data) int sb_postproccess(enum screen_type screen, struct wps_data *data)
{ {
if (data->wps_loaded) if (data->wps_loaded)
{ {
/* hide the sb's default viewport because it has nasty effect with stuff /* hide the sb's default viewport because it has nasty effect with stuff
* not part of the statusbar, * not part of the statusbar,
* hence .sbs's without any other vps are unsupported*/ * hence .sbs's without any other vps are unsupported*/
struct skin_viewport *vp = skin_find_item(VP_DEFAULT_LABEL_STRING, SKIN_FIND_VP, data); struct skin_viewport *vp = skin_find_item(VP_DEFAULT_LABEL_STRING, SKIN_FIND_VP, data);
struct skin_element *tree = SKINOFFSETTOPTR(get_skin_buffer(data), data->tree); struct skin_element *tree = SKINOFFSETTOPTR(get_skin_buffer(data), data->tree);
struct skin_element *next_vp = SKINOFFSETTOPTR(get_skin_buffer(data), tree->next); struct skin_element *next_vp = NULL;
if (tree) next_vp = SKINOFFSETTOPTR(get_skin_buffer(data), tree->next);
if (vp) if (vp)
{ {
if (!next_vp) if (!next_vp)
@ -132,9 +133,12 @@ struct viewport *sb_skin_get_info_vp(enum screen_type screen)
viewportmanager_theme_enable(screen, false, NULL); viewportmanager_theme_enable(screen, false, NULL);
viewportmanager_theme_undo(screen, true); viewportmanager_theme_undo(screen, true);
} }
label = SKINOFFSETTOPTR(get_skin_buffer(data), infovp_label[screen]);
if (infovp_label[screen] == VP_DEFAULT_LABEL) if (infovp_label[screen] == VP_DEFAULT_LABEL)
label = VP_DEFAULT_LABEL_STRING; label = VP_DEFAULT_LABEL_STRING;
else
label = SKINOFFSETTOPTR(get_skin_buffer(data), infovp_label[screen]);
if (!label)
return NULL;
vp = skin_find_item(label, SKIN_FIND_UIVP, data); vp = skin_find_item(label, SKIN_FIND_UIVP, data);
if (!vp) if (!vp)
return NULL; return NULL;

View file

@ -623,6 +623,7 @@ struct pgn_game_node* pgn_list_games(const char* filename){
/* a new game header is found */ /* a new game header is found */
if (line_buffer[0] == '['){ if (line_buffer[0] == '['){
temp_node = (struct pgn_game_node *)pl_malloc(sizeof size_node); temp_node = (struct pgn_game_node *)pl_malloc(sizeof size_node);
if (!temp_node) return NULL;
temp_node->next_node = NULL; temp_node->next_node = NULL;
if (curr_node == NULL) { if (curr_node == NULL) {
first_game = curr_node = temp_node; first_game = curr_node = temp_node;
@ -773,9 +774,11 @@ void pgn_parse_game(const char* filename,
*/ */
if (first_ply != NULL){ if (first_ply != NULL){
temp_ply = (struct pgn_ply_node *)pl_malloc(sizeof size_ply); temp_ply = (struct pgn_ply_node *)pl_malloc(sizeof size_ply);
temp_ply->player = neutral; if (temp_ply) {
temp_ply->prev_node = curr_node; temp_ply->player = neutral;
curr_node->next_node = temp_ply; temp_ply->prev_node = curr_node;
curr_node->next_node = temp_ply;
}
} }
selected_game->first_ply = first_ply; selected_game->first_ply = first_ply;
@ -793,6 +796,7 @@ struct pgn_game_node* pgn_init_game(void){
/* create an "end of game" dummy ply and assign defaults */ /* create an "end of game" dummy ply and assign defaults */
ply = (struct pgn_ply_node *)pl_malloc(sizeof ply_size); ply = (struct pgn_ply_node *)pl_malloc(sizeof ply_size);
if (!ply) return NULL;
ply->player = neutral; ply->player = neutral;
ply->pgn_text[0] = '\0'; ply->pgn_text[0] = '\0';
ply->prev_node = NULL; ply->prev_node = NULL;
@ -800,6 +804,8 @@ struct pgn_game_node* pgn_init_game(void){
/* create the game and assign defaults */ /* create the game and assign defaults */
game = (struct pgn_game_node *)pl_malloc(sizeof game_size); game = (struct pgn_game_node *)pl_malloc(sizeof game_size);
if (!game) return NULL;
game->game_number = 0; game->game_number = 0;
rb->strcpy(game->white_player,"Player"); rb->strcpy(game->white_player,"Player");
rb->strcpy(game->black_player,"GnuChess"); rb->strcpy(game->black_player,"GnuChess");
@ -823,6 +829,7 @@ void pgn_append_ply(struct pgn_game_node* game,
struct pgn_ply_node ply_size, *ply, *temp; struct pgn_ply_node ply_size, *ply, *temp;
ply = (struct pgn_ply_node *)pl_malloc(sizeof ply_size); ply = (struct pgn_ply_node *)pl_malloc(sizeof ply_size);
if (!ply) return;
ply->player = ply_player; ply->player = ply_player;
ply->column_from = move_buffer[0] - 'a'; ply->column_from = move_buffer[0] - 'a';
ply->row_from = move_buffer[1] - '1'; ply->row_from = move_buffer[1] - '1';
@ -847,6 +854,7 @@ void pgn_append_ply(struct pgn_game_node* game,
} else { } else {
temp->prev_node->next_node = ply; temp->prev_node->next_node = ply;
} }
temp->prev_node = ply; temp->prev_node = ply;
} }

View file

@ -637,12 +637,13 @@ enum plugin_status plugin_start(const void *parameter) {
draw_screen = false; draw_screen = false;
} }
switch(cur_player) { switch(cur_player) {
case BLACK:
cur_strategy = black_strategy;
break;
case WHITE: case WHITE:
cur_strategy = white_strategy; cur_strategy = white_strategy;
break; break;
case BLACK:
default:
cur_strategy = black_strategy;
break;
} }
if(cur_strategy->is_robot && !game_finished) { if(cur_strategy->is_robot && !game_finished) {