Sophie

Sophie

distrib > Mageia > 6 > armv7hl > by-pkgid > 6b6be615f8743ce6e3523cc425763687 > files > 9

graphicsmagick-1.3.31-1.5.mga6.src.rpm

Index: GraphicsMagick-1.3.29/coders/xwd.c
===================================================================
--- GraphicsMagick-1.3.29.orig/coders/xwd.c	2017-12-09 21:02:45.000000000 +0100
+++ GraphicsMagick-1.3.29/coders/xwd.c	2019-04-30 12:01:19.204675966 +0200
@@ -1,5 +1,5 @@
 /*
-% Copyright (C) 2003-2015 GraphicsMagick Group
+% Copyright (C) 2003-2019 GraphicsMagick Group
 % Copyright (C) 2002 ImageMagick Studio
 % Copyright 1991-1999 E. I. du Pont de Nemours and Company
 %
@@ -96,6 +96,143 @@ static unsigned int IsXWD(const unsigned
 
 #if defined(HasX11)
 #include "magick/xwindow.h"
+
+static void TraceXWDHeader(const XWDFileHeader *header)
+{
+  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+                        "XWDFileHeader:\n"
+                        "    header_size      : %u\n"
+                        "    file_version     : %u\n"
+                        "    pixmap_format    : %s\n"
+                        "    pixmap_depth     : %u\n"
+                        "    pixmap_width     : %u\n"
+                        "    pixmap_height    : %u\n"
+                        "    xoffset          : %u\n"
+                        "    byte_order       : %s\n"
+                        "    bitmap_unit      : %u\n"
+                        "    bitmap_bit_order : %s\n"
+                        "    bitmap_pad       : %u\n"
+                        "    bits_per_pixel   : %u\n"
+                        "    bytes_per_line   : %u\n"
+                        "    visual_class     : %s\n"
+                        "    red_mask         : 0x%06X\n"
+                        "    green_mask       : 0x%06X\n"
+                        "    blue_mask        : 0x%06X\n"
+                        "    bits_per_rgb     : %u\n"
+                        "    colormap_entries : %u\n"
+                        "    ncolors          : %u\n"
+                        "    window_width     : %u\n"
+                        "    window_height    : %u\n"
+                        "    window_x         : %u\n"
+                        "    window_y         : %u\n"
+                        "    window_bdrwidth  : %u",
+                        (unsigned int) header->header_size,
+                        (unsigned int) header->file_version,
+                        /* (unsigned int) header->pixmap_format, */
+                        (header->pixmap_format == XYBitmap ? "XYBitmap" :
+                         (header->pixmap_format == XYPixmap ? "XYPixmap" :
+                          (header->pixmap_format == ZPixmap ? "ZPixmap" : "?"))),
+                        (unsigned int) header->pixmap_depth,
+                        (unsigned int) header->pixmap_width,
+                        (unsigned int) header->pixmap_height,
+                        (unsigned int) header->xoffset,
+                        (header->byte_order == MSBFirst? "MSBFirst" :
+                         (header->byte_order == LSBFirst ? "LSBFirst" : "?")),
+                        (unsigned int) header->bitmap_unit,
+                        (header->bitmap_bit_order == MSBFirst? "MSBFirst" :
+                         (header->bitmap_bit_order == LSBFirst ? "LSBFirst" :
+                          "?")),
+                        (unsigned int) header->bitmap_pad,
+                        (unsigned int) header->bits_per_pixel,
+                        (unsigned int) header->bytes_per_line,
+                        (header->visual_class == StaticGray ? "StaticGray" :
+                         (header->visual_class == GrayScale ? "GrayScale" :
+                          (header->visual_class == StaticColor ? "StaticColor" :
+                           (header->visual_class == PseudoColor ? "PseudoColor" :
+                            (header->visual_class == TrueColor ? "TrueColor" :
+                             (header->visual_class == DirectColor ?
+                              "DirectColor" : "?")))))),
+                        (unsigned int) header->red_mask,
+                        (unsigned int) header->green_mask,
+                        (unsigned int) header->blue_mask,
+                        (unsigned int) header->bits_per_rgb,
+                        (unsigned int) header->colormap_entries,
+                        (unsigned int) header->ncolors,
+                        (unsigned int) header->window_width,
+                        (unsigned int) header->window_height,
+                        (unsigned int) header->window_x,
+                        (unsigned int) header->window_y,
+                        (unsigned int) header->window_bdrwidth
+                        );
+}
+
+static void TraceXImage(const XImage *ximage)
+{
+  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+                        "XImage:\n"
+                        "  width: %d\n"
+                        "  height: %d\n"
+                        "  xoffset: %d\n"
+                        "  format: %s\n"
+                        "  data: %p\n"
+                        "  byte_order: %s\n"
+                        "  bitmap_unit: %d\n"
+                        "  bitmap_bit_order: %s\n"
+                        "  bitmap_pad: %d\n"
+                        "  depth: %d\n"
+                        "  bytes_per_line: %d\n"
+                        "  bits_per_pixel: %d\n"
+                        "  red_mask: %06lX\n"
+                        "  green_mask: %06lX\n"
+                        "  blue_mask: %06lX\n",
+                        ximage->width,
+                        ximage->height,
+                        ximage->xoffset,
+                        (ximage->format == XYBitmap ? "XYBitmap" :
+                         (ximage->format == XYPixmap ? "XYPixmap" :
+                          (ximage->format == ZPixmap ? "ZPixmap" : "?"))),
+                        ximage->data,
+                        (ximage->byte_order == MSBFirst? "MSBFirst" :
+                         (ximage->byte_order == LSBFirst ? "LSBFirst" : "?")),
+                        ximage->bitmap_unit,
+                        (ximage->bitmap_bit_order == MSBFirst? "MSBFirst" :
+                         (ximage->bitmap_bit_order == LSBFirst ? "LSBFirst" :
+                          "?")),
+                        ximage->bitmap_pad,
+                        ximage->depth,
+                        ximage->bytes_per_line,
+                        ximage->bits_per_pixel,
+                        ximage->red_mask,
+                        ximage->green_mask,
+                        ximage->blue_mask);
+}
+
+/*
+  Compute required allocation sizes
+
+  FIXME: This is still a work in progress.
+
+  BitmapUnit (pixmap_depth) is the size of each data unit in each
+  scan line.  This value may be 8, 16, or 32.
+
+  BitmapPad (bitmap_pad) is the number of bits of padding added to
+  each scan line.  This value may be 8, 16, or 32.
+*/
+static MagickPassFail BytesPerLine(size_t *bytes_per_line,
+                                   size_t *scanline_bits,
+                                   const size_t pixmap_width,
+                                   const size_t pixmap_depth,
+                                   const size_t bitmap_pad)
+{
+  *bytes_per_line=0;
+  *scanline_bits=MagickArraySize(pixmap_width,pixmap_depth);
+  if ((*scanline_bits > 0) && (((~(size_t)0) - *scanline_bits > (bitmap_pad)-1)))
+    *bytes_per_line=((((*scanline_bits)+((bitmap_pad)-1))/
+                      (bitmap_pad))*((bitmap_pad) >> 3));
+
+  return (*bytes_per_line !=0 && *scanline_bits != 0) ? MagickPass : MagickFail;
+}
+
 /*
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 %                                                                             %
@@ -129,7 +266,6 @@ static unsigned int IsXWD(const unsigned
 */
 #define ThrowXWDReaderException(code_,reason_,image_) \
 do { \
-  MagickFreeMemory(comment); \
   if (ximage) \
     MagickFreeMemory(ximage->data); \
   MagickFreeMemory(ximage); \
@@ -140,7 +276,7 @@ do { \
 static Image *ReadXWDImage(const ImageInfo *image_info,ExceptionInfo *exception)
 {
   char
-    *comment = (char *) NULL;
+    comment[MaxTextExtent];
 
   Image
     *image;
@@ -211,71 +347,11 @@ static Image *ReadXWDImage(const ImageIn
   if (*(char *) &lsb_first)
     MSBOrderLong((unsigned char *) &header,sz_XWDheader);
 
-  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
-                        "XWDFileHeader:\n"
-                        "    header_size      : %u\n"
-                        "    file_version     : %u\n"
-                        "    pixmap_format    : %s\n"
-                        "    pixmap_depth     : %u\n"
-                        "    pixmap_width     : %u\n"
-                        "    pixmap_height    : %u\n"
-                        "    xoffset          : %u\n"
-                        "    byte_order       : %s\n"
-                        "    bitmap_unit      : %u\n"
-                        "    bitmap_bit_order : %s\n"
-                        "    bitmap_pad       : %u\n"
-                        "    bits_per_pixel   : %u\n"
-                        "    bytes_per_line   : %u\n"
-                        "    visual_class     : %s\n"
-                        "    red_mask         : 0x%06X\n"
-                        "    green_mask       : 0x%06X\n"
-                        "    blue_mask        : 0x%06X\n"
-                        "    bits_per_rgb     : %u\n"
-                        "    colormap_entries : %u\n"
-                        "    ncolors          : %u\n"
-                        "    window_width     : %u\n"
-                        "    window_height    : %u\n"
-                        "    window_x         : %u\n"
-                        "    window_y         : %u\n"
-                        "    window_bdrwidth  : %u",
-                        (unsigned int) header.header_size,
-                        (unsigned int) header.file_version,
-                        /* (unsigned int) header.pixmap_format, */
-                        (header.pixmap_format == XYBitmap ? "XYBitmap" :
-                         (header.pixmap_format == XYPixmap ? "XYPixmap" :
-                          (header.pixmap_format == ZPixmap ? "ZPixmap" : "?"))),
-                        (unsigned int) header.pixmap_depth,
-                        (unsigned int) header.pixmap_width,
-                        (unsigned int) header.pixmap_height,
-                        (unsigned int) header.xoffset,
-                        (header.byte_order == MSBFirst? "MSBFirst" :
-                         (header.byte_order == LSBFirst ? "LSBFirst" : "?")),
-                        (unsigned int) header.bitmap_unit,
-                        (header.bitmap_bit_order == MSBFirst? "MSBFirst" :
-                         (header.bitmap_bit_order == LSBFirst ? "LSBFirst" :
-                          "?")),
-                        (unsigned int) header.bitmap_pad,
-                        (unsigned int) header.bits_per_pixel,
-                        (unsigned int) header.bytes_per_line,
-                        (header.visual_class == StaticGray ? "StaticGray" :
-                         (header.visual_class == GrayScale ? "GrayScale" :
-                          (header.visual_class == StaticColor ? "StaticColor" :
-                           (header.visual_class == PseudoColor ? "PseudoColor" :
-                            (header.visual_class == TrueColor ? "TrueColor" :
-                             (header.visual_class == DirectColor ?
-                              "DirectColor" : "?")))))),
-                        (unsigned int) header.red_mask,
-                        (unsigned int) header.green_mask,
-                        (unsigned int) header.blue_mask,
-                        (unsigned int) header.bits_per_rgb,
-                        (unsigned int) header.colormap_entries,
-                        (unsigned int) header.ncolors,
-                        (unsigned int) header.window_width,
-                        (unsigned int) header.window_height,
-                        (unsigned int) header.window_x,
-                        (unsigned int) header.window_y,
-                        (unsigned int) header.window_bdrwidth
-                        );
+  /*
+    Trace XWD header
+  */
+  if (image->logging)
+    TraceXWDHeader(&header);
 
   /*
     Check to see if the dump file is in the proper format.
@@ -283,7 +359,19 @@ static Image *ReadXWDImage(const ImageIn
   if (header.file_version != XWD_FILE_VERSION)
     ThrowXWDReaderException(CorruptImageError,InvalidFileFormatVersion,image);
   if (header.header_size < sz_XWDheader)
-    ThrowXWDReaderException(CorruptImageError,CorruptImage,image);
+    ThrowXWDReaderException(CorruptImageError,ImproperImageHeader,image);
+
+  /*
+    Detect signed integer overflow
+  */
+  if (((magick_uint32_t) header.pixmap_depth | header.pixmap_format |
+       header.xoffset | header.pixmap_width | header.pixmap_height |
+       header.bitmap_pad | header.bytes_per_line | header.byte_order |
+       header.bitmap_unit | header.bitmap_bit_order |
+       header.bits_per_pixel) >> 31)
+    ThrowXWDReaderException(CorruptImageError,ImproperImageHeader,image);
+
+  /* Display classes  used in opening the connection */
   switch (header.visual_class)
     {
     case StaticGray:
@@ -295,37 +383,152 @@ static Image *ReadXWDImage(const ImageIn
       break;
     default:
       {
-        ThrowXWDReaderException(CorruptImageError,CorruptImage,image);
+        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:
       {
-        ThrowXWDReaderException(CorruptImageError,CorruptImage,image);
+        ThrowXWDReaderException(CorruptImageError,ImproperImageHeader,image);
       }
     }
 
+  /* 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);
+        }
+      }
+
+  /* xoffset should be in the bounds of pixmap_width */
+  if (header.xoffset >= header.pixmap_width)
+    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);
+
+  {
+    size_t
+      bytes_per_line=0,
+      scanline_bits;
+
+    if (BytesPerLine(&bytes_per_line,&scanline_bits,
+                     header.pixmap_width,header.pixmap_depth,header.bitmap_pad)
+        == MagickFail)
+      ThrowReaderException(CoderError,ArithmeticOverflow,image);
+
+    if (header.bytes_per_line < bytes_per_line)
+      {
+        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+                              "Header bytes_per_line = %" MAGICK_SIZE_T_F "u,"
+                              " expected %" MAGICK_SIZE_T_F "u",
+                              (MAGICK_SIZE_T) header.bytes_per_line,
+                              (MAGICK_SIZE_T) bytes_per_line);
+        ThrowXWDReaderException(CorruptImageError,ImproperImageHeader,image);
+      }
+  }
+
+
   /*
     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.
@@ -348,37 +551,29 @@ static Image *ReadXWDImage(const ImageIn
   ximage->red_mask=header.red_mask;
   ximage->green_mask=header.green_mask;
   ximage->blue_mask=header.blue_mask;
-  /*
-    XImage uses signed integers rather than unsigned.  Check for
-    overflow due to assignment.
-  */
-  if (ximage->width < 0 ||
-      ximage->height < 0 ||
-      ximage->format < 0 ||
-      ximage->byte_order < 0 ||
-      ximage->bitmap_unit < 0 ||
-      ximage->bitmap_bit_order < 0 ||
-      ximage->bitmap_pad < 0 ||
-      ximage->depth < 0 ||
-      ximage->bytes_per_line < 0 ||
-      ximage->bits_per_pixel < 0)
-    ThrowXWDReaderException(CorruptImageError,ImproperImageHeader,image);
-  /* Guard against buffer overflow in libX11. */
-  if (ximage->bits_per_pixel > 32 || ximage->bitmap_unit > 32)
-    ThrowXWDReaderException(CorruptImageError,ImproperImageHeader,image);
+
   status=XInitImage(ximage);
   if (status == False)
     ThrowXWDReaderException(CorruptImageError,UnrecognizedXWDHeader,image);
-  image->columns=ximage->width;
-  image->rows=ximage->height;
+
+  if (image->logging)
+    TraceXImage(ximage);
+
+  image->columns=(unsigned long) ximage->width;
+  image->rows=(unsigned long) ximage->height;
   if (!image_info->ping)
     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)
@@ -390,8 +585,8 @@ static Image *ReadXWDImage(const ImageIn
   else
     {
       image->storage_class=PseudoClass;
+      image->colors=header.visual_class == StaticGray ? 2 : header.ncolors; /* FIXME! */
     }
-  image->colors=header.ncolors;
   if (!image_info->ping)
     {
       /*
@@ -403,17 +598,14 @@ static Image *ReadXWDImage(const ImageIn
           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)
@@ -430,7 +622,7 @@ static Image *ReadXWDImage(const ImageIn
           */
           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));
@@ -444,18 +636,32 @@ static Image *ReadXWDImage(const ImageIn
       /*
         Allocate the pixel buffer.
       */
-#define XWD_OVERFLOW(c,a,b) ((b) != 0 && ((c)/((size_t) b) != ((size_t) a)))
-      length=ximage->bytes_per_line*ximage->height;
-      if (XWD_OVERFLOW(length,ximage->bytes_per_line,ximage->height))
+      length=MagickArraySize(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);
         }
+      {
+
+        magick_off_t
+          file_size;
+
+        file_size=GetBlobSize(image);
+
+        (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+                              "File size %" MAGICK_OFF_F "d,"
+                              "Pixels allocation size %" MAGICK_SIZE_T_F "u",
+                              file_size, (MAGICK_SIZE_T) length);
+
+        if ((file_size != 0) && ((size_t) file_size < length))
+          ThrowXWDReaderException(CorruptImageError,UnexpectedEndOfFile,image);
+      }
+
       ximage->data=MagickAllocateMemory(char *,length);
       if (ximage->data == (char *) NULL)
         ThrowXWDReaderException(ResourceLimitError,MemoryAllocationFailed,image);
@@ -507,7 +713,7 @@ static Image *ReadXWDImage(const ImageIn
             /*
               Convert X image to DirectClass packets.
             */
-            if (image->colors != 0)
+            if (header.ncolors != 0)
               {
                 for (y=0; y < (long) image->rows; y++)
                   {
@@ -519,12 +725,15 @@ static Image *ReadXWDImage(const ImageIn
                         pixel=XGetPixel(ximage,(int) x,(int) y);
                         index_val=(unsigned short)
                           ((pixel >> red_shift) & red_mask);
+                        VerifyColormapIndexWithColors(image,index_val,header.ncolors);
                         q->red=ScaleShortToQuantum(colors[index_val].red);
                         index_val=(unsigned short)
                           ((pixel >> green_shift) & green_mask);
+                        VerifyColormapIndexWithColors(image,index_val,header.ncolors);
                         q->green=ScaleShortToQuantum(colors[index_val].green);
                         index_val=(unsigned short)
                           ((pixel >> blue_shift) & blue_mask);
+                        VerifyColormapIndexWithColors(image,index_val,header.ncolors);
                         q->blue=ScaleShortToQuantum(colors[index_val].blue);
                         q++;
                       }
@@ -575,17 +784,21 @@ static Image *ReadXWDImage(const ImageIn
             /*
               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++)
+            if (colors != (XColor *) NULL)
               {
-                image->colormap[i].red=ScaleShortToQuantum(colors[i].red);
-                image->colormap[i].green=ScaleShortToQuantum(colors[i].green);
-                image->colormap[i].blue=ScaleShortToQuantum(colors[i].blue);
+                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++)
               {
@@ -722,16 +935,16 @@ ModuleExport void UnregisterXWDImage(voi
 */
 static unsigned int WriteXWDImage(const ImageInfo *image_info,Image *image)
 {
-  long
+  unsigned long
     y;
 
   register const PixelPacket
     *p;
 
-  register long
+  register unsigned long
     x;
 
-  register long
+  register unsigned int
     i;
 
   register unsigned char
@@ -740,17 +953,22 @@ static unsigned int WriteXWDImage(const
   unsigned char
     *pixels;
 
+  unsigned int
+    bits_per_pixel;
+
   size_t
-    pixels_size;
+    bytes_per_line=0,
+    scanline_bits,
+    scanline_pad=0;
 
   unsigned int
+    bitmap_pad;
+
+  MagickPassFail
     status;
 
   unsigned long
-    bits_per_pixel,
-    bytes_per_line,
-    lsb_first,
-    scanline_pad;
+    lsb_first;
 
   XWDFileHeader
     xwd_info;
@@ -763,7 +981,7 @@ static unsigned int WriteXWDImage(const
   assert(image != (Image *) NULL);
   assert(image->signature == MagickSignature);
   status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception);
-  if (status == False)
+  if (status == MagickFail)
     ThrowWriterException(FileOpenError,UnableToOpenFile,image);
   (void) TransformColorspace(image,RGBColorspace);
   /*
@@ -771,6 +989,40 @@ static unsigned int WriteXWDImage(const
   */
   if ((image->storage_class == PseudoClass) && (image->colors > 256))
     SetImageType(image,TrueColorType);
+
+  /*
+    Compute required allocation sizes
+
+    BitmapUnit is the size of each data unit in each scan line.  This
+    value may be 8, 16, or 32.
+
+    BitmapPad is the number of bits of padding added to each scan
+    line.  This value may be 8, 16, or 32.
+  */
+  bits_per_pixel=(image->storage_class == DirectClass ? 24 : 8);
+  bitmap_pad=(image->storage_class == DirectClass ? 32 : 8);
+
+  if (BytesPerLine(&bytes_per_line,&scanline_bits,image->columns,
+                   bits_per_pixel,bitmap_pad) != MagickFail)
+    scanline_pad=(bytes_per_line-(scanline_bits >> 3));
+
+  if (image->logging)
+    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
+                          " image->columns=%lu,"
+                          " bits_per_pixel=%u,"
+                          " bytes_per_line=%" MAGICK_SIZE_T_F "u,"
+                          " bitmap_pad=%u",
+                          image->columns,
+                          bits_per_pixel,
+                          (MAGICK_SIZE_T) bytes_per_line,
+                          bitmap_pad);
+  if ((scanline_bits == 0) || (bytes_per_line < (scanline_bits >> 3)))
+    ThrowWriterException(CoderError,ArithmeticOverflow,image);
+
+  if (((bytes_per_line & 0x7fffffff) != bytes_per_line) ||
+      ((image->rows & 0x7fffffff) != image->rows))
+    ThrowWriterException(CoderError,ImageColumnOrRowSizeIsNotSupported,image);
+
   /*
     Initialize XWD file header.
   */
@@ -785,19 +1037,14 @@ static unsigned int WriteXWDImage(const
   xwd_info.byte_order=(CARD32) MSBFirst;
   xwd_info.bitmap_unit=(CARD32) (image->storage_class == DirectClass ? 32 : 8);
   xwd_info.bitmap_bit_order=(CARD32) MSBFirst;
-  xwd_info.bitmap_pad=(CARD32) (image->storage_class == DirectClass ? 32 : 8);
-  bits_per_pixel=(image->storage_class == DirectClass ? 24 : 8);
+  xwd_info.bitmap_pad=(CARD32) bitmap_pad;
   xwd_info.bits_per_pixel=(CARD32) bits_per_pixel;
-  bytes_per_line=(CARD32) ((((xwd_info.bits_per_pixel*
-    xwd_info.pixmap_width)+((xwd_info.bitmap_pad)-1))/
-    (xwd_info.bitmap_pad))*((xwd_info.bitmap_pad) >> 3));
   xwd_info.bytes_per_line=(CARD32) bytes_per_line;
   xwd_info.visual_class=(CARD32)
     (image->storage_class == DirectClass ? DirectColor : PseudoColor);
   xwd_info.red_mask=(CARD32)
     (image->storage_class == DirectClass ? 0xff0000 : 0);
-  xwd_info.green_mask=(CARD32)
-    (image->storage_class == DirectClass ? 0xff00 : 0);
+  xwd_info.green_mask=(CARD32)(image->storage_class == DirectClass ? 0xff00 : 0);
   xwd_info.blue_mask=(CARD32) (image->storage_class == DirectClass ? 0xff : 0);
   xwd_info.bits_per_rgb=(CARD32) (image->storage_class == DirectClass ? 24 : 8);
   xwd_info.colormap_entries=(CARD32)
@@ -809,6 +1056,20 @@ static unsigned int WriteXWDImage(const
   xwd_info.window_x=0;
   xwd_info.window_y=0;
   xwd_info.window_bdrwidth=(CARD32) 0;
+
+  /*
+    Trace XWD header
+  */
+  if (image->logging)
+    TraceXWDHeader(&xwd_info);
+
+  /*
+    Allocate memory for pixels.
+  */
+  pixels=MagickAllocateMemory(unsigned char *,bytes_per_line);
+  if (pixels == (unsigned char *) NULL)
+    ThrowWriterException(ResourceLimitError,MemoryAllocationFailed,image);
+
   /*
     Write XWD header.
   */
@@ -832,7 +1093,7 @@ static unsigned int WriteXWDImage(const
       colors=MagickAllocateArray(XColor *,image->colors,sizeof(XColor));
       if (colors == (XColor *) NULL)
         ThrowWriterException(ResourceLimitError,MemoryAllocationFailed,image);
-      for (i=0; i < (long) image->colors; i++)
+      for (i=0; i < image->colors; i++)
       {
         colors[i].pixel=i;
         colors[i].red=ScaleQuantumToShort(image->colormap[i].red);
@@ -846,30 +1107,22 @@ static unsigned int WriteXWDImage(const
             MSBOrderShort((unsigned char *) &colors[i].red,3*sizeof(short));
           }
       }
-      for (i=0; i < (long) image->colors; i++)
+      for (i=0; i < image->colors; i++)
       {
         color.pixel=(CARD32) colors[i].pixel;
         color.red=colors[i].red;
         color.green=colors[i].green;
         color.blue=colors[i].blue;
         color.flags=colors[i].flags;
-        (void) WriteBlob(image,sz_XWDColor,(char *) &color);
+        if (WriteBlob(image,sz_XWDColor,(char *) &color) != sz_XWDColor)
+          break;
       }
       MagickFreeMemory(colors);
     }
   /*
-    Allocate memory for pixels.
-  */
-  scanline_pad=(bytes_per_line-((image->columns*bits_per_pixel) >> 3));
-  pixels_size=image->columns*(image->storage_class == PseudoClass ? 1 : 3)+scanline_pad;
-  pixels=MagickAllocateMemory(unsigned char *,pixels_size);
-  if (pixels == (unsigned char *) NULL)
-    ThrowWriterException(ResourceLimitError,MemoryAllocationFailed,image);
-  (void) memset(pixels,0,pixels_size);
-  /*
     Convert MIFF to XWD raster pixels.
   */
-  for (y=0; y < (long) image->rows; y++)
+  for (y=0; y < image->rows; y++)
   {
     p=AcquireImagePixels(image,0,y,image->columns,1,&image->exception);
     if (p == (const PixelPacket *) NULL)
@@ -882,12 +1135,12 @@ static unsigned int WriteXWDImage(const
           *indexes;
 
         indexes=AccessImmutableIndexes(image);
-        for (x=0; x < (long) image->columns; x++)
+        for (x=0; x < image->columns; x++)
           *q++=(unsigned char) indexes[x];
       }
     else
       {
-        for (x=(long) image->columns; x > 0; x--)
+        for (x=0; x < image->columns; x++)
           {
 
             *q++=ScaleQuantumToChar(p->red);
@@ -898,7 +1151,8 @@ static unsigned int WriteXWDImage(const
       }
     for (x=(long) scanline_pad; x > 0; x--)
       *q++=0;
-    (void) WriteBlob(image,(size_t) (q-pixels),(char *) pixels);
+    if (WriteBlob(image,(size_t) (q-pixels),(char *) pixels) != (size_t) (q-pixels))
+      break;
     if (image->previous == (Image *) NULL)
       if (QuantumTick(y,image->rows))
         if (!MagickMonitorFormatted(y,image->rows,&image->exception,
@@ -908,6 +1162,6 @@ static unsigned int WriteXWDImage(const
   }
   MagickFreeMemory(pixels);
   CloseBlob(image);
-  return(True);
+  return (y < image->rows ? MagickFail :  MagickPass);
 }
 #endif