From 3c23dfbe1c4c3446fc0c6ab5095e6f9c488ec34f Mon Sep 17 00:00:00 2001
From: caodongxia <315816521@qq.com>
Date: Mon, 7 Dec 2020 18:22:24 +0800
Subject: [PATCH] create patch


diff --git a/ChangeLog b/ChangeLog
index 4284834..a89c828 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2019-04-17  Bob Friesenhahn  <bfriesen@simple.dallas.tx.us>
+	* coders/xwd.c (ReadXWDImage): Added even more XWD header
+	validation logic.  Addresses problems noted by email from Hongxu
+	Chen to the graphicsmagick-security mail alias on Wed, 17 Apr 2019
+	and entitled "Multiple crashes (FPE and invalid read) when
+	processing XWD files".  Also addresses additional issues noted
+	that an attacker could request to allocate an arbitrary amount of
+	memory based on ncolors and the claimed header size.
+
 2018-06-23  Bob Friesenhahn  <bfriesen@simple.dallas.tx.us>
 
 	* version.sh: Update library versioning for 1.3.30 release.
diff --git a/coders/xwd.c b/coders/xwd.c
index 9f9b850..caff995 100644
--- a/coders/xwd.c
+++ b/coders/xwd.c
@@ -225,7 +225,6 @@ static MagickPassFail BytesPerLine(size_t *bytes_per_line,
 */
 #define ThrowXWDReaderException(code_,reason_,image_) \
 do { \
-  MagickFreeMemory(comment); \
   if (ximage) \
     MagickFreeMemory(ximage->data); \
   MagickFreeMemory(ximage); \
@@ -236,8 +235,7 @@ do { \
 static Image *ReadXWDImage(const ImageInfo *image_info,ExceptionInfo *exception)
 {
   char
-    *comment = (char *) NULL;
-
+    comment[MaxTextExtent];
   Image
     *image;
 
@@ -320,7 +318,7 @@ static Image *ReadXWDImage(const ImageInfo *image_info,ExceptionInfo *exception)
     ThrowXWDReaderException(CorruptImageError,InvalidFileFormatVersion,image);
   if (header.header_size < sz_XWDheader)
     ThrowXWDReaderException(CorruptImageError,ImproperImageHeader,image);
-
+   /* Display classes  used in opening the connection */
   switch (header.visual_class)
     {
     case StaticGray:
@@ -335,11 +333,18 @@ static Image *ReadXWDImage(const ImageInfo *image_info,ExceptionInfo *exception)
         ThrowXWDReaderException(CorruptImageError,ImproperImageHeader,image);
       }
     }
+
+  /* XYBitmap, XYPixmap, ZPixmap */
   switch (header.pixmap_format)
     {
-    case XYBitmap:
-    case XYPixmap:
-    case ZPixmap:
+    case XYBitmap: /* 1 bit bitmap format */
+      if (header.pixmap_depth != 1)
+	ThrowXWDReaderException(CorruptImageError,ImproperImageHeader,image);
+      break;
+    case XYPixmap: /* Single plane bitmap. */
+    case ZPixmap:  /* Bitmap with 2 or more planes */
+      if ((header.pixmap_depth < 1) || (header.pixmap_depth > 32))
+	ThrowXWDReaderException(CorruptImageError,ImproperImageHeader,image);
       break;
     default:
       {
@@ -347,8 +352,80 @@ static Image *ReadXWDImage(const ImageInfo *image_info,ExceptionInfo *exception)
       }
     }
 
-  if ((header.bits_per_pixel == 0) || (header.bits_per_pixel > 32))
+  /* Data byte order, LSBFirst, MSBFirst */
+ switch (header.byte_order)
+   { 
+   case LSBFirst:
+   case MSBFirst:
+     break;
+   default:
+     {
+       ThrowXWDReaderException(CorruptImageError,ImproperImageHeader,image);
+     }
+   } 
+  /* Quant. of scanline 8, 16, 32 */
+  switch (header.bitmap_unit)
+    {
+    case 8:
+    case 16:
+    case 32:
+      break;
+    default:
+      {
+        ThrowXWDReaderException(CorruptImageError,ImproperImageHeader,image);
+      }
+     }
+  /* LSBFirst, MSBFirst */
+  switch (header.bitmap_bit_order)
+    {
+    case LSBFirst:
+    case MSBFirst:
+      break;
+    default:
+      {
+        ThrowXWDReaderException(CorruptImageError,ImproperImageHeader,image);
+      }
+    }
+  /* 8, 16, 32 either XY or ZPixmap */
+  if ((header.pixmap_format == XYPixmap) || (header.pixmap_format == ZPixmap))
+     switch (header.bitmap_pad)
+       {
+       case 8:
+       case 16:
+       case 32:
+         break;
+       default:
+	 {
+           ThrowXWDReaderException(CorruptImageError,ImproperImageHeader,image);
+	 }
+       }
+  /* Bits per pixel (ZPixmap) */
+  switch (header.visual_class)
+    {
+    case StaticGray:
+    case GrayScale:
+      /* Gray-scale image */
+      if (header.bits_per_pixel != 1)
+	ThrowXWDReaderException(CorruptImageError,ImproperImageHeader,image);
+      break;
+    case StaticColor:
+    case PseudoColor:
+      /* Color-mapped image */
+      if ((header.bits_per_pixel < 1) || (header.bits_per_pixel > 15) || (header.ncolors == 0))
+	ThrowXWDReaderException(CorruptImageError,ImproperImageHeader,image);
+      break;
+    case TrueColor:
+    case DirectColor:
+      /* True-color image */ 
+      if ((header.bits_per_pixel != 16) && (header.bits_per_pixel != 24) && (header.bits_per_pixel != 32))
+	ThrowXWDReaderException(CorruptImageError,ImproperImageHeader,image);
+      break;
+    }
+  /* Place an arbitrary limit on colormap size */ 
+  if (header.ncolors > 4096)
     ThrowXWDReaderException(CorruptImageError,ImproperImageHeader,image);
+
+  /* 8, 16, 32 either XY or ZPixmap */
   if ((header.bitmap_pad % 8 != 0) || (header.bitmap_pad > 32))
     ThrowXWDReaderException(CorruptImageError,ImproperImageHeader,image);
 
@@ -377,18 +454,14 @@ static Image *ReadXWDImage(const ImageInfo *image_info,ExceptionInfo *exception)
     Retrieve comment (if any)
   */
   length=header.header_size-sz_XWDheader;
-  if (length > ((~0UL)/sizeof(*comment)))
+  if (length >= MaxTextExtent)
     ThrowXWDReaderException(CorruptImageError,ImproperImageHeader,image);
-  comment=MagickAllocateMemory(char *,length+1);
-  if (comment == (char *) NULL)
-    ThrowXWDReaderException(ResourceLimitError,MemoryAllocationFailed,image);
   count=ReadBlob(image,length,comment);
   if (count != length)
     ThrowXWDReaderException(CorruptImageError,UnableToReadWindowNameFromDumpFile,
                             image);
   comment[length]='\0';
   (void) SetImageAttribute(image,"comment",comment);
-  MagickFreeMemory(comment);
 
   /*
     Initialize the X image.
@@ -417,6 +490,7 @@ static Image *ReadXWDImage(const ImageInfo *image_info,ExceptionInfo *exception)
   */
   if (ximage->width < 0 ||
       ximage->height < 0 ||
+      ximage->xoffset < 0 ||
       ximage->format < 0 ||
       ximage->byte_order < 0 ||
       ximage->bitmap_unit < 0 ||
@@ -439,10 +513,14 @@ static Image *ReadXWDImage(const ImageInfo *image_info,ExceptionInfo *exception)
     if (CheckImagePixelLimits(image, exception) != MagickPass)
       ThrowXWDReaderException(ResourceLimitError,ImagePixelLimitExceeded,image);
   image->depth=8;
-  if ((header.ncolors == 0U) ||
-      ((ximage->red_mask != 0) ||
-       (ximage->green_mask != 0) ||
-       (ximage->blue_mask != 0)))
+  /*
+     FIXME: This block of logic should be re-worked.
+   */
+  if ((header.visual_class != StaticGray) &&
+      ((header.ncolors == 0U) ||
+       ((ximage->red_mask != 0) ||
+	(ximage->green_mask != 0) ||
+	(ximage->blue_mask != 0))))
     {
       image->storage_class=DirectClass;
       if (!image_info->ping)
@@ -454,7 +532,7 @@ static Image *ReadXWDImage(const ImageInfo *image_info,ExceptionInfo *exception)
   else
     {
       image->storage_class=PseudoClass;
-      image->colors=header.ncolors;
+      image->colors=header.visual_class == StaticGray ? 2 : header.ncolors; /* FIXME! */
     }
   if (!image_info->ping)
     {
@@ -467,17 +545,13 @@ static Image *ReadXWDImage(const ImageInfo *image_info,ExceptionInfo *exception)
           XWDColor
             color;
 
-          register long
+          register unsigned int
             i;
-
-          length=(size_t) header.ncolors;
-          if (length > ((~0UL)/sizeof(*colors)))
-            ThrowXWDReaderException(CorruptImageError,ImproperImageHeader,image);
-          colors=MagickAllocateArray(XColor *,length,sizeof(XColor));
+          colors=MagickAllocateArray(XColor *,header.ncolors,sizeof(XColor));
           if (colors == (XColor *) NULL)
             ThrowXWDReaderException(ResourceLimitError,MemoryAllocationFailed,
                                     image);
-          for (i=0; i < (long) header.ncolors; i++)
+          for (i=0; i < header.ncolors; i++)
             {
               count=ReadBlob(image,sz_XWDColor,(char *) &color);
               if (count != sz_XWDColor)
@@ -494,7 +568,7 @@ static Image *ReadXWDImage(const ImageInfo *image_info,ExceptionInfo *exception)
           */
           lsb_first=1;
           if (*(char *) &lsb_first)
-            for (i=0; i < (long) header.ncolors; i++)
+            for (i=0; i < header.ncolors; i++)
               {
                 MSBOrderLong((unsigned char *) &colors[i].pixel,
                              sizeof(unsigned long));
@@ -508,15 +582,14 @@ static Image *ReadXWDImage(const ImageInfo *image_info,ExceptionInfo *exception)
       /*
         Allocate the pixel buffer.
       */
-#define XWD_OVERFLOW(c,a,b) ((b) != 0 && ((c)/((size_t) b) != ((size_t) a)))
+      length=MagickArraySize(ximage->bytes_per_line,ximage->height);
       length=ximage->bytes_per_line*ximage->height;
-      if (XWD_OVERFLOW(length,ximage->bytes_per_line,ximage->height))
+      if (0 == length)
         ThrowXWDReaderException(ResourceLimitError,MemoryAllocationFailed,image);
       if (ximage->format != ZPixmap)
         {
-          size_t tmp=length;
-          length*=ximage->depth;
-          if (XWD_OVERFLOW(length,tmp,ximage->depth))
+          length=MagickArraySize(length,ximage->depth);
+	  if (0 == length)
             ThrowXWDReaderException(ResourceLimitError,MemoryAllocationFailed,
                                     image);
         }
@@ -658,17 +731,21 @@ static Image *ReadXWDImage(const ImageInfo *image_info,ExceptionInfo *exception)
             /*
               Convert X image to PseudoClass packets.
             */
-            register long
+            register unsigned int
               i;
 
             if (!AllocateImageColormap(image,image->colors))
               ThrowXWDReaderException(ResourceLimitError,MemoryAllocationFailed,
                                       image);
-            for (i=0; i < (long) image->colors; i++)
-              {
-                image->colormap[i].red=ScaleShortToQuantum(colors[i].red);
-                image->colormap[i].green=ScaleShortToQuantum(colors[i].green);
-                image->colormap[i].blue=ScaleShortToQuantum(colors[i].blue);
+	    if (colors != (XColor *) NULL)
+	      {
+	        const unsigned int min_colors = Min(image->colors,header.ncolors);
+		for (i=0; i < min_colors; i++)
+                  {
+                    image->colormap[i].red=ScaleShortToQuantum(colors[i].red);
+                    image->colormap[i].green=ScaleShortToQuantum(colors[i].green);
+                    image->colormap[i].blue=ScaleShortToQuantum(colors[i].blue);
+		  }
               }
             for (y=0; y < (long) image->rows; y++)
               {
diff --git a/magick/version.h b/magick/version.h
index 527a09a..a9e0dca 100644
--- a/magick/version.h
+++ b/magick/version.h
@@ -38,8 +38,8 @@ extern "C" {
 #define MagickLibVersion  0x211801
 #define MagickLibVersionText  "1.3.30"
 #define MagickLibVersionNumber 21,18,1
-#define MagickChangeDate   "20180623"
-#define MagickReleaseDate  "2018-06-23"
+#define MagickChangeDate   "20190417"
+#define MagickReleaseDate  "snapshot-20190417"
 	
 /*
   The MagickLibInterfaceNewest and MagickLibInterfaceOldest defines
diff --git a/www/Changelog.html b/www/Changelog.html
index f1ab73c..e5a21da 100644
--- a/www/Changelog.html
+++ b/www/Changelog.html
@@ -34,6 +34,18 @@
 </div>
 <div class="document">
 
+<p>2019-04-17  Bob Friesenhahn  &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
+<blockquote>
+<ul class="simple">
+<li>coders/xwd.c (ReadXWDImage): Added even more XWD header
+validation logic.  Addresses problems noted by email from Hongxu
+Chen to the graphicsmagick-security mail alias on Wed, 17 Apr 2019
+and entitled &quot;Multiple crashes (FPE and invalid read) when
+processing XWD files&quot;.  Also addresses additional issues noted
+that an attacker could request to allocate an arbitrary amount of
+memory based on ncolors and the claimed header size.</li>
+</ul>
+</blockquote>
 
 <p>2018-06-23  Bob Friesenhahn  &lt;<a class="reference external" href="mailto:bfriesen&#37;&#52;&#48;simple&#46;dallas&#46;tx&#46;us">bfriesen<span>&#64;</span>simple<span>&#46;</span>dallas<span>&#46;</span>tx<span>&#46;</span>us</a>&gt;</p>
 <blockquote>
-- 
2.27.0

