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,

Reply via email to