$OpenBSD: patch-src_modules_loaders_loader_tga_c,v 1.1 2006/11/20 09:21:09 bernd Exp $

Fix for CVE-2006-4806, CVE-2006-4807, CVE-2006-4808, CVE-2006-4809.
Should be fixed in >1.3.0.

--- src/modules/loaders/loader_tga.c.orig	Wed Sep  6 13:34:49 2006
+++ src/modules/loaders/loader_tga.c	Mon Nov  6 10:41:32 2006
@@ -297,9 +297,8 @@ load(ImlibImage * im, ImlibProgressFunct
    im->w = (header->widthHi << 8) | header->widthLo;
    im->h = (header->heightHi << 8) | header->heightLo;
 
-   if ((im->w > 32767) || (im->w < 1) || (im->h > 32767) || (im->h < 1))
+   if ((im->w < 1) || (im->h < 1) || (im->w > 8192) || (im->h > 8192))
      {
-        im->w = 0;
 	munmap(seg, ss.st_size);
         close(fd);
         return 0;
@@ -318,7 +317,7 @@ load(ImlibImage * im, ImlibProgressFunct
    if (((!im->data) && (im->loader)) || (immediate_load) || (progress))
      {
         unsigned long       datasize;
-        unsigned char      *bufptr;
+        unsigned char      *bufptr, *bufend;
         DATA32             *dataptr;
 
         int                 y;
@@ -346,6 +345,7 @@ load(ImlibImage * im, ImlibProgressFunct
 
         /* bufptr is the next byte to be read from the buffer */
         bufptr = filedata;
+	bufend = filedata + datasize;
 
         /* dataptr is the next 32-bit pixel to be filled in */
         dataptr = im->data;
@@ -418,9 +418,10 @@ load(ImlibImage * im, ImlibProgressFunct
              unsigned char       curbyte, red, green, blue, alpha;
              DATA32             *final_pixel = dataptr + im->w * im->h;
 
-             /* loop until we've got all the pixels */
-             while (dataptr < final_pixel)
-               {
+             /* loop until we've got all the pixels or run out of input */
+	     while ((dataptr < final_pixel) &&
+		    ((bufptr + 1 + (bpp / 8)) < bufend))
+	       {
                   int                 count;
 
                   curbyte = *bufptr++;
@@ -437,7 +438,7 @@ load(ImlibImage * im, ImlibProgressFunct
                               green = *bufptr++;
                               red = *bufptr++;
                               alpha = *bufptr++;
-                              for (i = 0; i < count; i++)
+			    for (i = 0; (i < count) && (dataptr < final_pixel); i++)
                                 {
                                    WRITE_RGBA(dataptr, red, green, blue, alpha);
                                    dataptr++;
@@ -448,7 +449,7 @@ load(ImlibImage * im, ImlibProgressFunct
                               blue = *bufptr++;
                               green = *bufptr++;
                               red = *bufptr++;
-                              for (i = 0; i < count; i++)
+			    for (i = 0; (i < count) && (dataptr < final_pixel); i++)
                                 {
                                    WRITE_RGBA(dataptr, red, green, blue,
                                               (char)0xff);
@@ -458,7 +459,7 @@ load(ImlibImage * im, ImlibProgressFunct
 
                            case 8:
                               alpha = *bufptr++;
-                              for (i = 0; i < count; i++)
+			    for (i = 0; (i < count) && (dataptr < final_pixel); i++)
                                 {
                                    WRITE_RGBA(dataptr, alpha, alpha, alpha,
                                               (char)0xff);
@@ -473,7 +474,7 @@ load(ImlibImage * im, ImlibProgressFunct
                     {
                        int                 i;
 
-                       for (i = 0; i < count; i++)
+                       for (i = 0; (i < count) && (dataptr < final_pixel); i++)
                          {
                             switch (bpp)
                               {
