From 6c18fa71bc004235219f6f8d6ef28f0abf924546 Mon Sep 17 00:00:00 2001
From: Vincent <vincent.fourmond@9online.fr>
Date: Sat, 16 May 2015 01:37:59 +0200
Subject: [PATCH] Avoid heap overflow in palm, pnm and xpm files

Commit backported from christy's commit
---
 coders/palm.c | 48 ++++++++++++++++++++++++------------------------
 coders/pnm.c  |  2 +-
 coders/xpm.c  | 49 +++++++++++++++++++++++++++----------------------
 3 files changed, 52 insertions(+), 47 deletions(-)

diff --git a/coders/palm.c b/coders/palm.c
index b77af07..f006bd6 100644
--- a/coders/palm.c
+++ b/coders/palm.c
@@ -186,7 +186,7 @@ static MagickBooleanType
 %    o pixel: a pointer to the PixelPacket to be matched.
 %
 */
-static int FindColor(PixelPacket *pixel)
+static ssize_t FindColor(PixelPacket *pixel)
 {
   register long
     i;
@@ -369,26 +369,26 @@ static Image *ReadPALMImage(const ImageInfo *image_info,
             for (i=0; i < (long) count; i++)
             {
               ReadBlobByte(image);
-              index=ConstrainColormapIndex(image,255-i);
-              image->colormap[(int) index].red=
-                ScaleCharToQuantum((unsigned char) ReadBlobByte(image));
-              image->colormap[(int) index].green=
-                ScaleCharToQuantum((unsigned char) ReadBlobByte(image));
-              image->colormap[(int) index].blue=
-                ScaleCharToQuantum((unsigned char) ReadBlobByte(image));
+              index=ConstrainColormapIndex(image,(size_t) (255-i));
+              image->colormap[(int) index].red=ScaleCharToQuantum(
+                (unsigned char) ReadBlobByte(image));
+              image->colormap[(int) index].green=ScaleCharToQuantum(
+                (unsigned char) ReadBlobByte(image));
+              image->colormap[(int) index].blue=ScaleCharToQuantum(
+                (unsigned char) ReadBlobByte(image));
           }
         }
       else
         {
           for (i=0; i < (long) (1L << bits_per_pixel); i++)
           {
-            index=ConstrainColormapIndex(image,255-i);
-            image->colormap[(int) index].red=
-              ScaleCharToQuantum(PalmPalette[i][0]);
-            image->colormap[(int) index].green=
-              ScaleCharToQuantum(PalmPalette[i][1]);
-            image->colormap[(int) index].blue=
-              ScaleCharToQuantum(PalmPalette[i][2]);
+            index=ConstrainColormapIndex(image,(size_t) (255-i));
+            image->colormap[(int) index].red=ScaleCharToQuantum(
+              PalmPalette[i][0]);
+            image->colormap[(int) index].green=ScaleCharToQuantum(
+              PalmPalette[i][1]);
+            image->colormap[(int) index].blue=ScaleCharToQuantum(
+              PalmPalette[i][2]);
           }
         }
       }
@@ -400,14 +400,14 @@ static Image *ReadPALMImage(const ImageInfo *image_info,
         image->storage_class=PseudoClass;
         image->depth=8;
       }
-    one_row=(unsigned char *) AcquireQuantumMemory(bytes_per_row,
-      sizeof(*one_row));
+    one_row=(unsigned char *) AcquireQuantumMemory(MagickMax(bytes_per_row,
+      2*image->columns),sizeof(*one_row));
     if (one_row == (unsigned char *) NULL)
       ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
     lastrow=(unsigned char *) NULL;
     if (compressionType == PALM_COMPRESSION_SCANLINE) {
-      lastrow=(unsigned char *) AcquireQuantumMemory(bytes_per_row,
-        sizeof(*lastrow));
+      lastrow=(unsigned char *) AcquireQuantumMemory(MagickMax(bytes_per_row,
+        2*image->columns),sizeof(*lastrow));
     if (lastrow == (unsigned char *) NULL)
       ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
     }
@@ -443,7 +443,7 @@ static Image *ReadPALMImage(const ImageInfo *image_info,
               for (i=0; i < (long) bytes_per_row; i+=8)
               {
                 count=(ssize_t) ReadBlobByte(image);
-                byte=1UL*MagickMin((ssize_t) bytes_per_row-i,8);
+                byte=(size_t) MagickMin((ssize_t) bytes_per_row-i,8);
                 for (bit=0; bit < byte; bit++)
                 {
                   if ((y == 0) || (count & (1 << (7 - bit))))
@@ -645,7 +645,7 @@ ModuleExport void UnregisterPALMImage(void)
 static MagickBooleanType WritePALMImage(const ImageInfo *image_info,
   Image *image)
 {
-  int
+  unsigned long
     y;
 
   ExceptionInfo
@@ -832,7 +832,7 @@ static MagickBooleanType WritePALMImage(const ImageInfo *image_info,
       sizeof(*one_row));
     if (one_row == (unsigned char *) NULL)
       ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
-    for (y=0; y < (int) image->rows; y++)
+    for (y=0; y < (ssize_t) image->rows; y++)
     {
       ptr=one_row;
       (void) ResetMagickMemory(ptr,0,bytes_per_row);
@@ -842,7 +842,7 @@ static MagickBooleanType WritePALMImage(const ImageInfo *image_info,
       indexes=GetAuthenticIndexQueue(image);
       if (bits_per_pixel == 16)
         {
-          for (x=0; x < (int) image->columns; x++)
+          for (x=0; x < (ssize_t) image->columns; x++)
           {
             color16=(unsigned short) ((((31*(unsigned long) GetRedPixelComponent(p))/
               (unsigned long) QuantumRange) << 11) |
@@ -865,7 +865,7 @@ static MagickBooleanType WritePALMImage(const ImageInfo *image_info,
         {
           byte=0x00;
           bit=(unsigned char) (8-bits_per_pixel);
-          for (x=0; x < (int) image->columns; x++)
+          for (x=0; x < (ssize_t) image->columns; x++)
           {
             if (bits_per_pixel >= 8)
               color=(unsigned char) indexes[x];
diff --git a/coders/pnm.c b/coders/pnm.c
index 2289cdc..76f94e9 100644
--- a/coders/pnm.c
+++ b/coders/pnm.c
@@ -165,7 +165,7 @@ static void PNMComment(Image *image)
     Read comment.
   */
   comment=AcquireString(GetImageProperty(image,"comment"));
-  extent=strlen(comment);
+  extent=MaxTextExtent;
   p=comment+strlen(comment);
   for (c='#'; (c != EOF) && (c != (int) '\n'); p++)
   {
diff --git a/coders/xpm.c b/coders/xpm.c
index 97ee9c8..7b1af9a 100644
--- a/coders/xpm.c
+++ b/coders/xpm.c
@@ -148,12 +148,16 @@ static int CompareXPMColor(const void *target,const void *source)
   return(strcmp(p,q));
 }
 
-static char *CopyXPMColor(char *destination,const char *source,size_t length)
+static size_t CopyXPMColor(char *destination,const char *source,size_t length)
 {
-  while (length-- && (*source != '\0'))
-    *destination++=(*source++);
+  register const char
+    *p;
+
+  p=source;
+  while (length-- && (*p != '\0'))
+    *destination++=(*p++);
   *destination='\0';
-  return(destination-length);
+  return((size_t) (p-source));
 }
 
 static char *NextXPMLine(char *p)
@@ -281,24 +285,26 @@ static Image *ReadXPMImage(const ImageInfo *image_info,ExceptionInfo *exception)
   */
   length=MaxTextExtent;
   xpm_buffer=(char *) AcquireQuantumMemory((size_t) length,sizeof(*xpm_buffer));
+  if (xpm_buffer == (char *) NULL)
+    ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
+  *xpm_buffer='\0';
   p=xpm_buffer;
-  if (xpm_buffer != (char *) NULL)
-    while (ReadBlobString(image,p) != (char *) NULL)
-    {
-      if ((*p == '#') && ((p == xpm_buffer) || (*(p-1) == '\n')))
-        continue;
-      if ((*p == '}') && (*(p+1) == ';'))
-        break;
-      p+=strlen(p);
-      if ((size_t) (p-xpm_buffer+MaxTextExtent) < length)
-        continue;
-      length<<=1;
-      xpm_buffer=(char *) ResizeQuantumMemory(xpm_buffer,length+MaxTextExtent,
-        sizeof(*xpm_buffer));
-      if (xpm_buffer == (char *) NULL)
-        break;
-      p=xpm_buffer+strlen(xpm_buffer);
-    }
+  while (ReadBlobString(image,p) != (char *) NULL)
+  {
+    if ((*p == '#') && ((p == xpm_buffer) || (*(p-1) == '\n')))
+      continue;
+    if ((*p == '}') && (*(p+1) == ';'))
+      break;
+    p+=strlen(p);
+    if ((size_t) (p-xpm_buffer+MaxTextExtent) < length)
+      continue;
+    length<<=1;
+    xpm_buffer=(char *) ResizeQuantumMemory(xpm_buffer,length+MaxTextExtent,
+      sizeof(*xpm_buffer));
+    if (xpm_buffer == (char *) NULL)
+      break;
+    p=xpm_buffer+strlen(xpm_buffer);
+  }
   if (xpm_buffer == (char *) NULL)
     ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
   /*
@@ -406,7 +412,6 @@ static Image *ReadXPMImage(const ImageInfo *image_info,ExceptionInfo *exception)
             indexes[x]=(IndexPacket) j;
           *r=image->colormap[j];
           r++;
-          p+=width;
         }
         if (SyncAuthenticPixels(image,exception) == MagickFalse)
           break;
-- 
2.1.4

