Sanity checks in load_info_about_label_surface()

Avoid crashes when coming across unexpected Label data stored within
a saved PNG image.
(h/t Donny Sianipar for the report & sample image)
This commit is contained in:
Bill Kendrick 2022-04-02 17:29:22 -07:00
parent b8429734de
commit 347a9b5cc8
2 changed files with 184 additions and 150 deletions

View file

@ -7,7 +7,7 @@ Various contributors (see below, and AUTHORS.txt)
http://www.tuxpaint.org/ http://www.tuxpaint.org/
2022.March.30 (0.9.28) 2022.April.2 (0.9.28)
* Improvements to "Paint" and "Lines" tools: * Improvements to "Paint" and "Lines" tools:
------------------------------------------ ------------------------------------------
* Brush spacing may now be altered within Tux Paint. * Brush spacing may now be altered within Tux Paint.
@ -188,6 +188,11 @@ http://www.tuxpaint.org/
saved drawing. (Affected Windows only.) saved drawing. (Affected Windows only.)
Bill Kendrick <bill@newbreedsoftware.com> Bill Kendrick <bill@newbreedsoftware.com>
* Avoid crashes when coming across unexpected Label data stored within
a saved PNG image.
(h/t Donny Sianipar for the report & sample image)
Bill Kendrick <bill@newbreedsoftware.com>
* Ports & Building: * Ports & Building:
----------------- -----------------
* Windows * Windows

View file

@ -22,7 +22,7 @@
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
(See COPYING.txt) (See COPYING.txt)
June 14, 2002 - March 17, 2022 June 14, 2002 - April 2, 2022
*/ */
#include "platform.h" #include "platform.h"
@ -24168,12 +24168,12 @@ static void load_info_about_label_surface(FILE * lfi)
int tmp_fscanf_return; int tmp_fscanf_return;
char *tmp_fgets_return; char *tmp_fgets_return;
Uint8 a; Uint8 a;
wchar_t *wtmpstr;
size_t nwchar;
#ifdef WIN32 #ifdef WIN32
char *tmpstr; char *tmpstr;
wchar_t *wtmpstr;
#endif #endif
/* Clear label surface */ /* Clear label surface */
SDL_FillRect(label, NULL, SDL_MapRGBA(label->format, 0, 0, 0, 0)); SDL_FillRect(label, NULL, SDL_MapRGBA(label->format, 0, 0, 0, 0));
@ -24194,6 +24194,13 @@ static void load_info_about_label_surface(FILE * lfi)
/* Read count of label nodes: */ /* Read count of label nodes: */
tmp_fscanf_return = fscanf(lfi, "%d\n", &list_ctr); tmp_fscanf_return = fscanf(lfi, "%d\n", &list_ctr);
if (list_ctr <= 0)
{
fprintf(stderr, "Unexpected! Count of label notes is <= 0 (%d)!\n", list_ctr);
fclose(lfi);
return;
}
/* Read saved canvas width/height, so we can scale to the current canvas /* Read saved canvas width/height, so we can scale to the current canvas
(in case it changed due to window size / fullscreen resolution changes, (in case it changed due to window size / fullscreen resolution changes,
larger UI button size, etc. */ larger UI button size, etc. */
@ -24201,6 +24208,13 @@ static void load_info_about_label_surface(FILE * lfi)
tmp_fscanf_return = fscanf(lfi, "%d\n\n", &tmp_scale_h); tmp_fscanf_return = fscanf(lfi, "%d\n\n", &tmp_scale_h);
(void)tmp_fscanf_return; (void)tmp_fscanf_return;
if (tmp_scale_w <= 0 || tmp_scale_h <= 0)
{
fprintf(stderr, "Unexpected! Saved canvas dimensions %d x %d!\n", tmp_scale_w, tmp_scale_h);
fclose(lfi);
return;
}
/* Calculate canvas aspect ratios & such */ /* Calculate canvas aspect ratios & such */
old_width = tmp_scale_w; old_width = tmp_scale_w;
old_height = tmp_scale_h; old_height = tmp_scale_h;
@ -24214,15 +24228,16 @@ static void load_info_about_label_surface(FILE * lfi)
new_to_old_ratio = (float)new_height / old_height; new_to_old_ratio = (float)new_height / old_height;
/* Read the labels' text: */ wtmpstr = malloc(1024);
size_t nwchar;
#ifdef WIN32 #ifdef WIN32
tmpstr = malloc(1024); tmpstr = malloc(1024);
wtmpstr = malloc(1024);
#endif #endif
/* Read the labels' text: */
for (k = 0; k < list_ctr; k++) for (k = 0; k < list_ctr; k++)
{ {
new_node = malloc(sizeof(struct label_node)); new_node = malloc(sizeof(struct label_node));
@ -24233,6 +24248,19 @@ static void load_info_about_label_surface(FILE * lfi)
printf("Reading %d wide chars\n", new_node->save_texttool_len); fflush(stdout); printf("Reading %d wide chars\n", new_node->save_texttool_len); fflush(stdout);
#endif #endif
if (new_node->save_texttool_len >= 1024)
{
fprintf(stderr, "Unexpected! Saved text length is >= 1024 (%u!)\n", new_node->save_texttool_len);
free(new_node);
free(wtmpstr);
#ifdef WIN32
free(tmpstr);
#endif
fclose(lfi);
return;
}
else
{
#ifdef WIN32 #ifdef WIN32
/* Using fancy "%[]" operator to scan until the end of a line */ /* Using fancy "%[]" operator to scan until the end of a line */
tmp_fscanf_return = fscanf(lfi, "%[^\n]\n", tmpstr); tmp_fscanf_return = fscanf(lfi, "%[^\n]\n", tmpstr);
@ -24254,12 +24282,12 @@ static void load_info_about_label_surface(FILE * lfi)
nwchar = wcslen(new_node->save_texttool_str); nwchar = wcslen(new_node->save_texttool_str);
if (nwchar < new_node->save_texttool_len) if (nwchar < new_node->save_texttool_len)
{ {
wchar_t *wtmpstr;
size_t diff, i; size_t diff, i;
wtmpstr = malloc(1024);
diff = new_node->save_texttool_len - nwchar; diff = new_node->save_texttool_len - nwchar;
printf("diff = %d\n", diff); fflush(stdout);
for (i = 0; i < diff; i++) for (i = 0; i < diff; i++)
wtmpstr[i] = L' '; wtmpstr[i] = L' ';
@ -24267,7 +24295,6 @@ static void load_info_about_label_surface(FILE * lfi)
wtmpstr[i + diff] = new_node->save_texttool_str[i]; wtmpstr[i + diff] = new_node->save_texttool_str[i];
memcpy(new_node->save_texttool_str, wtmpstr, sizeof(wchar_t) * (new_node->save_texttool_len + 1)); memcpy(new_node->save_texttool_str, wtmpstr, sizeof(wchar_t) * (new_node->save_texttool_len + 1));
free(wtmpstr);
#ifdef DEBUG #ifdef DEBUG
printf("Fixed \"%ls\"\n", new_node->save_texttool_str); fflush(stdout); printf("Fixed \"%ls\"\n", new_node->save_texttool_str); fflush(stdout);
@ -24317,6 +24344,7 @@ static void load_info_about_label_surface(FILE * lfi)
/* Read the label's font */ /* Read the label's font */
tmp_fscanf_return = fscanf(lfi, "%d\n", &new_node->save_cur_font); tmp_fscanf_return = fscanf(lfi, "%d\n", &new_node->save_cur_font);
/* FIXME: This seems wrong! -bjk 2022.04.02 */
new_node->save_cur_font = 0; new_node->save_cur_font = 0;
new_node->save_font_type = malloc(64); new_node->save_font_type = malloc(64);
@ -24392,16 +24420,17 @@ static void load_info_about_label_surface(FILE * lfi)
highlighted_label_node = current_label_node; highlighted_label_node = current_label_node;
simply_render_node(current_label_node); simply_render_node(current_label_node);
} }
}
first_label_node_in_redo_stack = NULL; first_label_node_in_redo_stack = NULL;
fclose(lfi); fclose(lfi);
free(wtmpstr);
#ifdef WIN32 #ifdef WIN32
free(tmpstr); free(tmpstr);
free(wtmpstr);
#endif #endif
if (font_thread_done) if (font_thread_done)
set_label_fonts(); set_label_fonts();
} }