From 59c460bb33fbc5fd9d54efc2ecb94bfe0e7b8c40 Mon Sep 17 00:00:00 2001
From: Nils Philippsen <nils@redhat.com>
Date: Thu, 12 Jul 2012 15:50:02 +0200
Subject: [PATCH 1/5] file-cel: check fread()/g_fopen() return values and pass
 on errors (cherry picked from commit
 9b2b8999497c28a4f9152c6d1bc85219d5fdd845)

---
 plug-ins/common/file-cel.c |  190 +++++++++++++++++++++++++++++++++++++-------
 1 file changed, 160 insertions(+), 30 deletions(-)

diff --git a/plug-ins/common/file-cel.c b/plug-ins/common/file-cel.c
index a94671c..83226d4 100644
--- a/plug-ins/common/file-cel.c
+++ b/plug-ins/common/file-cel.c
@@ -44,8 +44,10 @@ static void run   (const gchar      *name,
                    gint             *nreturn_vals,
                    GimpParam       **return_vals);
 
-static gint      load_palette   (FILE         *fp,
-                                 guchar        palette[]);
+static gint      load_palette   (const gchar  *file,
+                                 FILE         *fp,
+                                 guchar        palette[],
+                                 GError      **error);
 static gint32    load_image     (const gchar  *file,
                                  const gchar  *brief,
                                  GError      **error);
@@ -55,7 +57,8 @@ static gboolean  save_image     (const gchar  *file,
                                  gint32        layer,
                                  GError      **error);
 static void      palette_dialog (const gchar  *title);
-static gboolean  need_palette   (const gchar  *file);
+static gboolean  need_palette   (const gchar  *file,
+                                 GError      **error);
 
 
 /* Globals... */
@@ -150,6 +153,7 @@ run (const gchar      *name,
   gint32             image;
   GimpExportReturn   export = GIMP_EXPORT_CANCEL;
   GError            *error  = NULL;
+  gint               needs_palette = 0;
 
   run_mode = param[0].data.d_int32;
 
@@ -187,20 +191,32 @@ run (const gchar      *name,
       else if (run_mode == GIMP_RUN_INTERACTIVE)
         {
           /* Let user choose KCF palette (cancel ignores) */
-          if (need_palette (param[1].data.d_string))
-            palette_dialog (_("Load KISS Palette"));
+          needs_palette = need_palette (param[1].data.d_string, &error);
 
-          gimp_set_data (SAVE_PROC, palette_file, data_length);
-        }
+          if (! error)
+            {
+              if (needs_palette)
+                palette_dialog (_("Load KISS Palette"));
 
-      image = load_image (param[1].data.d_string, param[2].data.d_string,
-                          &error);
+              gimp_set_data (SAVE_PROC, palette_file, data_length);
+            }
+        }
 
-      if (image != -1)
+      if (! error)
         {
-          *nreturn_vals = 2;
-          values[1].type         = GIMP_PDB_IMAGE;
-          values[1].data.d_image = image;
+          image = load_image (param[1].data.d_string, param[2].data.d_string,
+                              &error);
+
+          if (image != -1)
+            {
+              *nreturn_vals = 2;
+              values[1].type         = GIMP_PDB_IMAGE;
+              values[1].data.d_image = image;
+            }
+          else
+            {
+              status = GIMP_PDB_EXECUTION_ERROR;
+            }
         }
       else
         {
@@ -263,18 +279,33 @@ run (const gchar      *name,
 
 /* Peek into the file to determine whether we need a palette */
 static gboolean
-need_palette (const gchar *file)
+need_palette (const gchar *file,
+              GError     **error)
 {
   FILE   *fp;
   guchar  header[32];
+  size_t  n_read;
 
   fp = g_fopen (file, "rb");
-  if (!fp)
-    return FALSE;
+  if (fp == NULL)
+    {
+      g_set_error (error, G_FILE_ERROR, g_file_error_from_errno (errno),
+                   _("Could not open '%s' for reading: %s"),
+                   gimp_filename_to_utf8 (file), g_strerror (errno));
+      return FALSE;
+    }
+
+  n_read = fread (header, 32, 1, fp);
 
-  fread (header, 32, 1, fp);
   fclose (fp);
 
+  if (n_read < 1)
+    {
+      g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
+                   _("EOF or error while reading image header"));
+      return FALSE;
+    }
+
   return (header[5] < 32);
 }
 
@@ -301,6 +332,7 @@ load_image (const gchar  *file,
   GimpPixelRgn  pixel_rgn;  /* Pixel region for layer */
 
   gint       i, j, k;       /* Counters */
+  size_t     n_read;        /* Number of items read from file */
 
 
   /* Open the file for reading */
@@ -319,7 +351,14 @@ load_image (const gchar  *file,
 
   /* Get the image dimensions and create the image... */
 
-  fread (header, 4, 1, fp);
+  n_read = fread (header, 4, 1, fp);
+
+  if (n_read < 1)
+    {
+      g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
+                   _("EOF or error while reading image header"));
+      return -1;
+    }
 
   if (strncmp ((const gchar *) header, "KiSS", 4))
     {
@@ -332,7 +371,15 @@ load_image (const gchar  *file,
     }
   else
     { /* New-style image file, read full header */
-      fread (header, 28, 1, fp);
+      n_read = fread (header, 28, 1, fp);
+
+      if (n_read < 1)
+        {
+          g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
+                       _("EOF or error while reading image header"));
+          return -1;
+        }
+
       bpp = header[1];
       if (bpp == 24)
         colours = -1;
@@ -383,7 +430,15 @@ load_image (const gchar  *file,
       switch (bpp)
         {
         case 4:
-          fread (buffer, (width+1)/2, 1, fp);
+          n_read = fread (buffer, (width+1)/2, 1, fp);
+
+          if (n_read < 1)
+            {
+              g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
+                           _("EOF or error while reading image data"));
+              return -1;
+            }
+
           for (j = 0, k = 0; j < width*2; j+= 4, ++k)
             {
               if (buffer[k] / 16 == 0)
@@ -410,7 +465,15 @@ load_image (const gchar  *file,
           break;
 
         case 8:
-          fread (buffer, width, 1, fp);
+          n_read = fread (buffer, width, 1, fp);
+
+          if (n_read < 1)
+            {
+              g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
+                           _("EOF or error while reading image data"));
+              return -1;
+            }
+
           for (j = 0, k = 0; j < width*2; j+= 2, ++k)
             {
               if (buffer[k] == 0)
@@ -427,7 +490,15 @@ load_image (const gchar  *file,
           break;
 
         case 32:
-          fread (line, width*4, 1, fp);
+          n_read = fread (line, width*4, 1, fp);
+
+          if (n_read < 1)
+            {
+              g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
+                           _("EOF or error while reading image data"));
+              return -1;
+            }
+
           /* The CEL file order is BGR so we need to swap B and R
            * to get the Gimp RGB order.
            */
@@ -467,12 +538,23 @@ load_image (const gchar  *file,
       else
         {
           fp = g_fopen (palette_file, "r");
+
+          if (fp == NULL)
+            {
+              g_set_error (error, G_FILE_ERROR, g_file_error_from_errno (errno),
+                           _("Could not open '%s' for reading: %s"),
+                           gimp_filename_to_utf8 (palette_file),
+                           g_strerror (errno));
+              return -1;
+            }
         }
 
       if (fp != NULL)
         {
-          colours = load_palette (fp, palette);
+          colours = load_palette (palette_file, fp, palette, error);
           fclose (fp);
+          if (colours < 0)
+            return -1;
         }
       else
         {
@@ -498,24 +580,55 @@ load_image (const gchar  *file,
 }
 
 static gint
-load_palette (FILE   *fp,
-              guchar  palette[])
+load_palette (const gchar *file,
+              FILE        *fp,
+              guchar       palette[],
+              GError     **error)
 {
   guchar        header[32];     /* File header */
   guchar        buffer[2];
   int           i, bpp, colours= 0;
+  size_t        n_read;
+
+  n_read = fread (header, 4, 1, fp);
+
+  if (n_read < 1)
+    {
+      g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
+                   _("'%s': EOF or error while reading palette header"),
+                   gimp_filename_to_utf8 (file));
+      return -1;
+    }
 
-  fread (header, 4, 1, fp);
   if (!strncmp ((const gchar *) header, "KiSS", 4))
     {
-      fread (header+4, 28, 1, fp);
+      n_read = fread (header+4, 28, 1, fp);
+
+      if (n_read < 1)
+        {
+          g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
+                       _("'%s': EOF or error while reading palette header"),
+                       gimp_filename_to_utf8 (file));
+          return -1;
+        }
+
       bpp = header[5];
       colours = header[8] + header[9] * 256;
       if (bpp == 12)
         {
           for (i = 0; i < colours; ++i)
             {
-              fread (buffer, 1, 2, fp);
+              n_read = fread (buffer, 1, 2, fp);
+
+              if (n_read < 2)
+                {
+                  g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
+                               _("'%s': EOF or error while reading "
+                                 "palette data"),
+                               gimp_filename_to_utf8 (file));
+                  return -1;
+                }
+
               palette[i*3]= buffer[0] & 0xf0;
               palette[i*3+1]= (buffer[1] & 0x0f) * 16;
               palette[i*3+2]= (buffer[0] & 0x0f) * 16;
@@ -523,7 +636,15 @@ load_palette (FILE   *fp,
         }
       else
         {
-          fread (palette, colours, 3, fp);
+          n_read = fread (palette, colours, 3, fp);
+
+          if (n_read < 3)
+            {
+              g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
+                           _("'%s': EOF or error while reading palette data"),
+                           gimp_filename_to_utf8 (file));
+              return -1;
+            }
         }
     }
   else
@@ -532,7 +653,16 @@ load_palette (FILE   *fp,
       fseek (fp, 0, SEEK_SET);
       for (i= 0; i < colours; ++i)
         {
-          fread (buffer, 1, 2, fp);
+          n_read = fread (buffer, 1, 2, fp);
+
+          if (n_read < 2)
+            {
+              g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
+                           _("'%s': EOF or error while reading palette data"),
+                           gimp_filename_to_utf8 (file));
+              return -1;
+            }
+
           palette[i*3] = buffer[0] & 0xf0;
           palette[i*3+1] = (buffer[1] & 0x0f) * 16;
           palette[i*3+2] = (buffer[0] & 0x0f) * 16;
-- 
1.7.10.4

