Fill: Avoid infinite recursion crash
simulate_flood_fill_outside_check() could spin in an infinite loop because it could sometimes set values in the `touched[]` array to 0, which means the spot was never seen. Values going in there are not boolean, but a 0-255 gradient, for smoother fills on antialiased edges. This change forces it to be a 1-255 value, ensuring that a 'touched' spot on the canvas will have a non-zero `touched[]` value. h/t Pere for noticing the bug, providing some details, and best of all providing a sample image to play with which consistently invoked the crash. (It made mending this a 10 minute task for me, rather than an hours-long hunt to reproduce! Big 'thanks' for doing that ahead of time!!!)
This commit is contained in:
parent
6568cbb433
commit
2ce07ac9de
1 changed files with 23 additions and 6 deletions
29
src/fill.c
29
src/fill.c
|
|
@ -4,7 +4,7 @@
|
|||
Fill tool
|
||||
Tux Paint - A simple drawing program for children.
|
||||
|
||||
Copyright (c) 2002-2019 by Bill Kendrick and others; see AUTHORS.txt
|
||||
Copyright (c) 2002-2021 by Bill Kendrick and others; see AUTHORS.txt
|
||||
bill@newbreedsoftware.com
|
||||
http://www.tuxpaint.org/
|
||||
|
||||
|
|
@ -27,7 +27,7 @@
|
|||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
(See COPYING.txt)
|
||||
|
||||
Last updated: March 8, 2021
|
||||
Last updated: May 5, 2021
|
||||
$Id$
|
||||
*/
|
||||
|
||||
|
|
@ -137,6 +137,7 @@ void simulate_flood_fill_outside_check(SDL_Surface * screen, SDL_Surface * last,
|
|||
double in_line, closeness;
|
||||
static unsigned char prog_anim;
|
||||
Uint32 px_colr;
|
||||
Uint8 touch_byt;
|
||||
|
||||
|
||||
/* "Same" color? No need to fill */
|
||||
|
|
@ -187,7 +188,11 @@ void simulate_flood_fill_outside_check(SDL_Surface * screen, SDL_Surface * last,
|
|||
}
|
||||
|
||||
if (touched != NULL) {
|
||||
touched[(y * canvas->w) + fillL] = (255 - ((Uint8) (in_line * 85)));
|
||||
touch_byt = (255 - ((Uint8) (in_line * 85)));
|
||||
if (touch_byt == 0)
|
||||
touch_byt = 1;
|
||||
|
||||
touched[(y * canvas->w) + fillL] = touch_byt;
|
||||
}
|
||||
|
||||
px_colr = getpixels[last->format->BytesPerPixel] (last, fillL, y);
|
||||
|
|
@ -210,7 +215,11 @@ void simulate_flood_fill_outside_check(SDL_Surface * screen, SDL_Surface * last,
|
|||
{
|
||||
if (touched != NULL)
|
||||
{
|
||||
touched[(y * canvas->w) + fillL] = (255 - ((Uint8) (in_line * 85)));
|
||||
touch_byt = (255 - ((Uint8) (in_line * 85)));
|
||||
if (touch_byt == 0)
|
||||
touch_byt = 1;
|
||||
|
||||
touched[(y * canvas->w) + fillL] = touch_byt;
|
||||
}
|
||||
|
||||
px_colr = getpixels[last->format->BytesPerPixel] (last, fillL, y);
|
||||
|
|
@ -240,7 +249,11 @@ void simulate_flood_fill_outside_check(SDL_Surface * screen, SDL_Surface * last,
|
|||
}
|
||||
|
||||
if (touched != NULL) {
|
||||
touched[(y * canvas->w) + fillR] = (255 - ((Uint8) (in_line * 85)));
|
||||
touch_byt = (255 - ((Uint8) (in_line * 85)));
|
||||
if (touch_byt == 0)
|
||||
touch_byt = 1;
|
||||
|
||||
touched[(y * canvas->w) + fillR] = touch_byt;
|
||||
}
|
||||
|
||||
px_colr = getpixels[last->format->BytesPerPixel] (last, fillR, y);
|
||||
|
|
@ -263,7 +276,11 @@ void simulate_flood_fill_outside_check(SDL_Surface * screen, SDL_Surface * last,
|
|||
{
|
||||
if (touched != NULL)
|
||||
{
|
||||
touched[(y * canvas->w) + fillR] = (255 - ((Uint8) (in_line * 85)));
|
||||
touch_byt = (255 - ((Uint8) (in_line * 85)));
|
||||
if (touch_byt == 0)
|
||||
touch_byt = 1;
|
||||
|
||||
touched[(y * canvas->w) + fillR] = touch_byt;
|
||||
}
|
||||
|
||||
px_colr = getpixels[last->format->BytesPerPixel] (last, fillR, y);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue