File ImageMagick-6.2.5-bug258253.patch of Package ImageMagick

--- coders/bmp.c
+++ coders/bmp.c
@@ -842,7 +842,8 @@
           packet_size=3;
         else
           packet_size=4;
-        (void) SeekBlob(image,start_position+14+bmp_info.size,SEEK_SET);
+        if (SeekBlob(image,start_position+14+bmp_info.size,SEEK_SET) == -1)
+	  ThrowReaderException(CorruptImageError,"ImproperImageHeader")
         count=ReadBlob(image,packet_size*image->colors,bmp_colormap);
         if (count != (ssize_t) (packet_size*image->colors))
           ThrowReaderException(CorruptImageError,"InsufficientImageDataInFile");
@@ -863,7 +864,8 @@
     /*
       Read image data.
     */
-    (void) SeekBlob(image,start_position+bmp_info.offset_bits,SEEK_SET);
+    if (SeekBlob(image,start_position+bmp_info.offset_bits,SEEK_SET) == -1)
+      ThrowReaderException(CorruptImageError,"ImproperImageHeader")
     if (bmp_info.compression == BI_RLE4)
       bmp_info.bits_per_pixel<<=1;
     bytes_per_line=4*((image->columns*bmp_info.bits_per_pixel+31)/32);
@@ -1282,7 +1284,8 @@
         break;
     *magick='\0';
     if (bmp_info.ba_offset != 0)
-      (void) SeekBlob(image,(MagickOffsetType) bmp_info.ba_offset,SEEK_SET);
+      if (SeekBlob(image,(MagickOffsetType) bmp_info.ba_offset,SEEK_SET) == -1)
+        ThrowReaderException(CorruptImageError,"ImproperImageHeader")
     count=ReadBlob(image,2,magick);
     if ((count == 2) && (IsBMP(magick,2) != MagickFalse))
       {
--- coders/cin.c
+++ coders/cin.c
@@ -297,7 +297,8 @@
   (void) ReadBlobByte(image);
   image->columns=ReadBlobLong(image);
   image->rows=ReadBlobLong(image);
-  (void) SeekBlob(image,(MagickOffsetType) headersize,SEEK_SET);
+  if (SeekBlob(image,(MagickOffsetType) headersize,SEEK_SET) == -1)
+    ThrowReaderException(CorruptImageError,"ImproperImageHeader");
   if (image_info->ping)
     {
       CloseBlob(image);
--- coders/dcm.c
+++ coders/dcm.c
@@ -2900,6 +2900,9 @@
         else
           if ((quantum != 0) && (length != 0))
             {
+              /* new check for CVE-2007-1797 */
+	      if (length > ((~0UL)/quantum))
+	        ThrowReaderException(CorruptImageError,"ImproperImageHeader");
               data=(unsigned char *)
                 AcquireMagickMemory((size_t) quantum*(length+1));
               if (data == (unsigned char *) NULL)
--- coders/icon.c
+++ coders/icon.c
@@ -242,13 +242,16 @@
     /*
       Verify Icon identifier.
     */
-    (void) SeekBlob(image,(MagickOffsetType) icon_file.directory[i].offset,
-      SEEK_SET);
+    if (SeekBlob(image,(MagickOffsetType) icon_file.directory[i].offset,
+      SEEK_SET) == -1)
+      ThrowReaderException(CorruptImageError,"ImproperImageHeader");
     icon_info.size=ReadBlobLSBLong(image);
     icon_info.width=ReadBlobLSBLong(image);
     icon_info.height=ReadBlobLSBLong(image);
     icon_info.planes=ReadBlobLSBShort(image);
     icon_info.bits_per_pixel=ReadBlobLSBShort(image);
+    if (icon_info.bits_per_pixel > 32)
+      ThrowReaderException(CorruptImageError,"ImproperImageHeader");
     icon_info.compression=ReadBlobLSBLong(image);
     icon_info.image_size=ReadBlobLSBLong(image);
     icon_info.x_pixels=ReadBlobLSBLong(image);
@@ -259,7 +262,7 @@
     image->columns=icon_info.width;
     image->rows=icon_info.height;
     image->depth=8;
-    if ((icon_info.number_colors != 0) || (icon_info.bits_per_pixel < 16))
+    if ((icon_info.number_colors != 0) || (icon_info.bits_per_pixel <= 16))
       {
         image->storage_class=PseudoClass;
         image->colors=icon_info.number_colors;
--- coders/pcx.c
+++ coders/pcx.c
@@ -289,7 +289,9 @@
       }
     }
   if (page_table != (MagickOffsetType *) NULL)
-    (void) SeekBlob(image,(MagickOffsetType) page_table[0],SEEK_SET);
+    if (SeekBlob(image,(MagickOffsetType) page_table[0],SEEK_SET)
+        == -1)
+      ThrowReaderException(CorruptImageError,"ImproperImageHeader");
   pcx_colormap=(unsigned char *) NULL;
   count=ReadBlob(image,1,&pcx_info.identifier);
   for (id=1; id < 1024; id++)
@@ -328,7 +330,11 @@
     if ((pcx_info.bits_per_pixel != 8) || (pcx_info.planes == 1))
       if ((pcx_info.version == 3) || (pcx_info.version == 5) ||
           ((pcx_info.bits_per_pixel*pcx_info.planes) == 1))
-        image->colors=1 << (pcx_info.bits_per_pixel*pcx_info.planes);
+	{
+          image->colors=1 << (pcx_info.bits_per_pixel*pcx_info.planes);
+	  if (image->colors > 256)
+	    image->colors = 256;
+	}
     if (AllocateImageColormap(image,image->colors) == MagickFalse)
       ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
     if ((pcx_info.bits_per_pixel >= 8) && (pcx_info.planes != 1))
@@ -355,7 +361,7 @@
     pcx_pixels=(unsigned char *)
       AcquireMagickMemory(pcx_packets*sizeof(*pcx_pixels));
     scanline=(unsigned char *) AcquireMagickMemory(Max(image->columns,
-      pcx_info.bytes_per_line)*pcx_info.planes*sizeof(*scanline));
+      pcx_info.bytes_per_line)*Max(pcx_info.planes,8)*sizeof(*scanline));
     if ((pcx_pixels == (unsigned char *) NULL) ||
         (scanline == (unsigned char *) NULL))
       ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
@@ -613,7 +619,9 @@
       break;
     if (page_table[id] == 0)
       break;
-    (void) SeekBlob(image,(MagickOffsetType) page_table[id],SEEK_SET);
+    if (SeekBlob(image,(MagickOffsetType) page_table[id],SEEK_SET)
+        == -1)
+      ThrowReaderException(CorruptImageError,"ImproperImageHeader");
     count=ReadBlob(image,1,&pcx_info.identifier);
     if ((count != 0) && (pcx_info.identifier == 0x0a))
       {
--- coders/pict.c
+++ coders/pict.c
@@ -79,6 +79,10 @@
   pixmap.plane_bytes=ReadBlobMSBLong(image); \
   pixmap.table=ReadBlobMSBLong(image); \
   pixmap.reserved=ReadBlobMSBLong(image); \
+  if (pixmap.bits_per_pixel <= 0 || pixmap.bits_per_pixel > 32 || \
+      pixmap.component_count <= 0 || pixmap.component_count > 4 || \
+      pixmap.component_size <= 0) \
+    ThrowReaderException(CorruptImageError,"ImproperImageHeader"); \
 }
 
 #define ReadRectangle(rectangle) \
@@ -87,6 +91,9 @@
   rectangle.left=ReadBlobMSBShort(image); \
   rectangle.bottom=ReadBlobMSBShort(image); \
   rectangle.right=ReadBlobMSBShort(image); \
+  if (rectangle.top > rectangle.bottom || \
+      rectangle.left > rectangle.right) \
+    ThrowReaderException(CorruptImageError,"ImproperImageHeader"); \
 }
 
 typedef struct _PICTCode
--- coders/png.c
+++ coders/png.c
@@ -4721,6 +4721,8 @@
             continue;
           }
 #ifdef MNG_INSERT_LAYERS
+        if (length < 8)
+          ThrowReaderException(CorruptImageError,"ImproperImageHeader");
         image_width=(unsigned  long) mng_get_long(p);
         image_height=(unsigned  long) mng_get_long(&p[4]);
 #endif
--- coders/pnm.c
+++ coders/pnm.c
@@ -217,6 +217,19 @@
   return(value);
 }
 
+#define ValidateScalingIndex(image, index, max) \
+	do { \
+		if (index < 0 || index > max) \
+			ThrowReaderException(CorruptImageError,"CorruptImage"); \
+	} while (0)
+
+#define ValidateScalingPixel(image, pixel, max) \
+	do { \
+		ValidateScalingIndex(image, pixel.red, max); \
+		ValidateScalingIndex(image, pixel.green, max); \
+		ValidateScalingIndex(image, pixel.blue, max); \
+	} while (0)
+
 static Image *ReadPNMImage(const ImageInfo *image_info,ExceptionInfo *exception)
 {
 #define PushCharPixel(pixel,p) \
@@ -477,6 +490,7 @@
           for (x=0; x < (long) image->columns; x++)
           {
             intensity=PNMInteger(image,10);
+            ValidateScalingIndex(image, intensity, max_value);
             if (scale != (Quantum *) NULL)
               intensity=scale[intensity];
             index=(IndexPacket) intensity;
@@ -522,6 +536,7 @@
             pixel.red=PNMInteger(image,10);
             pixel.green=PNMInteger(image,10);
             pixel.blue=PNMInteger(image,10);
+            ValidateScalingPixel(image, pixel, max_value);
             if (scale != (Quantum *) NULL)
               {
                 pixel.red=scale[pixel.red];
@@ -687,6 +702,7 @@
               PushCharPixel(pixel.red,p);
               PushCharPixel(pixel.green,p);
               PushCharPixel(pixel.blue,p);
+              ValidateScalingPixel(image, pixel, max_value);
               if (scale != (Quantum *) NULL)
                 {
                   pixel.red=scale[pixel.red];
@@ -704,6 +720,7 @@
               PushShortPixel(pixel.red,p);
               PushShortPixel(pixel.green,p);
               PushShortPixel(pixel.blue,p);
+              ValidateScalingPixel(image, pixel, max_value);
               if (scale != (Quantum *) NULL)
                 {
                   pixel.red=scale[pixel.red];
--- coders/sgi.c
+++ coders/sgi.c
@@ -152,8 +152,9 @@
 %
 */
 
-static void SGIDecode(const unsigned long width,const size_t bytes_per_pixel,
-  unsigned char *max_packets,unsigned char *pixels)
+static int SGIDecode(const unsigned long width,const size_t bytes_per_pixel,
+  unsigned char *max_packets,unsigned char *pixels,
+  unsigned long npackets,unsigned long npixels)
 {
   register unsigned char
     *p,
@@ -174,21 +175,30 @@
     {
       for ( i=0 ; ; )
       {
+        if (npackets-- == 0)
+	  return -1;
         pixel=(unsigned long) (*p++) << 8;
         pixel|=(*p++);
         count=(ssize_t) (pixel & 0x7f);
         i+=count;
         if (count == 0 || i > (long) width)
           break;
+	if (count > npixels)
+	  return -1;
+	npixels -= count;
         if ((pixel & 0x80) != 0)
           for ( ; count != 0; count--)
           {
+	    if (npackets-- == 0)
+	      return -1;
             *q=(*p++);
             *(q+1)=(*p++);
             q+=8;
           }
         else
           {
+	    if (npackets-- == 0)
+	      return -1;
             pixel=(unsigned long) (*p++) << 8;
             pixel|=(*p++);
             for ( ; count != 0; count--)
@@ -199,23 +209,32 @@
             }
           }
       }
-      return;
+      return 0;
     }
   for ( i=0 ; ; )
   {
+    if (npackets-- == 0)
+      return -1;
     pixel=(unsigned long) (*p++);
     count=(ssize_t) (pixel & 0x7f);
     i+=count;
     if (count == 0 || i > (long) width)
       break;
+    if (count > npixels)
+      return -1;
+    npixels -= count;
     if ((pixel & 0x80) != 0)
       for ( ; count != 0; count--)
       {
+        if (npackets-- == 0)
+          return -1;
         *q=(*p++);
         q+=4;
       }
     else
       {
+        if (npackets-- == 0)
+          return -1;
         pixel=(unsigned long) (*p++);
         for ( ; count != 0; count--)
         {
@@ -224,6 +243,7 @@
         }
       }
   }
+  return 0;
 }
 
 static Image *ReadSGIImage(const ImageInfo *image_info,ExceptionInfo *exception)
@@ -298,13 +318,12 @@
     if ((int) iris_info.storage == 0x01)
       image->compression=RLECompression;
     iris_info.bytes_per_pixel=(unsigned char) ReadBlobByte(image);
+    if (iris_info.bytes_per_pixel > 2 || iris_info.bytes_per_pixel == 0)
+      ThrowReaderException(CorruptImageError,"ImproperImageHeader");
     iris_info.dimension=ReadBlobMSBShort(image);
     iris_info.columns=ReadBlobMSBShort(image);
     iris_info.rows=ReadBlobMSBShort(image);
     iris_info.depth=ReadBlobMSBShort(image);
-    image->columns=iris_info.columns;
-    image->rows=iris_info.rows;
-    image->depth=(unsigned long) (iris_info.depth <= 8 ? 8 : QuantumDepth);
     if (iris_info.depth > 4 || iris_info.depth == 0)
       ThrowReaderException(CorruptImageError,"ImproperImageHeader");
     if (iris_info.depth < 3)
@@ -312,6 +333,9 @@
         image->storage_class=PseudoClass;
         image->colors=256;
       }
+    image->columns=iris_info.columns;
+    image->rows=iris_info.rows;
+    image->depth=bytes_per_pixel == 1 ? 8 : QuantumDepth;
     if ((image_info->ping != MagickFalse)  && (image_info->number_scenes != 0))
       if (image->scene >= (image_info->scene+image_info->number_scenes-1))
         break;
@@ -435,8 +459,11 @@
                 if (EOFBlob(image) != MagickFalse)
                   break;
                 offset+=runlength[y+z*iris_info.rows];
-                SGIDecode(iris_info.columns,bytes_per_pixel,max_packets,
-                  p+bytes_per_pixel*z);
+                if (SGIDecode(iris_info.columns,bytes_per_pixel,max_packets,
+                  p+bytes_per_pixel*z,
+		              runlength[y+z*iris_info.rows]/bytes_per_pixel,
+                              iris_info.columns) == -1)
+	          ThrowReaderException(CorruptImageError,"ImproperImageHeader"); 
                 p+=(iris_info.columns*4*bytes_per_pixel);
               }
             }
@@ -462,8 +489,11 @@
                 if (EOFBlob(image) != MagickFalse)
                   break;
                 offset+=runlength[y+z*iris_info.rows];
-                SGIDecode(iris_info.columns,bytes_per_pixel,max_packets,
-                  p+bytes_per_pixel*z);
+                if (SGIDecode(iris_info.columns,bytes_per_pixel,max_packets,
+                  p+bytes_per_pixel*z,
+		              runlength[y+z*iris_info.rows]/bytes_per_pixel,
+                              iris_info.columns) == -1)
+	          ThrowReaderException(CorruptImageError,"ImproperImageHeader"); 
               }
               p+=(iris_info.columns*4*bytes_per_pixel);
             }
--- coders/sun.c
+++ coders/sun.c
@@ -304,6 +304,8 @@
     sun_info.maplength=ReadBlobMSBLong(image);
     image->columns= sun_info.width;
     image->rows= sun_info.height;
+    if (sun_info.depth == 0 || sun_info.depth > 32)
+      ThrowReaderException(CorruptImageError,"ImproperImageHeader");
     image->depth=sun_info.depth <= 8 ? 8UL : QuantumDepth;
     if (sun_info.depth < 24)
       {
@@ -462,72 +464,85 @@
       }
     else
       if (image->storage_class == PseudoClass)
-        for (y=0; y < (long) image->rows; y++)
         {
-          q=SetImagePixels(image,0,y,image->columns,1);
-          if (q == (PixelPacket *) NULL)
-            break;
-          indexes=GetIndexes(image);
-          for (x=0; x < (long) image->columns; x++)
-            indexes[x]=(*p++);
-          if ((image->columns % 2) != 0)
-            p++;
-          if (SyncImagePixels(image) == MagickFalse)
-            break;
-          if (image->previous == (Image *) NULL)
-            if ((image->progress_monitor != (MagickProgressMonitor) NULL) &&
+	  unsigned long n = image->rows*(image->columns+image->columns%2);
+	  if ((sun_info.type == RT_ENCODED && n > bytes_per_line*image->rows) ||
+	      (sun_info.type != RT_ENCODED && n > sun_info.length))
+	    ThrowReaderException(CorruptImageError,"ImproperImageHeader");
+          for (y=0; y < (long) image->rows; y++)
+          {
+            q=SetImagePixels(image,0,y,image->columns,1);
+            if (q == (PixelPacket *) NULL)
+              break;
+            indexes=GetIndexes(image);
+            for (x=0; x < (long) image->columns; x++)
+              indexes[x]=(*p++);
+            if ((image->columns % 2) != 0)
+              p++;
+            if (SyncImagePixels(image) == MagickFalse)
+              break;
+            if (image->previous == (Image *) NULL)
+              if ((image->progress_monitor != (MagickProgressMonitor) NULL) &&
                 (QuantumTick(y,image->rows) != MagickFalse))
-              {
+                {
                 status=image->progress_monitor(LoadImageTag,y,image->rows,
                   image->client_data);
-                if (status == MagickFalse)
+                  if (status == MagickFalse)
                   break;
               }
-        }
+          }
+	}
       else
-        for (y=0; y < (long) image->rows; y++)
         {
-          q=SetImagePixels(image,0,y,image->columns,1);
-          if (q == (PixelPacket *) NULL)
-            break;
-          for (x=0; x < (long) image->columns; x++)
+	  unsigned long n = image->columns*((image->matte) ? 4 : 3);
+	  n = image->rows*(n+image->columns%2);
+	  if ((sun_info.type == RT_ENCODED && n > bytes_per_line*image->rows) ||
+	      (sun_info.type != RT_ENCODED && n > sun_info.length))
+	    ThrowReaderException(CorruptImageError,"ImproperImageHeader");
+          for (y=0; y < (long) image->rows; y++)
           {
-            if (image->matte != MagickFalse)
-              q->opacity=(Quantum) (QuantumRange-ScaleCharToQuantum(*p++));
-            if (sun_info.type == RT_STANDARD)
-              {
-                q->blue=ScaleCharToQuantum(*p++);
-                q->green=ScaleCharToQuantum(*p++);
-                q->red=ScaleCharToQuantum(*p++);
-              }
-            else
-              {
-                q->red=ScaleCharToQuantum(*p++);
-                q->green=ScaleCharToQuantum(*p++);
-                q->blue=ScaleCharToQuantum(*p++);
-              }
-            if (image->colors != 0)
-              {
-                q->red=image->colormap[q->red].red;
-                q->green=image->colormap[q->green].green;
-                q->blue=image->colormap[q->blue].blue;
-              }
-            q++;
-          }
-          if ((image->columns % 2) != 0)
-            p++;
-          if (SyncImagePixels(image) == MagickFalse)
-            break;
-          if (image->previous == (Image *) NULL)
-            if ((image->progress_monitor != (MagickProgressMonitor) NULL) &&
+            q=SetImagePixels(image,0,y,image->columns,1);
+            if (q == (PixelPacket *) NULL)
+              break;
+            for (x=0; x < (long) image->columns; x++)
+            {
+              if (image->matte != MagickFalse)
+                q->opacity=(Quantum) (QuantumRange-ScaleCharToQuantum(*p++));
+              if (sun_info.type == RT_STANDARD)
+                {
+                  q->blue=ScaleCharToQuantum(*p++);
+                  q->green=ScaleCharToQuantum(*p++);
+                  q->red=ScaleCharToQuantum(*p++);
+                }
+              else
+                {
+                  q->red=ScaleCharToQuantum(*p++);
+                  q->green=ScaleCharToQuantum(*p++);
+                  q->blue=ScaleCharToQuantum(*p++);
+                }
+              if (image->colors != 0)
+                {
+                  q->red=image->colormap[q->red].red;
+                  q->green=image->colormap[q->green].green;
+                  q->blue=image->colormap[q->blue].blue;
+                }
+              q++;
+            }
+            if ((image->columns % 2) != 0)
+              p++;
+            if (SyncImagePixels(image) == MagickFalse)
+              break;
+            if (image->previous == (Image *) NULL)
+              if ((image->progress_monitor != (MagickProgressMonitor) NULL) &&
                 (QuantumTick(y,image->rows) != MagickFalse))
-              {
+                {
                 status=image->progress_monitor(LoadImageTag,y,image->rows,
                   image->client_data);
-                if (status == MagickFalse)
+                  if (status == MagickFalse)
                   break;
               }
-        }
+          }
+	}
     if (image->storage_class == PseudoClass)
       (void) SyncImage(image);
     sun_pixels=(unsigned char *) RelinquishMagickMemory(sun_pixels);
--- coders/xwd.c
+++ coders/xwd.c
@@ -235,6 +235,10 @@
   if (header.header_size < sz_XWDheader)
     ThrowReaderException(CorruptImageError,"CorruptImage");
   length=(size_t) header.header_size-sz_XWDheader;
+  /* new check for CVE-2007-1797 */
+  if (length > ((~0UL)/sizeof(*comment)))
+    ThrowReaderException(CorruptImageError,"ImproperImageHeader");
+
   comment=(char *) AcquireMagickMemory(length+MaxTextExtent);
   if (comment == (char *) NULL)
     ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
@@ -266,6 +270,13 @@
   ximage->red_mask=header.red_mask;
   ximage->green_mask=header.green_mask;
   ximage->blue_mask=header.blue_mask;
+  /* Why those are signed ints is beyond me. */
+  if (ximage->depth < 0 || ximage->width < 0 || ximage->height < 0 ||
+      ximage->bitmap_pad < 0 || ximage->bytes_per_line < 0)
+    ThrowReaderException(CorruptImageError,"ImproperImageHeader");
+  /* Guard against buffer overflow in libX11. */
+  if (ximage->bits_per_pixel > 32 || ximage->bitmap_unit > 32)
+    ThrowReaderException(CorruptImageError,"ImproperImageHeader");
   x_status=XInitImage(ximage);
   if (x_status == 0)
     ThrowReaderException(CorruptImageError,"UnableToReadImageHeader");
@@ -278,6 +289,10 @@
       XWDColor
         color;
 
+      /* new check for CVE-2007-1797 */
+      if (length > ((~0UL)/sizeof(*colors)))
+        ThrowReaderException(CorruptImageError,"ImproperImageHeader");
+               
       colors=(XColor *)
         AcquireMagickMemory((size_t) header.ncolors*sizeof(*colors));
       if (colors == (XColor *) NULL)
@@ -310,11 +325,23 @@
   /*
     Allocate the pixel buffer.
   */
-  if (ximage->format == ZPixmap)
-    length=(size_t) ximage->bytes_per_line*ximage->height;
-  else
-    length=(size_t) ximage->bytes_per_line*ximage->height*ximage->depth;
-  ximage->data=(char *) AcquireMagickMemory(length);
+  {
+#define OVERFLOW(c,a,b) ((b) != 0 && ((c)/(b) != (a)))
+  int overflow=0;
+  length=(size_t) ximage->bytes_per_line*ximage->height;
+  if (OVERFLOW(length, (size_t) ximage->bytes_per_line, ximage->height)) overflow=1;
+  if (ximage->format != ZPixmap) {
+    size_t l1=length*ximage->depth;
+    if (OVERFLOW(l1, length, ximage->depth)) overflow=1;
+    length=l1;
+  }
+  if (overflow) {
+    ximage->data = (char *) NULL;
+  } else {
+    ximage->data=(char *) AcquireMagickMemory(length);
+  }
+#undef OVERFLOW
+  }
   if (ximage->data == (char *) NULL)
     ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
   count=ReadBlob(image,length,(unsigned char *) ximage->data);
openSUSE Build Service is sponsored by