From: Vadim Zeitlin Date: Thu, 14 Mar 2002 13:55:04 +0000 (+0000) Subject: applied the patch from Dimitri to prevent crashes with (some) interlaced GIFs X-Git-Url: https://git.saurik.com/wxWidgets.git/commitdiff_plain/e34f4f195d204ca8eb94c651f8bed85e1820c368 applied the patch from Dimitri to prevent crashes with (some) interlaced GIFs git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@14590 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- diff --git a/src/common/gifdecod.cpp b/src/common/gifdecod.cpp index db32b8fa25..011d8cf3ad 100644 --- a/src/common/gifdecod.cpp +++ b/src/common/gifdecod.cpp @@ -456,6 +456,15 @@ int wxGIFDecoder::dgif(GIFImage *img, int interl, int bits) return wxGIF_INVFORMAT; } } + + if (pos >= allocSize) + { + delete[] ab_prefix; + delete[] ab_tail; + delete[] stack; + return wxGIF_INVFORMAT; + } + stack[pos] = code; /* push last code into the stack */ abcabca = code; /* save for special case */ @@ -473,18 +482,11 @@ int wxGIFDecoder::dgif(GIFImage *img, int interl, int bits) } } - /* dump stack data to the buffer */ + /* dump stack data to the image buffer */ while (pos >= 0) { - if (pos >= allocSize) - { - delete[] ab_prefix; - delete[] ab_tail; - delete[] stack; - return wxGIF_INVFORMAT; - } - - (img->p)[x + (y * (img->w))] = (char)stack[pos--]; + (img->p)[x + (y * (img->w))] = (char) stack[pos]; + pos--; if (++x >= (img->w)) { @@ -500,13 +502,50 @@ int wxGIFDecoder::dgif(GIFImage *img, int interl, int bits) case 3: y += 4; break; case 4: y += 2; break; } - if (y >= (img->h)) + + /* loop until a valid y coordinate has been + found, Or if the maximum number of passes has + been reached, exit the loop, and stop image + decoding (At this point the image is succesfully + decoded). + If we don't loop, but merely set y to some other + value, that new value might still be invalid depending + on the height of the image. This would cause out of + bounds writing. + */ + while (y >= (img->h)) { switch (++pass) { case 2: y = 4; break; case 3: y = 2; break; case 4: y = 1; break; + + default: + /* + It's possible we arrive here. For example this + happens when the image is interlaced, and the + height is 1. Looking at the above cases, the + lowest possible y is 1. While the only valid + one would be 0 for an image of height 1. So + 'eventually' the loop will arrive here. + This case makes sure this while loop is + exited, as well as the 2 other ones. + */ + + // Set y to a valid coordinate so the local + // while loop will be exited. (y = 0 always + // is >= img->h since if img->h == 0 the + // image is never decoded) + y = 0; + + // This will exit the other outer while loop + pos = -1; + + // This will halt image decoding. + code = ab_fin; + + break; } } }