From 82b80dcb70a7ca8986125ff412bceddafc896842 Mon Sep 17 00:00:00 2001
From: Mike Frysinger <vapier@gentoo.org>
Date: Sat, 14 May 2016 02:13:15 -0400
Subject: [PATCH] gif: avoid out-of-bound reads of masks array #209

When given invalid inputs, we might be fed the EOF marker before it is
actually the EOF.  The gif logic assumes once it sees the EOF marker,
there won't be any more data, so it leaves the cur_bits index possibly
negative.  So when we get more data, we underflow the masks array.

Flag it so we don't try to output anything more.  The image is invalid,
so we shouldn't be truncating any valid inputs.

This fixes #209.
---
 src/gd_gif_out.c | 12 +++++++++++-
 1 file changed, 11 insertions(+), 1 deletion(-)

Index: libgd2-2.1.0/src/gd_gif_out.c
===================================================================
--- libgd2-2.1.0.orig/src/gd_gif_out.c	2016-07-08 14:41:42.343361086 -0400
+++ libgd2-2.1.0/src/gd_gif_out.c	2016-07-08 14:41:42.343361086 -0400
@@ -1000,15 +1000,23 @@
  * code in turn.  When the buffer fills up empty it and start over.
  */
 
-static unsigned long masks[] = {
+static const unsigned long masks[] = {
 	0x0000, 0x0001, 0x0003, 0x0007, 0x000F,
 	0x001F, 0x003F, 0x007F, 0x00FF,
 	0x01FF, 0x03FF, 0x07FF, 0x0FFF,
 	0x1FFF, 0x3FFF, 0x7FFF, 0xFFFF
 };
 
+/* Arbitrary value to mark output is done.  When we see EOFCode, then we don't
+ * expect to see any more data.  If we do (e.g. corrupt image inputs), cur_bits
+ * might be negative, so flag it to return early.
+ */
+#define CUR_BITS_FINISHED -1000
+
 static void output(code_int code, GifCtx *ctx)
 {
+	if (ctx->cur_bits == CUR_BITS_FINISHED)
+		return;
 	ctx->cur_accum &= masks[ctx->cur_bits];
 
 	if(ctx->cur_bits > 0) {
@@ -1050,6 +1058,8 @@
 			ctx->cur_accum >>= 8;
 			ctx->cur_bits -= 8;
 		}
+		/* Flag that it's done to prevent re-entry. */
+		ctx->cur_bits = CUR_BITS_FINISHED;
 
 		flush_char(ctx);
 	}
