]> git.saurik.com Git - wxWidgets.git/blobdiff - src/common/gifdecod.cpp
fixing overrelease and out-of-bounds write, fixes #13725
[wxWidgets.git] / src / common / gifdecod.cpp
index e8faf7d1dd2773858b43f2078a6fefa21802605c..b853ee97a987f11e9e4eee57b8292318e3927f11 100644 (file)
@@ -40,6 +40,8 @@ enum
     GIF_MARKER_EXT_APP              = 0xFF
 };
 
+#define GetFrame(n)     ((GIFImage*)m_frames[n])
+
 //---------------------------------------------------------------------------
 // GIFImage
 //---------------------------------------------------------------------------
@@ -61,6 +63,7 @@ public:
     unsigned char *p;               // bitmap
     unsigned char *pal;             // palette
     unsigned int ncolours;          // number of colours
+    wxString comment;
 
     wxDECLARE_NO_COPY_CLASS(GIFImage);
 };
@@ -135,7 +138,7 @@ bool wxGIFDecoder::ConvertToImage(unsigned int frame, wxImage *image) const
     image->Create(sz.GetWidth(), sz.GetHeight());
     image->SetType(wxBITMAP_TYPE_GIF);
 
-    if (!image->Ok())
+    if (!image->IsOk())
         return false;
 
     pal = GetPalette(frame);
@@ -189,6 +192,12 @@ bool wxGIFDecoder::ConvertToImage(unsigned int frame, wxImage *image) const
         *(dst++) = pal[3 * (*src) + 2];
     }
 
+    wxString comment = GetFrame(frame)->comment;
+    if ( !comment.empty() )
+    {
+        image->SetOption(wxIMAGE_OPTION_GIF_COMMENT, comment);
+    }
+
     return true;
 }
 
@@ -197,9 +206,6 @@ bool wxGIFDecoder::ConvertToImage(unsigned int frame, wxImage *image) const
 // Data accessors
 //---------------------------------------------------------------------------
 
-#define GetFrame(n)     ((GIFImage*)m_frames[n])
-
-
 // Get data for current frame
 
 wxSize wxGIFDecoder::GetFrameSize(unsigned int frame) const
@@ -348,7 +354,7 @@ wxGIFDecoder::dgif(wxInputStream& stream, GIFImage *img, int interl, int bits)
     ab_clr = (1 << bits);
     ab_fin = (1 << bits) + 1;
 
-    // these will change through the decompression proccess
+    // these will change through the decompression process
     ab_bits  = bits + 1;
     ab_free  = (1 << bits) + 2;
     ab_max   = (1 << ab_bits) - 1;
@@ -672,6 +678,7 @@ wxGIFErrorCode wxGIFDecoder::LoadGIF(wxInputStream& stream)
     int transparent = -1;
     disposal = wxANIM_UNSPECIFIED;
     delay = -1;
+    wxString comment;
 
     bool done = false;
     while (!done)
@@ -701,38 +708,68 @@ wxGIFErrorCode wxGIFDecoder::LoadGIF(wxInputStream& stream)
                 done = true;
                 break;
             case GIF_MARKER_EXT:
-                if (stream.GetC() == GIF_MARKER_EXT_GRAPHICS_CONTROL)
-                // graphics control extension, parse it
+                switch (stream.GetC())
                 {
-                    static const unsigned int gceSize = 6;
-                    stream.Read(buf, gceSize);
-                    if (stream.LastRead() != gceSize)
+                    case GIF_MARKER_EXT_GRAPHICS_CONTROL:
                     {
-                        Destroy();
-                        return wxGIF_INVFORMAT;
-                    }
+                        // graphics control extension, parse it
 
-                    // read delay and convert from 1/100 of a second to ms
-                    delay = 10 * (buf[2] + 256 * buf[3]);
+                        static const unsigned int gceSize = 6;
+                        stream.Read(buf, gceSize);
+                        if (stream.LastRead() != gceSize)
+                        {
+                            Destroy();
+                            return wxGIF_INVFORMAT;
+                        }
 
-                    // read transparent colour index, if used
-                    transparent = buf[1] & 0x01 ? buf[4] : -1;
+                        // read delay and convert from 1/100 of a second to ms
+                        delay = 10 * (buf[2] + 256 * buf[3]);
 
-                    // read disposal method
-                    disposal = (wxAnimationDisposal)(((buf[1] & 0x1C) >> 2) - 1);
-                }
-                else
-                // other extension, skip
-                {
-                    while ((i = stream.GetC()) != 0)
+                        // read transparent colour index, if used
+                        transparent = buf[1] & 0x01 ? buf[4] : -1;
+
+                        // read disposal method
+                        disposal = (wxAnimationDisposal)(((buf[1] & 0x1C) >> 2) - 1);
+                        break;
+                    }
+                    case GIF_MARKER_EXT_COMMENT:
                     {
-                        if (stream.Eof() || (stream.LastRead() == 0) ||
-                            stream.SeekI(i, wxFromCurrent) == wxInvalidOffset)
+                        int len = stream.GetC();
+                        while (len)
                         {
-                            done = true;
-                            break;
+                            if ( stream.Eof() )
+                            {
+                                done = true;
+                                break;
+                            }
+
+                            wxCharBuffer charbuf(len);
+                            stream.Read(charbuf.data(), len);
+                            if ( (int) stream.LastRead() != len )
+                            {
+                                done = true;
+                                break;
+                            }
+
+                            comment += wxConvertMB2WX(charbuf.data());
+
+                            len = stream.GetC();
                         }
+
+                        break;
                     }
+                    default:
+                        // other extension, skip
+                        while ((i = stream.GetC()) != 0)
+                        {
+                            if (stream.Eof() || (stream.LastRead() == 0) ||
+                                stream.SeekI(i, wxFromCurrent) == wxInvalidOffset)
+                            {
+                                done = true;
+                                break;
+                            }
+                        }
+                        break;
                 }
                 break;
             case GIF_MARKER_SEP:
@@ -751,6 +788,8 @@ wxGIFErrorCode wxGIFDecoder::LoadGIF(wxInputStream& stream)
                 if (stream.LastRead() != idbSize)
                     return wxGIF_INVFORMAT;
 
+                pimg->comment = comment;
+                comment.clear();
                 pimg->left = buf[0] + 256 * buf[1];
                 pimg->top = buf[2] + 256 * buf[3];
     /*