summaryrefslogtreecommitdiffstats
path: root/WebCore/platform/image-decoders/gif/GIFImageReader.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'WebCore/platform/image-decoders/gif/GIFImageReader.cpp')
-rw-r--r--WebCore/platform/image-decoders/gif/GIFImageReader.cpp21
1 files changed, 15 insertions, 6 deletions
diff --git a/WebCore/platform/image-decoders/gif/GIFImageReader.cpp b/WebCore/platform/image-decoders/gif/GIFImageReader.cpp
index 95ab40d..002f67a 100644
--- a/WebCore/platform/image-decoders/gif/GIFImageReader.cpp
+++ b/WebCore/platform/image-decoders/gif/GIFImageReader.cpp
@@ -311,9 +311,13 @@ int GIFImageReader::do_lzw(const unsigned char *q)
while (code >= clear_code)
{
- if (code == prefix[code])
+ if (code >= MAX_BITS || code == prefix[code])
return -1;
+ // Even though suffix[] only holds characters through suffix[avail - 1],
+ // allowing code >= avail here lets us be more tolerant of malformed
+ // data. As long as code < MAX_BITS, the only risk is a garbled image,
+ // which is no worse than refusing to display it.
*stackp++ = suffix[code];
code = prefix[code];
@@ -445,7 +449,10 @@ bool GIFImageReader::read(const unsigned char *buf, unsigned len,
{
/* Initialize LZW parser/decoder */
int datasize = *q;
- if (datasize > MAX_LZW_BITS) {
+ // Since we use a codesize of 1 more than the datasize, we need to ensure
+ // that our datasize is strictly less than the MAX_LZW_BITS value (12).
+ // This sets the largest possible codemask correctly at 4095.
+ if (datasize >= MAX_LZW_BITS) {
state = gif_error;
break;
}
@@ -468,6 +475,8 @@ bool GIFImageReader::read(const unsigned char *buf, unsigned len,
/* init the tables */
if (!frame_reader->suffix)
frame_reader->suffix = new unsigned char[MAX_BITS];
+ // Clearing the whole suffix table lets us be more tolerant of bad data.
+ memset(frame_reader->suffix, 0, MAX_BITS);
for (int i = 0; i < frame_reader->clear_code; i++)
frame_reader->suffix[i] = i;
@@ -508,8 +517,8 @@ bool GIFImageReader::read(const unsigned char *buf, unsigned len,
screen_height = GETINT16(q + 2);
// CALLBACK: Inform the decoderplugin of our size.
- if (clientptr)
- clientptr->sizeNowAvailable(screen_width, screen_height);
+ if (clientptr && !clientptr->sizeNowAvailable(screen_width, screen_height))
+ return false;
screen_bgcolor = q[5];
global_colormap_size = 2<<(q[4]&0x07);
@@ -734,8 +743,8 @@ bool GIFImageReader::read(const unsigned char *buf, unsigned len,
y_offset = 0;
// CALLBACK: Inform the decoderplugin of our size.
- if (clientptr)
- clientptr->sizeNowAvailable(screen_width, screen_height);
+ if (clientptr && !clientptr->sizeNowAvailable(screen_width, screen_height))
+ return false;
}
/* Work around more broken GIF files that have zero image