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
|
Fill tool
|
||||||
Tux Paint - A simple drawing program for children.
|
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
|
bill@newbreedsoftware.com
|
||||||
http://www.tuxpaint.org/
|
http://www.tuxpaint.org/
|
||||||
|
|
||||||
|
|
@ -27,7 +27,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)
|
||||||
|
|
||||||
Last updated: March 8, 2021
|
Last updated: May 5, 2021
|
||||||
$Id$
|
$Id$
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
@ -137,6 +137,7 @@ void simulate_flood_fill_outside_check(SDL_Surface * screen, SDL_Surface * last,
|
||||||
double in_line, closeness;
|
double in_line, closeness;
|
||||||
static unsigned char prog_anim;
|
static unsigned char prog_anim;
|
||||||
Uint32 px_colr;
|
Uint32 px_colr;
|
||||||
|
Uint8 touch_byt;
|
||||||
|
|
||||||
|
|
||||||
/* "Same" color? No need to fill */
|
/* "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) {
|
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);
|
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)
|
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);
|
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) {
|
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);
|
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)
|
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);
|
px_colr = getpixels[last->format->BytesPerPixel] (last, fillR, y);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue