Package: libwebkit-1.0-2
Severity: normal
I am attaching a patch back ported from webkit release branch 1.3.1 that fixes
this issue. I would have gone more upstream but there are too many API changes
really to go that far.
-- System Information:
Debian Release: 6.0.3
APT prefers stable-updates
APT policy: (500, 'stable-updates'), (500, 'stable')
Architecture: i386 (i686)
Kernel: Linux 2.6.32-5-686 (SMP w/1 CPU core)
Locale: LANG=en_GB.utf8, LC_CTYPE=en_GB.utf8 (charmap=UTF-8)
Shell: /bin/sh linked to /bin/dash
Versions of packages libwebkit-1.0-2 depends on:
ii libatk1.0-0 1.30.0-1 The ATK accessibility toolkit
ii libc6 2.11.2-10 Embedded GNU C Library: Shared lib
ii libcairo2 1.8.10-6 The Cairo 2D vector graphics libra
ii libenchant1c2a 1.6.0-1 a wrapper library for various spel
ii libfontconfig1 2.8.0-2.1 generic font configuration library
ii libfreetype6 2.4.2-2.1+squeeze1 FreeType 2 font engine, shared lib
ii libgail18 2.20.1-2 GNOME Accessibility Implementation
ii libgcc1 1:4.4.5-8 GCC support library
ii libglib2.0-0 2.24.2-1 The GLib library of C routines
ii libgstreamer-plugi 0.10.30-1 GStreamer libraries from the "base
ii libgstreamer0.10-0 0.10.30-1 Core GStreamer libraries and eleme
ii libgtk2.0-0 2.20.1-2 The GTK+ graphical user interface
ii libicu44 4.4.1-7 International Components for Unico
ii libjpeg62 6b1-1 The Independent JPEG Group's JPEG
ii libpango1.0-0 1.28.3-1+squeeze2 Layout and rendering of internatio
ii libpng12-0 1.2.44-1+squeeze1 PNG library - runtime
ii libsoup2.4-1 2.30.2-1 an HTTP library implementation in
ii libsqlite3-0 3.7.3-1 SQLite 3 shared library
ii libstdc++6 4.4.5-8 The GNU Standard C++ Library v3
ii libwebkit-1.0-comm 1.2.7-0+squeeze1.1 Web content engine library for Gtk
ii libxml2 2.7.8.dfsg-2+squeeze1 GNOME XML library
ii libxslt1.1 1.1.26-6 XSLT 1.0 processing library - runt
ii libxt6 1:1.0.7-1 X11 toolkit intrinsics library
libwebkit-1.0-2 recommends no packages.
libwebkit-1.0-2 suggests no packages.
-- no debconf information
Backport patch from webkit-1.3.1 to correct non animating and flashing animated gif images.
--- webkit-1.2.7/WebCore/platform/image-decoders/gif/GIFImageDecoder.cpp 2011-02-07 17:29:58.000000000 +0000
+++ webkit-1.3.1/WebCore/platform/image-decoders/gif/GIFImageDecoder.cpp 2011-10-20 21:29:26.000000000 +0100
@@ -235,13 +235,13 @@ bool GIFImageDecoder::haveDecodedRow(uns
return true;
}
-void GIFImageDecoder::frameComplete(unsigned frameIndex, unsigned frameDuration, RGBA32Buffer::FrameDisposalMethod disposalMethod)
+bool GIFImageDecoder::frameComplete(unsigned frameIndex, unsigned frameDuration, RGBA32Buffer::FrameDisposalMethod disposalMethod)
{
// Initialize the frame if necessary. Some GIFs insert do-nothing frames,
// in which case we never reach haveDecodedRow() before getting here.
RGBA32Buffer& buffer = m_frameBufferCache[frameIndex];
if ((buffer.status() == RGBA32Buffer::FrameEmpty) && !initFrameBuffer(frameIndex))
- return;
+ return false; // initFrameBuffer() has already called setFailed().
buffer.setStatus(RGBA32Buffer::FrameComplete);
buffer.setDuration(frameDuration);
@@ -277,6 +277,8 @@ void GIFImageDecoder::frameComplete(unsi
buffer.setHasAlpha(false);
}
}
+
+ return true;
}
void GIFImageDecoder::gifComplete()
@@ -294,7 +296,9 @@ void GIFImageDecoder::decode(unsigned ha
if (!m_reader)
m_reader.set(new GIFImageReader(this));
- if (!m_reader->read((const unsigned char*)m_data->data() + m_readOffset, m_data->size() - m_readOffset, query, haltAtFrame))
+ // If we couldn't decode the image but we've received all the data, decoding
+ // has failed.
+ if (!m_reader->read((const unsigned char*)m_data->data() + m_readOffset, m_data->size() - m_readOffset, query, haltAtFrame) && isAllDataReceived())
setFailed();
if (failed())
@@ -343,8 +347,7 @@ bool GIFImageDecoder::initFrameBuffer(un
if ((prevMethod == RGBA32Buffer::DisposeNotSpecified) || (prevMethod == RGBA32Buffer::DisposeKeep)) {
// Preserve the last frame as the starting state for this frame.
- if (!buffer->copyBitmapData(*prevBuffer));
- return setFailed();
+ buffer->copyBitmapData(*prevBuffer);
} else {
// We want to clear the previous frame to transparent, without
// affecting pixels in the image outside of the frame.
@@ -357,8 +360,7 @@ bool GIFImageDecoder::initFrameBuffer(un
return setFailed();
} else {
// Copy the whole previous buffer, then clear just its frame.
- if (!buffer->copyBitmapData(*prevBuffer));
- return setFailed();
+ buffer->copyBitmapData(*prevBuffer);
for (int y = prevRect.y(); y < prevRect.bottom(); ++y) {
for (int x = prevRect.x(); x < prevRect.right(); ++x)
buffer->setRGBA(x, y, 0, 0, 0, 0);
--- webkit-1.2.7/WebCore/platform/image-decoders/gif/GIFImageDecoder.h 2010-09-10 14:20:33.000000000 +0100
+++ webkit-1.3.1/WebCore/platform/image-decoders/gif/GIFImageDecoder.h 2011-10-20 21:31:25.000000000 +0100
@@ -54,13 +54,14 @@ namespace WebCore {
// Callbacks from the GIF reader.
void decodingHalted(unsigned bytesLeft);
bool haveDecodedRow(unsigned frameIndex, unsigned char* rowBuffer, unsigned char* rowEnd, unsigned rowNumber, unsigned repeatCount, bool writeTransparentPixels);
- void frameComplete(unsigned frameIndex, unsigned frameDuration, RGBA32Buffer::FrameDisposalMethod disposalMethod);
+ bool frameComplete(unsigned frameIndex, unsigned frameDuration, RGBA32Buffer::FrameDisposalMethod disposalMethod);
void gifComplete();
private:
// If the query is GIFFullQuery, decodes the image up to (but not
// including) |haltAtFrame|. Otherwise, decodes as much as is needed to
- // answer the query, ignoring bitmap data.
+ // answer the query, ignoring bitmap data. If decoding fails but there
+ // is no more data coming, sets the "decode failure" flag.
void decode(unsigned haltAtFrame, GIFQuery);
// Called to initialize the frame buffer with the given index, based on
--- webkit-1.2.7/WebCore/platform/image-decoders/gif/GIFImageReader.cpp 2010-09-10 14:20:33.000000000 +0100
+++ webkit-1.3.1/WebCore/platform/image-decoders/gif/GIFImageReader.cpp 2011-10-20 21:31:46.000000000 +0100
@@ -290,7 +290,9 @@ bool GIFImageReader::do_lzw(const unsign
/* Check for explicit end-of-stream code */
if (code == (clear_code + 1)) {
/* end-of-stream should only appear after all image data */
- return !rows_remaining;
+ if (!rows_remaining)
+ return true;
+ return clientptr ? clientptr->setFailed() : false;
}
if (oldcode == -1) {
@@ -308,13 +310,13 @@ bool GIFImageReader::do_lzw(const unsign
code = oldcode;
if (stackp == stack + MAX_BITS)
- return false;
+ return clientptr ? clientptr->setFailed() : false;
}
while (code >= clear_code)
{
if (code >= MAX_BITS || code == prefix[code])
- return false;
+ return clientptr ? clientptr->setFailed() : false;
// Even though suffix[] only holds characters through suffix[avail - 1],
// allowing code >= avail here lets us be more tolerant of malformed
@@ -324,7 +326,7 @@ bool GIFImageReader::do_lzw(const unsign
code = prefix[code];
if (stackp == stack + MAX_BITS)
- return false;
+ return clientptr ? clientptr->setFailed() : false;
}
*stackp++ = firstchar = suffix[code];
@@ -415,7 +417,7 @@ bool GIFImageReader::read(const unsigned
bytes_to_consume -= l;
if (clientptr)
clientptr->decodingHalted(0);
- return true;
+ return false;
}
// Reset hold buffer count
bytes_in_hold = 0;
@@ -440,10 +442,9 @@ bool GIFImageReader::read(const unsigned
switch (state)
{
case gif_lzw:
- if (!do_lzw(q)) {
- state = gif_error;
- break;
- }
+ if (!do_lzw(q))
+ return false; // If do_lzw() encountered an error, it has already called
+ // clientptr->setFailed().
GETN(1, gif_sub_block);
break;
@@ -454,15 +455,11 @@ bool GIFImageReader::read(const unsigned
// 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;
- }
+ if (datasize >= MAX_LZW_BITS)
+ return clientptr ? clientptr->setFailed() : false;
int clear_code = 1 << datasize;
- if (clear_code >= MAX_BITS) {
- state = gif_error;
- break;
- }
+ if (clear_code >= MAX_BITS)
+ return clientptr ? clientptr->setFailed() : false;
if (frame_reader) {
frame_reader->datasize = datasize;
@@ -498,10 +495,8 @@ bool GIFImageReader::read(const unsigned
version = 89;
else if (!strncmp((char*)q, "GIF87a", 6))
version = 87;
- else {
- state = gif_error;
- break;
- }
+ else
+ return clientptr ? clientptr->setFailed() : false;
GETN(7, gif_global_header);
}
break;
@@ -562,7 +557,7 @@ bool GIFImageReader::read(const unsigned
case gif_image_start:
{
if (*q == ';') { /* terminator */
- state = gif_done;
+ GETN(0, gif_done);
break;
}
@@ -576,21 +571,10 @@ bool GIFImageReader::read(const unsigned
* between blocks. The GIF87a spec tells us to keep reading
* until we find an image separator, but GIF89a says such
* a file is corrupt. We follow GIF89a and bail out. */
- if (*q != ',') {
- if (images_decoded > 0) {
- /* The file is corrupt, but one or more images have
- * been decoded correctly. In this case, we proceed
- * as if the file were correctly terminated and set
- * the state to gif_done, so the GIF will display.
- */
- state = gif_done;
- } else {
- /* No images decoded, there is nothing to display. */
- state = gif_error;
- }
- break;
- } else
- GETN(9, gif_image_header);
+ if (*q != ',')
+ return clientptr ? clientptr->setFailed() : false;
+
+ GETN(9, gif_image_header);
}
break;
@@ -714,7 +698,7 @@ bool GIFImageReader::read(const unsigned
GETN(1, gif_netscape_extension_block);
} else {
// 0,3-7 are yet to be defined netscape extension codes
- state = gif_error;
+ return clientptr ? clientptr->setFailed() : false;
}
break;
@@ -755,10 +739,8 @@ bool GIFImageReader::read(const unsigned
if (!height || !width) {
height = screen_height;
width = screen_width;
- if (!height || !width) {
- state = gif_error;
- break;
- }
+ if (!height || !width)
+ return clientptr ? clientptr->setFailed() : false;
}
if (query == GIFImageDecoder::GIFSizeQuery || haltAtFrame == images_decoded) {
@@ -794,10 +776,8 @@ bool GIFImageReader::read(const unsigned
frame_reader->rowbuf = new unsigned char[screen_width];
}
- if (!frame_reader->rowbuf) {
- state = gif_oom;
- break;
- }
+ if (!frame_reader->rowbuf)
+ return clientptr ? clientptr->setFailed() : false;
if (screen_height < height)
screen_height = height;
@@ -838,10 +818,8 @@ bool GIFImageReader::read(const unsigned
if (frame_reader && (!map || (num_colors > frame_reader->local_colormap_size))) {
delete []map;
map = new unsigned char[size];
- if (!map) {
- state = gif_oom;
- break;
- }
+ if (!map)
+ return clientptr ? clientptr->setFailed() : false;
}
/* Switch to the new local palette after it loads */
@@ -893,8 +871,9 @@ bool GIFImageReader::read(const unsigned
images_decoded++;
// CALLBACK: The frame is now complete.
- if (clientptr && frame_reader)
- clientptr->frameComplete(images_decoded - 1, frame_reader->delay_time, frame_reader->disposal_method);
+ if (clientptr && frame_reader && !clientptr->frameComplete(images_decoded - 1, frame_reader->delay_time, frame_reader->disposal_method))
+ return false; // frameComplete() has already called
+ // clientptr->setFailed().
/* Clear state from this image */
if (frame_reader) {
@@ -913,14 +892,6 @@ bool GIFImageReader::read(const unsigned
clientptr->gifComplete();
return true;
- // Handle out of memory errors
- case gif_oom:
- return false;
-
- // Handle general errors
- case gif_error:
- return false;
-
// We shouldn't ever get here.
default:
break;
@@ -945,5 +916,5 @@ bool GIFImageReader::read(const unsigned
if (clientptr)
clientptr->decodingHalted(0);
- return true;
+ return false;
}
--- webkit-1.2.7/WebCore/platform/image-decoders/gif/GIFImageReader.h 2010-09-10 14:20:33.000000000 +0100
+++ webkit-1.3.1/WebCore/platform/image-decoders/gif/GIFImageReader.h 2011-10-20 21:32:05.000000000 +0100
@@ -69,8 +69,6 @@ typedef enum {
gif_consume_block,
gif_skip_block,
gif_done,
- gif_oom,
- gif_error,
gif_comment_extension,
gif_application_extension,
gif_netscape_extension_block,