From 908a179726d010963f4fe1b57fb5f7bf590d7d64 Mon Sep 17 00:00:00 2001
From: Kim Woelders <kim@woelders.dk>
Date: Tue, 31 Dec 2013 18:13:45 +0100
Subject: [PATCH 2/5] GIF loader: Simplify error handling.

Also:
- Fix memory leak when image data allocation fails.
- Some aux data arrays may as well be const.
---
 src/modules/loaders/loader_gif.c | 80 ++++++++++++++++------------------------
 1 file changed, 32 insertions(+), 48 deletions(-)

diff --git a/src/modules/loaders/loader_gif.c b/src/modules/loaders/loader_gif.c
index d1c2ae2..a39c860 100644
--- a/src/modules/loaders/loader_gif.c
+++ b/src/modules/loaders/loader_gif.c
@@ -8,6 +8,9 @@ char
 load(ImlibImage * im, ImlibProgressFunction progress, char progress_granularity,
      char immediate_load)
 {
+   static const int    intoffset[] = { 0, 4, 2, 1 };
+   static const int    intjump[] = { 8, 8, 4, 2 };
+   int                 rc;
    DATA32             *ptr;
    GifFileType        *gif;
    GifRowType         *rows;
@@ -16,8 +19,6 @@ load(ImlibImage * im, ImlibProgressFunction progress, char progress_granularity,
    int                 i, j, done, bg, r, g, b, w = 0, h = 0;
    float               per = 0.0, per_inc;
    int                 last_per = 0, last_y = 0;
-   int                 intoffset[] = { 0, 4, 2, 1 };
-   int                 intjump[] = { 8, 8, 4, 2 };
    int                 transp;
    int                 fd;
 
@@ -49,6 +50,8 @@ load(ImlibImage * im, ImlibProgressFunction progress, char progress_granularity,
         return 0;
      }
 
+   rc = 0;                      /* Failure */
+
    do
      {
         if (DGifGetRecordType(gif, &rec) == GIF_ERROR)
@@ -66,37 +69,19 @@ load(ImlibImage * im, ImlibProgressFunction progress, char progress_granularity,
              w = gif->Image.Width;
              h = gif->Image.Height;
              if (!IMAGE_DIMENSIONS_OK(w, h))
-               {
-                  DGifCloseFile(gif);
-                  return 0;
-               }
-             rows = malloc(h * sizeof(GifRowType *));
+                goto quit2;
+
+             rows = calloc(h, sizeof(GifRowType *));
              if (!rows)
-               {
-                  DGifCloseFile(gif);
-                  return 0;
-               }
-             for (i = 0; i < h; i++)
-               {
-                  rows[i] = NULL;
-               }
+                goto quit2;
+
              for (i = 0; i < h; i++)
                {
                   rows[i] = malloc(w * sizeof(GifPixelType));
                   if (!rows[i])
-                    {
-                       DGifCloseFile(gif);
-                       for (i = 0; i < h; i++)
-                         {
-                            if (rows[i])
-                              {
-                                 free(rows[i]);
-                              }
-                         }
-                       free(rows);
-                       return 0;
-                    }
+                     goto quit;
                }
+
              if (gif->Image.Interlace)
                {
                   for (i = 0; i < 4; i++)
@@ -135,6 +120,7 @@ load(ImlibImage * im, ImlibProgressFunction progress, char progress_granularity,
           }
      }
    while (rec != TERMINATE_RECORD_TYPE);
+
    if (transp >= 0)
      {
         SET_FLAG(im->flags, F_HAS_ALPHA);
@@ -143,6 +129,7 @@ load(ImlibImage * im, ImlibProgressFunction progress, char progress_granularity,
      {
         UNSET_FLAG(im->flags, F_HAS_ALPHA);
      }
+
    /* set the format string member to the lower-case full extension */
    /* name for the format - so example names would be: */
    /* "png", "jpeg", "tiff", "ppm", "pgm", "pbm", "gif", "xpm" ... */
@@ -150,17 +137,15 @@ load(ImlibImage * im, ImlibProgressFunction progress, char progress_granularity,
    im->h = h;
    if (!im->format)
       im->format = strdup("gif");
+
    if (im->loader || immediate_load || progress)
      {
         bg = gif->SBackGroundColor;
         cmap = (gif->Image.ColorMap ? gif->Image.ColorMap : gif->SColorMap);
         im->data = (DATA32 *) malloc(sizeof(DATA32) * w * h);
         if (!im->data)
-          {
-             DGifCloseFile(gif);
-             free(rows);
-             return 0;
-          }
+           goto quit;
+
         ptr = im->data;
         per_inc = 100.0 / (((float)w) * h);
         for (i = 0; i < h; i++)
@@ -188,30 +173,29 @@ load(ImlibImage * im, ImlibProgressFunction progress, char progress_granularity,
                        last_per = (int)per;
                        if (!(progress(im, (int)per, 0, last_y, w, i)))
                          {
-                            DGifCloseFile(gif);
-                            for (i = 0; i < h; i++)
-                              {
-                                 free(rows[i]);
-                              }
-                            free(rows);
-                            return 2;
+                            rc = 2;
+                            goto quit;
                          }
                        last_y = i;
                     }
                }
           }
+
+        if (progress)
+           progress(im, 100, 0, last_y, w, h);
      }
-   if (progress)
-     {
-        progress(im, 100, 0, last_y, w, h);
-     }
-   DGifCloseFile(gif);
+
+   rc = 1;                      /* Success */
+
+ quit:
    for (i = 0; i < h; i++)
-     {
-        free(rows[i]);
-     }
+      free(rows[i]);
    free(rows);
-   return 1;
+
+ quit2:
+   DGifCloseFile(gif);
+
+   return rc;
 }
 
 void
-- 
2.3.1