From d26132b02c2c04298724139c8cb166c7e2e179b0 Mon Sep 17 00:00:00 2001
From: Federico Mena Quintero <federico@gnome.org>
Date: Fri, 24 Nov 2017 18:12:03 -0600
Subject: [PATCH 7/8] Round up fixes to io-gif.c

---
 gdk-pixbuf/io-gif.c | 51 +++++++++++++++++++++++++++++++++++++++------------
 1 file changed, 39 insertions(+), 12 deletions(-)

diff --git a/gdk-pixbuf/io-gif.c b/gdk-pixbuf/io-gif.c
index 03d94d3..a09c3e5 100644
--- a/gdk-pixbuf/io-gif.c
+++ b/gdk-pixbuf/io-gif.c
@@ -60,6 +60,7 @@
 #include "gdk-pixbuf-private.h"
 #include "gdk-pixbuf-io.h"
 #include "io-gif-animation.h"
+#include "glib-overflow-arithmetic.h"
 
 
 
@@ -190,6 +191,7 @@ struct _GifContext
         GError **error;
 };
 
+/* The buffer must be at least 255 bytes long. */
 static int GetDataBlock (GifContext *, unsigned char *);
 
 
@@ -212,7 +214,7 @@ gif_read (GifContext *context, guchar *buffer, size_t len)
 		count += len;
 		g_print ("Fsize :%d\tcount :%d\t", len, count);
 #endif
-		retval = (fread(buffer, len, 1, context->file) != 0);
+		retval = (fread (buffer, 1, len, context->file) == len);
 
                 if (!retval && ferror (context->file)) {
                         gint save_errno = errno;
@@ -453,6 +455,7 @@ gif_get_extension (GifContext *context)
 
 static int ZeroDataBlock = FALSE;
 
+/* @buf must be at least 255 bytes long. */
 static int
 GetDataBlock (GifContext *context,
 	      unsigned char *buf)
@@ -851,13 +854,29 @@ gif_get_lzw (GifContext *context)
                                 pixels[2] = 0;
                                 pixels[3] = 0;
                         }
-                } else
-                        context->frame->pixbuf =
-                                gdk_pixbuf_new (GDK_COLORSPACE_RGB,
-                                                TRUE,
-                                                8,
-                                                context->frame_len,
-                                                context->frame_height);
+                } else {
+                        int rowstride;
+                        guint64 len;
+
+                        rowstride = gdk_pixbuf_calculate_rowstride (GDK_COLORSPACE_RGB,
+                                                                    TRUE,
+                                                                    8,
+                                                                    context->frame_len,
+                                                                    context->frame_height);
+                        if (rowstride > 0 &&
+                            g_uint64_checked_mul (&len, rowstride, context->frame_height) &&
+                            len <= G_MAXINT) {
+                                context->frame->pixbuf =
+                                        gdk_pixbuf_new (GDK_COLORSPACE_RGB,
+                                                        TRUE,
+                                                        8,
+                                                        context->frame_len,
+                                                        context->frame_height);
+                        } else {
+                                context->frame->pixbuf = NULL;
+                        }
+                }
+
                 if (!context->frame->pixbuf) {
                         g_free (context->frame);
                         g_set_error_literal (context->error,
@@ -1072,7 +1091,7 @@ gif_get_lzw (GifContext *context)
                                       context->frame->x_offset,
                                       context->frame->y_offset + lower_bound,
                                       gdk_pixbuf_get_width (context->frame->pixbuf),
-                                      upper_bound - lower_bound);
+                                      upper_bound - lower_bound + 1);
 		} else {
 			if (lower_bound <= upper_bound) {
                                 maybe_update (context,
@@ -1439,7 +1458,8 @@ new_context (void)
 	context->update_func = NULL;
 	context->user_data = NULL;
 	context->buf = NULL;
-	context->amount_needed = 0;
+	context->amount_needed = 13;
+	context->buf = g_new (guchar, context->amount_needed);
 	context->gif89.transparent = -1;
 	context->gif89.delay_time = -1;
 	context->gif89.input_flag = -1;
@@ -1537,15 +1557,22 @@ gdk_pixbuf__gif_image_stop_load (gpointer data, GError **error)
 	GifContext *context = (GifContext *) data;
         gboolean retval = TRUE;
         
-        if (context->state != GIF_DONE || context->animation->frames == NULL) {
+        if (context->animation->frames == NULL) {
                 g_set_error_literal (error,
                                      GDK_PIXBUF_ERROR,
                                      GDK_PIXBUF_ERROR_CORRUPT_IMAGE,
                                      _("GIF image was truncated or incomplete."));
 
+                retval = FALSE;
+        } else if (context->state != GIF_DONE) {
+                g_set_error_literal (error,
+                                     GDK_PIXBUF_ERROR,
+                                     GDK_PIXBUF_ERROR_INCOMPLETE_ANIMATION,
+                                     _("Not all frames of the GIF image were loaded."));
+
                 retval = FALSE;
         }
-        
+
         g_object_unref (context->animation);
 
   	g_free (context->buf);
-- 
2.16.1

