pkgsrc-Bugs archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: pkg/48074 (libgdiplus fails build with the latest giflib)



The following reply was made to PR pkg/48074; it has been noted by GNATS.

From: Onno van der Linden <o.vd.linden%quicknet.nl@localhost>
To: gnats-bugs%netbsd.org@localhost
Cc: 
Subject: Re: pkg/48074 (libgdiplus fails build with the latest giflib)
Date: Sun, 5 Jan 2014 15:30:52 +0100

 Yes it compiles. But it can cause a crash due to calling
 DGifGetExtension() with 
 &temp_save.ExtensionBlocks[temp_save.ExtensionBlockCount].Function
 as the second parameter.
 
 If the ExtensionBlocks pointer is NULL .........
 
 Here's one line from a mono stack trace and some debug output
 with some printfs in libgdiplus' DGifSlurpMono() and in
 giflib's DGifGetExtension()
 
 $ mono /usr/local/CUETools_2.1.5/CUETools.exe 
 ExtensionBlockCount = 0 ExtensionBlocks = 0x0 <----------
 GifFile = 0xb9595380 ExtCode = 0x8 Extension = 0xbfbfd8d8
 Before IS_READABLE
 Before READ
 Before *ExtCode
 Stacktrace:
 
   at (wrapper managed-to-native) 
System.Drawing.GDIPlus.GdipLoadImageFromDelegate_linux 
(System.Drawing.GDIPlus/StreamGetHeaderDelegate,System.Drawing.GDIPlus/StreamGetBytesDelegate,System.Drawing.GDIPlus/StreamPutBytesDelegate,System.Drawing.GDIPlus/StreamSeekDelegate,System.Drawing.GDIPlus/StreamCloseDelegate,System.Drawing.GDIPlus/StreamSizeDelegate,intptr&)
 <0xffffffff>
 
 Here's the (complete) gifcodec diff which seems to work for me:
 
 
 --- gifcodec.c.orig    2011-01-13 23:28:19.000000000 +0100
 +++ gifcodec.c 2014-01-05 15:23:43.000000000 +0100
 @@ -39,8 +39,12 @@
  
  #include "gifcodec.h"
  
 -/* giflib declares this incorrectly as EgifOpen */
 +/* giflib declares this incorrectly as EgifOpen up to 4.1.2
 +   GIF_LIB_VERSION is defined up to 4.1.6, and prototype is changed in 5.0,
 +   so it is safe to use it as check condition */
 +#ifdef GIF_LIB_VERSION
  extern GifFileType *EGifOpen(void *userData, OutputFunc writeFunc);
 +#endif
  
  /* Data structure used for callback */
  typedef struct
 @@ -105,7 +109,7 @@
  */
  
  static int
 -AddExtensionBlockMono(SavedImage *New, int Len, BYTE ExtData[])
 +AddExtensionBlockMono(SavedImage *New, int ExtCode, int Len, BYTE ExtData[])
  {
        ExtensionBlock  *ep;
  
 @@ -129,7 +133,7 @@
  
        if (ExtData) {
                memcpy(ep->Bytes, ExtData, Len);
 -              ep->Function = New->Function;
 +              ep->Function = ExtCode;
        }
  
        return (GIF_OK);
 @@ -232,20 +236,31 @@
                        }
  
                        case EXTENSION_RECORD_TYPE: {
 +#if GIFLIB_MAJOR >= 5
 +                              int ExtCode;
 +                              if (DGifGetExtension(GifFile, &ExtCode, 
&ExtData) == GIF_ERROR) {
 +#else
                                if (DGifGetExtension(GifFile, 
&temp_save.Function, &ExtData) == GIF_ERROR) {
 +#endif
                                        return (GIF_ERROR);
                                }
  
                                while (ExtData != NULL) {
                                        /* Create an extension block with our 
data */
 -                                      if (AddExtensionBlockMono(&temp_save, 
ExtData[0], &ExtData[1]) == GIF_ERROR) {
 +#if GIFLIB_MAJOR >= 5
 +                                      if (AddExtensionBlockMono(&temp_save, 
ExtCode, ExtData[0], &ExtData[1]) == GIF_ERROR) {
 +#else
 +                                      if (AddExtensionBlockMono(&temp_save, 
temp_save.Function  ExtData[0], &ExtData[1]) == GIF_ERROR) {
 +#endif
                                                return (GIF_ERROR);
                                        }
  
                                        if (DGifGetExtensionNext(GifFile, 
&ExtData) == GIF_ERROR) {
                                                return (GIF_ERROR);
                                        }
 +#if GIFLIB_MAJOR < 5
                                        temp_save.Function = 0;
 +#endif
                                }
                                break;
                        }
 @@ -304,9 +319,17 @@
        loop_counter = FALSE;
  
        if (from_file) {
 +#if GIFLIB_MAJOR >= 5
 +              gif = DGifOpen(stream, &gdip_gif_fileinputfunc, NULL);
 +#else 
                gif = DGifOpen(stream, &gdip_gif_fileinputfunc);
 +#endif
        } else {
 +#if GIFLIB_MAJOR >= 5
 +              gif = DGifOpen (stream, &gdip_gif_inputfunc, NULL);
 +#else
                gif = DGifOpen (stream, &gdip_gif_inputfunc);
 +#endif
        }
        
        if (gif == NULL) {
 @@ -662,9 +685,17 @@
        }
  
        if (from_file) {
 +#if GIFLIB_MAJOR >= 5
 +              fp = EGifOpenFileName (stream, 0, NULL);
 +#else
                fp = EGifOpenFileName (stream, 0);
 +#endif
        } else {
 +#if GIFLIB_MAJOR >= 5
 +              fp = EGifOpen (stream, gdip_gif_outputfunc, NULL);
 +#else
                fp = EGifOpen (stream, gdip_gif_outputfunc);
 +#endif
        }
                
        if (!fp) {
 @@ -703,7 +734,11 @@
                                        goto error; 
                                }
  
 +#if GIFLIB_MAJOR >= 5
 +                              cmap = GifMakeMapObject(cmap_size, 0);
 +#else
                                cmap = MakeMapObject(cmap_size, 0);
 +#endif
  
                                pixbuf = GdipAlloc(pixbuf_size);
                                if (pixbuf == NULL) {
 @@ -794,7 +829,11 @@
                                pixbuf = pixbuf_org;
                        } else {
                                cmap_size = 256;
 +#if GIFLIB_MAJOR >= 5
 +                              cmap  = GifMakeMapObject (cmap_size, 0);
 +#else
                                cmap  = MakeMapObject (cmap_size, 0);
 +#endif
  
                                red = GdipAlloc(pixbuf_size);
                                green = GdipAlloc(pixbuf_size);
 @@ -825,13 +864,21 @@
                                                v += 4;
                                        }
                                }
 +#if GIFLIB_MAJOR >= 5
 +                              if (GifQuantizeBuffer(bitmap_data->width, 
bitmap_data->height, &cmap_size, 
 +#else
                                if (QuantizeBuffer(bitmap_data->width, 
bitmap_data->height, &cmap_size, 
 +#endif
                                                red,  green, blue, pixbuf, 
cmap->Colors) == GIF_ERROR) {
                                        goto error;
                                }
                        }
  
 +#if GIFLIB_MAJOR >= 5
 +                      cmap->BitsPerPixel = GifBitSize (cmap_size);
 +#else
                        cmap->BitsPerPixel = BitSize (cmap_size);
 +#endif
                        cmap->ColorCount = 1 << cmap->BitsPerPixel;
  
                        if ((frame == 0) && (k == 0)) {
 @@ -849,8 +896,15 @@
                                                Buffer[0] = 1;
                                                Buffer[1] = ptr[0];
                                                Buffer[2] = ptr[1];
 +#if GIFLIB_MAJOR >= 5
 +                                              EGifPutExtensionLeader(fp, 
APPLICATION_EXT_FUNC_CODE);
 +                                              EGifPutExtensionBlock(fp, 11, 
"NETSCAPE2.0");
 +                                              EGifPutExtensionBlock(fp, 3, 
Buffer);
 +                                              EGifPutExtensionTrailer(fp);
 +#else
                                                EGifPutExtensionFirst(fp, 
APPLICATION_EXT_FUNC_CODE, 11, "NETSCAPE2.0");
                                                EGifPutExtensionLast(fp, 
APPLICATION_EXT_FUNC_CODE, 3, Buffer);
 +#endif
                                        }
                                }
  
 @@ -902,7 +956,11 @@
                                pixbuf += bitmap_data->width;
                        }
  
 +#if GIFLIB_MAJOR >= 5
 +                      GifFreeMapObject (cmap);
 +#else
                        FreeMapObject (cmap);
 +#endif
                        if (red != NULL) {
                                GdipFree (red);
                        }
 @@ -930,7 +988,11 @@
  
  error:
        if (cmap != NULL) {
 +#if GIFLIB_MAJOR >= 5
 +              GifFreeMapObject (cmap);
 +#else
                FreeMapObject (cmap);
 +#endif
        }
  
        if (red != NULL) {
 


Home | Main Index | Thread Index | Old Index