From 875e62fa38250ccd78798252a1a2a119f9ccc5d1 Mon Sep 17 00:00:00 2001
From: "donal.k.fellows@manchester.ac.uk" <dkf>
Date: Mon, 27 Mar 2006 12:13:55 +0000
Subject: Fix (and add test for) [Bug 1458234]

---
 ChangeLog           |  5 +++++
 generic/tkImgGIF.c  | 28 ++++++++++++++--------------
 tests/imgPhoto.test | 15 ++++++++++++++-
 3 files changed, 33 insertions(+), 15 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index f91d50c..d491ba4 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2006-03-27  Donal K. Fellows  <donal.k.fellows@man.ac.uk>
+
+	* generic/tkImgGIF.c (FileReadGIF): Stop crashes when the first GIF
+	frame does not define the overall size of the image. [Bug 1458234]
+
 2006-03-22  Don Porter  <dgp@users.sourceforge.net>
 
 	*** 8.4.13 TAGGED FOR RELEASE ***
diff --git a/generic/tkImgGIF.c b/generic/tkImgGIF.c
index 42a3132..d4e5d39 100644
--- a/generic/tkImgGIF.c
+++ b/generic/tkImgGIF.c
@@ -29,7 +29,7 @@
  * |   provided "as is" without express or implied warranty.		|
  * +-------------------------------------------------------------------+
  *
- * RCS: @(#) $Id: tkImgGIF.c,v 1.24.2.3 2005/12/01 03:22:10 hobbs Exp $
+ * RCS: @(#) $Id: tkImgGIF.c,v 1.24.2.4 2006/03/27 12:13:56 dkf Exp $
  */
 
 /*
@@ -243,7 +243,7 @@ FileReadGIF(interp, chan, fileName, format, imageHandle, destX, destY,
     int srcX, srcY;		/* Coordinates of top-left pixel to be used
 				 * in image being read. */
 {
-    int fileWidth, fileHeight;
+    int fileWidth, fileHeight, imageWidth, imageHeight;
     int nBytes, index = 0, argc = 0, i;
     Tcl_Obj **objv;
     Tk_PhotoImageBlock block;
@@ -376,8 +376,8 @@ FileReadGIF(interp, chan, fileName, format, imageHandle, destX, destY,
 	    goto error;
 	}
 
-	fileWidth = LM_to_uint(buf[4],buf[5]);
-	fileHeight = LM_to_uint(buf[6],buf[7]);
+	imageWidth = LM_to_uint(buf[4],buf[5]);
+	imageHeight = LM_to_uint(buf[6],buf[7]);
 
 	bitPixel = 1<<((buf[8]&0x07)+1);
 
@@ -419,8 +419,8 @@ FileReadGIF(interp, chan, fileName, format, imageHandle, destX, destY,
 	     * of the less frequent case, I chose to maintain high
 	     * performance for the common case.
 	     */
-	    if (ReadImage(interp, (char *) trashBuffer, chan, fileWidth,
-		    fileHeight, colorMap, 0, 0, 0, 0, 0, -1) != TCL_OK) {
+	    if (ReadImage(interp, (char *) trashBuffer, chan, imageWidth,
+		    imageHeight, colorMap, 0, 0, 0, 0, 0, -1) != TCL_OK) {
 		goto error;
 	    }
 	    continue;
@@ -441,8 +441,8 @@ FileReadGIF(interp, chan, fileName, format, imageHandle, destX, destY,
 	    srcX = 0;
 	}
 
-	if (width > fileWidth) {
-	    width = fileWidth;
+	if (width > imageWidth) {
+	    width = imageWidth;
 	}
 
 	index = LM_to_uint(buf[2],buf[3]);
@@ -451,8 +451,8 @@ FileReadGIF(interp, chan, fileName, format, imageHandle, destX, destY,
 	    destY -= srcY; height += srcY;
 	    srcY = 0;
 	}
-	if (height > fileHeight) {
-	    height = fileHeight;
+	if (height > imageHeight) {
+	    height = imageHeight;
 	}
 
 	if ((width <= 0) || (height <= 0)) {
@@ -464,12 +464,12 @@ FileReadGIF(interp, chan, fileName, format, imageHandle, destX, destY,
 	block.height = height;
 	block.pixelSize = (transparent>=0) ? 4 : 3;
 	block.offset[3] = (transparent>=0) ? 3 : 0;
-	block.pitch = block.pixelSize * fileWidth;
-	nBytes = block.pitch * fileHeight;
+	block.pitch = block.pixelSize * imageWidth;
+	nBytes = block.pitch * imageHeight;
 	block.pixelPtr = (unsigned char *) ckalloc((unsigned) nBytes);
 
-	if (ReadImage(interp, (char *) block.pixelPtr, chan, fileWidth,
-		fileHeight, colorMap, fileWidth, fileHeight, srcX, srcY,
+	if (ReadImage(interp, (char *) block.pixelPtr, chan, imageWidth,
+		imageHeight, colorMap, fileWidth, fileHeight, srcX, srcY,
 		BitSet(buf[8], INTERLACE), transparent) != TCL_OK) {
 	    goto error;
 	}
diff --git a/tests/imgPhoto.test b/tests/imgPhoto.test
index b568477..341e82a 100644
--- a/tests/imgPhoto.test
+++ b/tests/imgPhoto.test
@@ -9,7 +9,7 @@
 #
 # Author: Paul Mackerras (paulus@cs.anu.edu.au)
 #
-# RCS: @(#) $Id: imgPhoto.test,v 1.15.2.2 2004/02/17 20:40:41 dgp Exp $
+# RCS: @(#) $Id: imgPhoto.test,v 1.15.2.3 2006/03/27 12:13:56 dkf Exp $
 
 package require tcltest 2.1
 namespace import -force tcltest::configure
@@ -653,6 +653,19 @@ hciva9/Ovbv37+BzBgEEADs=
     catch {file delete -force $filename}
     set result
 } 1
+test imgPhoto-14.2 {GIF -index handler buffer sizing} {
+    # Bug 1458234 makes this crash when trying to access buffers of the
+    # wrong size, caused when the initial frame is not the largest frame.
+    set data {
+        R0lGODlhIAAgAKEAAPkOSQsi7////////yH/C05FVFNDQVBFMi4wAwEAAAAh
+        +QQJMgAAACwGAAYAFAAUAAACEYyPqcvtD6OctNqLs968+68VACH5BAkyAAEA
+        LAMAAwAaABoAAAI0jH+gq+gfmFzQzUsr3gBybn1gIm5kaUaoubbuC8fyTNel
+        Ohv1CSO533u8KrgbUfc5Ci/EAgA7
+    }
+    set i [image create photo]
+    $i configure -data $data -format {gif -index 2}
+    image delete $i
+} {}
 
 test imgPhoto-15.1 {photo images can fail to allocate memory gracefully} \
 	{nonPortable} {
-- 
cgit v0.12