diff options
author | Solomon Peachy <pizza@shaftnet.org> | 2020-10-27 11:14:23 -0400 |
---|---|---|
committer | Solomon Peachy <pizza@shaftnet.org> | 2020-10-28 08:42:49 -0400 |
commit | a605cdf7008f856946cbf01193f4dffc3ee63fdb (patch) | |
tree | 53368641340ffd9d10f77f56b2bde66916a1cfd1 /apps/gui/skin_engine/skin_render.c | |
parent | 621e363e70e69a92169494515c5637551ceba219 (diff) | |
download | rockbox-a605cdf7008f856946cbf01193f4dffc3ee63fdb.tar.gz rockbox-a605cdf7008f856946cbf01193f4dffc3ee63fdb.zip |
Fix multiple potential null pointer dereferencess
GCC's optimizer thinks all of these _will_ fail at some point
Change-Id: I287eeb574162a5d3b3347654d25aa1f53e9f5563
Diffstat (limited to 'apps/gui/skin_engine/skin_render.c')
-rw-r--r-- | apps/gui/skin_engine/skin_render.c | 66 |
1 files changed, 43 insertions, 23 deletions
diff --git a/apps/gui/skin_engine/skin_render.c b/apps/gui/skin_engine/skin_render.c index ed2f783e7a..7f2dcab222 100644 --- a/apps/gui/skin_engine/skin_render.c +++ b/apps/gui/skin_engine/skin_render.c | |||
@@ -96,7 +96,7 @@ static bool do_non_text_tags(struct gui_wps *gwps, struct skin_draw_info *info, | |||
96 | struct skin_element *element, struct skin_viewport* skin_vp) | 96 | struct skin_element *element, struct skin_viewport* skin_vp) |
97 | { | 97 | { |
98 | struct wps_token *token = (struct wps_token *)SKINOFFSETTOPTR(skin_buffer, element->data); | 98 | struct wps_token *token = (struct wps_token *)SKINOFFSETTOPTR(skin_buffer, element->data); |
99 | 99 | if (!token) return false; | |
100 | struct viewport *vp = &skin_vp->vp; | 100 | struct viewport *vp = &skin_vp->vp; |
101 | struct wps_data *data = gwps->data; | 101 | struct wps_data *data = gwps->data; |
102 | bool do_refresh = (element->tag->flags & info->refresh_type) > 0; | 102 | 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, | |||
107 | case SKIN_TOKEN_VIEWPORT_FGCOLOUR: | 107 | case SKIN_TOKEN_VIEWPORT_FGCOLOUR: |
108 | { | 108 | { |
109 | struct viewport_colour *col = SKINOFFSETTOPTR(skin_buffer, token->value.data); | 109 | struct viewport_colour *col = SKINOFFSETTOPTR(skin_buffer, token->value.data); |
110 | if (!col) return false; | ||
110 | struct viewport *vp = SKINOFFSETTOPTR(skin_buffer, col->vp); | 111 | struct viewport *vp = SKINOFFSETTOPTR(skin_buffer, col->vp); |
112 | if (!vp) return false; | ||
111 | vp->fg_pattern = col->colour; | 113 | vp->fg_pattern = col->colour; |
112 | skin_vp->fgbg_changed = true; | 114 | skin_vp->fgbg_changed = true; |
113 | } | 115 | } |
@@ -115,7 +117,9 @@ static bool do_non_text_tags(struct gui_wps *gwps, struct skin_draw_info *info, | |||
115 | case SKIN_TOKEN_VIEWPORT_BGCOLOUR: | 117 | case SKIN_TOKEN_VIEWPORT_BGCOLOUR: |
116 | { | 118 | { |
117 | struct viewport_colour *col = SKINOFFSETTOPTR(skin_buffer, token->value.data); | 119 | struct viewport_colour *col = SKINOFFSETTOPTR(skin_buffer, token->value.data); |
120 | if (!col) return false; | ||
118 | struct viewport *vp = SKINOFFSETTOPTR(skin_buffer, col->vp); | 121 | struct viewport *vp = SKINOFFSETTOPTR(skin_buffer, col->vp); |
122 | if (!vp) return false; | ||
119 | vp->bg_pattern = col->colour; | 123 | vp->bg_pattern = col->colour; |
120 | skin_vp->fgbg_changed = true; | 124 | skin_vp->fgbg_changed = true; |
121 | } | 125 | } |
@@ -124,6 +128,7 @@ static bool do_non_text_tags(struct gui_wps *gwps, struct skin_draw_info *info, | |||
124 | { | 128 | { |
125 | struct line_desc *data = SKINOFFSETTOPTR(skin_buffer, token->value.data); | 129 | struct line_desc *data = SKINOFFSETTOPTR(skin_buffer, token->value.data); |
126 | struct line_desc *linedes = &info->line_desc; | 130 | struct line_desc *linedes = &info->line_desc; |
131 | if (!data || !linedes) return false; | ||
127 | /* gradient colors are handled with a separate tag | 132 | /* gradient colors are handled with a separate tag |
128 | * (SKIN_TOKEN_VIEWPORT_GRADIENT_SETUP, see below). since it may | 133 | * (SKIN_TOKEN_VIEWPORT_GRADIENT_SETUP, see below). since it may |
129 | * come before the text style tag color fields need to be preserved */ | 134 | * 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, | |||
147 | { | 152 | { |
148 | struct gradient_config *cfg = SKINOFFSETTOPTR(skin_buffer, token->value.data); | 153 | struct gradient_config *cfg = SKINOFFSETTOPTR(skin_buffer, token->value.data); |
149 | struct line_desc *linedes = &info->line_desc; | 154 | struct line_desc *linedes = &info->line_desc; |
155 | if (!cfg || !linedes) return false; | ||
150 | linedes->text_color = cfg->text; | 156 | linedes->text_color = cfg->text; |
151 | linedes->line_color = cfg->start; | 157 | linedes->line_color = cfg->start; |
152 | linedes->line_end_color = cfg->end; | 158 | 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, | |||
162 | { | 168 | { |
163 | struct skin_viewport *skinvp = SKINOFFSETTOPTR(skin_buffer, viewport->data); | 169 | struct skin_viewport *skinvp = SKINOFFSETTOPTR(skin_buffer, viewport->data); |
164 | 170 | ||
165 | char *vplabel = SKINOFFSETTOPTR(skin_buffer, skinvp->label); | 171 | if (skinvp) { |
166 | if (skinvp->label == VP_DEFAULT_LABEL) | 172 | char *vplabel = SKINOFFSETTOPTR(skin_buffer, skinvp->label); |
167 | vplabel = VP_DEFAULT_LABEL_STRING; | 173 | if (skinvp->label == VP_DEFAULT_LABEL) |
168 | if (vplabel && !skinvp->is_infovp && | 174 | vplabel = VP_DEFAULT_LABEL_STRING; |
169 | !strcmp(vplabel, label)) | 175 | if (vplabel && !skinvp->is_infovp && |
170 | { | 176 | !strcmp(vplabel, label)) |
171 | if (skinvp->hidden_flags&VP_DRAW_HIDDEN) | ||
172 | { | 177 | { |
173 | temp |= VP_DRAW_WASHIDDEN; | 178 | if (skinvp->hidden_flags&VP_DRAW_HIDDEN) |
179 | { | ||
180 | temp |= VP_DRAW_WASHIDDEN; | ||
181 | } | ||
182 | skinvp->hidden_flags = temp; | ||
174 | } | 183 | } |
175 | skinvp->hidden_flags = temp; | ||
176 | } | 184 | } |
177 | viewport = SKINOFFSETTOPTR(skin_buffer, viewport->next); | 185 | viewport = SKINOFFSETTOPTR(skin_buffer, viewport->next); |
178 | } | 186 | } |
@@ -195,12 +203,13 @@ static bool do_non_text_tags(struct gui_wps *gwps, struct skin_draw_info *info, | |||
195 | { | 203 | { |
196 | struct draw_rectangle *rect = | 204 | struct draw_rectangle *rect = |
197 | SKINOFFSETTOPTR(skin_buffer, token->value.data); | 205 | SKINOFFSETTOPTR(skin_buffer, token->value.data); |
206 | if (!rect) break; | ||
198 | #ifdef HAVE_LCD_COLOR | 207 | #ifdef HAVE_LCD_COLOR |
199 | if (rect->start_colour != rect->end_colour && | 208 | if (rect->start_colour != rect->end_colour && |
200 | gwps->display->screen_type == SCREEN_MAIN) | 209 | gwps->display->screen_type == SCREEN_MAIN) |
201 | { | 210 | { |
202 | gwps->display->gradient_fillrect(rect->x, rect->y, rect->width, | 211 | gwps->display->gradient_fillrect(rect->x, rect->y, rect->width, |
203 | rect->height, rect->start_colour, rect->end_colour); | 212 | rect->height, rect->start_colour, rect->end_colour); |
204 | } | 213 | } |
205 | else | 214 | else |
206 | #endif | 215 | #endif |
@@ -210,7 +219,7 @@ static bool do_non_text_tags(struct gui_wps *gwps, struct skin_draw_info *info, | |||
210 | vp->fg_pattern = rect->start_colour; | 219 | vp->fg_pattern = rect->start_colour; |
211 | #endif | 220 | #endif |
212 | gwps->display->fillrect(rect->x, rect->y, rect->width, | 221 | gwps->display->fillrect(rect->x, rect->y, rect->width, |
213 | rect->height); | 222 | rect->height); |
214 | #if LCD_DEPTH > 1 | 223 | #if LCD_DEPTH > 1 |
215 | vp->fg_pattern = backup; | 224 | vp->fg_pattern = backup; |
216 | #endif | 225 | #endif |
@@ -245,6 +254,7 @@ static bool do_non_text_tags(struct gui_wps *gwps, struct skin_draw_info *info, | |||
245 | case SKIN_TOKEN_IMAGE_DISPLAY_9SEGMENT: | 254 | case SKIN_TOKEN_IMAGE_DISPLAY_9SEGMENT: |
246 | { | 255 | { |
247 | struct image_display *id = SKINOFFSETTOPTR(skin_buffer, token->value.data); | 256 | struct image_display *id = SKINOFFSETTOPTR(skin_buffer, token->value.data); |
257 | if (!id) break; | ||
248 | const char* label = SKINOFFSETTOPTR(skin_buffer, id->label); | 258 | const char* label = SKINOFFSETTOPTR(skin_buffer, id->label); |
249 | struct gui_img *img = skin_find_item(label,SKIN_FIND_IMAGE, data); | 259 | struct gui_img *img = skin_find_item(label,SKIN_FIND_IMAGE, data); |
250 | if (img && img->loaded) | 260 | if (img && img->loaded) |
@@ -313,7 +323,6 @@ static bool do_non_text_tags(struct gui_wps *gwps, struct skin_draw_info *info, | |||
313 | skin_render_playlistviewer(SKINOFFSETTOPTR(skin_buffer, token->value.data), gwps, | 323 | skin_render_playlistviewer(SKINOFFSETTOPTR(skin_buffer, token->value.data), gwps, |
314 | info->skin_vp, info->refresh_type); | 324 | info->skin_vp, info->refresh_type); |
315 | break; | 325 | break; |
316 | |||
317 | #ifdef HAVE_SKIN_VARIABLES | 326 | #ifdef HAVE_SKIN_VARIABLES |
318 | case SKIN_TOKEN_VAR_SET: | 327 | case SKIN_TOKEN_VAR_SET: |
319 | { | 328 | { |
@@ -374,19 +383,21 @@ static void do_tags_in_hidden_conditional(struct skin_element* branch, | |||
374 | { | 383 | { |
375 | do_tags_in_hidden_conditional(get_child(child->children, i), info); | 384 | do_tags_in_hidden_conditional(get_child(child->children, i), info); |
376 | } | 385 | } |
377 | child = SKINOFFSETTOPTR(skin_buffer, child->next); | 386 | goto skip; |
378 | continue; | ||
379 | } | 387 | } |
380 | else if (child->type != TAG || !SKINOFFSETTOPTR(skin_buffer, child->data)) | 388 | else if (child->type != TAG || !SKINOFFSETTOPTR(skin_buffer, child->data)) |
381 | { | 389 | { |
382 | child = SKINOFFSETTOPTR(skin_buffer, child->next); | 390 | goto skip; |
383 | continue; | ||
384 | } | 391 | } |
392 | |||
385 | token = (struct wps_token *)SKINOFFSETTOPTR(skin_buffer, child->data); | 393 | token = (struct wps_token *)SKINOFFSETTOPTR(skin_buffer, child->data); |
394 | |||
386 | /* clear all pictures in the conditional and nested ones */ | 395 | /* clear all pictures in the conditional and nested ones */ |
387 | if (token->type == SKIN_TOKEN_IMAGE_PRELOAD_DISPLAY) | 396 | if (token->type == SKIN_TOKEN_IMAGE_PRELOAD_DISPLAY) |
388 | { | 397 | { |
389 | struct image_display *id = SKINOFFSETTOPTR(skin_buffer, token->value.data); | 398 | struct image_display *id = SKINOFFSETTOPTR(skin_buffer, token->value.data); |
399 | if (!id) goto skip; | ||
400 | |||
390 | struct gui_img *img = skin_find_item(SKINOFFSETTOPTR(skin_buffer, id->label), | 401 | struct gui_img *img = skin_find_item(SKINOFFSETTOPTR(skin_buffer, id->label), |
391 | SKIN_FIND_IMAGE, data); | 402 | SKIN_FIND_IMAGE, data); |
392 | clear_image_pos(gwps, img); | 403 | clear_image_pos(gwps, img); |
@@ -404,6 +415,7 @@ static void do_tags_in_hidden_conditional(struct skin_element* branch, | |||
404 | viewport = SKINOFFSETTOPTR(skin_buffer, viewport->next)) | 415 | viewport = SKINOFFSETTOPTR(skin_buffer, viewport->next)) |
405 | { | 416 | { |
406 | struct skin_viewport *skin_viewport = SKINOFFSETTOPTR(skin_buffer, viewport->data); | 417 | struct skin_viewport *skin_viewport = SKINOFFSETTOPTR(skin_buffer, viewport->data); |
418 | if (!skin_viewport) continue; | ||
407 | char *vplabel = SKINOFFSETTOPTR(skin_buffer, skin_viewport->label); | 419 | char *vplabel = SKINOFFSETTOPTR(skin_buffer, skin_viewport->label); |
408 | if (skin_viewport->label == VP_DEFAULT_LABEL) | 420 | if (skin_viewport->label == VP_DEFAULT_LABEL) |
409 | vplabel = VP_DEFAULT_LABEL_STRING; | 421 | vplabel = VP_DEFAULT_LABEL_STRING; |
@@ -451,6 +463,7 @@ static void do_tags_in_hidden_conditional(struct skin_element* branch, | |||
451 | playback_current_aa_hid(data->playback_aa_slot), true); | 463 | playback_current_aa_hid(data->playback_aa_slot), true); |
452 | } | 464 | } |
453 | #endif | 465 | #endif |
466 | skip: | ||
454 | child = SKINOFFSETTOPTR(skin_buffer, child->next); | 467 | child = SKINOFFSETTOPTR(skin_buffer, child->next); |
455 | } | 468 | } |
456 | } | 469 | } |
@@ -517,6 +530,7 @@ static bool skin_render_line(struct skin_element* line, struct skin_draw_info *i | |||
517 | { | 530 | { |
518 | case CONDITIONAL: | 531 | case CONDITIONAL: |
519 | conditional = SKINOFFSETTOPTR(skin_buffer, child->data); | 532 | conditional = SKINOFFSETTOPTR(skin_buffer, child->data); |
533 | if (!conditional) break; | ||
520 | last_value = conditional->last_value; | 534 | last_value = conditional->last_value; |
521 | value = evaluate_conditional(info->gwps, info->offset, | 535 | value = evaluate_conditional(info->gwps, info->offset, |
522 | conditional, child->children_count); | 536 | conditional, child->children_count); |
@@ -623,7 +637,8 @@ static int get_subline_timeout(struct gui_wps *gwps, struct skin_element* line) | |||
623 | element->tag->type == SKIN_TOKEN_SUBLINE_TIMEOUT ) | 637 | element->tag->type == SKIN_TOKEN_SUBLINE_TIMEOUT ) |
624 | { | 638 | { |
625 | token = SKINOFFSETTOPTR(skin_buffer, element->data); | 639 | token = SKINOFFSETTOPTR(skin_buffer, element->data); |
626 | return token->value.i; | 640 | if (token) |
641 | return token->value.i; | ||
627 | } | 642 | } |
628 | else if (element->type == CONDITIONAL) | 643 | else if (element->type == CONDITIONAL) |
629 | { | 644 | { |
@@ -726,8 +741,11 @@ void skin_render_viewport(struct skin_element* viewport, struct gui_wps *gwps, | |||
726 | while (imglist) | 741 | while (imglist) |
727 | { | 742 | { |
728 | struct wps_token *token = SKINOFFSETTOPTR(skin_buffer, imglist->token); | 743 | struct wps_token *token = SKINOFFSETTOPTR(skin_buffer, imglist->token); |
729 | struct gui_img *img = (struct gui_img *)SKINOFFSETTOPTR(skin_buffer, token->value.data); | 744 | if (token) { |
730 | img->display = -1; | 745 | struct gui_img *img = (struct gui_img *)SKINOFFSETTOPTR(skin_buffer, token->value.data); |
746 | if (img) | ||
747 | img->display = -1; | ||
748 | } | ||
731 | imglist = SKINOFFSETTOPTR(skin_buffer, imglist->next); | 749 | imglist = SKINOFFSETTOPTR(skin_buffer, imglist->next); |
732 | } | 750 | } |
733 | 751 | ||
@@ -756,7 +774,6 @@ void skin_render_viewport(struct skin_element* viewport, struct gui_wps *gwps, | |||
756 | align->center = NULL; | 774 | align->center = NULL; |
757 | align->right = NULL; | 775 | align->right = NULL; |
758 | 776 | ||
759 | |||
760 | if (line->type == LINE_ALTERNATOR) | 777 | if (line->type == LINE_ALTERNATOR) |
761 | func = skin_render_alternator; | 778 | func = skin_render_alternator; |
762 | else if (line->type == LINE) | 779 | else if (line->type == LINE) |
@@ -819,9 +836,10 @@ void skin_render(struct gui_wps *gwps, unsigned refresh_mode) | |||
819 | display->clear_viewport(); | 836 | display->clear_viewport(); |
820 | } | 837 | } |
821 | } | 838 | } |
822 | |||
823 | viewport = SKINOFFSETTOPTR(skin_buffer, data->tree); | 839 | viewport = SKINOFFSETTOPTR(skin_buffer, data->tree); |
840 | if (!viewport) return; | ||
824 | skin_viewport = SKINOFFSETTOPTR(skin_buffer, viewport->data); | 841 | skin_viewport = SKINOFFSETTOPTR(skin_buffer, viewport->data); |
842 | if (!skin_viewport) return; | ||
825 | label = SKINOFFSETTOPTR(skin_buffer, skin_viewport->label); | 843 | label = SKINOFFSETTOPTR(skin_buffer, skin_viewport->label); |
826 | if (skin_viewport->label == VP_DEFAULT_LABEL) | 844 | if (skin_viewport->label == VP_DEFAULT_LABEL) |
827 | label = VP_DEFAULT_LABEL_STRING; | 845 | label = VP_DEFAULT_LABEL_STRING; |
@@ -833,8 +851,10 @@ void skin_render(struct gui_wps *gwps, unsigned refresh_mode) | |||
833 | viewport; | 851 | viewport; |
834 | viewport = SKINOFFSETTOPTR(skin_buffer, viewport->next)) | 852 | viewport = SKINOFFSETTOPTR(skin_buffer, viewport->next)) |
835 | { | 853 | { |
854 | |||
836 | /* SETUP */ | 855 | /* SETUP */ |
837 | skin_viewport = SKINOFFSETTOPTR(skin_buffer, viewport->data); | 856 | skin_viewport = SKINOFFSETTOPTR(skin_buffer, viewport->data); |
857 | if (!skin_viewport) continue; | ||
838 | unsigned vp_refresh_mode = refresh_mode; | 858 | unsigned vp_refresh_mode = refresh_mode; |
839 | #if (LCD_DEPTH > 1) || (defined(HAVE_REMOTE_LCD) && LCD_REMOTE_DEPTH > 1) | 859 | #if (LCD_DEPTH > 1) || (defined(HAVE_REMOTE_LCD) && LCD_REMOTE_DEPTH > 1) |
840 | if (skin_viewport->output_to_backdrop_buffer) | 860 | if (skin_viewport->output_to_backdrop_buffer) |